2 * PowerPC CPU initialization for qemu.
4 * Copyright (c) 2003-2007 Jocelyn Mayer
5 * Copyright 2011 Freescale Semiconductor, Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include "qemu/osdep.h"
22 #include "disas/bfd.h"
23 #include "exec/gdbstub.h"
25 #include "sysemu/arch_init.h"
26 #include "sysemu/cpus.h"
27 #include "sysemu/hw_accel.h"
28 #include "cpu-models.h"
29 #include "mmu-hash32.h"
30 #include "mmu-hash64.h"
31 #include "qemu/error-report.h"
32 #include "qapi/visitor.h"
33 #include "hw/qdev-properties.h"
34 #include "hw/ppc/ppc.h"
35 #include "mmu-book3s-v3.h"
37 //#define PPC_DUMP_CPU
38 //#define PPC_DEBUG_SPR
39 //#define PPC_DUMP_SPR_ACCESSES
40 /* #define USE_APPLE_GDB */
43 * do nothing but store/retrieve spr value
45 static void spr_load_dump_spr(int sprn
)
47 #ifdef PPC_DUMP_SPR_ACCESSES
48 TCGv_i32 t0
= tcg_const_i32(sprn
);
49 gen_helper_load_dump_spr(cpu_env
, t0
);
50 tcg_temp_free_i32(t0
);
54 static void spr_read_generic (DisasContext
*ctx
, int gprn
, int sprn
)
56 gen_load_spr(cpu_gpr
[gprn
], sprn
);
57 spr_load_dump_spr(sprn
);
60 static void spr_store_dump_spr(int sprn
)
62 #ifdef PPC_DUMP_SPR_ACCESSES
63 TCGv_i32 t0
= tcg_const_i32(sprn
);
64 gen_helper_store_dump_spr(cpu_env
, t0
);
65 tcg_temp_free_i32(t0
);
69 static void spr_write_generic (DisasContext
*ctx
, int sprn
, int gprn
)
71 gen_store_spr(sprn
, cpu_gpr
[gprn
]);
72 spr_store_dump_spr(sprn
);
75 #if !defined(CONFIG_USER_ONLY)
76 static void spr_write_generic32(DisasContext
*ctx
, int sprn
, int gprn
)
79 TCGv t0
= tcg_temp_new();
80 tcg_gen_ext32u_tl(t0
, cpu_gpr
[gprn
]);
81 gen_store_spr(sprn
, t0
);
83 spr_store_dump_spr(sprn
);
85 spr_write_generic(ctx
, sprn
, gprn
);
89 static void spr_write_clear (DisasContext
*ctx
, int sprn
, int gprn
)
91 TCGv t0
= tcg_temp_new();
92 TCGv t1
= tcg_temp_new();
93 gen_load_spr(t0
, sprn
);
94 tcg_gen_neg_tl(t1
, cpu_gpr
[gprn
]);
95 tcg_gen_and_tl(t0
, t0
, t1
);
96 gen_store_spr(sprn
, t0
);
101 static void spr_access_nop(DisasContext
*ctx
, int sprn
, int gprn
)
107 /* SPR common to all PowerPC */
109 static void spr_read_xer (DisasContext
*ctx
, int gprn
, int sprn
)
111 gen_read_xer(ctx
, cpu_gpr
[gprn
]);
114 static void spr_write_xer (DisasContext
*ctx
, int sprn
, int gprn
)
116 gen_write_xer(cpu_gpr
[gprn
]);
120 static void spr_read_lr (DisasContext
*ctx
, int gprn
, int sprn
)
122 tcg_gen_mov_tl(cpu_gpr
[gprn
], cpu_lr
);
125 static void spr_write_lr (DisasContext
*ctx
, int sprn
, int gprn
)
127 tcg_gen_mov_tl(cpu_lr
, cpu_gpr
[gprn
]);
131 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
132 static void spr_read_cfar (DisasContext
*ctx
, int gprn
, int sprn
)
134 tcg_gen_mov_tl(cpu_gpr
[gprn
], cpu_cfar
);
137 static void spr_write_cfar (DisasContext
*ctx
, int sprn
, int gprn
)
139 tcg_gen_mov_tl(cpu_cfar
, cpu_gpr
[gprn
]);
141 #endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
144 static void spr_read_ctr (DisasContext
*ctx
, int gprn
, int sprn
)
146 tcg_gen_mov_tl(cpu_gpr
[gprn
], cpu_ctr
);
149 static void spr_write_ctr (DisasContext
*ctx
, int sprn
, int gprn
)
151 tcg_gen_mov_tl(cpu_ctr
, cpu_gpr
[gprn
]);
154 /* User read access to SPR */
160 static void spr_read_ureg (DisasContext
*ctx
, int gprn
, int sprn
)
162 gen_load_spr(cpu_gpr
[gprn
], sprn
+ 0x10);
165 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
166 static void spr_write_ureg(DisasContext
*ctx
, int sprn
, int gprn
)
168 gen_store_spr(sprn
+ 0x10, cpu_gpr
[gprn
]);
172 /* SPR common to all non-embedded PowerPC */
174 #if !defined(CONFIG_USER_ONLY)
175 static void spr_read_decr (DisasContext
*ctx
, int gprn
, int sprn
)
177 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
180 gen_helper_load_decr(cpu_gpr
[gprn
], cpu_env
);
181 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
183 gen_stop_exception(ctx
);
187 static void spr_write_decr (DisasContext
*ctx
, int sprn
, int gprn
)
189 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
192 gen_helper_store_decr(cpu_env
, cpu_gpr
[gprn
]);
193 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
195 gen_stop_exception(ctx
);
200 /* SPR common to all non-embedded PowerPC, except 601 */
202 static void spr_read_tbl (DisasContext
*ctx
, int gprn
, int sprn
)
204 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
207 gen_helper_load_tbl(cpu_gpr
[gprn
], cpu_env
);
208 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
210 gen_stop_exception(ctx
);
214 static void spr_read_tbu (DisasContext
*ctx
, int gprn
, int sprn
)
216 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
219 gen_helper_load_tbu(cpu_gpr
[gprn
], cpu_env
);
220 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
222 gen_stop_exception(ctx
);
226 __attribute__ (( unused
))
227 static void spr_read_atbl (DisasContext
*ctx
, int gprn
, int sprn
)
229 gen_helper_load_atbl(cpu_gpr
[gprn
], cpu_env
);
232 __attribute__ (( unused
))
233 static void spr_read_atbu (DisasContext
*ctx
, int gprn
, int sprn
)
235 gen_helper_load_atbu(cpu_gpr
[gprn
], cpu_env
);
238 #if !defined(CONFIG_USER_ONLY)
239 static void spr_write_tbl (DisasContext
*ctx
, int sprn
, int gprn
)
241 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
244 gen_helper_store_tbl(cpu_env
, cpu_gpr
[gprn
]);
245 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
247 gen_stop_exception(ctx
);
251 static void spr_write_tbu (DisasContext
*ctx
, int sprn
, int gprn
)
253 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
256 gen_helper_store_tbu(cpu_env
, cpu_gpr
[gprn
]);
257 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
259 gen_stop_exception(ctx
);
263 __attribute__ (( unused
))
264 static void spr_write_atbl (DisasContext
*ctx
, int sprn
, int gprn
)
266 gen_helper_store_atbl(cpu_env
, cpu_gpr
[gprn
]);
269 __attribute__ (( unused
))
270 static void spr_write_atbu (DisasContext
*ctx
, int sprn
, int gprn
)
272 gen_helper_store_atbu(cpu_env
, cpu_gpr
[gprn
]);
275 #if defined(TARGET_PPC64)
276 __attribute__ (( unused
))
277 static void spr_read_purr (DisasContext
*ctx
, int gprn
, int sprn
)
279 gen_helper_load_purr(cpu_gpr
[gprn
], cpu_env
);
283 static void spr_read_hdecr(DisasContext
*ctx
, int gprn
, int sprn
)
285 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
288 gen_helper_load_hdecr(cpu_gpr
[gprn
], cpu_env
);
289 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
291 gen_stop_exception(ctx
);
295 static void spr_write_hdecr(DisasContext
*ctx
, int sprn
, int gprn
)
297 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
300 gen_helper_store_hdecr(cpu_env
, cpu_gpr
[gprn
]);
301 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
303 gen_stop_exception(ctx
);
310 #if !defined(CONFIG_USER_ONLY)
311 /* IBAT0U...IBAT0U */
312 /* IBAT0L...IBAT7L */
313 static void spr_read_ibat (DisasContext
*ctx
, int gprn
, int sprn
)
315 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, IBAT
[sprn
& 1][(sprn
- SPR_IBAT0U
) / 2]));
318 static void spr_read_ibat_h (DisasContext
*ctx
, int gprn
, int sprn
)
320 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, IBAT
[sprn
& 1][((sprn
- SPR_IBAT4U
) / 2) + 4]));
323 static void spr_write_ibatu (DisasContext
*ctx
, int sprn
, int gprn
)
325 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0U
) / 2);
326 gen_helper_store_ibatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
327 tcg_temp_free_i32(t0
);
330 static void spr_write_ibatu_h (DisasContext
*ctx
, int sprn
, int gprn
)
332 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_IBAT4U
) / 2) + 4);
333 gen_helper_store_ibatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
334 tcg_temp_free_i32(t0
);
337 static void spr_write_ibatl (DisasContext
*ctx
, int sprn
, int gprn
)
339 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0L
) / 2);
340 gen_helper_store_ibatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
341 tcg_temp_free_i32(t0
);
344 static void spr_write_ibatl_h (DisasContext
*ctx
, int sprn
, int gprn
)
346 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_IBAT4L
) / 2) + 4);
347 gen_helper_store_ibatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
348 tcg_temp_free_i32(t0
);
351 /* DBAT0U...DBAT7U */
352 /* DBAT0L...DBAT7L */
353 static void spr_read_dbat (DisasContext
*ctx
, int gprn
, int sprn
)
355 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, DBAT
[sprn
& 1][(sprn
- SPR_DBAT0U
) / 2]));
358 static void spr_read_dbat_h (DisasContext
*ctx
, int gprn
, int sprn
)
360 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, DBAT
[sprn
& 1][((sprn
- SPR_DBAT4U
) / 2) + 4]));
363 static void spr_write_dbatu (DisasContext
*ctx
, int sprn
, int gprn
)
365 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_DBAT0U
) / 2);
366 gen_helper_store_dbatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
367 tcg_temp_free_i32(t0
);
370 static void spr_write_dbatu_h (DisasContext
*ctx
, int sprn
, int gprn
)
372 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_DBAT4U
) / 2) + 4);
373 gen_helper_store_dbatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
374 tcg_temp_free_i32(t0
);
377 static void spr_write_dbatl (DisasContext
*ctx
, int sprn
, int gprn
)
379 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_DBAT0L
) / 2);
380 gen_helper_store_dbatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
381 tcg_temp_free_i32(t0
);
384 static void spr_write_dbatl_h (DisasContext
*ctx
, int sprn
, int gprn
)
386 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_DBAT4L
) / 2) + 4);
387 gen_helper_store_dbatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
388 tcg_temp_free_i32(t0
);
392 static void spr_write_sdr1 (DisasContext
*ctx
, int sprn
, int gprn
)
394 gen_helper_store_sdr1(cpu_env
, cpu_gpr
[gprn
]);
397 /* 64 bits PowerPC specific SPRs */
398 #if defined(TARGET_PPC64)
399 static void spr_read_hior (DisasContext
*ctx
, int gprn
, int sprn
)
401 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, excp_prefix
));
404 static void spr_write_hior (DisasContext
*ctx
, int sprn
, int gprn
)
406 TCGv t0
= tcg_temp_new();
407 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], 0x3FFFFF00000ULL
);
408 tcg_gen_st_tl(t0
, cpu_env
, offsetof(CPUPPCState
, excp_prefix
));
414 /* PowerPC 601 specific registers */
416 static void spr_read_601_rtcl (DisasContext
*ctx
, int gprn
, int sprn
)
418 gen_helper_load_601_rtcl(cpu_gpr
[gprn
], cpu_env
);
421 static void spr_read_601_rtcu (DisasContext
*ctx
, int gprn
, int sprn
)
423 gen_helper_load_601_rtcu(cpu_gpr
[gprn
], cpu_env
);
426 #if !defined(CONFIG_USER_ONLY)
427 static void spr_write_601_rtcu (DisasContext
*ctx
, int sprn
, int gprn
)
429 gen_helper_store_601_rtcu(cpu_env
, cpu_gpr
[gprn
]);
432 static void spr_write_601_rtcl (DisasContext
*ctx
, int sprn
, int gprn
)
434 gen_helper_store_601_rtcl(cpu_env
, cpu_gpr
[gprn
]);
437 static void spr_write_hid0_601 (DisasContext
*ctx
, int sprn
, int gprn
)
439 gen_helper_store_hid0_601(cpu_env
, cpu_gpr
[gprn
]);
440 /* Must stop the translation as endianness may have changed */
441 gen_stop_exception(ctx
);
446 #if !defined(CONFIG_USER_ONLY)
447 static void spr_read_601_ubat (DisasContext
*ctx
, int gprn
, int sprn
)
449 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, IBAT
[sprn
& 1][(sprn
- SPR_IBAT0U
) / 2]));
452 static void spr_write_601_ubatu (DisasContext
*ctx
, int sprn
, int gprn
)
454 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0U
) / 2);
455 gen_helper_store_601_batl(cpu_env
, t0
, cpu_gpr
[gprn
]);
456 tcg_temp_free_i32(t0
);
459 static void spr_write_601_ubatl (DisasContext
*ctx
, int sprn
, int gprn
)
461 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0U
) / 2);
462 gen_helper_store_601_batu(cpu_env
, t0
, cpu_gpr
[gprn
]);
463 tcg_temp_free_i32(t0
);
467 /* PowerPC 40x specific registers */
468 #if !defined(CONFIG_USER_ONLY)
469 static void spr_read_40x_pit (DisasContext
*ctx
, int gprn
, int sprn
)
471 gen_helper_load_40x_pit(cpu_gpr
[gprn
], cpu_env
);
474 static void spr_write_40x_pit (DisasContext
*ctx
, int sprn
, int gprn
)
476 gen_helper_store_40x_pit(cpu_env
, cpu_gpr
[gprn
]);
479 static void spr_write_40x_dbcr0 (DisasContext
*ctx
, int sprn
, int gprn
)
481 gen_helper_store_40x_dbcr0(cpu_env
, cpu_gpr
[gprn
]);
482 /* We must stop translation as we may have rebooted */
483 gen_stop_exception(ctx
);
486 static void spr_write_40x_sler (DisasContext
*ctx
, int sprn
, int gprn
)
488 gen_helper_store_40x_sler(cpu_env
, cpu_gpr
[gprn
]);
491 static void spr_write_booke_tcr (DisasContext
*ctx
, int sprn
, int gprn
)
493 gen_helper_store_booke_tcr(cpu_env
, cpu_gpr
[gprn
]);
496 static void spr_write_booke_tsr (DisasContext
*ctx
, int sprn
, int gprn
)
498 gen_helper_store_booke_tsr(cpu_env
, cpu_gpr
[gprn
]);
502 /* PowerPC 403 specific registers */
503 /* PBL1 / PBU1 / PBL2 / PBU2 */
504 #if !defined(CONFIG_USER_ONLY)
505 static void spr_read_403_pbr (DisasContext
*ctx
, int gprn
, int sprn
)
507 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, pb
[sprn
- SPR_403_PBL1
]));
510 static void spr_write_403_pbr (DisasContext
*ctx
, int sprn
, int gprn
)
512 TCGv_i32 t0
= tcg_const_i32(sprn
- SPR_403_PBL1
);
513 gen_helper_store_403_pbr(cpu_env
, t0
, cpu_gpr
[gprn
]);
514 tcg_temp_free_i32(t0
);
517 static void spr_write_pir (DisasContext
*ctx
, int sprn
, int gprn
)
519 TCGv t0
= tcg_temp_new();
520 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], 0xF);
521 gen_store_spr(SPR_PIR
, t0
);
526 /* SPE specific registers */
527 static void spr_read_spefscr (DisasContext
*ctx
, int gprn
, int sprn
)
529 TCGv_i32 t0
= tcg_temp_new_i32();
530 tcg_gen_ld_i32(t0
, cpu_env
, offsetof(CPUPPCState
, spe_fscr
));
531 tcg_gen_extu_i32_tl(cpu_gpr
[gprn
], t0
);
532 tcg_temp_free_i32(t0
);
535 static void spr_write_spefscr (DisasContext
*ctx
, int sprn
, int gprn
)
537 TCGv_i32 t0
= tcg_temp_new_i32();
538 tcg_gen_trunc_tl_i32(t0
, cpu_gpr
[gprn
]);
539 tcg_gen_st_i32(t0
, cpu_env
, offsetof(CPUPPCState
, spe_fscr
));
540 tcg_temp_free_i32(t0
);
543 #if !defined(CONFIG_USER_ONLY)
544 /* Callback used to write the exception vector base */
545 static void spr_write_excp_prefix (DisasContext
*ctx
, int sprn
, int gprn
)
547 TCGv t0
= tcg_temp_new();
548 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUPPCState
, ivpr_mask
));
549 tcg_gen_and_tl(t0
, t0
, cpu_gpr
[gprn
]);
550 tcg_gen_st_tl(t0
, cpu_env
, offsetof(CPUPPCState
, excp_prefix
));
551 gen_store_spr(sprn
, t0
);
555 static void spr_write_excp_vector (DisasContext
*ctx
, int sprn
, int gprn
)
559 if (sprn
>= SPR_BOOKE_IVOR0
&& sprn
<= SPR_BOOKE_IVOR15
) {
560 sprn_offs
= sprn
- SPR_BOOKE_IVOR0
;
561 } else if (sprn
>= SPR_BOOKE_IVOR32
&& sprn
<= SPR_BOOKE_IVOR37
) {
562 sprn_offs
= sprn
- SPR_BOOKE_IVOR32
+ 32;
563 } else if (sprn
>= SPR_BOOKE_IVOR38
&& sprn
<= SPR_BOOKE_IVOR42
) {
564 sprn_offs
= sprn
- SPR_BOOKE_IVOR38
+ 38;
566 printf("Trying to write an unknown exception vector %d %03x\n",
568 gen_inval_exception(ctx
, POWERPC_EXCP_PRIV_REG
);
572 TCGv t0
= tcg_temp_new();
573 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUPPCState
, ivor_mask
));
574 tcg_gen_and_tl(t0
, t0
, cpu_gpr
[gprn
]);
575 tcg_gen_st_tl(t0
, cpu_env
, offsetof(CPUPPCState
, excp_vectors
[sprn_offs
]));
576 gen_store_spr(sprn
, t0
);
581 static inline void vscr_init (CPUPPCState
*env
, uint32_t val
)
584 /* Altivec always uses round-to-nearest */
585 set_float_rounding_mode(float_round_nearest_even
, &env
->vec_status
);
586 set_flush_to_zero(vscr_nj
, &env
->vec_status
);
589 #ifdef CONFIG_USER_ONLY
590 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
591 oea_read, oea_write, one_reg_id, initial_value) \
592 _spr_register(env, num, name, uea_read, uea_write, initial_value)
593 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
594 oea_read, oea_write, hea_read, hea_write, \
595 one_reg_id, initial_value) \
596 _spr_register(env, num, name, uea_read, uea_write, initial_value)
598 #if !defined(CONFIG_KVM)
599 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
600 oea_read, oea_write, one_reg_id, initial_value) \
601 _spr_register(env, num, name, uea_read, uea_write, \
602 oea_read, oea_write, oea_read, oea_write, initial_value)
603 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
604 oea_read, oea_write, hea_read, hea_write, \
605 one_reg_id, initial_value) \
606 _spr_register(env, num, name, uea_read, uea_write, \
607 oea_read, oea_write, hea_read, hea_write, initial_value)
609 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
610 oea_read, oea_write, one_reg_id, initial_value) \
611 _spr_register(env, num, name, uea_read, uea_write, \
612 oea_read, oea_write, oea_read, oea_write, \
613 one_reg_id, initial_value)
614 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
615 oea_read, oea_write, hea_read, hea_write, \
616 one_reg_id, initial_value) \
617 _spr_register(env, num, name, uea_read, uea_write, \
618 oea_read, oea_write, hea_read, hea_write, \
619 one_reg_id, initial_value)
623 #define spr_register(env, num, name, uea_read, uea_write, \
624 oea_read, oea_write, initial_value) \
625 spr_register_kvm(env, num, name, uea_read, uea_write, \
626 oea_read, oea_write, 0, initial_value)
628 #define spr_register_hv(env, num, name, uea_read, uea_write, \
629 oea_read, oea_write, hea_read, hea_write, \
631 spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
632 oea_read, oea_write, hea_read, hea_write, \
635 static inline void _spr_register(CPUPPCState
*env
, int num
,
637 void (*uea_read
)(DisasContext
*ctx
, int gprn
, int sprn
),
638 void (*uea_write
)(DisasContext
*ctx
, int sprn
, int gprn
),
639 #if !defined(CONFIG_USER_ONLY)
641 void (*oea_read
)(DisasContext
*ctx
, int gprn
, int sprn
),
642 void (*oea_write
)(DisasContext
*ctx
, int sprn
, int gprn
),
643 void (*hea_read
)(DisasContext
*opaque
, int gprn
, int sprn
),
644 void (*hea_write
)(DisasContext
*opaque
, int sprn
, int gprn
),
646 #if defined(CONFIG_KVM)
649 target_ulong initial_value
)
653 spr
= &env
->spr_cb
[num
];
654 if (spr
->name
!= NULL
||env
-> spr
[num
] != 0x00000000 ||
655 #if !defined(CONFIG_USER_ONLY)
656 spr
->oea_read
!= NULL
|| spr
->oea_write
!= NULL
||
658 spr
->uea_read
!= NULL
|| spr
->uea_write
!= NULL
) {
659 printf("Error: Trying to register SPR %d (%03x) twice !\n", num
, num
);
662 #if defined(PPC_DEBUG_SPR)
663 printf("*** register spr %d (%03x) %s val " TARGET_FMT_lx
"\n", num
, num
,
664 name
, initial_value
);
667 spr
->uea_read
= uea_read
;
668 spr
->uea_write
= uea_write
;
669 #if !defined(CONFIG_USER_ONLY)
670 spr
->oea_read
= oea_read
;
671 spr
->oea_write
= oea_write
;
672 spr
->hea_read
= hea_read
;
673 spr
->hea_write
= hea_write
;
675 #if defined(CONFIG_KVM)
676 spr
->one_reg_id
= one_reg_id
,
678 env
->spr
[num
] = spr
->default_value
= initial_value
;
681 /* Generic PowerPC SPRs */
682 static void gen_spr_generic (CPUPPCState
*env
)
684 /* Integer processing */
685 spr_register(env
, SPR_XER
, "XER",
686 &spr_read_xer
, &spr_write_xer
,
687 &spr_read_xer
, &spr_write_xer
,
690 spr_register(env
, SPR_LR
, "LR",
691 &spr_read_lr
, &spr_write_lr
,
692 &spr_read_lr
, &spr_write_lr
,
694 spr_register(env
, SPR_CTR
, "CTR",
695 &spr_read_ctr
, &spr_write_ctr
,
696 &spr_read_ctr
, &spr_write_ctr
,
698 /* Interrupt processing */
699 spr_register(env
, SPR_SRR0
, "SRR0",
700 SPR_NOACCESS
, SPR_NOACCESS
,
701 &spr_read_generic
, &spr_write_generic
,
703 spr_register(env
, SPR_SRR1
, "SRR1",
704 SPR_NOACCESS
, SPR_NOACCESS
,
705 &spr_read_generic
, &spr_write_generic
,
707 /* Processor control */
708 spr_register(env
, SPR_SPRG0
, "SPRG0",
709 SPR_NOACCESS
, SPR_NOACCESS
,
710 &spr_read_generic
, &spr_write_generic
,
712 spr_register(env
, SPR_SPRG1
, "SPRG1",
713 SPR_NOACCESS
, SPR_NOACCESS
,
714 &spr_read_generic
, &spr_write_generic
,
716 spr_register(env
, SPR_SPRG2
, "SPRG2",
717 SPR_NOACCESS
, SPR_NOACCESS
,
718 &spr_read_generic
, &spr_write_generic
,
720 spr_register(env
, SPR_SPRG3
, "SPRG3",
721 SPR_NOACCESS
, SPR_NOACCESS
,
722 &spr_read_generic
, &spr_write_generic
,
726 /* SPR common to all non-embedded PowerPC, including 601 */
727 static void gen_spr_ne_601(CPUPPCState
*env
)
729 /* Exception processing */
730 spr_register_kvm(env
, SPR_DSISR
, "DSISR",
731 SPR_NOACCESS
, SPR_NOACCESS
,
732 &spr_read_generic
, &spr_write_generic
,
733 KVM_REG_PPC_DSISR
, 0x00000000);
734 spr_register_kvm(env
, SPR_DAR
, "DAR",
735 SPR_NOACCESS
, SPR_NOACCESS
,
736 &spr_read_generic
, &spr_write_generic
,
737 KVM_REG_PPC_DAR
, 0x00000000);
739 spr_register(env
, SPR_DECR
, "DECR",
740 SPR_NOACCESS
, SPR_NOACCESS
,
741 &spr_read_decr
, &spr_write_decr
,
745 /* Storage Description Register 1 */
746 static void gen_spr_sdr1(CPUPPCState
*env
)
748 #ifndef CONFIG_USER_ONLY
749 if (env
->has_hv_mode
) {
750 /* SDR1 is a hypervisor resource on CPUs which have a
752 spr_register_hv(env
, SPR_SDR1
, "SDR1",
753 SPR_NOACCESS
, SPR_NOACCESS
,
754 SPR_NOACCESS
, SPR_NOACCESS
,
755 &spr_read_generic
, &spr_write_sdr1
,
758 spr_register(env
, SPR_SDR1
, "SDR1",
759 SPR_NOACCESS
, SPR_NOACCESS
,
760 &spr_read_generic
, &spr_write_sdr1
,
767 static void gen_low_BATs (CPUPPCState
*env
)
769 #if !defined(CONFIG_USER_ONLY)
770 spr_register(env
, SPR_IBAT0U
, "IBAT0U",
771 SPR_NOACCESS
, SPR_NOACCESS
,
772 &spr_read_ibat
, &spr_write_ibatu
,
774 spr_register(env
, SPR_IBAT0L
, "IBAT0L",
775 SPR_NOACCESS
, SPR_NOACCESS
,
776 &spr_read_ibat
, &spr_write_ibatl
,
778 spr_register(env
, SPR_IBAT1U
, "IBAT1U",
779 SPR_NOACCESS
, SPR_NOACCESS
,
780 &spr_read_ibat
, &spr_write_ibatu
,
782 spr_register(env
, SPR_IBAT1L
, "IBAT1L",
783 SPR_NOACCESS
, SPR_NOACCESS
,
784 &spr_read_ibat
, &spr_write_ibatl
,
786 spr_register(env
, SPR_IBAT2U
, "IBAT2U",
787 SPR_NOACCESS
, SPR_NOACCESS
,
788 &spr_read_ibat
, &spr_write_ibatu
,
790 spr_register(env
, SPR_IBAT2L
, "IBAT2L",
791 SPR_NOACCESS
, SPR_NOACCESS
,
792 &spr_read_ibat
, &spr_write_ibatl
,
794 spr_register(env
, SPR_IBAT3U
, "IBAT3U",
795 SPR_NOACCESS
, SPR_NOACCESS
,
796 &spr_read_ibat
, &spr_write_ibatu
,
798 spr_register(env
, SPR_IBAT3L
, "IBAT3L",
799 SPR_NOACCESS
, SPR_NOACCESS
,
800 &spr_read_ibat
, &spr_write_ibatl
,
802 spr_register(env
, SPR_DBAT0U
, "DBAT0U",
803 SPR_NOACCESS
, SPR_NOACCESS
,
804 &spr_read_dbat
, &spr_write_dbatu
,
806 spr_register(env
, SPR_DBAT0L
, "DBAT0L",
807 SPR_NOACCESS
, SPR_NOACCESS
,
808 &spr_read_dbat
, &spr_write_dbatl
,
810 spr_register(env
, SPR_DBAT1U
, "DBAT1U",
811 SPR_NOACCESS
, SPR_NOACCESS
,
812 &spr_read_dbat
, &spr_write_dbatu
,
814 spr_register(env
, SPR_DBAT1L
, "DBAT1L",
815 SPR_NOACCESS
, SPR_NOACCESS
,
816 &spr_read_dbat
, &spr_write_dbatl
,
818 spr_register(env
, SPR_DBAT2U
, "DBAT2U",
819 SPR_NOACCESS
, SPR_NOACCESS
,
820 &spr_read_dbat
, &spr_write_dbatu
,
822 spr_register(env
, SPR_DBAT2L
, "DBAT2L",
823 SPR_NOACCESS
, SPR_NOACCESS
,
824 &spr_read_dbat
, &spr_write_dbatl
,
826 spr_register(env
, SPR_DBAT3U
, "DBAT3U",
827 SPR_NOACCESS
, SPR_NOACCESS
,
828 &spr_read_dbat
, &spr_write_dbatu
,
830 spr_register(env
, SPR_DBAT3L
, "DBAT3L",
831 SPR_NOACCESS
, SPR_NOACCESS
,
832 &spr_read_dbat
, &spr_write_dbatl
,
839 static void gen_high_BATs (CPUPPCState
*env
)
841 #if !defined(CONFIG_USER_ONLY)
842 spr_register(env
, SPR_IBAT4U
, "IBAT4U",
843 SPR_NOACCESS
, SPR_NOACCESS
,
844 &spr_read_ibat_h
, &spr_write_ibatu_h
,
846 spr_register(env
, SPR_IBAT4L
, "IBAT4L",
847 SPR_NOACCESS
, SPR_NOACCESS
,
848 &spr_read_ibat_h
, &spr_write_ibatl_h
,
850 spr_register(env
, SPR_IBAT5U
, "IBAT5U",
851 SPR_NOACCESS
, SPR_NOACCESS
,
852 &spr_read_ibat_h
, &spr_write_ibatu_h
,
854 spr_register(env
, SPR_IBAT5L
, "IBAT5L",
855 SPR_NOACCESS
, SPR_NOACCESS
,
856 &spr_read_ibat_h
, &spr_write_ibatl_h
,
858 spr_register(env
, SPR_IBAT6U
, "IBAT6U",
859 SPR_NOACCESS
, SPR_NOACCESS
,
860 &spr_read_ibat_h
, &spr_write_ibatu_h
,
862 spr_register(env
, SPR_IBAT6L
, "IBAT6L",
863 SPR_NOACCESS
, SPR_NOACCESS
,
864 &spr_read_ibat_h
, &spr_write_ibatl_h
,
866 spr_register(env
, SPR_IBAT7U
, "IBAT7U",
867 SPR_NOACCESS
, SPR_NOACCESS
,
868 &spr_read_ibat_h
, &spr_write_ibatu_h
,
870 spr_register(env
, SPR_IBAT7L
, "IBAT7L",
871 SPR_NOACCESS
, SPR_NOACCESS
,
872 &spr_read_ibat_h
, &spr_write_ibatl_h
,
874 spr_register(env
, SPR_DBAT4U
, "DBAT4U",
875 SPR_NOACCESS
, SPR_NOACCESS
,
876 &spr_read_dbat_h
, &spr_write_dbatu_h
,
878 spr_register(env
, SPR_DBAT4L
, "DBAT4L",
879 SPR_NOACCESS
, SPR_NOACCESS
,
880 &spr_read_dbat_h
, &spr_write_dbatl_h
,
882 spr_register(env
, SPR_DBAT5U
, "DBAT5U",
883 SPR_NOACCESS
, SPR_NOACCESS
,
884 &spr_read_dbat_h
, &spr_write_dbatu_h
,
886 spr_register(env
, SPR_DBAT5L
, "DBAT5L",
887 SPR_NOACCESS
, SPR_NOACCESS
,
888 &spr_read_dbat_h
, &spr_write_dbatl_h
,
890 spr_register(env
, SPR_DBAT6U
, "DBAT6U",
891 SPR_NOACCESS
, SPR_NOACCESS
,
892 &spr_read_dbat_h
, &spr_write_dbatu_h
,
894 spr_register(env
, SPR_DBAT6L
, "DBAT6L",
895 SPR_NOACCESS
, SPR_NOACCESS
,
896 &spr_read_dbat_h
, &spr_write_dbatl_h
,
898 spr_register(env
, SPR_DBAT7U
, "DBAT7U",
899 SPR_NOACCESS
, SPR_NOACCESS
,
900 &spr_read_dbat_h
, &spr_write_dbatu_h
,
902 spr_register(env
, SPR_DBAT7L
, "DBAT7L",
903 SPR_NOACCESS
, SPR_NOACCESS
,
904 &spr_read_dbat_h
, &spr_write_dbatl_h
,
910 /* Generic PowerPC time base */
911 static void gen_tbl (CPUPPCState
*env
)
913 spr_register(env
, SPR_VTBL
, "TBL",
914 &spr_read_tbl
, SPR_NOACCESS
,
915 &spr_read_tbl
, SPR_NOACCESS
,
917 spr_register(env
, SPR_TBL
, "TBL",
918 &spr_read_tbl
, SPR_NOACCESS
,
919 &spr_read_tbl
, &spr_write_tbl
,
921 spr_register(env
, SPR_VTBU
, "TBU",
922 &spr_read_tbu
, SPR_NOACCESS
,
923 &spr_read_tbu
, SPR_NOACCESS
,
925 spr_register(env
, SPR_TBU
, "TBU",
926 &spr_read_tbu
, SPR_NOACCESS
,
927 &spr_read_tbu
, &spr_write_tbu
,
931 /* Softare table search registers */
932 static void gen_6xx_7xx_soft_tlb (CPUPPCState
*env
, int nb_tlbs
, int nb_ways
)
934 #if !defined(CONFIG_USER_ONLY)
935 env
->nb_tlb
= nb_tlbs
;
936 env
->nb_ways
= nb_ways
;
938 env
->tlb_type
= TLB_6XX
;
939 spr_register(env
, SPR_DMISS
, "DMISS",
940 SPR_NOACCESS
, SPR_NOACCESS
,
941 &spr_read_generic
, SPR_NOACCESS
,
943 spr_register(env
, SPR_DCMP
, "DCMP",
944 SPR_NOACCESS
, SPR_NOACCESS
,
945 &spr_read_generic
, SPR_NOACCESS
,
947 spr_register(env
, SPR_HASH1
, "HASH1",
948 SPR_NOACCESS
, SPR_NOACCESS
,
949 &spr_read_generic
, SPR_NOACCESS
,
951 spr_register(env
, SPR_HASH2
, "HASH2",
952 SPR_NOACCESS
, SPR_NOACCESS
,
953 &spr_read_generic
, SPR_NOACCESS
,
955 spr_register(env
, SPR_IMISS
, "IMISS",
956 SPR_NOACCESS
, SPR_NOACCESS
,
957 &spr_read_generic
, SPR_NOACCESS
,
959 spr_register(env
, SPR_ICMP
, "ICMP",
960 SPR_NOACCESS
, SPR_NOACCESS
,
961 &spr_read_generic
, SPR_NOACCESS
,
963 spr_register(env
, SPR_RPA
, "RPA",
964 SPR_NOACCESS
, SPR_NOACCESS
,
965 &spr_read_generic
, &spr_write_generic
,
970 /* SPR common to MPC755 and G2 */
971 static void gen_spr_G2_755 (CPUPPCState
*env
)
974 spr_register(env
, SPR_SPRG4
, "SPRG4",
975 SPR_NOACCESS
, SPR_NOACCESS
,
976 &spr_read_generic
, &spr_write_generic
,
978 spr_register(env
, SPR_SPRG5
, "SPRG5",
979 SPR_NOACCESS
, SPR_NOACCESS
,
980 &spr_read_generic
, &spr_write_generic
,
982 spr_register(env
, SPR_SPRG6
, "SPRG6",
983 SPR_NOACCESS
, SPR_NOACCESS
,
984 &spr_read_generic
, &spr_write_generic
,
986 spr_register(env
, SPR_SPRG7
, "SPRG7",
987 SPR_NOACCESS
, SPR_NOACCESS
,
988 &spr_read_generic
, &spr_write_generic
,
992 /* SPR common to all 7xx PowerPC implementations */
993 static void gen_spr_7xx (CPUPPCState
*env
)
996 /* XXX : not implemented */
997 spr_register_kvm(env
, SPR_DABR
, "DABR",
998 SPR_NOACCESS
, SPR_NOACCESS
,
999 &spr_read_generic
, &spr_write_generic
,
1000 KVM_REG_PPC_DABR
, 0x00000000);
1001 /* XXX : not implemented */
1002 spr_register(env
, SPR_IABR
, "IABR",
1003 SPR_NOACCESS
, SPR_NOACCESS
,
1004 &spr_read_generic
, &spr_write_generic
,
1006 /* Cache management */
1007 /* XXX : not implemented */
1008 spr_register(env
, SPR_ICTC
, "ICTC",
1009 SPR_NOACCESS
, SPR_NOACCESS
,
1010 &spr_read_generic
, &spr_write_generic
,
1012 /* Performance monitors */
1013 /* XXX : not implemented */
1014 spr_register(env
, SPR_7XX_MMCR0
, "MMCR0",
1015 SPR_NOACCESS
, SPR_NOACCESS
,
1016 &spr_read_generic
, &spr_write_generic
,
1018 /* XXX : not implemented */
1019 spr_register(env
, SPR_7XX_MMCR1
, "MMCR1",
1020 SPR_NOACCESS
, SPR_NOACCESS
,
1021 &spr_read_generic
, &spr_write_generic
,
1023 /* XXX : not implemented */
1024 spr_register(env
, SPR_7XX_PMC1
, "PMC1",
1025 SPR_NOACCESS
, SPR_NOACCESS
,
1026 &spr_read_generic
, &spr_write_generic
,
1028 /* XXX : not implemented */
1029 spr_register(env
, SPR_7XX_PMC2
, "PMC2",
1030 SPR_NOACCESS
, SPR_NOACCESS
,
1031 &spr_read_generic
, &spr_write_generic
,
1033 /* XXX : not implemented */
1034 spr_register(env
, SPR_7XX_PMC3
, "PMC3",
1035 SPR_NOACCESS
, SPR_NOACCESS
,
1036 &spr_read_generic
, &spr_write_generic
,
1038 /* XXX : not implemented */
1039 spr_register(env
, SPR_7XX_PMC4
, "PMC4",
1040 SPR_NOACCESS
, SPR_NOACCESS
,
1041 &spr_read_generic
, &spr_write_generic
,
1043 /* XXX : not implemented */
1044 spr_register(env
, SPR_7XX_SIAR
, "SIAR",
1045 SPR_NOACCESS
, SPR_NOACCESS
,
1046 &spr_read_generic
, SPR_NOACCESS
,
1048 /* XXX : not implemented */
1049 spr_register(env
, SPR_7XX_UMMCR0
, "UMMCR0",
1050 &spr_read_ureg
, SPR_NOACCESS
,
1051 &spr_read_ureg
, SPR_NOACCESS
,
1053 /* XXX : not implemented */
1054 spr_register(env
, SPR_7XX_UMMCR1
, "UMMCR1",
1055 &spr_read_ureg
, SPR_NOACCESS
,
1056 &spr_read_ureg
, SPR_NOACCESS
,
1058 /* XXX : not implemented */
1059 spr_register(env
, SPR_7XX_UPMC1
, "UPMC1",
1060 &spr_read_ureg
, SPR_NOACCESS
,
1061 &spr_read_ureg
, SPR_NOACCESS
,
1063 /* XXX : not implemented */
1064 spr_register(env
, SPR_7XX_UPMC2
, "UPMC2",
1065 &spr_read_ureg
, SPR_NOACCESS
,
1066 &spr_read_ureg
, SPR_NOACCESS
,
1068 /* XXX : not implemented */
1069 spr_register(env
, SPR_7XX_UPMC3
, "UPMC3",
1070 &spr_read_ureg
, SPR_NOACCESS
,
1071 &spr_read_ureg
, SPR_NOACCESS
,
1073 /* XXX : not implemented */
1074 spr_register(env
, SPR_7XX_UPMC4
, "UPMC4",
1075 &spr_read_ureg
, SPR_NOACCESS
,
1076 &spr_read_ureg
, SPR_NOACCESS
,
1078 /* XXX : not implemented */
1079 spr_register(env
, SPR_7XX_USIAR
, "USIAR",
1080 &spr_read_ureg
, SPR_NOACCESS
,
1081 &spr_read_ureg
, SPR_NOACCESS
,
1083 /* External access control */
1084 /* XXX : not implemented */
1085 spr_register(env
, SPR_EAR
, "EAR",
1086 SPR_NOACCESS
, SPR_NOACCESS
,
1087 &spr_read_generic
, &spr_write_generic
,
1092 #ifndef CONFIG_USER_ONLY
1093 static void spr_write_amr(DisasContext
*ctx
, int sprn
, int gprn
)
1095 TCGv t0
= tcg_temp_new();
1096 TCGv t1
= tcg_temp_new();
1097 TCGv t2
= tcg_temp_new();
1099 /* Note, the HV=1 PR=0 case is handled earlier by simply using
1100 * spr_write_generic for HV mode in the SPR table
1103 /* Build insertion mask into t1 based on context */
1105 gen_load_spr(t1
, SPR_UAMOR
);
1107 gen_load_spr(t1
, SPR_AMOR
);
1110 /* Mask new bits into t2 */
1111 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1113 /* Load AMR and clear new bits in t0 */
1114 gen_load_spr(t0
, SPR_AMR
);
1115 tcg_gen_andc_tl(t0
, t0
, t1
);
1117 /* Or'in new bits and write it out */
1118 tcg_gen_or_tl(t0
, t0
, t2
);
1119 gen_store_spr(SPR_AMR
, t0
);
1120 spr_store_dump_spr(SPR_AMR
);
1127 static void spr_write_uamor(DisasContext
*ctx
, int sprn
, int gprn
)
1129 TCGv t0
= tcg_temp_new();
1130 TCGv t1
= tcg_temp_new();
1131 TCGv t2
= tcg_temp_new();
1133 /* Note, the HV=1 case is handled earlier by simply using
1134 * spr_write_generic for HV mode in the SPR table
1137 /* Build insertion mask into t1 based on context */
1138 gen_load_spr(t1
, SPR_AMOR
);
1140 /* Mask new bits into t2 */
1141 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1143 /* Load AMR and clear new bits in t0 */
1144 gen_load_spr(t0
, SPR_UAMOR
);
1145 tcg_gen_andc_tl(t0
, t0
, t1
);
1147 /* Or'in new bits and write it out */
1148 tcg_gen_or_tl(t0
, t0
, t2
);
1149 gen_store_spr(SPR_UAMOR
, t0
);
1150 spr_store_dump_spr(SPR_UAMOR
);
1157 static void spr_write_iamr(DisasContext
*ctx
, int sprn
, int gprn
)
1159 TCGv t0
= tcg_temp_new();
1160 TCGv t1
= tcg_temp_new();
1161 TCGv t2
= tcg_temp_new();
1163 /* Note, the HV=1 case is handled earlier by simply using
1164 * spr_write_generic for HV mode in the SPR table
1167 /* Build insertion mask into t1 based on context */
1168 gen_load_spr(t1
, SPR_AMOR
);
1170 /* Mask new bits into t2 */
1171 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1173 /* Load AMR and clear new bits in t0 */
1174 gen_load_spr(t0
, SPR_IAMR
);
1175 tcg_gen_andc_tl(t0
, t0
, t1
);
1177 /* Or'in new bits and write it out */
1178 tcg_gen_or_tl(t0
, t0
, t2
);
1179 gen_store_spr(SPR_IAMR
, t0
);
1180 spr_store_dump_spr(SPR_IAMR
);
1186 #endif /* CONFIG_USER_ONLY */
1188 static void gen_spr_amr(CPUPPCState
*env
)
1190 #ifndef CONFIG_USER_ONLY
1191 /* Virtual Page Class Key protection */
1192 /* The AMR is accessible either via SPR 13 or SPR 29. 13 is
1193 * userspace accessible, 29 is privileged. So we only need to set
1194 * the kvm ONE_REG id on one of them, we use 29 */
1195 spr_register(env
, SPR_UAMR
, "UAMR",
1196 &spr_read_generic
, &spr_write_amr
,
1197 &spr_read_generic
, &spr_write_amr
,
1199 spr_register_kvm_hv(env
, SPR_AMR
, "AMR",
1200 SPR_NOACCESS
, SPR_NOACCESS
,
1201 &spr_read_generic
, &spr_write_amr
,
1202 &spr_read_generic
, &spr_write_generic
,
1203 KVM_REG_PPC_AMR
, 0);
1204 spr_register_kvm_hv(env
, SPR_UAMOR
, "UAMOR",
1205 SPR_NOACCESS
, SPR_NOACCESS
,
1206 &spr_read_generic
, &spr_write_uamor
,
1207 &spr_read_generic
, &spr_write_generic
,
1208 KVM_REG_PPC_UAMOR
, 0);
1209 spr_register_hv(env
, SPR_AMOR
, "AMOR",
1210 SPR_NOACCESS
, SPR_NOACCESS
,
1211 SPR_NOACCESS
, SPR_NOACCESS
,
1212 &spr_read_generic
, &spr_write_generic
,
1214 #endif /* !CONFIG_USER_ONLY */
1217 static void gen_spr_iamr(CPUPPCState
*env
)
1219 #ifndef CONFIG_USER_ONLY
1220 spr_register_kvm_hv(env
, SPR_IAMR
, "IAMR",
1221 SPR_NOACCESS
, SPR_NOACCESS
,
1222 &spr_read_generic
, &spr_write_iamr
,
1223 &spr_read_generic
, &spr_write_generic
,
1224 KVM_REG_PPC_IAMR
, 0);
1225 #endif /* !CONFIG_USER_ONLY */
1227 #endif /* TARGET_PPC64 */
1229 #ifndef CONFIG_USER_ONLY
1230 static void spr_read_thrm(DisasContext
*ctx
, int gprn
, int sprn
)
1232 gen_helper_fixup_thrm(cpu_env
);
1233 gen_load_spr(cpu_gpr
[gprn
], sprn
);
1234 spr_load_dump_spr(sprn
);
1236 #endif /* !CONFIG_USER_ONLY */
1238 static void gen_spr_thrm (CPUPPCState
*env
)
1240 /* Thermal management */
1241 /* XXX : not implemented */
1242 spr_register(env
, SPR_THRM1
, "THRM1",
1243 SPR_NOACCESS
, SPR_NOACCESS
,
1244 &spr_read_thrm
, &spr_write_generic
,
1246 /* XXX : not implemented */
1247 spr_register(env
, SPR_THRM2
, "THRM2",
1248 SPR_NOACCESS
, SPR_NOACCESS
,
1249 &spr_read_thrm
, &spr_write_generic
,
1251 /* XXX : not implemented */
1252 spr_register(env
, SPR_THRM3
, "THRM3",
1253 SPR_NOACCESS
, SPR_NOACCESS
,
1254 &spr_read_thrm
, &spr_write_generic
,
1258 /* SPR specific to PowerPC 604 implementation */
1259 static void gen_spr_604 (CPUPPCState
*env
)
1261 /* Processor identification */
1262 spr_register(env
, SPR_PIR
, "PIR",
1263 SPR_NOACCESS
, SPR_NOACCESS
,
1264 &spr_read_generic
, &spr_write_pir
,
1267 /* XXX : not implemented */
1268 spr_register(env
, SPR_IABR
, "IABR",
1269 SPR_NOACCESS
, SPR_NOACCESS
,
1270 &spr_read_generic
, &spr_write_generic
,
1272 /* XXX : not implemented */
1273 spr_register_kvm(env
, SPR_DABR
, "DABR",
1274 SPR_NOACCESS
, SPR_NOACCESS
,
1275 &spr_read_generic
, &spr_write_generic
,
1276 KVM_REG_PPC_DABR
, 0x00000000);
1277 /* Performance counters */
1278 /* XXX : not implemented */
1279 spr_register(env
, SPR_7XX_MMCR0
, "MMCR0",
1280 SPR_NOACCESS
, SPR_NOACCESS
,
1281 &spr_read_generic
, &spr_write_generic
,
1283 /* XXX : not implemented */
1284 spr_register(env
, SPR_7XX_PMC1
, "PMC1",
1285 SPR_NOACCESS
, SPR_NOACCESS
,
1286 &spr_read_generic
, &spr_write_generic
,
1288 /* XXX : not implemented */
1289 spr_register(env
, SPR_7XX_PMC2
, "PMC2",
1290 SPR_NOACCESS
, SPR_NOACCESS
,
1291 &spr_read_generic
, &spr_write_generic
,
1293 /* XXX : not implemented */
1294 spr_register(env
, SPR_7XX_SIAR
, "SIAR",
1295 SPR_NOACCESS
, SPR_NOACCESS
,
1296 &spr_read_generic
, SPR_NOACCESS
,
1298 /* XXX : not implemented */
1299 spr_register(env
, SPR_SDA
, "SDA",
1300 SPR_NOACCESS
, SPR_NOACCESS
,
1301 &spr_read_generic
, SPR_NOACCESS
,
1303 /* External access control */
1304 /* XXX : not implemented */
1305 spr_register(env
, SPR_EAR
, "EAR",
1306 SPR_NOACCESS
, SPR_NOACCESS
,
1307 &spr_read_generic
, &spr_write_generic
,
1311 /* SPR specific to PowerPC 603 implementation */
1312 static void gen_spr_603 (CPUPPCState
*env
)
1314 /* External access control */
1315 /* XXX : not implemented */
1316 spr_register(env
, SPR_EAR
, "EAR",
1317 SPR_NOACCESS
, SPR_NOACCESS
,
1318 &spr_read_generic
, &spr_write_generic
,
1321 /* XXX : not implemented */
1322 spr_register(env
, SPR_IABR
, "IABR",
1323 SPR_NOACCESS
, SPR_NOACCESS
,
1324 &spr_read_generic
, &spr_write_generic
,
1329 /* SPR specific to PowerPC G2 implementation */
1330 static void gen_spr_G2 (CPUPPCState
*env
)
1332 /* Memory base address */
1334 /* XXX : not implemented */
1335 spr_register(env
, SPR_MBAR
, "MBAR",
1336 SPR_NOACCESS
, SPR_NOACCESS
,
1337 &spr_read_generic
, &spr_write_generic
,
1339 /* Exception processing */
1340 spr_register(env
, SPR_BOOKE_CSRR0
, "CSRR0",
1341 SPR_NOACCESS
, SPR_NOACCESS
,
1342 &spr_read_generic
, &spr_write_generic
,
1344 spr_register(env
, SPR_BOOKE_CSRR1
, "CSRR1",
1345 SPR_NOACCESS
, SPR_NOACCESS
,
1346 &spr_read_generic
, &spr_write_generic
,
1349 /* XXX : not implemented */
1350 spr_register(env
, SPR_DABR
, "DABR",
1351 SPR_NOACCESS
, SPR_NOACCESS
,
1352 &spr_read_generic
, &spr_write_generic
,
1354 /* XXX : not implemented */
1355 spr_register(env
, SPR_DABR2
, "DABR2",
1356 SPR_NOACCESS
, SPR_NOACCESS
,
1357 &spr_read_generic
, &spr_write_generic
,
1359 /* XXX : not implemented */
1360 spr_register(env
, SPR_IABR
, "IABR",
1361 SPR_NOACCESS
, SPR_NOACCESS
,
1362 &spr_read_generic
, &spr_write_generic
,
1364 /* XXX : not implemented */
1365 spr_register(env
, SPR_IABR2
, "IABR2",
1366 SPR_NOACCESS
, SPR_NOACCESS
,
1367 &spr_read_generic
, &spr_write_generic
,
1369 /* XXX : not implemented */
1370 spr_register(env
, SPR_IBCR
, "IBCR",
1371 SPR_NOACCESS
, SPR_NOACCESS
,
1372 &spr_read_generic
, &spr_write_generic
,
1374 /* XXX : not implemented */
1375 spr_register(env
, SPR_DBCR
, "DBCR",
1376 SPR_NOACCESS
, SPR_NOACCESS
,
1377 &spr_read_generic
, &spr_write_generic
,
1381 /* SPR specific to PowerPC 602 implementation */
1382 static void gen_spr_602 (CPUPPCState
*env
)
1385 /* XXX : not implemented */
1386 spr_register(env
, SPR_SER
, "SER",
1387 SPR_NOACCESS
, SPR_NOACCESS
,
1388 &spr_read_generic
, &spr_write_generic
,
1390 /* XXX : not implemented */
1391 spr_register(env
, SPR_SEBR
, "SEBR",
1392 SPR_NOACCESS
, SPR_NOACCESS
,
1393 &spr_read_generic
, &spr_write_generic
,
1395 /* XXX : not implemented */
1396 spr_register(env
, SPR_ESASRR
, "ESASRR",
1397 SPR_NOACCESS
, SPR_NOACCESS
,
1398 &spr_read_generic
, &spr_write_generic
,
1400 /* Floating point status */
1401 /* XXX : not implemented */
1402 spr_register(env
, SPR_SP
, "SP",
1403 SPR_NOACCESS
, SPR_NOACCESS
,
1404 &spr_read_generic
, &spr_write_generic
,
1406 /* XXX : not implemented */
1407 spr_register(env
, SPR_LT
, "LT",
1408 SPR_NOACCESS
, SPR_NOACCESS
,
1409 &spr_read_generic
, &spr_write_generic
,
1411 /* Watchdog timer */
1412 /* XXX : not implemented */
1413 spr_register(env
, SPR_TCR
, "TCR",
1414 SPR_NOACCESS
, SPR_NOACCESS
,
1415 &spr_read_generic
, &spr_write_generic
,
1417 /* Interrupt base */
1418 spr_register(env
, SPR_IBR
, "IBR",
1419 SPR_NOACCESS
, SPR_NOACCESS
,
1420 &spr_read_generic
, &spr_write_generic
,
1422 /* XXX : not implemented */
1423 spr_register(env
, SPR_IABR
, "IABR",
1424 SPR_NOACCESS
, SPR_NOACCESS
,
1425 &spr_read_generic
, &spr_write_generic
,
1429 /* SPR specific to PowerPC 601 implementation */
1430 static void gen_spr_601 (CPUPPCState
*env
)
1432 /* Multiplication/division register */
1434 spr_register(env
, SPR_MQ
, "MQ",
1435 &spr_read_generic
, &spr_write_generic
,
1436 &spr_read_generic
, &spr_write_generic
,
1439 spr_register(env
, SPR_601_RTCU
, "RTCU",
1440 SPR_NOACCESS
, SPR_NOACCESS
,
1441 SPR_NOACCESS
, &spr_write_601_rtcu
,
1443 spr_register(env
, SPR_601_VRTCU
, "RTCU",
1444 &spr_read_601_rtcu
, SPR_NOACCESS
,
1445 &spr_read_601_rtcu
, SPR_NOACCESS
,
1447 spr_register(env
, SPR_601_RTCL
, "RTCL",
1448 SPR_NOACCESS
, SPR_NOACCESS
,
1449 SPR_NOACCESS
, &spr_write_601_rtcl
,
1451 spr_register(env
, SPR_601_VRTCL
, "RTCL",
1452 &spr_read_601_rtcl
, SPR_NOACCESS
,
1453 &spr_read_601_rtcl
, SPR_NOACCESS
,
1457 spr_register(env
, SPR_601_UDECR
, "UDECR",
1458 &spr_read_decr
, SPR_NOACCESS
,
1459 &spr_read_decr
, SPR_NOACCESS
,
1462 /* External access control */
1463 /* XXX : not implemented */
1464 spr_register(env
, SPR_EAR
, "EAR",
1465 SPR_NOACCESS
, SPR_NOACCESS
,
1466 &spr_read_generic
, &spr_write_generic
,
1468 /* Memory management */
1469 #if !defined(CONFIG_USER_ONLY)
1470 spr_register(env
, SPR_IBAT0U
, "IBAT0U",
1471 SPR_NOACCESS
, SPR_NOACCESS
,
1472 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1474 spr_register(env
, SPR_IBAT0L
, "IBAT0L",
1475 SPR_NOACCESS
, SPR_NOACCESS
,
1476 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1478 spr_register(env
, SPR_IBAT1U
, "IBAT1U",
1479 SPR_NOACCESS
, SPR_NOACCESS
,
1480 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1482 spr_register(env
, SPR_IBAT1L
, "IBAT1L",
1483 SPR_NOACCESS
, SPR_NOACCESS
,
1484 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1486 spr_register(env
, SPR_IBAT2U
, "IBAT2U",
1487 SPR_NOACCESS
, SPR_NOACCESS
,
1488 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1490 spr_register(env
, SPR_IBAT2L
, "IBAT2L",
1491 SPR_NOACCESS
, SPR_NOACCESS
,
1492 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1494 spr_register(env
, SPR_IBAT3U
, "IBAT3U",
1495 SPR_NOACCESS
, SPR_NOACCESS
,
1496 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1498 spr_register(env
, SPR_IBAT3L
, "IBAT3L",
1499 SPR_NOACCESS
, SPR_NOACCESS
,
1500 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1506 static void gen_spr_74xx (CPUPPCState
*env
)
1508 /* Processor identification */
1509 spr_register(env
, SPR_PIR
, "PIR",
1510 SPR_NOACCESS
, SPR_NOACCESS
,
1511 &spr_read_generic
, &spr_write_pir
,
1513 /* XXX : not implemented */
1514 spr_register(env
, SPR_74XX_MMCR2
, "MMCR2",
1515 SPR_NOACCESS
, SPR_NOACCESS
,
1516 &spr_read_generic
, &spr_write_generic
,
1518 /* XXX : not implemented */
1519 spr_register(env
, SPR_74XX_UMMCR2
, "UMMCR2",
1520 &spr_read_ureg
, SPR_NOACCESS
,
1521 &spr_read_ureg
, SPR_NOACCESS
,
1523 /* XXX: not implemented */
1524 spr_register(env
, SPR_BAMR
, "BAMR",
1525 SPR_NOACCESS
, SPR_NOACCESS
,
1526 &spr_read_generic
, &spr_write_generic
,
1528 /* XXX : not implemented */
1529 spr_register(env
, SPR_MSSCR0
, "MSSCR0",
1530 SPR_NOACCESS
, SPR_NOACCESS
,
1531 &spr_read_generic
, &spr_write_generic
,
1533 /* Hardware implementation registers */
1534 /* XXX : not implemented */
1535 spr_register(env
, SPR_HID0
, "HID0",
1536 SPR_NOACCESS
, SPR_NOACCESS
,
1537 &spr_read_generic
, &spr_write_generic
,
1539 /* XXX : not implemented */
1540 spr_register(env
, SPR_HID1
, "HID1",
1541 SPR_NOACCESS
, SPR_NOACCESS
,
1542 &spr_read_generic
, &spr_write_generic
,
1545 spr_register(env
, SPR_VRSAVE
, "VRSAVE",
1546 &spr_read_generic
, &spr_write_generic
,
1547 &spr_read_generic
, &spr_write_generic
,
1549 /* XXX : not implemented */
1550 spr_register(env
, SPR_L2CR
, "L2CR",
1551 SPR_NOACCESS
, SPR_NOACCESS
,
1552 &spr_read_generic
, spr_access_nop
,
1554 /* Not strictly an SPR */
1555 vscr_init(env
, 0x00010000);
1558 static void gen_l3_ctrl (CPUPPCState
*env
)
1561 /* XXX : not implemented */
1562 spr_register(env
, SPR_L3CR
, "L3CR",
1563 SPR_NOACCESS
, SPR_NOACCESS
,
1564 &spr_read_generic
, &spr_write_generic
,
1567 /* XXX : not implemented */
1568 spr_register(env
, SPR_L3ITCR0
, "L3ITCR0",
1569 SPR_NOACCESS
, SPR_NOACCESS
,
1570 &spr_read_generic
, &spr_write_generic
,
1573 /* XXX : not implemented */
1574 spr_register(env
, SPR_L3PM
, "L3PM",
1575 SPR_NOACCESS
, SPR_NOACCESS
,
1576 &spr_read_generic
, &spr_write_generic
,
1580 static void gen_74xx_soft_tlb (CPUPPCState
*env
, int nb_tlbs
, int nb_ways
)
1582 #if !defined(CONFIG_USER_ONLY)
1583 env
->nb_tlb
= nb_tlbs
;
1584 env
->nb_ways
= nb_ways
;
1586 env
->tlb_type
= TLB_6XX
;
1587 /* XXX : not implemented */
1588 spr_register(env
, SPR_PTEHI
, "PTEHI",
1589 SPR_NOACCESS
, SPR_NOACCESS
,
1590 &spr_read_generic
, &spr_write_generic
,
1592 /* XXX : not implemented */
1593 spr_register(env
, SPR_PTELO
, "PTELO",
1594 SPR_NOACCESS
, SPR_NOACCESS
,
1595 &spr_read_generic
, &spr_write_generic
,
1597 /* XXX : not implemented */
1598 spr_register(env
, SPR_TLBMISS
, "TLBMISS",
1599 SPR_NOACCESS
, SPR_NOACCESS
,
1600 &spr_read_generic
, &spr_write_generic
,
1605 #if !defined(CONFIG_USER_ONLY)
1606 static void spr_write_e500_l1csr0 (DisasContext
*ctx
, int sprn
, int gprn
)
1608 TCGv t0
= tcg_temp_new();
1610 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], L1CSR0_DCE
| L1CSR0_CPE
);
1611 gen_store_spr(sprn
, t0
);
1615 static void spr_write_e500_l1csr1(DisasContext
*ctx
, int sprn
, int gprn
)
1617 TCGv t0
= tcg_temp_new();
1619 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], L1CSR1_ICE
| L1CSR1_CPE
);
1620 gen_store_spr(sprn
, t0
);
1624 static void spr_write_booke206_mmucsr0 (DisasContext
*ctx
, int sprn
, int gprn
)
1626 gen_helper_booke206_tlbflush(cpu_env
, cpu_gpr
[gprn
]);
1629 static void spr_write_booke_pid (DisasContext
*ctx
, int sprn
, int gprn
)
1631 TCGv_i32 t0
= tcg_const_i32(sprn
);
1632 gen_helper_booke_setpid(cpu_env
, t0
, cpu_gpr
[gprn
]);
1633 tcg_temp_free_i32(t0
);
1637 static void gen_spr_usprgh (CPUPPCState
*env
)
1639 spr_register(env
, SPR_USPRG4
, "USPRG4",
1640 &spr_read_ureg
, SPR_NOACCESS
,
1641 &spr_read_ureg
, SPR_NOACCESS
,
1643 spr_register(env
, SPR_USPRG5
, "USPRG5",
1644 &spr_read_ureg
, SPR_NOACCESS
,
1645 &spr_read_ureg
, SPR_NOACCESS
,
1647 spr_register(env
, SPR_USPRG6
, "USPRG6",
1648 &spr_read_ureg
, SPR_NOACCESS
,
1649 &spr_read_ureg
, SPR_NOACCESS
,
1651 spr_register(env
, SPR_USPRG7
, "USPRG7",
1652 &spr_read_ureg
, SPR_NOACCESS
,
1653 &spr_read_ureg
, SPR_NOACCESS
,
1657 /* PowerPC BookE SPR */
1658 static void gen_spr_BookE (CPUPPCState
*env
, uint64_t ivor_mask
)
1660 const char *ivor_names
[64] = {
1661 "IVOR0", "IVOR1", "IVOR2", "IVOR3",
1662 "IVOR4", "IVOR5", "IVOR6", "IVOR7",
1663 "IVOR8", "IVOR9", "IVOR10", "IVOR11",
1664 "IVOR12", "IVOR13", "IVOR14", "IVOR15",
1665 "IVOR16", "IVOR17", "IVOR18", "IVOR19",
1666 "IVOR20", "IVOR21", "IVOR22", "IVOR23",
1667 "IVOR24", "IVOR25", "IVOR26", "IVOR27",
1668 "IVOR28", "IVOR29", "IVOR30", "IVOR31",
1669 "IVOR32", "IVOR33", "IVOR34", "IVOR35",
1670 "IVOR36", "IVOR37", "IVOR38", "IVOR39",
1671 "IVOR40", "IVOR41", "IVOR42", "IVOR43",
1672 "IVOR44", "IVOR45", "IVOR46", "IVOR47",
1673 "IVOR48", "IVOR49", "IVOR50", "IVOR51",
1674 "IVOR52", "IVOR53", "IVOR54", "IVOR55",
1675 "IVOR56", "IVOR57", "IVOR58", "IVOR59",
1676 "IVOR60", "IVOR61", "IVOR62", "IVOR63",
1678 #define SPR_BOOKE_IVORxx (-1)
1679 int ivor_sprn
[64] = {
1680 SPR_BOOKE_IVOR0
, SPR_BOOKE_IVOR1
, SPR_BOOKE_IVOR2
, SPR_BOOKE_IVOR3
,
1681 SPR_BOOKE_IVOR4
, SPR_BOOKE_IVOR5
, SPR_BOOKE_IVOR6
, SPR_BOOKE_IVOR7
,
1682 SPR_BOOKE_IVOR8
, SPR_BOOKE_IVOR9
, SPR_BOOKE_IVOR10
, SPR_BOOKE_IVOR11
,
1683 SPR_BOOKE_IVOR12
, SPR_BOOKE_IVOR13
, SPR_BOOKE_IVOR14
, SPR_BOOKE_IVOR15
,
1684 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1685 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1686 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1687 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1688 SPR_BOOKE_IVOR32
, SPR_BOOKE_IVOR33
, SPR_BOOKE_IVOR34
, SPR_BOOKE_IVOR35
,
1689 SPR_BOOKE_IVOR36
, SPR_BOOKE_IVOR37
, SPR_BOOKE_IVOR38
, SPR_BOOKE_IVOR39
,
1690 SPR_BOOKE_IVOR40
, SPR_BOOKE_IVOR41
, SPR_BOOKE_IVOR42
, SPR_BOOKE_IVORxx
,
1691 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1692 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1693 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1694 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1695 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1699 /* Interrupt processing */
1700 spr_register(env
, SPR_BOOKE_CSRR0
, "CSRR0",
1701 SPR_NOACCESS
, SPR_NOACCESS
,
1702 &spr_read_generic
, &spr_write_generic
,
1704 spr_register(env
, SPR_BOOKE_CSRR1
, "CSRR1",
1705 SPR_NOACCESS
, SPR_NOACCESS
,
1706 &spr_read_generic
, &spr_write_generic
,
1709 /* XXX : not implemented */
1710 spr_register(env
, SPR_BOOKE_IAC1
, "IAC1",
1711 SPR_NOACCESS
, SPR_NOACCESS
,
1712 &spr_read_generic
, &spr_write_generic
,
1714 /* XXX : not implemented */
1715 spr_register(env
, SPR_BOOKE_IAC2
, "IAC2",
1716 SPR_NOACCESS
, SPR_NOACCESS
,
1717 &spr_read_generic
, &spr_write_generic
,
1719 /* XXX : not implemented */
1720 spr_register(env
, SPR_BOOKE_DAC1
, "DAC1",
1721 SPR_NOACCESS
, SPR_NOACCESS
,
1722 &spr_read_generic
, &spr_write_generic
,
1724 /* XXX : not implemented */
1725 spr_register(env
, SPR_BOOKE_DAC2
, "DAC2",
1726 SPR_NOACCESS
, SPR_NOACCESS
,
1727 &spr_read_generic
, &spr_write_generic
,
1729 /* XXX : not implemented */
1730 spr_register(env
, SPR_BOOKE_DBCR0
, "DBCR0",
1731 SPR_NOACCESS
, SPR_NOACCESS
,
1732 &spr_read_generic
, &spr_write_40x_dbcr0
,
1734 /* XXX : not implemented */
1735 spr_register(env
, SPR_BOOKE_DBCR1
, "DBCR1",
1736 SPR_NOACCESS
, SPR_NOACCESS
,
1737 &spr_read_generic
, &spr_write_generic
,
1739 /* XXX : not implemented */
1740 spr_register(env
, SPR_BOOKE_DBCR2
, "DBCR2",
1741 SPR_NOACCESS
, SPR_NOACCESS
,
1742 &spr_read_generic
, &spr_write_generic
,
1744 /* XXX : not implemented */
1745 spr_register(env
, SPR_BOOKE_DBSR
, "DBSR",
1746 SPR_NOACCESS
, SPR_NOACCESS
,
1747 &spr_read_generic
, &spr_write_clear
,
1749 spr_register(env
, SPR_BOOKE_DEAR
, "DEAR",
1750 SPR_NOACCESS
, SPR_NOACCESS
,
1751 &spr_read_generic
, &spr_write_generic
,
1753 spr_register(env
, SPR_BOOKE_ESR
, "ESR",
1754 SPR_NOACCESS
, SPR_NOACCESS
,
1755 &spr_read_generic
, &spr_write_generic
,
1757 spr_register(env
, SPR_BOOKE_IVPR
, "IVPR",
1758 SPR_NOACCESS
, SPR_NOACCESS
,
1759 &spr_read_generic
, &spr_write_excp_prefix
,
1761 /* Exception vectors */
1762 for (i
= 0; i
< 64; i
++) {
1763 if (ivor_mask
& (1ULL << i
)) {
1764 if (ivor_sprn
[i
] == SPR_BOOKE_IVORxx
) {
1765 fprintf(stderr
, "ERROR: IVOR %d SPR is not defined\n", i
);
1768 spr_register(env
, ivor_sprn
[i
], ivor_names
[i
],
1769 SPR_NOACCESS
, SPR_NOACCESS
,
1770 &spr_read_generic
, &spr_write_excp_vector
,
1774 spr_register(env
, SPR_BOOKE_PID
, "PID",
1775 SPR_NOACCESS
, SPR_NOACCESS
,
1776 &spr_read_generic
, &spr_write_booke_pid
,
1778 spr_register(env
, SPR_BOOKE_TCR
, "TCR",
1779 SPR_NOACCESS
, SPR_NOACCESS
,
1780 &spr_read_generic
, &spr_write_booke_tcr
,
1782 spr_register(env
, SPR_BOOKE_TSR
, "TSR",
1783 SPR_NOACCESS
, SPR_NOACCESS
,
1784 &spr_read_generic
, &spr_write_booke_tsr
,
1787 spr_register(env
, SPR_DECR
, "DECR",
1788 SPR_NOACCESS
, SPR_NOACCESS
,
1789 &spr_read_decr
, &spr_write_decr
,
1791 spr_register(env
, SPR_BOOKE_DECAR
, "DECAR",
1792 SPR_NOACCESS
, SPR_NOACCESS
,
1793 SPR_NOACCESS
, &spr_write_generic
,
1796 spr_register(env
, SPR_USPRG0
, "USPRG0",
1797 &spr_read_generic
, &spr_write_generic
,
1798 &spr_read_generic
, &spr_write_generic
,
1800 spr_register(env
, SPR_SPRG4
, "SPRG4",
1801 SPR_NOACCESS
, SPR_NOACCESS
,
1802 &spr_read_generic
, &spr_write_generic
,
1804 spr_register(env
, SPR_SPRG5
, "SPRG5",
1805 SPR_NOACCESS
, SPR_NOACCESS
,
1806 &spr_read_generic
, &spr_write_generic
,
1808 spr_register(env
, SPR_SPRG6
, "SPRG6",
1809 SPR_NOACCESS
, SPR_NOACCESS
,
1810 &spr_read_generic
, &spr_write_generic
,
1812 spr_register(env
, SPR_SPRG7
, "SPRG7",
1813 SPR_NOACCESS
, SPR_NOACCESS
,
1814 &spr_read_generic
, &spr_write_generic
,
1818 static inline uint32_t gen_tlbncfg(uint32_t assoc
, uint32_t minsize
,
1819 uint32_t maxsize
, uint32_t flags
,
1822 return (assoc
<< TLBnCFG_ASSOC_SHIFT
) |
1823 (minsize
<< TLBnCFG_MINSIZE_SHIFT
) |
1824 (maxsize
<< TLBnCFG_MAXSIZE_SHIFT
) |
1828 /* BookE 2.06 storage control registers */
1829 static void gen_spr_BookE206(CPUPPCState
*env
, uint32_t mas_mask
,
1832 #if !defined(CONFIG_USER_ONLY)
1833 const char *mas_names
[8] = {
1834 "MAS0", "MAS1", "MAS2", "MAS3", "MAS4", "MAS5", "MAS6", "MAS7",
1837 SPR_BOOKE_MAS0
, SPR_BOOKE_MAS1
, SPR_BOOKE_MAS2
, SPR_BOOKE_MAS3
,
1838 SPR_BOOKE_MAS4
, SPR_BOOKE_MAS5
, SPR_BOOKE_MAS6
, SPR_BOOKE_MAS7
,
1842 /* TLB assist registers */
1843 /* XXX : not implemented */
1844 for (i
= 0; i
< 8; i
++) {
1845 void (*uea_write
)(DisasContext
*ctx
, int sprn
, int gprn
) = &spr_write_generic32
;
1846 if (i
== 2 && (mas_mask
& (1 << i
)) && (env
->insns_flags
& PPC_64B
)) {
1847 uea_write
= &spr_write_generic
;
1849 if (mas_mask
& (1 << i
)) {
1850 spr_register(env
, mas_sprn
[i
], mas_names
[i
],
1851 SPR_NOACCESS
, SPR_NOACCESS
,
1852 &spr_read_generic
, uea_write
,
1856 if (env
->nb_pids
> 1) {
1857 /* XXX : not implemented */
1858 spr_register(env
, SPR_BOOKE_PID1
, "PID1",
1859 SPR_NOACCESS
, SPR_NOACCESS
,
1860 &spr_read_generic
, &spr_write_booke_pid
,
1863 if (env
->nb_pids
> 2) {
1864 /* XXX : not implemented */
1865 spr_register(env
, SPR_BOOKE_PID2
, "PID2",
1866 SPR_NOACCESS
, SPR_NOACCESS
,
1867 &spr_read_generic
, &spr_write_booke_pid
,
1870 /* XXX : not implemented */
1871 spr_register(env
, SPR_MMUCFG
, "MMUCFG",
1872 SPR_NOACCESS
, SPR_NOACCESS
,
1873 &spr_read_generic
, SPR_NOACCESS
,
1874 0x00000000); /* TOFIX */
1875 switch (env
->nb_ways
) {
1877 spr_register(env
, SPR_BOOKE_TLB3CFG
, "TLB3CFG",
1878 SPR_NOACCESS
, SPR_NOACCESS
,
1879 &spr_read_generic
, SPR_NOACCESS
,
1883 spr_register(env
, SPR_BOOKE_TLB2CFG
, "TLB2CFG",
1884 SPR_NOACCESS
, SPR_NOACCESS
,
1885 &spr_read_generic
, SPR_NOACCESS
,
1889 spr_register(env
, SPR_BOOKE_TLB1CFG
, "TLB1CFG",
1890 SPR_NOACCESS
, SPR_NOACCESS
,
1891 &spr_read_generic
, SPR_NOACCESS
,
1895 spr_register(env
, SPR_BOOKE_TLB0CFG
, "TLB0CFG",
1896 SPR_NOACCESS
, SPR_NOACCESS
,
1897 &spr_read_generic
, SPR_NOACCESS
,
1906 gen_spr_usprgh(env
);
1909 /* SPR specific to PowerPC 440 implementation */
1910 static void gen_spr_440 (CPUPPCState
*env
)
1913 /* XXX : not implemented */
1914 spr_register(env
, SPR_440_DNV0
, "DNV0",
1915 SPR_NOACCESS
, SPR_NOACCESS
,
1916 &spr_read_generic
, &spr_write_generic
,
1918 /* XXX : not implemented */
1919 spr_register(env
, SPR_440_DNV1
, "DNV1",
1920 SPR_NOACCESS
, SPR_NOACCESS
,
1921 &spr_read_generic
, &spr_write_generic
,
1923 /* XXX : not implemented */
1924 spr_register(env
, SPR_440_DNV2
, "DNV2",
1925 SPR_NOACCESS
, SPR_NOACCESS
,
1926 &spr_read_generic
, &spr_write_generic
,
1928 /* XXX : not implemented */
1929 spr_register(env
, SPR_440_DNV3
, "DNV3",
1930 SPR_NOACCESS
, SPR_NOACCESS
,
1931 &spr_read_generic
, &spr_write_generic
,
1933 /* XXX : not implemented */
1934 spr_register(env
, SPR_440_DTV0
, "DTV0",
1935 SPR_NOACCESS
, SPR_NOACCESS
,
1936 &spr_read_generic
, &spr_write_generic
,
1938 /* XXX : not implemented */
1939 spr_register(env
, SPR_440_DTV1
, "DTV1",
1940 SPR_NOACCESS
, SPR_NOACCESS
,
1941 &spr_read_generic
, &spr_write_generic
,
1943 /* XXX : not implemented */
1944 spr_register(env
, SPR_440_DTV2
, "DTV2",
1945 SPR_NOACCESS
, SPR_NOACCESS
,
1946 &spr_read_generic
, &spr_write_generic
,
1948 /* XXX : not implemented */
1949 spr_register(env
, SPR_440_DTV3
, "DTV3",
1950 SPR_NOACCESS
, SPR_NOACCESS
,
1951 &spr_read_generic
, &spr_write_generic
,
1953 /* XXX : not implemented */
1954 spr_register(env
, SPR_440_DVLIM
, "DVLIM",
1955 SPR_NOACCESS
, SPR_NOACCESS
,
1956 &spr_read_generic
, &spr_write_generic
,
1958 /* XXX : not implemented */
1959 spr_register(env
, SPR_440_INV0
, "INV0",
1960 SPR_NOACCESS
, SPR_NOACCESS
,
1961 &spr_read_generic
, &spr_write_generic
,
1963 /* XXX : not implemented */
1964 spr_register(env
, SPR_440_INV1
, "INV1",
1965 SPR_NOACCESS
, SPR_NOACCESS
,
1966 &spr_read_generic
, &spr_write_generic
,
1968 /* XXX : not implemented */
1969 spr_register(env
, SPR_440_INV2
, "INV2",
1970 SPR_NOACCESS
, SPR_NOACCESS
,
1971 &spr_read_generic
, &spr_write_generic
,
1973 /* XXX : not implemented */
1974 spr_register(env
, SPR_440_INV3
, "INV3",
1975 SPR_NOACCESS
, SPR_NOACCESS
,
1976 &spr_read_generic
, &spr_write_generic
,
1978 /* XXX : not implemented */
1979 spr_register(env
, SPR_440_ITV0
, "ITV0",
1980 SPR_NOACCESS
, SPR_NOACCESS
,
1981 &spr_read_generic
, &spr_write_generic
,
1983 /* XXX : not implemented */
1984 spr_register(env
, SPR_440_ITV1
, "ITV1",
1985 SPR_NOACCESS
, SPR_NOACCESS
,
1986 &spr_read_generic
, &spr_write_generic
,
1988 /* XXX : not implemented */
1989 spr_register(env
, SPR_440_ITV2
, "ITV2",
1990 SPR_NOACCESS
, SPR_NOACCESS
,
1991 &spr_read_generic
, &spr_write_generic
,
1993 /* XXX : not implemented */
1994 spr_register(env
, SPR_440_ITV3
, "ITV3",
1995 SPR_NOACCESS
, SPR_NOACCESS
,
1996 &spr_read_generic
, &spr_write_generic
,
1998 /* XXX : not implemented */
1999 spr_register(env
, SPR_440_IVLIM
, "IVLIM",
2000 SPR_NOACCESS
, SPR_NOACCESS
,
2001 &spr_read_generic
, &spr_write_generic
,
2004 /* XXX : not implemented */
2005 spr_register(env
, SPR_BOOKE_DCDBTRH
, "DCDBTRH",
2006 SPR_NOACCESS
, SPR_NOACCESS
,
2007 &spr_read_generic
, SPR_NOACCESS
,
2009 /* XXX : not implemented */
2010 spr_register(env
, SPR_BOOKE_DCDBTRL
, "DCDBTRL",
2011 SPR_NOACCESS
, SPR_NOACCESS
,
2012 &spr_read_generic
, SPR_NOACCESS
,
2014 /* XXX : not implemented */
2015 spr_register(env
, SPR_BOOKE_ICDBDR
, "ICDBDR",
2016 SPR_NOACCESS
, SPR_NOACCESS
,
2017 &spr_read_generic
, SPR_NOACCESS
,
2019 /* XXX : not implemented */
2020 spr_register(env
, SPR_BOOKE_ICDBTRH
, "ICDBTRH",
2021 SPR_NOACCESS
, SPR_NOACCESS
,
2022 &spr_read_generic
, SPR_NOACCESS
,
2024 /* XXX : not implemented */
2025 spr_register(env
, SPR_BOOKE_ICDBTRL
, "ICDBTRL",
2026 SPR_NOACCESS
, SPR_NOACCESS
,
2027 &spr_read_generic
, SPR_NOACCESS
,
2029 /* XXX : not implemented */
2030 spr_register(env
, SPR_440_DBDR
, "DBDR",
2031 SPR_NOACCESS
, SPR_NOACCESS
,
2032 &spr_read_generic
, &spr_write_generic
,
2034 /* Processor control */
2035 spr_register(env
, SPR_4xx_CCR0
, "CCR0",
2036 SPR_NOACCESS
, SPR_NOACCESS
,
2037 &spr_read_generic
, &spr_write_generic
,
2039 spr_register(env
, SPR_440_RSTCFG
, "RSTCFG",
2040 SPR_NOACCESS
, SPR_NOACCESS
,
2041 &spr_read_generic
, SPR_NOACCESS
,
2043 /* Storage control */
2044 spr_register(env
, SPR_440_MMUCR
, "MMUCR",
2045 SPR_NOACCESS
, SPR_NOACCESS
,
2046 &spr_read_generic
, &spr_write_generic
,
2050 /* SPR shared between PowerPC 40x implementations */
2051 static void gen_spr_40x (CPUPPCState
*env
)
2054 /* not emulated, as QEMU do not emulate caches */
2055 spr_register(env
, SPR_40x_DCCR
, "DCCR",
2056 SPR_NOACCESS
, SPR_NOACCESS
,
2057 &spr_read_generic
, &spr_write_generic
,
2059 /* not emulated, as QEMU do not emulate caches */
2060 spr_register(env
, SPR_40x_ICCR
, "ICCR",
2061 SPR_NOACCESS
, SPR_NOACCESS
,
2062 &spr_read_generic
, &spr_write_generic
,
2064 /* not emulated, as QEMU do not emulate caches */
2065 spr_register(env
, SPR_BOOKE_ICDBDR
, "ICDBDR",
2066 SPR_NOACCESS
, SPR_NOACCESS
,
2067 &spr_read_generic
, SPR_NOACCESS
,
2070 spr_register(env
, SPR_40x_DEAR
, "DEAR",
2071 SPR_NOACCESS
, SPR_NOACCESS
,
2072 &spr_read_generic
, &spr_write_generic
,
2074 spr_register(env
, SPR_40x_ESR
, "ESR",
2075 SPR_NOACCESS
, SPR_NOACCESS
,
2076 &spr_read_generic
, &spr_write_generic
,
2078 spr_register(env
, SPR_40x_EVPR
, "EVPR",
2079 SPR_NOACCESS
, SPR_NOACCESS
,
2080 &spr_read_generic
, &spr_write_excp_prefix
,
2082 spr_register(env
, SPR_40x_SRR2
, "SRR2",
2083 &spr_read_generic
, &spr_write_generic
,
2084 &spr_read_generic
, &spr_write_generic
,
2086 spr_register(env
, SPR_40x_SRR3
, "SRR3",
2087 &spr_read_generic
, &spr_write_generic
,
2088 &spr_read_generic
, &spr_write_generic
,
2091 spr_register(env
, SPR_40x_PIT
, "PIT",
2092 SPR_NOACCESS
, SPR_NOACCESS
,
2093 &spr_read_40x_pit
, &spr_write_40x_pit
,
2095 spr_register(env
, SPR_40x_TCR
, "TCR",
2096 SPR_NOACCESS
, SPR_NOACCESS
,
2097 &spr_read_generic
, &spr_write_booke_tcr
,
2099 spr_register(env
, SPR_40x_TSR
, "TSR",
2100 SPR_NOACCESS
, SPR_NOACCESS
,
2101 &spr_read_generic
, &spr_write_booke_tsr
,
2105 /* SPR specific to PowerPC 405 implementation */
2106 static void gen_spr_405 (CPUPPCState
*env
)
2109 spr_register(env
, SPR_40x_PID
, "PID",
2110 SPR_NOACCESS
, SPR_NOACCESS
,
2111 &spr_read_generic
, &spr_write_generic
,
2113 spr_register(env
, SPR_4xx_CCR0
, "CCR0",
2114 SPR_NOACCESS
, SPR_NOACCESS
,
2115 &spr_read_generic
, &spr_write_generic
,
2117 /* Debug interface */
2118 /* XXX : not implemented */
2119 spr_register(env
, SPR_40x_DBCR0
, "DBCR0",
2120 SPR_NOACCESS
, SPR_NOACCESS
,
2121 &spr_read_generic
, &spr_write_40x_dbcr0
,
2123 /* XXX : not implemented */
2124 spr_register(env
, SPR_405_DBCR1
, "DBCR1",
2125 SPR_NOACCESS
, SPR_NOACCESS
,
2126 &spr_read_generic
, &spr_write_generic
,
2128 /* XXX : not implemented */
2129 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2130 SPR_NOACCESS
, SPR_NOACCESS
,
2131 &spr_read_generic
, &spr_write_clear
,
2132 /* Last reset was system reset */
2134 /* XXX : not implemented */
2135 spr_register(env
, SPR_40x_DAC1
, "DAC1",
2136 SPR_NOACCESS
, SPR_NOACCESS
,
2137 &spr_read_generic
, &spr_write_generic
,
2139 spr_register(env
, SPR_40x_DAC2
, "DAC2",
2140 SPR_NOACCESS
, SPR_NOACCESS
,
2141 &spr_read_generic
, &spr_write_generic
,
2143 /* XXX : not implemented */
2144 spr_register(env
, SPR_405_DVC1
, "DVC1",
2145 SPR_NOACCESS
, SPR_NOACCESS
,
2146 &spr_read_generic
, &spr_write_generic
,
2148 /* XXX : not implemented */
2149 spr_register(env
, SPR_405_DVC2
, "DVC2",
2150 SPR_NOACCESS
, SPR_NOACCESS
,
2151 &spr_read_generic
, &spr_write_generic
,
2153 /* XXX : not implemented */
2154 spr_register(env
, SPR_40x_IAC1
, "IAC1",
2155 SPR_NOACCESS
, SPR_NOACCESS
,
2156 &spr_read_generic
, &spr_write_generic
,
2158 spr_register(env
, SPR_40x_IAC2
, "IAC2",
2159 SPR_NOACCESS
, SPR_NOACCESS
,
2160 &spr_read_generic
, &spr_write_generic
,
2162 /* XXX : not implemented */
2163 spr_register(env
, SPR_405_IAC3
, "IAC3",
2164 SPR_NOACCESS
, SPR_NOACCESS
,
2165 &spr_read_generic
, &spr_write_generic
,
2167 /* XXX : not implemented */
2168 spr_register(env
, SPR_405_IAC4
, "IAC4",
2169 SPR_NOACCESS
, SPR_NOACCESS
,
2170 &spr_read_generic
, &spr_write_generic
,
2172 /* Storage control */
2173 /* XXX: TODO: not implemented */
2174 spr_register(env
, SPR_405_SLER
, "SLER",
2175 SPR_NOACCESS
, SPR_NOACCESS
,
2176 &spr_read_generic
, &spr_write_40x_sler
,
2178 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2179 SPR_NOACCESS
, SPR_NOACCESS
,
2180 &spr_read_generic
, &spr_write_generic
,
2182 /* XXX : not implemented */
2183 spr_register(env
, SPR_405_SU0R
, "SU0R",
2184 SPR_NOACCESS
, SPR_NOACCESS
,
2185 &spr_read_generic
, &spr_write_generic
,
2188 spr_register(env
, SPR_USPRG0
, "USPRG0",
2189 &spr_read_ureg
, SPR_NOACCESS
,
2190 &spr_read_ureg
, SPR_NOACCESS
,
2192 spr_register(env
, SPR_SPRG4
, "SPRG4",
2193 SPR_NOACCESS
, SPR_NOACCESS
,
2194 &spr_read_generic
, &spr_write_generic
,
2196 spr_register(env
, SPR_SPRG5
, "SPRG5",
2197 SPR_NOACCESS
, SPR_NOACCESS
,
2198 spr_read_generic
, &spr_write_generic
,
2200 spr_register(env
, SPR_SPRG6
, "SPRG6",
2201 SPR_NOACCESS
, SPR_NOACCESS
,
2202 spr_read_generic
, &spr_write_generic
,
2204 spr_register(env
, SPR_SPRG7
, "SPRG7",
2205 SPR_NOACCESS
, SPR_NOACCESS
,
2206 spr_read_generic
, &spr_write_generic
,
2208 gen_spr_usprgh(env
);
2211 /* SPR shared between PowerPC 401 & 403 implementations */
2212 static void gen_spr_401_403 (CPUPPCState
*env
)
2215 spr_register(env
, SPR_403_VTBL
, "TBL",
2216 &spr_read_tbl
, SPR_NOACCESS
,
2217 &spr_read_tbl
, SPR_NOACCESS
,
2219 spr_register(env
, SPR_403_TBL
, "TBL",
2220 SPR_NOACCESS
, SPR_NOACCESS
,
2221 SPR_NOACCESS
, &spr_write_tbl
,
2223 spr_register(env
, SPR_403_VTBU
, "TBU",
2224 &spr_read_tbu
, SPR_NOACCESS
,
2225 &spr_read_tbu
, SPR_NOACCESS
,
2227 spr_register(env
, SPR_403_TBU
, "TBU",
2228 SPR_NOACCESS
, SPR_NOACCESS
,
2229 SPR_NOACCESS
, &spr_write_tbu
,
2232 /* not emulated, as QEMU do not emulate caches */
2233 spr_register(env
, SPR_403_CDBCR
, "CDBCR",
2234 SPR_NOACCESS
, SPR_NOACCESS
,
2235 &spr_read_generic
, &spr_write_generic
,
2239 /* SPR specific to PowerPC 401 implementation */
2240 static void gen_spr_401 (CPUPPCState
*env
)
2242 /* Debug interface */
2243 /* XXX : not implemented */
2244 spr_register(env
, SPR_40x_DBCR0
, "DBCR",
2245 SPR_NOACCESS
, SPR_NOACCESS
,
2246 &spr_read_generic
, &spr_write_40x_dbcr0
,
2248 /* XXX : not implemented */
2249 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2250 SPR_NOACCESS
, SPR_NOACCESS
,
2251 &spr_read_generic
, &spr_write_clear
,
2252 /* Last reset was system reset */
2254 /* XXX : not implemented */
2255 spr_register(env
, SPR_40x_DAC1
, "DAC",
2256 SPR_NOACCESS
, SPR_NOACCESS
,
2257 &spr_read_generic
, &spr_write_generic
,
2259 /* XXX : not implemented */
2260 spr_register(env
, SPR_40x_IAC1
, "IAC",
2261 SPR_NOACCESS
, SPR_NOACCESS
,
2262 &spr_read_generic
, &spr_write_generic
,
2264 /* Storage control */
2265 /* XXX: TODO: not implemented */
2266 spr_register(env
, SPR_405_SLER
, "SLER",
2267 SPR_NOACCESS
, SPR_NOACCESS
,
2268 &spr_read_generic
, &spr_write_40x_sler
,
2270 /* not emulated, as QEMU never does speculative access */
2271 spr_register(env
, SPR_40x_SGR
, "SGR",
2272 SPR_NOACCESS
, SPR_NOACCESS
,
2273 &spr_read_generic
, &spr_write_generic
,
2275 /* not emulated, as QEMU do not emulate caches */
2276 spr_register(env
, SPR_40x_DCWR
, "DCWR",
2277 SPR_NOACCESS
, SPR_NOACCESS
,
2278 &spr_read_generic
, &spr_write_generic
,
2282 static void gen_spr_401x2 (CPUPPCState
*env
)
2285 spr_register(env
, SPR_40x_PID
, "PID",
2286 SPR_NOACCESS
, SPR_NOACCESS
,
2287 &spr_read_generic
, &spr_write_generic
,
2289 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2290 SPR_NOACCESS
, SPR_NOACCESS
,
2291 &spr_read_generic
, &spr_write_generic
,
2295 /* SPR specific to PowerPC 403 implementation */
2296 static void gen_spr_403 (CPUPPCState
*env
)
2298 /* Debug interface */
2299 /* XXX : not implemented */
2300 spr_register(env
, SPR_40x_DBCR0
, "DBCR0",
2301 SPR_NOACCESS
, SPR_NOACCESS
,
2302 &spr_read_generic
, &spr_write_40x_dbcr0
,
2304 /* XXX : not implemented */
2305 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2306 SPR_NOACCESS
, SPR_NOACCESS
,
2307 &spr_read_generic
, &spr_write_clear
,
2308 /* Last reset was system reset */
2310 /* XXX : not implemented */
2311 spr_register(env
, SPR_40x_DAC1
, "DAC1",
2312 SPR_NOACCESS
, SPR_NOACCESS
,
2313 &spr_read_generic
, &spr_write_generic
,
2315 /* XXX : not implemented */
2316 spr_register(env
, SPR_40x_DAC2
, "DAC2",
2317 SPR_NOACCESS
, SPR_NOACCESS
,
2318 &spr_read_generic
, &spr_write_generic
,
2320 /* XXX : not implemented */
2321 spr_register(env
, SPR_40x_IAC1
, "IAC1",
2322 SPR_NOACCESS
, SPR_NOACCESS
,
2323 &spr_read_generic
, &spr_write_generic
,
2325 /* XXX : not implemented */
2326 spr_register(env
, SPR_40x_IAC2
, "IAC2",
2327 SPR_NOACCESS
, SPR_NOACCESS
,
2328 &spr_read_generic
, &spr_write_generic
,
2332 static void gen_spr_403_real (CPUPPCState
*env
)
2334 spr_register(env
, SPR_403_PBL1
, "PBL1",
2335 SPR_NOACCESS
, SPR_NOACCESS
,
2336 &spr_read_403_pbr
, &spr_write_403_pbr
,
2338 spr_register(env
, SPR_403_PBU1
, "PBU1",
2339 SPR_NOACCESS
, SPR_NOACCESS
,
2340 &spr_read_403_pbr
, &spr_write_403_pbr
,
2342 spr_register(env
, SPR_403_PBL2
, "PBL2",
2343 SPR_NOACCESS
, SPR_NOACCESS
,
2344 &spr_read_403_pbr
, &spr_write_403_pbr
,
2346 spr_register(env
, SPR_403_PBU2
, "PBU2",
2347 SPR_NOACCESS
, SPR_NOACCESS
,
2348 &spr_read_403_pbr
, &spr_write_403_pbr
,
2352 static void gen_spr_403_mmu (CPUPPCState
*env
)
2355 spr_register(env
, SPR_40x_PID
, "PID",
2356 SPR_NOACCESS
, SPR_NOACCESS
,
2357 &spr_read_generic
, &spr_write_generic
,
2359 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2360 SPR_NOACCESS
, SPR_NOACCESS
,
2361 &spr_read_generic
, &spr_write_generic
,
2365 /* SPR specific to PowerPC compression coprocessor extension */
2366 static void gen_spr_compress (CPUPPCState
*env
)
2368 /* XXX : not implemented */
2369 spr_register(env
, SPR_401_SKR
, "SKR",
2370 SPR_NOACCESS
, SPR_NOACCESS
,
2371 &spr_read_generic
, &spr_write_generic
,
2375 static void gen_spr_5xx_8xx (CPUPPCState
*env
)
2377 /* Exception processing */
2378 spr_register_kvm(env
, SPR_DSISR
, "DSISR",
2379 SPR_NOACCESS
, SPR_NOACCESS
,
2380 &spr_read_generic
, &spr_write_generic
,
2381 KVM_REG_PPC_DSISR
, 0x00000000);
2382 spr_register_kvm(env
, SPR_DAR
, "DAR",
2383 SPR_NOACCESS
, SPR_NOACCESS
,
2384 &spr_read_generic
, &spr_write_generic
,
2385 KVM_REG_PPC_DAR
, 0x00000000);
2387 spr_register(env
, SPR_DECR
, "DECR",
2388 SPR_NOACCESS
, SPR_NOACCESS
,
2389 &spr_read_decr
, &spr_write_decr
,
2391 /* XXX : not implemented */
2392 spr_register(env
, SPR_MPC_EIE
, "EIE",
2393 SPR_NOACCESS
, SPR_NOACCESS
,
2394 &spr_read_generic
, &spr_write_generic
,
2396 /* XXX : not implemented */
2397 spr_register(env
, SPR_MPC_EID
, "EID",
2398 SPR_NOACCESS
, SPR_NOACCESS
,
2399 &spr_read_generic
, &spr_write_generic
,
2401 /* XXX : not implemented */
2402 spr_register(env
, SPR_MPC_NRI
, "NRI",
2403 SPR_NOACCESS
, SPR_NOACCESS
,
2404 &spr_read_generic
, &spr_write_generic
,
2406 /* XXX : not implemented */
2407 spr_register(env
, SPR_MPC_CMPA
, "CMPA",
2408 SPR_NOACCESS
, SPR_NOACCESS
,
2409 &spr_read_generic
, &spr_write_generic
,
2411 /* XXX : not implemented */
2412 spr_register(env
, SPR_MPC_CMPB
, "CMPB",
2413 SPR_NOACCESS
, SPR_NOACCESS
,
2414 &spr_read_generic
, &spr_write_generic
,
2416 /* XXX : not implemented */
2417 spr_register(env
, SPR_MPC_CMPC
, "CMPC",
2418 SPR_NOACCESS
, SPR_NOACCESS
,
2419 &spr_read_generic
, &spr_write_generic
,
2421 /* XXX : not implemented */
2422 spr_register(env
, SPR_MPC_CMPD
, "CMPD",
2423 SPR_NOACCESS
, SPR_NOACCESS
,
2424 &spr_read_generic
, &spr_write_generic
,
2426 /* XXX : not implemented */
2427 spr_register(env
, SPR_MPC_ECR
, "ECR",
2428 SPR_NOACCESS
, SPR_NOACCESS
,
2429 &spr_read_generic
, &spr_write_generic
,
2431 /* XXX : not implemented */
2432 spr_register(env
, SPR_MPC_DER
, "DER",
2433 SPR_NOACCESS
, SPR_NOACCESS
,
2434 &spr_read_generic
, &spr_write_generic
,
2436 /* XXX : not implemented */
2437 spr_register(env
, SPR_MPC_COUNTA
, "COUNTA",
2438 SPR_NOACCESS
, SPR_NOACCESS
,
2439 &spr_read_generic
, &spr_write_generic
,
2441 /* XXX : not implemented */
2442 spr_register(env
, SPR_MPC_COUNTB
, "COUNTB",
2443 SPR_NOACCESS
, SPR_NOACCESS
,
2444 &spr_read_generic
, &spr_write_generic
,
2446 /* XXX : not implemented */
2447 spr_register(env
, SPR_MPC_CMPE
, "CMPE",
2448 SPR_NOACCESS
, SPR_NOACCESS
,
2449 &spr_read_generic
, &spr_write_generic
,
2451 /* XXX : not implemented */
2452 spr_register(env
, SPR_MPC_CMPF
, "CMPF",
2453 SPR_NOACCESS
, SPR_NOACCESS
,
2454 &spr_read_generic
, &spr_write_generic
,
2456 /* XXX : not implemented */
2457 spr_register(env
, SPR_MPC_CMPG
, "CMPG",
2458 SPR_NOACCESS
, SPR_NOACCESS
,
2459 &spr_read_generic
, &spr_write_generic
,
2461 /* XXX : not implemented */
2462 spr_register(env
, SPR_MPC_CMPH
, "CMPH",
2463 SPR_NOACCESS
, SPR_NOACCESS
,
2464 &spr_read_generic
, &spr_write_generic
,
2466 /* XXX : not implemented */
2467 spr_register(env
, SPR_MPC_LCTRL1
, "LCTRL1",
2468 SPR_NOACCESS
, SPR_NOACCESS
,
2469 &spr_read_generic
, &spr_write_generic
,
2471 /* XXX : not implemented */
2472 spr_register(env
, SPR_MPC_LCTRL2
, "LCTRL2",
2473 SPR_NOACCESS
, SPR_NOACCESS
,
2474 &spr_read_generic
, &spr_write_generic
,
2476 /* XXX : not implemented */
2477 spr_register(env
, SPR_MPC_BAR
, "BAR",
2478 SPR_NOACCESS
, SPR_NOACCESS
,
2479 &spr_read_generic
, &spr_write_generic
,
2481 /* XXX : not implemented */
2482 spr_register(env
, SPR_MPC_DPDR
, "DPDR",
2483 SPR_NOACCESS
, SPR_NOACCESS
,
2484 &spr_read_generic
, &spr_write_generic
,
2486 /* XXX : not implemented */
2487 spr_register(env
, SPR_MPC_IMMR
, "IMMR",
2488 SPR_NOACCESS
, SPR_NOACCESS
,
2489 &spr_read_generic
, &spr_write_generic
,
2493 static void gen_spr_5xx (CPUPPCState
*env
)
2495 /* XXX : not implemented */
2496 spr_register(env
, SPR_RCPU_MI_GRA
, "MI_GRA",
2497 SPR_NOACCESS
, SPR_NOACCESS
,
2498 &spr_read_generic
, &spr_write_generic
,
2500 /* XXX : not implemented */
2501 spr_register(env
, SPR_RCPU_L2U_GRA
, "L2U_GRA",
2502 SPR_NOACCESS
, SPR_NOACCESS
,
2503 &spr_read_generic
, &spr_write_generic
,
2505 /* XXX : not implemented */
2506 spr_register(env
, SPR_RPCU_BBCMCR
, "L2U_BBCMCR",
2507 SPR_NOACCESS
, SPR_NOACCESS
,
2508 &spr_read_generic
, &spr_write_generic
,
2510 /* XXX : not implemented */
2511 spr_register(env
, SPR_RCPU_L2U_MCR
, "L2U_MCR",
2512 SPR_NOACCESS
, SPR_NOACCESS
,
2513 &spr_read_generic
, &spr_write_generic
,
2515 /* XXX : not implemented */
2516 spr_register(env
, SPR_RCPU_MI_RBA0
, "MI_RBA0",
2517 SPR_NOACCESS
, SPR_NOACCESS
,
2518 &spr_read_generic
, &spr_write_generic
,
2520 /* XXX : not implemented */
2521 spr_register(env
, SPR_RCPU_MI_RBA1
, "MI_RBA1",
2522 SPR_NOACCESS
, SPR_NOACCESS
,
2523 &spr_read_generic
, &spr_write_generic
,
2525 /* XXX : not implemented */
2526 spr_register(env
, SPR_RCPU_MI_RBA2
, "MI_RBA2",
2527 SPR_NOACCESS
, SPR_NOACCESS
,
2528 &spr_read_generic
, &spr_write_generic
,
2530 /* XXX : not implemented */
2531 spr_register(env
, SPR_RCPU_MI_RBA3
, "MI_RBA3",
2532 SPR_NOACCESS
, SPR_NOACCESS
,
2533 &spr_read_generic
, &spr_write_generic
,
2535 /* XXX : not implemented */
2536 spr_register(env
, SPR_RCPU_L2U_RBA0
, "L2U_RBA0",
2537 SPR_NOACCESS
, SPR_NOACCESS
,
2538 &spr_read_generic
, &spr_write_generic
,
2540 /* XXX : not implemented */
2541 spr_register(env
, SPR_RCPU_L2U_RBA1
, "L2U_RBA1",
2542 SPR_NOACCESS
, SPR_NOACCESS
,
2543 &spr_read_generic
, &spr_write_generic
,
2545 /* XXX : not implemented */
2546 spr_register(env
, SPR_RCPU_L2U_RBA2
, "L2U_RBA2",
2547 SPR_NOACCESS
, SPR_NOACCESS
,
2548 &spr_read_generic
, &spr_write_generic
,
2550 /* XXX : not implemented */
2551 spr_register(env
, SPR_RCPU_L2U_RBA3
, "L2U_RBA3",
2552 SPR_NOACCESS
, SPR_NOACCESS
,
2553 &spr_read_generic
, &spr_write_generic
,
2555 /* XXX : not implemented */
2556 spr_register(env
, SPR_RCPU_MI_RA0
, "MI_RA0",
2557 SPR_NOACCESS
, SPR_NOACCESS
,
2558 &spr_read_generic
, &spr_write_generic
,
2560 /* XXX : not implemented */
2561 spr_register(env
, SPR_RCPU_MI_RA1
, "MI_RA1",
2562 SPR_NOACCESS
, SPR_NOACCESS
,
2563 &spr_read_generic
, &spr_write_generic
,
2565 /* XXX : not implemented */
2566 spr_register(env
, SPR_RCPU_MI_RA2
, "MI_RA2",
2567 SPR_NOACCESS
, SPR_NOACCESS
,
2568 &spr_read_generic
, &spr_write_generic
,
2570 /* XXX : not implemented */
2571 spr_register(env
, SPR_RCPU_MI_RA3
, "MI_RA3",
2572 SPR_NOACCESS
, SPR_NOACCESS
,
2573 &spr_read_generic
, &spr_write_generic
,
2575 /* XXX : not implemented */
2576 spr_register(env
, SPR_RCPU_L2U_RA0
, "L2U_RA0",
2577 SPR_NOACCESS
, SPR_NOACCESS
,
2578 &spr_read_generic
, &spr_write_generic
,
2580 /* XXX : not implemented */
2581 spr_register(env
, SPR_RCPU_L2U_RA1
, "L2U_RA1",
2582 SPR_NOACCESS
, SPR_NOACCESS
,
2583 &spr_read_generic
, &spr_write_generic
,
2585 /* XXX : not implemented */
2586 spr_register(env
, SPR_RCPU_L2U_RA2
, "L2U_RA2",
2587 SPR_NOACCESS
, SPR_NOACCESS
,
2588 &spr_read_generic
, &spr_write_generic
,
2590 /* XXX : not implemented */
2591 spr_register(env
, SPR_RCPU_L2U_RA3
, "L2U_RA3",
2592 SPR_NOACCESS
, SPR_NOACCESS
,
2593 &spr_read_generic
, &spr_write_generic
,
2595 /* XXX : not implemented */
2596 spr_register(env
, SPR_RCPU_FPECR
, "FPECR",
2597 SPR_NOACCESS
, SPR_NOACCESS
,
2598 &spr_read_generic
, &spr_write_generic
,
2602 static void gen_spr_8xx (CPUPPCState
*env
)
2604 /* XXX : not implemented */
2605 spr_register(env
, SPR_MPC_IC_CST
, "IC_CST",
2606 SPR_NOACCESS
, SPR_NOACCESS
,
2607 &spr_read_generic
, &spr_write_generic
,
2609 /* XXX : not implemented */
2610 spr_register(env
, SPR_MPC_IC_ADR
, "IC_ADR",
2611 SPR_NOACCESS
, SPR_NOACCESS
,
2612 &spr_read_generic
, &spr_write_generic
,
2614 /* XXX : not implemented */
2615 spr_register(env
, SPR_MPC_IC_DAT
, "IC_DAT",
2616 SPR_NOACCESS
, SPR_NOACCESS
,
2617 &spr_read_generic
, &spr_write_generic
,
2619 /* XXX : not implemented */
2620 spr_register(env
, SPR_MPC_DC_CST
, "DC_CST",
2621 SPR_NOACCESS
, SPR_NOACCESS
,
2622 &spr_read_generic
, &spr_write_generic
,
2624 /* XXX : not implemented */
2625 spr_register(env
, SPR_MPC_DC_ADR
, "DC_ADR",
2626 SPR_NOACCESS
, SPR_NOACCESS
,
2627 &spr_read_generic
, &spr_write_generic
,
2629 /* XXX : not implemented */
2630 spr_register(env
, SPR_MPC_DC_DAT
, "DC_DAT",
2631 SPR_NOACCESS
, SPR_NOACCESS
,
2632 &spr_read_generic
, &spr_write_generic
,
2634 /* XXX : not implemented */
2635 spr_register(env
, SPR_MPC_MI_CTR
, "MI_CTR",
2636 SPR_NOACCESS
, SPR_NOACCESS
,
2637 &spr_read_generic
, &spr_write_generic
,
2639 /* XXX : not implemented */
2640 spr_register(env
, SPR_MPC_MI_AP
, "MI_AP",
2641 SPR_NOACCESS
, SPR_NOACCESS
,
2642 &spr_read_generic
, &spr_write_generic
,
2644 /* XXX : not implemented */
2645 spr_register(env
, SPR_MPC_MI_EPN
, "MI_EPN",
2646 SPR_NOACCESS
, SPR_NOACCESS
,
2647 &spr_read_generic
, &spr_write_generic
,
2649 /* XXX : not implemented */
2650 spr_register(env
, SPR_MPC_MI_TWC
, "MI_TWC",
2651 SPR_NOACCESS
, SPR_NOACCESS
,
2652 &spr_read_generic
, &spr_write_generic
,
2654 /* XXX : not implemented */
2655 spr_register(env
, SPR_MPC_MI_RPN
, "MI_RPN",
2656 SPR_NOACCESS
, SPR_NOACCESS
,
2657 &spr_read_generic
, &spr_write_generic
,
2659 /* XXX : not implemented */
2660 spr_register(env
, SPR_MPC_MI_DBCAM
, "MI_DBCAM",
2661 SPR_NOACCESS
, SPR_NOACCESS
,
2662 &spr_read_generic
, &spr_write_generic
,
2664 /* XXX : not implemented */
2665 spr_register(env
, SPR_MPC_MI_DBRAM0
, "MI_DBRAM0",
2666 SPR_NOACCESS
, SPR_NOACCESS
,
2667 &spr_read_generic
, &spr_write_generic
,
2669 /* XXX : not implemented */
2670 spr_register(env
, SPR_MPC_MI_DBRAM1
, "MI_DBRAM1",
2671 SPR_NOACCESS
, SPR_NOACCESS
,
2672 &spr_read_generic
, &spr_write_generic
,
2674 /* XXX : not implemented */
2675 spr_register(env
, SPR_MPC_MD_CTR
, "MD_CTR",
2676 SPR_NOACCESS
, SPR_NOACCESS
,
2677 &spr_read_generic
, &spr_write_generic
,
2679 /* XXX : not implemented */
2680 spr_register(env
, SPR_MPC_MD_CASID
, "MD_CASID",
2681 SPR_NOACCESS
, SPR_NOACCESS
,
2682 &spr_read_generic
, &spr_write_generic
,
2684 /* XXX : not implemented */
2685 spr_register(env
, SPR_MPC_MD_AP
, "MD_AP",
2686 SPR_NOACCESS
, SPR_NOACCESS
,
2687 &spr_read_generic
, &spr_write_generic
,
2689 /* XXX : not implemented */
2690 spr_register(env
, SPR_MPC_MD_EPN
, "MD_EPN",
2691 SPR_NOACCESS
, SPR_NOACCESS
,
2692 &spr_read_generic
, &spr_write_generic
,
2694 /* XXX : not implemented */
2695 spr_register(env
, SPR_MPC_MD_TWB
, "MD_TWB",
2696 SPR_NOACCESS
, SPR_NOACCESS
,
2697 &spr_read_generic
, &spr_write_generic
,
2699 /* XXX : not implemented */
2700 spr_register(env
, SPR_MPC_MD_TWC
, "MD_TWC",
2701 SPR_NOACCESS
, SPR_NOACCESS
,
2702 &spr_read_generic
, &spr_write_generic
,
2704 /* XXX : not implemented */
2705 spr_register(env
, SPR_MPC_MD_RPN
, "MD_RPN",
2706 SPR_NOACCESS
, SPR_NOACCESS
,
2707 &spr_read_generic
, &spr_write_generic
,
2709 /* XXX : not implemented */
2710 spr_register(env
, SPR_MPC_MD_TW
, "MD_TW",
2711 SPR_NOACCESS
, SPR_NOACCESS
,
2712 &spr_read_generic
, &spr_write_generic
,
2714 /* XXX : not implemented */
2715 spr_register(env
, SPR_MPC_MD_DBCAM
, "MD_DBCAM",
2716 SPR_NOACCESS
, SPR_NOACCESS
,
2717 &spr_read_generic
, &spr_write_generic
,
2719 /* XXX : not implemented */
2720 spr_register(env
, SPR_MPC_MD_DBRAM0
, "MD_DBRAM0",
2721 SPR_NOACCESS
, SPR_NOACCESS
,
2722 &spr_read_generic
, &spr_write_generic
,
2724 /* XXX : not implemented */
2725 spr_register(env
, SPR_MPC_MD_DBRAM1
, "MD_DBRAM1",
2726 SPR_NOACCESS
, SPR_NOACCESS
,
2727 &spr_read_generic
, &spr_write_generic
,
2733 * AMR => SPR 29 (Power 2.04)
2734 * CTRL => SPR 136 (Power 2.04)
2735 * CTRL => SPR 152 (Power 2.04)
2736 * SCOMC => SPR 276 (64 bits ?)
2737 * SCOMD => SPR 277 (64 bits ?)
2738 * TBU40 => SPR 286 (Power 2.04 hypv)
2739 * HSPRG0 => SPR 304 (Power 2.04 hypv)
2740 * HSPRG1 => SPR 305 (Power 2.04 hypv)
2741 * HDSISR => SPR 306 (Power 2.04 hypv)
2742 * HDAR => SPR 307 (Power 2.04 hypv)
2743 * PURR => SPR 309 (Power 2.04 hypv)
2744 * HDEC => SPR 310 (Power 2.04 hypv)
2745 * HIOR => SPR 311 (hypv)
2746 * RMOR => SPR 312 (970)
2747 * HRMOR => SPR 313 (Power 2.04 hypv)
2748 * HSRR0 => SPR 314 (Power 2.04 hypv)
2749 * HSRR1 => SPR 315 (Power 2.04 hypv)
2750 * LPIDR => SPR 317 (970)
2751 * EPR => SPR 702 (Power 2.04 emb)
2752 * perf => 768-783 (Power 2.04)
2753 * perf => 784-799 (Power 2.04)
2754 * PPR => SPR 896 (Power 2.04)
2755 * EPLC => SPR 947 (Power 2.04 emb)
2756 * EPSC => SPR 948 (Power 2.04 emb)
2757 * DABRX => 1015 (Power 2.04 hypv)
2758 * FPECR => SPR 1022 (?)
2759 * ... and more (thermal management, performance counters, ...)
2762 /*****************************************************************************/
2763 /* Exception vectors models */
2764 static void init_excp_4xx_real (CPUPPCState
*env
)
2766 #if !defined(CONFIG_USER_ONLY)
2767 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000100;
2768 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2769 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2770 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2771 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2772 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2773 env
->excp_vectors
[POWERPC_EXCP_PIT
] = 0x00001000;
2774 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00001010;
2775 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001020;
2776 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00002000;
2777 env
->ivor_mask
= 0x0000FFF0UL
;
2778 env
->ivpr_mask
= 0xFFFF0000UL
;
2779 /* Hardware reset vector */
2780 env
->hreset_vector
= 0xFFFFFFFCUL
;
2784 static void init_excp_4xx_softmmu (CPUPPCState
*env
)
2786 #if !defined(CONFIG_USER_ONLY)
2787 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000100;
2788 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2789 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2790 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2791 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2792 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2793 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2794 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2795 env
->excp_vectors
[POWERPC_EXCP_PIT
] = 0x00001000;
2796 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00001010;
2797 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001020;
2798 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00001100;
2799 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00001200;
2800 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00002000;
2801 env
->ivor_mask
= 0x0000FFF0UL
;
2802 env
->ivpr_mask
= 0xFFFF0000UL
;
2803 /* Hardware reset vector */
2804 env
->hreset_vector
= 0xFFFFFFFCUL
;
2808 static void init_excp_MPC5xx (CPUPPCState
*env
)
2810 #if !defined(CONFIG_USER_ONLY)
2811 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2812 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2813 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2814 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2815 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2816 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000900;
2817 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2818 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2819 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2820 env
->excp_vectors
[POWERPC_EXCP_FPA
] = 0x00000E00;
2821 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001000;
2822 env
->excp_vectors
[POWERPC_EXCP_DABR
] = 0x00001C00;
2823 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001C00;
2824 env
->excp_vectors
[POWERPC_EXCP_MEXTBR
] = 0x00001E00;
2825 env
->excp_vectors
[POWERPC_EXCP_NMEXTBR
] = 0x00001F00;
2826 env
->ivor_mask
= 0x0000FFF0UL
;
2827 env
->ivpr_mask
= 0xFFFF0000UL
;
2828 /* Hardware reset vector */
2829 env
->hreset_vector
= 0x00000100UL
;
2833 static void init_excp_MPC8xx (CPUPPCState
*env
)
2835 #if !defined(CONFIG_USER_ONLY)
2836 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2837 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2838 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2839 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2840 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2841 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2842 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2843 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000900;
2844 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2845 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2846 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2847 env
->excp_vectors
[POWERPC_EXCP_FPA
] = 0x00000E00;
2848 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001000;
2849 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00001100;
2850 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00001200;
2851 env
->excp_vectors
[POWERPC_EXCP_ITLBE
] = 0x00001300;
2852 env
->excp_vectors
[POWERPC_EXCP_DTLBE
] = 0x00001400;
2853 env
->excp_vectors
[POWERPC_EXCP_DABR
] = 0x00001C00;
2854 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001C00;
2855 env
->excp_vectors
[POWERPC_EXCP_MEXTBR
] = 0x00001E00;
2856 env
->excp_vectors
[POWERPC_EXCP_NMEXTBR
] = 0x00001F00;
2857 env
->ivor_mask
= 0x0000FFF0UL
;
2858 env
->ivpr_mask
= 0xFFFF0000UL
;
2859 /* Hardware reset vector */
2860 env
->hreset_vector
= 0x00000100UL
;
2864 static void init_excp_G2 (CPUPPCState
*env
)
2866 #if !defined(CONFIG_USER_ONLY)
2867 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2868 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2869 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2870 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2871 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2872 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2873 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2874 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
2875 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2876 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000A00;
2877 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2878 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2879 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
2880 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
2881 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
2882 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
2883 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
2884 /* Hardware reset vector */
2885 env
->hreset_vector
= 0x00000100UL
;
2889 static void init_excp_e200(CPUPPCState
*env
, target_ulong ivpr_mask
)
2891 #if !defined(CONFIG_USER_ONLY)
2892 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000FFC;
2893 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000000;
2894 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000000;
2895 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000000;
2896 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000000;
2897 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000000;
2898 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000000;
2899 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000000;
2900 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000000;
2901 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000000;
2902 env
->excp_vectors
[POWERPC_EXCP_APU
] = 0x00000000;
2903 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000000;
2904 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00000000;
2905 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00000000;
2906 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00000000;
2907 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00000000;
2908 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00000000;
2909 env
->excp_vectors
[POWERPC_EXCP_SPEU
] = 0x00000000;
2910 env
->excp_vectors
[POWERPC_EXCP_EFPDI
] = 0x00000000;
2911 env
->excp_vectors
[POWERPC_EXCP_EFPRI
] = 0x00000000;
2912 env
->ivor_mask
= 0x0000FFF7UL
;
2913 env
->ivpr_mask
= ivpr_mask
;
2914 /* Hardware reset vector */
2915 env
->hreset_vector
= 0xFFFFFFFCUL
;
2919 static void init_excp_BookE (CPUPPCState
*env
)
2921 #if !defined(CONFIG_USER_ONLY)
2922 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000000;
2923 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000000;
2924 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000000;
2925 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000000;
2926 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000000;
2927 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000000;
2928 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000000;
2929 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000000;
2930 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000000;
2931 env
->excp_vectors
[POWERPC_EXCP_APU
] = 0x00000000;
2932 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000000;
2933 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00000000;
2934 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00000000;
2935 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00000000;
2936 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00000000;
2937 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00000000;
2938 env
->ivor_mask
= 0x0000FFF0UL
;
2939 env
->ivpr_mask
= 0xFFFF0000UL
;
2940 /* Hardware reset vector */
2941 env
->hreset_vector
= 0xFFFFFFFCUL
;
2945 static void init_excp_601 (CPUPPCState
*env
)
2947 #if !defined(CONFIG_USER_ONLY)
2948 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2949 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2950 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2951 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2952 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2953 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2954 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2955 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
2956 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2957 env
->excp_vectors
[POWERPC_EXCP_IO
] = 0x00000A00;
2958 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2959 env
->excp_vectors
[POWERPC_EXCP_RUNM
] = 0x00002000;
2960 /* Hardware reset vector */
2961 env
->hreset_vector
= 0x00000100UL
;
2965 static void init_excp_602 (CPUPPCState
*env
)
2967 #if !defined(CONFIG_USER_ONLY)
2968 /* XXX: exception prefix has a special behavior on 602 */
2969 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2970 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2971 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2972 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2973 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2974 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2975 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2976 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
2977 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2978 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2979 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2980 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
2981 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
2982 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
2983 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
2984 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
2985 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001500;
2986 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001600;
2987 /* Hardware reset vector */
2988 env
->hreset_vector
= 0x00000100UL
;
2992 static void init_excp_603 (CPUPPCState
*env
)
2994 #if !defined(CONFIG_USER_ONLY)
2995 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2996 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2997 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2998 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2999 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3000 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3001 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3002 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3003 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3004 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3005 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3006 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3007 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3008 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3009 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3010 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3011 /* Hardware reset vector */
3012 env
->hreset_vector
= 0x00000100UL
;
3016 static void init_excp_604 (CPUPPCState
*env
)
3018 #if !defined(CONFIG_USER_ONLY)
3019 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3020 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3021 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3022 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3023 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3024 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3025 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3026 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3027 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3028 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3029 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3030 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3031 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3032 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3033 /* Hardware reset vector */
3034 env
->hreset_vector
= 0x00000100UL
;
3038 static void init_excp_7x0 (CPUPPCState
*env
)
3040 #if !defined(CONFIG_USER_ONLY)
3041 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3042 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3043 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3044 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3045 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3046 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3047 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3048 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3049 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3050 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3051 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3052 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3053 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3054 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3055 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3056 /* Hardware reset vector */
3057 env
->hreset_vector
= 0x00000100UL
;
3061 static void init_excp_750cl (CPUPPCState
*env
)
3063 #if !defined(CONFIG_USER_ONLY)
3064 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3065 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3066 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3067 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3068 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3069 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3070 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3071 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3072 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3073 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3074 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3075 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3076 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3077 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3078 /* Hardware reset vector */
3079 env
->hreset_vector
= 0x00000100UL
;
3083 static void init_excp_750cx (CPUPPCState
*env
)
3085 #if !defined(CONFIG_USER_ONLY)
3086 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3087 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3088 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3089 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3090 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3091 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3092 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3093 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3094 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3095 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3096 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3097 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3098 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3099 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3100 /* Hardware reset vector */
3101 env
->hreset_vector
= 0x00000100UL
;
3105 /* XXX: Check if this is correct */
3106 static void init_excp_7x5 (CPUPPCState
*env
)
3108 #if !defined(CONFIG_USER_ONLY)
3109 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3110 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3111 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3112 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3113 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3114 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3115 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3116 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3117 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3118 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3119 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3120 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3121 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3122 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3123 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3124 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3125 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3126 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3127 /* Hardware reset vector */
3128 env
->hreset_vector
= 0x00000100UL
;
3132 static void init_excp_7400 (CPUPPCState
*env
)
3134 #if !defined(CONFIG_USER_ONLY)
3135 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3136 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3137 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3138 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3139 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3140 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3141 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3142 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3143 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3144 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3145 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3146 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3147 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3148 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3149 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3150 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001600;
3151 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3152 /* Hardware reset vector */
3153 env
->hreset_vector
= 0x00000100UL
;
3157 static void init_excp_7450 (CPUPPCState
*env
)
3159 #if !defined(CONFIG_USER_ONLY)
3160 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3161 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3162 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3163 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3164 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3165 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3166 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3167 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3168 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3169 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3170 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3171 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3172 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3173 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3174 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3175 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3176 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3177 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3178 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001600;
3179 /* Hardware reset vector */
3180 env
->hreset_vector
= 0x00000100UL
;
3184 #if defined (TARGET_PPC64)
3185 static void init_excp_970 (CPUPPCState
*env
)
3187 #if !defined(CONFIG_USER_ONLY)
3188 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3189 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3190 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3191 env
->excp_vectors
[POWERPC_EXCP_DSEG
] = 0x00000380;
3192 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3193 env
->excp_vectors
[POWERPC_EXCP_ISEG
] = 0x00000480;
3194 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3195 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3196 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3197 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3198 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3199 env
->excp_vectors
[POWERPC_EXCP_HDECR
] = 0x00000980;
3200 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3201 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3202 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3203 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3204 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3205 env
->excp_vectors
[POWERPC_EXCP_MAINT
] = 0x00001600;
3206 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001700;
3207 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001800;
3208 /* Hardware reset vector */
3209 env
->hreset_vector
= 0x0000000000000100ULL
;
3213 static void init_excp_POWER7 (CPUPPCState
*env
)
3215 #if !defined(CONFIG_USER_ONLY)
3216 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3217 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3218 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3219 env
->excp_vectors
[POWERPC_EXCP_DSEG
] = 0x00000380;
3220 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3221 env
->excp_vectors
[POWERPC_EXCP_ISEG
] = 0x00000480;
3222 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3223 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3224 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3225 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3226 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3227 env
->excp_vectors
[POWERPC_EXCP_HDECR
] = 0x00000980;
3228 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3229 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3230 env
->excp_vectors
[POWERPC_EXCP_HDSI
] = 0x00000E00;
3231 env
->excp_vectors
[POWERPC_EXCP_HISI
] = 0x00000E20;
3232 env
->excp_vectors
[POWERPC_EXCP_HV_EMU
] = 0x00000E40;
3233 env
->excp_vectors
[POWERPC_EXCP_HV_MAINT
] = 0x00000E60;
3234 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3235 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3236 env
->excp_vectors
[POWERPC_EXCP_VSXU
] = 0x00000F40;
3237 /* Hardware reset vector */
3238 env
->hreset_vector
= 0x0000000000000100ULL
;
3242 static void init_excp_POWER8(CPUPPCState
*env
)
3244 init_excp_POWER7(env
);
3246 #if !defined(CONFIG_USER_ONLY)
3247 env
->excp_vectors
[POWERPC_EXCP_SDOOR
] = 0x00000A00;
3248 env
->excp_vectors
[POWERPC_EXCP_FU
] = 0x00000F60;
3249 env
->excp_vectors
[POWERPC_EXCP_HV_FU
] = 0x00000F80;
3250 env
->excp_vectors
[POWERPC_EXCP_SDOOR_HV
] = 0x00000E80;
3256 /*****************************************************************************/
3257 /* Power management enable checks */
3258 static int check_pow_none (CPUPPCState
*env
)
3263 static int check_pow_nocheck (CPUPPCState
*env
)
3268 static int check_pow_hid0 (CPUPPCState
*env
)
3270 if (env
->spr
[SPR_HID0
] & 0x00E00000)
3276 static int check_pow_hid0_74xx (CPUPPCState
*env
)
3278 if (env
->spr
[SPR_HID0
] & 0x00600000)
3284 static bool ppc_cpu_interrupts_big_endian_always(PowerPCCPU
*cpu
)
3290 static bool ppc_cpu_interrupts_big_endian_lpcr(PowerPCCPU
*cpu
)
3292 return !(cpu
->env
.spr
[SPR_LPCR
] & LPCR_ILE
);
3296 /*****************************************************************************/
3297 /* PowerPC implementations definitions */
3299 #define POWERPC_FAMILY(_name) \
3301 glue(glue(ppc_, _name), _cpu_family_class_init)(ObjectClass *, void *); \
3303 static const TypeInfo \
3304 glue(glue(ppc_, _name), _cpu_family_type_info) = { \
3305 .name = stringify(_name) "-family-" TYPE_POWERPC_CPU, \
3306 .parent = TYPE_POWERPC_CPU, \
3308 .class_init = glue(glue(ppc_, _name), _cpu_family_class_init), \
3311 static void glue(glue(ppc_, _name), _cpu_family_register_types)(void) \
3313 type_register_static( \
3314 &glue(glue(ppc_, _name), _cpu_family_type_info)); \
3317 type_init(glue(glue(ppc_, _name), _cpu_family_register_types)) \
3319 static void glue(glue(ppc_, _name), _cpu_family_class_init)
3321 static void init_proc_401 (CPUPPCState
*env
)
3324 gen_spr_401_403(env
);
3326 init_excp_4xx_real(env
);
3327 env
->dcache_line_size
= 32;
3328 env
->icache_line_size
= 32;
3329 /* Allocate hardware IRQ controller */
3330 ppc40x_irq_init(ppc_env_get_cpu(env
));
3332 SET_FIT_PERIOD(12, 16, 20, 24);
3333 SET_WDT_PERIOD(16, 20, 24, 28);
3336 POWERPC_FAMILY(401)(ObjectClass
*oc
, void *data
)
3338 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3339 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3341 dc
->desc
= "PowerPC 401";
3342 pcc
->init_proc
= init_proc_401
;
3343 pcc
->check_pow
= check_pow_nocheck
;
3344 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3345 PPC_WRTEE
| PPC_DCR
|
3346 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3348 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3349 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3350 pcc
->msr_mask
= (1ull << MSR_KEY
) |
3359 pcc
->mmu_model
= POWERPC_MMU_REAL
;
3360 pcc
->excp_model
= POWERPC_EXCP_40x
;
3361 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3362 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3363 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3364 POWERPC_FLAG_BUS_CLK
;
3367 static void init_proc_401x2 (CPUPPCState
*env
)
3370 gen_spr_401_403(env
);
3372 gen_spr_compress(env
);
3373 /* Memory management */
3374 #if !defined(CONFIG_USER_ONLY)
3378 env
->tlb_type
= TLB_EMB
;
3380 init_excp_4xx_softmmu(env
);
3381 env
->dcache_line_size
= 32;
3382 env
->icache_line_size
= 32;
3383 /* Allocate hardware IRQ controller */
3384 ppc40x_irq_init(ppc_env_get_cpu(env
));
3386 SET_FIT_PERIOD(12, 16, 20, 24);
3387 SET_WDT_PERIOD(16, 20, 24, 28);
3390 POWERPC_FAMILY(401x2
)(ObjectClass
*oc
, void *data
)
3392 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3393 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3395 dc
->desc
= "PowerPC 401x2";
3396 pcc
->init_proc
= init_proc_401x2
;
3397 pcc
->check_pow
= check_pow_nocheck
;
3398 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3399 PPC_DCR
| PPC_WRTEE
|
3400 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3401 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3402 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3403 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3404 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3405 pcc
->msr_mask
= (1ull << 20) |
3417 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3418 pcc
->excp_model
= POWERPC_EXCP_40x
;
3419 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3420 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3421 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3422 POWERPC_FLAG_BUS_CLK
;
3425 static void init_proc_401x3 (CPUPPCState
*env
)
3428 gen_spr_401_403(env
);
3431 gen_spr_compress(env
);
3432 init_excp_4xx_softmmu(env
);
3433 env
->dcache_line_size
= 32;
3434 env
->icache_line_size
= 32;
3435 /* Allocate hardware IRQ controller */
3436 ppc40x_irq_init(ppc_env_get_cpu(env
));
3438 SET_FIT_PERIOD(12, 16, 20, 24);
3439 SET_WDT_PERIOD(16, 20, 24, 28);
3442 POWERPC_FAMILY(401x3
)(ObjectClass
*oc
, void *data
)
3444 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3445 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3447 dc
->desc
= "PowerPC 401x3";
3448 pcc
->init_proc
= init_proc_401x3
;
3449 pcc
->check_pow
= check_pow_nocheck
;
3450 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3451 PPC_DCR
| PPC_WRTEE
|
3452 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3453 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3454 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3455 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3456 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3457 pcc
->msr_mask
= (1ull << 20) |
3470 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3471 pcc
->excp_model
= POWERPC_EXCP_40x
;
3472 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3473 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3474 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3475 POWERPC_FLAG_BUS_CLK
;
3478 static void init_proc_IOP480 (CPUPPCState
*env
)
3481 gen_spr_401_403(env
);
3483 gen_spr_compress(env
);
3484 /* Memory management */
3485 #if !defined(CONFIG_USER_ONLY)
3489 env
->tlb_type
= TLB_EMB
;
3491 init_excp_4xx_softmmu(env
);
3492 env
->dcache_line_size
= 32;
3493 env
->icache_line_size
= 32;
3494 /* Allocate hardware IRQ controller */
3495 ppc40x_irq_init(ppc_env_get_cpu(env
));
3497 SET_FIT_PERIOD(8, 12, 16, 20);
3498 SET_WDT_PERIOD(16, 20, 24, 28);
3501 POWERPC_FAMILY(IOP480
)(ObjectClass
*oc
, void *data
)
3503 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3504 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3506 dc
->desc
= "IOP480";
3507 pcc
->init_proc
= init_proc_IOP480
;
3508 pcc
->check_pow
= check_pow_nocheck
;
3509 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3510 PPC_DCR
| PPC_WRTEE
|
3511 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3512 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3513 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3514 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3515 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3516 pcc
->msr_mask
= (1ull << 20) |
3528 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3529 pcc
->excp_model
= POWERPC_EXCP_40x
;
3530 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3531 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3532 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3533 POWERPC_FLAG_BUS_CLK
;
3536 static void init_proc_403 (CPUPPCState
*env
)
3539 gen_spr_401_403(env
);
3541 gen_spr_403_real(env
);
3542 init_excp_4xx_real(env
);
3543 env
->dcache_line_size
= 32;
3544 env
->icache_line_size
= 32;
3545 /* Allocate hardware IRQ controller */
3546 ppc40x_irq_init(ppc_env_get_cpu(env
));
3548 SET_FIT_PERIOD(8, 12, 16, 20);
3549 SET_WDT_PERIOD(16, 20, 24, 28);
3552 POWERPC_FAMILY(403)(ObjectClass
*oc
, void *data
)
3554 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3555 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3557 dc
->desc
= "PowerPC 403";
3558 pcc
->init_proc
= init_proc_403
;
3559 pcc
->check_pow
= check_pow_nocheck
;
3560 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3561 PPC_DCR
| PPC_WRTEE
|
3562 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3564 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3565 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3566 pcc
->msr_mask
= (1ull << MSR_POW
) |
3575 pcc
->mmu_model
= POWERPC_MMU_REAL
;
3576 pcc
->excp_model
= POWERPC_EXCP_40x
;
3577 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3578 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3579 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_PX
|
3580 POWERPC_FLAG_BUS_CLK
;
3583 static void init_proc_403GCX (CPUPPCState
*env
)
3586 gen_spr_401_403(env
);
3588 gen_spr_403_real(env
);
3589 gen_spr_403_mmu(env
);
3590 /* Bus access control */
3591 /* not emulated, as QEMU never does speculative access */
3592 spr_register(env
, SPR_40x_SGR
, "SGR",
3593 SPR_NOACCESS
, SPR_NOACCESS
,
3594 &spr_read_generic
, &spr_write_generic
,
3596 /* not emulated, as QEMU do not emulate caches */
3597 spr_register(env
, SPR_40x_DCWR
, "DCWR",
3598 SPR_NOACCESS
, SPR_NOACCESS
,
3599 &spr_read_generic
, &spr_write_generic
,
3601 /* Memory management */
3602 #if !defined(CONFIG_USER_ONLY)
3606 env
->tlb_type
= TLB_EMB
;
3608 init_excp_4xx_softmmu(env
);
3609 env
->dcache_line_size
= 32;
3610 env
->icache_line_size
= 32;
3611 /* Allocate hardware IRQ controller */
3612 ppc40x_irq_init(ppc_env_get_cpu(env
));
3614 SET_FIT_PERIOD(8, 12, 16, 20);
3615 SET_WDT_PERIOD(16, 20, 24, 28);
3618 POWERPC_FAMILY(403GCX
)(ObjectClass
*oc
, void *data
)
3620 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3621 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3623 dc
->desc
= "PowerPC 403 GCX";
3624 pcc
->init_proc
= init_proc_403GCX
;
3625 pcc
->check_pow
= check_pow_nocheck
;
3626 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3627 PPC_DCR
| PPC_WRTEE
|
3628 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3630 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3631 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3632 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3633 pcc
->msr_mask
= (1ull << MSR_POW
) |
3642 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3643 pcc
->excp_model
= POWERPC_EXCP_40x
;
3644 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3645 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3646 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_PX
|
3647 POWERPC_FLAG_BUS_CLK
;
3650 static void init_proc_405 (CPUPPCState
*env
)
3656 /* Bus access control */
3657 /* not emulated, as QEMU never does speculative access */
3658 spr_register(env
, SPR_40x_SGR
, "SGR",
3659 SPR_NOACCESS
, SPR_NOACCESS
,
3660 &spr_read_generic
, &spr_write_generic
,
3662 /* not emulated, as QEMU do not emulate caches */
3663 spr_register(env
, SPR_40x_DCWR
, "DCWR",
3664 SPR_NOACCESS
, SPR_NOACCESS
,
3665 &spr_read_generic
, &spr_write_generic
,
3667 /* Memory management */
3668 #if !defined(CONFIG_USER_ONLY)
3672 env
->tlb_type
= TLB_EMB
;
3674 init_excp_4xx_softmmu(env
);
3675 env
->dcache_line_size
= 32;
3676 env
->icache_line_size
= 32;
3677 /* Allocate hardware IRQ controller */
3678 ppc40x_irq_init(ppc_env_get_cpu(env
));
3680 SET_FIT_PERIOD(8, 12, 16, 20);
3681 SET_WDT_PERIOD(16, 20, 24, 28);
3684 POWERPC_FAMILY(405)(ObjectClass
*oc
, void *data
)
3686 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3687 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3689 dc
->desc
= "PowerPC 405";
3690 pcc
->init_proc
= init_proc_405
;
3691 pcc
->check_pow
= check_pow_nocheck
;
3692 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3693 PPC_DCR
| PPC_WRTEE
|
3694 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3695 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3696 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3697 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3698 PPC_4xx_COMMON
| PPC_405_MAC
| PPC_40x_EXCP
;
3699 pcc
->msr_mask
= (1ull << MSR_POW
) |
3708 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx
;
3709 pcc
->excp_model
= POWERPC_EXCP_40x
;
3710 pcc
->bus_model
= PPC_FLAGS_INPUT_405
;
3711 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3712 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3713 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3716 static void init_proc_440EP (CPUPPCState
*env
)
3720 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3722 gen_spr_usprgh(env
);
3723 /* Processor identification */
3724 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3725 SPR_NOACCESS
, SPR_NOACCESS
,
3726 &spr_read_generic
, &spr_write_pir
,
3728 /* XXX : not implemented */
3729 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
3730 SPR_NOACCESS
, SPR_NOACCESS
,
3731 &spr_read_generic
, &spr_write_generic
,
3733 /* XXX : not implemented */
3734 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
3735 SPR_NOACCESS
, SPR_NOACCESS
,
3736 &spr_read_generic
, &spr_write_generic
,
3738 /* XXX : not implemented */
3739 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
3740 SPR_NOACCESS
, SPR_NOACCESS
,
3741 &spr_read_generic
, &spr_write_generic
,
3743 /* XXX : not implemented */
3744 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
3745 SPR_NOACCESS
, SPR_NOACCESS
,
3746 &spr_read_generic
, &spr_write_generic
,
3748 /* XXX : not implemented */
3749 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
3750 SPR_NOACCESS
, SPR_NOACCESS
,
3751 &spr_read_generic
, &spr_write_generic
,
3753 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
3754 SPR_NOACCESS
, SPR_NOACCESS
,
3755 &spr_read_generic
, &spr_write_generic
,
3757 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
3758 SPR_NOACCESS
, SPR_NOACCESS
,
3759 &spr_read_generic
, &spr_write_generic
,
3761 /* XXX : not implemented */
3762 spr_register(env
, SPR_440_CCR1
, "CCR1",
3763 SPR_NOACCESS
, SPR_NOACCESS
,
3764 &spr_read_generic
, &spr_write_generic
,
3766 /* Memory management */
3767 #if !defined(CONFIG_USER_ONLY)
3771 env
->tlb_type
= TLB_EMB
;
3773 init_excp_BookE(env
);
3774 env
->dcache_line_size
= 32;
3775 env
->icache_line_size
= 32;
3776 ppc40x_irq_init(ppc_env_get_cpu(env
));
3778 SET_FIT_PERIOD(12, 16, 20, 24);
3779 SET_WDT_PERIOD(20, 24, 28, 32);
3782 POWERPC_FAMILY(440EP
)(ObjectClass
*oc
, void *data
)
3784 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3785 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3787 dc
->desc
= "PowerPC 440 EP";
3788 pcc
->init_proc
= init_proc_440EP
;
3789 pcc
->check_pow
= check_pow_nocheck
;
3790 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3791 PPC_FLOAT
| PPC_FLOAT_FRES
| PPC_FLOAT_FSEL
|
3792 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
3794 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
3795 PPC_CACHE
| PPC_CACHE_ICBI
|
3796 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3797 PPC_MEM_TLBSYNC
| PPC_MFTB
|
3798 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3800 pcc
->msr_mask
= (1ull << MSR_POW
) |
3812 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3813 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3814 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3815 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3816 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3817 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3820 static void init_proc_440GP (CPUPPCState
*env
)
3824 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3826 gen_spr_usprgh(env
);
3827 /* Processor identification */
3828 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3829 SPR_NOACCESS
, SPR_NOACCESS
,
3830 &spr_read_generic
, &spr_write_pir
,
3832 /* XXX : not implemented */
3833 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
3834 SPR_NOACCESS
, SPR_NOACCESS
,
3835 &spr_read_generic
, &spr_write_generic
,
3837 /* XXX : not implemented */
3838 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
3839 SPR_NOACCESS
, SPR_NOACCESS
,
3840 &spr_read_generic
, &spr_write_generic
,
3842 /* XXX : not implemented */
3843 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
3844 SPR_NOACCESS
, SPR_NOACCESS
,
3845 &spr_read_generic
, &spr_write_generic
,
3847 /* XXX : not implemented */
3848 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
3849 SPR_NOACCESS
, SPR_NOACCESS
,
3850 &spr_read_generic
, &spr_write_generic
,
3852 /* Memory management */
3853 #if !defined(CONFIG_USER_ONLY)
3857 env
->tlb_type
= TLB_EMB
;
3859 init_excp_BookE(env
);
3860 env
->dcache_line_size
= 32;
3861 env
->icache_line_size
= 32;
3862 /* XXX: TODO: allocate internal IRQ controller */
3864 SET_FIT_PERIOD(12, 16, 20, 24);
3865 SET_WDT_PERIOD(20, 24, 28, 32);
3868 POWERPC_FAMILY(440GP
)(ObjectClass
*oc
, void *data
)
3870 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3871 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3873 dc
->desc
= "PowerPC 440 GP";
3874 pcc
->init_proc
= init_proc_440GP
;
3875 pcc
->check_pow
= check_pow_nocheck
;
3876 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3877 PPC_DCR
| PPC_DCRX
| PPC_WRTEE
| PPC_MFAPIDI
|
3878 PPC_CACHE
| PPC_CACHE_ICBI
|
3879 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3880 PPC_MEM_TLBSYNC
| PPC_TLBIVA
| PPC_MFTB
|
3881 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3883 pcc
->msr_mask
= (1ull << MSR_POW
) |
3895 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3896 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3897 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3898 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3899 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3900 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3903 static void init_proc_440x4 (CPUPPCState
*env
)
3907 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3909 gen_spr_usprgh(env
);
3910 /* Processor identification */
3911 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3912 SPR_NOACCESS
, SPR_NOACCESS
,
3913 &spr_read_generic
, &spr_write_pir
,
3915 /* XXX : not implemented */
3916 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
3917 SPR_NOACCESS
, SPR_NOACCESS
,
3918 &spr_read_generic
, &spr_write_generic
,
3920 /* XXX : not implemented */
3921 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
3922 SPR_NOACCESS
, SPR_NOACCESS
,
3923 &spr_read_generic
, &spr_write_generic
,
3925 /* XXX : not implemented */
3926 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
3927 SPR_NOACCESS
, SPR_NOACCESS
,
3928 &spr_read_generic
, &spr_write_generic
,
3930 /* XXX : not implemented */
3931 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
3932 SPR_NOACCESS
, SPR_NOACCESS
,
3933 &spr_read_generic
, &spr_write_generic
,
3935 /* Memory management */
3936 #if !defined(CONFIG_USER_ONLY)
3940 env
->tlb_type
= TLB_EMB
;
3942 init_excp_BookE(env
);
3943 env
->dcache_line_size
= 32;
3944 env
->icache_line_size
= 32;
3945 /* XXX: TODO: allocate internal IRQ controller */
3947 SET_FIT_PERIOD(12, 16, 20, 24);
3948 SET_WDT_PERIOD(20, 24, 28, 32);
3951 POWERPC_FAMILY(440x4
)(ObjectClass
*oc
, void *data
)
3953 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3954 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3956 dc
->desc
= "PowerPC 440x4";
3957 pcc
->init_proc
= init_proc_440x4
;
3958 pcc
->check_pow
= check_pow_nocheck
;
3959 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3960 PPC_DCR
| PPC_WRTEE
|
3961 PPC_CACHE
| PPC_CACHE_ICBI
|
3962 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3963 PPC_MEM_TLBSYNC
| PPC_MFTB
|
3964 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3966 pcc
->msr_mask
= (1ull << MSR_POW
) |
3978 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3979 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3980 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3981 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3982 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3983 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3986 static void init_proc_440x5 (CPUPPCState
*env
)
3990 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3992 gen_spr_usprgh(env
);
3993 /* Processor identification */
3994 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3995 SPR_NOACCESS
, SPR_NOACCESS
,
3996 &spr_read_generic
, &spr_write_pir
,
3998 /* XXX : not implemented */
3999 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4000 SPR_NOACCESS
, SPR_NOACCESS
,
4001 &spr_read_generic
, &spr_write_generic
,
4003 /* XXX : not implemented */
4004 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4005 SPR_NOACCESS
, SPR_NOACCESS
,
4006 &spr_read_generic
, &spr_write_generic
,
4008 /* XXX : not implemented */
4009 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
4010 SPR_NOACCESS
, SPR_NOACCESS
,
4011 &spr_read_generic
, &spr_write_generic
,
4013 /* XXX : not implemented */
4014 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
4015 SPR_NOACCESS
, SPR_NOACCESS
,
4016 &spr_read_generic
, &spr_write_generic
,
4018 /* XXX : not implemented */
4019 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
4020 SPR_NOACCESS
, SPR_NOACCESS
,
4021 &spr_read_generic
, &spr_write_generic
,
4023 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
4024 SPR_NOACCESS
, SPR_NOACCESS
,
4025 &spr_read_generic
, &spr_write_generic
,
4027 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
4028 SPR_NOACCESS
, SPR_NOACCESS
,
4029 &spr_read_generic
, &spr_write_generic
,
4031 /* XXX : not implemented */
4032 spr_register(env
, SPR_440_CCR1
, "CCR1",
4033 SPR_NOACCESS
, SPR_NOACCESS
,
4034 &spr_read_generic
, &spr_write_generic
,
4036 /* Memory management */
4037 #if !defined(CONFIG_USER_ONLY)
4041 env
->tlb_type
= TLB_EMB
;
4043 init_excp_BookE(env
);
4044 env
->dcache_line_size
= 32;
4045 env
->icache_line_size
= 32;
4046 ppc40x_irq_init(ppc_env_get_cpu(env
));
4048 SET_FIT_PERIOD(12, 16, 20, 24);
4049 SET_WDT_PERIOD(20, 24, 28, 32);
4052 POWERPC_FAMILY(440x5
)(ObjectClass
*oc
, void *data
)
4054 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4055 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4057 dc
->desc
= "PowerPC 440x5";
4058 pcc
->init_proc
= init_proc_440x5
;
4059 pcc
->check_pow
= check_pow_nocheck
;
4060 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4061 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
4062 PPC_CACHE
| PPC_CACHE_ICBI
|
4063 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4064 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4065 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4067 pcc
->msr_mask
= (1ull << MSR_POW
) |
4079 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4080 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4081 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4082 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4083 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4084 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4087 POWERPC_FAMILY(440x5wDFPU
)(ObjectClass
*oc
, void *data
)
4089 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4090 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4092 dc
->desc
= "PowerPC 440x5 with double precision FPU";
4093 pcc
->init_proc
= init_proc_440x5
;
4094 pcc
->check_pow
= check_pow_nocheck
;
4095 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4096 PPC_FLOAT
| PPC_FLOAT_FSQRT
|
4098 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
4099 PPC_CACHE
| PPC_CACHE_ICBI
|
4100 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4101 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4102 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4104 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
4105 pcc
->msr_mask
= (1ull << MSR_POW
) |
4117 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4118 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4119 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4120 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4121 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4122 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4125 static void init_proc_460 (CPUPPCState
*env
)
4129 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
4131 gen_spr_usprgh(env
);
4132 /* Processor identification */
4133 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4134 SPR_NOACCESS
, SPR_NOACCESS
,
4135 &spr_read_generic
, &spr_write_pir
,
4137 /* XXX : not implemented */
4138 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4139 SPR_NOACCESS
, SPR_NOACCESS
,
4140 &spr_read_generic
, &spr_write_generic
,
4142 /* XXX : not implemented */
4143 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4144 SPR_NOACCESS
, SPR_NOACCESS
,
4145 &spr_read_generic
, &spr_write_generic
,
4147 /* XXX : not implemented */
4148 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
4149 SPR_NOACCESS
, SPR_NOACCESS
,
4150 &spr_read_generic
, &spr_write_generic
,
4152 /* XXX : not implemented */
4153 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
4154 SPR_NOACCESS
, SPR_NOACCESS
,
4155 &spr_read_generic
, &spr_write_generic
,
4157 /* XXX : not implemented */
4158 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
4159 SPR_NOACCESS
, SPR_NOACCESS
,
4160 &spr_read_generic
, &spr_write_generic
,
4162 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
4163 SPR_NOACCESS
, SPR_NOACCESS
,
4164 &spr_read_generic
, &spr_write_generic
,
4166 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
4167 SPR_NOACCESS
, SPR_NOACCESS
,
4168 &spr_read_generic
, &spr_write_generic
,
4170 /* XXX : not implemented */
4171 spr_register(env
, SPR_440_CCR1
, "CCR1",
4172 SPR_NOACCESS
, SPR_NOACCESS
,
4173 &spr_read_generic
, &spr_write_generic
,
4175 /* XXX : not implemented */
4176 spr_register(env
, SPR_DCRIPR
, "SPR_DCRIPR",
4177 &spr_read_generic
, &spr_write_generic
,
4178 &spr_read_generic
, &spr_write_generic
,
4180 /* Memory management */
4181 #if !defined(CONFIG_USER_ONLY)
4185 env
->tlb_type
= TLB_EMB
;
4187 init_excp_BookE(env
);
4188 env
->dcache_line_size
= 32;
4189 env
->icache_line_size
= 32;
4190 /* XXX: TODO: allocate internal IRQ controller */
4192 SET_FIT_PERIOD(12, 16, 20, 24);
4193 SET_WDT_PERIOD(20, 24, 28, 32);
4196 POWERPC_FAMILY(460)(ObjectClass
*oc
, void *data
)
4198 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4199 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4201 dc
->desc
= "PowerPC 460 (guessed)";
4202 pcc
->init_proc
= init_proc_460
;
4203 pcc
->check_pow
= check_pow_nocheck
;
4204 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4205 PPC_DCR
| PPC_DCRX
| PPC_DCRUX
|
4206 PPC_WRTEE
| PPC_MFAPIDI
| PPC_MFTB
|
4207 PPC_CACHE
| PPC_CACHE_ICBI
|
4208 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4209 PPC_MEM_TLBSYNC
| PPC_TLBIVA
|
4210 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4212 pcc
->msr_mask
= (1ull << MSR_POW
) |
4224 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4225 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4226 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4227 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4228 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4229 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4232 static void init_proc_460F (CPUPPCState
*env
)
4236 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
4238 gen_spr_usprgh(env
);
4239 /* Processor identification */
4240 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4241 SPR_NOACCESS
, SPR_NOACCESS
,
4242 &spr_read_generic
, &spr_write_pir
,
4244 /* XXX : not implemented */
4245 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4246 SPR_NOACCESS
, SPR_NOACCESS
,
4247 &spr_read_generic
, &spr_write_generic
,
4249 /* XXX : not implemented */
4250 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4251 SPR_NOACCESS
, SPR_NOACCESS
,
4252 &spr_read_generic
, &spr_write_generic
,
4254 /* XXX : not implemented */
4255 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
4256 SPR_NOACCESS
, SPR_NOACCESS
,
4257 &spr_read_generic
, &spr_write_generic
,
4259 /* XXX : not implemented */
4260 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
4261 SPR_NOACCESS
, SPR_NOACCESS
,
4262 &spr_read_generic
, &spr_write_generic
,
4264 /* XXX : not implemented */
4265 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
4266 SPR_NOACCESS
, SPR_NOACCESS
,
4267 &spr_read_generic
, &spr_write_generic
,
4269 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
4270 SPR_NOACCESS
, SPR_NOACCESS
,
4271 &spr_read_generic
, &spr_write_generic
,
4273 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
4274 SPR_NOACCESS
, SPR_NOACCESS
,
4275 &spr_read_generic
, &spr_write_generic
,
4277 /* XXX : not implemented */
4278 spr_register(env
, SPR_440_CCR1
, "CCR1",
4279 SPR_NOACCESS
, SPR_NOACCESS
,
4280 &spr_read_generic
, &spr_write_generic
,
4282 /* XXX : not implemented */
4283 spr_register(env
, SPR_DCRIPR
, "SPR_DCRIPR",
4284 &spr_read_generic
, &spr_write_generic
,
4285 &spr_read_generic
, &spr_write_generic
,
4287 /* Memory management */
4288 #if !defined(CONFIG_USER_ONLY)
4292 env
->tlb_type
= TLB_EMB
;
4294 init_excp_BookE(env
);
4295 env
->dcache_line_size
= 32;
4296 env
->icache_line_size
= 32;
4297 /* XXX: TODO: allocate internal IRQ controller */
4299 SET_FIT_PERIOD(12, 16, 20, 24);
4300 SET_WDT_PERIOD(20, 24, 28, 32);
4303 POWERPC_FAMILY(460F
)(ObjectClass
*oc
, void *data
)
4305 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4306 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4308 dc
->desc
= "PowerPC 460F (guessed)";
4309 pcc
->init_proc
= init_proc_460F
;
4310 pcc
->check_pow
= check_pow_nocheck
;
4311 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4312 PPC_FLOAT
| PPC_FLOAT_FRES
| PPC_FLOAT_FSEL
|
4313 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
4314 PPC_FLOAT_STFIWX
| PPC_MFTB
|
4315 PPC_DCR
| PPC_DCRX
| PPC_DCRUX
|
4316 PPC_WRTEE
| PPC_MFAPIDI
|
4317 PPC_CACHE
| PPC_CACHE_ICBI
|
4318 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4319 PPC_MEM_TLBSYNC
| PPC_TLBIVA
|
4320 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4322 pcc
->msr_mask
= (1ull << MSR_POW
) |
4334 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4335 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4336 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4337 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4338 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4339 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4342 static void init_proc_MPC5xx (CPUPPCState
*env
)
4346 gen_spr_5xx_8xx(env
);
4348 init_excp_MPC5xx(env
);
4349 env
->dcache_line_size
= 32;
4350 env
->icache_line_size
= 32;
4351 /* XXX: TODO: allocate internal IRQ controller */
4354 POWERPC_FAMILY(MPC5xx
)(ObjectClass
*oc
, void *data
)
4356 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4357 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4359 dc
->desc
= "Freescale 5xx cores (aka RCPU)";
4360 pcc
->init_proc
= init_proc_MPC5xx
;
4361 pcc
->check_pow
= check_pow_none
;
4362 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4363 PPC_MEM_EIEIO
| PPC_MEM_SYNC
|
4364 PPC_CACHE_ICBI
| PPC_FLOAT
| PPC_FLOAT_STFIWX
|
4366 pcc
->msr_mask
= (1ull << MSR_ILE
) |
4378 pcc
->mmu_model
= POWERPC_MMU_REAL
;
4379 pcc
->excp_model
= POWERPC_EXCP_603
;
4380 pcc
->bus_model
= PPC_FLAGS_INPUT_RCPU
;
4381 pcc
->bfd_mach
= bfd_mach_ppc_505
;
4382 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
4383 POWERPC_FLAG_BUS_CLK
;
4386 static void init_proc_MPC8xx (CPUPPCState
*env
)
4390 gen_spr_5xx_8xx(env
);
4392 init_excp_MPC8xx(env
);
4393 env
->dcache_line_size
= 32;
4394 env
->icache_line_size
= 32;
4395 /* XXX: TODO: allocate internal IRQ controller */
4398 POWERPC_FAMILY(MPC8xx
)(ObjectClass
*oc
, void *data
)
4400 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4401 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4403 dc
->desc
= "Freescale 8xx cores (aka PowerQUICC)";
4404 pcc
->init_proc
= init_proc_MPC8xx
;
4405 pcc
->check_pow
= check_pow_none
;
4406 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4407 PPC_MEM_EIEIO
| PPC_MEM_SYNC
|
4408 PPC_CACHE_ICBI
| PPC_MFTB
;
4409 pcc
->msr_mask
= (1ull << MSR_ILE
) |
4421 pcc
->mmu_model
= POWERPC_MMU_MPC8xx
;
4422 pcc
->excp_model
= POWERPC_EXCP_603
;
4423 pcc
->bus_model
= PPC_FLAGS_INPUT_RCPU
;
4424 pcc
->bfd_mach
= bfd_mach_ppc_860
;
4425 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
4426 POWERPC_FLAG_BUS_CLK
;
4429 /* Freescale 82xx cores (aka PowerQUICC-II) */
4431 static void init_proc_G2 (CPUPPCState
*env
)
4433 gen_spr_ne_601(env
);
4435 gen_spr_G2_755(env
);
4439 /* External access control */
4440 /* XXX : not implemented */
4441 spr_register(env
, SPR_EAR
, "EAR",
4442 SPR_NOACCESS
, SPR_NOACCESS
,
4443 &spr_read_generic
, &spr_write_generic
,
4445 /* Hardware implementation register */
4446 /* XXX : not implemented */
4447 spr_register(env
, SPR_HID0
, "HID0",
4448 SPR_NOACCESS
, SPR_NOACCESS
,
4449 &spr_read_generic
, &spr_write_generic
,
4451 /* XXX : not implemented */
4452 spr_register(env
, SPR_HID1
, "HID1",
4453 SPR_NOACCESS
, SPR_NOACCESS
,
4454 &spr_read_generic
, &spr_write_generic
,
4456 /* XXX : not implemented */
4457 spr_register(env
, SPR_HID2
, "HID2",
4458 SPR_NOACCESS
, SPR_NOACCESS
,
4459 &spr_read_generic
, &spr_write_generic
,
4461 /* Memory management */
4464 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4466 env
->dcache_line_size
= 32;
4467 env
->icache_line_size
= 32;
4468 /* Allocate hardware IRQ controller */
4469 ppc6xx_irq_init(ppc_env_get_cpu(env
));
4472 POWERPC_FAMILY(G2
)(ObjectClass
*oc
, void *data
)
4474 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4475 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4477 dc
->desc
= "PowerPC G2";
4478 pcc
->init_proc
= init_proc_G2
;
4479 pcc
->check_pow
= check_pow_hid0
;
4480 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4481 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4483 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4484 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4485 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4486 PPC_SEGMENT
| PPC_EXTERN
;
4487 pcc
->msr_mask
= (1ull << MSR_POW
) |
4488 (1ull << MSR_TGPR
) |
4502 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4503 pcc
->excp_model
= POWERPC_EXCP_G2
;
4504 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4505 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
4506 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4507 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4510 static void init_proc_G2LE (CPUPPCState
*env
)
4512 gen_spr_ne_601(env
);
4514 gen_spr_G2_755(env
);
4518 /* External access control */
4519 /* XXX : not implemented */
4520 spr_register(env
, SPR_EAR
, "EAR",
4521 SPR_NOACCESS
, SPR_NOACCESS
,
4522 &spr_read_generic
, &spr_write_generic
,
4524 /* Hardware implementation register */
4525 /* XXX : not implemented */
4526 spr_register(env
, SPR_HID0
, "HID0",
4527 SPR_NOACCESS
, SPR_NOACCESS
,
4528 &spr_read_generic
, &spr_write_generic
,
4530 /* XXX : not implemented */
4531 spr_register(env
, SPR_HID1
, "HID1",
4532 SPR_NOACCESS
, SPR_NOACCESS
,
4533 &spr_read_generic
, &spr_write_generic
,
4535 /* XXX : not implemented */
4536 spr_register(env
, SPR_HID2
, "HID2",
4537 SPR_NOACCESS
, SPR_NOACCESS
,
4538 &spr_read_generic
, &spr_write_generic
,
4541 /* Memory management */
4544 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4546 env
->dcache_line_size
= 32;
4547 env
->icache_line_size
= 32;
4548 /* Allocate hardware IRQ controller */
4549 ppc6xx_irq_init(ppc_env_get_cpu(env
));
4552 POWERPC_FAMILY(G2LE
)(ObjectClass
*oc
, void *data
)
4554 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4555 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4557 dc
->desc
= "PowerPC G2LE";
4558 pcc
->init_proc
= init_proc_G2LE
;
4559 pcc
->check_pow
= check_pow_hid0
;
4560 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4561 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4563 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4564 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4565 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4566 PPC_SEGMENT
| PPC_EXTERN
;
4567 pcc
->msr_mask
= (1ull << MSR_POW
) |
4568 (1ull << MSR_TGPR
) |
4584 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4585 pcc
->excp_model
= POWERPC_EXCP_G2
;
4586 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4587 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
4588 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4589 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4592 static void init_proc_e200 (CPUPPCState
*env
)
4596 gen_spr_BookE(env
, 0x000000070000FFFFULL
);
4597 /* XXX : not implemented */
4598 spr_register(env
, SPR_BOOKE_SPEFSCR
, "SPEFSCR",
4599 &spr_read_spefscr
, &spr_write_spefscr
,
4600 &spr_read_spefscr
, &spr_write_spefscr
,
4602 /* Memory management */
4603 gen_spr_BookE206(env
, 0x0000005D, NULL
);
4604 /* XXX : not implemented */
4605 spr_register(env
, SPR_HID0
, "HID0",
4606 SPR_NOACCESS
, SPR_NOACCESS
,
4607 &spr_read_generic
, &spr_write_generic
,
4609 /* XXX : not implemented */
4610 spr_register(env
, SPR_HID1
, "HID1",
4611 SPR_NOACCESS
, SPR_NOACCESS
,
4612 &spr_read_generic
, &spr_write_generic
,
4614 /* XXX : not implemented */
4615 spr_register(env
, SPR_Exxx_ALTCTXCR
, "ALTCTXCR",
4616 SPR_NOACCESS
, SPR_NOACCESS
,
4617 &spr_read_generic
, &spr_write_generic
,
4619 /* XXX : not implemented */
4620 spr_register(env
, SPR_Exxx_BUCSR
, "BUCSR",
4621 SPR_NOACCESS
, SPR_NOACCESS
,
4622 &spr_read_generic
, &spr_write_generic
,
4624 /* XXX : not implemented */
4625 spr_register(env
, SPR_Exxx_CTXCR
, "CTXCR",
4626 SPR_NOACCESS
, SPR_NOACCESS
,
4627 &spr_read_generic
, &spr_write_generic
,
4629 /* XXX : not implemented */
4630 spr_register(env
, SPR_Exxx_DBCNT
, "DBCNT",
4631 SPR_NOACCESS
, SPR_NOACCESS
,
4632 &spr_read_generic
, &spr_write_generic
,
4634 /* XXX : not implemented */
4635 spr_register(env
, SPR_Exxx_DBCR3
, "DBCR3",
4636 SPR_NOACCESS
, SPR_NOACCESS
,
4637 &spr_read_generic
, &spr_write_generic
,
4639 /* XXX : not implemented */
4640 spr_register(env
, SPR_Exxx_L1CFG0
, "L1CFG0",
4641 &spr_read_generic
, SPR_NOACCESS
,
4642 &spr_read_generic
, SPR_NOACCESS
,
4644 /* XXX : not implemented */
4645 spr_register(env
, SPR_Exxx_L1CSR0
, "L1CSR0",
4646 SPR_NOACCESS
, SPR_NOACCESS
,
4647 &spr_read_generic
, &spr_write_generic
,
4649 /* XXX : not implemented */
4650 spr_register(env
, SPR_Exxx_L1FINV0
, "L1FINV0",
4651 SPR_NOACCESS
, SPR_NOACCESS
,
4652 &spr_read_generic
, &spr_write_generic
,
4654 /* XXX : not implemented */
4655 spr_register(env
, SPR_BOOKE_TLB0CFG
, "TLB0CFG",
4656 SPR_NOACCESS
, SPR_NOACCESS
,
4657 &spr_read_generic
, &spr_write_generic
,
4659 /* XXX : not implemented */
4660 spr_register(env
, SPR_BOOKE_TLB1CFG
, "TLB1CFG",
4661 SPR_NOACCESS
, SPR_NOACCESS
,
4662 &spr_read_generic
, &spr_write_generic
,
4664 /* XXX : not implemented */
4665 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4666 SPR_NOACCESS
, SPR_NOACCESS
,
4667 &spr_read_generic
, &spr_write_generic
,
4669 /* XXX : not implemented */
4670 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4671 SPR_NOACCESS
, SPR_NOACCESS
,
4672 &spr_read_generic
, &spr_write_generic
,
4674 /* XXX : not implemented */
4675 spr_register(env
, SPR_MMUCSR0
, "MMUCSR0",
4676 SPR_NOACCESS
, SPR_NOACCESS
,
4677 &spr_read_generic
, &spr_write_generic
,
4678 0x00000000); /* TOFIX */
4679 spr_register(env
, SPR_BOOKE_DSRR0
, "DSRR0",
4680 SPR_NOACCESS
, SPR_NOACCESS
,
4681 &spr_read_generic
, &spr_write_generic
,
4683 spr_register(env
, SPR_BOOKE_DSRR1
, "DSRR1",
4684 SPR_NOACCESS
, SPR_NOACCESS
,
4685 &spr_read_generic
, &spr_write_generic
,
4687 #if !defined(CONFIG_USER_ONLY)
4691 env
->tlb_type
= TLB_EMB
;
4693 init_excp_e200(env
, 0xFFFF0000UL
);
4694 env
->dcache_line_size
= 32;
4695 env
->icache_line_size
= 32;
4696 /* XXX: TODO: allocate internal IRQ controller */
4699 POWERPC_FAMILY(e200
)(ObjectClass
*oc
, void *data
)
4701 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4702 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4704 dc
->desc
= "e200 core";
4705 pcc
->init_proc
= init_proc_e200
;
4706 pcc
->check_pow
= check_pow_hid0
;
4707 /* XXX: unimplemented instructions:
4714 * all SPE multiply-accumulate instructions
4716 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
4717 PPC_SPE
| PPC_SPE_SINGLE
|
4718 PPC_WRTEE
| PPC_RFDI
|
4719 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
4720 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4721 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
|
4723 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
4737 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
4738 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4739 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4740 pcc
->bfd_mach
= bfd_mach_ppc_860
;
4741 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
4742 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
4743 POWERPC_FLAG_BUS_CLK
;
4746 static void init_proc_e300 (CPUPPCState
*env
)
4748 gen_spr_ne_601(env
);
4753 /* hardware implementation registers */
4754 /* XXX : not implemented */
4755 spr_register(env
, SPR_HID0
, "HID0",
4756 SPR_NOACCESS
, SPR_NOACCESS
,
4757 &spr_read_generic
, &spr_write_generic
,
4759 /* XXX : not implemented */
4760 spr_register(env
, SPR_HID1
, "HID1",
4761 SPR_NOACCESS
, SPR_NOACCESS
,
4762 &spr_read_generic
, &spr_write_generic
,
4764 /* XXX : not implemented */
4765 spr_register(env
, SPR_HID2
, "HID2",
4766 SPR_NOACCESS
, SPR_NOACCESS
,
4767 &spr_read_generic
, &spr_write_generic
,
4770 /* XXX : not implemented */
4771 spr_register(env
, SPR_DABR
, "DABR",
4772 SPR_NOACCESS
, SPR_NOACCESS
,
4773 &spr_read_generic
, &spr_write_generic
,
4775 /* XXX : not implemented */
4776 spr_register(env
, SPR_DABR2
, "DABR2",
4777 SPR_NOACCESS
, SPR_NOACCESS
,
4778 &spr_read_generic
, &spr_write_generic
,
4780 /* XXX : not implemented */
4781 spr_register(env
, SPR_IABR2
, "IABR2",
4782 SPR_NOACCESS
, SPR_NOACCESS
,
4783 &spr_read_generic
, &spr_write_generic
,
4785 /* XXX : not implemented */
4786 spr_register(env
, SPR_IBCR
, "IBCR",
4787 SPR_NOACCESS
, SPR_NOACCESS
,
4788 &spr_read_generic
, &spr_write_generic
,
4790 /* XXX : not implemented */
4791 spr_register(env
, SPR_DBCR
, "DBCR",
4792 SPR_NOACCESS
, SPR_NOACCESS
,
4793 &spr_read_generic
, &spr_write_generic
,
4795 /* Memory management */
4798 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4800 env
->dcache_line_size
= 32;
4801 env
->icache_line_size
= 32;
4802 /* Allocate hardware IRQ controller */
4803 ppc6xx_irq_init(ppc_env_get_cpu(env
));
4806 POWERPC_FAMILY(e300
)(ObjectClass
*oc
, void *data
)
4808 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4809 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4811 dc
->desc
= "e300 core";
4812 pcc
->init_proc
= init_proc_e300
;
4813 pcc
->check_pow
= check_pow_hid0
;
4814 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4815 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4817 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4818 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4819 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4820 PPC_SEGMENT
| PPC_EXTERN
;
4821 pcc
->msr_mask
= (1ull << MSR_POW
) |
4822 (1ull << MSR_TGPR
) |
4838 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4839 pcc
->excp_model
= POWERPC_EXCP_603
;
4840 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4841 pcc
->bfd_mach
= bfd_mach_ppc_603
;
4842 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4843 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4846 #if !defined(CONFIG_USER_ONLY)
4847 static void spr_write_mas73(DisasContext
*ctx
, int sprn
, int gprn
)
4849 TCGv val
= tcg_temp_new();
4850 tcg_gen_ext32u_tl(val
, cpu_gpr
[gprn
]);
4851 gen_store_spr(SPR_BOOKE_MAS3
, val
);
4852 tcg_gen_shri_tl(val
, cpu_gpr
[gprn
], 32);
4853 gen_store_spr(SPR_BOOKE_MAS7
, val
);
4857 static void spr_read_mas73(DisasContext
*ctx
, int gprn
, int sprn
)
4859 TCGv mas7
= tcg_temp_new();
4860 TCGv mas3
= tcg_temp_new();
4861 gen_load_spr(mas7
, SPR_BOOKE_MAS7
);
4862 tcg_gen_shli_tl(mas7
, mas7
, 32);
4863 gen_load_spr(mas3
, SPR_BOOKE_MAS3
);
4864 tcg_gen_or_tl(cpu_gpr
[gprn
], mas3
, mas7
);
4865 tcg_temp_free(mas3
);
4866 tcg_temp_free(mas7
);
4871 enum fsl_e500_version
{
4878 static void init_proc_e500 (CPUPPCState
*env
, int version
)
4880 PowerPCCPU
*cpu
= ppc_env_get_cpu(env
);
4881 uint32_t tlbncfg
[2];
4883 uint64_t ivpr_mask
= 0xFFFF0000ULL
;
4884 uint32_t l1cfg0
= 0x3800 /* 8 ways */
4885 | 0x0020; /* 32 kb */
4886 uint32_t l1cfg1
= 0x3800 /* 8 ways */
4887 | 0x0020; /* 32 kb */
4888 #if !defined(CONFIG_USER_ONLY)
4895 * XXX The e500 doesn't implement IVOR7 and IVOR9, but doesn't
4896 * complain when accessing them.
4897 * gen_spr_BookE(env, 0x0000000F0000FD7FULL);
4903 ivor_mask
= 0x0000000F0000FFFFULL
;
4907 ivor_mask
= 0x000003FE0000FFFFULL
;
4910 gen_spr_BookE(env
, ivor_mask
);
4911 /* Processor identification */
4912 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4913 SPR_NOACCESS
, SPR_NOACCESS
,
4914 &spr_read_generic
, &spr_write_pir
,
4916 /* XXX : not implemented */
4917 spr_register(env
, SPR_BOOKE_SPEFSCR
, "SPEFSCR",
4918 &spr_read_spefscr
, &spr_write_spefscr
,
4919 &spr_read_spefscr
, &spr_write_spefscr
,
4921 #if !defined(CONFIG_USER_ONLY)
4922 /* Memory management */
4928 tlbncfg
[0] = gen_tlbncfg(2, 1, 1, 0, 256);
4929 tlbncfg
[1] = gen_tlbncfg(16, 1, 9, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 16);
4932 tlbncfg
[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4933 tlbncfg
[1] = gen_tlbncfg(16, 1, 12, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 16);
4937 tlbncfg
[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4938 tlbncfg
[1] = gen_tlbncfg(64, 1, 12, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 64);
4941 cpu_abort(CPU(cpu
), "Unknown CPU: " TARGET_FMT_lx
"\n", env
->spr
[SPR_PVR
]);
4948 env
->dcache_line_size
= 32;
4949 env
->icache_line_size
= 32;
4953 env
->dcache_line_size
= 64;
4954 env
->icache_line_size
= 64;
4955 l1cfg0
|= 0x1000000; /* 64 byte cache block size */
4956 l1cfg1
|= 0x1000000; /* 64 byte cache block size */
4959 cpu_abort(CPU(cpu
), "Unknown CPU: " TARGET_FMT_lx
"\n", env
->spr
[SPR_PVR
]);
4961 gen_spr_BookE206(env
, 0x000000DF, tlbncfg
);
4962 /* XXX : not implemented */
4963 spr_register(env
, SPR_HID0
, "HID0",
4964 SPR_NOACCESS
, SPR_NOACCESS
,
4965 &spr_read_generic
, &spr_write_generic
,
4967 /* XXX : not implemented */
4968 spr_register(env
, SPR_HID1
, "HID1",
4969 SPR_NOACCESS
, SPR_NOACCESS
,
4970 &spr_read_generic
, &spr_write_generic
,
4972 /* XXX : not implemented */
4973 spr_register(env
, SPR_Exxx_BBEAR
, "BBEAR",
4974 SPR_NOACCESS
, SPR_NOACCESS
,
4975 &spr_read_generic
, &spr_write_generic
,
4977 /* XXX : not implemented */
4978 spr_register(env
, SPR_Exxx_BBTAR
, "BBTAR",
4979 SPR_NOACCESS
, SPR_NOACCESS
,
4980 &spr_read_generic
, &spr_write_generic
,
4982 /* XXX : not implemented */
4983 spr_register(env
, SPR_Exxx_MCAR
, "MCAR",
4984 SPR_NOACCESS
, SPR_NOACCESS
,
4985 &spr_read_generic
, &spr_write_generic
,
4987 /* XXX : not implemented */
4988 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
4989 SPR_NOACCESS
, SPR_NOACCESS
,
4990 &spr_read_generic
, &spr_write_generic
,
4992 /* XXX : not implemented */
4993 spr_register(env
, SPR_Exxx_NPIDR
, "NPIDR",
4994 SPR_NOACCESS
, SPR_NOACCESS
,
4995 &spr_read_generic
, &spr_write_generic
,
4997 /* XXX : not implemented */
4998 spr_register(env
, SPR_Exxx_BUCSR
, "BUCSR",
4999 SPR_NOACCESS
, SPR_NOACCESS
,
5000 &spr_read_generic
, &spr_write_generic
,
5002 /* XXX : not implemented */
5003 spr_register(env
, SPR_Exxx_L1CFG0
, "L1CFG0",
5004 &spr_read_generic
, SPR_NOACCESS
,
5005 &spr_read_generic
, SPR_NOACCESS
,
5007 spr_register(env
, SPR_Exxx_L1CFG1
, "L1CFG1",
5008 &spr_read_generic
, SPR_NOACCESS
,
5009 &spr_read_generic
, SPR_NOACCESS
,
5011 spr_register(env
, SPR_Exxx_L1CSR0
, "L1CSR0",
5012 SPR_NOACCESS
, SPR_NOACCESS
,
5013 &spr_read_generic
, &spr_write_e500_l1csr0
,
5015 spr_register(env
, SPR_Exxx_L1CSR1
, "L1CSR1",
5016 SPR_NOACCESS
, SPR_NOACCESS
,
5017 &spr_read_generic
, &spr_write_e500_l1csr1
,
5019 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
5020 SPR_NOACCESS
, SPR_NOACCESS
,
5021 &spr_read_generic
, &spr_write_generic
,
5023 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
5024 SPR_NOACCESS
, SPR_NOACCESS
,
5025 &spr_read_generic
, &spr_write_generic
,
5027 spr_register(env
, SPR_MMUCSR0
, "MMUCSR0",
5028 SPR_NOACCESS
, SPR_NOACCESS
,
5029 &spr_read_generic
, &spr_write_booke206_mmucsr0
,
5031 spr_register(env
, SPR_BOOKE_EPR
, "EPR",
5032 SPR_NOACCESS
, SPR_NOACCESS
,
5033 &spr_read_generic
, SPR_NOACCESS
,
5035 /* XXX better abstract into Emb.xxx features */
5036 if (version
== fsl_e5500
) {
5037 spr_register(env
, SPR_BOOKE_EPCR
, "EPCR",
5038 SPR_NOACCESS
, SPR_NOACCESS
,
5039 &spr_read_generic
, &spr_write_generic
,
5041 spr_register(env
, SPR_BOOKE_MAS7_MAS3
, "MAS7_MAS3",
5042 SPR_NOACCESS
, SPR_NOACCESS
,
5043 &spr_read_mas73
, &spr_write_mas73
,
5045 ivpr_mask
= (target_ulong
)~0xFFFFULL
;
5048 #if !defined(CONFIG_USER_ONLY)
5050 env
->tlb_type
= TLB_MAS
;
5051 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
5052 env
->nb_tlb
+= booke206_tlb_size(env
, i
);
5056 init_excp_e200(env
, ivpr_mask
);
5057 /* Allocate hardware IRQ controller */
5058 ppce500_irq_init(ppc_env_get_cpu(env
));
5061 static void init_proc_e500v1(CPUPPCState
*env
)
5063 init_proc_e500(env
, fsl_e500v1
);
5066 POWERPC_FAMILY(e500v1
)(ObjectClass
*oc
, void *data
)
5068 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5069 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5071 dc
->desc
= "e500v1 core";
5072 pcc
->init_proc
= init_proc_e500v1
;
5073 pcc
->check_pow
= check_pow_hid0
;
5074 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
5075 PPC_SPE
| PPC_SPE_SINGLE
|
5076 PPC_WRTEE
| PPC_RFDI
|
5077 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5078 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5079 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5080 pcc
->insns_flags2
= PPC2_BOOKE206
;
5081 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
5095 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5096 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5097 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5098 pcc
->bfd_mach
= bfd_mach_ppc_860
;
5099 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
5100 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
5101 POWERPC_FLAG_BUS_CLK
;
5104 static void init_proc_e500v2(CPUPPCState
*env
)
5106 init_proc_e500(env
, fsl_e500v2
);
5109 POWERPC_FAMILY(e500v2
)(ObjectClass
*oc
, void *data
)
5111 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5112 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5114 dc
->desc
= "e500v2 core";
5115 pcc
->init_proc
= init_proc_e500v2
;
5116 pcc
->check_pow
= check_pow_hid0
;
5117 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
5118 PPC_SPE
| PPC_SPE_SINGLE
| PPC_SPE_DOUBLE
|
5119 PPC_WRTEE
| PPC_RFDI
|
5120 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5121 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5122 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5123 pcc
->insns_flags2
= PPC2_BOOKE206
;
5124 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
5138 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5139 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5140 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5141 pcc
->bfd_mach
= bfd_mach_ppc_860
;
5142 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
5143 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
5144 POWERPC_FLAG_BUS_CLK
;
5147 static void init_proc_e500mc(CPUPPCState
*env
)
5149 init_proc_e500(env
, fsl_e500mc
);
5152 POWERPC_FAMILY(e500mc
)(ObjectClass
*oc
, void *data
)
5154 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5155 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5157 dc
->desc
= "e500mc core";
5158 pcc
->init_proc
= init_proc_e500mc
;
5159 pcc
->check_pow
= check_pow_none
;
5160 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5161 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5162 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5163 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5164 PPC_FLOAT
| PPC_FLOAT_FRES
|
5165 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5166 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5167 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5168 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
;
5169 pcc
->msr_mask
= (1ull << MSR_GS
) |
5170 (1ull << MSR_UCLE
) |
5183 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5184 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5185 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5186 /* FIXME: figure out the correct flag for e500mc */
5187 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5188 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5189 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5193 static void init_proc_e5500(CPUPPCState
*env
)
5195 init_proc_e500(env
, fsl_e5500
);
5198 POWERPC_FAMILY(e5500
)(ObjectClass
*oc
, void *data
)
5200 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5201 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5203 dc
->desc
= "e5500 core";
5204 pcc
->init_proc
= init_proc_e5500
;
5205 pcc
->check_pow
= check_pow_none
;
5206 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5207 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5208 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5209 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5210 PPC_FLOAT
| PPC_FLOAT_FRES
|
5211 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5212 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5213 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
|
5214 PPC_64B
| PPC_POPCNTB
| PPC_POPCNTWD
;
5215 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
| PPC2_PERM_ISA206
| \
5217 pcc
->msr_mask
= (1ull << MSR_CM
) |
5219 (1ull << MSR_UCLE
) |
5232 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5233 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5234 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5235 /* FIXME: figure out the correct flag for e5500 */
5236 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5237 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5238 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5242 /* Non-embedded PowerPC */
5244 #define POWERPC_MSRR_601 (0x0000000000001040ULL)
5246 static void init_proc_601 (CPUPPCState
*env
)
5248 gen_spr_ne_601(env
);
5251 /* Hardware implementation registers */
5252 /* XXX : not implemented */
5253 spr_register(env
, SPR_HID0
, "HID0",
5254 SPR_NOACCESS
, SPR_NOACCESS
,
5255 &spr_read_generic
, &spr_write_hid0_601
,
5257 /* XXX : not implemented */
5258 spr_register(env
, SPR_HID1
, "HID1",
5259 SPR_NOACCESS
, SPR_NOACCESS
,
5260 &spr_read_generic
, &spr_write_generic
,
5262 /* XXX : not implemented */
5263 spr_register(env
, SPR_601_HID2
, "HID2",
5264 SPR_NOACCESS
, SPR_NOACCESS
,
5265 &spr_read_generic
, &spr_write_generic
,
5267 /* XXX : not implemented */
5268 spr_register(env
, SPR_601_HID5
, "HID5",
5269 SPR_NOACCESS
, SPR_NOACCESS
,
5270 &spr_read_generic
, &spr_write_generic
,
5272 /* Memory management */
5274 /* XXX: beware that dcache line size is 64
5275 * but dcbz uses 32 bytes "sectors"
5276 * XXX: this breaks clcs instruction !
5278 env
->dcache_line_size
= 32;
5279 env
->icache_line_size
= 64;
5280 /* Allocate hardware IRQ controller */
5281 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5284 POWERPC_FAMILY(601)(ObjectClass
*oc
, void *data
)
5286 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5287 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5289 dc
->desc
= "PowerPC 601";
5290 pcc
->init_proc
= init_proc_601
;
5291 pcc
->check_pow
= check_pow_none
;
5292 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_POWER_BR
|
5294 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5295 PPC_MEM_SYNC
| PPC_MEM_EIEIO
| PPC_MEM_TLBIE
|
5296 PPC_SEGMENT
| PPC_EXTERN
;
5297 pcc
->msr_mask
= (1ull << MSR_EE
) |
5307 pcc
->mmu_model
= POWERPC_MMU_601
;
5308 #if defined(CONFIG_SOFTMMU)
5309 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5311 pcc
->excp_model
= POWERPC_EXCP_601
;
5312 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5313 pcc
->bfd_mach
= bfd_mach_ppc_601
;
5314 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_RTC_CLK
;
5317 #define POWERPC_MSRR_601v (0x0000000000001040ULL)
5319 static void init_proc_601v (CPUPPCState
*env
)
5322 /* XXX : not implemented */
5323 spr_register(env
, SPR_601_HID15
, "HID15",
5324 SPR_NOACCESS
, SPR_NOACCESS
,
5325 &spr_read_generic
, &spr_write_generic
,
5329 POWERPC_FAMILY(601v
)(ObjectClass
*oc
, void *data
)
5331 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5332 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5334 dc
->desc
= "PowerPC 601v";
5335 pcc
->init_proc
= init_proc_601v
;
5336 pcc
->check_pow
= check_pow_none
;
5337 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_POWER_BR
|
5339 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5340 PPC_MEM_SYNC
| PPC_MEM_EIEIO
| PPC_MEM_TLBIE
|
5341 PPC_SEGMENT
| PPC_EXTERN
;
5342 pcc
->msr_mask
= (1ull << MSR_EE
) |
5352 pcc
->mmu_model
= POWERPC_MMU_601
;
5353 #if defined(CONFIG_SOFTMMU)
5354 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5356 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5357 pcc
->bfd_mach
= bfd_mach_ppc_601
;
5358 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_RTC_CLK
;
5361 static void init_proc_602 (CPUPPCState
*env
)
5363 gen_spr_ne_601(env
);
5368 /* hardware implementation registers */
5369 /* XXX : not implemented */
5370 spr_register(env
, SPR_HID0
, "HID0",
5371 SPR_NOACCESS
, SPR_NOACCESS
,
5372 &spr_read_generic
, &spr_write_generic
,
5374 /* XXX : not implemented */
5375 spr_register(env
, SPR_HID1
, "HID1",
5376 SPR_NOACCESS
, SPR_NOACCESS
,
5377 &spr_read_generic
, &spr_write_generic
,
5379 /* Memory management */
5381 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5383 env
->dcache_line_size
= 32;
5384 env
->icache_line_size
= 32;
5385 /* Allocate hardware IRQ controller */
5386 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5389 POWERPC_FAMILY(602)(ObjectClass
*oc
, void *data
)
5391 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5392 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5394 dc
->desc
= "PowerPC 602";
5395 pcc
->init_proc
= init_proc_602
;
5396 pcc
->check_pow
= check_pow_hid0
;
5397 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5398 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5399 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5400 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5401 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5402 PPC_MEM_TLBIE
| PPC_6xx_TLB
| PPC_MEM_TLBSYNC
|
5403 PPC_SEGMENT
| PPC_602_SPEC
;
5404 pcc
->msr_mask
= (1ull << MSR_VSX
) |
5407 (1ull << MSR_TGPR
) |
5422 /* XXX: 602 MMU is quite specific. Should add a special case */
5423 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5424 pcc
->excp_model
= POWERPC_EXCP_602
;
5425 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5426 pcc
->bfd_mach
= bfd_mach_ppc_602
;
5427 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5428 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5431 static void init_proc_603 (CPUPPCState
*env
)
5433 gen_spr_ne_601(env
);
5438 /* hardware implementation registers */
5439 /* XXX : not implemented */
5440 spr_register(env
, SPR_HID0
, "HID0",
5441 SPR_NOACCESS
, SPR_NOACCESS
,
5442 &spr_read_generic
, &spr_write_generic
,
5444 /* XXX : not implemented */
5445 spr_register(env
, SPR_HID1
, "HID1",
5446 SPR_NOACCESS
, SPR_NOACCESS
,
5447 &spr_read_generic
, &spr_write_generic
,
5449 /* Memory management */
5451 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5453 env
->dcache_line_size
= 32;
5454 env
->icache_line_size
= 32;
5455 /* Allocate hardware IRQ controller */
5456 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5459 POWERPC_FAMILY(603)(ObjectClass
*oc
, void *data
)
5461 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5462 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5464 dc
->desc
= "PowerPC 603";
5465 pcc
->init_proc
= init_proc_603
;
5466 pcc
->check_pow
= check_pow_hid0
;
5467 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5468 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5469 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5470 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5471 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5472 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
5473 PPC_SEGMENT
| PPC_EXTERN
;
5474 pcc
->msr_mask
= (1ull << MSR_POW
) |
5475 (1ull << MSR_TGPR
) |
5490 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5491 pcc
->excp_model
= POWERPC_EXCP_603
;
5492 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5493 pcc
->bfd_mach
= bfd_mach_ppc_603
;
5494 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5495 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5498 static void init_proc_603E (CPUPPCState
*env
)
5500 gen_spr_ne_601(env
);
5505 /* hardware implementation registers */
5506 /* XXX : not implemented */
5507 spr_register(env
, SPR_HID0
, "HID0",
5508 SPR_NOACCESS
, SPR_NOACCESS
,
5509 &spr_read_generic
, &spr_write_generic
,
5511 /* XXX : not implemented */
5512 spr_register(env
, SPR_HID1
, "HID1",
5513 SPR_NOACCESS
, SPR_NOACCESS
,
5514 &spr_read_generic
, &spr_write_generic
,
5516 /* Memory management */
5518 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5520 env
->dcache_line_size
= 32;
5521 env
->icache_line_size
= 32;
5522 /* Allocate hardware IRQ controller */
5523 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5526 POWERPC_FAMILY(603E
)(ObjectClass
*oc
, void *data
)
5528 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5529 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5531 dc
->desc
= "PowerPC 603e";
5532 pcc
->init_proc
= init_proc_603E
;
5533 pcc
->check_pow
= check_pow_hid0
;
5534 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5535 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5536 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5537 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5538 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5539 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
5540 PPC_SEGMENT
| PPC_EXTERN
;
5541 pcc
->msr_mask
= (1ull << MSR_POW
) |
5542 (1ull << MSR_TGPR
) |
5557 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5558 pcc
->excp_model
= POWERPC_EXCP_603E
;
5559 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5560 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
5561 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5562 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5565 static void init_proc_604 (CPUPPCState
*env
)
5567 gen_spr_ne_601(env
);
5572 /* Hardware implementation registers */
5573 /* XXX : not implemented */
5574 spr_register(env
, SPR_HID0
, "HID0",
5575 SPR_NOACCESS
, SPR_NOACCESS
,
5576 &spr_read_generic
, &spr_write_generic
,
5578 /* Memory management */
5581 env
->dcache_line_size
= 32;
5582 env
->icache_line_size
= 32;
5583 /* Allocate hardware IRQ controller */
5584 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5587 POWERPC_FAMILY(604)(ObjectClass
*oc
, void *data
)
5589 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5590 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5592 dc
->desc
= "PowerPC 604";
5593 pcc
->init_proc
= init_proc_604
;
5594 pcc
->check_pow
= check_pow_nocheck
;
5595 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5596 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5597 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5598 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5599 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5600 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5601 PPC_SEGMENT
| PPC_EXTERN
;
5602 pcc
->msr_mask
= (1ull << MSR_POW
) |
5618 pcc
->mmu_model
= POWERPC_MMU_32B
;
5619 #if defined(CONFIG_SOFTMMU)
5620 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5622 pcc
->excp_model
= POWERPC_EXCP_604
;
5623 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5624 pcc
->bfd_mach
= bfd_mach_ppc_604
;
5625 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5626 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5629 static void init_proc_604E (CPUPPCState
*env
)
5631 gen_spr_ne_601(env
);
5634 /* XXX : not implemented */
5635 spr_register(env
, SPR_7XX_MMCR1
, "MMCR1",
5636 SPR_NOACCESS
, SPR_NOACCESS
,
5637 &spr_read_generic
, &spr_write_generic
,
5639 /* XXX : not implemented */
5640 spr_register(env
, SPR_7XX_PMC3
, "PMC3",
5641 SPR_NOACCESS
, SPR_NOACCESS
,
5642 &spr_read_generic
, &spr_write_generic
,
5644 /* XXX : not implemented */
5645 spr_register(env
, SPR_7XX_PMC4
, "PMC4",
5646 SPR_NOACCESS
, SPR_NOACCESS
,
5647 &spr_read_generic
, &spr_write_generic
,
5651 /* Hardware implementation registers */
5652 /* XXX : not implemented */
5653 spr_register(env
, SPR_HID0
, "HID0",
5654 SPR_NOACCESS
, SPR_NOACCESS
,
5655 &spr_read_generic
, &spr_write_generic
,
5657 /* XXX : not implemented */
5658 spr_register(env
, SPR_HID1
, "HID1",
5659 SPR_NOACCESS
, SPR_NOACCESS
,
5660 &spr_read_generic
, &spr_write_generic
,
5662 /* Memory management */
5665 env
->dcache_line_size
= 32;
5666 env
->icache_line_size
= 32;
5667 /* Allocate hardware IRQ controller */
5668 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5671 POWERPC_FAMILY(604E
)(ObjectClass
*oc
, void *data
)
5673 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5674 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5676 dc
->desc
= "PowerPC 604E";
5677 pcc
->init_proc
= init_proc_604E
;
5678 pcc
->check_pow
= check_pow_nocheck
;
5679 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5680 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5681 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5682 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5683 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5684 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5685 PPC_SEGMENT
| PPC_EXTERN
;
5686 pcc
->msr_mask
= (1ull << MSR_POW
) |
5702 pcc
->mmu_model
= POWERPC_MMU_32B
;
5703 #if defined(CONFIG_SOFTMMU)
5704 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5706 pcc
->excp_model
= POWERPC_EXCP_604
;
5707 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5708 pcc
->bfd_mach
= bfd_mach_ppc_604
;
5709 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5710 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5713 static void init_proc_740 (CPUPPCState
*env
)
5715 gen_spr_ne_601(env
);
5720 /* Thermal management */
5722 /* Hardware implementation registers */
5723 /* XXX : not implemented */
5724 spr_register(env
, SPR_HID0
, "HID0",
5725 SPR_NOACCESS
, SPR_NOACCESS
,
5726 &spr_read_generic
, &spr_write_generic
,
5728 /* XXX : not implemented */
5729 spr_register(env
, SPR_HID1
, "HID1",
5730 SPR_NOACCESS
, SPR_NOACCESS
,
5731 &spr_read_generic
, &spr_write_generic
,
5733 /* Memory management */
5736 env
->dcache_line_size
= 32;
5737 env
->icache_line_size
= 32;
5738 /* Allocate hardware IRQ controller */
5739 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5742 POWERPC_FAMILY(740)(ObjectClass
*oc
, void *data
)
5744 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5745 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5747 dc
->desc
= "PowerPC 740";
5748 pcc
->init_proc
= init_proc_740
;
5749 pcc
->check_pow
= check_pow_hid0
;
5750 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5751 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5752 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5753 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5754 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5755 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5756 PPC_SEGMENT
| PPC_EXTERN
;
5757 pcc
->msr_mask
= (1ull << MSR_POW
) |
5773 pcc
->mmu_model
= POWERPC_MMU_32B
;
5774 #if defined(CONFIG_SOFTMMU)
5775 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5777 pcc
->excp_model
= POWERPC_EXCP_7x0
;
5778 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5779 pcc
->bfd_mach
= bfd_mach_ppc_750
;
5780 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5781 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5784 static void init_proc_750 (CPUPPCState
*env
)
5786 gen_spr_ne_601(env
);
5789 /* XXX : not implemented */
5790 spr_register(env
, SPR_L2CR
, "L2CR",
5791 SPR_NOACCESS
, SPR_NOACCESS
,
5792 &spr_read_generic
, spr_access_nop
,
5796 /* Thermal management */
5798 /* Hardware implementation registers */
5799 /* XXX : not implemented */
5800 spr_register(env
, SPR_HID0
, "HID0",
5801 SPR_NOACCESS
, SPR_NOACCESS
,
5802 &spr_read_generic
, &spr_write_generic
,
5804 /* XXX : not implemented */
5805 spr_register(env
, SPR_HID1
, "HID1",
5806 SPR_NOACCESS
, SPR_NOACCESS
,
5807 &spr_read_generic
, &spr_write_generic
,
5809 /* Memory management */
5811 /* XXX: high BATs are also present but are known to be bugged on
5815 env
->dcache_line_size
= 32;
5816 env
->icache_line_size
= 32;
5817 /* Allocate hardware IRQ controller */
5818 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5821 POWERPC_FAMILY(750)(ObjectClass
*oc
, void *data
)
5823 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5824 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5826 dc
->desc
= "PowerPC 750";
5827 pcc
->init_proc
= init_proc_750
;
5828 pcc
->check_pow
= check_pow_hid0
;
5829 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5830 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5831 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5832 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5833 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5834 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5835 PPC_SEGMENT
| PPC_EXTERN
;
5836 pcc
->msr_mask
= (1ull << MSR_POW
) |
5852 pcc
->mmu_model
= POWERPC_MMU_32B
;
5853 #if defined(CONFIG_SOFTMMU)
5854 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5856 pcc
->excp_model
= POWERPC_EXCP_7x0
;
5857 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5858 pcc
->bfd_mach
= bfd_mach_ppc_750
;
5859 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5860 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5863 static void init_proc_750cl (CPUPPCState
*env
)
5865 gen_spr_ne_601(env
);
5868 /* XXX : not implemented */
5869 spr_register(env
, SPR_L2CR
, "L2CR",
5870 SPR_NOACCESS
, SPR_NOACCESS
,
5871 &spr_read_generic
, spr_access_nop
,
5875 /* Thermal management */
5876 /* Those registers are fake on 750CL */
5877 spr_register(env
, SPR_THRM1
, "THRM1",
5878 SPR_NOACCESS
, SPR_NOACCESS
,
5879 &spr_read_generic
, &spr_write_generic
,
5881 spr_register(env
, SPR_THRM2
, "THRM2",
5882 SPR_NOACCESS
, SPR_NOACCESS
,
5883 &spr_read_generic
, &spr_write_generic
,
5885 spr_register(env
, SPR_THRM3
, "THRM3",
5886 SPR_NOACCESS
, SPR_NOACCESS
,
5887 &spr_read_generic
, &spr_write_generic
,
5889 /* XXX: not implemented */
5890 spr_register(env
, SPR_750_TDCL
, "TDCL",
5891 SPR_NOACCESS
, SPR_NOACCESS
,
5892 &spr_read_generic
, &spr_write_generic
,
5894 spr_register(env
, SPR_750_TDCH
, "TDCH",
5895 SPR_NOACCESS
, SPR_NOACCESS
,
5896 &spr_read_generic
, &spr_write_generic
,
5899 /* XXX : not implemented */
5900 spr_register(env
, SPR_750_WPAR
, "WPAR",
5901 SPR_NOACCESS
, SPR_NOACCESS
,
5902 &spr_read_generic
, &spr_write_generic
,
5904 spr_register(env
, SPR_750_DMAL
, "DMAL",
5905 SPR_NOACCESS
, SPR_NOACCESS
,
5906 &spr_read_generic
, &spr_write_generic
,
5908 spr_register(env
, SPR_750_DMAU
, "DMAU",
5909 SPR_NOACCESS
, SPR_NOACCESS
,
5910 &spr_read_generic
, &spr_write_generic
,
5912 /* Hardware implementation registers */
5913 /* XXX : not implemented */
5914 spr_register(env
, SPR_HID0
, "HID0",
5915 SPR_NOACCESS
, SPR_NOACCESS
,
5916 &spr_read_generic
, &spr_write_generic
,
5918 /* XXX : not implemented */
5919 spr_register(env
, SPR_HID1
, "HID1",
5920 SPR_NOACCESS
, SPR_NOACCESS
,
5921 &spr_read_generic
, &spr_write_generic
,
5923 /* XXX : not implemented */
5924 spr_register(env
, SPR_750CL_HID2
, "HID2",
5925 SPR_NOACCESS
, SPR_NOACCESS
,
5926 &spr_read_generic
, &spr_write_generic
,
5928 /* XXX : not implemented */
5929 spr_register(env
, SPR_750CL_HID4
, "HID4",
5930 SPR_NOACCESS
, SPR_NOACCESS
,
5931 &spr_read_generic
, &spr_write_generic
,
5933 /* Quantization registers */
5934 /* XXX : not implemented */
5935 spr_register(env
, SPR_750_GQR0
, "GQR0",
5936 SPR_NOACCESS
, SPR_NOACCESS
,
5937 &spr_read_generic
, &spr_write_generic
,
5939 /* XXX : not implemented */
5940 spr_register(env
, SPR_750_GQR1
, "GQR1",
5941 SPR_NOACCESS
, SPR_NOACCESS
,
5942 &spr_read_generic
, &spr_write_generic
,
5944 /* XXX : not implemented */
5945 spr_register(env
, SPR_750_GQR2
, "GQR2",
5946 SPR_NOACCESS
, SPR_NOACCESS
,
5947 &spr_read_generic
, &spr_write_generic
,
5949 /* XXX : not implemented */
5950 spr_register(env
, SPR_750_GQR3
, "GQR3",
5951 SPR_NOACCESS
, SPR_NOACCESS
,
5952 &spr_read_generic
, &spr_write_generic
,
5954 /* XXX : not implemented */
5955 spr_register(env
, SPR_750_GQR4
, "GQR4",
5956 SPR_NOACCESS
, SPR_NOACCESS
,
5957 &spr_read_generic
, &spr_write_generic
,
5959 /* XXX : not implemented */
5960 spr_register(env
, SPR_750_GQR5
, "GQR5",
5961 SPR_NOACCESS
, SPR_NOACCESS
,
5962 &spr_read_generic
, &spr_write_generic
,
5964 /* XXX : not implemented */
5965 spr_register(env
, SPR_750_GQR6
, "GQR6",
5966 SPR_NOACCESS
, SPR_NOACCESS
,
5967 &spr_read_generic
, &spr_write_generic
,
5969 /* XXX : not implemented */
5970 spr_register(env
, SPR_750_GQR7
, "GQR7",
5971 SPR_NOACCESS
, SPR_NOACCESS
,
5972 &spr_read_generic
, &spr_write_generic
,
5974 /* Memory management */
5976 /* PowerPC 750cl has 8 DBATs and 8 IBATs */
5978 init_excp_750cl(env
);
5979 env
->dcache_line_size
= 32;
5980 env
->icache_line_size
= 32;
5981 /* Allocate hardware IRQ controller */
5982 ppc6xx_irq_init(ppc_env_get_cpu(env
));
5985 POWERPC_FAMILY(750cl
)(ObjectClass
*oc
, void *data
)
5987 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5988 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5990 dc
->desc
= "PowerPC 750 CL";
5991 pcc
->init_proc
= init_proc_750cl
;
5992 pcc
->check_pow
= check_pow_hid0
;
5993 /* XXX: not implemented:
5994 * cache lock instructions:
5996 * floating point paired instructions
6031 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6032 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6033 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6034 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6035 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6036 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6037 PPC_SEGMENT
| PPC_EXTERN
;
6038 pcc
->msr_mask
= (1ull << MSR_POW
) |
6054 pcc
->mmu_model
= POWERPC_MMU_32B
;
6055 #if defined(CONFIG_SOFTMMU)
6056 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6058 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6059 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6060 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6061 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6062 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6065 static void init_proc_750cx (CPUPPCState
*env
)
6067 gen_spr_ne_601(env
);
6070 /* XXX : not implemented */
6071 spr_register(env
, SPR_L2CR
, "L2CR",
6072 SPR_NOACCESS
, SPR_NOACCESS
,
6073 &spr_read_generic
, spr_access_nop
,
6077 /* Thermal management */
6079 /* This register is not implemented but is present for compatibility */
6080 spr_register(env
, SPR_SDA
, "SDA",
6081 SPR_NOACCESS
, SPR_NOACCESS
,
6082 &spr_read_generic
, &spr_write_generic
,
6084 /* Hardware implementation registers */
6085 /* XXX : not implemented */
6086 spr_register(env
, SPR_HID0
, "HID0",
6087 SPR_NOACCESS
, SPR_NOACCESS
,
6088 &spr_read_generic
, &spr_write_generic
,
6090 /* XXX : not implemented */
6091 spr_register(env
, SPR_HID1
, "HID1",
6092 SPR_NOACCESS
, SPR_NOACCESS
,
6093 &spr_read_generic
, &spr_write_generic
,
6095 /* Memory management */
6097 /* PowerPC 750cx has 8 DBATs and 8 IBATs */
6099 init_excp_750cx(env
);
6100 env
->dcache_line_size
= 32;
6101 env
->icache_line_size
= 32;
6102 /* Allocate hardware IRQ controller */
6103 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6106 POWERPC_FAMILY(750cx
)(ObjectClass
*oc
, void *data
)
6108 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6109 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6111 dc
->desc
= "PowerPC 750CX";
6112 pcc
->init_proc
= init_proc_750cx
;
6113 pcc
->check_pow
= check_pow_hid0
;
6114 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6115 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6116 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6117 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6118 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6119 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6120 PPC_SEGMENT
| PPC_EXTERN
;
6121 pcc
->msr_mask
= (1ull << MSR_POW
) |
6137 pcc
->mmu_model
= POWERPC_MMU_32B
;
6138 #if defined(CONFIG_SOFTMMU)
6139 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6141 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6142 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6143 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6144 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6145 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6148 static void init_proc_750fx (CPUPPCState
*env
)
6150 gen_spr_ne_601(env
);
6153 /* XXX : not implemented */
6154 spr_register(env
, SPR_L2CR
, "L2CR",
6155 SPR_NOACCESS
, SPR_NOACCESS
,
6156 &spr_read_generic
, spr_access_nop
,
6160 /* Thermal management */
6162 /* XXX : not implemented */
6163 spr_register(env
, SPR_750_THRM4
, "THRM4",
6164 SPR_NOACCESS
, SPR_NOACCESS
,
6165 &spr_read_generic
, &spr_write_generic
,
6167 /* Hardware implementation registers */
6168 /* XXX : not implemented */
6169 spr_register(env
, SPR_HID0
, "HID0",
6170 SPR_NOACCESS
, SPR_NOACCESS
,
6171 &spr_read_generic
, &spr_write_generic
,
6173 /* XXX : not implemented */
6174 spr_register(env
, SPR_HID1
, "HID1",
6175 SPR_NOACCESS
, SPR_NOACCESS
,
6176 &spr_read_generic
, &spr_write_generic
,
6178 /* XXX : not implemented */
6179 spr_register(env
, SPR_750FX_HID2
, "HID2",
6180 SPR_NOACCESS
, SPR_NOACCESS
,
6181 &spr_read_generic
, &spr_write_generic
,
6183 /* Memory management */
6185 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6188 env
->dcache_line_size
= 32;
6189 env
->icache_line_size
= 32;
6190 /* Allocate hardware IRQ controller */
6191 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6194 POWERPC_FAMILY(750fx
)(ObjectClass
*oc
, void *data
)
6196 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6197 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6199 dc
->desc
= "PowerPC 750FX";
6200 pcc
->init_proc
= init_proc_750fx
;
6201 pcc
->check_pow
= check_pow_hid0
;
6202 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6203 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6204 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6205 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6206 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6207 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6208 PPC_SEGMENT
| PPC_EXTERN
;
6209 pcc
->msr_mask
= (1ull << MSR_POW
) |
6225 pcc
->mmu_model
= POWERPC_MMU_32B
;
6226 #if defined(CONFIG_SOFTMMU)
6227 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6229 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6230 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6231 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6232 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6233 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6236 static void init_proc_750gx (CPUPPCState
*env
)
6238 gen_spr_ne_601(env
);
6241 /* XXX : not implemented (XXX: different from 750fx) */
6242 spr_register(env
, SPR_L2CR
, "L2CR",
6243 SPR_NOACCESS
, SPR_NOACCESS
,
6244 &spr_read_generic
, spr_access_nop
,
6248 /* Thermal management */
6250 /* XXX : not implemented */
6251 spr_register(env
, SPR_750_THRM4
, "THRM4",
6252 SPR_NOACCESS
, SPR_NOACCESS
,
6253 &spr_read_generic
, &spr_write_generic
,
6255 /* Hardware implementation registers */
6256 /* XXX : not implemented (XXX: different from 750fx) */
6257 spr_register(env
, SPR_HID0
, "HID0",
6258 SPR_NOACCESS
, SPR_NOACCESS
,
6259 &spr_read_generic
, &spr_write_generic
,
6261 /* XXX : not implemented */
6262 spr_register(env
, SPR_HID1
, "HID1",
6263 SPR_NOACCESS
, SPR_NOACCESS
,
6264 &spr_read_generic
, &spr_write_generic
,
6266 /* XXX : not implemented (XXX: different from 750fx) */
6267 spr_register(env
, SPR_750FX_HID2
, "HID2",
6268 SPR_NOACCESS
, SPR_NOACCESS
,
6269 &spr_read_generic
, &spr_write_generic
,
6271 /* Memory management */
6273 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6276 env
->dcache_line_size
= 32;
6277 env
->icache_line_size
= 32;
6278 /* Allocate hardware IRQ controller */
6279 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6282 POWERPC_FAMILY(750gx
)(ObjectClass
*oc
, void *data
)
6284 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6285 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6287 dc
->desc
= "PowerPC 750GX";
6288 pcc
->init_proc
= init_proc_750gx
;
6289 pcc
->check_pow
= check_pow_hid0
;
6290 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6291 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6292 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6293 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6294 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6295 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6296 PPC_SEGMENT
| PPC_EXTERN
;
6297 pcc
->msr_mask
= (1ull << MSR_POW
) |
6313 pcc
->mmu_model
= POWERPC_MMU_32B
;
6314 #if defined(CONFIG_SOFTMMU)
6315 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6317 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6318 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6319 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6320 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6321 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6324 static void init_proc_745 (CPUPPCState
*env
)
6326 gen_spr_ne_601(env
);
6329 gen_spr_G2_755(env
);
6332 /* Thermal management */
6334 /* Hardware implementation registers */
6335 /* XXX : not implemented */
6336 spr_register(env
, SPR_HID0
, "HID0",
6337 SPR_NOACCESS
, SPR_NOACCESS
,
6338 &spr_read_generic
, &spr_write_generic
,
6340 /* XXX : not implemented */
6341 spr_register(env
, SPR_HID1
, "HID1",
6342 SPR_NOACCESS
, SPR_NOACCESS
,
6343 &spr_read_generic
, &spr_write_generic
,
6345 /* XXX : not implemented */
6346 spr_register(env
, SPR_HID2
, "HID2",
6347 SPR_NOACCESS
, SPR_NOACCESS
,
6348 &spr_read_generic
, &spr_write_generic
,
6350 /* Memory management */
6353 gen_6xx_7xx_soft_tlb(env
, 64, 2);
6355 env
->dcache_line_size
= 32;
6356 env
->icache_line_size
= 32;
6357 /* Allocate hardware IRQ controller */
6358 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6361 POWERPC_FAMILY(745)(ObjectClass
*oc
, void *data
)
6363 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6364 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6366 dc
->desc
= "PowerPC 745";
6367 pcc
->init_proc
= init_proc_745
;
6368 pcc
->check_pow
= check_pow_hid0
;
6369 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6370 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6371 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6372 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6373 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6374 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
6375 PPC_SEGMENT
| PPC_EXTERN
;
6376 pcc
->msr_mask
= (1ull << MSR_POW
) |
6392 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
6393 pcc
->excp_model
= POWERPC_EXCP_7x5
;
6394 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6395 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6396 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6397 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6400 static void init_proc_755 (CPUPPCState
*env
)
6402 gen_spr_ne_601(env
);
6405 gen_spr_G2_755(env
);
6408 /* L2 cache control */
6409 /* XXX : not implemented */
6410 spr_register(env
, SPR_L2CR
, "L2CR",
6411 SPR_NOACCESS
, SPR_NOACCESS
,
6412 &spr_read_generic
, spr_access_nop
,
6414 /* XXX : not implemented */
6415 spr_register(env
, SPR_L2PMCR
, "L2PMCR",
6416 SPR_NOACCESS
, SPR_NOACCESS
,
6417 &spr_read_generic
, &spr_write_generic
,
6419 /* Thermal management */
6421 /* Hardware implementation registers */
6422 /* XXX : not implemented */
6423 spr_register(env
, SPR_HID0
, "HID0",
6424 SPR_NOACCESS
, SPR_NOACCESS
,
6425 &spr_read_generic
, &spr_write_generic
,
6427 /* XXX : not implemented */
6428 spr_register(env
, SPR_HID1
, "HID1",
6429 SPR_NOACCESS
, SPR_NOACCESS
,
6430 &spr_read_generic
, &spr_write_generic
,
6432 /* XXX : not implemented */
6433 spr_register(env
, SPR_HID2
, "HID2",
6434 SPR_NOACCESS
, SPR_NOACCESS
,
6435 &spr_read_generic
, &spr_write_generic
,
6437 /* Memory management */
6440 gen_6xx_7xx_soft_tlb(env
, 64, 2);
6442 env
->dcache_line_size
= 32;
6443 env
->icache_line_size
= 32;
6444 /* Allocate hardware IRQ controller */
6445 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6448 POWERPC_FAMILY(755)(ObjectClass
*oc
, void *data
)
6450 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6451 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6453 dc
->desc
= "PowerPC 755";
6454 pcc
->init_proc
= init_proc_755
;
6455 pcc
->check_pow
= check_pow_hid0
;
6456 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6457 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6458 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6459 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6460 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6461 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
6462 PPC_SEGMENT
| PPC_EXTERN
;
6463 pcc
->msr_mask
= (1ull << MSR_POW
) |
6479 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
6480 pcc
->excp_model
= POWERPC_EXCP_7x5
;
6481 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6482 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6483 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6484 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6487 static void init_proc_7400 (CPUPPCState
*env
)
6489 gen_spr_ne_601(env
);
6494 /* 74xx specific SPR */
6496 /* XXX : not implemented */
6497 spr_register(env
, SPR_UBAMR
, "UBAMR",
6498 &spr_read_ureg
, SPR_NOACCESS
,
6499 &spr_read_ureg
, SPR_NOACCESS
,
6501 /* XXX: this seems not implemented on all revisions. */
6502 /* XXX : not implemented */
6503 spr_register(env
, SPR_MSSCR1
, "MSSCR1",
6504 SPR_NOACCESS
, SPR_NOACCESS
,
6505 &spr_read_generic
, &spr_write_generic
,
6507 /* Thermal management */
6509 /* Memory management */
6511 init_excp_7400(env
);
6512 env
->dcache_line_size
= 32;
6513 env
->icache_line_size
= 32;
6514 /* Allocate hardware IRQ controller */
6515 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6518 POWERPC_FAMILY(7400)(ObjectClass
*oc
, void *data
)
6520 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6521 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6523 dc
->desc
= "PowerPC 7400 (aka G4)";
6524 pcc
->init_proc
= init_proc_7400
;
6525 pcc
->check_pow
= check_pow_hid0
;
6526 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6527 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6528 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6530 PPC_CACHE
| PPC_CACHE_ICBI
|
6531 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6532 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6533 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6535 PPC_SEGMENT
| PPC_EXTERN
|
6537 pcc
->msr_mask
= (1ull << MSR_VR
) |
6554 pcc
->mmu_model
= POWERPC_MMU_32B
;
6555 #if defined(CONFIG_SOFTMMU)
6556 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6558 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6559 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6560 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6561 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6562 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6563 POWERPC_FLAG_BUS_CLK
;
6566 static void init_proc_7410 (CPUPPCState
*env
)
6568 gen_spr_ne_601(env
);
6573 /* 74xx specific SPR */
6575 /* XXX : not implemented */
6576 spr_register(env
, SPR_UBAMR
, "UBAMR",
6577 &spr_read_ureg
, SPR_NOACCESS
,
6578 &spr_read_ureg
, SPR_NOACCESS
,
6580 /* Thermal management */
6583 /* XXX : not implemented */
6584 spr_register(env
, SPR_L2PMCR
, "L2PMCR",
6585 SPR_NOACCESS
, SPR_NOACCESS
,
6586 &spr_read_generic
, &spr_write_generic
,
6589 /* XXX : not implemented */
6590 spr_register(env
, SPR_LDSTDB
, "LDSTDB",
6591 SPR_NOACCESS
, SPR_NOACCESS
,
6592 &spr_read_generic
, &spr_write_generic
,
6594 /* Memory management */
6596 init_excp_7400(env
);
6597 env
->dcache_line_size
= 32;
6598 env
->icache_line_size
= 32;
6599 /* Allocate hardware IRQ controller */
6600 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6603 POWERPC_FAMILY(7410)(ObjectClass
*oc
, void *data
)
6605 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6606 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6608 dc
->desc
= "PowerPC 7410 (aka G4)";
6609 pcc
->init_proc
= init_proc_7410
;
6610 pcc
->check_pow
= check_pow_hid0
;
6611 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6612 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6613 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6615 PPC_CACHE
| PPC_CACHE_ICBI
|
6616 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6617 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6618 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6620 PPC_SEGMENT
| PPC_EXTERN
|
6622 pcc
->msr_mask
= (1ull << MSR_VR
) |
6639 pcc
->mmu_model
= POWERPC_MMU_32B
;
6640 #if defined(CONFIG_SOFTMMU)
6641 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6643 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6644 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6645 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6646 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6647 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6648 POWERPC_FLAG_BUS_CLK
;
6651 static void init_proc_7440 (CPUPPCState
*env
)
6653 gen_spr_ne_601(env
);
6658 /* 74xx specific SPR */
6660 /* XXX : not implemented */
6661 spr_register(env
, SPR_UBAMR
, "UBAMR",
6662 &spr_read_ureg
, SPR_NOACCESS
,
6663 &spr_read_ureg
, SPR_NOACCESS
,
6666 /* XXX : not implemented */
6667 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6668 SPR_NOACCESS
, SPR_NOACCESS
,
6669 &spr_read_generic
, &spr_write_generic
,
6672 /* XXX : not implemented */
6673 spr_register(env
, SPR_ICTRL
, "ICTRL",
6674 SPR_NOACCESS
, SPR_NOACCESS
,
6675 &spr_read_generic
, &spr_write_generic
,
6678 /* XXX : not implemented */
6679 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6680 SPR_NOACCESS
, SPR_NOACCESS
,
6681 &spr_read_generic
, &spr_write_generic
,
6684 /* XXX : not implemented */
6685 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6686 SPR_NOACCESS
, SPR_NOACCESS
,
6687 &spr_read_generic
, &spr_write_generic
,
6689 /* XXX : not implemented */
6690 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6691 &spr_read_ureg
, SPR_NOACCESS
,
6692 &spr_read_ureg
, SPR_NOACCESS
,
6694 /* XXX : not implemented */
6695 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6696 SPR_NOACCESS
, SPR_NOACCESS
,
6697 &spr_read_generic
, &spr_write_generic
,
6699 /* XXX : not implemented */
6700 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6701 &spr_read_ureg
, SPR_NOACCESS
,
6702 &spr_read_ureg
, SPR_NOACCESS
,
6704 /* Memory management */
6706 gen_74xx_soft_tlb(env
, 128, 2);
6707 init_excp_7450(env
);
6708 env
->dcache_line_size
= 32;
6709 env
->icache_line_size
= 32;
6710 /* Allocate hardware IRQ controller */
6711 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6714 POWERPC_FAMILY(7440)(ObjectClass
*oc
, void *data
)
6716 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6717 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6719 dc
->desc
= "PowerPC 7440 (aka G4)";
6720 pcc
->init_proc
= init_proc_7440
;
6721 pcc
->check_pow
= check_pow_hid0_74xx
;
6722 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6723 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6724 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6726 PPC_CACHE
| PPC_CACHE_ICBI
|
6727 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6728 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6729 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6730 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6731 PPC_SEGMENT
| PPC_EXTERN
|
6733 pcc
->msr_mask
= (1ull << MSR_VR
) |
6750 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6751 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6752 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6753 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6754 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6755 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6756 POWERPC_FLAG_BUS_CLK
;
6759 static void init_proc_7450 (CPUPPCState
*env
)
6761 gen_spr_ne_601(env
);
6766 /* 74xx specific SPR */
6768 /* Level 3 cache control */
6771 /* XXX : not implemented */
6772 spr_register(env
, SPR_L3ITCR1
, "L3ITCR1",
6773 SPR_NOACCESS
, SPR_NOACCESS
,
6774 &spr_read_generic
, &spr_write_generic
,
6777 /* XXX : not implemented */
6778 spr_register(env
, SPR_L3ITCR2
, "L3ITCR2",
6779 SPR_NOACCESS
, SPR_NOACCESS
,
6780 &spr_read_generic
, &spr_write_generic
,
6783 /* XXX : not implemented */
6784 spr_register(env
, SPR_L3ITCR3
, "L3ITCR3",
6785 SPR_NOACCESS
, SPR_NOACCESS
,
6786 &spr_read_generic
, &spr_write_generic
,
6789 /* XXX : not implemented */
6790 spr_register(env
, SPR_L3OHCR
, "L3OHCR",
6791 SPR_NOACCESS
, SPR_NOACCESS
,
6792 &spr_read_generic
, &spr_write_generic
,
6794 /* XXX : not implemented */
6795 spr_register(env
, SPR_UBAMR
, "UBAMR",
6796 &spr_read_ureg
, SPR_NOACCESS
,
6797 &spr_read_ureg
, SPR_NOACCESS
,
6800 /* XXX : not implemented */
6801 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6802 SPR_NOACCESS
, SPR_NOACCESS
,
6803 &spr_read_generic
, &spr_write_generic
,
6806 /* XXX : not implemented */
6807 spr_register(env
, SPR_ICTRL
, "ICTRL",
6808 SPR_NOACCESS
, SPR_NOACCESS
,
6809 &spr_read_generic
, &spr_write_generic
,
6812 /* XXX : not implemented */
6813 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6814 SPR_NOACCESS
, SPR_NOACCESS
,
6815 &spr_read_generic
, &spr_write_generic
,
6818 /* XXX : not implemented */
6819 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6820 SPR_NOACCESS
, SPR_NOACCESS
,
6821 &spr_read_generic
, &spr_write_generic
,
6823 /* XXX : not implemented */
6824 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6825 &spr_read_ureg
, SPR_NOACCESS
,
6826 &spr_read_ureg
, SPR_NOACCESS
,
6828 /* XXX : not implemented */
6829 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6830 SPR_NOACCESS
, SPR_NOACCESS
,
6831 &spr_read_generic
, &spr_write_generic
,
6833 /* XXX : not implemented */
6834 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6835 &spr_read_ureg
, SPR_NOACCESS
,
6836 &spr_read_ureg
, SPR_NOACCESS
,
6838 /* Memory management */
6840 gen_74xx_soft_tlb(env
, 128, 2);
6841 init_excp_7450(env
);
6842 env
->dcache_line_size
= 32;
6843 env
->icache_line_size
= 32;
6844 /* Allocate hardware IRQ controller */
6845 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6848 POWERPC_FAMILY(7450)(ObjectClass
*oc
, void *data
)
6850 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6851 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6853 dc
->desc
= "PowerPC 7450 (aka G4)";
6854 pcc
->init_proc
= init_proc_7450
;
6855 pcc
->check_pow
= check_pow_hid0_74xx
;
6856 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6857 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6858 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6860 PPC_CACHE
| PPC_CACHE_ICBI
|
6861 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6862 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6863 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6864 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6865 PPC_SEGMENT
| PPC_EXTERN
|
6867 pcc
->msr_mask
= (1ull << MSR_VR
) |
6884 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6885 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6886 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6887 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6888 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6889 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6890 POWERPC_FLAG_BUS_CLK
;
6893 static void init_proc_7445 (CPUPPCState
*env
)
6895 gen_spr_ne_601(env
);
6900 /* 74xx specific SPR */
6903 /* XXX : not implemented */
6904 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6905 SPR_NOACCESS
, SPR_NOACCESS
,
6906 &spr_read_generic
, &spr_write_generic
,
6909 /* XXX : not implemented */
6910 spr_register(env
, SPR_ICTRL
, "ICTRL",
6911 SPR_NOACCESS
, SPR_NOACCESS
,
6912 &spr_read_generic
, &spr_write_generic
,
6915 /* XXX : not implemented */
6916 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6917 SPR_NOACCESS
, SPR_NOACCESS
,
6918 &spr_read_generic
, &spr_write_generic
,
6921 /* XXX : not implemented */
6922 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6923 SPR_NOACCESS
, SPR_NOACCESS
,
6924 &spr_read_generic
, &spr_write_generic
,
6926 /* XXX : not implemented */
6927 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6928 &spr_read_ureg
, SPR_NOACCESS
,
6929 &spr_read_ureg
, SPR_NOACCESS
,
6931 /* XXX : not implemented */
6932 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6933 SPR_NOACCESS
, SPR_NOACCESS
,
6934 &spr_read_generic
, &spr_write_generic
,
6936 /* XXX : not implemented */
6937 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6938 &spr_read_ureg
, SPR_NOACCESS
,
6939 &spr_read_ureg
, SPR_NOACCESS
,
6942 spr_register(env
, SPR_SPRG4
, "SPRG4",
6943 SPR_NOACCESS
, SPR_NOACCESS
,
6944 &spr_read_generic
, &spr_write_generic
,
6946 spr_register(env
, SPR_USPRG4
, "USPRG4",
6947 &spr_read_ureg
, SPR_NOACCESS
,
6948 &spr_read_ureg
, SPR_NOACCESS
,
6950 spr_register(env
, SPR_SPRG5
, "SPRG5",
6951 SPR_NOACCESS
, SPR_NOACCESS
,
6952 &spr_read_generic
, &spr_write_generic
,
6954 spr_register(env
, SPR_USPRG5
, "USPRG5",
6955 &spr_read_ureg
, SPR_NOACCESS
,
6956 &spr_read_ureg
, SPR_NOACCESS
,
6958 spr_register(env
, SPR_SPRG6
, "SPRG6",
6959 SPR_NOACCESS
, SPR_NOACCESS
,
6960 &spr_read_generic
, &spr_write_generic
,
6962 spr_register(env
, SPR_USPRG6
, "USPRG6",
6963 &spr_read_ureg
, SPR_NOACCESS
,
6964 &spr_read_ureg
, SPR_NOACCESS
,
6966 spr_register(env
, SPR_SPRG7
, "SPRG7",
6967 SPR_NOACCESS
, SPR_NOACCESS
,
6968 &spr_read_generic
, &spr_write_generic
,
6970 spr_register(env
, SPR_USPRG7
, "USPRG7",
6971 &spr_read_ureg
, SPR_NOACCESS
,
6972 &spr_read_ureg
, SPR_NOACCESS
,
6974 /* Memory management */
6977 gen_74xx_soft_tlb(env
, 128, 2);
6978 init_excp_7450(env
);
6979 env
->dcache_line_size
= 32;
6980 env
->icache_line_size
= 32;
6981 /* Allocate hardware IRQ controller */
6982 ppc6xx_irq_init(ppc_env_get_cpu(env
));
6985 POWERPC_FAMILY(7445)(ObjectClass
*oc
, void *data
)
6987 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6988 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6990 dc
->desc
= "PowerPC 7445 (aka G4)";
6991 pcc
->init_proc
= init_proc_7445
;
6992 pcc
->check_pow
= check_pow_hid0_74xx
;
6993 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6994 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6995 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6997 PPC_CACHE
| PPC_CACHE_ICBI
|
6998 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6999 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7000 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7001 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7002 PPC_SEGMENT
| PPC_EXTERN
|
7004 pcc
->msr_mask
= (1ull << MSR_VR
) |
7021 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7022 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7023 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7024 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7025 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7026 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7027 POWERPC_FLAG_BUS_CLK
;
7030 static void init_proc_7455 (CPUPPCState
*env
)
7032 gen_spr_ne_601(env
);
7037 /* 74xx specific SPR */
7039 /* Level 3 cache control */
7042 /* XXX : not implemented */
7043 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7044 SPR_NOACCESS
, SPR_NOACCESS
,
7045 &spr_read_generic
, &spr_write_generic
,
7048 /* XXX : not implemented */
7049 spr_register(env
, SPR_ICTRL
, "ICTRL",
7050 SPR_NOACCESS
, SPR_NOACCESS
,
7051 &spr_read_generic
, &spr_write_generic
,
7054 /* XXX : not implemented */
7055 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7056 SPR_NOACCESS
, SPR_NOACCESS
,
7057 &spr_read_generic
, &spr_write_generic
,
7060 /* XXX : not implemented */
7061 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7062 SPR_NOACCESS
, SPR_NOACCESS
,
7063 &spr_read_generic
, &spr_write_generic
,
7065 /* XXX : not implemented */
7066 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7067 &spr_read_ureg
, SPR_NOACCESS
,
7068 &spr_read_ureg
, SPR_NOACCESS
,
7070 /* XXX : not implemented */
7071 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7072 SPR_NOACCESS
, SPR_NOACCESS
,
7073 &spr_read_generic
, &spr_write_generic
,
7075 /* XXX : not implemented */
7076 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7077 &spr_read_ureg
, SPR_NOACCESS
,
7078 &spr_read_ureg
, SPR_NOACCESS
,
7081 spr_register(env
, SPR_SPRG4
, "SPRG4",
7082 SPR_NOACCESS
, SPR_NOACCESS
,
7083 &spr_read_generic
, &spr_write_generic
,
7085 spr_register(env
, SPR_USPRG4
, "USPRG4",
7086 &spr_read_ureg
, SPR_NOACCESS
,
7087 &spr_read_ureg
, SPR_NOACCESS
,
7089 spr_register(env
, SPR_SPRG5
, "SPRG5",
7090 SPR_NOACCESS
, SPR_NOACCESS
,
7091 &spr_read_generic
, &spr_write_generic
,
7093 spr_register(env
, SPR_USPRG5
, "USPRG5",
7094 &spr_read_ureg
, SPR_NOACCESS
,
7095 &spr_read_ureg
, SPR_NOACCESS
,
7097 spr_register(env
, SPR_SPRG6
, "SPRG6",
7098 SPR_NOACCESS
, SPR_NOACCESS
,
7099 &spr_read_generic
, &spr_write_generic
,
7101 spr_register(env
, SPR_USPRG6
, "USPRG6",
7102 &spr_read_ureg
, SPR_NOACCESS
,
7103 &spr_read_ureg
, SPR_NOACCESS
,
7105 spr_register(env
, SPR_SPRG7
, "SPRG7",
7106 SPR_NOACCESS
, SPR_NOACCESS
,
7107 &spr_read_generic
, &spr_write_generic
,
7109 spr_register(env
, SPR_USPRG7
, "USPRG7",
7110 &spr_read_ureg
, SPR_NOACCESS
,
7111 &spr_read_ureg
, SPR_NOACCESS
,
7113 /* Memory management */
7116 gen_74xx_soft_tlb(env
, 128, 2);
7117 init_excp_7450(env
);
7118 env
->dcache_line_size
= 32;
7119 env
->icache_line_size
= 32;
7120 /* Allocate hardware IRQ controller */
7121 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7124 POWERPC_FAMILY(7455)(ObjectClass
*oc
, void *data
)
7126 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7127 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7129 dc
->desc
= "PowerPC 7455 (aka G4)";
7130 pcc
->init_proc
= init_proc_7455
;
7131 pcc
->check_pow
= check_pow_hid0_74xx
;
7132 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7133 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7134 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7136 PPC_CACHE
| PPC_CACHE_ICBI
|
7137 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7138 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7139 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7140 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7141 PPC_SEGMENT
| PPC_EXTERN
|
7143 pcc
->msr_mask
= (1ull << MSR_VR
) |
7160 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7161 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7162 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7163 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7164 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7165 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7166 POWERPC_FLAG_BUS_CLK
;
7169 static void init_proc_7457 (CPUPPCState
*env
)
7171 gen_spr_ne_601(env
);
7176 /* 74xx specific SPR */
7178 /* Level 3 cache control */
7181 /* XXX : not implemented */
7182 spr_register(env
, SPR_L3ITCR1
, "L3ITCR1",
7183 SPR_NOACCESS
, SPR_NOACCESS
,
7184 &spr_read_generic
, &spr_write_generic
,
7187 /* XXX : not implemented */
7188 spr_register(env
, SPR_L3ITCR2
, "L3ITCR2",
7189 SPR_NOACCESS
, SPR_NOACCESS
,
7190 &spr_read_generic
, &spr_write_generic
,
7193 /* XXX : not implemented */
7194 spr_register(env
, SPR_L3ITCR3
, "L3ITCR3",
7195 SPR_NOACCESS
, SPR_NOACCESS
,
7196 &spr_read_generic
, &spr_write_generic
,
7199 /* XXX : not implemented */
7200 spr_register(env
, SPR_L3OHCR
, "L3OHCR",
7201 SPR_NOACCESS
, SPR_NOACCESS
,
7202 &spr_read_generic
, &spr_write_generic
,
7205 /* XXX : not implemented */
7206 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7207 SPR_NOACCESS
, SPR_NOACCESS
,
7208 &spr_read_generic
, &spr_write_generic
,
7211 /* XXX : not implemented */
7212 spr_register(env
, SPR_ICTRL
, "ICTRL",
7213 SPR_NOACCESS
, SPR_NOACCESS
,
7214 &spr_read_generic
, &spr_write_generic
,
7217 /* XXX : not implemented */
7218 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7219 SPR_NOACCESS
, SPR_NOACCESS
,
7220 &spr_read_generic
, &spr_write_generic
,
7223 /* XXX : not implemented */
7224 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7225 SPR_NOACCESS
, SPR_NOACCESS
,
7226 &spr_read_generic
, &spr_write_generic
,
7228 /* XXX : not implemented */
7229 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7230 &spr_read_ureg
, SPR_NOACCESS
,
7231 &spr_read_ureg
, SPR_NOACCESS
,
7233 /* XXX : not implemented */
7234 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7235 SPR_NOACCESS
, SPR_NOACCESS
,
7236 &spr_read_generic
, &spr_write_generic
,
7238 /* XXX : not implemented */
7239 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7240 &spr_read_ureg
, SPR_NOACCESS
,
7241 &spr_read_ureg
, SPR_NOACCESS
,
7244 spr_register(env
, SPR_SPRG4
, "SPRG4",
7245 SPR_NOACCESS
, SPR_NOACCESS
,
7246 &spr_read_generic
, &spr_write_generic
,
7248 spr_register(env
, SPR_USPRG4
, "USPRG4",
7249 &spr_read_ureg
, SPR_NOACCESS
,
7250 &spr_read_ureg
, SPR_NOACCESS
,
7252 spr_register(env
, SPR_SPRG5
, "SPRG5",
7253 SPR_NOACCESS
, SPR_NOACCESS
,
7254 &spr_read_generic
, &spr_write_generic
,
7256 spr_register(env
, SPR_USPRG5
, "USPRG5",
7257 &spr_read_ureg
, SPR_NOACCESS
,
7258 &spr_read_ureg
, SPR_NOACCESS
,
7260 spr_register(env
, SPR_SPRG6
, "SPRG6",
7261 SPR_NOACCESS
, SPR_NOACCESS
,
7262 &spr_read_generic
, &spr_write_generic
,
7264 spr_register(env
, SPR_USPRG6
, "USPRG6",
7265 &spr_read_ureg
, SPR_NOACCESS
,
7266 &spr_read_ureg
, SPR_NOACCESS
,
7268 spr_register(env
, SPR_SPRG7
, "SPRG7",
7269 SPR_NOACCESS
, SPR_NOACCESS
,
7270 &spr_read_generic
, &spr_write_generic
,
7272 spr_register(env
, SPR_USPRG7
, "USPRG7",
7273 &spr_read_ureg
, SPR_NOACCESS
,
7274 &spr_read_ureg
, SPR_NOACCESS
,
7276 /* Memory management */
7279 gen_74xx_soft_tlb(env
, 128, 2);
7280 init_excp_7450(env
);
7281 env
->dcache_line_size
= 32;
7282 env
->icache_line_size
= 32;
7283 /* Allocate hardware IRQ controller */
7284 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7287 POWERPC_FAMILY(7457)(ObjectClass
*oc
, void *data
)
7289 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7290 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7292 dc
->desc
= "PowerPC 7457 (aka G4)";
7293 pcc
->init_proc
= init_proc_7457
;
7294 pcc
->check_pow
= check_pow_hid0_74xx
;
7295 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7296 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7297 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7299 PPC_CACHE
| PPC_CACHE_ICBI
|
7300 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7301 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7302 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7303 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7304 PPC_SEGMENT
| PPC_EXTERN
|
7306 pcc
->msr_mask
= (1ull << MSR_VR
) |
7323 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7324 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7325 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7326 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7327 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7328 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7329 POWERPC_FLAG_BUS_CLK
;
7332 static void init_proc_e600 (CPUPPCState
*env
)
7334 gen_spr_ne_601(env
);
7339 /* 74xx specific SPR */
7341 /* XXX : not implemented */
7342 spr_register(env
, SPR_UBAMR
, "UBAMR",
7343 &spr_read_ureg
, SPR_NOACCESS
,
7344 &spr_read_ureg
, SPR_NOACCESS
,
7346 /* XXX : not implemented */
7347 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7348 SPR_NOACCESS
, SPR_NOACCESS
,
7349 &spr_read_generic
, &spr_write_generic
,
7351 /* XXX : not implemented */
7352 spr_register(env
, SPR_ICTRL
, "ICTRL",
7353 SPR_NOACCESS
, SPR_NOACCESS
,
7354 &spr_read_generic
, &spr_write_generic
,
7356 /* XXX : not implemented */
7357 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7358 SPR_NOACCESS
, SPR_NOACCESS
,
7359 &spr_read_generic
, &spr_write_generic
,
7361 /* XXX : not implemented */
7362 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7363 SPR_NOACCESS
, SPR_NOACCESS
,
7364 &spr_read_generic
, &spr_write_generic
,
7366 /* XXX : not implemented */
7367 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7368 &spr_read_ureg
, SPR_NOACCESS
,
7369 &spr_read_ureg
, SPR_NOACCESS
,
7371 /* XXX : not implemented */
7372 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7373 SPR_NOACCESS
, SPR_NOACCESS
,
7374 &spr_read_generic
, &spr_write_generic
,
7376 /* XXX : not implemented */
7377 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7378 &spr_read_ureg
, SPR_NOACCESS
,
7379 &spr_read_ureg
, SPR_NOACCESS
,
7382 spr_register(env
, SPR_SPRG4
, "SPRG4",
7383 SPR_NOACCESS
, SPR_NOACCESS
,
7384 &spr_read_generic
, &spr_write_generic
,
7386 spr_register(env
, SPR_USPRG4
, "USPRG4",
7387 &spr_read_ureg
, SPR_NOACCESS
,
7388 &spr_read_ureg
, SPR_NOACCESS
,
7390 spr_register(env
, SPR_SPRG5
, "SPRG5",
7391 SPR_NOACCESS
, SPR_NOACCESS
,
7392 &spr_read_generic
, &spr_write_generic
,
7394 spr_register(env
, SPR_USPRG5
, "USPRG5",
7395 &spr_read_ureg
, SPR_NOACCESS
,
7396 &spr_read_ureg
, SPR_NOACCESS
,
7398 spr_register(env
, SPR_SPRG6
, "SPRG6",
7399 SPR_NOACCESS
, SPR_NOACCESS
,
7400 &spr_read_generic
, &spr_write_generic
,
7402 spr_register(env
, SPR_USPRG6
, "USPRG6",
7403 &spr_read_ureg
, SPR_NOACCESS
,
7404 &spr_read_ureg
, SPR_NOACCESS
,
7406 spr_register(env
, SPR_SPRG7
, "SPRG7",
7407 SPR_NOACCESS
, SPR_NOACCESS
,
7408 &spr_read_generic
, &spr_write_generic
,
7410 spr_register(env
, SPR_USPRG7
, "USPRG7",
7411 &spr_read_ureg
, SPR_NOACCESS
,
7412 &spr_read_ureg
, SPR_NOACCESS
,
7414 /* Memory management */
7417 gen_74xx_soft_tlb(env
, 128, 2);
7418 init_excp_7450(env
);
7419 env
->dcache_line_size
= 32;
7420 env
->icache_line_size
= 32;
7421 /* Allocate hardware IRQ controller */
7422 ppc6xx_irq_init(ppc_env_get_cpu(env
));
7425 POWERPC_FAMILY(e600
)(ObjectClass
*oc
, void *data
)
7427 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7428 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7430 dc
->desc
= "PowerPC e600";
7431 pcc
->init_proc
= init_proc_e600
;
7432 pcc
->check_pow
= check_pow_hid0_74xx
;
7433 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7434 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7435 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7437 PPC_CACHE
| PPC_CACHE_ICBI
|
7438 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7439 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7440 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7441 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7442 PPC_SEGMENT
| PPC_EXTERN
|
7444 pcc
->insns_flags2
= PPC_NONE
;
7445 pcc
->msr_mask
= (1ull << MSR_VR
) |
7462 pcc
->mmu_model
= POWERPC_MMU_32B
;
7463 #if defined(CONFIG_SOFTMMU)
7464 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
7466 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7467 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7468 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7469 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7470 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7471 POWERPC_FLAG_BUS_CLK
;
7474 #if defined (TARGET_PPC64)
7475 #if defined(CONFIG_USER_ONLY)
7476 #define POWERPC970_HID5_INIT 0x00000080
7478 #define POWERPC970_HID5_INIT 0x00000000
7481 static void gen_fscr_facility_check(DisasContext
*ctx
, int facility_sprn
,
7482 int bit
, int sprn
, int cause
)
7484 TCGv_i32 t1
= tcg_const_i32(bit
);
7485 TCGv_i32 t2
= tcg_const_i32(sprn
);
7486 TCGv_i32 t3
= tcg_const_i32(cause
);
7488 gen_helper_fscr_facility_check(cpu_env
, t1
, t2
, t3
);
7490 tcg_temp_free_i32(t3
);
7491 tcg_temp_free_i32(t2
);
7492 tcg_temp_free_i32(t1
);
7495 static void gen_msr_facility_check(DisasContext
*ctx
, int facility_sprn
,
7496 int bit
, int sprn
, int cause
)
7498 TCGv_i32 t1
= tcg_const_i32(bit
);
7499 TCGv_i32 t2
= tcg_const_i32(sprn
);
7500 TCGv_i32 t3
= tcg_const_i32(cause
);
7502 gen_helper_msr_facility_check(cpu_env
, t1
, t2
, t3
);
7504 tcg_temp_free_i32(t3
);
7505 tcg_temp_free_i32(t2
);
7506 tcg_temp_free_i32(t1
);
7509 static void spr_read_prev_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
7511 TCGv spr_up
= tcg_temp_new();
7512 TCGv spr
= tcg_temp_new();
7514 gen_load_spr(spr
, sprn
- 1);
7515 tcg_gen_shri_tl(spr_up
, spr
, 32);
7516 tcg_gen_ext32u_tl(cpu_gpr
[gprn
], spr_up
);
7519 tcg_temp_free(spr_up
);
7522 static void spr_write_prev_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
7524 TCGv spr
= tcg_temp_new();
7526 gen_load_spr(spr
, sprn
- 1);
7527 tcg_gen_deposit_tl(spr
, spr
, cpu_gpr
[gprn
], 32, 32);
7528 gen_store_spr(sprn
- 1, spr
);
7533 static int check_pow_970 (CPUPPCState
*env
)
7535 if (env
->spr
[SPR_HID0
] & (HID0_DEEPNAP
| HID0_DOZE
| HID0_NAP
)) {
7542 static void gen_spr_970_hid(CPUPPCState
*env
)
7544 /* Hardware implementation registers */
7545 /* XXX : not implemented */
7546 spr_register(env
, SPR_HID0
, "HID0",
7547 SPR_NOACCESS
, SPR_NOACCESS
,
7548 &spr_read_generic
, &spr_write_clear
,
7550 spr_register(env
, SPR_HID1
, "HID1",
7551 SPR_NOACCESS
, SPR_NOACCESS
,
7552 &spr_read_generic
, &spr_write_generic
,
7554 spr_register(env
, SPR_970_HID5
, "HID5",
7555 SPR_NOACCESS
, SPR_NOACCESS
,
7556 &spr_read_generic
, &spr_write_generic
,
7557 POWERPC970_HID5_INIT
);
7560 static void gen_spr_970_hior(CPUPPCState
*env
)
7562 spr_register(env
, SPR_HIOR
, "SPR_HIOR",
7563 SPR_NOACCESS
, SPR_NOACCESS
,
7564 &spr_read_hior
, &spr_write_hior
,
7568 static void gen_spr_book3s_ctrl(CPUPPCState
*env
)
7570 spr_register(env
, SPR_CTRL
, "SPR_CTRL",
7571 SPR_NOACCESS
, SPR_NOACCESS
,
7572 SPR_NOACCESS
, &spr_write_generic
,
7574 spr_register(env
, SPR_UCTRL
, "SPR_UCTRL",
7575 &spr_read_ureg
, SPR_NOACCESS
,
7576 &spr_read_ureg
, SPR_NOACCESS
,
7580 static void gen_spr_book3s_altivec(CPUPPCState
*env
)
7582 if (!(env
->insns_flags
& PPC_ALTIVEC
)) {
7586 spr_register_kvm(env
, SPR_VRSAVE
, "VRSAVE",
7587 &spr_read_generic
, &spr_write_generic
,
7588 &spr_read_generic
, &spr_write_generic
,
7589 KVM_REG_PPC_VRSAVE
, 0x00000000);
7591 /* Can't find information on what this should be on reset. This
7592 * value is the one used by 74xx processors. */
7593 vscr_init(env
, 0x00010000);
7596 static void gen_spr_book3s_dbg(CPUPPCState
*env
)
7599 * TODO: different specs define different scopes for these,
7600 * will have to address this:
7601 * 970: super/write and super/read
7602 * powerisa 2.03..2.04: hypv/write and super/read.
7603 * powerisa 2.05 and newer: hypv/write and hypv/read.
7605 spr_register_kvm(env
, SPR_DABR
, "DABR",
7606 SPR_NOACCESS
, SPR_NOACCESS
,
7607 &spr_read_generic
, &spr_write_generic
,
7608 KVM_REG_PPC_DABR
, 0x00000000);
7609 spr_register_kvm(env
, SPR_DABRX
, "DABRX",
7610 SPR_NOACCESS
, SPR_NOACCESS
,
7611 &spr_read_generic
, &spr_write_generic
,
7612 KVM_REG_PPC_DABRX
, 0x00000000);
7615 static void gen_spr_book3s_207_dbg(CPUPPCState
*env
)
7617 spr_register_kvm_hv(env
, SPR_DAWR
, "DAWR",
7618 SPR_NOACCESS
, SPR_NOACCESS
,
7619 SPR_NOACCESS
, SPR_NOACCESS
,
7620 &spr_read_generic
, &spr_write_generic
,
7621 KVM_REG_PPC_DAWR
, 0x00000000);
7622 spr_register_kvm_hv(env
, SPR_DAWRX
, "DAWRX",
7623 SPR_NOACCESS
, SPR_NOACCESS
,
7624 SPR_NOACCESS
, SPR_NOACCESS
,
7625 &spr_read_generic
, &spr_write_generic
,
7626 KVM_REG_PPC_DAWRX
, 0x00000000);
7627 spr_register_kvm_hv(env
, SPR_CIABR
, "CIABR",
7628 SPR_NOACCESS
, SPR_NOACCESS
,
7629 SPR_NOACCESS
, SPR_NOACCESS
,
7630 &spr_read_generic
, &spr_write_generic
,
7631 KVM_REG_PPC_CIABR
, 0x00000000);
7634 static void gen_spr_970_dbg(CPUPPCState
*env
)
7637 spr_register(env
, SPR_IABR
, "IABR",
7638 SPR_NOACCESS
, SPR_NOACCESS
,
7639 &spr_read_generic
, &spr_write_generic
,
7643 static void gen_spr_book3s_pmu_sup(CPUPPCState
*env
)
7645 spr_register_kvm(env
, SPR_POWER_MMCR0
, "MMCR0",
7646 SPR_NOACCESS
, SPR_NOACCESS
,
7647 &spr_read_generic
, &spr_write_generic
,
7648 KVM_REG_PPC_MMCR0
, 0x00000000);
7649 spr_register_kvm(env
, SPR_POWER_MMCR1
, "MMCR1",
7650 SPR_NOACCESS
, SPR_NOACCESS
,
7651 &spr_read_generic
, &spr_write_generic
,
7652 KVM_REG_PPC_MMCR1
, 0x00000000);
7653 spr_register_kvm(env
, SPR_POWER_MMCRA
, "MMCRA",
7654 SPR_NOACCESS
, SPR_NOACCESS
,
7655 &spr_read_generic
, &spr_write_generic
,
7656 KVM_REG_PPC_MMCRA
, 0x00000000);
7657 spr_register_kvm(env
, SPR_POWER_PMC1
, "PMC1",
7658 SPR_NOACCESS
, SPR_NOACCESS
,
7659 &spr_read_generic
, &spr_write_generic
,
7660 KVM_REG_PPC_PMC1
, 0x00000000);
7661 spr_register_kvm(env
, SPR_POWER_PMC2
, "PMC2",
7662 SPR_NOACCESS
, SPR_NOACCESS
,
7663 &spr_read_generic
, &spr_write_generic
,
7664 KVM_REG_PPC_PMC2
, 0x00000000);
7665 spr_register_kvm(env
, SPR_POWER_PMC3
, "PMC3",
7666 SPR_NOACCESS
, SPR_NOACCESS
,
7667 &spr_read_generic
, &spr_write_generic
,
7668 KVM_REG_PPC_PMC3
, 0x00000000);
7669 spr_register_kvm(env
, SPR_POWER_PMC4
, "PMC4",
7670 SPR_NOACCESS
, SPR_NOACCESS
,
7671 &spr_read_generic
, &spr_write_generic
,
7672 KVM_REG_PPC_PMC4
, 0x00000000);
7673 spr_register_kvm(env
, SPR_POWER_PMC5
, "PMC5",
7674 SPR_NOACCESS
, SPR_NOACCESS
,
7675 &spr_read_generic
, &spr_write_generic
,
7676 KVM_REG_PPC_PMC5
, 0x00000000);
7677 spr_register_kvm(env
, SPR_POWER_PMC6
, "PMC6",
7678 SPR_NOACCESS
, SPR_NOACCESS
,
7679 &spr_read_generic
, &spr_write_generic
,
7680 KVM_REG_PPC_PMC6
, 0x00000000);
7681 spr_register_kvm(env
, SPR_POWER_SIAR
, "SIAR",
7682 SPR_NOACCESS
, SPR_NOACCESS
,
7683 &spr_read_generic
, &spr_write_generic
,
7684 KVM_REG_PPC_SIAR
, 0x00000000);
7685 spr_register_kvm(env
, SPR_POWER_SDAR
, "SDAR",
7686 SPR_NOACCESS
, SPR_NOACCESS
,
7687 &spr_read_generic
, &spr_write_generic
,
7688 KVM_REG_PPC_SDAR
, 0x00000000);
7691 static void gen_spr_book3s_pmu_user(CPUPPCState
*env
)
7693 spr_register(env
, SPR_POWER_UMMCR0
, "UMMCR0",
7694 &spr_read_ureg
, SPR_NOACCESS
,
7695 &spr_read_ureg
, &spr_write_ureg
,
7697 spr_register(env
, SPR_POWER_UMMCR1
, "UMMCR1",
7698 &spr_read_ureg
, SPR_NOACCESS
,
7699 &spr_read_ureg
, &spr_write_ureg
,
7701 spr_register(env
, SPR_POWER_UMMCRA
, "UMMCRA",
7702 &spr_read_ureg
, SPR_NOACCESS
,
7703 &spr_read_ureg
, &spr_write_ureg
,
7705 spr_register(env
, SPR_POWER_UPMC1
, "UPMC1",
7706 &spr_read_ureg
, SPR_NOACCESS
,
7707 &spr_read_ureg
, &spr_write_ureg
,
7709 spr_register(env
, SPR_POWER_UPMC2
, "UPMC2",
7710 &spr_read_ureg
, SPR_NOACCESS
,
7711 &spr_read_ureg
, &spr_write_ureg
,
7713 spr_register(env
, SPR_POWER_UPMC3
, "UPMC3",
7714 &spr_read_ureg
, SPR_NOACCESS
,
7715 &spr_read_ureg
, &spr_write_ureg
,
7717 spr_register(env
, SPR_POWER_UPMC4
, "UPMC4",
7718 &spr_read_ureg
, SPR_NOACCESS
,
7719 &spr_read_ureg
, &spr_write_ureg
,
7721 spr_register(env
, SPR_POWER_UPMC5
, "UPMC5",
7722 &spr_read_ureg
, SPR_NOACCESS
,
7723 &spr_read_ureg
, &spr_write_ureg
,
7725 spr_register(env
, SPR_POWER_UPMC6
, "UPMC6",
7726 &spr_read_ureg
, SPR_NOACCESS
,
7727 &spr_read_ureg
, &spr_write_ureg
,
7729 spr_register(env
, SPR_POWER_USIAR
, "USIAR",
7730 &spr_read_ureg
, SPR_NOACCESS
,
7731 &spr_read_ureg
, &spr_write_ureg
,
7733 spr_register(env
, SPR_POWER_USDAR
, "USDAR",
7734 &spr_read_ureg
, SPR_NOACCESS
,
7735 &spr_read_ureg
, &spr_write_ureg
,
7739 static void gen_spr_970_pmu_sup(CPUPPCState
*env
)
7741 spr_register_kvm(env
, SPR_970_PMC7
, "PMC7",
7742 SPR_NOACCESS
, SPR_NOACCESS
,
7743 &spr_read_generic
, &spr_write_generic
,
7744 KVM_REG_PPC_PMC7
, 0x00000000);
7745 spr_register_kvm(env
, SPR_970_PMC8
, "PMC8",
7746 SPR_NOACCESS
, SPR_NOACCESS
,
7747 &spr_read_generic
, &spr_write_generic
,
7748 KVM_REG_PPC_PMC8
, 0x00000000);
7751 static void gen_spr_970_pmu_user(CPUPPCState
*env
)
7753 spr_register(env
, SPR_970_UPMC7
, "UPMC7",
7754 &spr_read_ureg
, SPR_NOACCESS
,
7755 &spr_read_ureg
, &spr_write_ureg
,
7757 spr_register(env
, SPR_970_UPMC8
, "UPMC8",
7758 &spr_read_ureg
, SPR_NOACCESS
,
7759 &spr_read_ureg
, &spr_write_ureg
,
7763 static void gen_spr_power8_pmu_sup(CPUPPCState
*env
)
7765 spr_register_kvm(env
, SPR_POWER_MMCR2
, "MMCR2",
7766 SPR_NOACCESS
, SPR_NOACCESS
,
7767 &spr_read_generic
, &spr_write_generic
,
7768 KVM_REG_PPC_MMCR2
, 0x00000000);
7769 spr_register_kvm(env
, SPR_POWER_MMCRS
, "MMCRS",
7770 SPR_NOACCESS
, SPR_NOACCESS
,
7771 &spr_read_generic
, &spr_write_generic
,
7772 KVM_REG_PPC_MMCRS
, 0x00000000);
7773 spr_register_kvm(env
, SPR_POWER_SIER
, "SIER",
7774 SPR_NOACCESS
, SPR_NOACCESS
,
7775 &spr_read_generic
, &spr_write_generic
,
7776 KVM_REG_PPC_SIER
, 0x00000000);
7777 spr_register_kvm(env
, SPR_POWER_SPMC1
, "SPMC1",
7778 SPR_NOACCESS
, SPR_NOACCESS
,
7779 &spr_read_generic
, &spr_write_generic
,
7780 KVM_REG_PPC_SPMC1
, 0x00000000);
7781 spr_register_kvm(env
, SPR_POWER_SPMC2
, "SPMC2",
7782 SPR_NOACCESS
, SPR_NOACCESS
,
7783 &spr_read_generic
, &spr_write_generic
,
7784 KVM_REG_PPC_SPMC2
, 0x00000000);
7785 spr_register_kvm(env
, SPR_TACR
, "TACR",
7786 SPR_NOACCESS
, SPR_NOACCESS
,
7787 &spr_read_generic
, &spr_write_generic
,
7788 KVM_REG_PPC_TACR
, 0x00000000);
7789 spr_register_kvm(env
, SPR_TCSCR
, "TCSCR",
7790 SPR_NOACCESS
, SPR_NOACCESS
,
7791 &spr_read_generic
, &spr_write_generic
,
7792 KVM_REG_PPC_TCSCR
, 0x00000000);
7793 spr_register_kvm(env
, SPR_CSIGR
, "CSIGR",
7794 SPR_NOACCESS
, SPR_NOACCESS
,
7795 &spr_read_generic
, &spr_write_generic
,
7796 KVM_REG_PPC_CSIGR
, 0x00000000);
7799 static void gen_spr_power8_pmu_user(CPUPPCState
*env
)
7801 spr_register(env
, SPR_POWER_UMMCR2
, "UMMCR2",
7802 &spr_read_ureg
, SPR_NOACCESS
,
7803 &spr_read_ureg
, &spr_write_ureg
,
7805 spr_register(env
, SPR_POWER_USIER
, "USIER",
7806 &spr_read_generic
, SPR_NOACCESS
,
7807 &spr_read_generic
, &spr_write_generic
,
7811 static void gen_spr_power5p_ear(CPUPPCState
*env
)
7813 /* External access control */
7814 spr_register(env
, SPR_EAR
, "EAR",
7815 SPR_NOACCESS
, SPR_NOACCESS
,
7816 &spr_read_generic
, &spr_write_generic
,
7820 #if !defined(CONFIG_USER_ONLY)
7821 static void spr_write_hmer(DisasContext
*ctx
, int sprn
, int gprn
)
7823 TCGv hmer
= tcg_temp_new();
7825 gen_load_spr(hmer
, sprn
);
7826 tcg_gen_and_tl(hmer
, cpu_gpr
[gprn
], hmer
);
7827 gen_store_spr(sprn
, hmer
);
7828 spr_store_dump_spr(sprn
);
7829 tcg_temp_free(hmer
);
7832 static void spr_write_lpcr(DisasContext
*ctx
, int sprn
, int gprn
)
7834 gen_helper_store_lpcr(cpu_env
, cpu_gpr
[gprn
]);
7837 static void spr_write_970_hid4(DisasContext
*ctx
, int sprn
, int gprn
)
7839 #if defined(TARGET_PPC64)
7840 spr_write_generic(ctx
, sprn
, gprn
);
7841 gen_helper_store_lpcr(cpu_env
, cpu_gpr
[gprn
]);
7845 #endif /* !defined(CONFIG_USER_ONLY) */
7847 static void gen_spr_970_lpar(CPUPPCState
*env
)
7849 #if !defined(CONFIG_USER_ONLY)
7850 /* Logical partitionning */
7851 /* PPC970: HID4 is effectively the LPCR */
7852 spr_register(env
, SPR_970_HID4
, "HID4",
7853 SPR_NOACCESS
, SPR_NOACCESS
,
7854 &spr_read_generic
, &spr_write_970_hid4
,
7859 static void gen_spr_power5p_lpar(CPUPPCState
*env
)
7861 #if !defined(CONFIG_USER_ONLY)
7862 /* Logical partitionning */
7863 spr_register_kvm_hv(env
, SPR_LPCR
, "LPCR",
7864 SPR_NOACCESS
, SPR_NOACCESS
,
7865 SPR_NOACCESS
, SPR_NOACCESS
,
7866 &spr_read_generic
, &spr_write_lpcr
,
7867 KVM_REG_PPC_LPCR
, LPCR_LPES0
| LPCR_LPES1
);
7868 spr_register_hv(env
, SPR_HDEC
, "HDEC",
7869 SPR_NOACCESS
, SPR_NOACCESS
,
7870 SPR_NOACCESS
, SPR_NOACCESS
,
7871 &spr_read_hdecr
, &spr_write_hdecr
, 0);
7875 static void gen_spr_book3s_ids(CPUPPCState
*env
)
7877 /* FIXME: Will need to deal with thread vs core only SPRs */
7879 /* Processor identification */
7880 spr_register_hv(env
, SPR_PIR
, "PIR",
7881 SPR_NOACCESS
, SPR_NOACCESS
,
7882 SPR_NOACCESS
, SPR_NOACCESS
,
7883 &spr_read_generic
, NULL
,
7885 spr_register_hv(env
, SPR_HID0
, "HID0",
7886 SPR_NOACCESS
, SPR_NOACCESS
,
7887 SPR_NOACCESS
, SPR_NOACCESS
,
7888 &spr_read_generic
, &spr_write_generic
,
7890 spr_register_hv(env
, SPR_TSCR
, "TSCR",
7891 SPR_NOACCESS
, SPR_NOACCESS
,
7892 SPR_NOACCESS
, SPR_NOACCESS
,
7893 &spr_read_generic
, &spr_write_generic
,
7895 spr_register_hv(env
, SPR_HMER
, "HMER",
7896 SPR_NOACCESS
, SPR_NOACCESS
,
7897 SPR_NOACCESS
, SPR_NOACCESS
,
7898 &spr_read_generic
, &spr_write_hmer
,
7900 spr_register_hv(env
, SPR_HMEER
, "HMEER",
7901 SPR_NOACCESS
, SPR_NOACCESS
,
7902 SPR_NOACCESS
, SPR_NOACCESS
,
7903 &spr_read_generic
, &spr_write_generic
,
7905 spr_register_hv(env
, SPR_TFMR
, "TFMR",
7906 SPR_NOACCESS
, SPR_NOACCESS
,
7907 SPR_NOACCESS
, SPR_NOACCESS
,
7908 &spr_read_generic
, &spr_write_generic
,
7910 spr_register_hv(env
, SPR_LPIDR
, "LPIDR",
7911 SPR_NOACCESS
, SPR_NOACCESS
,
7912 SPR_NOACCESS
, SPR_NOACCESS
,
7913 &spr_read_generic
, &spr_write_generic
,
7915 spr_register_hv(env
, SPR_HFSCR
, "HFSCR",
7916 SPR_NOACCESS
, SPR_NOACCESS
,
7917 SPR_NOACCESS
, SPR_NOACCESS
,
7918 &spr_read_generic
, &spr_write_generic
,
7920 spr_register_hv(env
, SPR_MMCRC
, "MMCRC",
7921 SPR_NOACCESS
, SPR_NOACCESS
,
7922 SPR_NOACCESS
, SPR_NOACCESS
,
7923 &spr_read_generic
, &spr_write_generic
,
7925 spr_register_hv(env
, SPR_MMCRH
, "MMCRH",
7926 SPR_NOACCESS
, SPR_NOACCESS
,
7927 SPR_NOACCESS
, SPR_NOACCESS
,
7928 &spr_read_generic
, &spr_write_generic
,
7930 spr_register_hv(env
, SPR_HSPRG0
, "HSPRG0",
7931 SPR_NOACCESS
, SPR_NOACCESS
,
7932 SPR_NOACCESS
, SPR_NOACCESS
,
7933 &spr_read_generic
, &spr_write_generic
,
7935 spr_register_hv(env
, SPR_HSPRG1
, "HSPRG1",
7936 SPR_NOACCESS
, SPR_NOACCESS
,
7937 SPR_NOACCESS
, SPR_NOACCESS
,
7938 &spr_read_generic
, &spr_write_generic
,
7940 spr_register_hv(env
, SPR_HSRR0
, "HSRR0",
7941 SPR_NOACCESS
, SPR_NOACCESS
,
7942 SPR_NOACCESS
, SPR_NOACCESS
,
7943 &spr_read_generic
, &spr_write_generic
,
7945 spr_register_hv(env
, SPR_HSRR1
, "HSRR1",
7946 SPR_NOACCESS
, SPR_NOACCESS
,
7947 SPR_NOACCESS
, SPR_NOACCESS
,
7948 &spr_read_generic
, &spr_write_generic
,
7950 spr_register_hv(env
, SPR_HDAR
, "HDAR",
7951 SPR_NOACCESS
, SPR_NOACCESS
,
7952 SPR_NOACCESS
, SPR_NOACCESS
,
7953 &spr_read_generic
, &spr_write_generic
,
7955 spr_register_hv(env
, SPR_HDSISR
, "HDSISR",
7956 SPR_NOACCESS
, SPR_NOACCESS
,
7957 SPR_NOACCESS
, SPR_NOACCESS
,
7958 &spr_read_generic
, &spr_write_generic
,
7960 spr_register_hv(env
, SPR_RMOR
, "RMOR",
7961 SPR_NOACCESS
, SPR_NOACCESS
,
7962 SPR_NOACCESS
, SPR_NOACCESS
,
7963 &spr_read_generic
, &spr_write_generic
,
7965 spr_register_hv(env
, SPR_HRMOR
, "HRMOR",
7966 SPR_NOACCESS
, SPR_NOACCESS
,
7967 SPR_NOACCESS
, SPR_NOACCESS
,
7968 &spr_read_generic
, &spr_write_generic
,
7972 static void gen_spr_power8_ids(CPUPPCState
*env
)
7974 /* Thread identification */
7975 spr_register(env
, SPR_TIR
, "TIR",
7976 SPR_NOACCESS
, SPR_NOACCESS
,
7977 &spr_read_generic
, SPR_NOACCESS
,
7981 static void gen_spr_book3s_purr(CPUPPCState
*env
)
7983 #if !defined(CONFIG_USER_ONLY)
7984 /* PURR & SPURR: Hack - treat these as aliases for the TB for now */
7985 spr_register_kvm(env
, SPR_PURR
, "PURR",
7986 &spr_read_purr
, SPR_NOACCESS
,
7987 &spr_read_purr
, SPR_NOACCESS
,
7988 KVM_REG_PPC_PURR
, 0x00000000);
7989 spr_register_kvm(env
, SPR_SPURR
, "SPURR",
7990 &spr_read_purr
, SPR_NOACCESS
,
7991 &spr_read_purr
, SPR_NOACCESS
,
7992 KVM_REG_PPC_SPURR
, 0x00000000);
7996 static void gen_spr_power6_dbg(CPUPPCState
*env
)
7998 #if !defined(CONFIG_USER_ONLY)
7999 spr_register(env
, SPR_CFAR
, "SPR_CFAR",
8000 SPR_NOACCESS
, SPR_NOACCESS
,
8001 &spr_read_cfar
, &spr_write_cfar
,
8006 static void gen_spr_power5p_common(CPUPPCState
*env
)
8008 spr_register_kvm(env
, SPR_PPR
, "PPR",
8009 &spr_read_generic
, &spr_write_generic
,
8010 &spr_read_generic
, &spr_write_generic
,
8011 KVM_REG_PPC_PPR
, 0x00000000);
8014 static void gen_spr_power6_common(CPUPPCState
*env
)
8016 #if !defined(CONFIG_USER_ONLY)
8017 spr_register_kvm(env
, SPR_DSCR
, "SPR_DSCR",
8018 SPR_NOACCESS
, SPR_NOACCESS
,
8019 &spr_read_generic
, &spr_write_generic
,
8020 KVM_REG_PPC_DSCR
, 0x00000000);
8023 * Register PCR to report POWERPC_EXCP_PRIV_REG instead of
8024 * POWERPC_EXCP_INVAL_SPR.
8026 spr_register(env
, SPR_PCR
, "PCR",
8027 SPR_NOACCESS
, SPR_NOACCESS
,
8028 SPR_NOACCESS
, SPR_NOACCESS
,
8032 static void spr_read_tar(DisasContext
*ctx
, int gprn
, int sprn
)
8034 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_TAR
, sprn
, FSCR_IC_TAR
);
8035 spr_read_generic(ctx
, gprn
, sprn
);
8038 static void spr_write_tar(DisasContext
*ctx
, int sprn
, int gprn
)
8040 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_TAR
, sprn
, FSCR_IC_TAR
);
8041 spr_write_generic(ctx
, sprn
, gprn
);
8044 static void gen_spr_power8_tce_address_control(CPUPPCState
*env
)
8046 spr_register_kvm(env
, SPR_TAR
, "TAR",
8047 &spr_read_tar
, &spr_write_tar
,
8048 &spr_read_generic
, &spr_write_generic
,
8049 KVM_REG_PPC_TAR
, 0x00000000);
8052 static void spr_read_tm(DisasContext
*ctx
, int gprn
, int sprn
)
8054 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8055 spr_read_generic(ctx
, gprn
, sprn
);
8058 static void spr_write_tm(DisasContext
*ctx
, int sprn
, int gprn
)
8060 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8061 spr_write_generic(ctx
, sprn
, gprn
);
8064 static void spr_read_tm_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
8066 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8067 spr_read_prev_upper32(ctx
, gprn
, sprn
);
8070 static void spr_write_tm_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
8072 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8073 spr_write_prev_upper32(ctx
, sprn
, gprn
);
8076 static void gen_spr_power8_tm(CPUPPCState
*env
)
8078 spr_register_kvm(env
, SPR_TFHAR
, "TFHAR",
8079 &spr_read_tm
, &spr_write_tm
,
8080 &spr_read_tm
, &spr_write_tm
,
8081 KVM_REG_PPC_TFHAR
, 0x00000000);
8082 spr_register_kvm(env
, SPR_TFIAR
, "TFIAR",
8083 &spr_read_tm
, &spr_write_tm
,
8084 &spr_read_tm
, &spr_write_tm
,
8085 KVM_REG_PPC_TFIAR
, 0x00000000);
8086 spr_register_kvm(env
, SPR_TEXASR
, "TEXASR",
8087 &spr_read_tm
, &spr_write_tm
,
8088 &spr_read_tm
, &spr_write_tm
,
8089 KVM_REG_PPC_TEXASR
, 0x00000000);
8090 spr_register(env
, SPR_TEXASRU
, "TEXASRU",
8091 &spr_read_tm_upper32
, &spr_write_tm_upper32
,
8092 &spr_read_tm_upper32
, &spr_write_tm_upper32
,
8096 static void spr_read_ebb(DisasContext
*ctx
, int gprn
, int sprn
)
8098 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8099 spr_read_generic(ctx
, gprn
, sprn
);
8102 static void spr_write_ebb(DisasContext
*ctx
, int sprn
, int gprn
)
8104 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8105 spr_write_generic(ctx
, sprn
, gprn
);
8108 static void spr_read_ebb_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
8110 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8111 spr_read_prev_upper32(ctx
, gprn
, sprn
);
8114 static void spr_write_ebb_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
8116 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8117 spr_write_prev_upper32(ctx
, sprn
, gprn
);
8120 static void gen_spr_power8_ebb(CPUPPCState
*env
)
8122 spr_register(env
, SPR_BESCRS
, "BESCRS",
8123 &spr_read_ebb
, &spr_write_ebb
,
8124 &spr_read_generic
, &spr_write_generic
,
8126 spr_register(env
, SPR_BESCRSU
, "BESCRSU",
8127 &spr_read_ebb_upper32
, &spr_write_ebb_upper32
,
8128 &spr_read_prev_upper32
, &spr_write_prev_upper32
,
8130 spr_register(env
, SPR_BESCRR
, "BESCRR",
8131 &spr_read_ebb
, &spr_write_ebb
,
8132 &spr_read_generic
, &spr_write_generic
,
8134 spr_register(env
, SPR_BESCRRU
, "BESCRRU",
8135 &spr_read_ebb_upper32
, &spr_write_ebb_upper32
,
8136 &spr_read_prev_upper32
, &spr_write_prev_upper32
,
8138 spr_register_kvm(env
, SPR_EBBHR
, "EBBHR",
8139 &spr_read_ebb
, &spr_write_ebb
,
8140 &spr_read_generic
, &spr_write_generic
,
8141 KVM_REG_PPC_EBBHR
, 0x00000000);
8142 spr_register_kvm(env
, SPR_EBBRR
, "EBBRR",
8143 &spr_read_ebb
, &spr_write_ebb
,
8144 &spr_read_generic
, &spr_write_generic
,
8145 KVM_REG_PPC_EBBRR
, 0x00000000);
8146 spr_register_kvm(env
, SPR_BESCR
, "BESCR",
8147 &spr_read_ebb
, &spr_write_ebb
,
8148 &spr_read_generic
, &spr_write_generic
,
8149 KVM_REG_PPC_BESCR
, 0x00000000);
8152 /* Virtual Time Base */
8153 static void gen_spr_vtb(CPUPPCState
*env
)
8155 spr_register(env
, SPR_VTB
, "VTB",
8156 SPR_NOACCESS
, SPR_NOACCESS
,
8157 &spr_read_tbl
, SPR_NOACCESS
,
8161 static void gen_spr_power8_fscr(CPUPPCState
*env
)
8163 #if defined(CONFIG_USER_ONLY)
8164 target_ulong initval
= 1ULL << FSCR_TAR
;
8166 target_ulong initval
= 0;
8168 spr_register_kvm(env
, SPR_FSCR
, "FSCR",
8169 SPR_NOACCESS
, SPR_NOACCESS
,
8170 &spr_read_generic
, &spr_write_generic
,
8171 KVM_REG_PPC_FSCR
, initval
);
8174 static void gen_spr_power8_pspb(CPUPPCState
*env
)
8176 spr_register_kvm(env
, SPR_PSPB
, "PSPB",
8177 SPR_NOACCESS
, SPR_NOACCESS
,
8178 &spr_read_generic
, &spr_write_generic32
,
8179 KVM_REG_PPC_PSPB
, 0);
8182 static void gen_spr_power8_ic(CPUPPCState
*env
)
8184 #if !defined(CONFIG_USER_ONLY)
8185 spr_register_hv(env
, SPR_IC
, "IC",
8186 SPR_NOACCESS
, SPR_NOACCESS
,
8187 &spr_read_generic
, SPR_NOACCESS
,
8188 &spr_read_generic
, &spr_write_generic
,
8193 static void gen_spr_power8_book4(CPUPPCState
*env
)
8195 /* Add a number of P8 book4 registers */
8196 #if !defined(CONFIG_USER_ONLY)
8197 spr_register_kvm(env
, SPR_ACOP
, "ACOP",
8198 SPR_NOACCESS
, SPR_NOACCESS
,
8199 &spr_read_generic
, &spr_write_generic
,
8200 KVM_REG_PPC_ACOP
, 0);
8201 spr_register_kvm(env
, SPR_BOOKS_PID
, "PID",
8202 SPR_NOACCESS
, SPR_NOACCESS
,
8203 &spr_read_generic
, &spr_write_generic
,
8204 KVM_REG_PPC_PID
, 0);
8205 spr_register_kvm(env
, SPR_WORT
, "WORT",
8206 SPR_NOACCESS
, SPR_NOACCESS
,
8207 &spr_read_generic
, &spr_write_generic
,
8208 KVM_REG_PPC_WORT
, 0);
8212 static void gen_spr_power7_book4(CPUPPCState
*env
)
8214 /* Add a number of P7 book4 registers */
8215 #if !defined(CONFIG_USER_ONLY)
8216 spr_register_kvm(env
, SPR_ACOP
, "ACOP",
8217 SPR_NOACCESS
, SPR_NOACCESS
,
8218 &spr_read_generic
, &spr_write_generic
,
8219 KVM_REG_PPC_ACOP
, 0);
8220 spr_register_kvm(env
, SPR_BOOKS_PID
, "PID",
8221 SPR_NOACCESS
, SPR_NOACCESS
,
8222 &spr_read_generic
, &spr_write_generic
,
8223 KVM_REG_PPC_PID
, 0);
8227 static void gen_spr_power8_rpr(CPUPPCState
*env
)
8229 #if !defined(CONFIG_USER_ONLY)
8230 spr_register_hv(env
, SPR_RPR
, "RPR",
8231 SPR_NOACCESS
, SPR_NOACCESS
,
8232 SPR_NOACCESS
, SPR_NOACCESS
,
8233 &spr_read_generic
, &spr_write_generic
,
8234 0x00000103070F1F3F);
8238 static void init_proc_book3s_common(CPUPPCState
*env
)
8240 gen_spr_ne_601(env
);
8242 gen_spr_book3s_altivec(env
);
8243 gen_spr_book3s_pmu_sup(env
);
8244 gen_spr_book3s_pmu_user(env
);
8245 gen_spr_book3s_ctrl(env
);
8248 static void init_proc_970(CPUPPCState
*env
)
8250 /* Common Registers */
8251 init_proc_book3s_common(env
);
8253 gen_spr_book3s_dbg(env
);
8255 /* 970 Specific Registers */
8256 gen_spr_970_hid(env
);
8257 gen_spr_970_hior(env
);
8259 gen_spr_970_pmu_sup(env
);
8260 gen_spr_970_pmu_user(env
);
8261 gen_spr_970_lpar(env
);
8262 gen_spr_970_dbg(env
);
8265 #if !defined(CONFIG_USER_ONLY)
8268 env
->dcache_line_size
= 128;
8269 env
->icache_line_size
= 128;
8271 /* Allocate hardware IRQ controller */
8273 ppc970_irq_init(ppc_env_get_cpu(env
));
8276 POWERPC_FAMILY(970)(ObjectClass
*oc
, void *data
)
8278 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8279 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8281 dc
->desc
= "PowerPC 970";
8282 pcc
->init_proc
= init_proc_970
;
8283 pcc
->check_pow
= check_pow_970
;
8284 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
8285 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8286 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8288 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8289 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8290 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8291 PPC_64B
| PPC_ALTIVEC
|
8292 PPC_SEGMENT_64B
| PPC_SLBI
;
8293 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
8294 pcc
->msr_mask
= (1ull << MSR_SF
) |
8309 pcc
->mmu_model
= POWERPC_MMU_64B
;
8310 #if defined(CONFIG_SOFTMMU)
8311 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8313 pcc
->excp_model
= POWERPC_EXCP_970
;
8314 pcc
->bus_model
= PPC_FLAGS_INPUT_970
;
8315 pcc
->bfd_mach
= bfd_mach_ppc64
;
8316 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8317 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8318 POWERPC_FLAG_BUS_CLK
;
8319 pcc
->l1_dcache_size
= 0x8000;
8320 pcc
->l1_icache_size
= 0x10000;
8323 static void init_proc_power5plus(CPUPPCState
*env
)
8325 /* Common Registers */
8326 init_proc_book3s_common(env
);
8328 gen_spr_book3s_dbg(env
);
8330 /* POWER5+ Specific Registers */
8331 gen_spr_970_hid(env
);
8332 gen_spr_970_hior(env
);
8334 gen_spr_970_pmu_sup(env
);
8335 gen_spr_970_pmu_user(env
);
8336 gen_spr_power5p_common(env
);
8337 gen_spr_power5p_lpar(env
);
8338 gen_spr_power5p_ear(env
);
8341 #if !defined(CONFIG_USER_ONLY)
8344 env
->dcache_line_size
= 128;
8345 env
->icache_line_size
= 128;
8347 /* Allocate hardware IRQ controller */
8349 ppc970_irq_init(ppc_env_get_cpu(env
));
8352 POWERPC_FAMILY(POWER5P
)(ObjectClass
*oc
, void *data
)
8354 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8355 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8357 dc
->fw_name
= "PowerPC,POWER5";
8358 dc
->desc
= "POWER5+";
8359 pcc
->init_proc
= init_proc_power5plus
;
8360 pcc
->check_pow
= check_pow_970
;
8361 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
8362 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8363 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8365 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8366 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8367 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8369 PPC_SEGMENT_64B
| PPC_SLBI
;
8370 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
8371 pcc
->msr_mask
= (1ull << MSR_SF
) |
8386 pcc
->mmu_model
= POWERPC_MMU_2_03
;
8387 #if defined(CONFIG_SOFTMMU)
8388 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8390 pcc
->excp_model
= POWERPC_EXCP_970
;
8391 pcc
->bus_model
= PPC_FLAGS_INPUT_970
;
8392 pcc
->bfd_mach
= bfd_mach_ppc64
;
8393 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8394 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8395 POWERPC_FLAG_BUS_CLK
;
8396 pcc
->l1_dcache_size
= 0x8000;
8397 pcc
->l1_icache_size
= 0x10000;
8400 static void powerpc_get_compat(Object
*obj
, Visitor
*v
, const char *name
,
8401 void *opaque
, Error
**errp
)
8403 char *value
= (char *)"";
8404 Property
*prop
= opaque
;
8405 uint32_t *max_compat
= qdev_get_prop_ptr(DEVICE(obj
), prop
);
8407 switch (*max_compat
) {
8408 case CPU_POWERPC_LOGICAL_2_05
:
8409 value
= (char *)"power6";
8411 case CPU_POWERPC_LOGICAL_2_06
:
8412 value
= (char *)"power7";
8414 case CPU_POWERPC_LOGICAL_2_07
:
8415 value
= (char *)"power8";
8420 error_report("Internal error: compat is set to %x", *max_compat
);
8425 visit_type_str(v
, name
, &value
, errp
);
8428 static void powerpc_set_compat(Object
*obj
, Visitor
*v
, const char *name
,
8429 void *opaque
, Error
**errp
)
8431 Error
*error
= NULL
;
8433 Property
*prop
= opaque
;
8434 uint32_t *max_compat
= qdev_get_prop_ptr(DEVICE(obj
), prop
);
8436 visit_type_str(v
, name
, &value
, &error
);
8438 error_propagate(errp
, error
);
8442 if (strcmp(value
, "power6") == 0) {
8443 *max_compat
= CPU_POWERPC_LOGICAL_2_05
;
8444 } else if (strcmp(value
, "power7") == 0) {
8445 *max_compat
= CPU_POWERPC_LOGICAL_2_06
;
8446 } else if (strcmp(value
, "power8") == 0) {
8447 *max_compat
= CPU_POWERPC_LOGICAL_2_07
;
8449 error_setg(errp
, "Invalid compatibility mode \"%s\"", value
);
8455 static PropertyInfo powerpc_compat_propinfo
= {
8457 .description
= "compatibility mode, power6/power7/power8",
8458 .get
= powerpc_get_compat
,
8459 .set
= powerpc_set_compat
,
8462 #define DEFINE_PROP_POWERPC_COMPAT(_n, _s, _f) \
8463 DEFINE_PROP(_n, _s, _f, powerpc_compat_propinfo, uint32_t)
8465 static Property powerpc_servercpu_properties
[] = {
8466 DEFINE_PROP_POWERPC_COMPAT("compat", PowerPCCPU
, max_compat
),
8467 DEFINE_PROP_END_OF_LIST(),
8470 #ifdef CONFIG_SOFTMMU
8471 static const struct ppc_segment_page_sizes POWER7_POWER8_sps
= {
8474 .page_shift
= 12, /* 4K */
8476 .enc
= { { .page_shift
= 12, .pte_enc
= 0 },
8477 { .page_shift
= 16, .pte_enc
= 0x7 },
8478 { .page_shift
= 24, .pte_enc
= 0x38 }, },
8481 .page_shift
= 16, /* 64K */
8482 .slb_enc
= SLB_VSID_64K
,
8483 .enc
= { { .page_shift
= 16, .pte_enc
= 0x1 },
8484 { .page_shift
= 24, .pte_enc
= 0x8 }, },
8487 .page_shift
= 24, /* 16M */
8488 .slb_enc
= SLB_VSID_16M
,
8489 .enc
= { { .page_shift
= 24, .pte_enc
= 0 }, },
8492 .page_shift
= 34, /* 16G */
8493 .slb_enc
= SLB_VSID_16G
,
8494 .enc
= { { .page_shift
= 34, .pte_enc
= 0x3 }, },
8498 #endif /* CONFIG_SOFTMMU */
8500 static void init_proc_POWER7 (CPUPPCState
*env
)
8502 /* Common Registers */
8503 init_proc_book3s_common(env
);
8505 gen_spr_book3s_dbg(env
);
8507 /* POWER7 Specific Registers */
8508 gen_spr_book3s_ids(env
);
8510 gen_spr_book3s_purr(env
);
8511 gen_spr_power5p_common(env
);
8512 gen_spr_power5p_lpar(env
);
8513 gen_spr_power5p_ear(env
);
8514 gen_spr_power6_common(env
);
8515 gen_spr_power6_dbg(env
);
8516 gen_spr_power7_book4(env
);
8519 #if !defined(CONFIG_USER_ONLY)
8522 env
->ci_large_pages
= true;
8523 env
->dcache_line_size
= 128;
8524 env
->icache_line_size
= 128;
8526 /* Allocate hardware IRQ controller */
8527 init_excp_POWER7(env
);
8528 ppcPOWER7_irq_init(ppc_env_get_cpu(env
));
8531 static bool ppc_pvr_match_power7(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8533 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER7P_BASE
) {
8536 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER7_BASE
) {
8542 static bool cpu_has_work_POWER7(CPUState
*cs
)
8544 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8545 CPUPPCState
*env
= &cpu
->env
;
8548 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8551 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8552 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE0
)) {
8555 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8556 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE1
)) {
8559 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
)) &&
8560 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE2
)) {
8563 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HMI
)) &&
8564 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE2
)) {
8567 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8572 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8576 POWERPC_FAMILY(POWER7
)(ObjectClass
*oc
, void *data
)
8578 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8579 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8580 CPUClass
*cc
= CPU_CLASS(oc
);
8582 dc
->fw_name
= "PowerPC,POWER7";
8583 dc
->desc
= "POWER7";
8584 dc
->props
= powerpc_servercpu_properties
;
8585 pcc
->pvr_match
= ppc_pvr_match_power7
;
8586 pcc
->pcr_mask
= PCR_VEC_DIS
| PCR_VSX_DIS
| PCR_COMPAT_2_05
;
8587 pcc
->pcr_supported
= PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8588 pcc
->init_proc
= init_proc_POWER7
;
8589 pcc
->check_pow
= check_pow_nocheck
;
8590 cc
->has_work
= cpu_has_work_POWER7
;
8591 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8592 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8593 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8594 PPC_FLOAT_FRSQRTES
|
8597 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8598 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8599 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8600 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
8601 PPC_SEGMENT_64B
| PPC_SLBI
|
8602 PPC_POPCNTB
| PPC_POPCNTWD
|
8604 pcc
->insns_flags2
= PPC2_VSX
| PPC2_DFP
| PPC2_DBRX
| PPC2_ISA205
|
8605 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8606 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8607 PPC2_FP_TST_ISA206
| PPC2_FP_CVT_S64
|
8609 pcc
->msr_mask
= (1ull << MSR_SF
) |
8625 pcc
->mmu_model
= POWERPC_MMU_2_06
;
8626 #if defined(CONFIG_SOFTMMU)
8627 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8628 pcc
->sps
= &POWER7_POWER8_sps
;
8630 pcc
->excp_model
= POWERPC_EXCP_POWER7
;
8631 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8632 pcc
->bfd_mach
= bfd_mach_ppc64
;
8633 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8634 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8635 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8637 pcc
->l1_dcache_size
= 0x8000;
8638 pcc
->l1_icache_size
= 0x8000;
8639 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8642 static void init_proc_POWER8(CPUPPCState
*env
)
8644 /* Common Registers */
8645 init_proc_book3s_common(env
);
8647 gen_spr_book3s_207_dbg(env
);
8649 /* POWER8 Specific Registers */
8650 gen_spr_book3s_ids(env
);
8653 gen_spr_book3s_purr(env
);
8654 gen_spr_power5p_common(env
);
8655 gen_spr_power5p_lpar(env
);
8656 gen_spr_power5p_ear(env
);
8657 gen_spr_power6_common(env
);
8658 gen_spr_power6_dbg(env
);
8659 gen_spr_power8_tce_address_control(env
);
8660 gen_spr_power8_ids(env
);
8661 gen_spr_power8_ebb(env
);
8662 gen_spr_power8_fscr(env
);
8663 gen_spr_power8_pmu_sup(env
);
8664 gen_spr_power8_pmu_user(env
);
8665 gen_spr_power8_tm(env
);
8666 gen_spr_power8_pspb(env
);
8668 gen_spr_power8_ic(env
);
8669 gen_spr_power8_book4(env
);
8670 gen_spr_power8_rpr(env
);
8673 #if !defined(CONFIG_USER_ONLY)
8676 env
->ci_large_pages
= true;
8677 env
->dcache_line_size
= 128;
8678 env
->icache_line_size
= 128;
8680 /* Allocate hardware IRQ controller */
8681 init_excp_POWER8(env
);
8682 ppcPOWER7_irq_init(ppc_env_get_cpu(env
));
8685 static bool ppc_pvr_match_power8(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8687 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8NVL_BASE
) {
8690 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8E_BASE
) {
8693 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8_BASE
) {
8699 static bool cpu_has_work_POWER8(CPUState
*cs
)
8701 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8702 CPUPPCState
*env
= &cpu
->env
;
8705 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8708 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8709 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE2
)) {
8712 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8713 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE3
)) {
8716 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
)) &&
8717 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE4
)) {
8720 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HMI
)) &&
8721 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE4
)) {
8724 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DOORBELL
)) &&
8725 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE0
)) {
8728 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HDOORBELL
)) &&
8729 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE1
)) {
8732 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8737 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8741 POWERPC_FAMILY(POWER8
)(ObjectClass
*oc
, void *data
)
8743 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8744 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8745 CPUClass
*cc
= CPU_CLASS(oc
);
8747 dc
->fw_name
= "PowerPC,POWER8";
8748 dc
->desc
= "POWER8";
8749 dc
->props
= powerpc_servercpu_properties
;
8750 pcc
->pvr_match
= ppc_pvr_match_power8
;
8751 pcc
->pcr_mask
= PCR_TM_DIS
| PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8752 pcc
->pcr_supported
= PCR_COMPAT_2_07
| PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8753 pcc
->init_proc
= init_proc_POWER8
;
8754 pcc
->check_pow
= check_pow_nocheck
;
8755 cc
->has_work
= cpu_has_work_POWER8
;
8756 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8757 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8758 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8759 PPC_FLOAT_FRSQRTES
|
8762 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8763 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8764 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8765 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
8766 PPC_SEGMENT_64B
| PPC_SLBI
|
8767 PPC_POPCNTB
| PPC_POPCNTWD
|
8769 pcc
->insns_flags2
= PPC2_VSX
| PPC2_VSX207
| PPC2_DFP
| PPC2_DBRX
|
8770 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8771 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8772 PPC2_FP_TST_ISA206
| PPC2_BCTAR_ISA207
|
8773 PPC2_LSQ_ISA207
| PPC2_ALTIVEC_207
|
8774 PPC2_ISA205
| PPC2_ISA207S
| PPC2_FP_CVT_S64
|
8775 PPC2_TM
| PPC2_PM_ISA206
;
8776 pcc
->msr_mask
= (1ull << MSR_SF
) |
8794 pcc
->mmu_model
= POWERPC_MMU_2_07
;
8795 #if defined(CONFIG_SOFTMMU)
8796 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8797 pcc
->sps
= &POWER7_POWER8_sps
;
8799 pcc
->excp_model
= POWERPC_EXCP_POWER8
;
8800 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8801 pcc
->bfd_mach
= bfd_mach_ppc64
;
8802 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8803 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8804 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8805 POWERPC_FLAG_VSX
| POWERPC_FLAG_TM
;
8806 pcc
->l1_dcache_size
= 0x8000;
8807 pcc
->l1_icache_size
= 0x8000;
8808 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8811 static void init_proc_POWER9(CPUPPCState
*env
)
8813 /* Common Registers */
8814 init_proc_book3s_common(env
);
8815 gen_spr_book3s_207_dbg(env
);
8817 /* POWER8 Specific Registers */
8818 gen_spr_book3s_ids(env
);
8821 gen_spr_book3s_purr(env
);
8822 gen_spr_power5p_common(env
);
8823 gen_spr_power5p_lpar(env
);
8824 gen_spr_power5p_ear(env
);
8825 gen_spr_power6_common(env
);
8826 gen_spr_power6_dbg(env
);
8827 gen_spr_power8_tce_address_control(env
);
8828 gen_spr_power8_ids(env
);
8829 gen_spr_power8_ebb(env
);
8830 gen_spr_power8_fscr(env
);
8831 gen_spr_power8_pmu_sup(env
);
8832 gen_spr_power8_pmu_user(env
);
8833 gen_spr_power8_tm(env
);
8834 gen_spr_power8_pspb(env
);
8836 gen_spr_power8_ic(env
);
8837 gen_spr_power8_book4(env
);
8838 gen_spr_power8_rpr(env
);
8841 #if !defined(CONFIG_USER_ONLY)
8844 env
->ci_large_pages
= true;
8845 env
->dcache_line_size
= 128;
8846 env
->icache_line_size
= 128;
8848 /* Allocate hardware IRQ controller */
8849 init_excp_POWER8(env
);
8850 ppcPOWER7_irq_init(ppc_env_get_cpu(env
));
8853 static bool ppc_pvr_match_power9(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8855 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER9_BASE
) {
8861 static bool cpu_has_work_POWER9(CPUState
*cs
)
8863 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8864 CPUPPCState
*env
= &cpu
->env
;
8867 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8870 /* External Exception */
8871 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8872 (env
->spr
[SPR_LPCR
] & LPCR_EEE
)) {
8875 /* Decrementer Exception */
8876 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8877 (env
->spr
[SPR_LPCR
] & LPCR_DEE
)) {
8880 /* Machine Check or Hypervisor Maintenance Exception */
8881 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
|
8882 1u << PPC_INTERRUPT_HMI
)) && (env
->spr
[SPR_LPCR
] & LPCR_OEE
)) {
8885 /* Privileged Doorbell Exception */
8886 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DOORBELL
)) &&
8887 (env
->spr
[SPR_LPCR
] & LPCR_PDEE
)) {
8890 /* Hypervisor Doorbell Exception */
8891 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HDOORBELL
)) &&
8892 (env
->spr
[SPR_LPCR
] & LPCR_HDEE
)) {
8895 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8900 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8904 POWERPC_FAMILY(POWER9
)(ObjectClass
*oc
, void *data
)
8906 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8907 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8908 CPUClass
*cc
= CPU_CLASS(oc
);
8910 dc
->fw_name
= "PowerPC,POWER9";
8911 dc
->desc
= "POWER9";
8912 dc
->props
= powerpc_servercpu_properties
;
8913 pcc
->pvr_match
= ppc_pvr_match_power9
;
8914 pcc
->pcr_mask
= PCR_COMPAT_2_05
| PCR_COMPAT_2_06
| PCR_COMPAT_2_07
;
8915 pcc
->pcr_supported
= PCR_COMPAT_3_00
| PCR_COMPAT_2_07
| PCR_COMPAT_2_06
|
8917 pcc
->init_proc
= init_proc_POWER9
;
8918 pcc
->check_pow
= check_pow_nocheck
;
8919 cc
->has_work
= cpu_has_work_POWER9
;
8920 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8921 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8922 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8923 PPC_FLOAT_FRSQRTES
|
8926 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8927 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8928 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8929 PPC_64B
| PPC_64BX
| PPC_ALTIVEC
|
8930 PPC_SEGMENT_64B
| PPC_SLBI
|
8931 PPC_POPCNTB
| PPC_POPCNTWD
|
8933 pcc
->insns_flags2
= PPC2_VSX
| PPC2_VSX207
| PPC2_DFP
| PPC2_DBRX
|
8934 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8935 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8936 PPC2_FP_TST_ISA206
| PPC2_BCTAR_ISA207
|
8937 PPC2_LSQ_ISA207
| PPC2_ALTIVEC_207
|
8938 PPC2_ISA205
| PPC2_ISA207S
| PPC2_FP_CVT_S64
|
8939 PPC2_TM
| PPC2_PM_ISA206
| PPC2_ISA300
;
8940 pcc
->msr_mask
= (1ull << MSR_SF
) |
8957 pcc
->mmu_model
= POWERPC_MMU_3_00
;
8958 #if defined(CONFIG_SOFTMMU)
8959 pcc
->handle_mmu_fault
= ppc64_v3_handle_mmu_fault
;
8960 /* segment page size remain the same */
8961 pcc
->sps
= &POWER7_POWER8_sps
;
8963 pcc
->excp_model
= POWERPC_EXCP_POWER8
;
8964 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8965 pcc
->bfd_mach
= bfd_mach_ppc64
;
8966 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8967 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8968 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8969 POWERPC_FLAG_VSX
| POWERPC_FLAG_TM
;
8970 pcc
->l1_dcache_size
= 0x8000;
8971 pcc
->l1_icache_size
= 0x8000;
8972 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8975 #if !defined(CONFIG_USER_ONLY)
8976 void cpu_ppc_set_papr(PowerPCCPU
*cpu
, PPCVirtualHypervisor
*vhyp
)
8978 CPUPPCState
*env
= &cpu
->env
;
8979 ppc_spr_t
*lpcr
= &env
->spr_cb
[SPR_LPCR
];
8980 ppc_spr_t
*amor
= &env
->spr_cb
[SPR_AMOR
];
8984 /* PAPR always has exception vectors in RAM not ROM. To ensure this,
8985 * MSR[IP] should never be set.
8987 * We also disallow setting of MSR_HV
8989 env
->msr_mask
&= ~((1ull << MSR_EP
) | MSR_HVB
);
8991 /* Set emulated LPCR to not send interrupts to hypervisor. Note that
8992 * under KVM, the actual HW LPCR will be set differently by KVM itself,
8993 * the settings below ensure proper operations with TCG in absence of
8994 * a real hypervisor.
8996 * Clearing VPM0 will also cause us to use RMOR in mmu-hash64.c for
8997 * real mode accesses, which thankfully defaults to 0 and isn't
8998 * accessible in guest mode.
9000 lpcr
->default_value
&= ~(LPCR_VPM0
| LPCR_VPM1
| LPCR_ISL
| LPCR_KBV
);
9001 lpcr
->default_value
|= LPCR_LPES0
| LPCR_LPES1
;
9003 /* Set RMLS to the max (ie, 16G) */
9004 lpcr
->default_value
&= ~LPCR_RMLS
;
9005 lpcr
->default_value
|= 1ull << LPCR_RMLS_SHIFT
;
9007 switch (env
->mmu_model
) {
9008 case POWERPC_MMU_3_00
:
9009 /* By default we choose legacy mode and switch to new hash or radix
9010 * when a register process table hcall is made. So disable process
9011 * tables and guest translation shootdown by default
9013 lpcr
->default_value
&= ~(LPCR_UPRT
| LPCR_GTSE
);
9014 lpcr
->default_value
|= LPCR_PDEE
| LPCR_HDEE
| LPCR_EEE
| LPCR_DEE
|
9018 /* P7 and P8 has slightly different PECE bits, mostly because P8 adds
9019 * bit 47 and 48 which are reserved on P7. Here we set them all, which
9020 * will work as expected for both implementations
9022 lpcr
->default_value
|= LPCR_P8_PECE0
| LPCR_P8_PECE1
| LPCR_P8_PECE2
|
9023 LPCR_P8_PECE3
| LPCR_P8_PECE4
;
9026 /* We should be followed by a CPU reset but update the active value
9029 env
->spr
[SPR_LPCR
] = lpcr
->default_value
;
9031 /* Set a full AMOR so guest can use the AMR as it sees fit */
9032 env
->spr
[SPR_AMOR
] = amor
->default_value
= 0xffffffffffffffffull
;
9034 /* Update some env bits based on new LPCR value */
9035 ppc_hash64_update_rmls(env
);
9036 ppc_hash64_update_vrma(env
);
9038 /* Tell KVM that we're in PAPR mode */
9039 if (kvm_enabled()) {
9040 kvmppc_set_papr(cpu
);
9044 #endif /* !defined(CONFIG_USER_ONLY) */
9046 #endif /* defined (TARGET_PPC64) */
9048 /*****************************************************************************/
9049 /* Generic CPU instantiation routine */
9050 static void init_ppc_proc(PowerPCCPU
*cpu
)
9052 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9053 CPUPPCState
*env
= &cpu
->env
;
9054 #if !defined(CONFIG_USER_ONLY)
9057 env
->irq_inputs
= NULL
;
9058 /* Set all exception vectors to an invalid address */
9059 for (i
= 0; i
< POWERPC_EXCP_NB
; i
++)
9060 env
->excp_vectors
[i
] = (target_ulong
)(-1ULL);
9061 env
->ivor_mask
= 0x00000000;
9062 env
->ivpr_mask
= 0x00000000;
9063 /* Default MMU definitions */
9067 env
->tlb_type
= TLB_NONE
;
9069 /* Register SPR common to all PowerPC implementations */
9070 gen_spr_generic(env
);
9071 spr_register(env
, SPR_PVR
, "PVR",
9072 /* Linux permits userspace to read PVR */
9073 #if defined(CONFIG_LINUX_USER)
9079 &spr_read_generic
, SPR_NOACCESS
,
9081 /* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
9082 if (pcc
->svr
!= POWERPC_SVR_NONE
) {
9083 if (pcc
->svr
& POWERPC_SVR_E500
) {
9084 spr_register(env
, SPR_E500_SVR
, "SVR",
9085 SPR_NOACCESS
, SPR_NOACCESS
,
9086 &spr_read_generic
, SPR_NOACCESS
,
9087 pcc
->svr
& ~POWERPC_SVR_E500
);
9089 spr_register(env
, SPR_SVR
, "SVR",
9090 SPR_NOACCESS
, SPR_NOACCESS
,
9091 &spr_read_generic
, SPR_NOACCESS
,
9095 /* PowerPC implementation specific initialisations (SPRs, timers, ...) */
9096 (*pcc
->init_proc
)(env
);
9098 /* MSR bits & flags consistency checks */
9099 if (env
->msr_mask
& (1 << 25)) {
9100 switch (env
->flags
& (POWERPC_FLAG_SPE
| POWERPC_FLAG_VRE
)) {
9101 case POWERPC_FLAG_SPE
:
9102 case POWERPC_FLAG_VRE
:
9105 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9106 "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n");
9109 } else if (env
->flags
& (POWERPC_FLAG_SPE
| POWERPC_FLAG_VRE
)) {
9110 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9111 "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n");
9114 if (env
->msr_mask
& (1 << 17)) {
9115 switch (env
->flags
& (POWERPC_FLAG_TGPR
| POWERPC_FLAG_CE
)) {
9116 case POWERPC_FLAG_TGPR
:
9117 case POWERPC_FLAG_CE
:
9120 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9121 "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n");
9124 } else if (env
->flags
& (POWERPC_FLAG_TGPR
| POWERPC_FLAG_CE
)) {
9125 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9126 "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n");
9129 if (env
->msr_mask
& (1 << 10)) {
9130 switch (env
->flags
& (POWERPC_FLAG_SE
| POWERPC_FLAG_DWE
|
9131 POWERPC_FLAG_UBLE
)) {
9132 case POWERPC_FLAG_SE
:
9133 case POWERPC_FLAG_DWE
:
9134 case POWERPC_FLAG_UBLE
:
9137 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9138 "Should define POWERPC_FLAG_SE or POWERPC_FLAG_DWE or "
9139 "POWERPC_FLAG_UBLE\n");
9142 } else if (env
->flags
& (POWERPC_FLAG_SE
| POWERPC_FLAG_DWE
|
9143 POWERPC_FLAG_UBLE
)) {
9144 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9145 "Should not define POWERPC_FLAG_SE nor POWERPC_FLAG_DWE nor "
9146 "POWERPC_FLAG_UBLE\n");
9149 if (env
->msr_mask
& (1 << 9)) {
9150 switch (env
->flags
& (POWERPC_FLAG_BE
| POWERPC_FLAG_DE
)) {
9151 case POWERPC_FLAG_BE
:
9152 case POWERPC_FLAG_DE
:
9155 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9156 "Should define POWERPC_FLAG_BE or POWERPC_FLAG_DE\n");
9159 } else if (env
->flags
& (POWERPC_FLAG_BE
| POWERPC_FLAG_DE
)) {
9160 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9161 "Should not define POWERPC_FLAG_BE nor POWERPC_FLAG_DE\n");
9164 if (env
->msr_mask
& (1 << 2)) {
9165 switch (env
->flags
& (POWERPC_FLAG_PX
| POWERPC_FLAG_PMM
)) {
9166 case POWERPC_FLAG_PX
:
9167 case POWERPC_FLAG_PMM
:
9170 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9171 "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n");
9174 } else if (env
->flags
& (POWERPC_FLAG_PX
| POWERPC_FLAG_PMM
)) {
9175 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9176 "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n");
9179 if ((env
->flags
& (POWERPC_FLAG_RTC_CLK
| POWERPC_FLAG_BUS_CLK
)) == 0) {
9180 fprintf(stderr
, "PowerPC flags inconsistency\n"
9181 "Should define the time-base and decrementer clock source\n");
9184 /* Allocate TLBs buffer when needed */
9185 #if !defined(CONFIG_USER_ONLY)
9186 if (env
->nb_tlb
!= 0) {
9187 int nb_tlb
= env
->nb_tlb
;
9188 if (env
->id_tlbs
!= 0)
9190 switch (env
->tlb_type
) {
9192 env
->tlb
.tlb6
= g_malloc0(nb_tlb
* sizeof(ppc6xx_tlb_t
));
9195 env
->tlb
.tlbe
= g_malloc0(nb_tlb
* sizeof(ppcemb_tlb_t
));
9198 env
->tlb
.tlbm
= g_malloc0(nb_tlb
* sizeof(ppcmas_tlb_t
));
9201 /* Pre-compute some useful values */
9202 env
->tlb_per_way
= env
->nb_tlb
/ env
->nb_ways
;
9204 if (env
->irq_inputs
== NULL
) {
9205 fprintf(stderr
, "WARNING: no internal IRQ controller registered.\n"
9206 " Attempt QEMU to crash very soon !\n");
9209 if (env
->check_pow
== NULL
) {
9210 fprintf(stderr
, "WARNING: no power management check handler "
9212 " Attempt QEMU to crash very soon !\n");
9216 #if defined(PPC_DUMP_CPU)
9217 static void dump_ppc_sprs (CPUPPCState
*env
)
9220 #if !defined(CONFIG_USER_ONLY)
9226 printf("Special purpose registers:\n");
9227 for (i
= 0; i
< 32; i
++) {
9228 for (j
= 0; j
< 32; j
++) {
9230 spr
= &env
->spr_cb
[n
];
9231 uw
= spr
->uea_write
!= NULL
&& spr
->uea_write
!= SPR_NOACCESS
;
9232 ur
= spr
->uea_read
!= NULL
&& spr
->uea_read
!= SPR_NOACCESS
;
9233 #if !defined(CONFIG_USER_ONLY)
9234 sw
= spr
->oea_write
!= NULL
&& spr
->oea_write
!= SPR_NOACCESS
;
9235 sr
= spr
->oea_read
!= NULL
&& spr
->oea_read
!= SPR_NOACCESS
;
9236 if (sw
|| sr
|| uw
|| ur
) {
9237 printf("SPR: %4d (%03x) %-8s s%c%c u%c%c\n",
9238 (i
<< 5) | j
, (i
<< 5) | j
, spr
->name
,
9239 sw
? 'w' : '-', sr
? 'r' : '-',
9240 uw
? 'w' : '-', ur
? 'r' : '-');
9244 printf("SPR: %4d (%03x) %-8s u%c%c\n",
9245 (i
<< 5) | j
, (i
<< 5) | j
, spr
->name
,
9246 uw
? 'w' : '-', ur
? 'r' : '-');
9256 /*****************************************************************************/
9260 PPC_DIRECT
= 0, /* Opcode routine */
9261 PPC_INDIRECT
= 1, /* Indirect opcode table */
9264 #define PPC_OPCODE_MASK 0x3
9266 static inline int is_indirect_opcode (void *handler
)
9268 return ((uintptr_t)handler
& PPC_OPCODE_MASK
) == PPC_INDIRECT
;
9271 static inline opc_handler_t
**ind_table(void *handler
)
9273 return (opc_handler_t
**)((uintptr_t)handler
& ~PPC_OPCODE_MASK
);
9276 /* Instruction table creation */
9277 /* Opcodes tables creation */
9278 static void fill_new_table (opc_handler_t
**table
, int len
)
9282 for (i
= 0; i
< len
; i
++)
9283 table
[i
] = &invalid_handler
;
9286 static int create_new_table (opc_handler_t
**table
, unsigned char idx
)
9288 opc_handler_t
**tmp
;
9290 tmp
= g_new(opc_handler_t
*, PPC_CPU_INDIRECT_OPCODES_LEN
);
9291 fill_new_table(tmp
, PPC_CPU_INDIRECT_OPCODES_LEN
);
9292 table
[idx
] = (opc_handler_t
*)((uintptr_t)tmp
| PPC_INDIRECT
);
9297 static int insert_in_table (opc_handler_t
**table
, unsigned char idx
,
9298 opc_handler_t
*handler
)
9300 if (table
[idx
] != &invalid_handler
)
9302 table
[idx
] = handler
;
9307 static int register_direct_insn (opc_handler_t
**ppc_opcodes
,
9308 unsigned char idx
, opc_handler_t
*handler
)
9310 if (insert_in_table(ppc_opcodes
, idx
, handler
) < 0) {
9311 printf("*** ERROR: opcode %02x already assigned in main "
9312 "opcode table\n", idx
);
9313 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9314 printf(" Registered handler '%s' - new handler '%s'\n",
9315 ppc_opcodes
[idx
]->oname
, handler
->oname
);
9323 static int register_ind_in_table (opc_handler_t
**table
,
9324 unsigned char idx1
, unsigned char idx2
,
9325 opc_handler_t
*handler
)
9327 if (table
[idx1
] == &invalid_handler
) {
9328 if (create_new_table(table
, idx1
) < 0) {
9329 printf("*** ERROR: unable to create indirect table "
9330 "idx=%02x\n", idx1
);
9334 if (!is_indirect_opcode(table
[idx1
])) {
9335 printf("*** ERROR: idx %02x already assigned to a direct "
9337 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9338 printf(" Registered handler '%s' - new handler '%s'\n",
9339 ind_table(table
[idx1
])[idx2
]->oname
, handler
->oname
);
9344 if (handler
!= NULL
&&
9345 insert_in_table(ind_table(table
[idx1
]), idx2
, handler
) < 0) {
9346 printf("*** ERROR: opcode %02x already assigned in "
9347 "opcode table %02x\n", idx2
, idx1
);
9348 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9349 printf(" Registered handler '%s' - new handler '%s'\n",
9350 ind_table(table
[idx1
])[idx2
]->oname
, handler
->oname
);
9358 static int register_ind_insn (opc_handler_t
**ppc_opcodes
,
9359 unsigned char idx1
, unsigned char idx2
,
9360 opc_handler_t
*handler
)
9362 return register_ind_in_table(ppc_opcodes
, idx1
, idx2
, handler
);
9365 static int register_dblind_insn (opc_handler_t
**ppc_opcodes
,
9366 unsigned char idx1
, unsigned char idx2
,
9367 unsigned char idx3
, opc_handler_t
*handler
)
9369 if (register_ind_in_table(ppc_opcodes
, idx1
, idx2
, NULL
) < 0) {
9370 printf("*** ERROR: unable to join indirect table idx "
9371 "[%02x-%02x]\n", idx1
, idx2
);
9374 if (register_ind_in_table(ind_table(ppc_opcodes
[idx1
]), idx2
, idx3
,
9376 printf("*** ERROR: unable to insert opcode "
9377 "[%02x-%02x-%02x]\n", idx1
, idx2
, idx3
);
9384 static int register_trplind_insn(opc_handler_t
**ppc_opcodes
,
9385 unsigned char idx1
, unsigned char idx2
,
9386 unsigned char idx3
, unsigned char idx4
,
9387 opc_handler_t
*handler
)
9389 opc_handler_t
**table
;
9391 if (register_ind_in_table(ppc_opcodes
, idx1
, idx2
, NULL
) < 0) {
9392 printf("*** ERROR: unable to join indirect table idx "
9393 "[%02x-%02x]\n", idx1
, idx2
);
9396 table
= ind_table(ppc_opcodes
[idx1
]);
9397 if (register_ind_in_table(table
, idx2
, idx3
, NULL
) < 0) {
9398 printf("*** ERROR: unable to join 2nd-level indirect table idx "
9399 "[%02x-%02x-%02x]\n", idx1
, idx2
, idx3
);
9402 table
= ind_table(table
[idx2
]);
9403 if (register_ind_in_table(table
, idx3
, idx4
, handler
) < 0) {
9404 printf("*** ERROR: unable to insert opcode "
9405 "[%02x-%02x-%02x-%02x]\n", idx1
, idx2
, idx3
, idx4
);
9410 static int register_insn (opc_handler_t
**ppc_opcodes
, opcode_t
*insn
)
9412 if (insn
->opc2
!= 0xFF) {
9413 if (insn
->opc3
!= 0xFF) {
9414 if (insn
->opc4
!= 0xFF) {
9415 if (register_trplind_insn(ppc_opcodes
, insn
->opc1
, insn
->opc2
,
9416 insn
->opc3
, insn
->opc4
,
9417 &insn
->handler
) < 0) {
9421 if (register_dblind_insn(ppc_opcodes
, insn
->opc1
, insn
->opc2
,
9422 insn
->opc3
, &insn
->handler
) < 0)
9426 if (register_ind_insn(ppc_opcodes
, insn
->opc1
,
9427 insn
->opc2
, &insn
->handler
) < 0)
9431 if (register_direct_insn(ppc_opcodes
, insn
->opc1
, &insn
->handler
) < 0)
9438 static int test_opcode_table (opc_handler_t
**table
, int len
)
9442 for (i
= 0, count
= 0; i
< len
; i
++) {
9443 /* Consistency fixup */
9444 if (table
[i
] == NULL
)
9445 table
[i
] = &invalid_handler
;
9446 if (table
[i
] != &invalid_handler
) {
9447 if (is_indirect_opcode(table
[i
])) {
9448 tmp
= test_opcode_table(ind_table(table
[i
]),
9449 PPC_CPU_INDIRECT_OPCODES_LEN
);
9452 table
[i
] = &invalid_handler
;
9465 static void fix_opcode_tables (opc_handler_t
**ppc_opcodes
)
9467 if (test_opcode_table(ppc_opcodes
, PPC_CPU_OPCODES_LEN
) == 0)
9468 printf("*** WARNING: no opcode defined !\n");
9471 /*****************************************************************************/
9472 static void create_ppc_opcodes(PowerPCCPU
*cpu
, Error
**errp
)
9474 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9475 CPUPPCState
*env
= &cpu
->env
;
9478 fill_new_table(env
->opcodes
, PPC_CPU_OPCODES_LEN
);
9479 for (opc
= opcodes
; opc
< &opcodes
[ARRAY_SIZE(opcodes
)]; opc
++) {
9480 if (((opc
->handler
.type
& pcc
->insns_flags
) != 0) ||
9481 ((opc
->handler
.type2
& pcc
->insns_flags2
) != 0)) {
9482 if (register_insn(env
->opcodes
, opc
) < 0) {
9483 error_setg(errp
, "ERROR initializing PowerPC instruction "
9484 "0x%02x 0x%02x 0x%02x", opc
->opc1
, opc
->opc2
,
9490 fix_opcode_tables(env
->opcodes
);
9495 #if defined(PPC_DUMP_CPU)
9496 static void dump_ppc_insns (CPUPPCState
*env
)
9498 opc_handler_t
**table
, *handler
;
9500 uint8_t opc1
, opc2
, opc3
, opc4
;
9502 printf("Instructions set:\n");
9503 /* opc1 is 6 bits long */
9504 for (opc1
= 0x00; opc1
< PPC_CPU_OPCODES_LEN
; opc1
++) {
9505 table
= env
->opcodes
;
9506 handler
= table
[opc1
];
9507 if (is_indirect_opcode(handler
)) {
9508 /* opc2 is 5 bits long */
9509 for (opc2
= 0; opc2
< PPC_CPU_INDIRECT_OPCODES_LEN
; opc2
++) {
9510 table
= env
->opcodes
;
9511 handler
= env
->opcodes
[opc1
];
9512 table
= ind_table(handler
);
9513 handler
= table
[opc2
];
9514 if (is_indirect_opcode(handler
)) {
9515 table
= ind_table(handler
);
9516 /* opc3 is 5 bits long */
9517 for (opc3
= 0; opc3
< PPC_CPU_INDIRECT_OPCODES_LEN
;
9519 handler
= table
[opc3
];
9520 if (is_indirect_opcode(handler
)) {
9521 table
= ind_table(handler
);
9522 /* opc4 is 5 bits long */
9523 for (opc4
= 0; opc4
< PPC_CPU_INDIRECT_OPCODES_LEN
;
9525 handler
= table
[opc4
];
9526 if (handler
->handler
!= &gen_invalid
) {
9527 printf("INSN: %02x %02x %02x %02x -- "
9528 "(%02d %04d %02d) : %s\n",
9529 opc1
, opc2
, opc3
, opc4
,
9530 opc1
, (opc3
<< 5) | opc2
, opc4
,
9535 if (handler
->handler
!= &gen_invalid
) {
9536 /* Special hack to properly dump SPE insns */
9537 p
= strchr(handler
->oname
, '_');
9539 printf("INSN: %02x %02x %02x (%02d %04d) : "
9541 opc1
, opc2
, opc3
, opc1
,
9546 if ((p
- handler
->oname
) != strlen(q
)
9547 || (memcmp(handler
->oname
, q
, strlen(q
))
9549 /* First instruction */
9550 printf("INSN: %02x %02x %02x"
9551 "(%02d %04d) : %.*s\n",
9552 opc1
, opc2
<< 1, opc3
, opc1
,
9553 (opc3
<< 6) | (opc2
<< 1),
9554 (int)(p
- handler
->oname
),
9557 if (strcmp(p
+ 1, q
) != 0) {
9558 /* Second instruction */
9559 printf("INSN: %02x %02x %02x "
9560 "(%02d %04d) : %s\n", opc1
,
9561 (opc2
<< 1) | 1, opc3
, opc1
,
9562 (opc3
<< 6) | (opc2
<< 1) | 1,
9570 if (handler
->handler
!= &gen_invalid
) {
9571 printf("INSN: %02x %02x -- (%02d %04d) : %s\n",
9572 opc1
, opc2
, opc1
, opc2
, handler
->oname
);
9577 if (handler
->handler
!= &gen_invalid
) {
9578 printf("INSN: %02x -- -- (%02d ----) : %s\n",
9579 opc1
, opc1
, handler
->oname
);
9586 static bool avr_need_swap(CPUPPCState
*env
)
9588 #ifdef HOST_WORDS_BIGENDIAN
9595 static int gdb_get_float_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9598 stfq_p(mem_buf
, env
->fpr
[n
]);
9599 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9603 stl_p(mem_buf
, env
->fpscr
);
9604 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9610 static int gdb_set_float_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9613 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9614 env
->fpr
[n
] = ldfq_p(mem_buf
);
9618 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9619 helper_store_fpscr(env
, ldl_p(mem_buf
), 0xffffffff);
9625 static int gdb_get_avr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9628 if (!avr_need_swap(env
)) {
9629 stq_p(mem_buf
, env
->avr
[n
].u64
[0]);
9630 stq_p(mem_buf
+8, env
->avr
[n
].u64
[1]);
9632 stq_p(mem_buf
, env
->avr
[n
].u64
[1]);
9633 stq_p(mem_buf
+8, env
->avr
[n
].u64
[0]);
9635 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9636 ppc_maybe_bswap_register(env
, mem_buf
+ 8, 8);
9640 stl_p(mem_buf
, env
->vscr
);
9641 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9645 stl_p(mem_buf
, (uint32_t)env
->spr
[SPR_VRSAVE
]);
9646 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9652 static int gdb_set_avr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9655 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9656 ppc_maybe_bswap_register(env
, mem_buf
+ 8, 8);
9657 if (!avr_need_swap(env
)) {
9658 env
->avr
[n
].u64
[0] = ldq_p(mem_buf
);
9659 env
->avr
[n
].u64
[1] = ldq_p(mem_buf
+8);
9661 env
->avr
[n
].u64
[1] = ldq_p(mem_buf
);
9662 env
->avr
[n
].u64
[0] = ldq_p(mem_buf
+8);
9667 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9668 env
->vscr
= ldl_p(mem_buf
);
9672 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9673 env
->spr
[SPR_VRSAVE
] = (target_ulong
)ldl_p(mem_buf
);
9679 static int gdb_get_spe_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9682 #if defined(TARGET_PPC64)
9683 stl_p(mem_buf
, env
->gpr
[n
] >> 32);
9684 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9686 stl_p(mem_buf
, env
->gprh
[n
]);
9691 stq_p(mem_buf
, env
->spe_acc
);
9692 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9696 stl_p(mem_buf
, env
->spe_fscr
);
9697 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9703 static int gdb_set_spe_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9706 #if defined(TARGET_PPC64)
9707 target_ulong lo
= (uint32_t)env
->gpr
[n
];
9710 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9712 hi
= (target_ulong
)ldl_p(mem_buf
) << 32;
9713 env
->gpr
[n
] = lo
| hi
;
9715 env
->gprh
[n
] = ldl_p(mem_buf
);
9720 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9721 env
->spe_acc
= ldq_p(mem_buf
);
9725 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9726 env
->spe_fscr
= ldl_p(mem_buf
);
9732 static int gdb_get_vsx_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9735 stq_p(mem_buf
, env
->vsr
[n
]);
9736 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9742 static int gdb_set_vsx_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9745 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9746 env
->vsr
[n
] = ldq_p(mem_buf
);
9752 static int ppc_fixup_cpu(PowerPCCPU
*cpu
)
9754 CPUPPCState
*env
= &cpu
->env
;
9756 /* TCG doesn't (yet) emulate some groups of instructions that
9757 * are implemented on some otherwise supported CPUs (e.g. VSX
9758 * and decimal floating point instructions on POWER7). We
9759 * remove unsupported instruction groups from the cpu state's
9760 * instruction masks and hope the guest can cope. For at
9761 * least the pseries machine, the unavailability of these
9762 * instructions can be advertised to the guest via the device
9764 if ((env
->insns_flags
& ~PPC_TCG_INSNS
)
9765 || (env
->insns_flags2
& ~PPC_TCG_INSNS2
)) {
9766 fprintf(stderr
, "Warning: Disabling some instructions which are not "
9767 "emulated by TCG (0x%" PRIx64
", 0x%" PRIx64
")\n",
9768 env
->insns_flags
& ~PPC_TCG_INSNS
,
9769 env
->insns_flags2
& ~PPC_TCG_INSNS2
);
9771 env
->insns_flags
&= PPC_TCG_INSNS
;
9772 env
->insns_flags2
&= PPC_TCG_INSNS2
;
9776 static inline bool ppc_cpu_is_valid(PowerPCCPUClass
*pcc
)
9778 #ifdef TARGET_PPCEMB
9779 return pcc
->mmu_model
== POWERPC_MMU_BOOKE
||
9780 pcc
->mmu_model
== POWERPC_MMU_SOFT_4xx
||
9781 pcc
->mmu_model
== POWERPC_MMU_SOFT_4xx_Z
;
9787 static void ppc_cpu_realizefn(DeviceState
*dev
, Error
**errp
)
9789 CPUState
*cs
= CPU(dev
);
9790 PowerPCCPU
*cpu
= POWERPC_CPU(dev
);
9791 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9792 Error
*local_err
= NULL
;
9793 #if !defined(CONFIG_USER_ONLY)
9794 int max_smt
= kvmppc_smt_threads();
9797 #if !defined(CONFIG_USER_ONLY)
9798 if (smp_threads
> max_smt
) {
9799 error_setg(errp
, "Cannot support more than %d threads on PPC with %s",
9800 max_smt
, kvm_enabled() ? "KVM" : "TCG");
9803 if (!is_power_of_2(smp_threads
)) {
9804 error_setg(errp
, "Cannot support %d threads on PPC with %s, "
9805 "threads count must be a power of 2.",
9806 smp_threads
, kvm_enabled() ? "KVM" : "TCG");
9811 cpu_exec_realizefn(cs
, &local_err
);
9812 if (local_err
!= NULL
) {
9813 error_propagate(errp
, local_err
);
9817 #if !defined(CONFIG_USER_ONLY)
9818 cpu
->cpu_dt_id
= (cs
->cpu_index
/ smp_threads
) * max_smt
9819 + (cs
->cpu_index
% smp_threads
);
9821 if (kvm_enabled() && !kvm_vcpu_id_is_valid(cpu
->cpu_dt_id
)) {
9822 error_setg(errp
, "Can't create CPU with id %d in KVM", cpu
->cpu_dt_id
);
9823 error_append_hint(errp
, "Adjust the number of cpus to %d "
9824 "or try to raise the number of threads per core\n",
9825 cpu
->cpu_dt_id
* smp_threads
/ max_smt
);
9830 if (tcg_enabled()) {
9831 if (ppc_fixup_cpu(cpu
) != 0) {
9832 error_setg(errp
, "Unable to emulate selected CPU with TCG");
9837 #if defined(TARGET_PPCEMB)
9838 if (!ppc_cpu_is_valid(pcc
)) {
9839 error_setg(errp
, "CPU does not possess a BookE or 4xx MMU. "
9840 "Please use qemu-system-ppc or qemu-system-ppc64 instead "
9841 "or choose another CPU model.");
9846 create_ppc_opcodes(cpu
, &local_err
);
9847 if (local_err
!= NULL
) {
9848 error_propagate(errp
, local_err
);
9853 if (pcc
->insns_flags
& PPC_FLOAT
) {
9854 gdb_register_coprocessor(cs
, gdb_get_float_reg
, gdb_set_float_reg
,
9855 33, "power-fpu.xml", 0);
9857 if (pcc
->insns_flags
& PPC_ALTIVEC
) {
9858 gdb_register_coprocessor(cs
, gdb_get_avr_reg
, gdb_set_avr_reg
,
9859 34, "power-altivec.xml", 0);
9861 if (pcc
->insns_flags
& PPC_SPE
) {
9862 gdb_register_coprocessor(cs
, gdb_get_spe_reg
, gdb_set_spe_reg
,
9863 34, "power-spe.xml", 0);
9865 if (pcc
->insns_flags2
& PPC2_VSX
) {
9866 gdb_register_coprocessor(cs
, gdb_get_vsx_reg
, gdb_set_vsx_reg
,
9867 32, "power-vsx.xml", 0);
9872 pcc
->parent_realize(dev
, errp
);
9874 #if defined(PPC_DUMP_CPU)
9876 CPUPPCState
*env
= &cpu
->env
;
9877 const char *mmu_model
, *excp_model
, *bus_model
;
9878 switch (env
->mmu_model
) {
9879 case POWERPC_MMU_32B
:
9880 mmu_model
= "PowerPC 32";
9882 case POWERPC_MMU_SOFT_6xx
:
9883 mmu_model
= "PowerPC 6xx/7xx with software driven TLBs";
9885 case POWERPC_MMU_SOFT_74xx
:
9886 mmu_model
= "PowerPC 74xx with software driven TLBs";
9888 case POWERPC_MMU_SOFT_4xx
:
9889 mmu_model
= "PowerPC 4xx with software driven TLBs";
9891 case POWERPC_MMU_SOFT_4xx_Z
:
9892 mmu_model
= "PowerPC 4xx with software driven TLBs "
9893 "and zones protections";
9895 case POWERPC_MMU_REAL
:
9896 mmu_model
= "PowerPC real mode only";
9898 case POWERPC_MMU_MPC8xx
:
9899 mmu_model
= "PowerPC MPC8xx";
9901 case POWERPC_MMU_BOOKE
:
9902 mmu_model
= "PowerPC BookE";
9904 case POWERPC_MMU_BOOKE206
:
9905 mmu_model
= "PowerPC BookE 2.06";
9907 case POWERPC_MMU_601
:
9908 mmu_model
= "PowerPC 601";
9910 #if defined (TARGET_PPC64)
9911 case POWERPC_MMU_64B
:
9912 mmu_model
= "PowerPC 64";
9916 mmu_model
= "Unknown or invalid";
9919 switch (env
->excp_model
) {
9920 case POWERPC_EXCP_STD
:
9921 excp_model
= "PowerPC";
9923 case POWERPC_EXCP_40x
:
9924 excp_model
= "PowerPC 40x";
9926 case POWERPC_EXCP_601
:
9927 excp_model
= "PowerPC 601";
9929 case POWERPC_EXCP_602
:
9930 excp_model
= "PowerPC 602";
9932 case POWERPC_EXCP_603
:
9933 excp_model
= "PowerPC 603";
9935 case POWERPC_EXCP_603E
:
9936 excp_model
= "PowerPC 603e";
9938 case POWERPC_EXCP_604
:
9939 excp_model
= "PowerPC 604";
9941 case POWERPC_EXCP_7x0
:
9942 excp_model
= "PowerPC 740/750";
9944 case POWERPC_EXCP_7x5
:
9945 excp_model
= "PowerPC 745/755";
9947 case POWERPC_EXCP_74xx
:
9948 excp_model
= "PowerPC 74xx";
9950 case POWERPC_EXCP_BOOKE
:
9951 excp_model
= "PowerPC BookE";
9953 #if defined (TARGET_PPC64)
9954 case POWERPC_EXCP_970
:
9955 excp_model
= "PowerPC 970";
9959 excp_model
= "Unknown or invalid";
9962 switch (env
->bus_model
) {
9963 case PPC_FLAGS_INPUT_6xx
:
9964 bus_model
= "PowerPC 6xx";
9966 case PPC_FLAGS_INPUT_BookE
:
9967 bus_model
= "PowerPC BookE";
9969 case PPC_FLAGS_INPUT_405
:
9970 bus_model
= "PowerPC 405";
9972 case PPC_FLAGS_INPUT_401
:
9973 bus_model
= "PowerPC 401/403";
9975 case PPC_FLAGS_INPUT_RCPU
:
9976 bus_model
= "RCPU / MPC8xx";
9978 #if defined (TARGET_PPC64)
9979 case PPC_FLAGS_INPUT_970
:
9980 bus_model
= "PowerPC 970";
9984 bus_model
= "Unknown or invalid";
9987 printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64
"\n"
9988 " MMU model : %s\n",
9989 object_class_get_name(OBJECT_CLASS(pcc
)),
9990 pcc
->pvr
, pcc
->msr_mask
, mmu_model
);
9991 #if !defined(CONFIG_USER_ONLY)
9992 if (env
->tlb
.tlb6
) {
9993 printf(" %d %s TLB in %d ways\n",
9994 env
->nb_tlb
, env
->id_tlbs
? "splitted" : "merged",
9998 printf(" Exceptions model : %s\n"
9999 " Bus model : %s\n",
10000 excp_model
, bus_model
);
10001 printf(" MSR features :\n");
10002 if (env
->flags
& POWERPC_FLAG_SPE
)
10003 printf(" signal processing engine enable"
10005 else if (env
->flags
& POWERPC_FLAG_VRE
)
10006 printf(" vector processor enable\n");
10007 if (env
->flags
& POWERPC_FLAG_TGPR
)
10008 printf(" temporary GPRs\n");
10009 else if (env
->flags
& POWERPC_FLAG_CE
)
10010 printf(" critical input enable\n");
10011 if (env
->flags
& POWERPC_FLAG_SE
)
10012 printf(" single-step trace mode\n");
10013 else if (env
->flags
& POWERPC_FLAG_DWE
)
10014 printf(" debug wait enable\n");
10015 else if (env
->flags
& POWERPC_FLAG_UBLE
)
10016 printf(" user BTB lock enable\n");
10017 if (env
->flags
& POWERPC_FLAG_BE
)
10018 printf(" branch-step trace mode\n");
10019 else if (env
->flags
& POWERPC_FLAG_DE
)
10020 printf(" debug interrupt enable\n");
10021 if (env
->flags
& POWERPC_FLAG_PX
)
10022 printf(" inclusive protection\n");
10023 else if (env
->flags
& POWERPC_FLAG_PMM
)
10024 printf(" performance monitor mark\n");
10025 if (env
->flags
== POWERPC_FLAG_NONE
)
10027 printf(" Time-base/decrementer clock source: %s\n",
10028 env
->flags
& POWERPC_FLAG_RTC_CLK
? "RTC clock" : "bus clock");
10029 dump_ppc_insns(env
);
10030 dump_ppc_sprs(env
);
10036 static void ppc_cpu_unrealizefn(DeviceState
*dev
, Error
**errp
)
10038 PowerPCCPU
*cpu
= POWERPC_CPU(dev
);
10039 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10040 CPUPPCState
*env
= &cpu
->env
;
10041 Error
*local_err
= NULL
;
10042 opc_handler_t
**table
, **table_2
;
10045 pcc
->parent_unrealize(dev
, &local_err
);
10046 if (local_err
!= NULL
) {
10047 error_propagate(errp
, local_err
);
10051 for (i
= 0; i
< PPC_CPU_OPCODES_LEN
; i
++) {
10052 if (env
->opcodes
[i
] == &invalid_handler
) {
10055 if (is_indirect_opcode(env
->opcodes
[i
])) {
10056 table
= ind_table(env
->opcodes
[i
]);
10057 for (j
= 0; j
< PPC_CPU_INDIRECT_OPCODES_LEN
; j
++) {
10058 if (table
[j
] == &invalid_handler
) {
10061 if (is_indirect_opcode(table
[j
])) {
10062 table_2
= ind_table(table
[j
]);
10063 for (k
= 0; k
< PPC_CPU_INDIRECT_OPCODES_LEN
; k
++) {
10064 if (table_2
[k
] != &invalid_handler
&&
10065 is_indirect_opcode(table_2
[k
])) {
10066 g_free((opc_handler_t
*)((uintptr_t)table_2
[k
] &
10070 g_free((opc_handler_t
*)((uintptr_t)table
[j
] &
10074 g_free((opc_handler_t
*)((uintptr_t)env
->opcodes
[i
] &
10080 static gint
ppc_cpu_compare_class_pvr(gconstpointer a
, gconstpointer b
)
10082 ObjectClass
*oc
= (ObjectClass
*)a
;
10083 uint32_t pvr
= *(uint32_t *)b
;
10084 PowerPCCPUClass
*pcc
= (PowerPCCPUClass
*)a
;
10086 /* -cpu host does a PVR lookup during construction */
10087 if (unlikely(strcmp(object_class_get_name(oc
),
10088 TYPE_HOST_POWERPC_CPU
) == 0)) {
10092 if (!ppc_cpu_is_valid(pcc
)) {
10096 return pcc
->pvr
== pvr
? 0 : -1;
10099 PowerPCCPUClass
*ppc_cpu_class_by_pvr(uint32_t pvr
)
10101 GSList
*list
, *item
;
10102 PowerPCCPUClass
*pcc
= NULL
;
10104 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10105 item
= g_slist_find_custom(list
, &pvr
, ppc_cpu_compare_class_pvr
);
10106 if (item
!= NULL
) {
10107 pcc
= POWERPC_CPU_CLASS(item
->data
);
10109 g_slist_free(list
);
10114 static gint
ppc_cpu_compare_class_pvr_mask(gconstpointer a
, gconstpointer b
)
10116 ObjectClass
*oc
= (ObjectClass
*)a
;
10117 uint32_t pvr
= *(uint32_t *)b
;
10118 PowerPCCPUClass
*pcc
= (PowerPCCPUClass
*)a
;
10120 /* -cpu host does a PVR lookup during construction */
10121 if (unlikely(strcmp(object_class_get_name(oc
),
10122 TYPE_HOST_POWERPC_CPU
) == 0)) {
10126 if (!ppc_cpu_is_valid(pcc
)) {
10130 if (pcc
->pvr_match(pcc
, pvr
)) {
10137 PowerPCCPUClass
*ppc_cpu_class_by_pvr_mask(uint32_t pvr
)
10139 GSList
*list
, *item
;
10140 PowerPCCPUClass
*pcc
= NULL
;
10142 list
= object_class_get_list(TYPE_POWERPC_CPU
, true);
10143 item
= g_slist_find_custom(list
, &pvr
, ppc_cpu_compare_class_pvr_mask
);
10144 if (item
!= NULL
) {
10145 pcc
= POWERPC_CPU_CLASS(item
->data
);
10147 g_slist_free(list
);
10152 static gint
ppc_cpu_compare_class_name(gconstpointer a
, gconstpointer b
)
10154 ObjectClass
*oc
= (ObjectClass
*)a
;
10155 const char *name
= b
;
10156 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10158 if (strncasecmp(name
, object_class_get_name(oc
), strlen(name
)) == 0 &&
10159 ppc_cpu_is_valid(pcc
) &&
10160 strcmp(object_class_get_name(oc
) + strlen(name
),
10161 "-" TYPE_POWERPC_CPU
) == 0) {
10168 static ObjectClass
*ppc_cpu_class_by_name(const char *name
);
10170 static ObjectClass
*ppc_cpu_class_by_alias(PowerPCCPUAlias
*alias
)
10172 ObjectClass
*invalid_class
= (void*)ppc_cpu_class_by_alias
;
10174 /* Cache target class lookups in the alias table */
10176 alias
->oc
= ppc_cpu_class_by_name(alias
->model
);
10178 /* Fast check for non-existing aliases */
10179 alias
->oc
= invalid_class
;
10183 if (alias
->oc
== invalid_class
) {
10190 static ObjectClass
*ppc_cpu_class_by_name(const char *name
)
10192 GSList
*list
, *item
;
10193 ObjectClass
*ret
= NULL
;
10197 /* Check if the given name is a PVR */
10198 len
= strlen(name
);
10199 if (len
== 10 && name
[0] == '0' && name
[1] == 'x') {
10202 } else if (len
== 8) {
10205 for (i
= 0; i
< 8; i
++) {
10206 if (!qemu_isxdigit(*p
++))
10210 return OBJECT_CLASS(ppc_cpu_class_by_pvr(strtoul(name
, NULL
, 16)));
10214 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10215 item
= g_slist_find_custom(list
, name
, ppc_cpu_compare_class_name
);
10216 if (item
!= NULL
) {
10217 ret
= OBJECT_CLASS(item
->data
);
10219 g_slist_free(list
);
10225 for (i
= 0; ppc_cpu_aliases
[i
].alias
!= NULL
; i
++) {
10226 if (strcmp(ppc_cpu_aliases
[i
].alias
, name
) == 0) {
10227 return ppc_cpu_class_by_alias(&ppc_cpu_aliases
[i
]);
10234 const char *ppc_cpu_lookup_alias(const char *alias
)
10238 for (ai
= 0; ppc_cpu_aliases
[ai
].alias
!= NULL
; ai
++) {
10239 if (strcmp(ppc_cpu_aliases
[ai
].alias
, alias
) == 0) {
10240 return ppc_cpu_aliases
[ai
].model
;
10247 PowerPCCPU
*cpu_ppc_init(const char *cpu_model
)
10249 return POWERPC_CPU(cpu_generic_init(TYPE_POWERPC_CPU
, cpu_model
));
10252 /* Sort by PVR, ordering special case "host" last. */
10253 static gint
ppc_cpu_list_compare(gconstpointer a
, gconstpointer b
)
10255 ObjectClass
*oc_a
= (ObjectClass
*)a
;
10256 ObjectClass
*oc_b
= (ObjectClass
*)b
;
10257 PowerPCCPUClass
*pcc_a
= POWERPC_CPU_CLASS(oc_a
);
10258 PowerPCCPUClass
*pcc_b
= POWERPC_CPU_CLASS(oc_b
);
10259 const char *name_a
= object_class_get_name(oc_a
);
10260 const char *name_b
= object_class_get_name(oc_b
);
10262 if (strcmp(name_a
, TYPE_HOST_POWERPC_CPU
) == 0) {
10264 } else if (strcmp(name_b
, TYPE_HOST_POWERPC_CPU
) == 0) {
10267 /* Avoid an integer overflow during subtraction */
10268 if (pcc_a
->pvr
< pcc_b
->pvr
) {
10270 } else if (pcc_a
->pvr
> pcc_b
->pvr
) {
10278 static void ppc_cpu_list_entry(gpointer data
, gpointer user_data
)
10280 ObjectClass
*oc
= data
;
10281 CPUListState
*s
= user_data
;
10282 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10283 const char *typename
= object_class_get_name(oc
);
10287 if (!ppc_cpu_is_valid(pcc
)) {
10290 if (unlikely(strcmp(typename
, TYPE_HOST_POWERPC_CPU
) == 0)) {
10294 name
= g_strndup(typename
,
10295 strlen(typename
) - strlen("-" TYPE_POWERPC_CPU
));
10296 (*s
->cpu_fprintf
)(s
->file
, "PowerPC %-16s PVR %08x\n",
10298 for (i
= 0; ppc_cpu_aliases
[i
].alias
!= NULL
; i
++) {
10299 PowerPCCPUAlias
*alias
= &ppc_cpu_aliases
[i
];
10300 ObjectClass
*alias_oc
= ppc_cpu_class_by_alias(alias
);
10302 if (alias_oc
!= oc
) {
10305 (*s
->cpu_fprintf
)(s
->file
, "PowerPC %-16s (alias for %s)\n",
10306 alias
->alias
, name
);
10311 void ppc_cpu_list(FILE *f
, fprintf_function cpu_fprintf
)
10315 .cpu_fprintf
= cpu_fprintf
,
10319 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10320 list
= g_slist_sort(list
, ppc_cpu_list_compare
);
10321 g_slist_foreach(list
, ppc_cpu_list_entry
, &s
);
10322 g_slist_free(list
);
10325 cpu_fprintf(f
, "\n");
10326 cpu_fprintf(f
, "PowerPC %-16s\n", "host");
10330 static void ppc_cpu_defs_entry(gpointer data
, gpointer user_data
)
10332 ObjectClass
*oc
= data
;
10333 CpuDefinitionInfoList
**first
= user_data
;
10334 const char *typename
;
10335 CpuDefinitionInfoList
*entry
;
10336 CpuDefinitionInfo
*info
;
10337 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10339 if (!ppc_cpu_is_valid(pcc
)) {
10343 typename
= object_class_get_name(oc
);
10344 info
= g_malloc0(sizeof(*info
));
10345 info
->name
= g_strndup(typename
,
10346 strlen(typename
) - strlen("-" TYPE_POWERPC_CPU
));
10348 entry
= g_malloc0(sizeof(*entry
));
10349 entry
->value
= info
;
10350 entry
->next
= *first
;
10354 CpuDefinitionInfoList
*arch_query_cpu_definitions(Error
**errp
)
10356 CpuDefinitionInfoList
*cpu_list
= NULL
;
10360 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10361 g_slist_foreach(list
, ppc_cpu_defs_entry
, &cpu_list
);
10362 g_slist_free(list
);
10364 for (i
= 0; ppc_cpu_aliases
[i
].alias
!= NULL
; i
++) {
10365 PowerPCCPUAlias
*alias
= &ppc_cpu_aliases
[i
];
10367 CpuDefinitionInfoList
*entry
;
10368 CpuDefinitionInfo
*info
;
10370 oc
= ppc_cpu_class_by_alias(alias
);
10375 info
= g_malloc0(sizeof(*info
));
10376 info
->name
= g_strdup(alias
->alias
);
10377 info
->q_typename
= g_strdup(object_class_get_name(oc
));
10379 entry
= g_malloc0(sizeof(*entry
));
10380 entry
->value
= info
;
10381 entry
->next
= cpu_list
;
10388 static void ppc_cpu_set_pc(CPUState
*cs
, vaddr value
)
10390 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10392 cpu
->env
.nip
= value
;
10395 static bool ppc_cpu_has_work(CPUState
*cs
)
10397 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10398 CPUPPCState
*env
= &cpu
->env
;
10400 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
10403 static void ppc_cpu_exec_enter(CPUState
*cs
)
10405 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10406 CPUPPCState
*env
= &cpu
->env
;
10408 env
->reserve_addr
= -1;
10411 /* CPUClass::reset() */
10412 static void ppc_cpu_reset(CPUState
*s
)
10414 PowerPCCPU
*cpu
= POWERPC_CPU(s
);
10415 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10416 CPUPPCState
*env
= &cpu
->env
;
10420 pcc
->parent_reset(s
);
10422 msr
= (target_ulong
)0;
10423 msr
|= (target_ulong
)MSR_HVB
;
10424 msr
|= (target_ulong
)0 << MSR_AP
; /* TO BE CHECKED */
10425 msr
|= (target_ulong
)0 << MSR_SA
; /* TO BE CHECKED */
10426 msr
|= (target_ulong
)1 << MSR_EP
;
10427 #if defined(DO_SINGLE_STEP) && 0
10428 /* Single step trace mode */
10429 msr
|= (target_ulong
)1 << MSR_SE
;
10430 msr
|= (target_ulong
)1 << MSR_BE
;
10432 #if defined(CONFIG_USER_ONLY)
10433 msr
|= (target_ulong
)1 << MSR_FP
; /* Allow floating point usage */
10434 msr
|= (target_ulong
)1 << MSR_VR
; /* Allow altivec usage */
10435 msr
|= (target_ulong
)1 << MSR_VSX
; /* Allow VSX usage */
10436 msr
|= (target_ulong
)1 << MSR_SPE
; /* Allow SPE usage */
10437 msr
|= (target_ulong
)1 << MSR_PR
;
10438 #if defined(TARGET_PPC64)
10439 msr
|= (target_ulong
)1 << MSR_TM
; /* Transactional memory */
10441 #if !defined(TARGET_WORDS_BIGENDIAN)
10442 msr
|= (target_ulong
)1 << MSR_LE
; /* Little-endian user mode */
10443 if (!((env
->msr_mask
>> MSR_LE
) & 1)) {
10444 fprintf(stderr
, "Selected CPU does not support little-endian.\n");
10450 #if defined(TARGET_PPC64)
10451 if (env
->mmu_model
& POWERPC_MMU_64
) {
10452 msr
|= (1ULL << MSR_SF
);
10456 hreg_store_msr(env
, msr
, 1);
10458 #if !defined(CONFIG_USER_ONLY)
10459 env
->nip
= env
->hreset_vector
| env
->excp_prefix
;
10460 if (env
->mmu_model
!= POWERPC_MMU_REAL
) {
10461 ppc_tlb_invalidate_all(env
);
10465 hreg_compute_hflags(env
);
10466 env
->reserve_addr
= (target_ulong
)-1ULL;
10467 /* Be sure no exception or interrupt is pending */
10468 env
->pending_interrupts
= 0;
10469 s
->exception_index
= POWERPC_EXCP_NONE
;
10470 env
->error_code
= 0;
10472 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
10474 env
->slb_shadow_addr
= 0;
10475 env
->slb_shadow_size
= 0;
10478 #endif /* TARGET_PPC64 */
10480 for (i
= 0; i
< ARRAY_SIZE(env
->spr_cb
); i
++) {
10481 ppc_spr_t
*spr
= &env
->spr_cb
[i
];
10486 env
->spr
[i
] = spr
->default_value
;
10490 #ifndef CONFIG_USER_ONLY
10491 static bool ppc_cpu_is_big_endian(CPUState
*cs
)
10493 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10494 CPUPPCState
*env
= &cpu
->env
;
10496 cpu_synchronize_state(cs
);
10502 static void ppc_cpu_initfn(Object
*obj
)
10504 CPUState
*cs
= CPU(obj
);
10505 PowerPCCPU
*cpu
= POWERPC_CPU(obj
);
10506 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10507 CPUPPCState
*env
= &cpu
->env
;
10511 env
->msr_mask
= pcc
->msr_mask
;
10512 env
->mmu_model
= pcc
->mmu_model
;
10513 env
->excp_model
= pcc
->excp_model
;
10514 env
->bus_model
= pcc
->bus_model
;
10515 env
->insns_flags
= pcc
->insns_flags
;
10516 env
->insns_flags2
= pcc
->insns_flags2
;
10517 env
->flags
= pcc
->flags
;
10518 env
->bfd_mach
= pcc
->bfd_mach
;
10519 env
->check_pow
= pcc
->check_pow
;
10521 /* Mark HV mode as supported if the CPU has an MSR_HV bit
10522 * in the msr_mask. The mask can later be cleared by PAPR
10523 * mode but the hv mode support will remain, thus enforcing
10524 * that we cannot use priv. instructions in guest in PAPR
10525 * mode. For 970 we currently simply don't set HV in msr_mask
10526 * thus simulating an "Apple mode" 970. If we ever want to
10527 * support 970 HV mode, we'll have to add a processor attribute
10530 #if !defined(CONFIG_USER_ONLY)
10531 env
->has_hv_mode
= !!(env
->msr_mask
& MSR_HVB
);
10534 #if defined(TARGET_PPC64)
10536 env
->sps
= *pcc
->sps
;
10537 } else if (env
->mmu_model
& POWERPC_MMU_64
) {
10538 /* Use default sets of page sizes. We don't support MPSS */
10539 static const struct ppc_segment_page_sizes defsps_4k
= {
10541 { .page_shift
= 12, /* 4K */
10543 .enc
= { { .page_shift
= 12, .pte_enc
= 0 } }
10545 { .page_shift
= 24, /* 16M */
10547 .enc
= { { .page_shift
= 24, .pte_enc
= 0 } }
10551 static const struct ppc_segment_page_sizes defsps_64k
= {
10553 { .page_shift
= 12, /* 4K */
10555 .enc
= { { .page_shift
= 12, .pte_enc
= 0 } }
10557 { .page_shift
= 16, /* 64K */
10559 .enc
= { { .page_shift
= 16, .pte_enc
= 1 } }
10561 { .page_shift
= 24, /* 16M */
10563 .enc
= { { .page_shift
= 24, .pte_enc
= 0 } }
10567 env
->sps
= (env
->mmu_model
& POWERPC_MMU_64K
) ? defsps_64k
: defsps_4k
;
10569 #endif /* defined(TARGET_PPC64) */
10571 if (tcg_enabled()) {
10572 ppc_translate_init();
10576 static bool ppc_pvr_match_default(PowerPCCPUClass
*pcc
, uint32_t pvr
)
10578 return pcc
->pvr
== pvr
;
10581 static gchar
*ppc_gdb_arch_name(CPUState
*cs
)
10583 #if defined(TARGET_PPC64)
10584 return g_strdup("powerpc:common64");
10586 return g_strdup("powerpc:common");
10590 static Property ppc_cpu_properties
[] = {
10591 DEFINE_PROP_BOOL("pre-2.8-migration", PowerPCCPU
, pre_2_8_migration
, false),
10592 DEFINE_PROP_END_OF_LIST(),
10595 static void ppc_cpu_class_init(ObjectClass
*oc
, void *data
)
10597 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10598 CPUClass
*cc
= CPU_CLASS(oc
);
10599 DeviceClass
*dc
= DEVICE_CLASS(oc
);
10601 pcc
->parent_realize
= dc
->realize
;
10602 pcc
->parent_unrealize
= dc
->unrealize
;
10603 pcc
->pvr_match
= ppc_pvr_match_default
;
10604 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_always
;
10605 dc
->realize
= ppc_cpu_realizefn
;
10606 dc
->unrealize
= ppc_cpu_unrealizefn
;
10607 dc
->props
= ppc_cpu_properties
;
10609 pcc
->parent_reset
= cc
->reset
;
10610 cc
->reset
= ppc_cpu_reset
;
10612 cc
->class_by_name
= ppc_cpu_class_by_name
;
10613 cc
->has_work
= ppc_cpu_has_work
;
10614 cc
->do_interrupt
= ppc_cpu_do_interrupt
;
10615 cc
->cpu_exec_interrupt
= ppc_cpu_exec_interrupt
;
10616 cc
->dump_state
= ppc_cpu_dump_state
;
10617 cc
->dump_statistics
= ppc_cpu_dump_statistics
;
10618 cc
->set_pc
= ppc_cpu_set_pc
;
10619 cc
->gdb_read_register
= ppc_cpu_gdb_read_register
;
10620 cc
->gdb_write_register
= ppc_cpu_gdb_write_register
;
10621 #ifdef CONFIG_USER_ONLY
10622 cc
->handle_mmu_fault
= ppc_cpu_handle_mmu_fault
;
10624 cc
->get_phys_page_debug
= ppc_cpu_get_phys_page_debug
;
10625 cc
->vmsd
= &vmstate_ppc_cpu
;
10627 cc
->cpu_exec_enter
= ppc_cpu_exec_enter
;
10628 #if defined(CONFIG_SOFTMMU)
10629 cc
->write_elf64_note
= ppc64_cpu_write_elf64_note
;
10630 cc
->write_elf32_note
= ppc32_cpu_write_elf32_note
;
10633 cc
->gdb_num_core_regs
= 71;
10635 #ifdef USE_APPLE_GDB
10636 cc
->gdb_read_register
= ppc_cpu_gdb_read_register_apple
;
10637 cc
->gdb_write_register
= ppc_cpu_gdb_write_register_apple
;
10638 cc
->gdb_num_core_regs
= 71 + 32;
10641 cc
->gdb_arch_name
= ppc_gdb_arch_name
;
10642 #if defined(TARGET_PPC64)
10643 cc
->gdb_core_xml_file
= "power64-core.xml";
10645 cc
->gdb_core_xml_file
= "power-core.xml";
10647 #ifndef CONFIG_USER_ONLY
10648 cc
->virtio_is_big_endian
= ppc_cpu_is_big_endian
;
10651 dc
->fw_name
= "PowerPC,UNKNOWN";
10654 static const TypeInfo ppc_cpu_type_info
= {
10655 .name
= TYPE_POWERPC_CPU
,
10656 .parent
= TYPE_CPU
,
10657 .instance_size
= sizeof(PowerPCCPU
),
10658 .instance_init
= ppc_cpu_initfn
,
10660 .class_size
= sizeof(PowerPCCPUClass
),
10661 .class_init
= ppc_cpu_class_init
,
10664 static const TypeInfo ppc_vhyp_type_info
= {
10665 .name
= TYPE_PPC_VIRTUAL_HYPERVISOR
,
10666 .parent
= TYPE_INTERFACE
,
10667 .class_size
= sizeof(PPCVirtualHypervisorClass
),
10670 static void ppc_cpu_register_types(void)
10672 type_register_static(&ppc_cpu_type_info
);
10673 type_register_static(&ppc_vhyp_type_info
);
10676 type_init(ppc_cpu_register_types
)