2 * PowerPC CPU initialization for qemu.
4 * Copyright (c) 2003-2007 Jocelyn Mayer
5 * Copyright 2011 Freescale Semiconductor, Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include "disas/dis-asm.h"
22 #include "exec/gdbstub.h"
24 #include "sysemu/arch_init.h"
25 #include "sysemu/cpus.h"
26 #include "sysemu/hw_accel.h"
27 #include "sysemu/tcg.h"
28 #include "cpu-models.h"
29 #include "mmu-hash32.h"
30 #include "mmu-hash64.h"
31 #include "qemu/error-report.h"
32 #include "qemu/module.h"
33 #include "qemu/qemu-print.h"
34 #include "qapi/error.h"
35 #include "qapi/qmp/qnull.h"
36 #include "qapi/visitor.h"
37 #include "hw/qdev-properties.h"
38 #include "hw/ppc/ppc.h"
39 #include "mmu-book3s-v3.h"
40 #include "sysemu/qtest.h"
41 #include "qemu/cutils.h"
42 #include "disas/capstone.h"
43 #include "fpu/softfloat.h"
44 #include "qapi/qapi-commands-machine-target.h"
46 /* #define PPC_DUMP_CPU */
47 /* #define PPC_DEBUG_SPR */
48 /* #define PPC_DUMP_SPR_ACCESSES */
49 /* #define USE_APPLE_GDB */
53 * do nothing but store/retrieve spr value
55 static void spr_load_dump_spr(int sprn
)
57 #ifdef PPC_DUMP_SPR_ACCESSES
58 TCGv_i32 t0
= tcg_const_i32(sprn
);
59 gen_helper_load_dump_spr(cpu_env
, t0
);
60 tcg_temp_free_i32(t0
);
64 static void spr_read_generic(DisasContext
*ctx
, int gprn
, int sprn
)
66 gen_load_spr(cpu_gpr
[gprn
], sprn
);
67 spr_load_dump_spr(sprn
);
70 static void spr_store_dump_spr(int sprn
)
72 #ifdef PPC_DUMP_SPR_ACCESSES
73 TCGv_i32 t0
= tcg_const_i32(sprn
);
74 gen_helper_store_dump_spr(cpu_env
, t0
);
75 tcg_temp_free_i32(t0
);
79 static void spr_write_generic(DisasContext
*ctx
, int sprn
, int gprn
)
81 gen_store_spr(sprn
, cpu_gpr
[gprn
]);
82 spr_store_dump_spr(sprn
);
85 #if !defined(CONFIG_USER_ONLY)
86 static void spr_write_generic32(DisasContext
*ctx
, int sprn
, int gprn
)
89 TCGv t0
= tcg_temp_new();
90 tcg_gen_ext32u_tl(t0
, cpu_gpr
[gprn
]);
91 gen_store_spr(sprn
, t0
);
93 spr_store_dump_spr(sprn
);
95 spr_write_generic(ctx
, sprn
, gprn
);
99 static void spr_write_clear(DisasContext
*ctx
, int sprn
, int gprn
)
101 TCGv t0
= tcg_temp_new();
102 TCGv t1
= tcg_temp_new();
103 gen_load_spr(t0
, sprn
);
104 tcg_gen_neg_tl(t1
, cpu_gpr
[gprn
]);
105 tcg_gen_and_tl(t0
, t0
, t1
);
106 gen_store_spr(sprn
, t0
);
111 static void spr_access_nop(DisasContext
*ctx
, int sprn
, int gprn
)
117 /* SPR common to all PowerPC */
119 static void spr_read_xer(DisasContext
*ctx
, int gprn
, int sprn
)
121 gen_read_xer(ctx
, cpu_gpr
[gprn
]);
124 static void spr_write_xer(DisasContext
*ctx
, int sprn
, int gprn
)
126 gen_write_xer(cpu_gpr
[gprn
]);
130 static void spr_read_lr(DisasContext
*ctx
, int gprn
, int sprn
)
132 tcg_gen_mov_tl(cpu_gpr
[gprn
], cpu_lr
);
135 static void spr_write_lr(DisasContext
*ctx
, int sprn
, int gprn
)
137 tcg_gen_mov_tl(cpu_lr
, cpu_gpr
[gprn
]);
141 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
142 static void spr_read_cfar(DisasContext
*ctx
, int gprn
, int sprn
)
144 tcg_gen_mov_tl(cpu_gpr
[gprn
], cpu_cfar
);
147 static void spr_write_cfar(DisasContext
*ctx
, int sprn
, int gprn
)
149 tcg_gen_mov_tl(cpu_cfar
, cpu_gpr
[gprn
]);
151 #endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
154 static void spr_read_ctr(DisasContext
*ctx
, int gprn
, int sprn
)
156 tcg_gen_mov_tl(cpu_gpr
[gprn
], cpu_ctr
);
159 static void spr_write_ctr(DisasContext
*ctx
, int sprn
, int gprn
)
161 tcg_gen_mov_tl(cpu_ctr
, cpu_gpr
[gprn
]);
164 /* User read access to SPR */
170 static void spr_read_ureg(DisasContext
*ctx
, int gprn
, int sprn
)
172 gen_load_spr(cpu_gpr
[gprn
], sprn
+ 0x10);
175 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
176 static void spr_write_ureg(DisasContext
*ctx
, int sprn
, int gprn
)
178 gen_store_spr(sprn
+ 0x10, cpu_gpr
[gprn
]);
182 /* SPR common to all non-embedded PowerPC */
184 #if !defined(CONFIG_USER_ONLY)
185 static void spr_read_decr(DisasContext
*ctx
, int gprn
, int sprn
)
187 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
190 gen_helper_load_decr(cpu_gpr
[gprn
], cpu_env
);
191 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
192 gen_stop_exception(ctx
);
196 static void spr_write_decr(DisasContext
*ctx
, int sprn
, int gprn
)
198 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
201 gen_helper_store_decr(cpu_env
, cpu_gpr
[gprn
]);
202 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
203 gen_stop_exception(ctx
);
208 /* SPR common to all non-embedded PowerPC, except 601 */
210 static void spr_read_tbl(DisasContext
*ctx
, int gprn
, int sprn
)
212 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
215 gen_helper_load_tbl(cpu_gpr
[gprn
], cpu_env
);
216 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
218 gen_stop_exception(ctx
);
222 static void spr_read_tbu(DisasContext
*ctx
, int gprn
, int sprn
)
224 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
227 gen_helper_load_tbu(cpu_gpr
[gprn
], cpu_env
);
228 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
230 gen_stop_exception(ctx
);
235 static void spr_read_atbl(DisasContext
*ctx
, int gprn
, int sprn
)
237 gen_helper_load_atbl(cpu_gpr
[gprn
], cpu_env
);
241 static void spr_read_atbu(DisasContext
*ctx
, int gprn
, int sprn
)
243 gen_helper_load_atbu(cpu_gpr
[gprn
], cpu_env
);
246 #if !defined(CONFIG_USER_ONLY)
247 static void spr_write_tbl(DisasContext
*ctx
, int sprn
, int gprn
)
249 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
252 gen_helper_store_tbl(cpu_env
, cpu_gpr
[gprn
]);
253 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
255 gen_stop_exception(ctx
);
259 static void spr_write_tbu(DisasContext
*ctx
, int sprn
, int gprn
)
261 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
264 gen_helper_store_tbu(cpu_env
, cpu_gpr
[gprn
]);
265 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
267 gen_stop_exception(ctx
);
272 static void spr_write_atbl(DisasContext
*ctx
, int sprn
, int gprn
)
274 gen_helper_store_atbl(cpu_env
, cpu_gpr
[gprn
]);
278 static void spr_write_atbu(DisasContext
*ctx
, int sprn
, int gprn
)
280 gen_helper_store_atbu(cpu_env
, cpu_gpr
[gprn
]);
283 #if defined(TARGET_PPC64)
285 static void spr_read_purr(DisasContext
*ctx
, int gprn
, int sprn
)
287 gen_helper_load_purr(cpu_gpr
[gprn
], cpu_env
);
291 static void spr_read_hdecr(DisasContext
*ctx
, int gprn
, int sprn
)
293 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
296 gen_helper_load_hdecr(cpu_gpr
[gprn
], cpu_env
);
297 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
299 gen_stop_exception(ctx
);
303 static void spr_write_hdecr(DisasContext
*ctx
, int sprn
, int gprn
)
305 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
308 gen_helper_store_hdecr(cpu_env
, cpu_gpr
[gprn
]);
309 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
311 gen_stop_exception(ctx
);
318 #if !defined(CONFIG_USER_ONLY)
319 /* IBAT0U...IBAT0U */
320 /* IBAT0L...IBAT7L */
321 static void spr_read_ibat(DisasContext
*ctx
, int gprn
, int sprn
)
323 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
,
324 offsetof(CPUPPCState
,
325 IBAT
[sprn
& 1][(sprn
- SPR_IBAT0U
) / 2]));
328 static void spr_read_ibat_h(DisasContext
*ctx
, int gprn
, int sprn
)
330 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
,
331 offsetof(CPUPPCState
,
332 IBAT
[sprn
& 1][((sprn
- SPR_IBAT4U
) / 2) + 4]));
335 static void spr_write_ibatu(DisasContext
*ctx
, int sprn
, int gprn
)
337 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0U
) / 2);
338 gen_helper_store_ibatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
339 tcg_temp_free_i32(t0
);
342 static void spr_write_ibatu_h(DisasContext
*ctx
, int sprn
, int gprn
)
344 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_IBAT4U
) / 2) + 4);
345 gen_helper_store_ibatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
346 tcg_temp_free_i32(t0
);
349 static void spr_write_ibatl(DisasContext
*ctx
, int sprn
, int gprn
)
351 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0L
) / 2);
352 gen_helper_store_ibatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
353 tcg_temp_free_i32(t0
);
356 static void spr_write_ibatl_h(DisasContext
*ctx
, int sprn
, int gprn
)
358 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_IBAT4L
) / 2) + 4);
359 gen_helper_store_ibatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
360 tcg_temp_free_i32(t0
);
363 /* DBAT0U...DBAT7U */
364 /* DBAT0L...DBAT7L */
365 static void spr_read_dbat(DisasContext
*ctx
, int gprn
, int sprn
)
367 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
,
368 offsetof(CPUPPCState
,
369 DBAT
[sprn
& 1][(sprn
- SPR_DBAT0U
) / 2]));
372 static void spr_read_dbat_h(DisasContext
*ctx
, int gprn
, int sprn
)
374 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
,
375 offsetof(CPUPPCState
,
376 DBAT
[sprn
& 1][((sprn
- SPR_DBAT4U
) / 2) + 4]));
379 static void spr_write_dbatu(DisasContext
*ctx
, int sprn
, int gprn
)
381 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_DBAT0U
) / 2);
382 gen_helper_store_dbatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
383 tcg_temp_free_i32(t0
);
386 static void spr_write_dbatu_h(DisasContext
*ctx
, int sprn
, int gprn
)
388 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_DBAT4U
) / 2) + 4);
389 gen_helper_store_dbatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
390 tcg_temp_free_i32(t0
);
393 static void spr_write_dbatl(DisasContext
*ctx
, int sprn
, int gprn
)
395 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_DBAT0L
) / 2);
396 gen_helper_store_dbatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
397 tcg_temp_free_i32(t0
);
400 static void spr_write_dbatl_h(DisasContext
*ctx
, int sprn
, int gprn
)
402 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_DBAT4L
) / 2) + 4);
403 gen_helper_store_dbatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
404 tcg_temp_free_i32(t0
);
408 static void spr_write_sdr1(DisasContext
*ctx
, int sprn
, int gprn
)
410 gen_helper_store_sdr1(cpu_env
, cpu_gpr
[gprn
]);
413 #if defined(TARGET_PPC64)
414 /* 64 bits PowerPC specific SPRs */
416 static void spr_write_pidr(DisasContext
*ctx
, int sprn
, int gprn
)
418 gen_helper_store_pidr(cpu_env
, cpu_gpr
[gprn
]);
421 static void spr_write_lpidr(DisasContext
*ctx
, int sprn
, int gprn
)
423 gen_helper_store_lpidr(cpu_env
, cpu_gpr
[gprn
]);
426 static void spr_read_hior(DisasContext
*ctx
, int gprn
, int sprn
)
428 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, excp_prefix
));
431 static void spr_write_hior(DisasContext
*ctx
, int sprn
, int gprn
)
433 TCGv t0
= tcg_temp_new();
434 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], 0x3FFFFF00000ULL
);
435 tcg_gen_st_tl(t0
, cpu_env
, offsetof(CPUPPCState
, excp_prefix
));
438 static void spr_write_ptcr(DisasContext
*ctx
, int sprn
, int gprn
)
440 gen_helper_store_ptcr(cpu_env
, cpu_gpr
[gprn
]);
443 static void spr_write_pcr(DisasContext
*ctx
, int sprn
, int gprn
)
445 gen_helper_store_pcr(cpu_env
, cpu_gpr
[gprn
]);
450 /* PowerPC 601 specific registers */
452 static void spr_read_601_rtcl(DisasContext
*ctx
, int gprn
, int sprn
)
454 gen_helper_load_601_rtcl(cpu_gpr
[gprn
], cpu_env
);
457 static void spr_read_601_rtcu(DisasContext
*ctx
, int gprn
, int sprn
)
459 gen_helper_load_601_rtcu(cpu_gpr
[gprn
], cpu_env
);
462 #if !defined(CONFIG_USER_ONLY)
463 static void spr_write_601_rtcu(DisasContext
*ctx
, int sprn
, int gprn
)
465 gen_helper_store_601_rtcu(cpu_env
, cpu_gpr
[gprn
]);
468 static void spr_write_601_rtcl(DisasContext
*ctx
, int sprn
, int gprn
)
470 gen_helper_store_601_rtcl(cpu_env
, cpu_gpr
[gprn
]);
473 static void spr_write_hid0_601(DisasContext
*ctx
, int sprn
, int gprn
)
475 gen_helper_store_hid0_601(cpu_env
, cpu_gpr
[gprn
]);
476 /* Must stop the translation as endianness may have changed */
477 gen_stop_exception(ctx
);
482 #if !defined(CONFIG_USER_ONLY)
483 static void spr_read_601_ubat(DisasContext
*ctx
, int gprn
, int sprn
)
485 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
,
486 offsetof(CPUPPCState
,
487 IBAT
[sprn
& 1][(sprn
- SPR_IBAT0U
) / 2]));
490 static void spr_write_601_ubatu(DisasContext
*ctx
, int sprn
, int gprn
)
492 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0U
) / 2);
493 gen_helper_store_601_batl(cpu_env
, t0
, cpu_gpr
[gprn
]);
494 tcg_temp_free_i32(t0
);
497 static void spr_write_601_ubatl(DisasContext
*ctx
, int sprn
, int gprn
)
499 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0U
) / 2);
500 gen_helper_store_601_batu(cpu_env
, t0
, cpu_gpr
[gprn
]);
501 tcg_temp_free_i32(t0
);
505 /* PowerPC 40x specific registers */
506 #if !defined(CONFIG_USER_ONLY)
507 static void spr_read_40x_pit(DisasContext
*ctx
, int gprn
, int sprn
)
509 gen_helper_load_40x_pit(cpu_gpr
[gprn
], cpu_env
);
512 static void spr_write_40x_pit(DisasContext
*ctx
, int sprn
, int gprn
)
514 gen_helper_store_40x_pit(cpu_env
, cpu_gpr
[gprn
]);
517 static void spr_write_40x_dbcr0(DisasContext
*ctx
, int sprn
, int gprn
)
519 gen_store_spr(sprn
, cpu_gpr
[gprn
]);
520 gen_helper_store_40x_dbcr0(cpu_env
, cpu_gpr
[gprn
]);
521 /* We must stop translation as we may have rebooted */
522 gen_stop_exception(ctx
);
525 static void spr_write_40x_sler(DisasContext
*ctx
, int sprn
, int gprn
)
527 gen_helper_store_40x_sler(cpu_env
, cpu_gpr
[gprn
]);
530 static void spr_write_booke_tcr(DisasContext
*ctx
, int sprn
, int gprn
)
532 gen_helper_store_booke_tcr(cpu_env
, cpu_gpr
[gprn
]);
535 static void spr_write_booke_tsr(DisasContext
*ctx
, int sprn
, int gprn
)
537 gen_helper_store_booke_tsr(cpu_env
, cpu_gpr
[gprn
]);
541 /* PowerPC 403 specific registers */
542 /* PBL1 / PBU1 / PBL2 / PBU2 */
543 #if !defined(CONFIG_USER_ONLY)
544 static void spr_read_403_pbr(DisasContext
*ctx
, int gprn
, int sprn
)
546 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
,
547 offsetof(CPUPPCState
, pb
[sprn
- SPR_403_PBL1
]));
550 static void spr_write_403_pbr(DisasContext
*ctx
, int sprn
, int gprn
)
552 TCGv_i32 t0
= tcg_const_i32(sprn
- SPR_403_PBL1
);
553 gen_helper_store_403_pbr(cpu_env
, t0
, cpu_gpr
[gprn
]);
554 tcg_temp_free_i32(t0
);
557 static void spr_write_pir(DisasContext
*ctx
, int sprn
, int gprn
)
559 TCGv t0
= tcg_temp_new();
560 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], 0xF);
561 gen_store_spr(SPR_PIR
, t0
);
566 /* SPE specific registers */
567 static void spr_read_spefscr(DisasContext
*ctx
, int gprn
, int sprn
)
569 TCGv_i32 t0
= tcg_temp_new_i32();
570 tcg_gen_ld_i32(t0
, cpu_env
, offsetof(CPUPPCState
, spe_fscr
));
571 tcg_gen_extu_i32_tl(cpu_gpr
[gprn
], t0
);
572 tcg_temp_free_i32(t0
);
575 static void spr_write_spefscr(DisasContext
*ctx
, int sprn
, int gprn
)
577 TCGv_i32 t0
= tcg_temp_new_i32();
578 tcg_gen_trunc_tl_i32(t0
, cpu_gpr
[gprn
]);
579 tcg_gen_st_i32(t0
, cpu_env
, offsetof(CPUPPCState
, spe_fscr
));
580 tcg_temp_free_i32(t0
);
583 #if !defined(CONFIG_USER_ONLY)
584 /* Callback used to write the exception vector base */
585 static void spr_write_excp_prefix(DisasContext
*ctx
, int sprn
, int gprn
)
587 TCGv t0
= tcg_temp_new();
588 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUPPCState
, ivpr_mask
));
589 tcg_gen_and_tl(t0
, t0
, cpu_gpr
[gprn
]);
590 tcg_gen_st_tl(t0
, cpu_env
, offsetof(CPUPPCState
, excp_prefix
));
591 gen_store_spr(sprn
, t0
);
595 static void spr_write_excp_vector(DisasContext
*ctx
, int sprn
, int gprn
)
599 if (sprn
>= SPR_BOOKE_IVOR0
&& sprn
<= SPR_BOOKE_IVOR15
) {
600 sprn_offs
= sprn
- SPR_BOOKE_IVOR0
;
601 } else if (sprn
>= SPR_BOOKE_IVOR32
&& sprn
<= SPR_BOOKE_IVOR37
) {
602 sprn_offs
= sprn
- SPR_BOOKE_IVOR32
+ 32;
603 } else if (sprn
>= SPR_BOOKE_IVOR38
&& sprn
<= SPR_BOOKE_IVOR42
) {
604 sprn_offs
= sprn
- SPR_BOOKE_IVOR38
+ 38;
606 printf("Trying to write an unknown exception vector %d %03x\n",
608 gen_inval_exception(ctx
, POWERPC_EXCP_PRIV_REG
);
612 TCGv t0
= tcg_temp_new();
613 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUPPCState
, ivor_mask
));
614 tcg_gen_and_tl(t0
, t0
, cpu_gpr
[gprn
]);
615 tcg_gen_st_tl(t0
, cpu_env
, offsetof(CPUPPCState
, excp_vectors
[sprn_offs
]));
616 gen_store_spr(sprn
, t0
);
621 static inline void vscr_init(CPUPPCState
*env
, uint32_t val
)
623 /* Altivec always uses round-to-nearest */
624 set_float_rounding_mode(float_round_nearest_even
, &env
->vec_status
);
625 helper_mtvscr(env
, val
);
628 #ifdef CONFIG_USER_ONLY
629 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
630 oea_read, oea_write, one_reg_id, initial_value) \
631 _spr_register(env, num, name, uea_read, uea_write, initial_value)
632 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
633 oea_read, oea_write, hea_read, hea_write, \
634 one_reg_id, initial_value) \
635 _spr_register(env, num, name, uea_read, uea_write, initial_value)
637 #if !defined(CONFIG_KVM)
638 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
639 oea_read, oea_write, one_reg_id, initial_value) \
640 _spr_register(env, num, name, uea_read, uea_write, \
641 oea_read, oea_write, oea_read, oea_write, initial_value)
642 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
643 oea_read, oea_write, hea_read, hea_write, \
644 one_reg_id, initial_value) \
645 _spr_register(env, num, name, uea_read, uea_write, \
646 oea_read, oea_write, hea_read, hea_write, initial_value)
648 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
649 oea_read, oea_write, one_reg_id, initial_value) \
650 _spr_register(env, num, name, uea_read, uea_write, \
651 oea_read, oea_write, oea_read, oea_write, \
652 one_reg_id, initial_value)
653 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
654 oea_read, oea_write, hea_read, hea_write, \
655 one_reg_id, initial_value) \
656 _spr_register(env, num, name, uea_read, uea_write, \
657 oea_read, oea_write, hea_read, hea_write, \
658 one_reg_id, initial_value)
662 #define spr_register(env, num, name, uea_read, uea_write, \
663 oea_read, oea_write, initial_value) \
664 spr_register_kvm(env, num, name, uea_read, uea_write, \
665 oea_read, oea_write, 0, initial_value)
667 #define spr_register_hv(env, num, name, uea_read, uea_write, \
668 oea_read, oea_write, hea_read, hea_write, \
670 spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
671 oea_read, oea_write, hea_read, hea_write, \
674 static inline void _spr_register(CPUPPCState
*env
, int num
,
676 void (*uea_read
)(DisasContext
*ctx
,
678 void (*uea_write
)(DisasContext
*ctx
,
680 #if !defined(CONFIG_USER_ONLY)
682 void (*oea_read
)(DisasContext
*ctx
,
684 void (*oea_write
)(DisasContext
*ctx
,
686 void (*hea_read
)(DisasContext
*opaque
,
688 void (*hea_write
)(DisasContext
*opaque
,
691 #if defined(CONFIG_KVM)
694 target_ulong initial_value
)
698 spr
= &env
->spr_cb
[num
];
699 if (spr
->name
!= NULL
|| env
->spr
[num
] != 0x00000000 ||
700 #if !defined(CONFIG_USER_ONLY)
701 spr
->oea_read
!= NULL
|| spr
->oea_write
!= NULL
||
703 spr
->uea_read
!= NULL
|| spr
->uea_write
!= NULL
) {
704 printf("Error: Trying to register SPR %d (%03x) twice !\n", num
, num
);
707 #if defined(PPC_DEBUG_SPR)
708 printf("*** register spr %d (%03x) %s val " TARGET_FMT_lx
"\n", num
, num
,
709 name
, initial_value
);
712 spr
->uea_read
= uea_read
;
713 spr
->uea_write
= uea_write
;
714 #if !defined(CONFIG_USER_ONLY)
715 spr
->oea_read
= oea_read
;
716 spr
->oea_write
= oea_write
;
717 spr
->hea_read
= hea_read
;
718 spr
->hea_write
= hea_write
;
720 #if defined(CONFIG_KVM)
721 spr
->one_reg_id
= one_reg_id
,
723 env
->spr
[num
] = spr
->default_value
= initial_value
;
726 /* Generic PowerPC SPRs */
727 static void gen_spr_generic(CPUPPCState
*env
)
729 /* Integer processing */
730 spr_register(env
, SPR_XER
, "XER",
731 &spr_read_xer
, &spr_write_xer
,
732 &spr_read_xer
, &spr_write_xer
,
735 spr_register(env
, SPR_LR
, "LR",
736 &spr_read_lr
, &spr_write_lr
,
737 &spr_read_lr
, &spr_write_lr
,
739 spr_register(env
, SPR_CTR
, "CTR",
740 &spr_read_ctr
, &spr_write_ctr
,
741 &spr_read_ctr
, &spr_write_ctr
,
743 /* Interrupt processing */
744 spr_register(env
, SPR_SRR0
, "SRR0",
745 SPR_NOACCESS
, SPR_NOACCESS
,
746 &spr_read_generic
, &spr_write_generic
,
748 spr_register(env
, SPR_SRR1
, "SRR1",
749 SPR_NOACCESS
, SPR_NOACCESS
,
750 &spr_read_generic
, &spr_write_generic
,
752 /* Processor control */
753 spr_register(env
, SPR_SPRG0
, "SPRG0",
754 SPR_NOACCESS
, SPR_NOACCESS
,
755 &spr_read_generic
, &spr_write_generic
,
757 spr_register(env
, SPR_SPRG1
, "SPRG1",
758 SPR_NOACCESS
, SPR_NOACCESS
,
759 &spr_read_generic
, &spr_write_generic
,
761 spr_register(env
, SPR_SPRG2
, "SPRG2",
762 SPR_NOACCESS
, SPR_NOACCESS
,
763 &spr_read_generic
, &spr_write_generic
,
765 spr_register(env
, SPR_SPRG3
, "SPRG3",
766 SPR_NOACCESS
, SPR_NOACCESS
,
767 &spr_read_generic
, &spr_write_generic
,
771 /* SPR common to all non-embedded PowerPC, including 601 */
772 static void gen_spr_ne_601(CPUPPCState
*env
)
774 /* Exception processing */
775 spr_register_kvm(env
, SPR_DSISR
, "DSISR",
776 SPR_NOACCESS
, SPR_NOACCESS
,
777 &spr_read_generic
, &spr_write_generic
,
778 KVM_REG_PPC_DSISR
, 0x00000000);
779 spr_register_kvm(env
, SPR_DAR
, "DAR",
780 SPR_NOACCESS
, SPR_NOACCESS
,
781 &spr_read_generic
, &spr_write_generic
,
782 KVM_REG_PPC_DAR
, 0x00000000);
784 spr_register(env
, SPR_DECR
, "DECR",
785 SPR_NOACCESS
, SPR_NOACCESS
,
786 &spr_read_decr
, &spr_write_decr
,
790 /* Storage Description Register 1 */
791 static void gen_spr_sdr1(CPUPPCState
*env
)
793 #ifndef CONFIG_USER_ONLY
794 if (env
->has_hv_mode
) {
796 * SDR1 is a hypervisor resource on CPUs which have a
799 spr_register_hv(env
, SPR_SDR1
, "SDR1",
800 SPR_NOACCESS
, SPR_NOACCESS
,
801 SPR_NOACCESS
, SPR_NOACCESS
,
802 &spr_read_generic
, &spr_write_sdr1
,
805 spr_register(env
, SPR_SDR1
, "SDR1",
806 SPR_NOACCESS
, SPR_NOACCESS
,
807 &spr_read_generic
, &spr_write_sdr1
,
814 static void gen_low_BATs(CPUPPCState
*env
)
816 #if !defined(CONFIG_USER_ONLY)
817 spr_register(env
, SPR_IBAT0U
, "IBAT0U",
818 SPR_NOACCESS
, SPR_NOACCESS
,
819 &spr_read_ibat
, &spr_write_ibatu
,
821 spr_register(env
, SPR_IBAT0L
, "IBAT0L",
822 SPR_NOACCESS
, SPR_NOACCESS
,
823 &spr_read_ibat
, &spr_write_ibatl
,
825 spr_register(env
, SPR_IBAT1U
, "IBAT1U",
826 SPR_NOACCESS
, SPR_NOACCESS
,
827 &spr_read_ibat
, &spr_write_ibatu
,
829 spr_register(env
, SPR_IBAT1L
, "IBAT1L",
830 SPR_NOACCESS
, SPR_NOACCESS
,
831 &spr_read_ibat
, &spr_write_ibatl
,
833 spr_register(env
, SPR_IBAT2U
, "IBAT2U",
834 SPR_NOACCESS
, SPR_NOACCESS
,
835 &spr_read_ibat
, &spr_write_ibatu
,
837 spr_register(env
, SPR_IBAT2L
, "IBAT2L",
838 SPR_NOACCESS
, SPR_NOACCESS
,
839 &spr_read_ibat
, &spr_write_ibatl
,
841 spr_register(env
, SPR_IBAT3U
, "IBAT3U",
842 SPR_NOACCESS
, SPR_NOACCESS
,
843 &spr_read_ibat
, &spr_write_ibatu
,
845 spr_register(env
, SPR_IBAT3L
, "IBAT3L",
846 SPR_NOACCESS
, SPR_NOACCESS
,
847 &spr_read_ibat
, &spr_write_ibatl
,
849 spr_register(env
, SPR_DBAT0U
, "DBAT0U",
850 SPR_NOACCESS
, SPR_NOACCESS
,
851 &spr_read_dbat
, &spr_write_dbatu
,
853 spr_register(env
, SPR_DBAT0L
, "DBAT0L",
854 SPR_NOACCESS
, SPR_NOACCESS
,
855 &spr_read_dbat
, &spr_write_dbatl
,
857 spr_register(env
, SPR_DBAT1U
, "DBAT1U",
858 SPR_NOACCESS
, SPR_NOACCESS
,
859 &spr_read_dbat
, &spr_write_dbatu
,
861 spr_register(env
, SPR_DBAT1L
, "DBAT1L",
862 SPR_NOACCESS
, SPR_NOACCESS
,
863 &spr_read_dbat
, &spr_write_dbatl
,
865 spr_register(env
, SPR_DBAT2U
, "DBAT2U",
866 SPR_NOACCESS
, SPR_NOACCESS
,
867 &spr_read_dbat
, &spr_write_dbatu
,
869 spr_register(env
, SPR_DBAT2L
, "DBAT2L",
870 SPR_NOACCESS
, SPR_NOACCESS
,
871 &spr_read_dbat
, &spr_write_dbatl
,
873 spr_register(env
, SPR_DBAT3U
, "DBAT3U",
874 SPR_NOACCESS
, SPR_NOACCESS
,
875 &spr_read_dbat
, &spr_write_dbatu
,
877 spr_register(env
, SPR_DBAT3L
, "DBAT3L",
878 SPR_NOACCESS
, SPR_NOACCESS
,
879 &spr_read_dbat
, &spr_write_dbatl
,
886 static void gen_high_BATs(CPUPPCState
*env
)
888 #if !defined(CONFIG_USER_ONLY)
889 spr_register(env
, SPR_IBAT4U
, "IBAT4U",
890 SPR_NOACCESS
, SPR_NOACCESS
,
891 &spr_read_ibat_h
, &spr_write_ibatu_h
,
893 spr_register(env
, SPR_IBAT4L
, "IBAT4L",
894 SPR_NOACCESS
, SPR_NOACCESS
,
895 &spr_read_ibat_h
, &spr_write_ibatl_h
,
897 spr_register(env
, SPR_IBAT5U
, "IBAT5U",
898 SPR_NOACCESS
, SPR_NOACCESS
,
899 &spr_read_ibat_h
, &spr_write_ibatu_h
,
901 spr_register(env
, SPR_IBAT5L
, "IBAT5L",
902 SPR_NOACCESS
, SPR_NOACCESS
,
903 &spr_read_ibat_h
, &spr_write_ibatl_h
,
905 spr_register(env
, SPR_IBAT6U
, "IBAT6U",
906 SPR_NOACCESS
, SPR_NOACCESS
,
907 &spr_read_ibat_h
, &spr_write_ibatu_h
,
909 spr_register(env
, SPR_IBAT6L
, "IBAT6L",
910 SPR_NOACCESS
, SPR_NOACCESS
,
911 &spr_read_ibat_h
, &spr_write_ibatl_h
,
913 spr_register(env
, SPR_IBAT7U
, "IBAT7U",
914 SPR_NOACCESS
, SPR_NOACCESS
,
915 &spr_read_ibat_h
, &spr_write_ibatu_h
,
917 spr_register(env
, SPR_IBAT7L
, "IBAT7L",
918 SPR_NOACCESS
, SPR_NOACCESS
,
919 &spr_read_ibat_h
, &spr_write_ibatl_h
,
921 spr_register(env
, SPR_DBAT4U
, "DBAT4U",
922 SPR_NOACCESS
, SPR_NOACCESS
,
923 &spr_read_dbat_h
, &spr_write_dbatu_h
,
925 spr_register(env
, SPR_DBAT4L
, "DBAT4L",
926 SPR_NOACCESS
, SPR_NOACCESS
,
927 &spr_read_dbat_h
, &spr_write_dbatl_h
,
929 spr_register(env
, SPR_DBAT5U
, "DBAT5U",
930 SPR_NOACCESS
, SPR_NOACCESS
,
931 &spr_read_dbat_h
, &spr_write_dbatu_h
,
933 spr_register(env
, SPR_DBAT5L
, "DBAT5L",
934 SPR_NOACCESS
, SPR_NOACCESS
,
935 &spr_read_dbat_h
, &spr_write_dbatl_h
,
937 spr_register(env
, SPR_DBAT6U
, "DBAT6U",
938 SPR_NOACCESS
, SPR_NOACCESS
,
939 &spr_read_dbat_h
, &spr_write_dbatu_h
,
941 spr_register(env
, SPR_DBAT6L
, "DBAT6L",
942 SPR_NOACCESS
, SPR_NOACCESS
,
943 &spr_read_dbat_h
, &spr_write_dbatl_h
,
945 spr_register(env
, SPR_DBAT7U
, "DBAT7U",
946 SPR_NOACCESS
, SPR_NOACCESS
,
947 &spr_read_dbat_h
, &spr_write_dbatu_h
,
949 spr_register(env
, SPR_DBAT7L
, "DBAT7L",
950 SPR_NOACCESS
, SPR_NOACCESS
,
951 &spr_read_dbat_h
, &spr_write_dbatl_h
,
957 /* Generic PowerPC time base */
958 static void gen_tbl(CPUPPCState
*env
)
960 spr_register(env
, SPR_VTBL
, "TBL",
961 &spr_read_tbl
, SPR_NOACCESS
,
962 &spr_read_tbl
, SPR_NOACCESS
,
964 spr_register(env
, SPR_TBL
, "TBL",
965 &spr_read_tbl
, SPR_NOACCESS
,
966 &spr_read_tbl
, &spr_write_tbl
,
968 spr_register(env
, SPR_VTBU
, "TBU",
969 &spr_read_tbu
, SPR_NOACCESS
,
970 &spr_read_tbu
, SPR_NOACCESS
,
972 spr_register(env
, SPR_TBU
, "TBU",
973 &spr_read_tbu
, SPR_NOACCESS
,
974 &spr_read_tbu
, &spr_write_tbu
,
978 /* Softare table search registers */
979 static void gen_6xx_7xx_soft_tlb(CPUPPCState
*env
, int nb_tlbs
, int nb_ways
)
981 #if !defined(CONFIG_USER_ONLY)
982 env
->nb_tlb
= nb_tlbs
;
983 env
->nb_ways
= nb_ways
;
985 env
->tlb_type
= TLB_6XX
;
986 spr_register(env
, SPR_DMISS
, "DMISS",
987 SPR_NOACCESS
, SPR_NOACCESS
,
988 &spr_read_generic
, SPR_NOACCESS
,
990 spr_register(env
, SPR_DCMP
, "DCMP",
991 SPR_NOACCESS
, SPR_NOACCESS
,
992 &spr_read_generic
, SPR_NOACCESS
,
994 spr_register(env
, SPR_HASH1
, "HASH1",
995 SPR_NOACCESS
, SPR_NOACCESS
,
996 &spr_read_generic
, SPR_NOACCESS
,
998 spr_register(env
, SPR_HASH2
, "HASH2",
999 SPR_NOACCESS
, SPR_NOACCESS
,
1000 &spr_read_generic
, SPR_NOACCESS
,
1002 spr_register(env
, SPR_IMISS
, "IMISS",
1003 SPR_NOACCESS
, SPR_NOACCESS
,
1004 &spr_read_generic
, SPR_NOACCESS
,
1006 spr_register(env
, SPR_ICMP
, "ICMP",
1007 SPR_NOACCESS
, SPR_NOACCESS
,
1008 &spr_read_generic
, SPR_NOACCESS
,
1010 spr_register(env
, SPR_RPA
, "RPA",
1011 SPR_NOACCESS
, SPR_NOACCESS
,
1012 &spr_read_generic
, &spr_write_generic
,
1017 /* SPR common to MPC755 and G2 */
1018 static void gen_spr_G2_755(CPUPPCState
*env
)
1021 spr_register(env
, SPR_SPRG4
, "SPRG4",
1022 SPR_NOACCESS
, SPR_NOACCESS
,
1023 &spr_read_generic
, &spr_write_generic
,
1025 spr_register(env
, SPR_SPRG5
, "SPRG5",
1026 SPR_NOACCESS
, SPR_NOACCESS
,
1027 &spr_read_generic
, &spr_write_generic
,
1029 spr_register(env
, SPR_SPRG6
, "SPRG6",
1030 SPR_NOACCESS
, SPR_NOACCESS
,
1031 &spr_read_generic
, &spr_write_generic
,
1033 spr_register(env
, SPR_SPRG7
, "SPRG7",
1034 SPR_NOACCESS
, SPR_NOACCESS
,
1035 &spr_read_generic
, &spr_write_generic
,
1039 /* SPR common to all 7xx PowerPC implementations */
1040 static void gen_spr_7xx(CPUPPCState
*env
)
1043 /* XXX : not implemented */
1044 spr_register_kvm(env
, SPR_DABR
, "DABR",
1045 SPR_NOACCESS
, SPR_NOACCESS
,
1046 &spr_read_generic
, &spr_write_generic
,
1047 KVM_REG_PPC_DABR
, 0x00000000);
1048 /* XXX : not implemented */
1049 spr_register(env
, SPR_IABR
, "IABR",
1050 SPR_NOACCESS
, SPR_NOACCESS
,
1051 &spr_read_generic
, &spr_write_generic
,
1053 /* Cache management */
1054 /* XXX : not implemented */
1055 spr_register(env
, SPR_ICTC
, "ICTC",
1056 SPR_NOACCESS
, SPR_NOACCESS
,
1057 &spr_read_generic
, &spr_write_generic
,
1059 /* Performance monitors */
1060 /* XXX : not implemented */
1061 spr_register(env
, SPR_7XX_MMCR0
, "MMCR0",
1062 SPR_NOACCESS
, SPR_NOACCESS
,
1063 &spr_read_generic
, &spr_write_generic
,
1065 /* XXX : not implemented */
1066 spr_register(env
, SPR_7XX_MMCR1
, "MMCR1",
1067 SPR_NOACCESS
, SPR_NOACCESS
,
1068 &spr_read_generic
, &spr_write_generic
,
1070 /* XXX : not implemented */
1071 spr_register(env
, SPR_7XX_PMC1
, "PMC1",
1072 SPR_NOACCESS
, SPR_NOACCESS
,
1073 &spr_read_generic
, &spr_write_generic
,
1075 /* XXX : not implemented */
1076 spr_register(env
, SPR_7XX_PMC2
, "PMC2",
1077 SPR_NOACCESS
, SPR_NOACCESS
,
1078 &spr_read_generic
, &spr_write_generic
,
1080 /* XXX : not implemented */
1081 spr_register(env
, SPR_7XX_PMC3
, "PMC3",
1082 SPR_NOACCESS
, SPR_NOACCESS
,
1083 &spr_read_generic
, &spr_write_generic
,
1085 /* XXX : not implemented */
1086 spr_register(env
, SPR_7XX_PMC4
, "PMC4",
1087 SPR_NOACCESS
, SPR_NOACCESS
,
1088 &spr_read_generic
, &spr_write_generic
,
1090 /* XXX : not implemented */
1091 spr_register(env
, SPR_7XX_SIAR
, "SIAR",
1092 SPR_NOACCESS
, SPR_NOACCESS
,
1093 &spr_read_generic
, SPR_NOACCESS
,
1095 /* XXX : not implemented */
1096 spr_register(env
, SPR_7XX_UMMCR0
, "UMMCR0",
1097 &spr_read_ureg
, SPR_NOACCESS
,
1098 &spr_read_ureg
, SPR_NOACCESS
,
1100 /* XXX : not implemented */
1101 spr_register(env
, SPR_7XX_UMMCR1
, "UMMCR1",
1102 &spr_read_ureg
, SPR_NOACCESS
,
1103 &spr_read_ureg
, SPR_NOACCESS
,
1105 /* XXX : not implemented */
1106 spr_register(env
, SPR_7XX_UPMC1
, "UPMC1",
1107 &spr_read_ureg
, SPR_NOACCESS
,
1108 &spr_read_ureg
, SPR_NOACCESS
,
1110 /* XXX : not implemented */
1111 spr_register(env
, SPR_7XX_UPMC2
, "UPMC2",
1112 &spr_read_ureg
, SPR_NOACCESS
,
1113 &spr_read_ureg
, SPR_NOACCESS
,
1115 /* XXX : not implemented */
1116 spr_register(env
, SPR_7XX_UPMC3
, "UPMC3",
1117 &spr_read_ureg
, SPR_NOACCESS
,
1118 &spr_read_ureg
, SPR_NOACCESS
,
1120 /* XXX : not implemented */
1121 spr_register(env
, SPR_7XX_UPMC4
, "UPMC4",
1122 &spr_read_ureg
, SPR_NOACCESS
,
1123 &spr_read_ureg
, SPR_NOACCESS
,
1125 /* XXX : not implemented */
1126 spr_register(env
, SPR_7XX_USIAR
, "USIAR",
1127 &spr_read_ureg
, SPR_NOACCESS
,
1128 &spr_read_ureg
, SPR_NOACCESS
,
1130 /* External access control */
1131 /* XXX : not implemented */
1132 spr_register(env
, SPR_EAR
, "EAR",
1133 SPR_NOACCESS
, SPR_NOACCESS
,
1134 &spr_read_generic
, &spr_write_generic
,
1139 #ifndef CONFIG_USER_ONLY
1140 static void spr_write_amr(DisasContext
*ctx
, int sprn
, int gprn
)
1142 TCGv t0
= tcg_temp_new();
1143 TCGv t1
= tcg_temp_new();
1144 TCGv t2
= tcg_temp_new();
1147 * Note, the HV=1 PR=0 case is handled earlier by simply using
1148 * spr_write_generic for HV mode in the SPR table
1151 /* Build insertion mask into t1 based on context */
1153 gen_load_spr(t1
, SPR_UAMOR
);
1155 gen_load_spr(t1
, SPR_AMOR
);
1158 /* Mask new bits into t2 */
1159 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1161 /* Load AMR and clear new bits in t0 */
1162 gen_load_spr(t0
, SPR_AMR
);
1163 tcg_gen_andc_tl(t0
, t0
, t1
);
1165 /* Or'in new bits and write it out */
1166 tcg_gen_or_tl(t0
, t0
, t2
);
1167 gen_store_spr(SPR_AMR
, t0
);
1168 spr_store_dump_spr(SPR_AMR
);
1175 static void spr_write_uamor(DisasContext
*ctx
, int sprn
, int gprn
)
1177 TCGv t0
= tcg_temp_new();
1178 TCGv t1
= tcg_temp_new();
1179 TCGv t2
= tcg_temp_new();
1182 * Note, the HV=1 case is handled earlier by simply using
1183 * spr_write_generic for HV mode in the SPR table
1186 /* Build insertion mask into t1 based on context */
1187 gen_load_spr(t1
, SPR_AMOR
);
1189 /* Mask new bits into t2 */
1190 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1192 /* Load AMR and clear new bits in t0 */
1193 gen_load_spr(t0
, SPR_UAMOR
);
1194 tcg_gen_andc_tl(t0
, t0
, t1
);
1196 /* Or'in new bits and write it out */
1197 tcg_gen_or_tl(t0
, t0
, t2
);
1198 gen_store_spr(SPR_UAMOR
, t0
);
1199 spr_store_dump_spr(SPR_UAMOR
);
1206 static void spr_write_iamr(DisasContext
*ctx
, int sprn
, int gprn
)
1208 TCGv t0
= tcg_temp_new();
1209 TCGv t1
= tcg_temp_new();
1210 TCGv t2
= tcg_temp_new();
1213 * Note, the HV=1 case is handled earlier by simply using
1214 * spr_write_generic for HV mode in the SPR table
1217 /* Build insertion mask into t1 based on context */
1218 gen_load_spr(t1
, SPR_AMOR
);
1220 /* Mask new bits into t2 */
1221 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1223 /* Load AMR and clear new bits in t0 */
1224 gen_load_spr(t0
, SPR_IAMR
);
1225 tcg_gen_andc_tl(t0
, t0
, t1
);
1227 /* Or'in new bits and write it out */
1228 tcg_gen_or_tl(t0
, t0
, t2
);
1229 gen_store_spr(SPR_IAMR
, t0
);
1230 spr_store_dump_spr(SPR_IAMR
);
1236 #endif /* CONFIG_USER_ONLY */
1238 static void gen_spr_amr(CPUPPCState
*env
)
1240 #ifndef CONFIG_USER_ONLY
1242 * Virtual Page Class Key protection
1244 * The AMR is accessible either via SPR 13 or SPR 29. 13 is
1245 * userspace accessible, 29 is privileged. So we only need to set
1246 * the kvm ONE_REG id on one of them, we use 29
1248 spr_register(env
, SPR_UAMR
, "UAMR",
1249 &spr_read_generic
, &spr_write_amr
,
1250 &spr_read_generic
, &spr_write_amr
,
1252 spr_register_kvm_hv(env
, SPR_AMR
, "AMR",
1253 SPR_NOACCESS
, SPR_NOACCESS
,
1254 &spr_read_generic
, &spr_write_amr
,
1255 &spr_read_generic
, &spr_write_generic
,
1256 KVM_REG_PPC_AMR
, 0);
1257 spr_register_kvm_hv(env
, SPR_UAMOR
, "UAMOR",
1258 SPR_NOACCESS
, SPR_NOACCESS
,
1259 &spr_read_generic
, &spr_write_uamor
,
1260 &spr_read_generic
, &spr_write_generic
,
1261 KVM_REG_PPC_UAMOR
, 0);
1262 spr_register_hv(env
, SPR_AMOR
, "AMOR",
1263 SPR_NOACCESS
, SPR_NOACCESS
,
1264 SPR_NOACCESS
, SPR_NOACCESS
,
1265 &spr_read_generic
, &spr_write_generic
,
1267 #endif /* !CONFIG_USER_ONLY */
1270 static void gen_spr_iamr(CPUPPCState
*env
)
1272 #ifndef CONFIG_USER_ONLY
1273 spr_register_kvm_hv(env
, SPR_IAMR
, "IAMR",
1274 SPR_NOACCESS
, SPR_NOACCESS
,
1275 &spr_read_generic
, &spr_write_iamr
,
1276 &spr_read_generic
, &spr_write_generic
,
1277 KVM_REG_PPC_IAMR
, 0);
1278 #endif /* !CONFIG_USER_ONLY */
1280 #endif /* TARGET_PPC64 */
1282 #ifndef CONFIG_USER_ONLY
1283 static void spr_read_thrm(DisasContext
*ctx
, int gprn
, int sprn
)
1285 gen_helper_fixup_thrm(cpu_env
);
1286 gen_load_spr(cpu_gpr
[gprn
], sprn
);
1287 spr_load_dump_spr(sprn
);
1289 #endif /* !CONFIG_USER_ONLY */
1291 static void gen_spr_thrm(CPUPPCState
*env
)
1293 /* Thermal management */
1294 /* XXX : not implemented */
1295 spr_register(env
, SPR_THRM1
, "THRM1",
1296 SPR_NOACCESS
, SPR_NOACCESS
,
1297 &spr_read_thrm
, &spr_write_generic
,
1299 /* XXX : not implemented */
1300 spr_register(env
, SPR_THRM2
, "THRM2",
1301 SPR_NOACCESS
, SPR_NOACCESS
,
1302 &spr_read_thrm
, &spr_write_generic
,
1304 /* XXX : not implemented */
1305 spr_register(env
, SPR_THRM3
, "THRM3",
1306 SPR_NOACCESS
, SPR_NOACCESS
,
1307 &spr_read_thrm
, &spr_write_generic
,
1311 /* SPR specific to PowerPC 604 implementation */
1312 static void gen_spr_604(CPUPPCState
*env
)
1314 /* Processor identification */
1315 spr_register(env
, SPR_PIR
, "PIR",
1316 SPR_NOACCESS
, SPR_NOACCESS
,
1317 &spr_read_generic
, &spr_write_pir
,
1320 /* XXX : not implemented */
1321 spr_register(env
, SPR_IABR
, "IABR",
1322 SPR_NOACCESS
, SPR_NOACCESS
,
1323 &spr_read_generic
, &spr_write_generic
,
1325 /* XXX : not implemented */
1326 spr_register_kvm(env
, SPR_DABR
, "DABR",
1327 SPR_NOACCESS
, SPR_NOACCESS
,
1328 &spr_read_generic
, &spr_write_generic
,
1329 KVM_REG_PPC_DABR
, 0x00000000);
1330 /* Performance counters */
1331 /* XXX : not implemented */
1332 spr_register(env
, SPR_7XX_MMCR0
, "MMCR0",
1333 SPR_NOACCESS
, SPR_NOACCESS
,
1334 &spr_read_generic
, &spr_write_generic
,
1336 /* XXX : not implemented */
1337 spr_register(env
, SPR_7XX_PMC1
, "PMC1",
1338 SPR_NOACCESS
, SPR_NOACCESS
,
1339 &spr_read_generic
, &spr_write_generic
,
1341 /* XXX : not implemented */
1342 spr_register(env
, SPR_7XX_PMC2
, "PMC2",
1343 SPR_NOACCESS
, SPR_NOACCESS
,
1344 &spr_read_generic
, &spr_write_generic
,
1346 /* XXX : not implemented */
1347 spr_register(env
, SPR_7XX_SIAR
, "SIAR",
1348 SPR_NOACCESS
, SPR_NOACCESS
,
1349 &spr_read_generic
, SPR_NOACCESS
,
1351 /* XXX : not implemented */
1352 spr_register(env
, SPR_SDA
, "SDA",
1353 SPR_NOACCESS
, SPR_NOACCESS
,
1354 &spr_read_generic
, SPR_NOACCESS
,
1356 /* External access control */
1357 /* XXX : not implemented */
1358 spr_register(env
, SPR_EAR
, "EAR",
1359 SPR_NOACCESS
, SPR_NOACCESS
,
1360 &spr_read_generic
, &spr_write_generic
,
1364 /* SPR specific to PowerPC 603 implementation */
1365 static void gen_spr_603(CPUPPCState
*env
)
1367 /* External access control */
1368 /* XXX : not implemented */
1369 spr_register(env
, SPR_EAR
, "EAR",
1370 SPR_NOACCESS
, SPR_NOACCESS
,
1371 &spr_read_generic
, &spr_write_generic
,
1374 /* XXX : not implemented */
1375 spr_register(env
, SPR_IABR
, "IABR",
1376 SPR_NOACCESS
, SPR_NOACCESS
,
1377 &spr_read_generic
, &spr_write_generic
,
1382 /* SPR specific to PowerPC G2 implementation */
1383 static void gen_spr_G2(CPUPPCState
*env
)
1385 /* Memory base address */
1387 /* XXX : not implemented */
1388 spr_register(env
, SPR_MBAR
, "MBAR",
1389 SPR_NOACCESS
, SPR_NOACCESS
,
1390 &spr_read_generic
, &spr_write_generic
,
1392 /* Exception processing */
1393 spr_register(env
, SPR_BOOKE_CSRR0
, "CSRR0",
1394 SPR_NOACCESS
, SPR_NOACCESS
,
1395 &spr_read_generic
, &spr_write_generic
,
1397 spr_register(env
, SPR_BOOKE_CSRR1
, "CSRR1",
1398 SPR_NOACCESS
, SPR_NOACCESS
,
1399 &spr_read_generic
, &spr_write_generic
,
1402 /* XXX : not implemented */
1403 spr_register(env
, SPR_DABR
, "DABR",
1404 SPR_NOACCESS
, SPR_NOACCESS
,
1405 &spr_read_generic
, &spr_write_generic
,
1407 /* XXX : not implemented */
1408 spr_register(env
, SPR_DABR2
, "DABR2",
1409 SPR_NOACCESS
, SPR_NOACCESS
,
1410 &spr_read_generic
, &spr_write_generic
,
1412 /* XXX : not implemented */
1413 spr_register(env
, SPR_IABR
, "IABR",
1414 SPR_NOACCESS
, SPR_NOACCESS
,
1415 &spr_read_generic
, &spr_write_generic
,
1417 /* XXX : not implemented */
1418 spr_register(env
, SPR_IABR2
, "IABR2",
1419 SPR_NOACCESS
, SPR_NOACCESS
,
1420 &spr_read_generic
, &spr_write_generic
,
1422 /* XXX : not implemented */
1423 spr_register(env
, SPR_IBCR
, "IBCR",
1424 SPR_NOACCESS
, SPR_NOACCESS
,
1425 &spr_read_generic
, &spr_write_generic
,
1427 /* XXX : not implemented */
1428 spr_register(env
, SPR_DBCR
, "DBCR",
1429 SPR_NOACCESS
, SPR_NOACCESS
,
1430 &spr_read_generic
, &spr_write_generic
,
1434 /* SPR specific to PowerPC 602 implementation */
1435 static void gen_spr_602(CPUPPCState
*env
)
1438 /* XXX : not implemented */
1439 spr_register(env
, SPR_SER
, "SER",
1440 SPR_NOACCESS
, SPR_NOACCESS
,
1441 &spr_read_generic
, &spr_write_generic
,
1443 /* XXX : not implemented */
1444 spr_register(env
, SPR_SEBR
, "SEBR",
1445 SPR_NOACCESS
, SPR_NOACCESS
,
1446 &spr_read_generic
, &spr_write_generic
,
1448 /* XXX : not implemented */
1449 spr_register(env
, SPR_ESASRR
, "ESASRR",
1450 SPR_NOACCESS
, SPR_NOACCESS
,
1451 &spr_read_generic
, &spr_write_generic
,
1453 /* Floating point status */
1454 /* XXX : not implemented */
1455 spr_register(env
, SPR_SP
, "SP",
1456 SPR_NOACCESS
, SPR_NOACCESS
,
1457 &spr_read_generic
, &spr_write_generic
,
1459 /* XXX : not implemented */
1460 spr_register(env
, SPR_LT
, "LT",
1461 SPR_NOACCESS
, SPR_NOACCESS
,
1462 &spr_read_generic
, &spr_write_generic
,
1464 /* Watchdog timer */
1465 /* XXX : not implemented */
1466 spr_register(env
, SPR_TCR
, "TCR",
1467 SPR_NOACCESS
, SPR_NOACCESS
,
1468 &spr_read_generic
, &spr_write_generic
,
1470 /* Interrupt base */
1471 spr_register(env
, SPR_IBR
, "IBR",
1472 SPR_NOACCESS
, SPR_NOACCESS
,
1473 &spr_read_generic
, &spr_write_generic
,
1475 /* XXX : not implemented */
1476 spr_register(env
, SPR_IABR
, "IABR",
1477 SPR_NOACCESS
, SPR_NOACCESS
,
1478 &spr_read_generic
, &spr_write_generic
,
1482 /* SPR specific to PowerPC 601 implementation */
1483 static void gen_spr_601(CPUPPCState
*env
)
1485 /* Multiplication/division register */
1487 spr_register(env
, SPR_MQ
, "MQ",
1488 &spr_read_generic
, &spr_write_generic
,
1489 &spr_read_generic
, &spr_write_generic
,
1492 spr_register(env
, SPR_601_RTCU
, "RTCU",
1493 SPR_NOACCESS
, SPR_NOACCESS
,
1494 SPR_NOACCESS
, &spr_write_601_rtcu
,
1496 spr_register(env
, SPR_601_VRTCU
, "RTCU",
1497 &spr_read_601_rtcu
, SPR_NOACCESS
,
1498 &spr_read_601_rtcu
, SPR_NOACCESS
,
1500 spr_register(env
, SPR_601_RTCL
, "RTCL",
1501 SPR_NOACCESS
, SPR_NOACCESS
,
1502 SPR_NOACCESS
, &spr_write_601_rtcl
,
1504 spr_register(env
, SPR_601_VRTCL
, "RTCL",
1505 &spr_read_601_rtcl
, SPR_NOACCESS
,
1506 &spr_read_601_rtcl
, SPR_NOACCESS
,
1510 spr_register(env
, SPR_601_UDECR
, "UDECR",
1511 &spr_read_decr
, SPR_NOACCESS
,
1512 &spr_read_decr
, SPR_NOACCESS
,
1515 /* External access control */
1516 /* XXX : not implemented */
1517 spr_register(env
, SPR_EAR
, "EAR",
1518 SPR_NOACCESS
, SPR_NOACCESS
,
1519 &spr_read_generic
, &spr_write_generic
,
1521 /* Memory management */
1522 #if !defined(CONFIG_USER_ONLY)
1523 spr_register(env
, SPR_IBAT0U
, "IBAT0U",
1524 SPR_NOACCESS
, SPR_NOACCESS
,
1525 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1527 spr_register(env
, SPR_IBAT0L
, "IBAT0L",
1528 SPR_NOACCESS
, SPR_NOACCESS
,
1529 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1531 spr_register(env
, SPR_IBAT1U
, "IBAT1U",
1532 SPR_NOACCESS
, SPR_NOACCESS
,
1533 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1535 spr_register(env
, SPR_IBAT1L
, "IBAT1L",
1536 SPR_NOACCESS
, SPR_NOACCESS
,
1537 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1539 spr_register(env
, SPR_IBAT2U
, "IBAT2U",
1540 SPR_NOACCESS
, SPR_NOACCESS
,
1541 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1543 spr_register(env
, SPR_IBAT2L
, "IBAT2L",
1544 SPR_NOACCESS
, SPR_NOACCESS
,
1545 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1547 spr_register(env
, SPR_IBAT3U
, "IBAT3U",
1548 SPR_NOACCESS
, SPR_NOACCESS
,
1549 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1551 spr_register(env
, SPR_IBAT3L
, "IBAT3L",
1552 SPR_NOACCESS
, SPR_NOACCESS
,
1553 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1559 static void gen_spr_74xx(CPUPPCState
*env
)
1561 /* Processor identification */
1562 spr_register(env
, SPR_PIR
, "PIR",
1563 SPR_NOACCESS
, SPR_NOACCESS
,
1564 &spr_read_generic
, &spr_write_pir
,
1566 /* XXX : not implemented */
1567 spr_register(env
, SPR_74XX_MMCR2
, "MMCR2",
1568 SPR_NOACCESS
, SPR_NOACCESS
,
1569 &spr_read_generic
, &spr_write_generic
,
1571 /* XXX : not implemented */
1572 spr_register(env
, SPR_74XX_UMMCR2
, "UMMCR2",
1573 &spr_read_ureg
, SPR_NOACCESS
,
1574 &spr_read_ureg
, SPR_NOACCESS
,
1576 /* XXX: not implemented */
1577 spr_register(env
, SPR_BAMR
, "BAMR",
1578 SPR_NOACCESS
, SPR_NOACCESS
,
1579 &spr_read_generic
, &spr_write_generic
,
1581 /* XXX : not implemented */
1582 spr_register(env
, SPR_MSSCR0
, "MSSCR0",
1583 SPR_NOACCESS
, SPR_NOACCESS
,
1584 &spr_read_generic
, &spr_write_generic
,
1586 /* Hardware implementation registers */
1587 /* XXX : not implemented */
1588 spr_register(env
, SPR_HID0
, "HID0",
1589 SPR_NOACCESS
, SPR_NOACCESS
,
1590 &spr_read_generic
, &spr_write_generic
,
1592 /* XXX : not implemented */
1593 spr_register(env
, SPR_HID1
, "HID1",
1594 SPR_NOACCESS
, SPR_NOACCESS
,
1595 &spr_read_generic
, &spr_write_generic
,
1598 spr_register(env
, SPR_VRSAVE
, "VRSAVE",
1599 &spr_read_generic
, &spr_write_generic
,
1600 &spr_read_generic
, &spr_write_generic
,
1602 /* XXX : not implemented */
1603 spr_register(env
, SPR_L2CR
, "L2CR",
1604 SPR_NOACCESS
, SPR_NOACCESS
,
1605 &spr_read_generic
, spr_access_nop
,
1607 /* Not strictly an SPR */
1608 vscr_init(env
, 0x00010000);
1611 static void gen_l3_ctrl(CPUPPCState
*env
)
1614 /* XXX : not implemented */
1615 spr_register(env
, SPR_L3CR
, "L3CR",
1616 SPR_NOACCESS
, SPR_NOACCESS
,
1617 &spr_read_generic
, &spr_write_generic
,
1620 /* XXX : not implemented */
1621 spr_register(env
, SPR_L3ITCR0
, "L3ITCR0",
1622 SPR_NOACCESS
, SPR_NOACCESS
,
1623 &spr_read_generic
, &spr_write_generic
,
1626 /* XXX : not implemented */
1627 spr_register(env
, SPR_L3PM
, "L3PM",
1628 SPR_NOACCESS
, SPR_NOACCESS
,
1629 &spr_read_generic
, &spr_write_generic
,
1633 static void gen_74xx_soft_tlb(CPUPPCState
*env
, int nb_tlbs
, int nb_ways
)
1635 #if !defined(CONFIG_USER_ONLY)
1636 env
->nb_tlb
= nb_tlbs
;
1637 env
->nb_ways
= nb_ways
;
1639 env
->tlb_type
= TLB_6XX
;
1640 /* XXX : not implemented */
1641 spr_register(env
, SPR_PTEHI
, "PTEHI",
1642 SPR_NOACCESS
, SPR_NOACCESS
,
1643 &spr_read_generic
, &spr_write_generic
,
1645 /* XXX : not implemented */
1646 spr_register(env
, SPR_PTELO
, "PTELO",
1647 SPR_NOACCESS
, SPR_NOACCESS
,
1648 &spr_read_generic
, &spr_write_generic
,
1650 /* XXX : not implemented */
1651 spr_register(env
, SPR_TLBMISS
, "TLBMISS",
1652 SPR_NOACCESS
, SPR_NOACCESS
,
1653 &spr_read_generic
, &spr_write_generic
,
1658 #if !defined(CONFIG_USER_ONLY)
1659 static void spr_write_e500_l1csr0(DisasContext
*ctx
, int sprn
, int gprn
)
1661 TCGv t0
= tcg_temp_new();
1663 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], L1CSR0_DCE
| L1CSR0_CPE
);
1664 gen_store_spr(sprn
, t0
);
1668 static void spr_write_e500_l1csr1(DisasContext
*ctx
, int sprn
, int gprn
)
1670 TCGv t0
= tcg_temp_new();
1672 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], L1CSR1_ICE
| L1CSR1_CPE
);
1673 gen_store_spr(sprn
, t0
);
1677 static void spr_write_booke206_mmucsr0(DisasContext
*ctx
, int sprn
, int gprn
)
1679 gen_helper_booke206_tlbflush(cpu_env
, cpu_gpr
[gprn
]);
1682 static void spr_write_booke_pid(DisasContext
*ctx
, int sprn
, int gprn
)
1684 TCGv_i32 t0
= tcg_const_i32(sprn
);
1685 gen_helper_booke_setpid(cpu_env
, t0
, cpu_gpr
[gprn
]);
1686 tcg_temp_free_i32(t0
);
1688 static void spr_write_eplc(DisasContext
*ctx
, int sprn
, int gprn
)
1690 gen_helper_booke_set_eplc(cpu_env
, cpu_gpr
[gprn
]);
1692 static void spr_write_epsc(DisasContext
*ctx
, int sprn
, int gprn
)
1694 gen_helper_booke_set_epsc(cpu_env
, cpu_gpr
[gprn
]);
1699 static void gen_spr_usprg3(CPUPPCState
*env
)
1701 spr_register(env
, SPR_USPRG3
, "USPRG3",
1702 &spr_read_ureg
, SPR_NOACCESS
,
1703 &spr_read_ureg
, SPR_NOACCESS
,
1707 static void gen_spr_usprgh(CPUPPCState
*env
)
1709 spr_register(env
, SPR_USPRG4
, "USPRG4",
1710 &spr_read_ureg
, SPR_NOACCESS
,
1711 &spr_read_ureg
, SPR_NOACCESS
,
1713 spr_register(env
, SPR_USPRG5
, "USPRG5",
1714 &spr_read_ureg
, SPR_NOACCESS
,
1715 &spr_read_ureg
, SPR_NOACCESS
,
1717 spr_register(env
, SPR_USPRG6
, "USPRG6",
1718 &spr_read_ureg
, SPR_NOACCESS
,
1719 &spr_read_ureg
, SPR_NOACCESS
,
1721 spr_register(env
, SPR_USPRG7
, "USPRG7",
1722 &spr_read_ureg
, SPR_NOACCESS
,
1723 &spr_read_ureg
, SPR_NOACCESS
,
1727 /* PowerPC BookE SPR */
1728 static void gen_spr_BookE(CPUPPCState
*env
, uint64_t ivor_mask
)
1730 const char *ivor_names
[64] = {
1731 "IVOR0", "IVOR1", "IVOR2", "IVOR3",
1732 "IVOR4", "IVOR5", "IVOR6", "IVOR7",
1733 "IVOR8", "IVOR9", "IVOR10", "IVOR11",
1734 "IVOR12", "IVOR13", "IVOR14", "IVOR15",
1735 "IVOR16", "IVOR17", "IVOR18", "IVOR19",
1736 "IVOR20", "IVOR21", "IVOR22", "IVOR23",
1737 "IVOR24", "IVOR25", "IVOR26", "IVOR27",
1738 "IVOR28", "IVOR29", "IVOR30", "IVOR31",
1739 "IVOR32", "IVOR33", "IVOR34", "IVOR35",
1740 "IVOR36", "IVOR37", "IVOR38", "IVOR39",
1741 "IVOR40", "IVOR41", "IVOR42", "IVOR43",
1742 "IVOR44", "IVOR45", "IVOR46", "IVOR47",
1743 "IVOR48", "IVOR49", "IVOR50", "IVOR51",
1744 "IVOR52", "IVOR53", "IVOR54", "IVOR55",
1745 "IVOR56", "IVOR57", "IVOR58", "IVOR59",
1746 "IVOR60", "IVOR61", "IVOR62", "IVOR63",
1748 #define SPR_BOOKE_IVORxx (-1)
1749 int ivor_sprn
[64] = {
1750 SPR_BOOKE_IVOR0
, SPR_BOOKE_IVOR1
, SPR_BOOKE_IVOR2
, SPR_BOOKE_IVOR3
,
1751 SPR_BOOKE_IVOR4
, SPR_BOOKE_IVOR5
, SPR_BOOKE_IVOR6
, SPR_BOOKE_IVOR7
,
1752 SPR_BOOKE_IVOR8
, SPR_BOOKE_IVOR9
, SPR_BOOKE_IVOR10
, SPR_BOOKE_IVOR11
,
1753 SPR_BOOKE_IVOR12
, SPR_BOOKE_IVOR13
, SPR_BOOKE_IVOR14
, SPR_BOOKE_IVOR15
,
1754 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1755 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1756 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1757 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1758 SPR_BOOKE_IVOR32
, SPR_BOOKE_IVOR33
, SPR_BOOKE_IVOR34
, SPR_BOOKE_IVOR35
,
1759 SPR_BOOKE_IVOR36
, SPR_BOOKE_IVOR37
, SPR_BOOKE_IVOR38
, SPR_BOOKE_IVOR39
,
1760 SPR_BOOKE_IVOR40
, SPR_BOOKE_IVOR41
, SPR_BOOKE_IVOR42
, SPR_BOOKE_IVORxx
,
1761 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1762 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1763 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1764 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1765 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1769 /* Interrupt processing */
1770 spr_register(env
, SPR_BOOKE_CSRR0
, "CSRR0",
1771 SPR_NOACCESS
, SPR_NOACCESS
,
1772 &spr_read_generic
, &spr_write_generic
,
1774 spr_register(env
, SPR_BOOKE_CSRR1
, "CSRR1",
1775 SPR_NOACCESS
, SPR_NOACCESS
,
1776 &spr_read_generic
, &spr_write_generic
,
1779 /* XXX : not implemented */
1780 spr_register(env
, SPR_BOOKE_IAC1
, "IAC1",
1781 SPR_NOACCESS
, SPR_NOACCESS
,
1782 &spr_read_generic
, &spr_write_generic
,
1784 /* XXX : not implemented */
1785 spr_register(env
, SPR_BOOKE_IAC2
, "IAC2",
1786 SPR_NOACCESS
, SPR_NOACCESS
,
1787 &spr_read_generic
, &spr_write_generic
,
1789 /* XXX : not implemented */
1790 spr_register(env
, SPR_BOOKE_DAC1
, "DAC1",
1791 SPR_NOACCESS
, SPR_NOACCESS
,
1792 &spr_read_generic
, &spr_write_generic
,
1794 /* XXX : not implemented */
1795 spr_register(env
, SPR_BOOKE_DAC2
, "DAC2",
1796 SPR_NOACCESS
, SPR_NOACCESS
,
1797 &spr_read_generic
, &spr_write_generic
,
1799 /* XXX : not implemented */
1800 spr_register(env
, SPR_BOOKE_DBCR0
, "DBCR0",
1801 SPR_NOACCESS
, SPR_NOACCESS
,
1802 &spr_read_generic
, &spr_write_40x_dbcr0
,
1804 /* XXX : not implemented */
1805 spr_register(env
, SPR_BOOKE_DBCR1
, "DBCR1",
1806 SPR_NOACCESS
, SPR_NOACCESS
,
1807 &spr_read_generic
, &spr_write_generic
,
1809 /* XXX : not implemented */
1810 spr_register(env
, SPR_BOOKE_DBCR2
, "DBCR2",
1811 SPR_NOACCESS
, SPR_NOACCESS
,
1812 &spr_read_generic
, &spr_write_generic
,
1814 spr_register(env
, SPR_BOOKE_DSRR0
, "DSRR0",
1815 SPR_NOACCESS
, SPR_NOACCESS
,
1816 &spr_read_generic
, &spr_write_generic
,
1818 spr_register(env
, SPR_BOOKE_DSRR1
, "DSRR1",
1819 SPR_NOACCESS
, SPR_NOACCESS
,
1820 &spr_read_generic
, &spr_write_generic
,
1822 /* XXX : not implemented */
1823 spr_register(env
, SPR_BOOKE_DBSR
, "DBSR",
1824 SPR_NOACCESS
, SPR_NOACCESS
,
1825 &spr_read_generic
, &spr_write_clear
,
1827 spr_register(env
, SPR_BOOKE_DEAR
, "DEAR",
1828 SPR_NOACCESS
, SPR_NOACCESS
,
1829 &spr_read_generic
, &spr_write_generic
,
1831 spr_register(env
, SPR_BOOKE_ESR
, "ESR",
1832 SPR_NOACCESS
, SPR_NOACCESS
,
1833 &spr_read_generic
, &spr_write_generic
,
1835 spr_register(env
, SPR_BOOKE_IVPR
, "IVPR",
1836 SPR_NOACCESS
, SPR_NOACCESS
,
1837 &spr_read_generic
, &spr_write_excp_prefix
,
1839 /* Exception vectors */
1840 for (i
= 0; i
< 64; i
++) {
1841 if (ivor_mask
& (1ULL << i
)) {
1842 if (ivor_sprn
[i
] == SPR_BOOKE_IVORxx
) {
1843 fprintf(stderr
, "ERROR: IVOR %d SPR is not defined\n", i
);
1846 spr_register(env
, ivor_sprn
[i
], ivor_names
[i
],
1847 SPR_NOACCESS
, SPR_NOACCESS
,
1848 &spr_read_generic
, &spr_write_excp_vector
,
1852 spr_register(env
, SPR_BOOKE_PID
, "PID",
1853 SPR_NOACCESS
, SPR_NOACCESS
,
1854 &spr_read_generic
, &spr_write_booke_pid
,
1856 spr_register(env
, SPR_BOOKE_TCR
, "TCR",
1857 SPR_NOACCESS
, SPR_NOACCESS
,
1858 &spr_read_generic
, &spr_write_booke_tcr
,
1860 spr_register(env
, SPR_BOOKE_TSR
, "TSR",
1861 SPR_NOACCESS
, SPR_NOACCESS
,
1862 &spr_read_generic
, &spr_write_booke_tsr
,
1865 spr_register(env
, SPR_DECR
, "DECR",
1866 SPR_NOACCESS
, SPR_NOACCESS
,
1867 &spr_read_decr
, &spr_write_decr
,
1869 spr_register(env
, SPR_BOOKE_DECAR
, "DECAR",
1870 SPR_NOACCESS
, SPR_NOACCESS
,
1871 SPR_NOACCESS
, &spr_write_generic
,
1874 spr_register(env
, SPR_USPRG0
, "USPRG0",
1875 &spr_read_generic
, &spr_write_generic
,
1876 &spr_read_generic
, &spr_write_generic
,
1878 spr_register(env
, SPR_SPRG4
, "SPRG4",
1879 SPR_NOACCESS
, SPR_NOACCESS
,
1880 &spr_read_generic
, &spr_write_generic
,
1882 spr_register(env
, SPR_SPRG5
, "SPRG5",
1883 SPR_NOACCESS
, SPR_NOACCESS
,
1884 &spr_read_generic
, &spr_write_generic
,
1886 spr_register(env
, SPR_SPRG6
, "SPRG6",
1887 SPR_NOACCESS
, SPR_NOACCESS
,
1888 &spr_read_generic
, &spr_write_generic
,
1890 spr_register(env
, SPR_SPRG7
, "SPRG7",
1891 SPR_NOACCESS
, SPR_NOACCESS
,
1892 &spr_read_generic
, &spr_write_generic
,
1894 spr_register(env
, SPR_BOOKE_SPRG8
, "SPRG8",
1895 SPR_NOACCESS
, SPR_NOACCESS
,
1896 &spr_read_generic
, &spr_write_generic
,
1898 spr_register(env
, SPR_BOOKE_SPRG9
, "SPRG9",
1899 SPR_NOACCESS
, SPR_NOACCESS
,
1900 &spr_read_generic
, &spr_write_generic
,
1904 static inline uint32_t gen_tlbncfg(uint32_t assoc
, uint32_t minsize
,
1905 uint32_t maxsize
, uint32_t flags
,
1908 return (assoc
<< TLBnCFG_ASSOC_SHIFT
) |
1909 (minsize
<< TLBnCFG_MINSIZE_SHIFT
) |
1910 (maxsize
<< TLBnCFG_MAXSIZE_SHIFT
) |
1914 /* BookE 2.06 storage control registers */
1915 static void gen_spr_BookE206(CPUPPCState
*env
, uint32_t mas_mask
,
1916 uint32_t *tlbncfg
, uint32_t mmucfg
)
1918 #if !defined(CONFIG_USER_ONLY)
1919 const char *mas_names
[8] = {
1920 "MAS0", "MAS1", "MAS2", "MAS3", "MAS4", "MAS5", "MAS6", "MAS7",
1923 SPR_BOOKE_MAS0
, SPR_BOOKE_MAS1
, SPR_BOOKE_MAS2
, SPR_BOOKE_MAS3
,
1924 SPR_BOOKE_MAS4
, SPR_BOOKE_MAS5
, SPR_BOOKE_MAS6
, SPR_BOOKE_MAS7
,
1928 /* TLB assist registers */
1929 /* XXX : not implemented */
1930 for (i
= 0; i
< 8; i
++) {
1931 void (*uea_write
)(DisasContext
*ctx
, int sprn
, int gprn
) =
1932 &spr_write_generic32
;
1933 if (i
== 2 && (mas_mask
& (1 << i
)) && (env
->insns_flags
& PPC_64B
)) {
1934 uea_write
= &spr_write_generic
;
1936 if (mas_mask
& (1 << i
)) {
1937 spr_register(env
, mas_sprn
[i
], mas_names
[i
],
1938 SPR_NOACCESS
, SPR_NOACCESS
,
1939 &spr_read_generic
, uea_write
,
1943 if (env
->nb_pids
> 1) {
1944 /* XXX : not implemented */
1945 spr_register(env
, SPR_BOOKE_PID1
, "PID1",
1946 SPR_NOACCESS
, SPR_NOACCESS
,
1947 &spr_read_generic
, &spr_write_booke_pid
,
1950 if (env
->nb_pids
> 2) {
1951 /* XXX : not implemented */
1952 spr_register(env
, SPR_BOOKE_PID2
, "PID2",
1953 SPR_NOACCESS
, SPR_NOACCESS
,
1954 &spr_read_generic
, &spr_write_booke_pid
,
1958 spr_register(env
, SPR_BOOKE_EPLC
, "EPLC",
1959 SPR_NOACCESS
, SPR_NOACCESS
,
1960 &spr_read_generic
, &spr_write_eplc
,
1962 spr_register(env
, SPR_BOOKE_EPSC
, "EPSC",
1963 SPR_NOACCESS
, SPR_NOACCESS
,
1964 &spr_read_generic
, &spr_write_epsc
,
1967 /* XXX : not implemented */
1968 spr_register(env
, SPR_MMUCFG
, "MMUCFG",
1969 SPR_NOACCESS
, SPR_NOACCESS
,
1970 &spr_read_generic
, SPR_NOACCESS
,
1972 switch (env
->nb_ways
) {
1974 spr_register(env
, SPR_BOOKE_TLB3CFG
, "TLB3CFG",
1975 SPR_NOACCESS
, SPR_NOACCESS
,
1976 &spr_read_generic
, SPR_NOACCESS
,
1980 spr_register(env
, SPR_BOOKE_TLB2CFG
, "TLB2CFG",
1981 SPR_NOACCESS
, SPR_NOACCESS
,
1982 &spr_read_generic
, SPR_NOACCESS
,
1986 spr_register(env
, SPR_BOOKE_TLB1CFG
, "TLB1CFG",
1987 SPR_NOACCESS
, SPR_NOACCESS
,
1988 &spr_read_generic
, SPR_NOACCESS
,
1992 spr_register(env
, SPR_BOOKE_TLB0CFG
, "TLB0CFG",
1993 SPR_NOACCESS
, SPR_NOACCESS
,
1994 &spr_read_generic
, SPR_NOACCESS
,
2003 gen_spr_usprgh(env
);
2006 /* SPR specific to PowerPC 440 implementation */
2007 static void gen_spr_440(CPUPPCState
*env
)
2010 /* XXX : not implemented */
2011 spr_register(env
, SPR_440_DNV0
, "DNV0",
2012 SPR_NOACCESS
, SPR_NOACCESS
,
2013 &spr_read_generic
, &spr_write_generic
,
2015 /* XXX : not implemented */
2016 spr_register(env
, SPR_440_DNV1
, "DNV1",
2017 SPR_NOACCESS
, SPR_NOACCESS
,
2018 &spr_read_generic
, &spr_write_generic
,
2020 /* XXX : not implemented */
2021 spr_register(env
, SPR_440_DNV2
, "DNV2",
2022 SPR_NOACCESS
, SPR_NOACCESS
,
2023 &spr_read_generic
, &spr_write_generic
,
2025 /* XXX : not implemented */
2026 spr_register(env
, SPR_440_DNV3
, "DNV3",
2027 SPR_NOACCESS
, SPR_NOACCESS
,
2028 &spr_read_generic
, &spr_write_generic
,
2030 /* XXX : not implemented */
2031 spr_register(env
, SPR_440_DTV0
, "DTV0",
2032 SPR_NOACCESS
, SPR_NOACCESS
,
2033 &spr_read_generic
, &spr_write_generic
,
2035 /* XXX : not implemented */
2036 spr_register(env
, SPR_440_DTV1
, "DTV1",
2037 SPR_NOACCESS
, SPR_NOACCESS
,
2038 &spr_read_generic
, &spr_write_generic
,
2040 /* XXX : not implemented */
2041 spr_register(env
, SPR_440_DTV2
, "DTV2",
2042 SPR_NOACCESS
, SPR_NOACCESS
,
2043 &spr_read_generic
, &spr_write_generic
,
2045 /* XXX : not implemented */
2046 spr_register(env
, SPR_440_DTV3
, "DTV3",
2047 SPR_NOACCESS
, SPR_NOACCESS
,
2048 &spr_read_generic
, &spr_write_generic
,
2050 /* XXX : not implemented */
2051 spr_register(env
, SPR_440_DVLIM
, "DVLIM",
2052 SPR_NOACCESS
, SPR_NOACCESS
,
2053 &spr_read_generic
, &spr_write_generic
,
2055 /* XXX : not implemented */
2056 spr_register(env
, SPR_440_INV0
, "INV0",
2057 SPR_NOACCESS
, SPR_NOACCESS
,
2058 &spr_read_generic
, &spr_write_generic
,
2060 /* XXX : not implemented */
2061 spr_register(env
, SPR_440_INV1
, "INV1",
2062 SPR_NOACCESS
, SPR_NOACCESS
,
2063 &spr_read_generic
, &spr_write_generic
,
2065 /* XXX : not implemented */
2066 spr_register(env
, SPR_440_INV2
, "INV2",
2067 SPR_NOACCESS
, SPR_NOACCESS
,
2068 &spr_read_generic
, &spr_write_generic
,
2070 /* XXX : not implemented */
2071 spr_register(env
, SPR_440_INV3
, "INV3",
2072 SPR_NOACCESS
, SPR_NOACCESS
,
2073 &spr_read_generic
, &spr_write_generic
,
2075 /* XXX : not implemented */
2076 spr_register(env
, SPR_440_ITV0
, "ITV0",
2077 SPR_NOACCESS
, SPR_NOACCESS
,
2078 &spr_read_generic
, &spr_write_generic
,
2080 /* XXX : not implemented */
2081 spr_register(env
, SPR_440_ITV1
, "ITV1",
2082 SPR_NOACCESS
, SPR_NOACCESS
,
2083 &spr_read_generic
, &spr_write_generic
,
2085 /* XXX : not implemented */
2086 spr_register(env
, SPR_440_ITV2
, "ITV2",
2087 SPR_NOACCESS
, SPR_NOACCESS
,
2088 &spr_read_generic
, &spr_write_generic
,
2090 /* XXX : not implemented */
2091 spr_register(env
, SPR_440_ITV3
, "ITV3",
2092 SPR_NOACCESS
, SPR_NOACCESS
,
2093 &spr_read_generic
, &spr_write_generic
,
2095 /* XXX : not implemented */
2096 spr_register(env
, SPR_440_IVLIM
, "IVLIM",
2097 SPR_NOACCESS
, SPR_NOACCESS
,
2098 &spr_read_generic
, &spr_write_generic
,
2101 /* XXX : not implemented */
2102 spr_register(env
, SPR_BOOKE_DCDBTRH
, "DCDBTRH",
2103 SPR_NOACCESS
, SPR_NOACCESS
,
2104 &spr_read_generic
, SPR_NOACCESS
,
2106 /* XXX : not implemented */
2107 spr_register(env
, SPR_BOOKE_DCDBTRL
, "DCDBTRL",
2108 SPR_NOACCESS
, SPR_NOACCESS
,
2109 &spr_read_generic
, SPR_NOACCESS
,
2111 /* XXX : not implemented */
2112 spr_register(env
, SPR_BOOKE_ICDBDR
, "ICDBDR",
2113 SPR_NOACCESS
, SPR_NOACCESS
,
2114 &spr_read_generic
, SPR_NOACCESS
,
2116 /* XXX : not implemented */
2117 spr_register(env
, SPR_BOOKE_ICDBTRH
, "ICDBTRH",
2118 SPR_NOACCESS
, SPR_NOACCESS
,
2119 &spr_read_generic
, SPR_NOACCESS
,
2121 /* XXX : not implemented */
2122 spr_register(env
, SPR_BOOKE_ICDBTRL
, "ICDBTRL",
2123 SPR_NOACCESS
, SPR_NOACCESS
,
2124 &spr_read_generic
, SPR_NOACCESS
,
2126 /* XXX : not implemented */
2127 spr_register(env
, SPR_440_DBDR
, "DBDR",
2128 SPR_NOACCESS
, SPR_NOACCESS
,
2129 &spr_read_generic
, &spr_write_generic
,
2131 /* Processor control */
2132 spr_register(env
, SPR_4xx_CCR0
, "CCR0",
2133 SPR_NOACCESS
, SPR_NOACCESS
,
2134 &spr_read_generic
, &spr_write_generic
,
2136 spr_register(env
, SPR_440_RSTCFG
, "RSTCFG",
2137 SPR_NOACCESS
, SPR_NOACCESS
,
2138 &spr_read_generic
, SPR_NOACCESS
,
2140 /* Storage control */
2141 spr_register(env
, SPR_440_MMUCR
, "MMUCR",
2142 SPR_NOACCESS
, SPR_NOACCESS
,
2143 &spr_read_generic
, &spr_write_generic
,
2147 /* SPR shared between PowerPC 40x implementations */
2148 static void gen_spr_40x(CPUPPCState
*env
)
2151 /* not emulated, as QEMU do not emulate caches */
2152 spr_register(env
, SPR_40x_DCCR
, "DCCR",
2153 SPR_NOACCESS
, SPR_NOACCESS
,
2154 &spr_read_generic
, &spr_write_generic
,
2156 /* not emulated, as QEMU do not emulate caches */
2157 spr_register(env
, SPR_40x_ICCR
, "ICCR",
2158 SPR_NOACCESS
, SPR_NOACCESS
,
2159 &spr_read_generic
, &spr_write_generic
,
2161 /* not emulated, as QEMU do not emulate caches */
2162 spr_register(env
, SPR_BOOKE_ICDBDR
, "ICDBDR",
2163 SPR_NOACCESS
, SPR_NOACCESS
,
2164 &spr_read_generic
, SPR_NOACCESS
,
2167 spr_register(env
, SPR_40x_DEAR
, "DEAR",
2168 SPR_NOACCESS
, SPR_NOACCESS
,
2169 &spr_read_generic
, &spr_write_generic
,
2171 spr_register(env
, SPR_40x_ESR
, "ESR",
2172 SPR_NOACCESS
, SPR_NOACCESS
,
2173 &spr_read_generic
, &spr_write_generic
,
2175 spr_register(env
, SPR_40x_EVPR
, "EVPR",
2176 SPR_NOACCESS
, SPR_NOACCESS
,
2177 &spr_read_generic
, &spr_write_excp_prefix
,
2179 spr_register(env
, SPR_40x_SRR2
, "SRR2",
2180 &spr_read_generic
, &spr_write_generic
,
2181 &spr_read_generic
, &spr_write_generic
,
2183 spr_register(env
, SPR_40x_SRR3
, "SRR3",
2184 &spr_read_generic
, &spr_write_generic
,
2185 &spr_read_generic
, &spr_write_generic
,
2188 spr_register(env
, SPR_40x_PIT
, "PIT",
2189 SPR_NOACCESS
, SPR_NOACCESS
,
2190 &spr_read_40x_pit
, &spr_write_40x_pit
,
2192 spr_register(env
, SPR_40x_TCR
, "TCR",
2193 SPR_NOACCESS
, SPR_NOACCESS
,
2194 &spr_read_generic
, &spr_write_booke_tcr
,
2196 spr_register(env
, SPR_40x_TSR
, "TSR",
2197 SPR_NOACCESS
, SPR_NOACCESS
,
2198 &spr_read_generic
, &spr_write_booke_tsr
,
2202 /* SPR specific to PowerPC 405 implementation */
2203 static void gen_spr_405(CPUPPCState
*env
)
2206 spr_register(env
, SPR_40x_PID
, "PID",
2207 SPR_NOACCESS
, SPR_NOACCESS
,
2208 &spr_read_generic
, &spr_write_generic
,
2210 spr_register(env
, SPR_4xx_CCR0
, "CCR0",
2211 SPR_NOACCESS
, SPR_NOACCESS
,
2212 &spr_read_generic
, &spr_write_generic
,
2214 /* Debug interface */
2215 /* XXX : not implemented */
2216 spr_register(env
, SPR_40x_DBCR0
, "DBCR0",
2217 SPR_NOACCESS
, SPR_NOACCESS
,
2218 &spr_read_generic
, &spr_write_40x_dbcr0
,
2220 /* XXX : not implemented */
2221 spr_register(env
, SPR_405_DBCR1
, "DBCR1",
2222 SPR_NOACCESS
, SPR_NOACCESS
,
2223 &spr_read_generic
, &spr_write_generic
,
2225 /* XXX : not implemented */
2226 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2227 SPR_NOACCESS
, SPR_NOACCESS
,
2228 &spr_read_generic
, &spr_write_clear
,
2229 /* Last reset was system reset */
2231 /* XXX : not implemented */
2232 spr_register(env
, SPR_40x_DAC1
, "DAC1",
2233 SPR_NOACCESS
, SPR_NOACCESS
,
2234 &spr_read_generic
, &spr_write_generic
,
2236 spr_register(env
, SPR_40x_DAC2
, "DAC2",
2237 SPR_NOACCESS
, SPR_NOACCESS
,
2238 &spr_read_generic
, &spr_write_generic
,
2240 /* XXX : not implemented */
2241 spr_register(env
, SPR_405_DVC1
, "DVC1",
2242 SPR_NOACCESS
, SPR_NOACCESS
,
2243 &spr_read_generic
, &spr_write_generic
,
2245 /* XXX : not implemented */
2246 spr_register(env
, SPR_405_DVC2
, "DVC2",
2247 SPR_NOACCESS
, SPR_NOACCESS
,
2248 &spr_read_generic
, &spr_write_generic
,
2250 /* XXX : not implemented */
2251 spr_register(env
, SPR_40x_IAC1
, "IAC1",
2252 SPR_NOACCESS
, SPR_NOACCESS
,
2253 &spr_read_generic
, &spr_write_generic
,
2255 spr_register(env
, SPR_40x_IAC2
, "IAC2",
2256 SPR_NOACCESS
, SPR_NOACCESS
,
2257 &spr_read_generic
, &spr_write_generic
,
2259 /* XXX : not implemented */
2260 spr_register(env
, SPR_405_IAC3
, "IAC3",
2261 SPR_NOACCESS
, SPR_NOACCESS
,
2262 &spr_read_generic
, &spr_write_generic
,
2264 /* XXX : not implemented */
2265 spr_register(env
, SPR_405_IAC4
, "IAC4",
2266 SPR_NOACCESS
, SPR_NOACCESS
,
2267 &spr_read_generic
, &spr_write_generic
,
2269 /* Storage control */
2270 /* XXX: TODO: not implemented */
2271 spr_register(env
, SPR_405_SLER
, "SLER",
2272 SPR_NOACCESS
, SPR_NOACCESS
,
2273 &spr_read_generic
, &spr_write_40x_sler
,
2275 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2276 SPR_NOACCESS
, SPR_NOACCESS
,
2277 &spr_read_generic
, &spr_write_generic
,
2279 /* XXX : not implemented */
2280 spr_register(env
, SPR_405_SU0R
, "SU0R",
2281 SPR_NOACCESS
, SPR_NOACCESS
,
2282 &spr_read_generic
, &spr_write_generic
,
2285 spr_register(env
, SPR_USPRG0
, "USPRG0",
2286 &spr_read_ureg
, SPR_NOACCESS
,
2287 &spr_read_ureg
, SPR_NOACCESS
,
2289 spr_register(env
, SPR_SPRG4
, "SPRG4",
2290 SPR_NOACCESS
, SPR_NOACCESS
,
2291 &spr_read_generic
, &spr_write_generic
,
2293 spr_register(env
, SPR_SPRG5
, "SPRG5",
2294 SPR_NOACCESS
, SPR_NOACCESS
,
2295 spr_read_generic
, &spr_write_generic
,
2297 spr_register(env
, SPR_SPRG6
, "SPRG6",
2298 SPR_NOACCESS
, SPR_NOACCESS
,
2299 spr_read_generic
, &spr_write_generic
,
2301 spr_register(env
, SPR_SPRG7
, "SPRG7",
2302 SPR_NOACCESS
, SPR_NOACCESS
,
2303 spr_read_generic
, &spr_write_generic
,
2305 gen_spr_usprgh(env
);
2308 /* SPR shared between PowerPC 401 & 403 implementations */
2309 static void gen_spr_401_403(CPUPPCState
*env
)
2312 spr_register(env
, SPR_403_VTBL
, "TBL",
2313 &spr_read_tbl
, SPR_NOACCESS
,
2314 &spr_read_tbl
, SPR_NOACCESS
,
2316 spr_register(env
, SPR_403_TBL
, "TBL",
2317 SPR_NOACCESS
, SPR_NOACCESS
,
2318 SPR_NOACCESS
, &spr_write_tbl
,
2320 spr_register(env
, SPR_403_VTBU
, "TBU",
2321 &spr_read_tbu
, SPR_NOACCESS
,
2322 &spr_read_tbu
, SPR_NOACCESS
,
2324 spr_register(env
, SPR_403_TBU
, "TBU",
2325 SPR_NOACCESS
, SPR_NOACCESS
,
2326 SPR_NOACCESS
, &spr_write_tbu
,
2329 /* not emulated, as QEMU do not emulate caches */
2330 spr_register(env
, SPR_403_CDBCR
, "CDBCR",
2331 SPR_NOACCESS
, SPR_NOACCESS
,
2332 &spr_read_generic
, &spr_write_generic
,
2336 /* SPR specific to PowerPC 401 implementation */
2337 static void gen_spr_401(CPUPPCState
*env
)
2339 /* Debug interface */
2340 /* XXX : not implemented */
2341 spr_register(env
, SPR_40x_DBCR0
, "DBCR",
2342 SPR_NOACCESS
, SPR_NOACCESS
,
2343 &spr_read_generic
, &spr_write_40x_dbcr0
,
2345 /* XXX : not implemented */
2346 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2347 SPR_NOACCESS
, SPR_NOACCESS
,
2348 &spr_read_generic
, &spr_write_clear
,
2349 /* Last reset was system reset */
2351 /* XXX : not implemented */
2352 spr_register(env
, SPR_40x_DAC1
, "DAC",
2353 SPR_NOACCESS
, SPR_NOACCESS
,
2354 &spr_read_generic
, &spr_write_generic
,
2356 /* XXX : not implemented */
2357 spr_register(env
, SPR_40x_IAC1
, "IAC",
2358 SPR_NOACCESS
, SPR_NOACCESS
,
2359 &spr_read_generic
, &spr_write_generic
,
2361 /* Storage control */
2362 /* XXX: TODO: not implemented */
2363 spr_register(env
, SPR_405_SLER
, "SLER",
2364 SPR_NOACCESS
, SPR_NOACCESS
,
2365 &spr_read_generic
, &spr_write_40x_sler
,
2367 /* not emulated, as QEMU never does speculative access */
2368 spr_register(env
, SPR_40x_SGR
, "SGR",
2369 SPR_NOACCESS
, SPR_NOACCESS
,
2370 &spr_read_generic
, &spr_write_generic
,
2372 /* not emulated, as QEMU do not emulate caches */
2373 spr_register(env
, SPR_40x_DCWR
, "DCWR",
2374 SPR_NOACCESS
, SPR_NOACCESS
,
2375 &spr_read_generic
, &spr_write_generic
,
2379 static void gen_spr_401x2(CPUPPCState
*env
)
2382 spr_register(env
, SPR_40x_PID
, "PID",
2383 SPR_NOACCESS
, SPR_NOACCESS
,
2384 &spr_read_generic
, &spr_write_generic
,
2386 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2387 SPR_NOACCESS
, SPR_NOACCESS
,
2388 &spr_read_generic
, &spr_write_generic
,
2392 /* SPR specific to PowerPC 403 implementation */
2393 static void gen_spr_403(CPUPPCState
*env
)
2395 /* Debug interface */
2396 /* XXX : not implemented */
2397 spr_register(env
, SPR_40x_DBCR0
, "DBCR0",
2398 SPR_NOACCESS
, SPR_NOACCESS
,
2399 &spr_read_generic
, &spr_write_40x_dbcr0
,
2401 /* XXX : not implemented */
2402 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2403 SPR_NOACCESS
, SPR_NOACCESS
,
2404 &spr_read_generic
, &spr_write_clear
,
2405 /* Last reset was system reset */
2407 /* XXX : not implemented */
2408 spr_register(env
, SPR_40x_DAC1
, "DAC1",
2409 SPR_NOACCESS
, SPR_NOACCESS
,
2410 &spr_read_generic
, &spr_write_generic
,
2412 /* XXX : not implemented */
2413 spr_register(env
, SPR_40x_DAC2
, "DAC2",
2414 SPR_NOACCESS
, SPR_NOACCESS
,
2415 &spr_read_generic
, &spr_write_generic
,
2417 /* XXX : not implemented */
2418 spr_register(env
, SPR_40x_IAC1
, "IAC1",
2419 SPR_NOACCESS
, SPR_NOACCESS
,
2420 &spr_read_generic
, &spr_write_generic
,
2422 /* XXX : not implemented */
2423 spr_register(env
, SPR_40x_IAC2
, "IAC2",
2424 SPR_NOACCESS
, SPR_NOACCESS
,
2425 &spr_read_generic
, &spr_write_generic
,
2429 static void gen_spr_403_real(CPUPPCState
*env
)
2431 spr_register(env
, SPR_403_PBL1
, "PBL1",
2432 SPR_NOACCESS
, SPR_NOACCESS
,
2433 &spr_read_403_pbr
, &spr_write_403_pbr
,
2435 spr_register(env
, SPR_403_PBU1
, "PBU1",
2436 SPR_NOACCESS
, SPR_NOACCESS
,
2437 &spr_read_403_pbr
, &spr_write_403_pbr
,
2439 spr_register(env
, SPR_403_PBL2
, "PBL2",
2440 SPR_NOACCESS
, SPR_NOACCESS
,
2441 &spr_read_403_pbr
, &spr_write_403_pbr
,
2443 spr_register(env
, SPR_403_PBU2
, "PBU2",
2444 SPR_NOACCESS
, SPR_NOACCESS
,
2445 &spr_read_403_pbr
, &spr_write_403_pbr
,
2449 static void gen_spr_403_mmu(CPUPPCState
*env
)
2452 spr_register(env
, SPR_40x_PID
, "PID",
2453 SPR_NOACCESS
, SPR_NOACCESS
,
2454 &spr_read_generic
, &spr_write_generic
,
2456 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2457 SPR_NOACCESS
, SPR_NOACCESS
,
2458 &spr_read_generic
, &spr_write_generic
,
2462 /* SPR specific to PowerPC compression coprocessor extension */
2463 static void gen_spr_compress(CPUPPCState
*env
)
2465 /* XXX : not implemented */
2466 spr_register(env
, SPR_401_SKR
, "SKR",
2467 SPR_NOACCESS
, SPR_NOACCESS
,
2468 &spr_read_generic
, &spr_write_generic
,
2472 static void gen_spr_5xx_8xx(CPUPPCState
*env
)
2474 /* Exception processing */
2475 spr_register_kvm(env
, SPR_DSISR
, "DSISR",
2476 SPR_NOACCESS
, SPR_NOACCESS
,
2477 &spr_read_generic
, &spr_write_generic
,
2478 KVM_REG_PPC_DSISR
, 0x00000000);
2479 spr_register_kvm(env
, SPR_DAR
, "DAR",
2480 SPR_NOACCESS
, SPR_NOACCESS
,
2481 &spr_read_generic
, &spr_write_generic
,
2482 KVM_REG_PPC_DAR
, 0x00000000);
2484 spr_register(env
, SPR_DECR
, "DECR",
2485 SPR_NOACCESS
, SPR_NOACCESS
,
2486 &spr_read_decr
, &spr_write_decr
,
2488 /* XXX : not implemented */
2489 spr_register(env
, SPR_MPC_EIE
, "EIE",
2490 SPR_NOACCESS
, SPR_NOACCESS
,
2491 &spr_read_generic
, &spr_write_generic
,
2493 /* XXX : not implemented */
2494 spr_register(env
, SPR_MPC_EID
, "EID",
2495 SPR_NOACCESS
, SPR_NOACCESS
,
2496 &spr_read_generic
, &spr_write_generic
,
2498 /* XXX : not implemented */
2499 spr_register(env
, SPR_MPC_NRI
, "NRI",
2500 SPR_NOACCESS
, SPR_NOACCESS
,
2501 &spr_read_generic
, &spr_write_generic
,
2503 /* XXX : not implemented */
2504 spr_register(env
, SPR_MPC_CMPA
, "CMPA",
2505 SPR_NOACCESS
, SPR_NOACCESS
,
2506 &spr_read_generic
, &spr_write_generic
,
2508 /* XXX : not implemented */
2509 spr_register(env
, SPR_MPC_CMPB
, "CMPB",
2510 SPR_NOACCESS
, SPR_NOACCESS
,
2511 &spr_read_generic
, &spr_write_generic
,
2513 /* XXX : not implemented */
2514 spr_register(env
, SPR_MPC_CMPC
, "CMPC",
2515 SPR_NOACCESS
, SPR_NOACCESS
,
2516 &spr_read_generic
, &spr_write_generic
,
2518 /* XXX : not implemented */
2519 spr_register(env
, SPR_MPC_CMPD
, "CMPD",
2520 SPR_NOACCESS
, SPR_NOACCESS
,
2521 &spr_read_generic
, &spr_write_generic
,
2523 /* XXX : not implemented */
2524 spr_register(env
, SPR_MPC_ECR
, "ECR",
2525 SPR_NOACCESS
, SPR_NOACCESS
,
2526 &spr_read_generic
, &spr_write_generic
,
2528 /* XXX : not implemented */
2529 spr_register(env
, SPR_MPC_DER
, "DER",
2530 SPR_NOACCESS
, SPR_NOACCESS
,
2531 &spr_read_generic
, &spr_write_generic
,
2533 /* XXX : not implemented */
2534 spr_register(env
, SPR_MPC_COUNTA
, "COUNTA",
2535 SPR_NOACCESS
, SPR_NOACCESS
,
2536 &spr_read_generic
, &spr_write_generic
,
2538 /* XXX : not implemented */
2539 spr_register(env
, SPR_MPC_COUNTB
, "COUNTB",
2540 SPR_NOACCESS
, SPR_NOACCESS
,
2541 &spr_read_generic
, &spr_write_generic
,
2543 /* XXX : not implemented */
2544 spr_register(env
, SPR_MPC_CMPE
, "CMPE",
2545 SPR_NOACCESS
, SPR_NOACCESS
,
2546 &spr_read_generic
, &spr_write_generic
,
2548 /* XXX : not implemented */
2549 spr_register(env
, SPR_MPC_CMPF
, "CMPF",
2550 SPR_NOACCESS
, SPR_NOACCESS
,
2551 &spr_read_generic
, &spr_write_generic
,
2553 /* XXX : not implemented */
2554 spr_register(env
, SPR_MPC_CMPG
, "CMPG",
2555 SPR_NOACCESS
, SPR_NOACCESS
,
2556 &spr_read_generic
, &spr_write_generic
,
2558 /* XXX : not implemented */
2559 spr_register(env
, SPR_MPC_CMPH
, "CMPH",
2560 SPR_NOACCESS
, SPR_NOACCESS
,
2561 &spr_read_generic
, &spr_write_generic
,
2563 /* XXX : not implemented */
2564 spr_register(env
, SPR_MPC_LCTRL1
, "LCTRL1",
2565 SPR_NOACCESS
, SPR_NOACCESS
,
2566 &spr_read_generic
, &spr_write_generic
,
2568 /* XXX : not implemented */
2569 spr_register(env
, SPR_MPC_LCTRL2
, "LCTRL2",
2570 SPR_NOACCESS
, SPR_NOACCESS
,
2571 &spr_read_generic
, &spr_write_generic
,
2573 /* XXX : not implemented */
2574 spr_register(env
, SPR_MPC_BAR
, "BAR",
2575 SPR_NOACCESS
, SPR_NOACCESS
,
2576 &spr_read_generic
, &spr_write_generic
,
2578 /* XXX : not implemented */
2579 spr_register(env
, SPR_MPC_DPDR
, "DPDR",
2580 SPR_NOACCESS
, SPR_NOACCESS
,
2581 &spr_read_generic
, &spr_write_generic
,
2583 /* XXX : not implemented */
2584 spr_register(env
, SPR_MPC_IMMR
, "IMMR",
2585 SPR_NOACCESS
, SPR_NOACCESS
,
2586 &spr_read_generic
, &spr_write_generic
,
2590 static void gen_spr_5xx(CPUPPCState
*env
)
2592 /* XXX : not implemented */
2593 spr_register(env
, SPR_RCPU_MI_GRA
, "MI_GRA",
2594 SPR_NOACCESS
, SPR_NOACCESS
,
2595 &spr_read_generic
, &spr_write_generic
,
2597 /* XXX : not implemented */
2598 spr_register(env
, SPR_RCPU_L2U_GRA
, "L2U_GRA",
2599 SPR_NOACCESS
, SPR_NOACCESS
,
2600 &spr_read_generic
, &spr_write_generic
,
2602 /* XXX : not implemented */
2603 spr_register(env
, SPR_RPCU_BBCMCR
, "L2U_BBCMCR",
2604 SPR_NOACCESS
, SPR_NOACCESS
,
2605 &spr_read_generic
, &spr_write_generic
,
2607 /* XXX : not implemented */
2608 spr_register(env
, SPR_RCPU_L2U_MCR
, "L2U_MCR",
2609 SPR_NOACCESS
, SPR_NOACCESS
,
2610 &spr_read_generic
, &spr_write_generic
,
2612 /* XXX : not implemented */
2613 spr_register(env
, SPR_RCPU_MI_RBA0
, "MI_RBA0",
2614 SPR_NOACCESS
, SPR_NOACCESS
,
2615 &spr_read_generic
, &spr_write_generic
,
2617 /* XXX : not implemented */
2618 spr_register(env
, SPR_RCPU_MI_RBA1
, "MI_RBA1",
2619 SPR_NOACCESS
, SPR_NOACCESS
,
2620 &spr_read_generic
, &spr_write_generic
,
2622 /* XXX : not implemented */
2623 spr_register(env
, SPR_RCPU_MI_RBA2
, "MI_RBA2",
2624 SPR_NOACCESS
, SPR_NOACCESS
,
2625 &spr_read_generic
, &spr_write_generic
,
2627 /* XXX : not implemented */
2628 spr_register(env
, SPR_RCPU_MI_RBA3
, "MI_RBA3",
2629 SPR_NOACCESS
, SPR_NOACCESS
,
2630 &spr_read_generic
, &spr_write_generic
,
2632 /* XXX : not implemented */
2633 spr_register(env
, SPR_RCPU_L2U_RBA0
, "L2U_RBA0",
2634 SPR_NOACCESS
, SPR_NOACCESS
,
2635 &spr_read_generic
, &spr_write_generic
,
2637 /* XXX : not implemented */
2638 spr_register(env
, SPR_RCPU_L2U_RBA1
, "L2U_RBA1",
2639 SPR_NOACCESS
, SPR_NOACCESS
,
2640 &spr_read_generic
, &spr_write_generic
,
2642 /* XXX : not implemented */
2643 spr_register(env
, SPR_RCPU_L2U_RBA2
, "L2U_RBA2",
2644 SPR_NOACCESS
, SPR_NOACCESS
,
2645 &spr_read_generic
, &spr_write_generic
,
2647 /* XXX : not implemented */
2648 spr_register(env
, SPR_RCPU_L2U_RBA3
, "L2U_RBA3",
2649 SPR_NOACCESS
, SPR_NOACCESS
,
2650 &spr_read_generic
, &spr_write_generic
,
2652 /* XXX : not implemented */
2653 spr_register(env
, SPR_RCPU_MI_RA0
, "MI_RA0",
2654 SPR_NOACCESS
, SPR_NOACCESS
,
2655 &spr_read_generic
, &spr_write_generic
,
2657 /* XXX : not implemented */
2658 spr_register(env
, SPR_RCPU_MI_RA1
, "MI_RA1",
2659 SPR_NOACCESS
, SPR_NOACCESS
,
2660 &spr_read_generic
, &spr_write_generic
,
2662 /* XXX : not implemented */
2663 spr_register(env
, SPR_RCPU_MI_RA2
, "MI_RA2",
2664 SPR_NOACCESS
, SPR_NOACCESS
,
2665 &spr_read_generic
, &spr_write_generic
,
2667 /* XXX : not implemented */
2668 spr_register(env
, SPR_RCPU_MI_RA3
, "MI_RA3",
2669 SPR_NOACCESS
, SPR_NOACCESS
,
2670 &spr_read_generic
, &spr_write_generic
,
2672 /* XXX : not implemented */
2673 spr_register(env
, SPR_RCPU_L2U_RA0
, "L2U_RA0",
2674 SPR_NOACCESS
, SPR_NOACCESS
,
2675 &spr_read_generic
, &spr_write_generic
,
2677 /* XXX : not implemented */
2678 spr_register(env
, SPR_RCPU_L2U_RA1
, "L2U_RA1",
2679 SPR_NOACCESS
, SPR_NOACCESS
,
2680 &spr_read_generic
, &spr_write_generic
,
2682 /* XXX : not implemented */
2683 spr_register(env
, SPR_RCPU_L2U_RA2
, "L2U_RA2",
2684 SPR_NOACCESS
, SPR_NOACCESS
,
2685 &spr_read_generic
, &spr_write_generic
,
2687 /* XXX : not implemented */
2688 spr_register(env
, SPR_RCPU_L2U_RA3
, "L2U_RA3",
2689 SPR_NOACCESS
, SPR_NOACCESS
,
2690 &spr_read_generic
, &spr_write_generic
,
2692 /* XXX : not implemented */
2693 spr_register(env
, SPR_RCPU_FPECR
, "FPECR",
2694 SPR_NOACCESS
, SPR_NOACCESS
,
2695 &spr_read_generic
, &spr_write_generic
,
2699 static void gen_spr_8xx(CPUPPCState
*env
)
2701 /* XXX : not implemented */
2702 spr_register(env
, SPR_MPC_IC_CST
, "IC_CST",
2703 SPR_NOACCESS
, SPR_NOACCESS
,
2704 &spr_read_generic
, &spr_write_generic
,
2706 /* XXX : not implemented */
2707 spr_register(env
, SPR_MPC_IC_ADR
, "IC_ADR",
2708 SPR_NOACCESS
, SPR_NOACCESS
,
2709 &spr_read_generic
, &spr_write_generic
,
2711 /* XXX : not implemented */
2712 spr_register(env
, SPR_MPC_IC_DAT
, "IC_DAT",
2713 SPR_NOACCESS
, SPR_NOACCESS
,
2714 &spr_read_generic
, &spr_write_generic
,
2716 /* XXX : not implemented */
2717 spr_register(env
, SPR_MPC_DC_CST
, "DC_CST",
2718 SPR_NOACCESS
, SPR_NOACCESS
,
2719 &spr_read_generic
, &spr_write_generic
,
2721 /* XXX : not implemented */
2722 spr_register(env
, SPR_MPC_DC_ADR
, "DC_ADR",
2723 SPR_NOACCESS
, SPR_NOACCESS
,
2724 &spr_read_generic
, &spr_write_generic
,
2726 /* XXX : not implemented */
2727 spr_register(env
, SPR_MPC_DC_DAT
, "DC_DAT",
2728 SPR_NOACCESS
, SPR_NOACCESS
,
2729 &spr_read_generic
, &spr_write_generic
,
2731 /* XXX : not implemented */
2732 spr_register(env
, SPR_MPC_MI_CTR
, "MI_CTR",
2733 SPR_NOACCESS
, SPR_NOACCESS
,
2734 &spr_read_generic
, &spr_write_generic
,
2736 /* XXX : not implemented */
2737 spr_register(env
, SPR_MPC_MI_AP
, "MI_AP",
2738 SPR_NOACCESS
, SPR_NOACCESS
,
2739 &spr_read_generic
, &spr_write_generic
,
2741 /* XXX : not implemented */
2742 spr_register(env
, SPR_MPC_MI_EPN
, "MI_EPN",
2743 SPR_NOACCESS
, SPR_NOACCESS
,
2744 &spr_read_generic
, &spr_write_generic
,
2746 /* XXX : not implemented */
2747 spr_register(env
, SPR_MPC_MI_TWC
, "MI_TWC",
2748 SPR_NOACCESS
, SPR_NOACCESS
,
2749 &spr_read_generic
, &spr_write_generic
,
2751 /* XXX : not implemented */
2752 spr_register(env
, SPR_MPC_MI_RPN
, "MI_RPN",
2753 SPR_NOACCESS
, SPR_NOACCESS
,
2754 &spr_read_generic
, &spr_write_generic
,
2756 /* XXX : not implemented */
2757 spr_register(env
, SPR_MPC_MI_DBCAM
, "MI_DBCAM",
2758 SPR_NOACCESS
, SPR_NOACCESS
,
2759 &spr_read_generic
, &spr_write_generic
,
2761 /* XXX : not implemented */
2762 spr_register(env
, SPR_MPC_MI_DBRAM0
, "MI_DBRAM0",
2763 SPR_NOACCESS
, SPR_NOACCESS
,
2764 &spr_read_generic
, &spr_write_generic
,
2766 /* XXX : not implemented */
2767 spr_register(env
, SPR_MPC_MI_DBRAM1
, "MI_DBRAM1",
2768 SPR_NOACCESS
, SPR_NOACCESS
,
2769 &spr_read_generic
, &spr_write_generic
,
2771 /* XXX : not implemented */
2772 spr_register(env
, SPR_MPC_MD_CTR
, "MD_CTR",
2773 SPR_NOACCESS
, SPR_NOACCESS
,
2774 &spr_read_generic
, &spr_write_generic
,
2776 /* XXX : not implemented */
2777 spr_register(env
, SPR_MPC_MD_CASID
, "MD_CASID",
2778 SPR_NOACCESS
, SPR_NOACCESS
,
2779 &spr_read_generic
, &spr_write_generic
,
2781 /* XXX : not implemented */
2782 spr_register(env
, SPR_MPC_MD_AP
, "MD_AP",
2783 SPR_NOACCESS
, SPR_NOACCESS
,
2784 &spr_read_generic
, &spr_write_generic
,
2786 /* XXX : not implemented */
2787 spr_register(env
, SPR_MPC_MD_EPN
, "MD_EPN",
2788 SPR_NOACCESS
, SPR_NOACCESS
,
2789 &spr_read_generic
, &spr_write_generic
,
2791 /* XXX : not implemented */
2792 spr_register(env
, SPR_MPC_MD_TWB
, "MD_TWB",
2793 SPR_NOACCESS
, SPR_NOACCESS
,
2794 &spr_read_generic
, &spr_write_generic
,
2796 /* XXX : not implemented */
2797 spr_register(env
, SPR_MPC_MD_TWC
, "MD_TWC",
2798 SPR_NOACCESS
, SPR_NOACCESS
,
2799 &spr_read_generic
, &spr_write_generic
,
2801 /* XXX : not implemented */
2802 spr_register(env
, SPR_MPC_MD_RPN
, "MD_RPN",
2803 SPR_NOACCESS
, SPR_NOACCESS
,
2804 &spr_read_generic
, &spr_write_generic
,
2806 /* XXX : not implemented */
2807 spr_register(env
, SPR_MPC_MD_TW
, "MD_TW",
2808 SPR_NOACCESS
, SPR_NOACCESS
,
2809 &spr_read_generic
, &spr_write_generic
,
2811 /* XXX : not implemented */
2812 spr_register(env
, SPR_MPC_MD_DBCAM
, "MD_DBCAM",
2813 SPR_NOACCESS
, SPR_NOACCESS
,
2814 &spr_read_generic
, &spr_write_generic
,
2816 /* XXX : not implemented */
2817 spr_register(env
, SPR_MPC_MD_DBRAM0
, "MD_DBRAM0",
2818 SPR_NOACCESS
, SPR_NOACCESS
,
2819 &spr_read_generic
, &spr_write_generic
,
2821 /* XXX : not implemented */
2822 spr_register(env
, SPR_MPC_MD_DBRAM1
, "MD_DBRAM1",
2823 SPR_NOACCESS
, SPR_NOACCESS
,
2824 &spr_read_generic
, &spr_write_generic
,
2829 * AMR => SPR 29 (Power 2.04)
2830 * CTRL => SPR 136 (Power 2.04)
2831 * CTRL => SPR 152 (Power 2.04)
2832 * SCOMC => SPR 276 (64 bits ?)
2833 * SCOMD => SPR 277 (64 bits ?)
2834 * TBU40 => SPR 286 (Power 2.04 hypv)
2835 * HSPRG0 => SPR 304 (Power 2.04 hypv)
2836 * HSPRG1 => SPR 305 (Power 2.04 hypv)
2837 * HDSISR => SPR 306 (Power 2.04 hypv)
2838 * HDAR => SPR 307 (Power 2.04 hypv)
2839 * PURR => SPR 309 (Power 2.04 hypv)
2840 * HDEC => SPR 310 (Power 2.04 hypv)
2841 * HIOR => SPR 311 (hypv)
2842 * RMOR => SPR 312 (970)
2843 * HRMOR => SPR 313 (Power 2.04 hypv)
2844 * HSRR0 => SPR 314 (Power 2.04 hypv)
2845 * HSRR1 => SPR 315 (Power 2.04 hypv)
2846 * LPIDR => SPR 317 (970)
2847 * EPR => SPR 702 (Power 2.04 emb)
2848 * perf => 768-783 (Power 2.04)
2849 * perf => 784-799 (Power 2.04)
2850 * PPR => SPR 896 (Power 2.04)
2851 * DABRX => 1015 (Power 2.04 hypv)
2852 * FPECR => SPR 1022 (?)
2853 * ... and more (thermal management, performance counters, ...)
2856 /*****************************************************************************/
2857 /* Exception vectors models */
2858 static void init_excp_4xx_real(CPUPPCState
*env
)
2860 #if !defined(CONFIG_USER_ONLY)
2861 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000100;
2862 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2863 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2864 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2865 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2866 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2867 env
->excp_vectors
[POWERPC_EXCP_PIT
] = 0x00001000;
2868 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00001010;
2869 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001020;
2870 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00002000;
2871 env
->ivor_mask
= 0x0000FFF0UL
;
2872 env
->ivpr_mask
= 0xFFFF0000UL
;
2873 /* Hardware reset vector */
2874 env
->hreset_vector
= 0xFFFFFFFCUL
;
2878 static void init_excp_4xx_softmmu(CPUPPCState
*env
)
2880 #if !defined(CONFIG_USER_ONLY)
2881 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000100;
2882 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2883 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2884 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2885 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2886 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2887 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2888 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2889 env
->excp_vectors
[POWERPC_EXCP_PIT
] = 0x00001000;
2890 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00001010;
2891 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001020;
2892 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00001100;
2893 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00001200;
2894 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00002000;
2895 env
->ivor_mask
= 0x0000FFF0UL
;
2896 env
->ivpr_mask
= 0xFFFF0000UL
;
2897 /* Hardware reset vector */
2898 env
->hreset_vector
= 0xFFFFFFFCUL
;
2902 static void init_excp_MPC5xx(CPUPPCState
*env
)
2904 #if !defined(CONFIG_USER_ONLY)
2905 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2906 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2907 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2908 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2909 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2910 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000900;
2911 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2912 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2913 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2914 env
->excp_vectors
[POWERPC_EXCP_FPA
] = 0x00000E00;
2915 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001000;
2916 env
->excp_vectors
[POWERPC_EXCP_DABR
] = 0x00001C00;
2917 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001C00;
2918 env
->excp_vectors
[POWERPC_EXCP_MEXTBR
] = 0x00001E00;
2919 env
->excp_vectors
[POWERPC_EXCP_NMEXTBR
] = 0x00001F00;
2920 env
->ivor_mask
= 0x0000FFF0UL
;
2921 env
->ivpr_mask
= 0xFFFF0000UL
;
2922 /* Hardware reset vector */
2923 env
->hreset_vector
= 0x00000100UL
;
2927 static void init_excp_MPC8xx(CPUPPCState
*env
)
2929 #if !defined(CONFIG_USER_ONLY)
2930 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2931 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2932 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2933 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2934 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2935 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2936 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2937 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000900;
2938 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2939 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2940 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2941 env
->excp_vectors
[POWERPC_EXCP_FPA
] = 0x00000E00;
2942 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001000;
2943 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00001100;
2944 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00001200;
2945 env
->excp_vectors
[POWERPC_EXCP_ITLBE
] = 0x00001300;
2946 env
->excp_vectors
[POWERPC_EXCP_DTLBE
] = 0x00001400;
2947 env
->excp_vectors
[POWERPC_EXCP_DABR
] = 0x00001C00;
2948 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001C00;
2949 env
->excp_vectors
[POWERPC_EXCP_MEXTBR
] = 0x00001E00;
2950 env
->excp_vectors
[POWERPC_EXCP_NMEXTBR
] = 0x00001F00;
2951 env
->ivor_mask
= 0x0000FFF0UL
;
2952 env
->ivpr_mask
= 0xFFFF0000UL
;
2953 /* Hardware reset vector */
2954 env
->hreset_vector
= 0x00000100UL
;
2958 static void init_excp_G2(CPUPPCState
*env
)
2960 #if !defined(CONFIG_USER_ONLY)
2961 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2962 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2963 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2964 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2965 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2966 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2967 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2968 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
2969 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2970 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000A00;
2971 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2972 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2973 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
2974 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
2975 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
2976 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
2977 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
2978 /* Hardware reset vector */
2979 env
->hreset_vector
= 0x00000100UL
;
2983 static void init_excp_e200(CPUPPCState
*env
, target_ulong ivpr_mask
)
2985 #if !defined(CONFIG_USER_ONLY)
2986 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000FFC;
2987 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000000;
2988 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000000;
2989 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000000;
2990 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000000;
2991 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000000;
2992 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000000;
2993 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000000;
2994 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000000;
2995 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000000;
2996 env
->excp_vectors
[POWERPC_EXCP_APU
] = 0x00000000;
2997 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000000;
2998 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00000000;
2999 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00000000;
3000 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00000000;
3001 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00000000;
3002 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00000000;
3003 env
->excp_vectors
[POWERPC_EXCP_SPEU
] = 0x00000000;
3004 env
->excp_vectors
[POWERPC_EXCP_EFPDI
] = 0x00000000;
3005 env
->excp_vectors
[POWERPC_EXCP_EFPRI
] = 0x00000000;
3006 env
->ivor_mask
= 0x0000FFF7UL
;
3007 env
->ivpr_mask
= ivpr_mask
;
3008 /* Hardware reset vector */
3009 env
->hreset_vector
= 0xFFFFFFFCUL
;
3013 static void init_excp_BookE(CPUPPCState
*env
)
3015 #if !defined(CONFIG_USER_ONLY)
3016 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000000;
3017 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000000;
3018 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000000;
3019 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000000;
3020 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000000;
3021 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000000;
3022 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000000;
3023 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000000;
3024 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000000;
3025 env
->excp_vectors
[POWERPC_EXCP_APU
] = 0x00000000;
3026 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000000;
3027 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00000000;
3028 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00000000;
3029 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00000000;
3030 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00000000;
3031 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00000000;
3032 env
->ivor_mask
= 0x0000FFF0UL
;
3033 env
->ivpr_mask
= 0xFFFF0000UL
;
3034 /* Hardware reset vector */
3035 env
->hreset_vector
= 0xFFFFFFFCUL
;
3039 static void init_excp_601(CPUPPCState
*env
)
3041 #if !defined(CONFIG_USER_ONLY)
3042 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3043 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3044 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3045 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3046 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3047 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3048 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3049 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3050 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3051 env
->excp_vectors
[POWERPC_EXCP_IO
] = 0x00000A00;
3052 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3053 env
->excp_vectors
[POWERPC_EXCP_RUNM
] = 0x00002000;
3054 /* Hardware reset vector */
3055 env
->hreset_vector
= 0x00000100UL
;
3059 static void init_excp_602(CPUPPCState
*env
)
3061 #if !defined(CONFIG_USER_ONLY)
3062 /* XXX: exception prefix has a special behavior on 602 */
3063 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3064 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3065 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3066 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3067 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3068 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3069 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3070 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3071 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3072 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3073 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3074 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3075 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3076 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3077 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3078 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3079 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001500;
3080 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001600;
3081 /* Hardware reset vector */
3082 env
->hreset_vector
= 0x00000100UL
;
3086 static void init_excp_603(CPUPPCState
*env
)
3088 #if !defined(CONFIG_USER_ONLY)
3089 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3090 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3091 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3092 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3093 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3094 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3095 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3096 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3097 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3098 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3099 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3100 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3101 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3102 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3103 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3104 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3105 /* Hardware reset vector */
3106 env
->hreset_vector
= 0x00000100UL
;
3110 static void init_excp_604(CPUPPCState
*env
)
3112 #if !defined(CONFIG_USER_ONLY)
3113 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3114 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3115 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3116 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3117 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3118 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3119 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3120 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3121 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3122 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3123 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3124 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3125 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3126 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3127 /* Hardware reset vector */
3128 env
->hreset_vector
= 0x00000100UL
;
3132 static void init_excp_7x0(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_IABR
] = 0x00001300;
3148 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3149 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3150 /* Hardware reset vector */
3151 env
->hreset_vector
= 0x00000100UL
;
3155 static void init_excp_750cl(CPUPPCState
*env
)
3157 #if !defined(CONFIG_USER_ONLY)
3158 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3159 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3160 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3161 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3162 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3163 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3164 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3165 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3166 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3167 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3168 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3169 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3170 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3171 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3172 /* Hardware reset vector */
3173 env
->hreset_vector
= 0x00000100UL
;
3177 static void init_excp_750cx(CPUPPCState
*env
)
3179 #if !defined(CONFIG_USER_ONLY)
3180 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3181 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3182 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3183 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3184 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3185 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3186 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3187 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3188 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3189 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3190 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3191 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3192 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3193 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3194 /* Hardware reset vector */
3195 env
->hreset_vector
= 0x00000100UL
;
3199 /* XXX: Check if this is correct */
3200 static void init_excp_7x5(CPUPPCState
*env
)
3202 #if !defined(CONFIG_USER_ONLY)
3203 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3204 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3205 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3206 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3207 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3208 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3209 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3210 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3211 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3212 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3213 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3214 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3215 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3216 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3217 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3218 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3219 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3220 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3221 /* Hardware reset vector */
3222 env
->hreset_vector
= 0x00000100UL
;
3226 static void init_excp_7400(CPUPPCState
*env
)
3228 #if !defined(CONFIG_USER_ONLY)
3229 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3230 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3231 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3232 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3233 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3234 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3235 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3236 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3237 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3238 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3239 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3240 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3241 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3242 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3243 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3244 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001600;
3245 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3246 /* Hardware reset vector */
3247 env
->hreset_vector
= 0x00000100UL
;
3251 static void init_excp_7450(CPUPPCState
*env
)
3253 #if !defined(CONFIG_USER_ONLY)
3254 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3255 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3256 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3257 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3258 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3259 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3260 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3261 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3262 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3263 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3264 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3265 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3266 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3267 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3268 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3269 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3270 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3271 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3272 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001600;
3273 /* Hardware reset vector */
3274 env
->hreset_vector
= 0x00000100UL
;
3278 #if defined(TARGET_PPC64)
3279 static void init_excp_970(CPUPPCState
*env
)
3281 #if !defined(CONFIG_USER_ONLY)
3282 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3283 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3284 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3285 env
->excp_vectors
[POWERPC_EXCP_DSEG
] = 0x00000380;
3286 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3287 env
->excp_vectors
[POWERPC_EXCP_ISEG
] = 0x00000480;
3288 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3289 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3290 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3291 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3292 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3293 env
->excp_vectors
[POWERPC_EXCP_HDECR
] = 0x00000980;
3294 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3295 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3296 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3297 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3298 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3299 env
->excp_vectors
[POWERPC_EXCP_MAINT
] = 0x00001600;
3300 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001700;
3301 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001800;
3302 /* Hardware reset vector */
3303 env
->hreset_vector
= 0x0000000000000100ULL
;
3307 static void init_excp_POWER7(CPUPPCState
*env
)
3309 #if !defined(CONFIG_USER_ONLY)
3310 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3311 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3312 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3313 env
->excp_vectors
[POWERPC_EXCP_DSEG
] = 0x00000380;
3314 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3315 env
->excp_vectors
[POWERPC_EXCP_ISEG
] = 0x00000480;
3316 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3317 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3318 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3319 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3320 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3321 env
->excp_vectors
[POWERPC_EXCP_HDECR
] = 0x00000980;
3322 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3323 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3324 env
->excp_vectors
[POWERPC_EXCP_HDSI
] = 0x00000E00;
3325 env
->excp_vectors
[POWERPC_EXCP_HISI
] = 0x00000E20;
3326 env
->excp_vectors
[POWERPC_EXCP_HV_EMU
] = 0x00000E40;
3327 env
->excp_vectors
[POWERPC_EXCP_HV_MAINT
] = 0x00000E60;
3328 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3329 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3330 env
->excp_vectors
[POWERPC_EXCP_VSXU
] = 0x00000F40;
3331 /* Hardware reset vector */
3332 env
->hreset_vector
= 0x0000000000000100ULL
;
3336 static void init_excp_POWER8(CPUPPCState
*env
)
3338 init_excp_POWER7(env
);
3340 #if !defined(CONFIG_USER_ONLY)
3341 env
->excp_vectors
[POWERPC_EXCP_SDOOR
] = 0x00000A00;
3342 env
->excp_vectors
[POWERPC_EXCP_FU
] = 0x00000F60;
3343 env
->excp_vectors
[POWERPC_EXCP_HV_FU
] = 0x00000F80;
3344 env
->excp_vectors
[POWERPC_EXCP_SDOOR_HV
] = 0x00000E80;
3348 static void init_excp_POWER9(CPUPPCState
*env
)
3350 init_excp_POWER8(env
);
3352 #if !defined(CONFIG_USER_ONLY)
3353 env
->excp_vectors
[POWERPC_EXCP_HVIRT
] = 0x00000EA0;
3359 /*****************************************************************************/
3360 /* Power management enable checks */
3361 static int check_pow_none(CPUPPCState
*env
)
3366 static int check_pow_nocheck(CPUPPCState
*env
)
3371 static int check_pow_hid0(CPUPPCState
*env
)
3373 if (env
->spr
[SPR_HID0
] & 0x00E00000) {
3380 static int check_pow_hid0_74xx(CPUPPCState
*env
)
3382 if (env
->spr
[SPR_HID0
] & 0x00600000) {
3389 static bool ppc_cpu_interrupts_big_endian_always(PowerPCCPU
*cpu
)
3395 static bool ppc_cpu_interrupts_big_endian_lpcr(PowerPCCPU
*cpu
)
3397 return !(cpu
->env
.spr
[SPR_LPCR
] & LPCR_ILE
);
3401 /*****************************************************************************/
3402 /* PowerPC implementations definitions */
3404 #define POWERPC_FAMILY(_name) \
3406 glue(glue(ppc_, _name), _cpu_family_class_init)(ObjectClass *, void *); \
3408 static const TypeInfo \
3409 glue(glue(ppc_, _name), _cpu_family_type_info) = { \
3410 .name = stringify(_name) "-family-" TYPE_POWERPC_CPU, \
3411 .parent = TYPE_POWERPC_CPU, \
3413 .class_init = glue(glue(ppc_, _name), _cpu_family_class_init), \
3416 static void glue(glue(ppc_, _name), _cpu_family_register_types)(void) \
3418 type_register_static( \
3419 &glue(glue(ppc_, _name), _cpu_family_type_info)); \
3422 type_init(glue(glue(ppc_, _name), _cpu_family_register_types)) \
3424 static void glue(glue(ppc_, _name), _cpu_family_class_init)
3426 static void init_proc_401(CPUPPCState
*env
)
3429 gen_spr_401_403(env
);
3431 init_excp_4xx_real(env
);
3432 env
->dcache_line_size
= 32;
3433 env
->icache_line_size
= 32;
3434 /* Allocate hardware IRQ controller */
3435 ppc40x_irq_init(env_archcpu(env
));
3437 SET_FIT_PERIOD(12, 16, 20, 24);
3438 SET_WDT_PERIOD(16, 20, 24, 28);
3441 POWERPC_FAMILY(401)(ObjectClass
*oc
, void *data
)
3443 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3444 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3446 dc
->desc
= "PowerPC 401";
3447 pcc
->init_proc
= init_proc_401
;
3448 pcc
->check_pow
= check_pow_nocheck
;
3449 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3450 PPC_WRTEE
| PPC_DCR
|
3451 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3453 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3454 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3455 pcc
->msr_mask
= (1ull << MSR_KEY
) |
3464 pcc
->mmu_model
= POWERPC_MMU_REAL
;
3465 pcc
->excp_model
= POWERPC_EXCP_40x
;
3466 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3467 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3468 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3469 POWERPC_FLAG_BUS_CLK
;
3472 static void init_proc_401x2(CPUPPCState
*env
)
3475 gen_spr_401_403(env
);
3477 gen_spr_compress(env
);
3478 /* Memory management */
3479 #if !defined(CONFIG_USER_ONLY)
3483 env
->tlb_type
= TLB_EMB
;
3485 init_excp_4xx_softmmu(env
);
3486 env
->dcache_line_size
= 32;
3487 env
->icache_line_size
= 32;
3488 /* Allocate hardware IRQ controller */
3489 ppc40x_irq_init(env_archcpu(env
));
3491 SET_FIT_PERIOD(12, 16, 20, 24);
3492 SET_WDT_PERIOD(16, 20, 24, 28);
3495 POWERPC_FAMILY(401x2
)(ObjectClass
*oc
, void *data
)
3497 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3498 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3500 dc
->desc
= "PowerPC 401x2";
3501 pcc
->init_proc
= init_proc_401x2
;
3502 pcc
->check_pow
= check_pow_nocheck
;
3503 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3504 PPC_DCR
| PPC_WRTEE
|
3505 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3506 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3507 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3508 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3509 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3510 pcc
->msr_mask
= (1ull << 20) |
3522 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3523 pcc
->excp_model
= POWERPC_EXCP_40x
;
3524 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3525 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3526 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3527 POWERPC_FLAG_BUS_CLK
;
3530 static void init_proc_401x3(CPUPPCState
*env
)
3533 gen_spr_401_403(env
);
3536 gen_spr_compress(env
);
3537 init_excp_4xx_softmmu(env
);
3538 env
->dcache_line_size
= 32;
3539 env
->icache_line_size
= 32;
3540 /* Allocate hardware IRQ controller */
3541 ppc40x_irq_init(env_archcpu(env
));
3543 SET_FIT_PERIOD(12, 16, 20, 24);
3544 SET_WDT_PERIOD(16, 20, 24, 28);
3547 POWERPC_FAMILY(401x3
)(ObjectClass
*oc
, void *data
)
3549 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3550 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3552 dc
->desc
= "PowerPC 401x3";
3553 pcc
->init_proc
= init_proc_401x3
;
3554 pcc
->check_pow
= check_pow_nocheck
;
3555 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3556 PPC_DCR
| PPC_WRTEE
|
3557 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3558 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3559 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3560 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3561 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3562 pcc
->msr_mask
= (1ull << 20) |
3575 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
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_DE
|
3580 POWERPC_FLAG_BUS_CLK
;
3583 static void init_proc_IOP480(CPUPPCState
*env
)
3586 gen_spr_401_403(env
);
3588 gen_spr_compress(env
);
3589 /* Memory management */
3590 #if !defined(CONFIG_USER_ONLY)
3594 env
->tlb_type
= TLB_EMB
;
3596 init_excp_4xx_softmmu(env
);
3597 env
->dcache_line_size
= 32;
3598 env
->icache_line_size
= 32;
3599 /* Allocate hardware IRQ controller */
3600 ppc40x_irq_init(env_archcpu(env
));
3602 SET_FIT_PERIOD(8, 12, 16, 20);
3603 SET_WDT_PERIOD(16, 20, 24, 28);
3606 POWERPC_FAMILY(IOP480
)(ObjectClass
*oc
, void *data
)
3608 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3609 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3611 dc
->desc
= "IOP480";
3612 pcc
->init_proc
= init_proc_IOP480
;
3613 pcc
->check_pow
= check_pow_nocheck
;
3614 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3615 PPC_DCR
| PPC_WRTEE
|
3616 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3617 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3618 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3619 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3620 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3621 pcc
->msr_mask
= (1ull << 20) |
3633 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3634 pcc
->excp_model
= POWERPC_EXCP_40x
;
3635 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3636 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3637 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3638 POWERPC_FLAG_BUS_CLK
;
3641 static void init_proc_403(CPUPPCState
*env
)
3644 gen_spr_401_403(env
);
3646 gen_spr_403_real(env
);
3647 init_excp_4xx_real(env
);
3648 env
->dcache_line_size
= 32;
3649 env
->icache_line_size
= 32;
3650 /* Allocate hardware IRQ controller */
3651 ppc40x_irq_init(env_archcpu(env
));
3653 SET_FIT_PERIOD(8, 12, 16, 20);
3654 SET_WDT_PERIOD(16, 20, 24, 28);
3657 POWERPC_FAMILY(403)(ObjectClass
*oc
, void *data
)
3659 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3660 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3662 dc
->desc
= "PowerPC 403";
3663 pcc
->init_proc
= init_proc_403
;
3664 pcc
->check_pow
= check_pow_nocheck
;
3665 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3666 PPC_DCR
| PPC_WRTEE
|
3667 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3669 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3670 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3671 pcc
->msr_mask
= (1ull << MSR_POW
) |
3680 pcc
->mmu_model
= POWERPC_MMU_REAL
;
3681 pcc
->excp_model
= POWERPC_EXCP_40x
;
3682 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3683 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3684 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_PX
|
3685 POWERPC_FLAG_BUS_CLK
;
3688 static void init_proc_403GCX(CPUPPCState
*env
)
3691 gen_spr_401_403(env
);
3693 gen_spr_403_real(env
);
3694 gen_spr_403_mmu(env
);
3695 /* Bus access control */
3696 /* not emulated, as QEMU never does speculative access */
3697 spr_register(env
, SPR_40x_SGR
, "SGR",
3698 SPR_NOACCESS
, SPR_NOACCESS
,
3699 &spr_read_generic
, &spr_write_generic
,
3701 /* not emulated, as QEMU do not emulate caches */
3702 spr_register(env
, SPR_40x_DCWR
, "DCWR",
3703 SPR_NOACCESS
, SPR_NOACCESS
,
3704 &spr_read_generic
, &spr_write_generic
,
3706 /* Memory management */
3707 #if !defined(CONFIG_USER_ONLY)
3711 env
->tlb_type
= TLB_EMB
;
3713 init_excp_4xx_softmmu(env
);
3714 env
->dcache_line_size
= 32;
3715 env
->icache_line_size
= 32;
3716 /* Allocate hardware IRQ controller */
3717 ppc40x_irq_init(env_archcpu(env
));
3719 SET_FIT_PERIOD(8, 12, 16, 20);
3720 SET_WDT_PERIOD(16, 20, 24, 28);
3723 POWERPC_FAMILY(403GCX
)(ObjectClass
*oc
, void *data
)
3725 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3726 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3728 dc
->desc
= "PowerPC 403 GCX";
3729 pcc
->init_proc
= init_proc_403GCX
;
3730 pcc
->check_pow
= check_pow_nocheck
;
3731 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3732 PPC_DCR
| PPC_WRTEE
|
3733 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3735 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3736 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3737 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3738 pcc
->msr_mask
= (1ull << MSR_POW
) |
3747 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3748 pcc
->excp_model
= POWERPC_EXCP_40x
;
3749 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3750 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3751 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_PX
|
3752 POWERPC_FLAG_BUS_CLK
;
3755 static void init_proc_405(CPUPPCState
*env
)
3761 /* Bus access control */
3762 /* not emulated, as QEMU never does speculative access */
3763 spr_register(env
, SPR_40x_SGR
, "SGR",
3764 SPR_NOACCESS
, SPR_NOACCESS
,
3765 &spr_read_generic
, &spr_write_generic
,
3767 /* not emulated, as QEMU do not emulate caches */
3768 spr_register(env
, SPR_40x_DCWR
, "DCWR",
3769 SPR_NOACCESS
, SPR_NOACCESS
,
3770 &spr_read_generic
, &spr_write_generic
,
3772 /* Memory management */
3773 #if !defined(CONFIG_USER_ONLY)
3777 env
->tlb_type
= TLB_EMB
;
3779 init_excp_4xx_softmmu(env
);
3780 env
->dcache_line_size
= 32;
3781 env
->icache_line_size
= 32;
3782 /* Allocate hardware IRQ controller */
3783 ppc40x_irq_init(env_archcpu(env
));
3785 SET_FIT_PERIOD(8, 12, 16, 20);
3786 SET_WDT_PERIOD(16, 20, 24, 28);
3789 POWERPC_FAMILY(405)(ObjectClass
*oc
, void *data
)
3791 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3792 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3794 dc
->desc
= "PowerPC 405";
3795 pcc
->init_proc
= init_proc_405
;
3796 pcc
->check_pow
= check_pow_nocheck
;
3797 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3798 PPC_DCR
| PPC_WRTEE
|
3799 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3800 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3801 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3802 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3803 PPC_4xx_COMMON
| PPC_405_MAC
| PPC_40x_EXCP
;
3804 pcc
->msr_mask
= (1ull << MSR_POW
) |
3813 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx
;
3814 pcc
->excp_model
= POWERPC_EXCP_40x
;
3815 pcc
->bus_model
= PPC_FLAGS_INPUT_405
;
3816 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3817 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3818 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3821 static void init_proc_440EP(CPUPPCState
*env
)
3825 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3827 gen_spr_usprgh(env
);
3828 /* Processor identification */
3829 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3830 SPR_NOACCESS
, SPR_NOACCESS
,
3831 &spr_read_generic
, &spr_write_pir
,
3833 /* XXX : not implemented */
3834 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
3835 SPR_NOACCESS
, SPR_NOACCESS
,
3836 &spr_read_generic
, &spr_write_generic
,
3838 /* XXX : not implemented */
3839 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
3840 SPR_NOACCESS
, SPR_NOACCESS
,
3841 &spr_read_generic
, &spr_write_generic
,
3843 /* XXX : not implemented */
3844 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
3845 SPR_NOACCESS
, SPR_NOACCESS
,
3846 &spr_read_generic
, &spr_write_generic
,
3848 /* XXX : not implemented */
3849 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
3850 SPR_NOACCESS
, SPR_NOACCESS
,
3851 &spr_read_generic
, &spr_write_generic
,
3853 /* XXX : not implemented */
3854 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
3855 SPR_NOACCESS
, SPR_NOACCESS
,
3856 &spr_read_generic
, &spr_write_generic
,
3858 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
3859 SPR_NOACCESS
, SPR_NOACCESS
,
3860 &spr_read_generic
, &spr_write_generic
,
3862 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
3863 SPR_NOACCESS
, SPR_NOACCESS
,
3864 &spr_read_generic
, &spr_write_generic
,
3866 /* XXX : not implemented */
3867 spr_register(env
, SPR_440_CCR1
, "CCR1",
3868 SPR_NOACCESS
, SPR_NOACCESS
,
3869 &spr_read_generic
, &spr_write_generic
,
3871 /* Memory management */
3872 #if !defined(CONFIG_USER_ONLY)
3876 env
->tlb_type
= TLB_EMB
;
3878 init_excp_BookE(env
);
3879 env
->dcache_line_size
= 32;
3880 env
->icache_line_size
= 32;
3881 ppc40x_irq_init(env_archcpu(env
));
3883 SET_FIT_PERIOD(12, 16, 20, 24);
3884 SET_WDT_PERIOD(20, 24, 28, 32);
3887 POWERPC_FAMILY(440EP
)(ObjectClass
*oc
, void *data
)
3889 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3890 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3892 dc
->desc
= "PowerPC 440 EP";
3893 pcc
->init_proc
= init_proc_440EP
;
3894 pcc
->check_pow
= check_pow_nocheck
;
3895 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3896 PPC_FLOAT
| PPC_FLOAT_FRES
| PPC_FLOAT_FSEL
|
3897 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
3899 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
3900 PPC_CACHE
| PPC_CACHE_ICBI
|
3901 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3902 PPC_MEM_TLBSYNC
| PPC_MFTB
|
3903 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3905 pcc
->msr_mask
= (1ull << MSR_POW
) |
3917 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3918 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3919 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3920 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3921 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3922 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3925 POWERPC_FAMILY(460EX
)(ObjectClass
*oc
, void *data
)
3927 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3928 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3930 dc
->desc
= "PowerPC 460 EX";
3931 pcc
->init_proc
= init_proc_440EP
;
3932 pcc
->check_pow
= check_pow_nocheck
;
3933 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3934 PPC_FLOAT
| PPC_FLOAT_FRES
| PPC_FLOAT_FSEL
|
3935 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
3937 PPC_DCR
| PPC_DCRX
| PPC_WRTEE
| PPC_RFMCI
|
3938 PPC_CACHE
| PPC_CACHE_ICBI
|
3939 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3940 PPC_MEM_TLBSYNC
| PPC_MFTB
|
3941 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3943 pcc
->msr_mask
= (1ull << MSR_POW
) |
3955 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3956 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3957 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3958 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3959 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3960 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3963 static void init_proc_440GP(CPUPPCState
*env
)
3967 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3969 gen_spr_usprgh(env
);
3970 /* Processor identification */
3971 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3972 SPR_NOACCESS
, SPR_NOACCESS
,
3973 &spr_read_generic
, &spr_write_pir
,
3975 /* XXX : not implemented */
3976 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
3977 SPR_NOACCESS
, SPR_NOACCESS
,
3978 &spr_read_generic
, &spr_write_generic
,
3980 /* XXX : not implemented */
3981 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
3982 SPR_NOACCESS
, SPR_NOACCESS
,
3983 &spr_read_generic
, &spr_write_generic
,
3985 /* XXX : not implemented */
3986 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
3987 SPR_NOACCESS
, SPR_NOACCESS
,
3988 &spr_read_generic
, &spr_write_generic
,
3990 /* XXX : not implemented */
3991 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
3992 SPR_NOACCESS
, SPR_NOACCESS
,
3993 &spr_read_generic
, &spr_write_generic
,
3995 /* Memory management */
3996 #if !defined(CONFIG_USER_ONLY)
4000 env
->tlb_type
= TLB_EMB
;
4002 init_excp_BookE(env
);
4003 env
->dcache_line_size
= 32;
4004 env
->icache_line_size
= 32;
4005 /* XXX: TODO: allocate internal IRQ controller */
4007 SET_FIT_PERIOD(12, 16, 20, 24);
4008 SET_WDT_PERIOD(20, 24, 28, 32);
4011 POWERPC_FAMILY(440GP
)(ObjectClass
*oc
, void *data
)
4013 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4014 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4016 dc
->desc
= "PowerPC 440 GP";
4017 pcc
->init_proc
= init_proc_440GP
;
4018 pcc
->check_pow
= check_pow_nocheck
;
4019 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4020 PPC_DCR
| PPC_DCRX
| PPC_WRTEE
| PPC_MFAPIDI
|
4021 PPC_CACHE
| PPC_CACHE_ICBI
|
4022 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4023 PPC_MEM_TLBSYNC
| PPC_TLBIVA
| PPC_MFTB
|
4024 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4026 pcc
->msr_mask
= (1ull << MSR_POW
) |
4038 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4039 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4040 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4041 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4042 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4043 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4046 static void init_proc_440x4(CPUPPCState
*env
)
4050 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
4052 gen_spr_usprgh(env
);
4053 /* Processor identification */
4054 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4055 SPR_NOACCESS
, SPR_NOACCESS
,
4056 &spr_read_generic
, &spr_write_pir
,
4058 /* XXX : not implemented */
4059 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4060 SPR_NOACCESS
, SPR_NOACCESS
,
4061 &spr_read_generic
, &spr_write_generic
,
4063 /* XXX : not implemented */
4064 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4065 SPR_NOACCESS
, SPR_NOACCESS
,
4066 &spr_read_generic
, &spr_write_generic
,
4068 /* XXX : not implemented */
4069 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
4070 SPR_NOACCESS
, SPR_NOACCESS
,
4071 &spr_read_generic
, &spr_write_generic
,
4073 /* XXX : not implemented */
4074 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
4075 SPR_NOACCESS
, SPR_NOACCESS
,
4076 &spr_read_generic
, &spr_write_generic
,
4078 /* Memory management */
4079 #if !defined(CONFIG_USER_ONLY)
4083 env
->tlb_type
= TLB_EMB
;
4085 init_excp_BookE(env
);
4086 env
->dcache_line_size
= 32;
4087 env
->icache_line_size
= 32;
4088 /* XXX: TODO: allocate internal IRQ controller */
4090 SET_FIT_PERIOD(12, 16, 20, 24);
4091 SET_WDT_PERIOD(20, 24, 28, 32);
4094 POWERPC_FAMILY(440x4
)(ObjectClass
*oc
, void *data
)
4096 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4097 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4099 dc
->desc
= "PowerPC 440x4";
4100 pcc
->init_proc
= init_proc_440x4
;
4101 pcc
->check_pow
= check_pow_nocheck
;
4102 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4103 PPC_DCR
| PPC_WRTEE
|
4104 PPC_CACHE
| PPC_CACHE_ICBI
|
4105 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4106 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4107 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4109 pcc
->msr_mask
= (1ull << MSR_POW
) |
4121 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4122 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4123 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4124 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4125 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4126 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4129 static void init_proc_440x5(CPUPPCState
*env
)
4133 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
4135 gen_spr_usprgh(env
);
4136 /* Processor identification */
4137 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4138 SPR_NOACCESS
, SPR_NOACCESS
,
4139 &spr_read_generic
, &spr_write_pir
,
4141 /* XXX : not implemented */
4142 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4143 SPR_NOACCESS
, SPR_NOACCESS
,
4144 &spr_read_generic
, &spr_write_generic
,
4146 /* XXX : not implemented */
4147 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4148 SPR_NOACCESS
, SPR_NOACCESS
,
4149 &spr_read_generic
, &spr_write_generic
,
4151 /* XXX : not implemented */
4152 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
4153 SPR_NOACCESS
, SPR_NOACCESS
,
4154 &spr_read_generic
, &spr_write_generic
,
4156 /* XXX : not implemented */
4157 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
4158 SPR_NOACCESS
, SPR_NOACCESS
,
4159 &spr_read_generic
, &spr_write_generic
,
4161 /* XXX : not implemented */
4162 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
4163 SPR_NOACCESS
, SPR_NOACCESS
,
4164 &spr_read_generic
, &spr_write_generic
,
4166 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
4167 SPR_NOACCESS
, SPR_NOACCESS
,
4168 &spr_read_generic
, &spr_write_generic
,
4170 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
4171 SPR_NOACCESS
, SPR_NOACCESS
,
4172 &spr_read_generic
, &spr_write_generic
,
4174 /* XXX : not implemented */
4175 spr_register(env
, SPR_440_CCR1
, "CCR1",
4176 SPR_NOACCESS
, SPR_NOACCESS
,
4177 &spr_read_generic
, &spr_write_generic
,
4179 /* Memory management */
4180 #if !defined(CONFIG_USER_ONLY)
4184 env
->tlb_type
= TLB_EMB
;
4186 init_excp_BookE(env
);
4187 env
->dcache_line_size
= 32;
4188 env
->icache_line_size
= 32;
4189 ppc40x_irq_init(env_archcpu(env
));
4191 SET_FIT_PERIOD(12, 16, 20, 24);
4192 SET_WDT_PERIOD(20, 24, 28, 32);
4195 POWERPC_FAMILY(440x5
)(ObjectClass
*oc
, void *data
)
4197 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4198 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4200 dc
->desc
= "PowerPC 440x5";
4201 pcc
->init_proc
= init_proc_440x5
;
4202 pcc
->check_pow
= check_pow_nocheck
;
4203 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4204 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
4205 PPC_CACHE
| PPC_CACHE_ICBI
|
4206 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4207 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4208 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4210 pcc
->msr_mask
= (1ull << MSR_POW
) |
4222 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4223 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4224 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4225 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4226 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4227 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4230 POWERPC_FAMILY(440x5wDFPU
)(ObjectClass
*oc
, void *data
)
4232 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4233 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4235 dc
->desc
= "PowerPC 440x5 with double precision FPU";
4236 pcc
->init_proc
= init_proc_440x5
;
4237 pcc
->check_pow
= check_pow_nocheck
;
4238 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4239 PPC_FLOAT
| PPC_FLOAT_FSQRT
|
4241 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
4242 PPC_CACHE
| PPC_CACHE_ICBI
|
4243 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4244 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4245 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4247 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
4248 pcc
->msr_mask
= (1ull << MSR_POW
) |
4260 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4261 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4262 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4263 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4264 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4265 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4268 static void init_proc_MPC5xx(CPUPPCState
*env
)
4272 gen_spr_5xx_8xx(env
);
4274 init_excp_MPC5xx(env
);
4275 env
->dcache_line_size
= 32;
4276 env
->icache_line_size
= 32;
4277 /* XXX: TODO: allocate internal IRQ controller */
4280 POWERPC_FAMILY(MPC5xx
)(ObjectClass
*oc
, void *data
)
4282 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4283 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4285 dc
->desc
= "Freescale 5xx cores (aka RCPU)";
4286 pcc
->init_proc
= init_proc_MPC5xx
;
4287 pcc
->check_pow
= check_pow_none
;
4288 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4289 PPC_MEM_EIEIO
| PPC_MEM_SYNC
|
4290 PPC_CACHE_ICBI
| PPC_FLOAT
| PPC_FLOAT_STFIWX
|
4292 pcc
->msr_mask
= (1ull << MSR_ILE
) |
4304 pcc
->mmu_model
= POWERPC_MMU_REAL
;
4305 pcc
->excp_model
= POWERPC_EXCP_603
;
4306 pcc
->bus_model
= PPC_FLAGS_INPUT_RCPU
;
4307 pcc
->bfd_mach
= bfd_mach_ppc_505
;
4308 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
4309 POWERPC_FLAG_BUS_CLK
;
4312 static void init_proc_MPC8xx(CPUPPCState
*env
)
4316 gen_spr_5xx_8xx(env
);
4318 init_excp_MPC8xx(env
);
4319 env
->dcache_line_size
= 32;
4320 env
->icache_line_size
= 32;
4321 /* XXX: TODO: allocate internal IRQ controller */
4324 POWERPC_FAMILY(MPC8xx
)(ObjectClass
*oc
, void *data
)
4326 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4327 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4329 dc
->desc
= "Freescale 8xx cores (aka PowerQUICC)";
4330 pcc
->init_proc
= init_proc_MPC8xx
;
4331 pcc
->check_pow
= check_pow_none
;
4332 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4333 PPC_MEM_EIEIO
| PPC_MEM_SYNC
|
4334 PPC_CACHE_ICBI
| PPC_MFTB
;
4335 pcc
->msr_mask
= (1ull << MSR_ILE
) |
4347 pcc
->mmu_model
= POWERPC_MMU_MPC8xx
;
4348 pcc
->excp_model
= POWERPC_EXCP_603
;
4349 pcc
->bus_model
= PPC_FLAGS_INPUT_RCPU
;
4350 pcc
->bfd_mach
= bfd_mach_ppc_860
;
4351 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
4352 POWERPC_FLAG_BUS_CLK
;
4355 /* Freescale 82xx cores (aka PowerQUICC-II) */
4357 static void init_proc_G2(CPUPPCState
*env
)
4359 gen_spr_ne_601(env
);
4361 gen_spr_G2_755(env
);
4365 /* External access control */
4366 /* XXX : not implemented */
4367 spr_register(env
, SPR_EAR
, "EAR",
4368 SPR_NOACCESS
, SPR_NOACCESS
,
4369 &spr_read_generic
, &spr_write_generic
,
4371 /* Hardware implementation register */
4372 /* XXX : not implemented */
4373 spr_register(env
, SPR_HID0
, "HID0",
4374 SPR_NOACCESS
, SPR_NOACCESS
,
4375 &spr_read_generic
, &spr_write_generic
,
4377 /* XXX : not implemented */
4378 spr_register(env
, SPR_HID1
, "HID1",
4379 SPR_NOACCESS
, SPR_NOACCESS
,
4380 &spr_read_generic
, &spr_write_generic
,
4382 /* XXX : not implemented */
4383 spr_register(env
, SPR_HID2
, "HID2",
4384 SPR_NOACCESS
, SPR_NOACCESS
,
4385 &spr_read_generic
, &spr_write_generic
,
4387 /* Memory management */
4390 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4392 env
->dcache_line_size
= 32;
4393 env
->icache_line_size
= 32;
4394 /* Allocate hardware IRQ controller */
4395 ppc6xx_irq_init(env_archcpu(env
));
4398 POWERPC_FAMILY(G2
)(ObjectClass
*oc
, void *data
)
4400 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4401 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4403 dc
->desc
= "PowerPC G2";
4404 pcc
->init_proc
= init_proc_G2
;
4405 pcc
->check_pow
= check_pow_hid0
;
4406 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4407 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4409 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4410 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4411 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4412 PPC_SEGMENT
| PPC_EXTERN
;
4413 pcc
->msr_mask
= (1ull << MSR_POW
) |
4414 (1ull << MSR_TGPR
) |
4428 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4429 pcc
->excp_model
= POWERPC_EXCP_G2
;
4430 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4431 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
4432 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4433 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4436 static void init_proc_G2LE(CPUPPCState
*env
)
4438 gen_spr_ne_601(env
);
4440 gen_spr_G2_755(env
);
4444 /* External access control */
4445 /* XXX : not implemented */
4446 spr_register(env
, SPR_EAR
, "EAR",
4447 SPR_NOACCESS
, SPR_NOACCESS
,
4448 &spr_read_generic
, &spr_write_generic
,
4450 /* Hardware implementation register */
4451 /* XXX : not implemented */
4452 spr_register(env
, SPR_HID0
, "HID0",
4453 SPR_NOACCESS
, SPR_NOACCESS
,
4454 &spr_read_generic
, &spr_write_generic
,
4456 /* XXX : not implemented */
4457 spr_register(env
, SPR_HID1
, "HID1",
4458 SPR_NOACCESS
, SPR_NOACCESS
,
4459 &spr_read_generic
, &spr_write_generic
,
4461 /* XXX : not implemented */
4462 spr_register(env
, SPR_HID2
, "HID2",
4463 SPR_NOACCESS
, SPR_NOACCESS
,
4464 &spr_read_generic
, &spr_write_generic
,
4467 /* Memory management */
4470 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4472 env
->dcache_line_size
= 32;
4473 env
->icache_line_size
= 32;
4474 /* Allocate hardware IRQ controller */
4475 ppc6xx_irq_init(env_archcpu(env
));
4478 POWERPC_FAMILY(G2LE
)(ObjectClass
*oc
, void *data
)
4480 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4481 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4483 dc
->desc
= "PowerPC G2LE";
4484 pcc
->init_proc
= init_proc_G2LE
;
4485 pcc
->check_pow
= check_pow_hid0
;
4486 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4487 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4489 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4490 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4491 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4492 PPC_SEGMENT
| PPC_EXTERN
;
4493 pcc
->msr_mask
= (1ull << MSR_POW
) |
4494 (1ull << MSR_TGPR
) |
4510 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4511 pcc
->excp_model
= POWERPC_EXCP_G2
;
4512 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4513 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
4514 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4515 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4518 static void init_proc_e200(CPUPPCState
*env
)
4522 gen_spr_BookE(env
, 0x000000070000FFFFULL
);
4523 /* XXX : not implemented */
4524 spr_register(env
, SPR_BOOKE_SPEFSCR
, "SPEFSCR",
4525 &spr_read_spefscr
, &spr_write_spefscr
,
4526 &spr_read_spefscr
, &spr_write_spefscr
,
4528 /* Memory management */
4529 gen_spr_BookE206(env
, 0x0000005D, NULL
, 0);
4530 /* XXX : not implemented */
4531 spr_register(env
, SPR_HID0
, "HID0",
4532 SPR_NOACCESS
, SPR_NOACCESS
,
4533 &spr_read_generic
, &spr_write_generic
,
4535 /* XXX : not implemented */
4536 spr_register(env
, SPR_HID1
, "HID1",
4537 SPR_NOACCESS
, SPR_NOACCESS
,
4538 &spr_read_generic
, &spr_write_generic
,
4540 /* XXX : not implemented */
4541 spr_register(env
, SPR_Exxx_ALTCTXCR
, "ALTCTXCR",
4542 SPR_NOACCESS
, SPR_NOACCESS
,
4543 &spr_read_generic
, &spr_write_generic
,
4545 /* XXX : not implemented */
4546 spr_register(env
, SPR_Exxx_BUCSR
, "BUCSR",
4547 SPR_NOACCESS
, SPR_NOACCESS
,
4548 &spr_read_generic
, &spr_write_generic
,
4550 /* XXX : not implemented */
4551 spr_register(env
, SPR_Exxx_CTXCR
, "CTXCR",
4552 SPR_NOACCESS
, SPR_NOACCESS
,
4553 &spr_read_generic
, &spr_write_generic
,
4555 /* XXX : not implemented */
4556 spr_register(env
, SPR_Exxx_DBCNT
, "DBCNT",
4557 SPR_NOACCESS
, SPR_NOACCESS
,
4558 &spr_read_generic
, &spr_write_generic
,
4560 /* XXX : not implemented */
4561 spr_register(env
, SPR_Exxx_DBCR3
, "DBCR3",
4562 SPR_NOACCESS
, SPR_NOACCESS
,
4563 &spr_read_generic
, &spr_write_generic
,
4565 /* XXX : not implemented */
4566 spr_register(env
, SPR_Exxx_L1CFG0
, "L1CFG0",
4567 &spr_read_generic
, SPR_NOACCESS
,
4568 &spr_read_generic
, SPR_NOACCESS
,
4570 /* XXX : not implemented */
4571 spr_register(env
, SPR_Exxx_L1CSR0
, "L1CSR0",
4572 SPR_NOACCESS
, SPR_NOACCESS
,
4573 &spr_read_generic
, &spr_write_generic
,
4575 /* XXX : not implemented */
4576 spr_register(env
, SPR_Exxx_L1FINV0
, "L1FINV0",
4577 SPR_NOACCESS
, SPR_NOACCESS
,
4578 &spr_read_generic
, &spr_write_generic
,
4580 /* XXX : not implemented */
4581 spr_register(env
, SPR_BOOKE_TLB0CFG
, "TLB0CFG",
4582 SPR_NOACCESS
, SPR_NOACCESS
,
4583 &spr_read_generic
, &spr_write_generic
,
4585 /* XXX : not implemented */
4586 spr_register(env
, SPR_BOOKE_TLB1CFG
, "TLB1CFG",
4587 SPR_NOACCESS
, SPR_NOACCESS
,
4588 &spr_read_generic
, &spr_write_generic
,
4590 /* XXX : not implemented */
4591 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4592 SPR_NOACCESS
, SPR_NOACCESS
,
4593 &spr_read_generic
, &spr_write_generic
,
4595 /* XXX : not implemented */
4596 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4597 SPR_NOACCESS
, SPR_NOACCESS
,
4598 &spr_read_generic
, &spr_write_generic
,
4600 /* XXX : not implemented */
4601 spr_register(env
, SPR_MMUCSR0
, "MMUCSR0",
4602 SPR_NOACCESS
, SPR_NOACCESS
,
4603 &spr_read_generic
, &spr_write_generic
,
4604 0x00000000); /* TOFIX */
4605 spr_register(env
, SPR_BOOKE_DSRR0
, "DSRR0",
4606 SPR_NOACCESS
, SPR_NOACCESS
,
4607 &spr_read_generic
, &spr_write_generic
,
4609 spr_register(env
, SPR_BOOKE_DSRR1
, "DSRR1",
4610 SPR_NOACCESS
, SPR_NOACCESS
,
4611 &spr_read_generic
, &spr_write_generic
,
4613 #if !defined(CONFIG_USER_ONLY)
4617 env
->tlb_type
= TLB_EMB
;
4619 init_excp_e200(env
, 0xFFFF0000UL
);
4620 env
->dcache_line_size
= 32;
4621 env
->icache_line_size
= 32;
4622 /* XXX: TODO: allocate internal IRQ controller */
4625 POWERPC_FAMILY(e200
)(ObjectClass
*oc
, void *data
)
4627 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4628 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4630 dc
->desc
= "e200 core";
4631 pcc
->init_proc
= init_proc_e200
;
4632 pcc
->check_pow
= check_pow_hid0
;
4634 * XXX: unimplemented instructions:
4641 * all SPE multiply-accumulate instructions
4643 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
4644 PPC_SPE
| PPC_SPE_SINGLE
|
4645 PPC_WRTEE
| PPC_RFDI
|
4646 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
4647 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4648 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
|
4650 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
4664 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
4665 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4666 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4667 pcc
->bfd_mach
= bfd_mach_ppc_860
;
4668 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
4669 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
4670 POWERPC_FLAG_BUS_CLK
;
4673 static void init_proc_e300(CPUPPCState
*env
)
4675 gen_spr_ne_601(env
);
4680 /* hardware implementation registers */
4681 /* XXX : not implemented */
4682 spr_register(env
, SPR_HID0
, "HID0",
4683 SPR_NOACCESS
, SPR_NOACCESS
,
4684 &spr_read_generic
, &spr_write_generic
,
4686 /* XXX : not implemented */
4687 spr_register(env
, SPR_HID1
, "HID1",
4688 SPR_NOACCESS
, SPR_NOACCESS
,
4689 &spr_read_generic
, &spr_write_generic
,
4691 /* XXX : not implemented */
4692 spr_register(env
, SPR_HID2
, "HID2",
4693 SPR_NOACCESS
, SPR_NOACCESS
,
4694 &spr_read_generic
, &spr_write_generic
,
4697 /* XXX : not implemented */
4698 spr_register(env
, SPR_DABR
, "DABR",
4699 SPR_NOACCESS
, SPR_NOACCESS
,
4700 &spr_read_generic
, &spr_write_generic
,
4702 /* XXX : not implemented */
4703 spr_register(env
, SPR_DABR2
, "DABR2",
4704 SPR_NOACCESS
, SPR_NOACCESS
,
4705 &spr_read_generic
, &spr_write_generic
,
4707 /* XXX : not implemented */
4708 spr_register(env
, SPR_IABR2
, "IABR2",
4709 SPR_NOACCESS
, SPR_NOACCESS
,
4710 &spr_read_generic
, &spr_write_generic
,
4712 /* XXX : not implemented */
4713 spr_register(env
, SPR_IBCR
, "IBCR",
4714 SPR_NOACCESS
, SPR_NOACCESS
,
4715 &spr_read_generic
, &spr_write_generic
,
4717 /* XXX : not implemented */
4718 spr_register(env
, SPR_DBCR
, "DBCR",
4719 SPR_NOACCESS
, SPR_NOACCESS
,
4720 &spr_read_generic
, &spr_write_generic
,
4722 /* Memory management */
4725 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4727 env
->dcache_line_size
= 32;
4728 env
->icache_line_size
= 32;
4729 /* Allocate hardware IRQ controller */
4730 ppc6xx_irq_init(env_archcpu(env
));
4733 POWERPC_FAMILY(e300
)(ObjectClass
*oc
, void *data
)
4735 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4736 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4738 dc
->desc
= "e300 core";
4739 pcc
->init_proc
= init_proc_e300
;
4740 pcc
->check_pow
= check_pow_hid0
;
4741 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4742 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4744 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4745 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4746 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4747 PPC_SEGMENT
| PPC_EXTERN
;
4748 pcc
->msr_mask
= (1ull << MSR_POW
) |
4749 (1ull << MSR_TGPR
) |
4765 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4766 pcc
->excp_model
= POWERPC_EXCP_603
;
4767 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4768 pcc
->bfd_mach
= bfd_mach_ppc_603
;
4769 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4770 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4773 #if !defined(CONFIG_USER_ONLY)
4774 static void spr_write_mas73(DisasContext
*ctx
, int sprn
, int gprn
)
4776 TCGv val
= tcg_temp_new();
4777 tcg_gen_ext32u_tl(val
, cpu_gpr
[gprn
]);
4778 gen_store_spr(SPR_BOOKE_MAS3
, val
);
4779 tcg_gen_shri_tl(val
, cpu_gpr
[gprn
], 32);
4780 gen_store_spr(SPR_BOOKE_MAS7
, val
);
4784 static void spr_read_mas73(DisasContext
*ctx
, int gprn
, int sprn
)
4786 TCGv mas7
= tcg_temp_new();
4787 TCGv mas3
= tcg_temp_new();
4788 gen_load_spr(mas7
, SPR_BOOKE_MAS7
);
4789 tcg_gen_shli_tl(mas7
, mas7
, 32);
4790 gen_load_spr(mas3
, SPR_BOOKE_MAS3
);
4791 tcg_gen_or_tl(cpu_gpr
[gprn
], mas3
, mas7
);
4792 tcg_temp_free(mas3
);
4793 tcg_temp_free(mas7
);
4798 enum fsl_e500_version
{
4806 static void init_proc_e500(CPUPPCState
*env
, int version
)
4808 uint32_t tlbncfg
[2];
4810 uint64_t ivpr_mask
= 0xFFFF0000ULL
;
4811 uint32_t l1cfg0
= 0x3800 /* 8 ways */
4812 | 0x0020; /* 32 kb */
4813 uint32_t l1cfg1
= 0x3800 /* 8 ways */
4814 | 0x0020; /* 32 kb */
4815 uint32_t mmucfg
= 0;
4816 #if !defined(CONFIG_USER_ONLY)
4823 * XXX The e500 doesn't implement IVOR7 and IVOR9, but doesn't
4824 * complain when accessing them.
4825 * gen_spr_BookE(env, 0x0000000F0000FD7FULL);
4831 ivor_mask
= 0x0000000F0000FFFFULL
;
4835 ivor_mask
= 0x000003FE0000FFFFULL
;
4838 ivor_mask
= 0x000003FF0000FFFFULL
;
4841 gen_spr_BookE(env
, ivor_mask
);
4842 gen_spr_usprg3(env
);
4843 /* Processor identification */
4844 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4845 SPR_NOACCESS
, SPR_NOACCESS
,
4846 &spr_read_generic
, &spr_write_pir
,
4848 /* XXX : not implemented */
4849 spr_register(env
, SPR_BOOKE_SPEFSCR
, "SPEFSCR",
4850 &spr_read_spefscr
, &spr_write_spefscr
,
4851 &spr_read_spefscr
, &spr_write_spefscr
,
4853 #if !defined(CONFIG_USER_ONLY)
4854 /* Memory management */
4860 tlbncfg
[0] = gen_tlbncfg(2, 1, 1, 0, 256);
4861 tlbncfg
[1] = gen_tlbncfg(16, 1, 9, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 16);
4864 tlbncfg
[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4865 tlbncfg
[1] = gen_tlbncfg(16, 1, 12, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 16);
4869 tlbncfg
[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4870 tlbncfg
[1] = gen_tlbncfg(64, 1, 12, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 64);
4875 tlbncfg
[0] = 0x08052400;
4876 tlbncfg
[1] = 0x40028040;
4879 cpu_abort(env_cpu(env
), "Unknown CPU: " TARGET_FMT_lx
"\n",
4887 env
->dcache_line_size
= 32;
4888 env
->icache_line_size
= 32;
4892 env
->dcache_line_size
= 64;
4893 env
->icache_line_size
= 64;
4894 l1cfg0
|= 0x1000000; /* 64 byte cache block size */
4895 l1cfg1
|= 0x1000000; /* 64 byte cache block size */
4898 env
->dcache_line_size
= 32;
4899 env
->icache_line_size
= 32;
4900 l1cfg0
|= 0x0F83820;
4901 l1cfg1
|= 0x0B83820;
4904 cpu_abort(env_cpu(env
), "Unknown CPU: " TARGET_FMT_lx
"\n",
4907 gen_spr_BookE206(env
, 0x000000DF, tlbncfg
, mmucfg
);
4908 /* XXX : not implemented */
4909 spr_register(env
, SPR_HID0
, "HID0",
4910 SPR_NOACCESS
, SPR_NOACCESS
,
4911 &spr_read_generic
, &spr_write_generic
,
4913 /* XXX : not implemented */
4914 spr_register(env
, SPR_HID1
, "HID1",
4915 SPR_NOACCESS
, SPR_NOACCESS
,
4916 &spr_read_generic
, &spr_write_generic
,
4918 /* XXX : not implemented */
4919 spr_register(env
, SPR_Exxx_BBEAR
, "BBEAR",
4920 SPR_NOACCESS
, SPR_NOACCESS
,
4921 &spr_read_generic
, &spr_write_generic
,
4923 /* XXX : not implemented */
4924 spr_register(env
, SPR_Exxx_BBTAR
, "BBTAR",
4925 SPR_NOACCESS
, SPR_NOACCESS
,
4926 &spr_read_generic
, &spr_write_generic
,
4928 /* XXX : not implemented */
4929 spr_register(env
, SPR_Exxx_MCAR
, "MCAR",
4930 SPR_NOACCESS
, SPR_NOACCESS
,
4931 &spr_read_generic
, &spr_write_generic
,
4933 /* XXX : not implemented */
4934 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
4935 SPR_NOACCESS
, SPR_NOACCESS
,
4936 &spr_read_generic
, &spr_write_generic
,
4938 /* XXX : not implemented */
4939 spr_register(env
, SPR_Exxx_NPIDR
, "NPIDR",
4940 SPR_NOACCESS
, SPR_NOACCESS
,
4941 &spr_read_generic
, &spr_write_generic
,
4943 /* XXX : not implemented */
4944 spr_register(env
, SPR_Exxx_BUCSR
, "BUCSR",
4945 SPR_NOACCESS
, SPR_NOACCESS
,
4946 &spr_read_generic
, &spr_write_generic
,
4948 /* XXX : not implemented */
4949 spr_register(env
, SPR_Exxx_L1CFG0
, "L1CFG0",
4950 &spr_read_generic
, SPR_NOACCESS
,
4951 &spr_read_generic
, SPR_NOACCESS
,
4953 spr_register(env
, SPR_Exxx_L1CFG1
, "L1CFG1",
4954 &spr_read_generic
, SPR_NOACCESS
,
4955 &spr_read_generic
, SPR_NOACCESS
,
4957 spr_register(env
, SPR_Exxx_L1CSR0
, "L1CSR0",
4958 SPR_NOACCESS
, SPR_NOACCESS
,
4959 &spr_read_generic
, &spr_write_e500_l1csr0
,
4961 spr_register(env
, SPR_Exxx_L1CSR1
, "L1CSR1",
4962 SPR_NOACCESS
, SPR_NOACCESS
,
4963 &spr_read_generic
, &spr_write_e500_l1csr1
,
4965 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
4966 SPR_NOACCESS
, SPR_NOACCESS
,
4967 &spr_read_generic
, &spr_write_generic
,
4969 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
4970 SPR_NOACCESS
, SPR_NOACCESS
,
4971 &spr_read_generic
, &spr_write_generic
,
4973 spr_register(env
, SPR_MMUCSR0
, "MMUCSR0",
4974 SPR_NOACCESS
, SPR_NOACCESS
,
4975 &spr_read_generic
, &spr_write_booke206_mmucsr0
,
4977 spr_register(env
, SPR_BOOKE_EPR
, "EPR",
4978 SPR_NOACCESS
, SPR_NOACCESS
,
4979 &spr_read_generic
, SPR_NOACCESS
,
4981 /* XXX better abstract into Emb.xxx features */
4982 if ((version
== fsl_e5500
) || (version
== fsl_e6500
)) {
4983 spr_register(env
, SPR_BOOKE_EPCR
, "EPCR",
4984 SPR_NOACCESS
, SPR_NOACCESS
,
4985 &spr_read_generic
, &spr_write_generic
,
4987 spr_register(env
, SPR_BOOKE_MAS7_MAS3
, "MAS7_MAS3",
4988 SPR_NOACCESS
, SPR_NOACCESS
,
4989 &spr_read_mas73
, &spr_write_mas73
,
4991 ivpr_mask
= (target_ulong
)~0xFFFFULL
;
4994 if (version
== fsl_e6500
) {
4995 /* Thread identification */
4996 spr_register(env
, SPR_TIR
, "TIR",
4997 SPR_NOACCESS
, SPR_NOACCESS
,
4998 &spr_read_generic
, SPR_NOACCESS
,
5000 spr_register(env
, SPR_BOOKE_TLB0PS
, "TLB0PS",
5001 SPR_NOACCESS
, SPR_NOACCESS
,
5002 &spr_read_generic
, SPR_NOACCESS
,
5004 spr_register(env
, SPR_BOOKE_TLB1PS
, "TLB1PS",
5005 SPR_NOACCESS
, SPR_NOACCESS
,
5006 &spr_read_generic
, SPR_NOACCESS
,
5010 #if !defined(CONFIG_USER_ONLY)
5012 env
->tlb_type
= TLB_MAS
;
5013 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
5014 env
->nb_tlb
+= booke206_tlb_size(env
, i
);
5018 init_excp_e200(env
, ivpr_mask
);
5019 /* Allocate hardware IRQ controller */
5020 ppce500_irq_init(env_archcpu(env
));
5023 static void init_proc_e500v1(CPUPPCState
*env
)
5025 init_proc_e500(env
, fsl_e500v1
);
5028 POWERPC_FAMILY(e500v1
)(ObjectClass
*oc
, void *data
)
5030 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5031 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5033 dc
->desc
= "e500v1 core";
5034 pcc
->init_proc
= init_proc_e500v1
;
5035 pcc
->check_pow
= check_pow_hid0
;
5036 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
5037 PPC_SPE
| PPC_SPE_SINGLE
|
5038 PPC_WRTEE
| PPC_RFDI
|
5039 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5040 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5041 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5042 pcc
->insns_flags2
= PPC2_BOOKE206
;
5043 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
5057 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5058 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5059 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5060 pcc
->bfd_mach
= bfd_mach_ppc_860
;
5061 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
5062 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
5063 POWERPC_FLAG_BUS_CLK
;
5066 static void init_proc_e500v2(CPUPPCState
*env
)
5068 init_proc_e500(env
, fsl_e500v2
);
5071 POWERPC_FAMILY(e500v2
)(ObjectClass
*oc
, void *data
)
5073 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5074 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5076 dc
->desc
= "e500v2 core";
5077 pcc
->init_proc
= init_proc_e500v2
;
5078 pcc
->check_pow
= check_pow_hid0
;
5079 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
5080 PPC_SPE
| PPC_SPE_SINGLE
| PPC_SPE_DOUBLE
|
5081 PPC_WRTEE
| PPC_RFDI
|
5082 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5083 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5084 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5085 pcc
->insns_flags2
= PPC2_BOOKE206
;
5086 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
5100 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5101 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5102 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5103 pcc
->bfd_mach
= bfd_mach_ppc_860
;
5104 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
5105 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
5106 POWERPC_FLAG_BUS_CLK
;
5109 static void init_proc_e500mc(CPUPPCState
*env
)
5111 init_proc_e500(env
, fsl_e500mc
);
5114 POWERPC_FAMILY(e500mc
)(ObjectClass
*oc
, void *data
)
5116 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5117 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5119 dc
->desc
= "e500mc core";
5120 pcc
->init_proc
= init_proc_e500mc
;
5121 pcc
->check_pow
= check_pow_none
;
5122 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5123 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5124 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5125 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5126 PPC_FLOAT
| PPC_FLOAT_FRES
|
5127 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5128 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5129 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5130 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
;
5131 pcc
->msr_mask
= (1ull << MSR_GS
) |
5132 (1ull << MSR_UCLE
) |
5145 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5146 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5147 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5148 /* FIXME: figure out the correct flag for e500mc */
5149 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5150 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5151 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5155 static void init_proc_e5500(CPUPPCState
*env
)
5157 init_proc_e500(env
, fsl_e5500
);
5160 POWERPC_FAMILY(e5500
)(ObjectClass
*oc
, void *data
)
5162 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5163 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5165 dc
->desc
= "e5500 core";
5166 pcc
->init_proc
= init_proc_e5500
;
5167 pcc
->check_pow
= check_pow_none
;
5168 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5169 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5170 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5171 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5172 PPC_FLOAT
| PPC_FLOAT_FRES
|
5173 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5174 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5175 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
|
5176 PPC_64B
| PPC_POPCNTB
| PPC_POPCNTWD
;
5177 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
| PPC2_PERM_ISA206
| \
5179 pcc
->msr_mask
= (1ull << MSR_CM
) |
5181 (1ull << MSR_UCLE
) |
5194 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5195 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5196 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5197 /* FIXME: figure out the correct flag for e5500 */
5198 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5199 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5200 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5203 static void init_proc_e6500(CPUPPCState
*env
)
5205 init_proc_e500(env
, fsl_e6500
);
5208 POWERPC_FAMILY(e6500
)(ObjectClass
*oc
, void *data
)
5210 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5211 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5213 dc
->desc
= "e6500 core";
5214 pcc
->init_proc
= init_proc_e6500
;
5215 pcc
->check_pow
= check_pow_none
;
5216 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5217 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5218 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5219 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5220 PPC_FLOAT
| PPC_FLOAT_FRES
|
5221 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5222 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5223 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
|
5224 PPC_64B
| PPC_POPCNTB
| PPC_POPCNTWD
| PPC_ALTIVEC
;
5225 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
| PPC2_PERM_ISA206
| \
5226 PPC2_FP_CVT_S64
| PPC2_ATOMIC_ISA206
;
5227 pcc
->msr_mask
= (1ull << MSR_CM
) |
5229 (1ull << MSR_UCLE
) |
5243 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5244 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5245 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5246 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5247 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5248 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_VRE
;
5253 /* Non-embedded PowerPC */
5255 #define POWERPC_MSRR_601 (0x0000000000001040ULL)
5257 static void init_proc_601(CPUPPCState
*env
)
5259 gen_spr_ne_601(env
);
5262 /* Hardware implementation registers */
5263 /* XXX : not implemented */
5264 spr_register(env
, SPR_HID0
, "HID0",
5265 SPR_NOACCESS
, SPR_NOACCESS
,
5266 &spr_read_generic
, &spr_write_hid0_601
,
5268 /* XXX : not implemented */
5269 spr_register(env
, SPR_HID1
, "HID1",
5270 SPR_NOACCESS
, SPR_NOACCESS
,
5271 &spr_read_generic
, &spr_write_generic
,
5273 /* XXX : not implemented */
5274 spr_register(env
, SPR_601_HID2
, "HID2",
5275 SPR_NOACCESS
, SPR_NOACCESS
,
5276 &spr_read_generic
, &spr_write_generic
,
5278 /* XXX : not implemented */
5279 spr_register(env
, SPR_601_HID5
, "HID5",
5280 SPR_NOACCESS
, SPR_NOACCESS
,
5281 &spr_read_generic
, &spr_write_generic
,
5283 /* Memory management */
5286 * XXX: beware that dcache line size is 64
5287 * but dcbz uses 32 bytes "sectors"
5288 * XXX: this breaks clcs instruction !
5290 env
->dcache_line_size
= 32;
5291 env
->icache_line_size
= 64;
5292 /* Allocate hardware IRQ controller */
5293 ppc6xx_irq_init(env_archcpu(env
));
5296 POWERPC_FAMILY(601)(ObjectClass
*oc
, void *data
)
5298 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5299 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5301 dc
->desc
= "PowerPC 601";
5302 pcc
->init_proc
= init_proc_601
;
5303 pcc
->check_pow
= check_pow_none
;
5304 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_POWER_BR
|
5306 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5307 PPC_MEM_SYNC
| PPC_MEM_EIEIO
| PPC_MEM_TLBIE
|
5308 PPC_SEGMENT
| PPC_EXTERN
;
5309 pcc
->msr_mask
= (1ull << MSR_EE
) |
5319 pcc
->mmu_model
= POWERPC_MMU_601
;
5320 #if defined(CONFIG_SOFTMMU)
5321 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5323 pcc
->excp_model
= POWERPC_EXCP_601
;
5324 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5325 pcc
->bfd_mach
= bfd_mach_ppc_601
;
5326 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_RTC_CLK
;
5329 #define POWERPC_MSRR_601v (0x0000000000001040ULL)
5331 static void init_proc_601v(CPUPPCState
*env
)
5334 /* XXX : not implemented */
5335 spr_register(env
, SPR_601_HID15
, "HID15",
5336 SPR_NOACCESS
, SPR_NOACCESS
,
5337 &spr_read_generic
, &spr_write_generic
,
5341 POWERPC_FAMILY(601v
)(ObjectClass
*oc
, void *data
)
5343 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5344 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5346 dc
->desc
= "PowerPC 601v";
5347 pcc
->init_proc
= init_proc_601v
;
5348 pcc
->check_pow
= check_pow_none
;
5349 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_POWER_BR
|
5351 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5352 PPC_MEM_SYNC
| PPC_MEM_EIEIO
| PPC_MEM_TLBIE
|
5353 PPC_SEGMENT
| PPC_EXTERN
;
5354 pcc
->msr_mask
= (1ull << MSR_EE
) |
5364 pcc
->mmu_model
= POWERPC_MMU_601
;
5365 #if defined(CONFIG_SOFTMMU)
5366 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5368 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5369 pcc
->bfd_mach
= bfd_mach_ppc_601
;
5370 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_RTC_CLK
;
5373 static void init_proc_602(CPUPPCState
*env
)
5375 gen_spr_ne_601(env
);
5380 /* hardware implementation registers */
5381 /* XXX : not implemented */
5382 spr_register(env
, SPR_HID0
, "HID0",
5383 SPR_NOACCESS
, SPR_NOACCESS
,
5384 &spr_read_generic
, &spr_write_generic
,
5386 /* XXX : not implemented */
5387 spr_register(env
, SPR_HID1
, "HID1",
5388 SPR_NOACCESS
, SPR_NOACCESS
,
5389 &spr_read_generic
, &spr_write_generic
,
5391 /* Memory management */
5393 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5395 env
->dcache_line_size
= 32;
5396 env
->icache_line_size
= 32;
5397 /* Allocate hardware IRQ controller */
5398 ppc6xx_irq_init(env_archcpu(env
));
5401 POWERPC_FAMILY(602)(ObjectClass
*oc
, void *data
)
5403 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5404 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5406 dc
->desc
= "PowerPC 602";
5407 pcc
->init_proc
= init_proc_602
;
5408 pcc
->check_pow
= check_pow_hid0
;
5409 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5410 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5411 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5412 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5413 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5414 PPC_MEM_TLBIE
| PPC_6xx_TLB
| PPC_MEM_TLBSYNC
|
5415 PPC_SEGMENT
| PPC_602_SPEC
;
5416 pcc
->msr_mask
= (1ull << MSR_VSX
) |
5419 (1ull << MSR_TGPR
) |
5434 /* XXX: 602 MMU is quite specific. Should add a special case */
5435 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5436 pcc
->excp_model
= POWERPC_EXCP_602
;
5437 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5438 pcc
->bfd_mach
= bfd_mach_ppc_602
;
5439 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5440 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5443 static void init_proc_603(CPUPPCState
*env
)
5445 gen_spr_ne_601(env
);
5450 /* hardware implementation registers */
5451 /* XXX : not implemented */
5452 spr_register(env
, SPR_HID0
, "HID0",
5453 SPR_NOACCESS
, SPR_NOACCESS
,
5454 &spr_read_generic
, &spr_write_generic
,
5456 /* XXX : not implemented */
5457 spr_register(env
, SPR_HID1
, "HID1",
5458 SPR_NOACCESS
, SPR_NOACCESS
,
5459 &spr_read_generic
, &spr_write_generic
,
5461 /* Memory management */
5463 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5465 env
->dcache_line_size
= 32;
5466 env
->icache_line_size
= 32;
5467 /* Allocate hardware IRQ controller */
5468 ppc6xx_irq_init(env_archcpu(env
));
5471 POWERPC_FAMILY(603)(ObjectClass
*oc
, void *data
)
5473 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5474 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5476 dc
->desc
= "PowerPC 603";
5477 pcc
->init_proc
= init_proc_603
;
5478 pcc
->check_pow
= check_pow_hid0
;
5479 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5480 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5481 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5482 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5483 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5484 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
5485 PPC_SEGMENT
| PPC_EXTERN
;
5486 pcc
->msr_mask
= (1ull << MSR_POW
) |
5487 (1ull << MSR_TGPR
) |
5502 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5503 pcc
->excp_model
= POWERPC_EXCP_603
;
5504 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5505 pcc
->bfd_mach
= bfd_mach_ppc_603
;
5506 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5507 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5510 static void init_proc_603E(CPUPPCState
*env
)
5512 gen_spr_ne_601(env
);
5517 /* hardware implementation registers */
5518 /* XXX : not implemented */
5519 spr_register(env
, SPR_HID0
, "HID0",
5520 SPR_NOACCESS
, SPR_NOACCESS
,
5521 &spr_read_generic
, &spr_write_generic
,
5523 /* XXX : not implemented */
5524 spr_register(env
, SPR_HID1
, "HID1",
5525 SPR_NOACCESS
, SPR_NOACCESS
,
5526 &spr_read_generic
, &spr_write_generic
,
5528 /* Memory management */
5530 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5532 env
->dcache_line_size
= 32;
5533 env
->icache_line_size
= 32;
5534 /* Allocate hardware IRQ controller */
5535 ppc6xx_irq_init(env_archcpu(env
));
5538 POWERPC_FAMILY(603E
)(ObjectClass
*oc
, void *data
)
5540 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5541 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5543 dc
->desc
= "PowerPC 603e";
5544 pcc
->init_proc
= init_proc_603E
;
5545 pcc
->check_pow
= check_pow_hid0
;
5546 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5547 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5548 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5549 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5550 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5551 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
5552 PPC_SEGMENT
| PPC_EXTERN
;
5553 pcc
->msr_mask
= (1ull << MSR_POW
) |
5554 (1ull << MSR_TGPR
) |
5569 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5570 pcc
->excp_model
= POWERPC_EXCP_603E
;
5571 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5572 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
5573 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5574 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5577 static void init_proc_604(CPUPPCState
*env
)
5579 gen_spr_ne_601(env
);
5584 /* Hardware implementation registers */
5585 /* XXX : not implemented */
5586 spr_register(env
, SPR_HID0
, "HID0",
5587 SPR_NOACCESS
, SPR_NOACCESS
,
5588 &spr_read_generic
, &spr_write_generic
,
5590 /* Memory management */
5593 env
->dcache_line_size
= 32;
5594 env
->icache_line_size
= 32;
5595 /* Allocate hardware IRQ controller */
5596 ppc6xx_irq_init(env_archcpu(env
));
5599 POWERPC_FAMILY(604)(ObjectClass
*oc
, void *data
)
5601 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5602 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5604 dc
->desc
= "PowerPC 604";
5605 pcc
->init_proc
= init_proc_604
;
5606 pcc
->check_pow
= check_pow_nocheck
;
5607 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5608 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5609 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5610 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5611 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5612 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5613 PPC_SEGMENT
| PPC_EXTERN
;
5614 pcc
->msr_mask
= (1ull << MSR_POW
) |
5630 pcc
->mmu_model
= POWERPC_MMU_32B
;
5631 #if defined(CONFIG_SOFTMMU)
5632 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5634 pcc
->excp_model
= POWERPC_EXCP_604
;
5635 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5636 pcc
->bfd_mach
= bfd_mach_ppc_604
;
5637 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5638 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5641 static void init_proc_604E(CPUPPCState
*env
)
5643 gen_spr_ne_601(env
);
5646 /* XXX : not implemented */
5647 spr_register(env
, SPR_7XX_MMCR1
, "MMCR1",
5648 SPR_NOACCESS
, SPR_NOACCESS
,
5649 &spr_read_generic
, &spr_write_generic
,
5651 /* XXX : not implemented */
5652 spr_register(env
, SPR_7XX_PMC3
, "PMC3",
5653 SPR_NOACCESS
, SPR_NOACCESS
,
5654 &spr_read_generic
, &spr_write_generic
,
5656 /* XXX : not implemented */
5657 spr_register(env
, SPR_7XX_PMC4
, "PMC4",
5658 SPR_NOACCESS
, SPR_NOACCESS
,
5659 &spr_read_generic
, &spr_write_generic
,
5663 /* Hardware implementation registers */
5664 /* XXX : not implemented */
5665 spr_register(env
, SPR_HID0
, "HID0",
5666 SPR_NOACCESS
, SPR_NOACCESS
,
5667 &spr_read_generic
, &spr_write_generic
,
5669 /* XXX : not implemented */
5670 spr_register(env
, SPR_HID1
, "HID1",
5671 SPR_NOACCESS
, SPR_NOACCESS
,
5672 &spr_read_generic
, &spr_write_generic
,
5674 /* Memory management */
5677 env
->dcache_line_size
= 32;
5678 env
->icache_line_size
= 32;
5679 /* Allocate hardware IRQ controller */
5680 ppc6xx_irq_init(env_archcpu(env
));
5683 POWERPC_FAMILY(604E
)(ObjectClass
*oc
, void *data
)
5685 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5686 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5688 dc
->desc
= "PowerPC 604E";
5689 pcc
->init_proc
= init_proc_604E
;
5690 pcc
->check_pow
= check_pow_nocheck
;
5691 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5692 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5693 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5694 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5695 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5696 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5697 PPC_SEGMENT
| PPC_EXTERN
;
5698 pcc
->msr_mask
= (1ull << MSR_POW
) |
5714 pcc
->mmu_model
= POWERPC_MMU_32B
;
5715 #if defined(CONFIG_SOFTMMU)
5716 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5718 pcc
->excp_model
= POWERPC_EXCP_604
;
5719 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5720 pcc
->bfd_mach
= bfd_mach_ppc_604
;
5721 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5722 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5725 static void init_proc_740(CPUPPCState
*env
)
5727 gen_spr_ne_601(env
);
5732 /* Thermal management */
5734 /* Hardware implementation registers */
5735 /* XXX : not implemented */
5736 spr_register(env
, SPR_HID0
, "HID0",
5737 SPR_NOACCESS
, SPR_NOACCESS
,
5738 &spr_read_generic
, &spr_write_generic
,
5740 /* XXX : not implemented */
5741 spr_register(env
, SPR_HID1
, "HID1",
5742 SPR_NOACCESS
, SPR_NOACCESS
,
5743 &spr_read_generic
, &spr_write_generic
,
5745 /* Memory management */
5748 env
->dcache_line_size
= 32;
5749 env
->icache_line_size
= 32;
5750 /* Allocate hardware IRQ controller */
5751 ppc6xx_irq_init(env_archcpu(env
));
5754 POWERPC_FAMILY(740)(ObjectClass
*oc
, void *data
)
5756 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5757 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5759 dc
->desc
= "PowerPC 740";
5760 pcc
->init_proc
= init_proc_740
;
5761 pcc
->check_pow
= check_pow_hid0
;
5762 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5763 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5764 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5765 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5766 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5767 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5768 PPC_SEGMENT
| PPC_EXTERN
;
5769 pcc
->msr_mask
= (1ull << MSR_POW
) |
5785 pcc
->mmu_model
= POWERPC_MMU_32B
;
5786 #if defined(CONFIG_SOFTMMU)
5787 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5789 pcc
->excp_model
= POWERPC_EXCP_7x0
;
5790 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5791 pcc
->bfd_mach
= bfd_mach_ppc_750
;
5792 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5793 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5796 static void init_proc_750(CPUPPCState
*env
)
5798 gen_spr_ne_601(env
);
5801 /* XXX : not implemented */
5802 spr_register(env
, SPR_L2CR
, "L2CR",
5803 SPR_NOACCESS
, SPR_NOACCESS
,
5804 &spr_read_generic
, spr_access_nop
,
5808 /* Thermal management */
5810 /* Hardware implementation registers */
5811 /* XXX : not implemented */
5812 spr_register(env
, SPR_HID0
, "HID0",
5813 SPR_NOACCESS
, SPR_NOACCESS
,
5814 &spr_read_generic
, &spr_write_generic
,
5816 /* XXX : not implemented */
5817 spr_register(env
, SPR_HID1
, "HID1",
5818 SPR_NOACCESS
, SPR_NOACCESS
,
5819 &spr_read_generic
, &spr_write_generic
,
5821 /* Memory management */
5824 * XXX: high BATs are also present but are known to be bugged on
5828 env
->dcache_line_size
= 32;
5829 env
->icache_line_size
= 32;
5830 /* Allocate hardware IRQ controller */
5831 ppc6xx_irq_init(env_archcpu(env
));
5834 POWERPC_FAMILY(750)(ObjectClass
*oc
, void *data
)
5836 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5837 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5839 dc
->desc
= "PowerPC 750";
5840 pcc
->init_proc
= init_proc_750
;
5841 pcc
->check_pow
= check_pow_hid0
;
5842 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5843 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5844 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5845 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5846 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5847 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5848 PPC_SEGMENT
| PPC_EXTERN
;
5849 pcc
->msr_mask
= (1ull << MSR_POW
) |
5865 pcc
->mmu_model
= POWERPC_MMU_32B
;
5866 #if defined(CONFIG_SOFTMMU)
5867 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5869 pcc
->excp_model
= POWERPC_EXCP_7x0
;
5870 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5871 pcc
->bfd_mach
= bfd_mach_ppc_750
;
5872 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5873 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5876 static void init_proc_750cl(CPUPPCState
*env
)
5878 gen_spr_ne_601(env
);
5881 /* XXX : not implemented */
5882 spr_register(env
, SPR_L2CR
, "L2CR",
5883 SPR_NOACCESS
, SPR_NOACCESS
,
5884 &spr_read_generic
, spr_access_nop
,
5888 /* Thermal management */
5889 /* Those registers are fake on 750CL */
5890 spr_register(env
, SPR_THRM1
, "THRM1",
5891 SPR_NOACCESS
, SPR_NOACCESS
,
5892 &spr_read_generic
, &spr_write_generic
,
5894 spr_register(env
, SPR_THRM2
, "THRM2",
5895 SPR_NOACCESS
, SPR_NOACCESS
,
5896 &spr_read_generic
, &spr_write_generic
,
5898 spr_register(env
, SPR_THRM3
, "THRM3",
5899 SPR_NOACCESS
, SPR_NOACCESS
,
5900 &spr_read_generic
, &spr_write_generic
,
5902 /* XXX: not implemented */
5903 spr_register(env
, SPR_750_TDCL
, "TDCL",
5904 SPR_NOACCESS
, SPR_NOACCESS
,
5905 &spr_read_generic
, &spr_write_generic
,
5907 spr_register(env
, SPR_750_TDCH
, "TDCH",
5908 SPR_NOACCESS
, SPR_NOACCESS
,
5909 &spr_read_generic
, &spr_write_generic
,
5912 /* XXX : not implemented */
5913 spr_register(env
, SPR_750_WPAR
, "WPAR",
5914 SPR_NOACCESS
, SPR_NOACCESS
,
5915 &spr_read_generic
, &spr_write_generic
,
5917 spr_register(env
, SPR_750_DMAL
, "DMAL",
5918 SPR_NOACCESS
, SPR_NOACCESS
,
5919 &spr_read_generic
, &spr_write_generic
,
5921 spr_register(env
, SPR_750_DMAU
, "DMAU",
5922 SPR_NOACCESS
, SPR_NOACCESS
,
5923 &spr_read_generic
, &spr_write_generic
,
5925 /* Hardware implementation registers */
5926 /* XXX : not implemented */
5927 spr_register(env
, SPR_HID0
, "HID0",
5928 SPR_NOACCESS
, SPR_NOACCESS
,
5929 &spr_read_generic
, &spr_write_generic
,
5931 /* XXX : not implemented */
5932 spr_register(env
, SPR_HID1
, "HID1",
5933 SPR_NOACCESS
, SPR_NOACCESS
,
5934 &spr_read_generic
, &spr_write_generic
,
5936 /* XXX : not implemented */
5937 spr_register(env
, SPR_750CL_HID2
, "HID2",
5938 SPR_NOACCESS
, SPR_NOACCESS
,
5939 &spr_read_generic
, &spr_write_generic
,
5941 /* XXX : not implemented */
5942 spr_register(env
, SPR_750CL_HID4
, "HID4",
5943 SPR_NOACCESS
, SPR_NOACCESS
,
5944 &spr_read_generic
, &spr_write_generic
,
5946 /* Quantization registers */
5947 /* XXX : not implemented */
5948 spr_register(env
, SPR_750_GQR0
, "GQR0",
5949 SPR_NOACCESS
, SPR_NOACCESS
,
5950 &spr_read_generic
, &spr_write_generic
,
5952 /* XXX : not implemented */
5953 spr_register(env
, SPR_750_GQR1
, "GQR1",
5954 SPR_NOACCESS
, SPR_NOACCESS
,
5955 &spr_read_generic
, &spr_write_generic
,
5957 /* XXX : not implemented */
5958 spr_register(env
, SPR_750_GQR2
, "GQR2",
5959 SPR_NOACCESS
, SPR_NOACCESS
,
5960 &spr_read_generic
, &spr_write_generic
,
5962 /* XXX : not implemented */
5963 spr_register(env
, SPR_750_GQR3
, "GQR3",
5964 SPR_NOACCESS
, SPR_NOACCESS
,
5965 &spr_read_generic
, &spr_write_generic
,
5967 /* XXX : not implemented */
5968 spr_register(env
, SPR_750_GQR4
, "GQR4",
5969 SPR_NOACCESS
, SPR_NOACCESS
,
5970 &spr_read_generic
, &spr_write_generic
,
5972 /* XXX : not implemented */
5973 spr_register(env
, SPR_750_GQR5
, "GQR5",
5974 SPR_NOACCESS
, SPR_NOACCESS
,
5975 &spr_read_generic
, &spr_write_generic
,
5977 /* XXX : not implemented */
5978 spr_register(env
, SPR_750_GQR6
, "GQR6",
5979 SPR_NOACCESS
, SPR_NOACCESS
,
5980 &spr_read_generic
, &spr_write_generic
,
5982 /* XXX : not implemented */
5983 spr_register(env
, SPR_750_GQR7
, "GQR7",
5984 SPR_NOACCESS
, SPR_NOACCESS
,
5985 &spr_read_generic
, &spr_write_generic
,
5987 /* Memory management */
5989 /* PowerPC 750cl has 8 DBATs and 8 IBATs */
5991 init_excp_750cl(env
);
5992 env
->dcache_line_size
= 32;
5993 env
->icache_line_size
= 32;
5994 /* Allocate hardware IRQ controller */
5995 ppc6xx_irq_init(env_archcpu(env
));
5998 POWERPC_FAMILY(750cl
)(ObjectClass
*oc
, void *data
)
6000 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6001 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6003 dc
->desc
= "PowerPC 750 CL";
6004 pcc
->init_proc
= init_proc_750cl
;
6005 pcc
->check_pow
= check_pow_hid0
;
6007 * XXX: not implemented:
6008 * cache lock instructions:
6010 * floating point paired instructions
6045 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6046 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6047 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6048 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6049 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6050 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6051 PPC_SEGMENT
| PPC_EXTERN
;
6052 pcc
->msr_mask
= (1ull << MSR_POW
) |
6068 pcc
->mmu_model
= POWERPC_MMU_32B
;
6069 #if defined(CONFIG_SOFTMMU)
6070 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6072 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6073 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6074 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6075 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6076 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6079 static void init_proc_750cx(CPUPPCState
*env
)
6081 gen_spr_ne_601(env
);
6084 /* XXX : not implemented */
6085 spr_register(env
, SPR_L2CR
, "L2CR",
6086 SPR_NOACCESS
, SPR_NOACCESS
,
6087 &spr_read_generic
, spr_access_nop
,
6091 /* Thermal management */
6093 /* This register is not implemented but is present for compatibility */
6094 spr_register(env
, SPR_SDA
, "SDA",
6095 SPR_NOACCESS
, SPR_NOACCESS
,
6096 &spr_read_generic
, &spr_write_generic
,
6098 /* Hardware implementation registers */
6099 /* XXX : not implemented */
6100 spr_register(env
, SPR_HID0
, "HID0",
6101 SPR_NOACCESS
, SPR_NOACCESS
,
6102 &spr_read_generic
, &spr_write_generic
,
6104 /* XXX : not implemented */
6105 spr_register(env
, SPR_HID1
, "HID1",
6106 SPR_NOACCESS
, SPR_NOACCESS
,
6107 &spr_read_generic
, &spr_write_generic
,
6109 /* Memory management */
6111 /* PowerPC 750cx has 8 DBATs and 8 IBATs */
6113 init_excp_750cx(env
);
6114 env
->dcache_line_size
= 32;
6115 env
->icache_line_size
= 32;
6116 /* Allocate hardware IRQ controller */
6117 ppc6xx_irq_init(env_archcpu(env
));
6120 POWERPC_FAMILY(750cx
)(ObjectClass
*oc
, void *data
)
6122 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6123 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6125 dc
->desc
= "PowerPC 750CX";
6126 pcc
->init_proc
= init_proc_750cx
;
6127 pcc
->check_pow
= check_pow_hid0
;
6128 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6129 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6130 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6131 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6132 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6133 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6134 PPC_SEGMENT
| PPC_EXTERN
;
6135 pcc
->msr_mask
= (1ull << MSR_POW
) |
6151 pcc
->mmu_model
= POWERPC_MMU_32B
;
6152 #if defined(CONFIG_SOFTMMU)
6153 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6155 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6156 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6157 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6158 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6159 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6162 static void init_proc_750fx(CPUPPCState
*env
)
6164 gen_spr_ne_601(env
);
6167 /* XXX : not implemented */
6168 spr_register(env
, SPR_L2CR
, "L2CR",
6169 SPR_NOACCESS
, SPR_NOACCESS
,
6170 &spr_read_generic
, spr_access_nop
,
6174 /* Thermal management */
6176 /* XXX : not implemented */
6177 spr_register(env
, SPR_750_THRM4
, "THRM4",
6178 SPR_NOACCESS
, SPR_NOACCESS
,
6179 &spr_read_generic
, &spr_write_generic
,
6181 /* Hardware implementation registers */
6182 /* XXX : not implemented */
6183 spr_register(env
, SPR_HID0
, "HID0",
6184 SPR_NOACCESS
, SPR_NOACCESS
,
6185 &spr_read_generic
, &spr_write_generic
,
6187 /* XXX : not implemented */
6188 spr_register(env
, SPR_HID1
, "HID1",
6189 SPR_NOACCESS
, SPR_NOACCESS
,
6190 &spr_read_generic
, &spr_write_generic
,
6192 /* XXX : not implemented */
6193 spr_register(env
, SPR_750FX_HID2
, "HID2",
6194 SPR_NOACCESS
, SPR_NOACCESS
,
6195 &spr_read_generic
, &spr_write_generic
,
6197 /* Memory management */
6199 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6202 env
->dcache_line_size
= 32;
6203 env
->icache_line_size
= 32;
6204 /* Allocate hardware IRQ controller */
6205 ppc6xx_irq_init(env_archcpu(env
));
6208 POWERPC_FAMILY(750fx
)(ObjectClass
*oc
, void *data
)
6210 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6211 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6213 dc
->desc
= "PowerPC 750FX";
6214 pcc
->init_proc
= init_proc_750fx
;
6215 pcc
->check_pow
= check_pow_hid0
;
6216 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6217 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6218 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6219 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6220 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6221 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6222 PPC_SEGMENT
| PPC_EXTERN
;
6223 pcc
->msr_mask
= (1ull << MSR_POW
) |
6239 pcc
->mmu_model
= POWERPC_MMU_32B
;
6240 #if defined(CONFIG_SOFTMMU)
6241 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6243 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6244 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6245 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6246 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6247 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6250 static void init_proc_750gx(CPUPPCState
*env
)
6252 gen_spr_ne_601(env
);
6255 /* XXX : not implemented (XXX: different from 750fx) */
6256 spr_register(env
, SPR_L2CR
, "L2CR",
6257 SPR_NOACCESS
, SPR_NOACCESS
,
6258 &spr_read_generic
, spr_access_nop
,
6262 /* Thermal management */
6264 /* XXX : not implemented */
6265 spr_register(env
, SPR_750_THRM4
, "THRM4",
6266 SPR_NOACCESS
, SPR_NOACCESS
,
6267 &spr_read_generic
, &spr_write_generic
,
6269 /* Hardware implementation registers */
6270 /* XXX : not implemented (XXX: different from 750fx) */
6271 spr_register(env
, SPR_HID0
, "HID0",
6272 SPR_NOACCESS
, SPR_NOACCESS
,
6273 &spr_read_generic
, &spr_write_generic
,
6275 /* XXX : not implemented */
6276 spr_register(env
, SPR_HID1
, "HID1",
6277 SPR_NOACCESS
, SPR_NOACCESS
,
6278 &spr_read_generic
, &spr_write_generic
,
6280 /* XXX : not implemented (XXX: different from 750fx) */
6281 spr_register(env
, SPR_750FX_HID2
, "HID2",
6282 SPR_NOACCESS
, SPR_NOACCESS
,
6283 &spr_read_generic
, &spr_write_generic
,
6285 /* Memory management */
6287 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6290 env
->dcache_line_size
= 32;
6291 env
->icache_line_size
= 32;
6292 /* Allocate hardware IRQ controller */
6293 ppc6xx_irq_init(env_archcpu(env
));
6296 POWERPC_FAMILY(750gx
)(ObjectClass
*oc
, void *data
)
6298 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6299 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6301 dc
->desc
= "PowerPC 750GX";
6302 pcc
->init_proc
= init_proc_750gx
;
6303 pcc
->check_pow
= check_pow_hid0
;
6304 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6305 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6306 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6307 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6308 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6309 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6310 PPC_SEGMENT
| PPC_EXTERN
;
6311 pcc
->msr_mask
= (1ull << MSR_POW
) |
6327 pcc
->mmu_model
= POWERPC_MMU_32B
;
6328 #if defined(CONFIG_SOFTMMU)
6329 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6331 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6332 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6333 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6334 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6335 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6338 static void init_proc_745(CPUPPCState
*env
)
6340 gen_spr_ne_601(env
);
6343 gen_spr_G2_755(env
);
6346 /* Thermal management */
6348 /* Hardware implementation registers */
6349 /* XXX : not implemented */
6350 spr_register(env
, SPR_HID0
, "HID0",
6351 SPR_NOACCESS
, SPR_NOACCESS
,
6352 &spr_read_generic
, &spr_write_generic
,
6354 /* XXX : not implemented */
6355 spr_register(env
, SPR_HID1
, "HID1",
6356 SPR_NOACCESS
, SPR_NOACCESS
,
6357 &spr_read_generic
, &spr_write_generic
,
6359 /* XXX : not implemented */
6360 spr_register(env
, SPR_HID2
, "HID2",
6361 SPR_NOACCESS
, SPR_NOACCESS
,
6362 &spr_read_generic
, &spr_write_generic
,
6364 /* Memory management */
6367 gen_6xx_7xx_soft_tlb(env
, 64, 2);
6369 env
->dcache_line_size
= 32;
6370 env
->icache_line_size
= 32;
6371 /* Allocate hardware IRQ controller */
6372 ppc6xx_irq_init(env_archcpu(env
));
6375 POWERPC_FAMILY(745)(ObjectClass
*oc
, void *data
)
6377 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6378 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6380 dc
->desc
= "PowerPC 745";
6381 pcc
->init_proc
= init_proc_745
;
6382 pcc
->check_pow
= check_pow_hid0
;
6383 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6384 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6385 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6386 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6387 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6388 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
6389 PPC_SEGMENT
| PPC_EXTERN
;
6390 pcc
->msr_mask
= (1ull << MSR_POW
) |
6406 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
6407 pcc
->excp_model
= POWERPC_EXCP_7x5
;
6408 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6409 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6410 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6411 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6414 static void init_proc_755(CPUPPCState
*env
)
6416 gen_spr_ne_601(env
);
6419 gen_spr_G2_755(env
);
6422 /* L2 cache control */
6423 /* XXX : not implemented */
6424 spr_register(env
, SPR_L2CR
, "L2CR",
6425 SPR_NOACCESS
, SPR_NOACCESS
,
6426 &spr_read_generic
, spr_access_nop
,
6428 /* XXX : not implemented */
6429 spr_register(env
, SPR_L2PMCR
, "L2PMCR",
6430 SPR_NOACCESS
, SPR_NOACCESS
,
6431 &spr_read_generic
, &spr_write_generic
,
6433 /* Thermal management */
6435 /* Hardware implementation registers */
6436 /* XXX : not implemented */
6437 spr_register(env
, SPR_HID0
, "HID0",
6438 SPR_NOACCESS
, SPR_NOACCESS
,
6439 &spr_read_generic
, &spr_write_generic
,
6441 /* XXX : not implemented */
6442 spr_register(env
, SPR_HID1
, "HID1",
6443 SPR_NOACCESS
, SPR_NOACCESS
,
6444 &spr_read_generic
, &spr_write_generic
,
6446 /* XXX : not implemented */
6447 spr_register(env
, SPR_HID2
, "HID2",
6448 SPR_NOACCESS
, SPR_NOACCESS
,
6449 &spr_read_generic
, &spr_write_generic
,
6451 /* Memory management */
6454 gen_6xx_7xx_soft_tlb(env
, 64, 2);
6456 env
->dcache_line_size
= 32;
6457 env
->icache_line_size
= 32;
6458 /* Allocate hardware IRQ controller */
6459 ppc6xx_irq_init(env_archcpu(env
));
6462 POWERPC_FAMILY(755)(ObjectClass
*oc
, void *data
)
6464 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6465 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6467 dc
->desc
= "PowerPC 755";
6468 pcc
->init_proc
= init_proc_755
;
6469 pcc
->check_pow
= check_pow_hid0
;
6470 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6471 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6472 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6473 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6474 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6475 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
6476 PPC_SEGMENT
| PPC_EXTERN
;
6477 pcc
->msr_mask
= (1ull << MSR_POW
) |
6493 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
6494 pcc
->excp_model
= POWERPC_EXCP_7x5
;
6495 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6496 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6497 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6498 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6501 static void init_proc_7400(CPUPPCState
*env
)
6503 gen_spr_ne_601(env
);
6508 /* 74xx specific SPR */
6510 /* XXX : not implemented */
6511 spr_register(env
, SPR_UBAMR
, "UBAMR",
6512 &spr_read_ureg
, SPR_NOACCESS
,
6513 &spr_read_ureg
, SPR_NOACCESS
,
6515 /* XXX: this seems not implemented on all revisions. */
6516 /* XXX : not implemented */
6517 spr_register(env
, SPR_MSSCR1
, "MSSCR1",
6518 SPR_NOACCESS
, SPR_NOACCESS
,
6519 &spr_read_generic
, &spr_write_generic
,
6521 /* Thermal management */
6523 /* Memory management */
6525 init_excp_7400(env
);
6526 env
->dcache_line_size
= 32;
6527 env
->icache_line_size
= 32;
6528 /* Allocate hardware IRQ controller */
6529 ppc6xx_irq_init(env_archcpu(env
));
6532 POWERPC_FAMILY(7400)(ObjectClass
*oc
, void *data
)
6534 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6535 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6537 dc
->desc
= "PowerPC 7400 (aka G4)";
6538 pcc
->init_proc
= init_proc_7400
;
6539 pcc
->check_pow
= check_pow_hid0
;
6540 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6541 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6542 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6544 PPC_CACHE
| PPC_CACHE_ICBI
|
6545 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6546 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6547 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6549 PPC_SEGMENT
| PPC_EXTERN
|
6551 pcc
->msr_mask
= (1ull << MSR_VR
) |
6568 pcc
->mmu_model
= POWERPC_MMU_32B
;
6569 #if defined(CONFIG_SOFTMMU)
6570 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6572 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6573 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6574 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6575 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6576 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6577 POWERPC_FLAG_BUS_CLK
;
6580 static void init_proc_7410(CPUPPCState
*env
)
6582 gen_spr_ne_601(env
);
6587 /* 74xx specific SPR */
6589 /* XXX : not implemented */
6590 spr_register(env
, SPR_UBAMR
, "UBAMR",
6591 &spr_read_ureg
, SPR_NOACCESS
,
6592 &spr_read_ureg
, SPR_NOACCESS
,
6594 /* Thermal management */
6597 /* XXX : not implemented */
6598 spr_register(env
, SPR_L2PMCR
, "L2PMCR",
6599 SPR_NOACCESS
, SPR_NOACCESS
,
6600 &spr_read_generic
, &spr_write_generic
,
6603 /* XXX : not implemented */
6604 spr_register(env
, SPR_LDSTDB
, "LDSTDB",
6605 SPR_NOACCESS
, SPR_NOACCESS
,
6606 &spr_read_generic
, &spr_write_generic
,
6608 /* Memory management */
6610 init_excp_7400(env
);
6611 env
->dcache_line_size
= 32;
6612 env
->icache_line_size
= 32;
6613 /* Allocate hardware IRQ controller */
6614 ppc6xx_irq_init(env_archcpu(env
));
6617 POWERPC_FAMILY(7410)(ObjectClass
*oc
, void *data
)
6619 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6620 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6622 dc
->desc
= "PowerPC 7410 (aka G4)";
6623 pcc
->init_proc
= init_proc_7410
;
6624 pcc
->check_pow
= check_pow_hid0
;
6625 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6626 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6627 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6629 PPC_CACHE
| PPC_CACHE_ICBI
|
6630 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6631 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6632 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6634 PPC_SEGMENT
| PPC_EXTERN
|
6636 pcc
->msr_mask
= (1ull << MSR_VR
) |
6653 pcc
->mmu_model
= POWERPC_MMU_32B
;
6654 #if defined(CONFIG_SOFTMMU)
6655 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6657 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6658 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6659 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6660 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6661 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6662 POWERPC_FLAG_BUS_CLK
;
6665 static void init_proc_7440(CPUPPCState
*env
)
6667 gen_spr_ne_601(env
);
6672 /* 74xx specific SPR */
6674 /* XXX : not implemented */
6675 spr_register(env
, SPR_UBAMR
, "UBAMR",
6676 &spr_read_ureg
, SPR_NOACCESS
,
6677 &spr_read_ureg
, SPR_NOACCESS
,
6680 /* XXX : not implemented */
6681 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6682 SPR_NOACCESS
, SPR_NOACCESS
,
6683 &spr_read_generic
, &spr_write_generic
,
6686 /* XXX : not implemented */
6687 spr_register(env
, SPR_ICTRL
, "ICTRL",
6688 SPR_NOACCESS
, SPR_NOACCESS
,
6689 &spr_read_generic
, &spr_write_generic
,
6692 /* XXX : not implemented */
6693 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6694 SPR_NOACCESS
, SPR_NOACCESS
,
6695 &spr_read_generic
, &spr_write_generic
,
6698 /* XXX : not implemented */
6699 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6700 SPR_NOACCESS
, SPR_NOACCESS
,
6701 &spr_read_generic
, &spr_write_generic
,
6703 /* XXX : not implemented */
6704 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6705 &spr_read_ureg
, SPR_NOACCESS
,
6706 &spr_read_ureg
, SPR_NOACCESS
,
6708 /* XXX : not implemented */
6709 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6710 SPR_NOACCESS
, SPR_NOACCESS
,
6711 &spr_read_generic
, &spr_write_generic
,
6713 /* XXX : not implemented */
6714 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6715 &spr_read_ureg
, SPR_NOACCESS
,
6716 &spr_read_ureg
, SPR_NOACCESS
,
6718 /* Memory management */
6720 gen_74xx_soft_tlb(env
, 128, 2);
6721 init_excp_7450(env
);
6722 env
->dcache_line_size
= 32;
6723 env
->icache_line_size
= 32;
6724 /* Allocate hardware IRQ controller */
6725 ppc6xx_irq_init(env_archcpu(env
));
6728 POWERPC_FAMILY(7440)(ObjectClass
*oc
, void *data
)
6730 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6731 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6733 dc
->desc
= "PowerPC 7440 (aka G4)";
6734 pcc
->init_proc
= init_proc_7440
;
6735 pcc
->check_pow
= check_pow_hid0_74xx
;
6736 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6737 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6738 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6740 PPC_CACHE
| PPC_CACHE_ICBI
|
6741 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6742 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6743 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6744 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6745 PPC_SEGMENT
| PPC_EXTERN
|
6747 pcc
->msr_mask
= (1ull << MSR_VR
) |
6764 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6765 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6766 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6767 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6768 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6769 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6770 POWERPC_FLAG_BUS_CLK
;
6773 static void init_proc_7450(CPUPPCState
*env
)
6775 gen_spr_ne_601(env
);
6780 /* 74xx specific SPR */
6782 /* Level 3 cache control */
6785 /* XXX : not implemented */
6786 spr_register(env
, SPR_L3ITCR1
, "L3ITCR1",
6787 SPR_NOACCESS
, SPR_NOACCESS
,
6788 &spr_read_generic
, &spr_write_generic
,
6791 /* XXX : not implemented */
6792 spr_register(env
, SPR_L3ITCR2
, "L3ITCR2",
6793 SPR_NOACCESS
, SPR_NOACCESS
,
6794 &spr_read_generic
, &spr_write_generic
,
6797 /* XXX : not implemented */
6798 spr_register(env
, SPR_L3ITCR3
, "L3ITCR3",
6799 SPR_NOACCESS
, SPR_NOACCESS
,
6800 &spr_read_generic
, &spr_write_generic
,
6803 /* XXX : not implemented */
6804 spr_register(env
, SPR_L3OHCR
, "L3OHCR",
6805 SPR_NOACCESS
, SPR_NOACCESS
,
6806 &spr_read_generic
, &spr_write_generic
,
6808 /* XXX : not implemented */
6809 spr_register(env
, SPR_UBAMR
, "UBAMR",
6810 &spr_read_ureg
, SPR_NOACCESS
,
6811 &spr_read_ureg
, SPR_NOACCESS
,
6814 /* XXX : not implemented */
6815 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6816 SPR_NOACCESS
, SPR_NOACCESS
,
6817 &spr_read_generic
, &spr_write_generic
,
6820 /* XXX : not implemented */
6821 spr_register(env
, SPR_ICTRL
, "ICTRL",
6822 SPR_NOACCESS
, SPR_NOACCESS
,
6823 &spr_read_generic
, &spr_write_generic
,
6826 /* XXX : not implemented */
6827 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6828 SPR_NOACCESS
, SPR_NOACCESS
,
6829 &spr_read_generic
, &spr_write_generic
,
6832 /* XXX : not implemented */
6833 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6834 SPR_NOACCESS
, SPR_NOACCESS
,
6835 &spr_read_generic
, &spr_write_generic
,
6837 /* XXX : not implemented */
6838 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6839 &spr_read_ureg
, SPR_NOACCESS
,
6840 &spr_read_ureg
, SPR_NOACCESS
,
6842 /* XXX : not implemented */
6843 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6844 SPR_NOACCESS
, SPR_NOACCESS
,
6845 &spr_read_generic
, &spr_write_generic
,
6847 /* XXX : not implemented */
6848 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6849 &spr_read_ureg
, SPR_NOACCESS
,
6850 &spr_read_ureg
, SPR_NOACCESS
,
6852 /* Memory management */
6854 gen_74xx_soft_tlb(env
, 128, 2);
6855 init_excp_7450(env
);
6856 env
->dcache_line_size
= 32;
6857 env
->icache_line_size
= 32;
6858 /* Allocate hardware IRQ controller */
6859 ppc6xx_irq_init(env_archcpu(env
));
6862 POWERPC_FAMILY(7450)(ObjectClass
*oc
, void *data
)
6864 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6865 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6867 dc
->desc
= "PowerPC 7450 (aka G4)";
6868 pcc
->init_proc
= init_proc_7450
;
6869 pcc
->check_pow
= check_pow_hid0_74xx
;
6870 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6871 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6872 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6874 PPC_CACHE
| PPC_CACHE_ICBI
|
6875 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6876 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6877 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6878 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6879 PPC_SEGMENT
| PPC_EXTERN
|
6881 pcc
->msr_mask
= (1ull << MSR_VR
) |
6898 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6899 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6900 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6901 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6902 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6903 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6904 POWERPC_FLAG_BUS_CLK
;
6907 static void init_proc_7445(CPUPPCState
*env
)
6909 gen_spr_ne_601(env
);
6914 /* 74xx specific SPR */
6917 /* XXX : not implemented */
6918 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6919 SPR_NOACCESS
, SPR_NOACCESS
,
6920 &spr_read_generic
, &spr_write_generic
,
6923 /* XXX : not implemented */
6924 spr_register(env
, SPR_ICTRL
, "ICTRL",
6925 SPR_NOACCESS
, SPR_NOACCESS
,
6926 &spr_read_generic
, &spr_write_generic
,
6929 /* XXX : not implemented */
6930 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6931 SPR_NOACCESS
, SPR_NOACCESS
,
6932 &spr_read_generic
, &spr_write_generic
,
6935 /* XXX : not implemented */
6936 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6937 SPR_NOACCESS
, SPR_NOACCESS
,
6938 &spr_read_generic
, &spr_write_generic
,
6940 /* XXX : not implemented */
6941 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6942 &spr_read_ureg
, SPR_NOACCESS
,
6943 &spr_read_ureg
, SPR_NOACCESS
,
6945 /* XXX : not implemented */
6946 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6947 SPR_NOACCESS
, SPR_NOACCESS
,
6948 &spr_read_generic
, &spr_write_generic
,
6950 /* XXX : not implemented */
6951 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6952 &spr_read_ureg
, SPR_NOACCESS
,
6953 &spr_read_ureg
, SPR_NOACCESS
,
6956 spr_register(env
, SPR_SPRG4
, "SPRG4",
6957 SPR_NOACCESS
, SPR_NOACCESS
,
6958 &spr_read_generic
, &spr_write_generic
,
6960 spr_register(env
, SPR_USPRG4
, "USPRG4",
6961 &spr_read_ureg
, SPR_NOACCESS
,
6962 &spr_read_ureg
, SPR_NOACCESS
,
6964 spr_register(env
, SPR_SPRG5
, "SPRG5",
6965 SPR_NOACCESS
, SPR_NOACCESS
,
6966 &spr_read_generic
, &spr_write_generic
,
6968 spr_register(env
, SPR_USPRG5
, "USPRG5",
6969 &spr_read_ureg
, SPR_NOACCESS
,
6970 &spr_read_ureg
, SPR_NOACCESS
,
6972 spr_register(env
, SPR_SPRG6
, "SPRG6",
6973 SPR_NOACCESS
, SPR_NOACCESS
,
6974 &spr_read_generic
, &spr_write_generic
,
6976 spr_register(env
, SPR_USPRG6
, "USPRG6",
6977 &spr_read_ureg
, SPR_NOACCESS
,
6978 &spr_read_ureg
, SPR_NOACCESS
,
6980 spr_register(env
, SPR_SPRG7
, "SPRG7",
6981 SPR_NOACCESS
, SPR_NOACCESS
,
6982 &spr_read_generic
, &spr_write_generic
,
6984 spr_register(env
, SPR_USPRG7
, "USPRG7",
6985 &spr_read_ureg
, SPR_NOACCESS
,
6986 &spr_read_ureg
, SPR_NOACCESS
,
6988 /* Memory management */
6991 gen_74xx_soft_tlb(env
, 128, 2);
6992 init_excp_7450(env
);
6993 env
->dcache_line_size
= 32;
6994 env
->icache_line_size
= 32;
6995 /* Allocate hardware IRQ controller */
6996 ppc6xx_irq_init(env_archcpu(env
));
6999 POWERPC_FAMILY(7445)(ObjectClass
*oc
, void *data
)
7001 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7002 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7004 dc
->desc
= "PowerPC 7445 (aka G4)";
7005 pcc
->init_proc
= init_proc_7445
;
7006 pcc
->check_pow
= check_pow_hid0_74xx
;
7007 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7008 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7009 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7011 PPC_CACHE
| PPC_CACHE_ICBI
|
7012 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7013 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7014 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7015 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7016 PPC_SEGMENT
| PPC_EXTERN
|
7018 pcc
->msr_mask
= (1ull << MSR_VR
) |
7035 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7036 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7037 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7038 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7039 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7040 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7041 POWERPC_FLAG_BUS_CLK
;
7044 static void init_proc_7455(CPUPPCState
*env
)
7046 gen_spr_ne_601(env
);
7051 /* 74xx specific SPR */
7053 /* Level 3 cache control */
7056 /* XXX : not implemented */
7057 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7058 SPR_NOACCESS
, SPR_NOACCESS
,
7059 &spr_read_generic
, &spr_write_generic
,
7062 /* XXX : not implemented */
7063 spr_register(env
, SPR_ICTRL
, "ICTRL",
7064 SPR_NOACCESS
, SPR_NOACCESS
,
7065 &spr_read_generic
, &spr_write_generic
,
7068 /* XXX : not implemented */
7069 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7070 SPR_NOACCESS
, SPR_NOACCESS
,
7071 &spr_read_generic
, &spr_write_generic
,
7074 /* XXX : not implemented */
7075 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7076 SPR_NOACCESS
, SPR_NOACCESS
,
7077 &spr_read_generic
, &spr_write_generic
,
7079 /* XXX : not implemented */
7080 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7081 &spr_read_ureg
, SPR_NOACCESS
,
7082 &spr_read_ureg
, SPR_NOACCESS
,
7084 /* XXX : not implemented */
7085 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7086 SPR_NOACCESS
, SPR_NOACCESS
,
7087 &spr_read_generic
, &spr_write_generic
,
7089 /* XXX : not implemented */
7090 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7091 &spr_read_ureg
, SPR_NOACCESS
,
7092 &spr_read_ureg
, SPR_NOACCESS
,
7095 spr_register(env
, SPR_SPRG4
, "SPRG4",
7096 SPR_NOACCESS
, SPR_NOACCESS
,
7097 &spr_read_generic
, &spr_write_generic
,
7099 spr_register(env
, SPR_USPRG4
, "USPRG4",
7100 &spr_read_ureg
, SPR_NOACCESS
,
7101 &spr_read_ureg
, SPR_NOACCESS
,
7103 spr_register(env
, SPR_SPRG5
, "SPRG5",
7104 SPR_NOACCESS
, SPR_NOACCESS
,
7105 &spr_read_generic
, &spr_write_generic
,
7107 spr_register(env
, SPR_USPRG5
, "USPRG5",
7108 &spr_read_ureg
, SPR_NOACCESS
,
7109 &spr_read_ureg
, SPR_NOACCESS
,
7111 spr_register(env
, SPR_SPRG6
, "SPRG6",
7112 SPR_NOACCESS
, SPR_NOACCESS
,
7113 &spr_read_generic
, &spr_write_generic
,
7115 spr_register(env
, SPR_USPRG6
, "USPRG6",
7116 &spr_read_ureg
, SPR_NOACCESS
,
7117 &spr_read_ureg
, SPR_NOACCESS
,
7119 spr_register(env
, SPR_SPRG7
, "SPRG7",
7120 SPR_NOACCESS
, SPR_NOACCESS
,
7121 &spr_read_generic
, &spr_write_generic
,
7123 spr_register(env
, SPR_USPRG7
, "USPRG7",
7124 &spr_read_ureg
, SPR_NOACCESS
,
7125 &spr_read_ureg
, SPR_NOACCESS
,
7127 /* Memory management */
7130 gen_74xx_soft_tlb(env
, 128, 2);
7131 init_excp_7450(env
);
7132 env
->dcache_line_size
= 32;
7133 env
->icache_line_size
= 32;
7134 /* Allocate hardware IRQ controller */
7135 ppc6xx_irq_init(env_archcpu(env
));
7138 POWERPC_FAMILY(7455)(ObjectClass
*oc
, void *data
)
7140 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7141 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7143 dc
->desc
= "PowerPC 7455 (aka G4)";
7144 pcc
->init_proc
= init_proc_7455
;
7145 pcc
->check_pow
= check_pow_hid0_74xx
;
7146 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7147 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7148 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7150 PPC_CACHE
| PPC_CACHE_ICBI
|
7151 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7152 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7153 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7154 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7155 PPC_SEGMENT
| PPC_EXTERN
|
7157 pcc
->msr_mask
= (1ull << MSR_VR
) |
7174 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7175 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7176 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7177 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7178 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7179 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7180 POWERPC_FLAG_BUS_CLK
;
7183 static void init_proc_7457(CPUPPCState
*env
)
7185 gen_spr_ne_601(env
);
7190 /* 74xx specific SPR */
7192 /* Level 3 cache control */
7195 /* XXX : not implemented */
7196 spr_register(env
, SPR_L3ITCR1
, "L3ITCR1",
7197 SPR_NOACCESS
, SPR_NOACCESS
,
7198 &spr_read_generic
, &spr_write_generic
,
7201 /* XXX : not implemented */
7202 spr_register(env
, SPR_L3ITCR2
, "L3ITCR2",
7203 SPR_NOACCESS
, SPR_NOACCESS
,
7204 &spr_read_generic
, &spr_write_generic
,
7207 /* XXX : not implemented */
7208 spr_register(env
, SPR_L3ITCR3
, "L3ITCR3",
7209 SPR_NOACCESS
, SPR_NOACCESS
,
7210 &spr_read_generic
, &spr_write_generic
,
7213 /* XXX : not implemented */
7214 spr_register(env
, SPR_L3OHCR
, "L3OHCR",
7215 SPR_NOACCESS
, SPR_NOACCESS
,
7216 &spr_read_generic
, &spr_write_generic
,
7219 /* XXX : not implemented */
7220 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7221 SPR_NOACCESS
, SPR_NOACCESS
,
7222 &spr_read_generic
, &spr_write_generic
,
7225 /* XXX : not implemented */
7226 spr_register(env
, SPR_ICTRL
, "ICTRL",
7227 SPR_NOACCESS
, SPR_NOACCESS
,
7228 &spr_read_generic
, &spr_write_generic
,
7231 /* XXX : not implemented */
7232 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7233 SPR_NOACCESS
, SPR_NOACCESS
,
7234 &spr_read_generic
, &spr_write_generic
,
7237 /* XXX : not implemented */
7238 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7239 SPR_NOACCESS
, SPR_NOACCESS
,
7240 &spr_read_generic
, &spr_write_generic
,
7242 /* XXX : not implemented */
7243 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7244 &spr_read_ureg
, SPR_NOACCESS
,
7245 &spr_read_ureg
, SPR_NOACCESS
,
7247 /* XXX : not implemented */
7248 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7249 SPR_NOACCESS
, SPR_NOACCESS
,
7250 &spr_read_generic
, &spr_write_generic
,
7252 /* XXX : not implemented */
7253 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7254 &spr_read_ureg
, SPR_NOACCESS
,
7255 &spr_read_ureg
, SPR_NOACCESS
,
7258 spr_register(env
, SPR_SPRG4
, "SPRG4",
7259 SPR_NOACCESS
, SPR_NOACCESS
,
7260 &spr_read_generic
, &spr_write_generic
,
7262 spr_register(env
, SPR_USPRG4
, "USPRG4",
7263 &spr_read_ureg
, SPR_NOACCESS
,
7264 &spr_read_ureg
, SPR_NOACCESS
,
7266 spr_register(env
, SPR_SPRG5
, "SPRG5",
7267 SPR_NOACCESS
, SPR_NOACCESS
,
7268 &spr_read_generic
, &spr_write_generic
,
7270 spr_register(env
, SPR_USPRG5
, "USPRG5",
7271 &spr_read_ureg
, SPR_NOACCESS
,
7272 &spr_read_ureg
, SPR_NOACCESS
,
7274 spr_register(env
, SPR_SPRG6
, "SPRG6",
7275 SPR_NOACCESS
, SPR_NOACCESS
,
7276 &spr_read_generic
, &spr_write_generic
,
7278 spr_register(env
, SPR_USPRG6
, "USPRG6",
7279 &spr_read_ureg
, SPR_NOACCESS
,
7280 &spr_read_ureg
, SPR_NOACCESS
,
7282 spr_register(env
, SPR_SPRG7
, "SPRG7",
7283 SPR_NOACCESS
, SPR_NOACCESS
,
7284 &spr_read_generic
, &spr_write_generic
,
7286 spr_register(env
, SPR_USPRG7
, "USPRG7",
7287 &spr_read_ureg
, SPR_NOACCESS
,
7288 &spr_read_ureg
, SPR_NOACCESS
,
7290 /* Memory management */
7293 gen_74xx_soft_tlb(env
, 128, 2);
7294 init_excp_7450(env
);
7295 env
->dcache_line_size
= 32;
7296 env
->icache_line_size
= 32;
7297 /* Allocate hardware IRQ controller */
7298 ppc6xx_irq_init(env_archcpu(env
));
7301 POWERPC_FAMILY(7457)(ObjectClass
*oc
, void *data
)
7303 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7304 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7306 dc
->desc
= "PowerPC 7457 (aka G4)";
7307 pcc
->init_proc
= init_proc_7457
;
7308 pcc
->check_pow
= check_pow_hid0_74xx
;
7309 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7310 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7311 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7313 PPC_CACHE
| PPC_CACHE_ICBI
|
7314 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7315 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7316 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7317 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7318 PPC_SEGMENT
| PPC_EXTERN
|
7320 pcc
->msr_mask
= (1ull << MSR_VR
) |
7337 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7338 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7339 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7340 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7341 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7342 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7343 POWERPC_FLAG_BUS_CLK
;
7346 static void init_proc_e600(CPUPPCState
*env
)
7348 gen_spr_ne_601(env
);
7353 /* 74xx specific SPR */
7355 /* XXX : not implemented */
7356 spr_register(env
, SPR_UBAMR
, "UBAMR",
7357 &spr_read_ureg
, SPR_NOACCESS
,
7358 &spr_read_ureg
, SPR_NOACCESS
,
7360 /* XXX : not implemented */
7361 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7362 SPR_NOACCESS
, SPR_NOACCESS
,
7363 &spr_read_generic
, &spr_write_generic
,
7365 /* XXX : not implemented */
7366 spr_register(env
, SPR_ICTRL
, "ICTRL",
7367 SPR_NOACCESS
, SPR_NOACCESS
,
7368 &spr_read_generic
, &spr_write_generic
,
7370 /* XXX : not implemented */
7371 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7372 SPR_NOACCESS
, SPR_NOACCESS
,
7373 &spr_read_generic
, &spr_write_generic
,
7375 /* XXX : not implemented */
7376 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7377 SPR_NOACCESS
, SPR_NOACCESS
,
7378 &spr_read_generic
, &spr_write_generic
,
7380 /* XXX : not implemented */
7381 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7382 &spr_read_ureg
, SPR_NOACCESS
,
7383 &spr_read_ureg
, SPR_NOACCESS
,
7385 /* XXX : not implemented */
7386 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7387 SPR_NOACCESS
, SPR_NOACCESS
,
7388 &spr_read_generic
, &spr_write_generic
,
7390 /* XXX : not implemented */
7391 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7392 &spr_read_ureg
, SPR_NOACCESS
,
7393 &spr_read_ureg
, SPR_NOACCESS
,
7396 spr_register(env
, SPR_SPRG4
, "SPRG4",
7397 SPR_NOACCESS
, SPR_NOACCESS
,
7398 &spr_read_generic
, &spr_write_generic
,
7400 spr_register(env
, SPR_USPRG4
, "USPRG4",
7401 &spr_read_ureg
, SPR_NOACCESS
,
7402 &spr_read_ureg
, SPR_NOACCESS
,
7404 spr_register(env
, SPR_SPRG5
, "SPRG5",
7405 SPR_NOACCESS
, SPR_NOACCESS
,
7406 &spr_read_generic
, &spr_write_generic
,
7408 spr_register(env
, SPR_USPRG5
, "USPRG5",
7409 &spr_read_ureg
, SPR_NOACCESS
,
7410 &spr_read_ureg
, SPR_NOACCESS
,
7412 spr_register(env
, SPR_SPRG6
, "SPRG6",
7413 SPR_NOACCESS
, SPR_NOACCESS
,
7414 &spr_read_generic
, &spr_write_generic
,
7416 spr_register(env
, SPR_USPRG6
, "USPRG6",
7417 &spr_read_ureg
, SPR_NOACCESS
,
7418 &spr_read_ureg
, SPR_NOACCESS
,
7420 spr_register(env
, SPR_SPRG7
, "SPRG7",
7421 SPR_NOACCESS
, SPR_NOACCESS
,
7422 &spr_read_generic
, &spr_write_generic
,
7424 spr_register(env
, SPR_USPRG7
, "USPRG7",
7425 &spr_read_ureg
, SPR_NOACCESS
,
7426 &spr_read_ureg
, SPR_NOACCESS
,
7428 /* Memory management */
7431 gen_74xx_soft_tlb(env
, 128, 2);
7432 init_excp_7450(env
);
7433 env
->dcache_line_size
= 32;
7434 env
->icache_line_size
= 32;
7435 /* Allocate hardware IRQ controller */
7436 ppc6xx_irq_init(env_archcpu(env
));
7439 POWERPC_FAMILY(e600
)(ObjectClass
*oc
, void *data
)
7441 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7442 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7444 dc
->desc
= "PowerPC e600";
7445 pcc
->init_proc
= init_proc_e600
;
7446 pcc
->check_pow
= check_pow_hid0_74xx
;
7447 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7448 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7449 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7451 PPC_CACHE
| PPC_CACHE_ICBI
|
7452 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7453 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7454 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7455 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7456 PPC_SEGMENT
| PPC_EXTERN
|
7458 pcc
->insns_flags2
= PPC_NONE
;
7459 pcc
->msr_mask
= (1ull << MSR_VR
) |
7476 pcc
->mmu_model
= POWERPC_MMU_32B
;
7477 #if defined(CONFIG_SOFTMMU)
7478 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
7480 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7481 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7482 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7483 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7484 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7485 POWERPC_FLAG_BUS_CLK
;
7488 #if defined(TARGET_PPC64)
7489 #if defined(CONFIG_USER_ONLY)
7490 #define POWERPC970_HID5_INIT 0x00000080
7492 #define POWERPC970_HID5_INIT 0x00000000
7495 static void gen_fscr_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_fscr_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 gen_msr_facility_check(DisasContext
*ctx
, int facility_sprn
,
7510 int bit
, int sprn
, int cause
)
7512 TCGv_i32 t1
= tcg_const_i32(bit
);
7513 TCGv_i32 t2
= tcg_const_i32(sprn
);
7514 TCGv_i32 t3
= tcg_const_i32(cause
);
7516 gen_helper_msr_facility_check(cpu_env
, t1
, t2
, t3
);
7518 tcg_temp_free_i32(t3
);
7519 tcg_temp_free_i32(t2
);
7520 tcg_temp_free_i32(t1
);
7523 static void spr_read_prev_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
7525 TCGv spr_up
= tcg_temp_new();
7526 TCGv spr
= tcg_temp_new();
7528 gen_load_spr(spr
, sprn
- 1);
7529 tcg_gen_shri_tl(spr_up
, spr
, 32);
7530 tcg_gen_ext32u_tl(cpu_gpr
[gprn
], spr_up
);
7533 tcg_temp_free(spr_up
);
7536 static void spr_write_prev_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
7538 TCGv spr
= tcg_temp_new();
7540 gen_load_spr(spr
, sprn
- 1);
7541 tcg_gen_deposit_tl(spr
, spr
, cpu_gpr
[gprn
], 32, 32);
7542 gen_store_spr(sprn
- 1, spr
);
7547 static int check_pow_970(CPUPPCState
*env
)
7549 if (env
->spr
[SPR_HID0
] & (HID0_DEEPNAP
| HID0_DOZE
| HID0_NAP
)) {
7556 static void gen_spr_970_hid(CPUPPCState
*env
)
7558 /* Hardware implementation registers */
7559 /* XXX : not implemented */
7560 spr_register(env
, SPR_HID0
, "HID0",
7561 SPR_NOACCESS
, SPR_NOACCESS
,
7562 &spr_read_generic
, &spr_write_clear
,
7564 spr_register(env
, SPR_HID1
, "HID1",
7565 SPR_NOACCESS
, SPR_NOACCESS
,
7566 &spr_read_generic
, &spr_write_generic
,
7568 spr_register(env
, SPR_970_HID5
, "HID5",
7569 SPR_NOACCESS
, SPR_NOACCESS
,
7570 &spr_read_generic
, &spr_write_generic
,
7571 POWERPC970_HID5_INIT
);
7574 static void gen_spr_970_hior(CPUPPCState
*env
)
7576 spr_register(env
, SPR_HIOR
, "SPR_HIOR",
7577 SPR_NOACCESS
, SPR_NOACCESS
,
7578 &spr_read_hior
, &spr_write_hior
,
7582 static void gen_spr_book3s_ctrl(CPUPPCState
*env
)
7584 spr_register(env
, SPR_CTRL
, "SPR_CTRL",
7585 SPR_NOACCESS
, SPR_NOACCESS
,
7586 SPR_NOACCESS
, &spr_write_generic
,
7588 spr_register(env
, SPR_UCTRL
, "SPR_UCTRL",
7589 &spr_read_ureg
, SPR_NOACCESS
,
7590 &spr_read_ureg
, SPR_NOACCESS
,
7594 static void gen_spr_book3s_altivec(CPUPPCState
*env
)
7596 if (!(env
->insns_flags
& PPC_ALTIVEC
)) {
7600 spr_register_kvm(env
, SPR_VRSAVE
, "VRSAVE",
7601 &spr_read_generic
, &spr_write_generic
,
7602 &spr_read_generic
, &spr_write_generic
,
7603 KVM_REG_PPC_VRSAVE
, 0x00000000);
7606 * Can't find information on what this should be on reset. This
7607 * value is the one used by 74xx processors.
7609 vscr_init(env
, 0x00010000);
7612 static void gen_spr_book3s_dbg(CPUPPCState
*env
)
7615 * TODO: different specs define different scopes for these,
7616 * will have to address this:
7617 * 970: super/write and super/read
7618 * powerisa 2.03..2.04: hypv/write and super/read.
7619 * powerisa 2.05 and newer: hypv/write and hypv/read.
7621 spr_register_kvm(env
, SPR_DABR
, "DABR",
7622 SPR_NOACCESS
, SPR_NOACCESS
,
7623 &spr_read_generic
, &spr_write_generic
,
7624 KVM_REG_PPC_DABR
, 0x00000000);
7625 spr_register_kvm(env
, SPR_DABRX
, "DABRX",
7626 SPR_NOACCESS
, SPR_NOACCESS
,
7627 &spr_read_generic
, &spr_write_generic
,
7628 KVM_REG_PPC_DABRX
, 0x00000000);
7631 static void gen_spr_book3s_207_dbg(CPUPPCState
*env
)
7633 spr_register_kvm_hv(env
, SPR_DAWR
, "DAWR",
7634 SPR_NOACCESS
, SPR_NOACCESS
,
7635 SPR_NOACCESS
, SPR_NOACCESS
,
7636 &spr_read_generic
, &spr_write_generic
,
7637 KVM_REG_PPC_DAWR
, 0x00000000);
7638 spr_register_kvm_hv(env
, SPR_DAWRX
, "DAWRX",
7639 SPR_NOACCESS
, SPR_NOACCESS
,
7640 SPR_NOACCESS
, SPR_NOACCESS
,
7641 &spr_read_generic
, &spr_write_generic
,
7642 KVM_REG_PPC_DAWRX
, 0x00000000);
7643 spr_register_kvm_hv(env
, SPR_CIABR
, "CIABR",
7644 SPR_NOACCESS
, SPR_NOACCESS
,
7645 SPR_NOACCESS
, SPR_NOACCESS
,
7646 &spr_read_generic
, &spr_write_generic
,
7647 KVM_REG_PPC_CIABR
, 0x00000000);
7650 static void gen_spr_970_dbg(CPUPPCState
*env
)
7653 spr_register(env
, SPR_IABR
, "IABR",
7654 SPR_NOACCESS
, SPR_NOACCESS
,
7655 &spr_read_generic
, &spr_write_generic
,
7659 static void gen_spr_book3s_pmu_sup(CPUPPCState
*env
)
7661 spr_register_kvm(env
, SPR_POWER_MMCR0
, "MMCR0",
7662 SPR_NOACCESS
, SPR_NOACCESS
,
7663 &spr_read_generic
, &spr_write_generic
,
7664 KVM_REG_PPC_MMCR0
, 0x00000000);
7665 spr_register_kvm(env
, SPR_POWER_MMCR1
, "MMCR1",
7666 SPR_NOACCESS
, SPR_NOACCESS
,
7667 &spr_read_generic
, &spr_write_generic
,
7668 KVM_REG_PPC_MMCR1
, 0x00000000);
7669 spr_register_kvm(env
, SPR_POWER_MMCRA
, "MMCRA",
7670 SPR_NOACCESS
, SPR_NOACCESS
,
7671 &spr_read_generic
, &spr_write_generic
,
7672 KVM_REG_PPC_MMCRA
, 0x00000000);
7673 spr_register_kvm(env
, SPR_POWER_PMC1
, "PMC1",
7674 SPR_NOACCESS
, SPR_NOACCESS
,
7675 &spr_read_generic
, &spr_write_generic
,
7676 KVM_REG_PPC_PMC1
, 0x00000000);
7677 spr_register_kvm(env
, SPR_POWER_PMC2
, "PMC2",
7678 SPR_NOACCESS
, SPR_NOACCESS
,
7679 &spr_read_generic
, &spr_write_generic
,
7680 KVM_REG_PPC_PMC2
, 0x00000000);
7681 spr_register_kvm(env
, SPR_POWER_PMC3
, "PMC3",
7682 SPR_NOACCESS
, SPR_NOACCESS
,
7683 &spr_read_generic
, &spr_write_generic
,
7684 KVM_REG_PPC_PMC3
, 0x00000000);
7685 spr_register_kvm(env
, SPR_POWER_PMC4
, "PMC4",
7686 SPR_NOACCESS
, SPR_NOACCESS
,
7687 &spr_read_generic
, &spr_write_generic
,
7688 KVM_REG_PPC_PMC4
, 0x00000000);
7689 spr_register_kvm(env
, SPR_POWER_PMC5
, "PMC5",
7690 SPR_NOACCESS
, SPR_NOACCESS
,
7691 &spr_read_generic
, &spr_write_generic
,
7692 KVM_REG_PPC_PMC5
, 0x00000000);
7693 spr_register_kvm(env
, SPR_POWER_PMC6
, "PMC6",
7694 SPR_NOACCESS
, SPR_NOACCESS
,
7695 &spr_read_generic
, &spr_write_generic
,
7696 KVM_REG_PPC_PMC6
, 0x00000000);
7697 spr_register_kvm(env
, SPR_POWER_SIAR
, "SIAR",
7698 SPR_NOACCESS
, SPR_NOACCESS
,
7699 &spr_read_generic
, &spr_write_generic
,
7700 KVM_REG_PPC_SIAR
, 0x00000000);
7701 spr_register_kvm(env
, SPR_POWER_SDAR
, "SDAR",
7702 SPR_NOACCESS
, SPR_NOACCESS
,
7703 &spr_read_generic
, &spr_write_generic
,
7704 KVM_REG_PPC_SDAR
, 0x00000000);
7707 static void gen_spr_book3s_pmu_user(CPUPPCState
*env
)
7709 spr_register(env
, SPR_POWER_UMMCR0
, "UMMCR0",
7710 &spr_read_ureg
, SPR_NOACCESS
,
7711 &spr_read_ureg
, &spr_write_ureg
,
7713 spr_register(env
, SPR_POWER_UMMCR1
, "UMMCR1",
7714 &spr_read_ureg
, SPR_NOACCESS
,
7715 &spr_read_ureg
, &spr_write_ureg
,
7717 spr_register(env
, SPR_POWER_UMMCRA
, "UMMCRA",
7718 &spr_read_ureg
, SPR_NOACCESS
,
7719 &spr_read_ureg
, &spr_write_ureg
,
7721 spr_register(env
, SPR_POWER_UPMC1
, "UPMC1",
7722 &spr_read_ureg
, SPR_NOACCESS
,
7723 &spr_read_ureg
, &spr_write_ureg
,
7725 spr_register(env
, SPR_POWER_UPMC2
, "UPMC2",
7726 &spr_read_ureg
, SPR_NOACCESS
,
7727 &spr_read_ureg
, &spr_write_ureg
,
7729 spr_register(env
, SPR_POWER_UPMC3
, "UPMC3",
7730 &spr_read_ureg
, SPR_NOACCESS
,
7731 &spr_read_ureg
, &spr_write_ureg
,
7733 spr_register(env
, SPR_POWER_UPMC4
, "UPMC4",
7734 &spr_read_ureg
, SPR_NOACCESS
,
7735 &spr_read_ureg
, &spr_write_ureg
,
7737 spr_register(env
, SPR_POWER_UPMC5
, "UPMC5",
7738 &spr_read_ureg
, SPR_NOACCESS
,
7739 &spr_read_ureg
, &spr_write_ureg
,
7741 spr_register(env
, SPR_POWER_UPMC6
, "UPMC6",
7742 &spr_read_ureg
, SPR_NOACCESS
,
7743 &spr_read_ureg
, &spr_write_ureg
,
7745 spr_register(env
, SPR_POWER_USIAR
, "USIAR",
7746 &spr_read_ureg
, SPR_NOACCESS
,
7747 &spr_read_ureg
, &spr_write_ureg
,
7749 spr_register(env
, SPR_POWER_USDAR
, "USDAR",
7750 &spr_read_ureg
, SPR_NOACCESS
,
7751 &spr_read_ureg
, &spr_write_ureg
,
7755 static void gen_spr_970_pmu_sup(CPUPPCState
*env
)
7757 spr_register_kvm(env
, SPR_970_PMC7
, "PMC7",
7758 SPR_NOACCESS
, SPR_NOACCESS
,
7759 &spr_read_generic
, &spr_write_generic
,
7760 KVM_REG_PPC_PMC7
, 0x00000000);
7761 spr_register_kvm(env
, SPR_970_PMC8
, "PMC8",
7762 SPR_NOACCESS
, SPR_NOACCESS
,
7763 &spr_read_generic
, &spr_write_generic
,
7764 KVM_REG_PPC_PMC8
, 0x00000000);
7767 static void gen_spr_970_pmu_user(CPUPPCState
*env
)
7769 spr_register(env
, SPR_970_UPMC7
, "UPMC7",
7770 &spr_read_ureg
, SPR_NOACCESS
,
7771 &spr_read_ureg
, &spr_write_ureg
,
7773 spr_register(env
, SPR_970_UPMC8
, "UPMC8",
7774 &spr_read_ureg
, SPR_NOACCESS
,
7775 &spr_read_ureg
, &spr_write_ureg
,
7779 static void gen_spr_power8_pmu_sup(CPUPPCState
*env
)
7781 spr_register_kvm(env
, SPR_POWER_MMCR2
, "MMCR2",
7782 SPR_NOACCESS
, SPR_NOACCESS
,
7783 &spr_read_generic
, &spr_write_generic
,
7784 KVM_REG_PPC_MMCR2
, 0x00000000);
7785 spr_register_kvm(env
, SPR_POWER_MMCRS
, "MMCRS",
7786 SPR_NOACCESS
, SPR_NOACCESS
,
7787 &spr_read_generic
, &spr_write_generic
,
7788 KVM_REG_PPC_MMCRS
, 0x00000000);
7789 spr_register_kvm(env
, SPR_POWER_SIER
, "SIER",
7790 SPR_NOACCESS
, SPR_NOACCESS
,
7791 &spr_read_generic
, &spr_write_generic
,
7792 KVM_REG_PPC_SIER
, 0x00000000);
7793 spr_register_kvm(env
, SPR_POWER_SPMC1
, "SPMC1",
7794 SPR_NOACCESS
, SPR_NOACCESS
,
7795 &spr_read_generic
, &spr_write_generic
,
7796 KVM_REG_PPC_SPMC1
, 0x00000000);
7797 spr_register_kvm(env
, SPR_POWER_SPMC2
, "SPMC2",
7798 SPR_NOACCESS
, SPR_NOACCESS
,
7799 &spr_read_generic
, &spr_write_generic
,
7800 KVM_REG_PPC_SPMC2
, 0x00000000);
7801 spr_register_kvm(env
, SPR_TACR
, "TACR",
7802 SPR_NOACCESS
, SPR_NOACCESS
,
7803 &spr_read_generic
, &spr_write_generic
,
7804 KVM_REG_PPC_TACR
, 0x00000000);
7805 spr_register_kvm(env
, SPR_TCSCR
, "TCSCR",
7806 SPR_NOACCESS
, SPR_NOACCESS
,
7807 &spr_read_generic
, &spr_write_generic
,
7808 KVM_REG_PPC_TCSCR
, 0x00000000);
7809 spr_register_kvm(env
, SPR_CSIGR
, "CSIGR",
7810 SPR_NOACCESS
, SPR_NOACCESS
,
7811 &spr_read_generic
, &spr_write_generic
,
7812 KVM_REG_PPC_CSIGR
, 0x00000000);
7815 static void gen_spr_power8_pmu_user(CPUPPCState
*env
)
7817 spr_register(env
, SPR_POWER_UMMCR2
, "UMMCR2",
7818 &spr_read_ureg
, SPR_NOACCESS
,
7819 &spr_read_ureg
, &spr_write_ureg
,
7821 spr_register(env
, SPR_POWER_USIER
, "USIER",
7822 &spr_read_generic
, SPR_NOACCESS
,
7823 &spr_read_generic
, &spr_write_generic
,
7827 static void gen_spr_power5p_ear(CPUPPCState
*env
)
7829 /* External access control */
7830 spr_register(env
, SPR_EAR
, "EAR",
7831 SPR_NOACCESS
, SPR_NOACCESS
,
7832 &spr_read_generic
, &spr_write_generic
,
7836 #if !defined(CONFIG_USER_ONLY)
7837 static void spr_write_hmer(DisasContext
*ctx
, int sprn
, int gprn
)
7839 TCGv hmer
= tcg_temp_new();
7841 gen_load_spr(hmer
, sprn
);
7842 tcg_gen_and_tl(hmer
, cpu_gpr
[gprn
], hmer
);
7843 gen_store_spr(sprn
, hmer
);
7844 spr_store_dump_spr(sprn
);
7845 tcg_temp_free(hmer
);
7848 static void spr_write_lpcr(DisasContext
*ctx
, int sprn
, int gprn
)
7850 gen_helper_store_lpcr(cpu_env
, cpu_gpr
[gprn
]);
7853 static void spr_write_970_hid4(DisasContext
*ctx
, int sprn
, int gprn
)
7855 #if defined(TARGET_PPC64)
7856 spr_write_generic(ctx
, sprn
, gprn
);
7857 gen_helper_store_lpcr(cpu_env
, cpu_gpr
[gprn
]);
7861 #endif /* !defined(CONFIG_USER_ONLY) */
7863 static void gen_spr_970_lpar(CPUPPCState
*env
)
7865 #if !defined(CONFIG_USER_ONLY)
7866 /* Logical partitionning */
7867 /* PPC970: HID4 is effectively the LPCR */
7868 spr_register(env
, SPR_970_HID4
, "HID4",
7869 SPR_NOACCESS
, SPR_NOACCESS
,
7870 &spr_read_generic
, &spr_write_970_hid4
,
7875 static void gen_spr_power5p_lpar(CPUPPCState
*env
)
7877 #if !defined(CONFIG_USER_ONLY)
7878 /* Logical partitionning */
7879 spr_register_kvm_hv(env
, SPR_LPCR
, "LPCR",
7880 SPR_NOACCESS
, SPR_NOACCESS
,
7881 SPR_NOACCESS
, SPR_NOACCESS
,
7882 &spr_read_generic
, &spr_write_lpcr
,
7883 KVM_REG_PPC_LPCR
, LPCR_LPES0
| LPCR_LPES1
);
7884 spr_register_hv(env
, SPR_HDEC
, "HDEC",
7885 SPR_NOACCESS
, SPR_NOACCESS
,
7886 SPR_NOACCESS
, SPR_NOACCESS
,
7887 &spr_read_hdecr
, &spr_write_hdecr
, 0);
7891 static void gen_spr_book3s_ids(CPUPPCState
*env
)
7893 /* FIXME: Will need to deal with thread vs core only SPRs */
7895 /* Processor identification */
7896 spr_register_hv(env
, SPR_PIR
, "PIR",
7897 SPR_NOACCESS
, SPR_NOACCESS
,
7898 &spr_read_generic
, SPR_NOACCESS
,
7899 &spr_read_generic
, NULL
,
7901 spr_register_hv(env
, SPR_HID0
, "HID0",
7902 SPR_NOACCESS
, SPR_NOACCESS
,
7903 SPR_NOACCESS
, SPR_NOACCESS
,
7904 &spr_read_generic
, &spr_write_generic
,
7906 spr_register_hv(env
, SPR_TSCR
, "TSCR",
7907 SPR_NOACCESS
, SPR_NOACCESS
,
7908 SPR_NOACCESS
, SPR_NOACCESS
,
7909 &spr_read_generic
, &spr_write_generic
,
7911 spr_register_hv(env
, SPR_HMER
, "HMER",
7912 SPR_NOACCESS
, SPR_NOACCESS
,
7913 SPR_NOACCESS
, SPR_NOACCESS
,
7914 &spr_read_generic
, &spr_write_hmer
,
7916 spr_register_hv(env
, SPR_HMEER
, "HMEER",
7917 SPR_NOACCESS
, SPR_NOACCESS
,
7918 SPR_NOACCESS
, SPR_NOACCESS
,
7919 &spr_read_generic
, &spr_write_generic
,
7921 spr_register_hv(env
, SPR_TFMR
, "TFMR",
7922 SPR_NOACCESS
, SPR_NOACCESS
,
7923 SPR_NOACCESS
, SPR_NOACCESS
,
7924 &spr_read_generic
, &spr_write_generic
,
7926 spr_register_hv(env
, SPR_LPIDR
, "LPIDR",
7927 SPR_NOACCESS
, SPR_NOACCESS
,
7928 SPR_NOACCESS
, SPR_NOACCESS
,
7929 &spr_read_generic
, &spr_write_lpidr
,
7931 spr_register_hv(env
, SPR_HFSCR
, "HFSCR",
7932 SPR_NOACCESS
, SPR_NOACCESS
,
7933 SPR_NOACCESS
, SPR_NOACCESS
,
7934 &spr_read_generic
, &spr_write_generic
,
7936 spr_register_hv(env
, SPR_MMCRC
, "MMCRC",
7937 SPR_NOACCESS
, SPR_NOACCESS
,
7938 SPR_NOACCESS
, SPR_NOACCESS
,
7939 &spr_read_generic
, &spr_write_generic
,
7941 spr_register_hv(env
, SPR_MMCRH
, "MMCRH",
7942 SPR_NOACCESS
, SPR_NOACCESS
,
7943 SPR_NOACCESS
, SPR_NOACCESS
,
7944 &spr_read_generic
, &spr_write_generic
,
7946 spr_register_hv(env
, SPR_HSPRG0
, "HSPRG0",
7947 SPR_NOACCESS
, SPR_NOACCESS
,
7948 SPR_NOACCESS
, SPR_NOACCESS
,
7949 &spr_read_generic
, &spr_write_generic
,
7951 spr_register_hv(env
, SPR_HSPRG1
, "HSPRG1",
7952 SPR_NOACCESS
, SPR_NOACCESS
,
7953 SPR_NOACCESS
, SPR_NOACCESS
,
7954 &spr_read_generic
, &spr_write_generic
,
7956 spr_register_hv(env
, SPR_HSRR0
, "HSRR0",
7957 SPR_NOACCESS
, SPR_NOACCESS
,
7958 SPR_NOACCESS
, SPR_NOACCESS
,
7959 &spr_read_generic
, &spr_write_generic
,
7961 spr_register_hv(env
, SPR_HSRR1
, "HSRR1",
7962 SPR_NOACCESS
, SPR_NOACCESS
,
7963 SPR_NOACCESS
, SPR_NOACCESS
,
7964 &spr_read_generic
, &spr_write_generic
,
7966 spr_register_hv(env
, SPR_HDAR
, "HDAR",
7967 SPR_NOACCESS
, SPR_NOACCESS
,
7968 SPR_NOACCESS
, SPR_NOACCESS
,
7969 &spr_read_generic
, &spr_write_generic
,
7971 spr_register_hv(env
, SPR_HDSISR
, "HDSISR",
7972 SPR_NOACCESS
, SPR_NOACCESS
,
7973 SPR_NOACCESS
, SPR_NOACCESS
,
7974 &spr_read_generic
, &spr_write_generic
,
7976 spr_register_hv(env
, SPR_RMOR
, "RMOR",
7977 SPR_NOACCESS
, SPR_NOACCESS
,
7978 SPR_NOACCESS
, SPR_NOACCESS
,
7979 &spr_read_generic
, &spr_write_generic
,
7981 spr_register_hv(env
, SPR_HRMOR
, "HRMOR",
7982 SPR_NOACCESS
, SPR_NOACCESS
,
7983 SPR_NOACCESS
, SPR_NOACCESS
,
7984 &spr_read_generic
, &spr_write_generic
,
7988 static void gen_spr_power8_ids(CPUPPCState
*env
)
7990 /* Thread identification */
7991 spr_register(env
, SPR_TIR
, "TIR",
7992 SPR_NOACCESS
, SPR_NOACCESS
,
7993 &spr_read_generic
, SPR_NOACCESS
,
7997 static void gen_spr_book3s_purr(CPUPPCState
*env
)
7999 #if !defined(CONFIG_USER_ONLY)
8000 /* PURR & SPURR: Hack - treat these as aliases for the TB for now */
8001 spr_register_kvm(env
, SPR_PURR
, "PURR",
8002 &spr_read_purr
, SPR_NOACCESS
,
8003 &spr_read_purr
, SPR_NOACCESS
,
8004 KVM_REG_PPC_PURR
, 0x00000000);
8005 spr_register_kvm(env
, SPR_SPURR
, "SPURR",
8006 &spr_read_purr
, SPR_NOACCESS
,
8007 &spr_read_purr
, SPR_NOACCESS
,
8008 KVM_REG_PPC_SPURR
, 0x00000000);
8012 static void gen_spr_power6_dbg(CPUPPCState
*env
)
8014 #if !defined(CONFIG_USER_ONLY)
8015 spr_register(env
, SPR_CFAR
, "SPR_CFAR",
8016 SPR_NOACCESS
, SPR_NOACCESS
,
8017 &spr_read_cfar
, &spr_write_cfar
,
8022 static void gen_spr_power5p_common(CPUPPCState
*env
)
8024 spr_register_kvm(env
, SPR_PPR
, "PPR",
8025 &spr_read_generic
, &spr_write_generic
,
8026 &spr_read_generic
, &spr_write_generic
,
8027 KVM_REG_PPC_PPR
, 0x00000000);
8030 static void gen_spr_power6_common(CPUPPCState
*env
)
8032 #if !defined(CONFIG_USER_ONLY)
8033 spr_register_kvm(env
, SPR_DSCR
, "SPR_DSCR",
8034 SPR_NOACCESS
, SPR_NOACCESS
,
8035 &spr_read_generic
, &spr_write_generic
,
8036 KVM_REG_PPC_DSCR
, 0x00000000);
8039 * Register PCR to report POWERPC_EXCP_PRIV_REG instead of
8040 * POWERPC_EXCP_INVAL_SPR in userspace. Permit hypervisor access.
8042 spr_register_hv(env
, SPR_PCR
, "PCR",
8043 SPR_NOACCESS
, SPR_NOACCESS
,
8044 SPR_NOACCESS
, SPR_NOACCESS
,
8045 &spr_read_generic
, &spr_write_pcr
,
8049 static void spr_read_tar(DisasContext
*ctx
, int gprn
, int sprn
)
8051 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_TAR
, sprn
, FSCR_IC_TAR
);
8052 spr_read_generic(ctx
, gprn
, sprn
);
8055 static void spr_write_tar(DisasContext
*ctx
, int sprn
, int gprn
)
8057 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_TAR
, sprn
, FSCR_IC_TAR
);
8058 spr_write_generic(ctx
, sprn
, gprn
);
8061 static void gen_spr_power8_tce_address_control(CPUPPCState
*env
)
8063 spr_register_kvm(env
, SPR_TAR
, "TAR",
8064 &spr_read_tar
, &spr_write_tar
,
8065 &spr_read_generic
, &spr_write_generic
,
8066 KVM_REG_PPC_TAR
, 0x00000000);
8069 static void spr_read_tm(DisasContext
*ctx
, int gprn
, int sprn
)
8071 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8072 spr_read_generic(ctx
, gprn
, sprn
);
8075 static void spr_write_tm(DisasContext
*ctx
, int sprn
, int gprn
)
8077 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8078 spr_write_generic(ctx
, sprn
, gprn
);
8081 static void spr_read_tm_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
8083 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8084 spr_read_prev_upper32(ctx
, gprn
, sprn
);
8087 static void spr_write_tm_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
8089 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8090 spr_write_prev_upper32(ctx
, sprn
, gprn
);
8093 static void gen_spr_power8_tm(CPUPPCState
*env
)
8095 spr_register_kvm(env
, SPR_TFHAR
, "TFHAR",
8096 &spr_read_tm
, &spr_write_tm
,
8097 &spr_read_tm
, &spr_write_tm
,
8098 KVM_REG_PPC_TFHAR
, 0x00000000);
8099 spr_register_kvm(env
, SPR_TFIAR
, "TFIAR",
8100 &spr_read_tm
, &spr_write_tm
,
8101 &spr_read_tm
, &spr_write_tm
,
8102 KVM_REG_PPC_TFIAR
, 0x00000000);
8103 spr_register_kvm(env
, SPR_TEXASR
, "TEXASR",
8104 &spr_read_tm
, &spr_write_tm
,
8105 &spr_read_tm
, &spr_write_tm
,
8106 KVM_REG_PPC_TEXASR
, 0x00000000);
8107 spr_register(env
, SPR_TEXASRU
, "TEXASRU",
8108 &spr_read_tm_upper32
, &spr_write_tm_upper32
,
8109 &spr_read_tm_upper32
, &spr_write_tm_upper32
,
8113 static void spr_read_ebb(DisasContext
*ctx
, int gprn
, int sprn
)
8115 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8116 spr_read_generic(ctx
, gprn
, sprn
);
8119 static void spr_write_ebb(DisasContext
*ctx
, int sprn
, int gprn
)
8121 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8122 spr_write_generic(ctx
, sprn
, gprn
);
8125 static void spr_read_ebb_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
8127 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8128 spr_read_prev_upper32(ctx
, gprn
, sprn
);
8131 static void spr_write_ebb_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
8133 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8134 spr_write_prev_upper32(ctx
, sprn
, gprn
);
8137 static void gen_spr_power8_ebb(CPUPPCState
*env
)
8139 spr_register(env
, SPR_BESCRS
, "BESCRS",
8140 &spr_read_ebb
, &spr_write_ebb
,
8141 &spr_read_generic
, &spr_write_generic
,
8143 spr_register(env
, SPR_BESCRSU
, "BESCRSU",
8144 &spr_read_ebb_upper32
, &spr_write_ebb_upper32
,
8145 &spr_read_prev_upper32
, &spr_write_prev_upper32
,
8147 spr_register(env
, SPR_BESCRR
, "BESCRR",
8148 &spr_read_ebb
, &spr_write_ebb
,
8149 &spr_read_generic
, &spr_write_generic
,
8151 spr_register(env
, SPR_BESCRRU
, "BESCRRU",
8152 &spr_read_ebb_upper32
, &spr_write_ebb_upper32
,
8153 &spr_read_prev_upper32
, &spr_write_prev_upper32
,
8155 spr_register_kvm(env
, SPR_EBBHR
, "EBBHR",
8156 &spr_read_ebb
, &spr_write_ebb
,
8157 &spr_read_generic
, &spr_write_generic
,
8158 KVM_REG_PPC_EBBHR
, 0x00000000);
8159 spr_register_kvm(env
, SPR_EBBRR
, "EBBRR",
8160 &spr_read_ebb
, &spr_write_ebb
,
8161 &spr_read_generic
, &spr_write_generic
,
8162 KVM_REG_PPC_EBBRR
, 0x00000000);
8163 spr_register_kvm(env
, SPR_BESCR
, "BESCR",
8164 &spr_read_ebb
, &spr_write_ebb
,
8165 &spr_read_generic
, &spr_write_generic
,
8166 KVM_REG_PPC_BESCR
, 0x00000000);
8169 /* Virtual Time Base */
8170 static void gen_spr_vtb(CPUPPCState
*env
)
8172 spr_register_kvm(env
, SPR_VTB
, "VTB",
8173 SPR_NOACCESS
, SPR_NOACCESS
,
8174 &spr_read_tbl
, SPR_NOACCESS
,
8175 KVM_REG_PPC_VTB
, 0x00000000);
8178 static void gen_spr_power8_fscr(CPUPPCState
*env
)
8180 #if defined(CONFIG_USER_ONLY)
8181 target_ulong initval
= 1ULL << FSCR_TAR
;
8183 target_ulong initval
= 0;
8185 spr_register_kvm(env
, SPR_FSCR
, "FSCR",
8186 SPR_NOACCESS
, SPR_NOACCESS
,
8187 &spr_read_generic
, &spr_write_generic
,
8188 KVM_REG_PPC_FSCR
, initval
);
8191 static void gen_spr_power8_pspb(CPUPPCState
*env
)
8193 spr_register_kvm(env
, SPR_PSPB
, "PSPB",
8194 SPR_NOACCESS
, SPR_NOACCESS
,
8195 &spr_read_generic
, &spr_write_generic32
,
8196 KVM_REG_PPC_PSPB
, 0);
8199 static void gen_spr_power8_dpdes(CPUPPCState
*env
)
8201 #if !defined(CONFIG_USER_ONLY)
8202 /* Directed Privileged Door-bell Exception State, used for IPI */
8203 spr_register_kvm_hv(env
, SPR_DPDES
, "DPDES",
8204 SPR_NOACCESS
, SPR_NOACCESS
,
8205 &spr_read_generic
, SPR_NOACCESS
,
8206 &spr_read_generic
, &spr_write_generic
,
8207 KVM_REG_PPC_DPDES
, 0x00000000);
8211 static void gen_spr_power8_ic(CPUPPCState
*env
)
8213 #if !defined(CONFIG_USER_ONLY)
8214 spr_register_hv(env
, SPR_IC
, "IC",
8215 SPR_NOACCESS
, SPR_NOACCESS
,
8216 &spr_read_generic
, SPR_NOACCESS
,
8217 &spr_read_generic
, &spr_write_generic
,
8222 static void gen_spr_power8_book4(CPUPPCState
*env
)
8224 /* Add a number of P8 book4 registers */
8225 #if !defined(CONFIG_USER_ONLY)
8226 spr_register_kvm(env
, SPR_ACOP
, "ACOP",
8227 SPR_NOACCESS
, SPR_NOACCESS
,
8228 &spr_read_generic
, &spr_write_generic
,
8229 KVM_REG_PPC_ACOP
, 0);
8230 spr_register_kvm(env
, SPR_BOOKS_PID
, "PID",
8231 SPR_NOACCESS
, SPR_NOACCESS
,
8232 &spr_read_generic
, &spr_write_pidr
,
8233 KVM_REG_PPC_PID
, 0);
8234 spr_register_kvm(env
, SPR_WORT
, "WORT",
8235 SPR_NOACCESS
, SPR_NOACCESS
,
8236 &spr_read_generic
, &spr_write_generic
,
8237 KVM_REG_PPC_WORT
, 0);
8241 static void gen_spr_power7_book4(CPUPPCState
*env
)
8243 /* Add a number of P7 book4 registers */
8244 #if !defined(CONFIG_USER_ONLY)
8245 spr_register_kvm(env
, SPR_ACOP
, "ACOP",
8246 SPR_NOACCESS
, SPR_NOACCESS
,
8247 &spr_read_generic
, &spr_write_generic
,
8248 KVM_REG_PPC_ACOP
, 0);
8249 spr_register_kvm(env
, SPR_BOOKS_PID
, "PID",
8250 SPR_NOACCESS
, SPR_NOACCESS
,
8251 &spr_read_generic
, &spr_write_generic
,
8252 KVM_REG_PPC_PID
, 0);
8256 static void gen_spr_power8_rpr(CPUPPCState
*env
)
8258 #if !defined(CONFIG_USER_ONLY)
8259 spr_register_hv(env
, SPR_RPR
, "RPR",
8260 SPR_NOACCESS
, SPR_NOACCESS
,
8261 SPR_NOACCESS
, SPR_NOACCESS
,
8262 &spr_read_generic
, &spr_write_generic
,
8263 0x00000103070F1F3F);
8267 static void gen_spr_power9_mmu(CPUPPCState
*env
)
8269 #if !defined(CONFIG_USER_ONLY)
8270 /* Partition Table Control */
8271 spr_register_kvm_hv(env
, SPR_PTCR
, "PTCR",
8272 SPR_NOACCESS
, SPR_NOACCESS
,
8273 SPR_NOACCESS
, SPR_NOACCESS
,
8274 &spr_read_generic
, &spr_write_ptcr
,
8275 KVM_REG_PPC_PTCR
, 0x00000000);
8279 static void init_proc_book3s_common(CPUPPCState
*env
)
8281 gen_spr_ne_601(env
);
8283 gen_spr_usprg3(env
);
8284 gen_spr_book3s_altivec(env
);
8285 gen_spr_book3s_pmu_sup(env
);
8286 gen_spr_book3s_pmu_user(env
);
8287 gen_spr_book3s_ctrl(env
);
8290 static void init_proc_970(CPUPPCState
*env
)
8292 /* Common Registers */
8293 init_proc_book3s_common(env
);
8295 gen_spr_book3s_dbg(env
);
8297 /* 970 Specific Registers */
8298 gen_spr_970_hid(env
);
8299 gen_spr_970_hior(env
);
8301 gen_spr_970_pmu_sup(env
);
8302 gen_spr_970_pmu_user(env
);
8303 gen_spr_970_lpar(env
);
8304 gen_spr_970_dbg(env
);
8307 env
->dcache_line_size
= 128;
8308 env
->icache_line_size
= 128;
8310 /* Allocate hardware IRQ controller */
8312 ppc970_irq_init(env_archcpu(env
));
8315 POWERPC_FAMILY(970)(ObjectClass
*oc
, void *data
)
8317 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8318 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8320 dc
->desc
= "PowerPC 970";
8321 pcc
->init_proc
= init_proc_970
;
8322 pcc
->check_pow
= check_pow_970
;
8323 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
8324 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8325 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8327 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8328 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8329 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8330 PPC_64B
| PPC_ALTIVEC
|
8331 PPC_SEGMENT_64B
| PPC_SLBI
;
8332 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
8333 pcc
->msr_mask
= (1ull << MSR_SF
) |
8348 pcc
->mmu_model
= POWERPC_MMU_64B
;
8349 #if defined(CONFIG_SOFTMMU)
8350 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8351 pcc
->hash64_opts
= &ppc_hash64_opts_basic
;
8353 pcc
->excp_model
= POWERPC_EXCP_970
;
8354 pcc
->bus_model
= PPC_FLAGS_INPUT_970
;
8355 pcc
->bfd_mach
= bfd_mach_ppc64
;
8356 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8357 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8358 POWERPC_FLAG_BUS_CLK
;
8359 pcc
->l1_dcache_size
= 0x8000;
8360 pcc
->l1_icache_size
= 0x10000;
8363 static void init_proc_power5plus(CPUPPCState
*env
)
8365 /* Common Registers */
8366 init_proc_book3s_common(env
);
8368 gen_spr_book3s_dbg(env
);
8370 /* POWER5+ Specific Registers */
8371 gen_spr_970_hid(env
);
8372 gen_spr_970_hior(env
);
8374 gen_spr_970_pmu_sup(env
);
8375 gen_spr_970_pmu_user(env
);
8376 gen_spr_power5p_common(env
);
8377 gen_spr_power5p_lpar(env
);
8378 gen_spr_power5p_ear(env
);
8381 env
->dcache_line_size
= 128;
8382 env
->icache_line_size
= 128;
8384 /* Allocate hardware IRQ controller */
8386 ppc970_irq_init(env_archcpu(env
));
8389 POWERPC_FAMILY(POWER5P
)(ObjectClass
*oc
, void *data
)
8391 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8392 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8394 dc
->fw_name
= "PowerPC,POWER5";
8395 dc
->desc
= "POWER5+";
8396 pcc
->init_proc
= init_proc_power5plus
;
8397 pcc
->check_pow
= check_pow_970
;
8398 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
8399 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8400 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8402 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8403 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8404 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8406 PPC_SEGMENT_64B
| PPC_SLBI
;
8407 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
8408 pcc
->msr_mask
= (1ull << MSR_SF
) |
8423 pcc
->mmu_model
= POWERPC_MMU_2_03
;
8424 #if defined(CONFIG_SOFTMMU)
8425 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8426 pcc
->hash64_opts
= &ppc_hash64_opts_basic
;
8427 pcc
->lrg_decr_bits
= 32;
8429 pcc
->excp_model
= POWERPC_EXCP_970
;
8430 pcc
->bus_model
= PPC_FLAGS_INPUT_970
;
8431 pcc
->bfd_mach
= bfd_mach_ppc64
;
8432 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8433 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8434 POWERPC_FLAG_BUS_CLK
;
8435 pcc
->l1_dcache_size
= 0x8000;
8436 pcc
->l1_icache_size
= 0x10000;
8440 * The CPU used to have a "compat" property which set the
8441 * compatibility mode PVR. However, this was conceptually broken - it
8442 * only makes sense on the pseries machine type (otherwise the guest
8443 * owns the PCR and can control the compatibility mode itself). It's
8444 * been replaced with the 'max-cpu-compat' property on the pseries
8445 * machine type. For backwards compatibility, pseries specially
8446 * parses the -cpu parameter and converts old compat= parameters into
8447 * the appropriate machine parameters. This stub implementation of
8448 * the parameter catches any uses on explicitly created CPUs.
8450 static void getset_compat_deprecated(Object
*obj
, Visitor
*v
, const char *name
,
8451 void *opaque
, Error
**errp
)
8455 if (!qtest_enabled()) {
8456 warn_report("CPU 'compat' property is deprecated and has no effect; "
8457 "use max-cpu-compat machine property instead");
8459 visit_type_null(v
, name
, &null
, NULL
);
8460 qobject_unref(null
);
8463 static const PropertyInfo ppc_compat_deprecated_propinfo
= {
8465 .description
= "compatibility mode (deprecated)",
8466 .get
= getset_compat_deprecated
,
8467 .set
= getset_compat_deprecated
,
8469 static Property powerpc_servercpu_properties
[] = {
8472 .info
= &ppc_compat_deprecated_propinfo
,
8474 DEFINE_PROP_END_OF_LIST(),
8477 static void init_proc_POWER7(CPUPPCState
*env
)
8479 /* Common Registers */
8480 init_proc_book3s_common(env
);
8482 gen_spr_book3s_dbg(env
);
8484 /* POWER7 Specific Registers */
8485 gen_spr_book3s_ids(env
);
8487 gen_spr_book3s_purr(env
);
8488 gen_spr_power5p_common(env
);
8489 gen_spr_power5p_lpar(env
);
8490 gen_spr_power5p_ear(env
);
8491 gen_spr_power6_common(env
);
8492 gen_spr_power6_dbg(env
);
8493 gen_spr_power7_book4(env
);
8496 env
->dcache_line_size
= 128;
8497 env
->icache_line_size
= 128;
8499 /* Allocate hardware IRQ controller */
8500 init_excp_POWER7(env
);
8501 ppcPOWER7_irq_init(env_archcpu(env
));
8504 static bool ppc_pvr_match_power7(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8506 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER7P_BASE
) {
8509 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER7_BASE
) {
8515 static bool cpu_has_work_POWER7(CPUState
*cs
)
8517 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8518 CPUPPCState
*env
= &cpu
->env
;
8521 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8524 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8525 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE0
)) {
8528 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8529 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE1
)) {
8532 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
)) &&
8533 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE2
)) {
8536 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HMI
)) &&
8537 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE2
)) {
8540 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8545 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8549 POWERPC_FAMILY(POWER7
)(ObjectClass
*oc
, void *data
)
8551 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8552 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8553 CPUClass
*cc
= CPU_CLASS(oc
);
8555 dc
->fw_name
= "PowerPC,POWER7";
8556 dc
->desc
= "POWER7";
8557 dc
->props
= powerpc_servercpu_properties
;
8558 pcc
->pvr_match
= ppc_pvr_match_power7
;
8559 pcc
->pcr_mask
= PCR_VEC_DIS
| PCR_VSX_DIS
| PCR_COMPAT_2_05
;
8560 pcc
->pcr_supported
= PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8561 pcc
->init_proc
= init_proc_POWER7
;
8562 pcc
->check_pow
= check_pow_nocheck
;
8563 cc
->has_work
= cpu_has_work_POWER7
;
8564 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8565 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8566 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8567 PPC_FLOAT_FRSQRTES
|
8570 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8571 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8572 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8573 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
8574 PPC_SEGMENT_64B
| PPC_SLBI
|
8575 PPC_POPCNTB
| PPC_POPCNTWD
|
8577 pcc
->insns_flags2
= PPC2_VSX
| PPC2_DFP
| PPC2_DBRX
| PPC2_ISA205
|
8578 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8579 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8580 PPC2_FP_TST_ISA206
| PPC2_FP_CVT_S64
|
8582 pcc
->msr_mask
= (1ull << MSR_SF
) |
8598 pcc
->mmu_model
= POWERPC_MMU_2_06
;
8599 #if defined(CONFIG_SOFTMMU)
8600 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8601 pcc
->hash64_opts
= &ppc_hash64_opts_POWER7
;
8602 pcc
->lrg_decr_bits
= 32;
8604 pcc
->excp_model
= POWERPC_EXCP_POWER7
;
8605 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8606 pcc
->bfd_mach
= bfd_mach_ppc64
;
8607 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8608 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8609 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8611 pcc
->l1_dcache_size
= 0x8000;
8612 pcc
->l1_icache_size
= 0x8000;
8613 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8614 pcc
->lpcr_pm
= LPCR_P7_PECE0
| LPCR_P7_PECE1
| LPCR_P7_PECE2
;
8617 static void init_proc_POWER8(CPUPPCState
*env
)
8619 /* Common Registers */
8620 init_proc_book3s_common(env
);
8622 gen_spr_book3s_207_dbg(env
);
8624 /* POWER8 Specific Registers */
8625 gen_spr_book3s_ids(env
);
8628 gen_spr_book3s_purr(env
);
8629 gen_spr_power5p_common(env
);
8630 gen_spr_power5p_lpar(env
);
8631 gen_spr_power5p_ear(env
);
8632 gen_spr_power6_common(env
);
8633 gen_spr_power6_dbg(env
);
8634 gen_spr_power8_tce_address_control(env
);
8635 gen_spr_power8_ids(env
);
8636 gen_spr_power8_ebb(env
);
8637 gen_spr_power8_fscr(env
);
8638 gen_spr_power8_pmu_sup(env
);
8639 gen_spr_power8_pmu_user(env
);
8640 gen_spr_power8_tm(env
);
8641 gen_spr_power8_pspb(env
);
8642 gen_spr_power8_dpdes(env
);
8644 gen_spr_power8_ic(env
);
8645 gen_spr_power8_book4(env
);
8646 gen_spr_power8_rpr(env
);
8649 env
->dcache_line_size
= 128;
8650 env
->icache_line_size
= 128;
8652 /* Allocate hardware IRQ controller */
8653 init_excp_POWER8(env
);
8654 ppcPOWER7_irq_init(env_archcpu(env
));
8657 static bool ppc_pvr_match_power8(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8659 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8NVL_BASE
) {
8662 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8E_BASE
) {
8665 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8_BASE
) {
8671 static bool cpu_has_work_POWER8(CPUState
*cs
)
8673 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8674 CPUPPCState
*env
= &cpu
->env
;
8677 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8680 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8681 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE2
)) {
8684 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8685 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE3
)) {
8688 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
)) &&
8689 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE4
)) {
8692 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HMI
)) &&
8693 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE4
)) {
8696 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DOORBELL
)) &&
8697 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE0
)) {
8700 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HDOORBELL
)) &&
8701 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE1
)) {
8704 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8709 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8713 POWERPC_FAMILY(POWER8
)(ObjectClass
*oc
, void *data
)
8715 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8716 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8717 CPUClass
*cc
= CPU_CLASS(oc
);
8719 dc
->fw_name
= "PowerPC,POWER8";
8720 dc
->desc
= "POWER8";
8721 dc
->props
= powerpc_servercpu_properties
;
8722 pcc
->pvr_match
= ppc_pvr_match_power8
;
8723 pcc
->pcr_mask
= PCR_TM_DIS
| PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8724 pcc
->pcr_supported
= PCR_COMPAT_2_07
| PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8725 pcc
->init_proc
= init_proc_POWER8
;
8726 pcc
->check_pow
= check_pow_nocheck
;
8727 cc
->has_work
= cpu_has_work_POWER8
;
8728 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8729 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8730 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8731 PPC_FLOAT_FRSQRTES
|
8734 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8735 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8736 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8737 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
8738 PPC_SEGMENT_64B
| PPC_SLBI
|
8739 PPC_POPCNTB
| PPC_POPCNTWD
|
8741 pcc
->insns_flags2
= PPC2_VSX
| PPC2_VSX207
| PPC2_DFP
| PPC2_DBRX
|
8742 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8743 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8744 PPC2_FP_TST_ISA206
| PPC2_BCTAR_ISA207
|
8745 PPC2_LSQ_ISA207
| PPC2_ALTIVEC_207
|
8746 PPC2_ISA205
| PPC2_ISA207S
| PPC2_FP_CVT_S64
|
8747 PPC2_TM
| PPC2_PM_ISA206
;
8748 pcc
->msr_mask
= (1ull << MSR_SF
) |
8768 pcc
->mmu_model
= POWERPC_MMU_2_07
;
8769 #if defined(CONFIG_SOFTMMU)
8770 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8771 pcc
->hash64_opts
= &ppc_hash64_opts_POWER7
;
8772 pcc
->lrg_decr_bits
= 32;
8773 pcc
->n_host_threads
= 8;
8775 pcc
->excp_model
= POWERPC_EXCP_POWER8
;
8776 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8777 pcc
->bfd_mach
= bfd_mach_ppc64
;
8778 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8779 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8780 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8781 POWERPC_FLAG_VSX
| POWERPC_FLAG_TM
;
8782 pcc
->l1_dcache_size
= 0x8000;
8783 pcc
->l1_icache_size
= 0x8000;
8784 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8785 pcc
->lpcr_pm
= LPCR_P8_PECE0
| LPCR_P8_PECE1
| LPCR_P8_PECE2
|
8786 LPCR_P8_PECE3
| LPCR_P8_PECE4
;
8789 #ifdef CONFIG_SOFTMMU
8791 * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings
8792 * Encoded as array of int_32s in the form:
8793 * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
8795 * y -> radix mode supported page size (encoded as a shift)
8797 static struct ppc_radix_page_info POWER9_radix_page_info
= {
8800 0x0000000c, /* 4K - enc: 0x0 */
8801 0xa0000010, /* 64K - enc: 0x5 */
8802 0x20000015, /* 2M - enc: 0x1 */
8803 0x4000001e /* 1G - enc: 0x2 */
8806 #endif /* CONFIG_SOFTMMU */
8808 static void init_proc_POWER9(CPUPPCState
*env
)
8810 /* Common Registers */
8811 init_proc_book3s_common(env
);
8812 gen_spr_book3s_207_dbg(env
);
8814 /* POWER8 Specific Registers */
8815 gen_spr_book3s_ids(env
);
8818 gen_spr_book3s_purr(env
);
8819 gen_spr_power5p_common(env
);
8820 gen_spr_power5p_lpar(env
);
8821 gen_spr_power5p_ear(env
);
8822 gen_spr_power6_common(env
);
8823 gen_spr_power6_dbg(env
);
8824 gen_spr_power8_tce_address_control(env
);
8825 gen_spr_power8_ids(env
);
8826 gen_spr_power8_ebb(env
);
8827 gen_spr_power8_fscr(env
);
8828 gen_spr_power8_pmu_sup(env
);
8829 gen_spr_power8_pmu_user(env
);
8830 gen_spr_power8_tm(env
);
8831 gen_spr_power8_pspb(env
);
8832 gen_spr_power8_dpdes(env
);
8834 gen_spr_power8_ic(env
);
8835 gen_spr_power8_book4(env
);
8836 gen_spr_power8_rpr(env
);
8837 gen_spr_power9_mmu(env
);
8839 /* POWER9 Specific registers */
8840 spr_register_kvm(env
, SPR_TIDR
, "TIDR", NULL
, NULL
,
8841 spr_read_generic
, spr_write_generic
,
8842 KVM_REG_PPC_TIDR
, 0);
8844 /* FIXME: Filter fields properly based on privilege level */
8845 spr_register_kvm_hv(env
, SPR_PSSCR
, "PSSCR", NULL
, NULL
, NULL
, NULL
,
8846 spr_read_generic
, spr_write_generic
,
8847 KVM_REG_PPC_PSSCR
, 0);
8850 env
->dcache_line_size
= 128;
8851 env
->icache_line_size
= 128;
8853 /* Allocate hardware IRQ controller */
8854 init_excp_POWER9(env
);
8855 ppcPOWER9_irq_init(env_archcpu(env
));
8858 static bool ppc_pvr_match_power9(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8860 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER9_BASE
) {
8866 static bool cpu_has_work_POWER9(CPUState
*cs
)
8868 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8869 CPUPPCState
*env
= &cpu
->env
;
8872 uint64_t psscr
= env
->spr
[SPR_PSSCR
];
8874 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8878 /* If EC is clear, just return true on any pending interrupt */
8879 if (!(psscr
& PSSCR_EC
)) {
8882 /* External Exception */
8883 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8884 (env
->spr
[SPR_LPCR
] & LPCR_EEE
)) {
8885 bool heic
= !!(env
->spr
[SPR_LPCR
] & LPCR_HEIC
);
8886 if (heic
== 0 || !msr_hv
|| msr_pr
) {
8890 /* Decrementer Exception */
8891 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8892 (env
->spr
[SPR_LPCR
] & LPCR_DEE
)) {
8895 /* Machine Check or Hypervisor Maintenance Exception */
8896 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
|
8897 1u << PPC_INTERRUPT_HMI
)) && (env
->spr
[SPR_LPCR
] & LPCR_OEE
)) {
8900 /* Privileged Doorbell Exception */
8901 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DOORBELL
)) &&
8902 (env
->spr
[SPR_LPCR
] & LPCR_PDEE
)) {
8905 /* Hypervisor Doorbell Exception */
8906 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HDOORBELL
)) &&
8907 (env
->spr
[SPR_LPCR
] & LPCR_HDEE
)) {
8910 /* Hypervisor virtualization exception */
8911 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HVIRT
)) &&
8912 (env
->spr
[SPR_LPCR
] & LPCR_HVEE
)) {
8915 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8920 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8924 POWERPC_FAMILY(POWER9
)(ObjectClass
*oc
, void *data
)
8926 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8927 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8928 CPUClass
*cc
= CPU_CLASS(oc
);
8930 dc
->fw_name
= "PowerPC,POWER9";
8931 dc
->desc
= "POWER9";
8932 dc
->props
= powerpc_servercpu_properties
;
8933 pcc
->pvr_match
= ppc_pvr_match_power9
;
8934 pcc
->pcr_mask
= PCR_COMPAT_2_05
| PCR_COMPAT_2_06
| PCR_COMPAT_2_07
;
8935 pcc
->pcr_supported
= PCR_COMPAT_3_00
| PCR_COMPAT_2_07
| PCR_COMPAT_2_06
|
8937 pcc
->init_proc
= init_proc_POWER9
;
8938 pcc
->check_pow
= check_pow_nocheck
;
8939 cc
->has_work
= cpu_has_work_POWER9
;
8940 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8941 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8942 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8943 PPC_FLOAT_FRSQRTES
|
8946 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8947 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8949 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
8950 PPC_SEGMENT_64B
| PPC_SLBI
|
8951 PPC_POPCNTB
| PPC_POPCNTWD
|
8953 pcc
->insns_flags2
= PPC2_VSX
| PPC2_VSX207
| PPC2_DFP
| PPC2_DBRX
|
8954 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8955 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8956 PPC2_FP_TST_ISA206
| PPC2_BCTAR_ISA207
|
8957 PPC2_LSQ_ISA207
| PPC2_ALTIVEC_207
|
8958 PPC2_ISA205
| PPC2_ISA207S
| PPC2_FP_CVT_S64
|
8959 PPC2_TM
| PPC2_ISA300
| PPC2_PRCNTL
;
8960 pcc
->msr_mask
= (1ull << MSR_SF
) |
8978 pcc
->mmu_model
= POWERPC_MMU_3_00
;
8979 #if defined(CONFIG_SOFTMMU)
8980 pcc
->handle_mmu_fault
= ppc64_v3_handle_mmu_fault
;
8981 /* segment page size remain the same */
8982 pcc
->hash64_opts
= &ppc_hash64_opts_POWER7
;
8983 pcc
->radix_page_info
= &POWER9_radix_page_info
;
8984 pcc
->lrg_decr_bits
= 56;
8985 pcc
->n_host_threads
= 4;
8987 pcc
->excp_model
= POWERPC_EXCP_POWER9
;
8988 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER9
;
8989 pcc
->bfd_mach
= bfd_mach_ppc64
;
8990 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8991 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8992 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8993 POWERPC_FLAG_VSX
| POWERPC_FLAG_TM
;
8994 pcc
->l1_dcache_size
= 0x8000;
8995 pcc
->l1_icache_size
= 0x8000;
8996 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8997 pcc
->lpcr_pm
= LPCR_PDEE
| LPCR_HDEE
| LPCR_EEE
| LPCR_DEE
| LPCR_OEE
;
9000 #if !defined(CONFIG_USER_ONLY)
9001 void cpu_ppc_set_vhyp(PowerPCCPU
*cpu
, PPCVirtualHypervisor
*vhyp
)
9003 CPUPPCState
*env
= &cpu
->env
;
9008 * With a virtual hypervisor mode we never allow the CPU to go
9009 * hypervisor mode itself
9011 env
->msr_mask
&= ~MSR_HVB
;
9014 #endif /* !defined(CONFIG_USER_ONLY) */
9016 #endif /* defined(TARGET_PPC64) */
9018 /*****************************************************************************/
9019 /* Generic CPU instantiation routine */
9020 static void init_ppc_proc(PowerPCCPU
*cpu
)
9022 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9023 CPUPPCState
*env
= &cpu
->env
;
9024 #if !defined(CONFIG_USER_ONLY)
9027 env
->irq_inputs
= NULL
;
9028 /* Set all exception vectors to an invalid address */
9029 for (i
= 0; i
< POWERPC_EXCP_NB
; i
++) {
9030 env
->excp_vectors
[i
] = (target_ulong
)(-1ULL);
9032 env
->ivor_mask
= 0x00000000;
9033 env
->ivpr_mask
= 0x00000000;
9034 /* Default MMU definitions */
9038 env
->tlb_type
= TLB_NONE
;
9040 /* Register SPR common to all PowerPC implementations */
9041 gen_spr_generic(env
);
9042 spr_register(env
, SPR_PVR
, "PVR",
9043 /* Linux permits userspace to read PVR */
9044 #if defined(CONFIG_LINUX_USER)
9050 &spr_read_generic
, SPR_NOACCESS
,
9052 /* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
9053 if (pcc
->svr
!= POWERPC_SVR_NONE
) {
9054 if (pcc
->svr
& POWERPC_SVR_E500
) {
9055 spr_register(env
, SPR_E500_SVR
, "SVR",
9056 SPR_NOACCESS
, SPR_NOACCESS
,
9057 &spr_read_generic
, SPR_NOACCESS
,
9058 pcc
->svr
& ~POWERPC_SVR_E500
);
9060 spr_register(env
, SPR_SVR
, "SVR",
9061 SPR_NOACCESS
, SPR_NOACCESS
,
9062 &spr_read_generic
, SPR_NOACCESS
,
9066 /* PowerPC implementation specific initialisations (SPRs, timers, ...) */
9067 (*pcc
->init_proc
)(env
);
9069 #if !defined(CONFIG_USER_ONLY)
9070 ppc_gdb_gen_spr_xml(cpu
);
9073 /* MSR bits & flags consistency checks */
9074 if (env
->msr_mask
& (1 << 25)) {
9075 switch (env
->flags
& (POWERPC_FLAG_SPE
| POWERPC_FLAG_VRE
)) {
9076 case POWERPC_FLAG_SPE
:
9077 case POWERPC_FLAG_VRE
:
9080 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9081 "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n");
9084 } else if (env
->flags
& (POWERPC_FLAG_SPE
| POWERPC_FLAG_VRE
)) {
9085 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9086 "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n");
9089 if (env
->msr_mask
& (1 << 17)) {
9090 switch (env
->flags
& (POWERPC_FLAG_TGPR
| POWERPC_FLAG_CE
)) {
9091 case POWERPC_FLAG_TGPR
:
9092 case POWERPC_FLAG_CE
:
9095 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9096 "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n");
9099 } else if (env
->flags
& (POWERPC_FLAG_TGPR
| POWERPC_FLAG_CE
)) {
9100 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9101 "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n");
9104 if (env
->msr_mask
& (1 << 10)) {
9105 switch (env
->flags
& (POWERPC_FLAG_SE
| POWERPC_FLAG_DWE
|
9106 POWERPC_FLAG_UBLE
)) {
9107 case POWERPC_FLAG_SE
:
9108 case POWERPC_FLAG_DWE
:
9109 case POWERPC_FLAG_UBLE
:
9112 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9113 "Should define POWERPC_FLAG_SE or POWERPC_FLAG_DWE or "
9114 "POWERPC_FLAG_UBLE\n");
9117 } else if (env
->flags
& (POWERPC_FLAG_SE
| POWERPC_FLAG_DWE
|
9118 POWERPC_FLAG_UBLE
)) {
9119 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9120 "Should not define POWERPC_FLAG_SE nor POWERPC_FLAG_DWE nor "
9121 "POWERPC_FLAG_UBLE\n");
9124 if (env
->msr_mask
& (1 << 9)) {
9125 switch (env
->flags
& (POWERPC_FLAG_BE
| POWERPC_FLAG_DE
)) {
9126 case POWERPC_FLAG_BE
:
9127 case POWERPC_FLAG_DE
:
9130 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9131 "Should define POWERPC_FLAG_BE or POWERPC_FLAG_DE\n");
9134 } else if (env
->flags
& (POWERPC_FLAG_BE
| POWERPC_FLAG_DE
)) {
9135 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9136 "Should not define POWERPC_FLAG_BE nor POWERPC_FLAG_DE\n");
9139 if (env
->msr_mask
& (1 << 2)) {
9140 switch (env
->flags
& (POWERPC_FLAG_PX
| POWERPC_FLAG_PMM
)) {
9141 case POWERPC_FLAG_PX
:
9142 case POWERPC_FLAG_PMM
:
9145 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9146 "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n");
9149 } else if (env
->flags
& (POWERPC_FLAG_PX
| POWERPC_FLAG_PMM
)) {
9150 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9151 "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n");
9154 if ((env
->flags
& (POWERPC_FLAG_RTC_CLK
| POWERPC_FLAG_BUS_CLK
)) == 0) {
9155 fprintf(stderr
, "PowerPC flags inconsistency\n"
9156 "Should define the time-base and decrementer clock source\n");
9159 /* Allocate TLBs buffer when needed */
9160 #if !defined(CONFIG_USER_ONLY)
9161 if (env
->nb_tlb
!= 0) {
9162 int nb_tlb
= env
->nb_tlb
;
9163 if (env
->id_tlbs
!= 0) {
9166 switch (env
->tlb_type
) {
9168 env
->tlb
.tlb6
= g_new0(ppc6xx_tlb_t
, nb_tlb
);
9171 env
->tlb
.tlbe
= g_new0(ppcemb_tlb_t
, nb_tlb
);
9174 env
->tlb
.tlbm
= g_new0(ppcmas_tlb_t
, nb_tlb
);
9177 /* Pre-compute some useful values */
9178 env
->tlb_per_way
= env
->nb_tlb
/ env
->nb_ways
;
9180 if (env
->irq_inputs
== NULL
) {
9181 warn_report("no internal IRQ controller registered."
9182 " Attempt QEMU to crash very soon !");
9185 if (env
->check_pow
== NULL
) {
9186 warn_report("no power management check handler registered."
9187 " Attempt QEMU to crash very soon !");
9191 #if defined(PPC_DUMP_CPU)
9192 static void dump_ppc_sprs(CPUPPCState
*env
)
9195 #if !defined(CONFIG_USER_ONLY)
9201 printf("Special purpose registers:\n");
9202 for (i
= 0; i
< 32; i
++) {
9203 for (j
= 0; j
< 32; j
++) {
9205 spr
= &env
->spr_cb
[n
];
9206 uw
= spr
->uea_write
!= NULL
&& spr
->uea_write
!= SPR_NOACCESS
;
9207 ur
= spr
->uea_read
!= NULL
&& spr
->uea_read
!= SPR_NOACCESS
;
9208 #if !defined(CONFIG_USER_ONLY)
9209 sw
= spr
->oea_write
!= NULL
&& spr
->oea_write
!= SPR_NOACCESS
;
9210 sr
= spr
->oea_read
!= NULL
&& spr
->oea_read
!= SPR_NOACCESS
;
9211 if (sw
|| sr
|| uw
|| ur
) {
9212 printf("SPR: %4d (%03x) %-8s s%c%c u%c%c\n",
9213 (i
<< 5) | j
, (i
<< 5) | j
, spr
->name
,
9214 sw
? 'w' : '-', sr
? 'r' : '-',
9215 uw
? 'w' : '-', ur
? 'r' : '-');
9219 printf("SPR: %4d (%03x) %-8s u%c%c\n",
9220 (i
<< 5) | j
, (i
<< 5) | j
, spr
->name
,
9221 uw
? 'w' : '-', ur
? 'r' : '-');
9231 /*****************************************************************************/
9235 PPC_DIRECT
= 0, /* Opcode routine */
9236 PPC_INDIRECT
= 1, /* Indirect opcode table */
9239 #define PPC_OPCODE_MASK 0x3
9241 static inline int is_indirect_opcode(void *handler
)
9243 return ((uintptr_t)handler
& PPC_OPCODE_MASK
) == PPC_INDIRECT
;
9246 static inline opc_handler_t
**ind_table(void *handler
)
9248 return (opc_handler_t
**)((uintptr_t)handler
& ~PPC_OPCODE_MASK
);
9251 /* Instruction table creation */
9252 /* Opcodes tables creation */
9253 static void fill_new_table(opc_handler_t
**table
, int len
)
9257 for (i
= 0; i
< len
; i
++) {
9258 table
[i
] = &invalid_handler
;
9262 static int create_new_table(opc_handler_t
**table
, unsigned char idx
)
9264 opc_handler_t
**tmp
;
9266 tmp
= g_new(opc_handler_t
*, PPC_CPU_INDIRECT_OPCODES_LEN
);
9267 fill_new_table(tmp
, PPC_CPU_INDIRECT_OPCODES_LEN
);
9268 table
[idx
] = (opc_handler_t
*)((uintptr_t)tmp
| PPC_INDIRECT
);
9273 static int insert_in_table(opc_handler_t
**table
, unsigned char idx
,
9274 opc_handler_t
*handler
)
9276 if (table
[idx
] != &invalid_handler
) {
9279 table
[idx
] = handler
;
9284 static int register_direct_insn(opc_handler_t
**ppc_opcodes
,
9285 unsigned char idx
, opc_handler_t
*handler
)
9287 if (insert_in_table(ppc_opcodes
, idx
, handler
) < 0) {
9288 printf("*** ERROR: opcode %02x already assigned in main "
9289 "opcode table\n", idx
);
9290 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9291 printf(" Registered handler '%s' - new handler '%s'\n",
9292 ppc_opcodes
[idx
]->oname
, handler
->oname
);
9300 static int register_ind_in_table(opc_handler_t
**table
,
9301 unsigned char idx1
, unsigned char idx2
,
9302 opc_handler_t
*handler
)
9304 if (table
[idx1
] == &invalid_handler
) {
9305 if (create_new_table(table
, idx1
) < 0) {
9306 printf("*** ERROR: unable to create indirect table "
9307 "idx=%02x\n", idx1
);
9311 if (!is_indirect_opcode(table
[idx1
])) {
9312 printf("*** ERROR: idx %02x already assigned to a direct "
9314 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9315 printf(" Registered handler '%s' - new handler '%s'\n",
9316 ind_table(table
[idx1
])[idx2
]->oname
, handler
->oname
);
9321 if (handler
!= NULL
&&
9322 insert_in_table(ind_table(table
[idx1
]), idx2
, handler
) < 0) {
9323 printf("*** ERROR: opcode %02x already assigned in "
9324 "opcode table %02x\n", idx2
, idx1
);
9325 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9326 printf(" Registered handler '%s' - new handler '%s'\n",
9327 ind_table(table
[idx1
])[idx2
]->oname
, handler
->oname
);
9335 static int register_ind_insn(opc_handler_t
**ppc_opcodes
,
9336 unsigned char idx1
, unsigned char idx2
,
9337 opc_handler_t
*handler
)
9339 return register_ind_in_table(ppc_opcodes
, idx1
, idx2
, handler
);
9342 static int register_dblind_insn(opc_handler_t
**ppc_opcodes
,
9343 unsigned char idx1
, unsigned char idx2
,
9344 unsigned char idx3
, opc_handler_t
*handler
)
9346 if (register_ind_in_table(ppc_opcodes
, idx1
, idx2
, NULL
) < 0) {
9347 printf("*** ERROR: unable to join indirect table idx "
9348 "[%02x-%02x]\n", idx1
, idx2
);
9351 if (register_ind_in_table(ind_table(ppc_opcodes
[idx1
]), idx2
, idx3
,
9353 printf("*** ERROR: unable to insert opcode "
9354 "[%02x-%02x-%02x]\n", idx1
, idx2
, idx3
);
9361 static int register_trplind_insn(opc_handler_t
**ppc_opcodes
,
9362 unsigned char idx1
, unsigned char idx2
,
9363 unsigned char idx3
, unsigned char idx4
,
9364 opc_handler_t
*handler
)
9366 opc_handler_t
**table
;
9368 if (register_ind_in_table(ppc_opcodes
, idx1
, idx2
, NULL
) < 0) {
9369 printf("*** ERROR: unable to join indirect table idx "
9370 "[%02x-%02x]\n", idx1
, idx2
);
9373 table
= ind_table(ppc_opcodes
[idx1
]);
9374 if (register_ind_in_table(table
, idx2
, idx3
, NULL
) < 0) {
9375 printf("*** ERROR: unable to join 2nd-level indirect table idx "
9376 "[%02x-%02x-%02x]\n", idx1
, idx2
, idx3
);
9379 table
= ind_table(table
[idx2
]);
9380 if (register_ind_in_table(table
, idx3
, idx4
, handler
) < 0) {
9381 printf("*** ERROR: unable to insert opcode "
9382 "[%02x-%02x-%02x-%02x]\n", idx1
, idx2
, idx3
, idx4
);
9387 static int register_insn(opc_handler_t
**ppc_opcodes
, opcode_t
*insn
)
9389 if (insn
->opc2
!= 0xFF) {
9390 if (insn
->opc3
!= 0xFF) {
9391 if (insn
->opc4
!= 0xFF) {
9392 if (register_trplind_insn(ppc_opcodes
, insn
->opc1
, insn
->opc2
,
9393 insn
->opc3
, insn
->opc4
,
9394 &insn
->handler
) < 0) {
9398 if (register_dblind_insn(ppc_opcodes
, insn
->opc1
, insn
->opc2
,
9399 insn
->opc3
, &insn
->handler
) < 0) {
9404 if (register_ind_insn(ppc_opcodes
, insn
->opc1
,
9405 insn
->opc2
, &insn
->handler
) < 0) {
9410 if (register_direct_insn(ppc_opcodes
, insn
->opc1
, &insn
->handler
) < 0) {
9418 static int test_opcode_table(opc_handler_t
**table
, int len
)
9422 for (i
= 0, count
= 0; i
< len
; i
++) {
9423 /* Consistency fixup */
9424 if (table
[i
] == NULL
) {
9425 table
[i
] = &invalid_handler
;
9427 if (table
[i
] != &invalid_handler
) {
9428 if (is_indirect_opcode(table
[i
])) {
9429 tmp
= test_opcode_table(ind_table(table
[i
]),
9430 PPC_CPU_INDIRECT_OPCODES_LEN
);
9433 table
[i
] = &invalid_handler
;
9446 static void fix_opcode_tables(opc_handler_t
**ppc_opcodes
)
9448 if (test_opcode_table(ppc_opcodes
, PPC_CPU_OPCODES_LEN
) == 0) {
9449 printf("*** WARNING: no opcode defined !\n");
9453 /*****************************************************************************/
9454 static void create_ppc_opcodes(PowerPCCPU
*cpu
, Error
**errp
)
9456 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9459 fill_new_table(cpu
->opcodes
, PPC_CPU_OPCODES_LEN
);
9460 for (opc
= opcodes
; opc
< &opcodes
[ARRAY_SIZE(opcodes
)]; opc
++) {
9461 if (((opc
->handler
.type
& pcc
->insns_flags
) != 0) ||
9462 ((opc
->handler
.type2
& pcc
->insns_flags2
) != 0)) {
9463 if (register_insn(cpu
->opcodes
, opc
) < 0) {
9464 error_setg(errp
, "ERROR initializing PowerPC instruction "
9465 "0x%02x 0x%02x 0x%02x", opc
->opc1
, opc
->opc2
,
9471 fix_opcode_tables(cpu
->opcodes
);
9476 #if defined(PPC_DUMP_CPU)
9477 static void dump_ppc_insns(CPUPPCState
*env
)
9479 opc_handler_t
**table
, *handler
;
9481 uint8_t opc1
, opc2
, opc3
, opc4
;
9483 printf("Instructions set:\n");
9484 /* opc1 is 6 bits long */
9485 for (opc1
= 0x00; opc1
< PPC_CPU_OPCODES_LEN
; opc1
++) {
9486 table
= env
->opcodes
;
9487 handler
= table
[opc1
];
9488 if (is_indirect_opcode(handler
)) {
9489 /* opc2 is 5 bits long */
9490 for (opc2
= 0; opc2
< PPC_CPU_INDIRECT_OPCODES_LEN
; opc2
++) {
9491 table
= env
->opcodes
;
9492 handler
= env
->opcodes
[opc1
];
9493 table
= ind_table(handler
);
9494 handler
= table
[opc2
];
9495 if (is_indirect_opcode(handler
)) {
9496 table
= ind_table(handler
);
9497 /* opc3 is 5 bits long */
9498 for (opc3
= 0; opc3
< PPC_CPU_INDIRECT_OPCODES_LEN
;
9500 handler
= table
[opc3
];
9501 if (is_indirect_opcode(handler
)) {
9502 table
= ind_table(handler
);
9503 /* opc4 is 5 bits long */
9504 for (opc4
= 0; opc4
< PPC_CPU_INDIRECT_OPCODES_LEN
;
9506 handler
= table
[opc4
];
9507 if (handler
->handler
!= &gen_invalid
) {
9508 printf("INSN: %02x %02x %02x %02x -- "
9509 "(%02d %04d %02d) : %s\n",
9510 opc1
, opc2
, opc3
, opc4
,
9511 opc1
, (opc3
<< 5) | opc2
, opc4
,
9516 if (handler
->handler
!= &gen_invalid
) {
9517 /* Special hack to properly dump SPE insns */
9518 p
= strchr(handler
->oname
, '_');
9520 printf("INSN: %02x %02x %02x (%02d %04d) : "
9522 opc1
, opc2
, opc3
, opc1
,
9527 if ((p
- handler
->oname
) != strlen(q
)
9528 || (memcmp(handler
->oname
, q
, strlen(q
))
9530 /* First instruction */
9531 printf("INSN: %02x %02x %02x"
9532 "(%02d %04d) : %.*s\n",
9533 opc1
, opc2
<< 1, opc3
, opc1
,
9534 (opc3
<< 6) | (opc2
<< 1),
9535 (int)(p
- handler
->oname
),
9538 if (strcmp(p
+ 1, q
) != 0) {
9539 /* Second instruction */
9540 printf("INSN: %02x %02x %02x "
9541 "(%02d %04d) : %s\n", opc1
,
9542 (opc2
<< 1) | 1, opc3
, opc1
,
9543 (opc3
<< 6) | (opc2
<< 1) | 1,
9551 if (handler
->handler
!= &gen_invalid
) {
9552 printf("INSN: %02x %02x -- (%02d %04d) : %s\n",
9553 opc1
, opc2
, opc1
, opc2
, handler
->oname
);
9558 if (handler
->handler
!= &gen_invalid
) {
9559 printf("INSN: %02x -- -- (%02d ----) : %s\n",
9560 opc1
, opc1
, handler
->oname
);
9567 static bool avr_need_swap(CPUPPCState
*env
)
9569 #ifdef HOST_WORDS_BIGENDIAN
9576 #if !defined(CONFIG_USER_ONLY)
9577 static int gdb_find_spr_idx(CPUPPCState
*env
, int n
)
9581 for (i
= 0; i
< ARRAY_SIZE(env
->spr_cb
); i
++) {
9582 ppc_spr_t
*spr
= &env
->spr_cb
[i
];
9584 if (spr
->name
&& spr
->gdb_id
== n
) {
9591 static int gdb_get_spr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9596 reg
= gdb_find_spr_idx(env
, n
);
9601 len
= TARGET_LONG_SIZE
;
9602 stn_p(mem_buf
, len
, env
->spr
[reg
]);
9603 ppc_maybe_bswap_register(env
, mem_buf
, len
);
9607 static int gdb_set_spr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9612 reg
= gdb_find_spr_idx(env
, n
);
9617 len
= TARGET_LONG_SIZE
;
9618 ppc_maybe_bswap_register(env
, mem_buf
, len
);
9619 env
->spr
[reg
] = ldn_p(mem_buf
, len
);
9625 static int gdb_get_float_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9628 stfq_p(mem_buf
, *cpu_fpr_ptr(env
, n
));
9629 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9633 stl_p(mem_buf
, env
->fpscr
);
9634 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9640 static int gdb_set_float_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9643 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9644 *cpu_fpr_ptr(env
, n
) = ldfq_p(mem_buf
);
9648 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9649 helper_store_fpscr(env
, ldl_p(mem_buf
), 0xffffffff);
9655 static int gdb_get_avr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9658 ppc_avr_t
*avr
= cpu_avr_ptr(env
, n
);
9659 if (!avr_need_swap(env
)) {
9660 stq_p(mem_buf
, avr
->u64
[0]);
9661 stq_p(mem_buf
+ 8, avr
->u64
[1]);
9663 stq_p(mem_buf
, avr
->u64
[1]);
9664 stq_p(mem_buf
+ 8, avr
->u64
[0]);
9666 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9667 ppc_maybe_bswap_register(env
, mem_buf
+ 8, 8);
9671 stl_p(mem_buf
, helper_mfvscr(env
));
9672 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9676 stl_p(mem_buf
, (uint32_t)env
->spr
[SPR_VRSAVE
]);
9677 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9683 static int gdb_set_avr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9686 ppc_avr_t
*avr
= cpu_avr_ptr(env
, n
);
9687 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9688 ppc_maybe_bswap_register(env
, mem_buf
+ 8, 8);
9689 if (!avr_need_swap(env
)) {
9690 avr
->u64
[0] = ldq_p(mem_buf
);
9691 avr
->u64
[1] = ldq_p(mem_buf
+ 8);
9693 avr
->u64
[1] = ldq_p(mem_buf
);
9694 avr
->u64
[0] = ldq_p(mem_buf
+ 8);
9699 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9700 helper_mtvscr(env
, ldl_p(mem_buf
));
9704 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9705 env
->spr
[SPR_VRSAVE
] = (target_ulong
)ldl_p(mem_buf
);
9711 static int gdb_get_spe_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9714 #if defined(TARGET_PPC64)
9715 stl_p(mem_buf
, env
->gpr
[n
] >> 32);
9716 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9718 stl_p(mem_buf
, env
->gprh
[n
]);
9723 stq_p(mem_buf
, env
->spe_acc
);
9724 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9728 stl_p(mem_buf
, env
->spe_fscr
);
9729 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9735 static int gdb_set_spe_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9738 #if defined(TARGET_PPC64)
9739 target_ulong lo
= (uint32_t)env
->gpr
[n
];
9742 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9744 hi
= (target_ulong
)ldl_p(mem_buf
) << 32;
9745 env
->gpr
[n
] = lo
| hi
;
9747 env
->gprh
[n
] = ldl_p(mem_buf
);
9752 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9753 env
->spe_acc
= ldq_p(mem_buf
);
9757 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9758 env
->spe_fscr
= ldl_p(mem_buf
);
9764 static int gdb_get_vsx_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9767 stq_p(mem_buf
, *cpu_vsrl_ptr(env
, n
));
9768 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9774 static int gdb_set_vsx_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9777 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9778 *cpu_vsrl_ptr(env
, n
) = ldq_p(mem_buf
);
9784 static int ppc_fixup_cpu(PowerPCCPU
*cpu
)
9786 CPUPPCState
*env
= &cpu
->env
;
9789 * TCG doesn't (yet) emulate some groups of instructions that are
9790 * implemented on some otherwise supported CPUs (e.g. VSX and
9791 * decimal floating point instructions on POWER7). We remove
9792 * unsupported instruction groups from the cpu state's instruction
9793 * masks and hope the guest can cope. For at least the pseries
9794 * machine, the unavailability of these instructions can be
9795 * advertised to the guest via the device tree.
9797 if ((env
->insns_flags
& ~PPC_TCG_INSNS
)
9798 || (env
->insns_flags2
& ~PPC_TCG_INSNS2
)) {
9799 warn_report("Disabling some instructions which are not "
9800 "emulated by TCG (0x%" PRIx64
", 0x%" PRIx64
")",
9801 env
->insns_flags
& ~PPC_TCG_INSNS
,
9802 env
->insns_flags2
& ~PPC_TCG_INSNS2
);
9804 env
->insns_flags
&= PPC_TCG_INSNS
;
9805 env
->insns_flags2
&= PPC_TCG_INSNS2
;
9809 static void ppc_cpu_realize(DeviceState
*dev
, Error
**errp
)
9811 CPUState
*cs
= CPU(dev
);
9812 PowerPCCPU
*cpu
= POWERPC_CPU(dev
);
9813 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9814 Error
*local_err
= NULL
;
9816 cpu_exec_realizefn(cs
, &local_err
);
9817 if (local_err
!= NULL
) {
9818 error_propagate(errp
, local_err
);
9821 if (cpu
->vcpu_id
== UNASSIGNED_CPU_INDEX
) {
9822 cpu
->vcpu_id
= cs
->cpu_index
;
9825 if (tcg_enabled()) {
9826 if (ppc_fixup_cpu(cpu
) != 0) {
9827 error_setg(errp
, "Unable to emulate selected CPU with TCG");
9832 create_ppc_opcodes(cpu
, &local_err
);
9833 if (local_err
!= NULL
) {
9834 error_propagate(errp
, local_err
);
9839 if (pcc
->insns_flags
& PPC_FLOAT
) {
9840 gdb_register_coprocessor(cs
, gdb_get_float_reg
, gdb_set_float_reg
,
9841 33, "power-fpu.xml", 0);
9843 if (pcc
->insns_flags
& PPC_ALTIVEC
) {
9844 gdb_register_coprocessor(cs
, gdb_get_avr_reg
, gdb_set_avr_reg
,
9845 34, "power-altivec.xml", 0);
9847 if (pcc
->insns_flags
& PPC_SPE
) {
9848 gdb_register_coprocessor(cs
, gdb_get_spe_reg
, gdb_set_spe_reg
,
9849 34, "power-spe.xml", 0);
9851 if (pcc
->insns_flags2
& PPC2_VSX
) {
9852 gdb_register_coprocessor(cs
, gdb_get_vsx_reg
, gdb_set_vsx_reg
,
9853 32, "power-vsx.xml", 0);
9855 #ifndef CONFIG_USER_ONLY
9856 gdb_register_coprocessor(cs
, gdb_get_spr_reg
, gdb_set_spr_reg
,
9857 pcc
->gdb_num_sprs
, "power-spr.xml", 0);
9861 pcc
->parent_realize(dev
, errp
);
9863 #if defined(PPC_DUMP_CPU)
9865 CPUPPCState
*env
= &cpu
->env
;
9866 const char *mmu_model
, *excp_model
, *bus_model
;
9867 switch (env
->mmu_model
) {
9868 case POWERPC_MMU_32B
:
9869 mmu_model
= "PowerPC 32";
9871 case POWERPC_MMU_SOFT_6xx
:
9872 mmu_model
= "PowerPC 6xx/7xx with software driven TLBs";
9874 case POWERPC_MMU_SOFT_74xx
:
9875 mmu_model
= "PowerPC 74xx with software driven TLBs";
9877 case POWERPC_MMU_SOFT_4xx
:
9878 mmu_model
= "PowerPC 4xx with software driven TLBs";
9880 case POWERPC_MMU_SOFT_4xx_Z
:
9881 mmu_model
= "PowerPC 4xx with software driven TLBs "
9882 "and zones protections";
9884 case POWERPC_MMU_REAL
:
9885 mmu_model
= "PowerPC real mode only";
9887 case POWERPC_MMU_MPC8xx
:
9888 mmu_model
= "PowerPC MPC8xx";
9890 case POWERPC_MMU_BOOKE
:
9891 mmu_model
= "PowerPC BookE";
9893 case POWERPC_MMU_BOOKE206
:
9894 mmu_model
= "PowerPC BookE 2.06";
9896 case POWERPC_MMU_601
:
9897 mmu_model
= "PowerPC 601";
9899 #if defined(TARGET_PPC64)
9900 case POWERPC_MMU_64B
:
9901 mmu_model
= "PowerPC 64";
9905 mmu_model
= "Unknown or invalid";
9908 switch (env
->excp_model
) {
9909 case POWERPC_EXCP_STD
:
9910 excp_model
= "PowerPC";
9912 case POWERPC_EXCP_40x
:
9913 excp_model
= "PowerPC 40x";
9915 case POWERPC_EXCP_601
:
9916 excp_model
= "PowerPC 601";
9918 case POWERPC_EXCP_602
:
9919 excp_model
= "PowerPC 602";
9921 case POWERPC_EXCP_603
:
9922 excp_model
= "PowerPC 603";
9924 case POWERPC_EXCP_603E
:
9925 excp_model
= "PowerPC 603e";
9927 case POWERPC_EXCP_604
:
9928 excp_model
= "PowerPC 604";
9930 case POWERPC_EXCP_7x0
:
9931 excp_model
= "PowerPC 740/750";
9933 case POWERPC_EXCP_7x5
:
9934 excp_model
= "PowerPC 745/755";
9936 case POWERPC_EXCP_74xx
:
9937 excp_model
= "PowerPC 74xx";
9939 case POWERPC_EXCP_BOOKE
:
9940 excp_model
= "PowerPC BookE";
9942 #if defined(TARGET_PPC64)
9943 case POWERPC_EXCP_970
:
9944 excp_model
= "PowerPC 970";
9948 excp_model
= "Unknown or invalid";
9951 switch (env
->bus_model
) {
9952 case PPC_FLAGS_INPUT_6xx
:
9953 bus_model
= "PowerPC 6xx";
9955 case PPC_FLAGS_INPUT_BookE
:
9956 bus_model
= "PowerPC BookE";
9958 case PPC_FLAGS_INPUT_405
:
9959 bus_model
= "PowerPC 405";
9961 case PPC_FLAGS_INPUT_401
:
9962 bus_model
= "PowerPC 401/403";
9964 case PPC_FLAGS_INPUT_RCPU
:
9965 bus_model
= "RCPU / MPC8xx";
9967 #if defined(TARGET_PPC64)
9968 case PPC_FLAGS_INPUT_970
:
9969 bus_model
= "PowerPC 970";
9973 bus_model
= "Unknown or invalid";
9976 printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64
"\n"
9977 " MMU model : %s\n",
9978 object_class_get_name(OBJECT_CLASS(pcc
)),
9979 pcc
->pvr
, pcc
->msr_mask
, mmu_model
);
9980 #if !defined(CONFIG_USER_ONLY)
9981 if (env
->tlb
.tlb6
) {
9982 printf(" %d %s TLB in %d ways\n",
9983 env
->nb_tlb
, env
->id_tlbs
? "splitted" : "merged",
9987 printf(" Exceptions model : %s\n"
9988 " Bus model : %s\n",
9989 excp_model
, bus_model
);
9990 printf(" MSR features :\n");
9991 if (env
->flags
& POWERPC_FLAG_SPE
) {
9992 printf(" signal processing engine enable"
9994 } else if (env
->flags
& POWERPC_FLAG_VRE
) {
9995 printf(" vector processor enable\n");
9997 if (env
->flags
& POWERPC_FLAG_TGPR
) {
9998 printf(" temporary GPRs\n");
9999 } else if (env
->flags
& POWERPC_FLAG_CE
) {
10000 printf(" critical input enable\n");
10002 if (env
->flags
& POWERPC_FLAG_SE
) {
10003 printf(" single-step trace mode\n");
10004 } else if (env
->flags
& POWERPC_FLAG_DWE
) {
10005 printf(" debug wait enable\n");
10006 } else if (env
->flags
& POWERPC_FLAG_UBLE
) {
10007 printf(" user BTB lock enable\n");
10009 if (env
->flags
& POWERPC_FLAG_BE
) {
10010 printf(" branch-step trace mode\n");
10011 } else if (env
->flags
& POWERPC_FLAG_DE
) {
10012 printf(" debug interrupt enable\n");
10014 if (env
->flags
& POWERPC_FLAG_PX
) {
10015 printf(" inclusive protection\n");
10016 } else if (env
->flags
& POWERPC_FLAG_PMM
) {
10017 printf(" performance monitor mark\n");
10019 if (env
->flags
== POWERPC_FLAG_NONE
) {
10022 printf(" Time-base/decrementer clock source: %s\n",
10023 env
->flags
& POWERPC_FLAG_RTC_CLK
? "RTC clock" : "bus clock");
10024 dump_ppc_insns(env
);
10025 dump_ppc_sprs(env
);
10032 cpu_exec_unrealizefn(cs
);
10035 static void ppc_cpu_unrealize(DeviceState
*dev
, Error
**errp
)
10037 PowerPCCPU
*cpu
= POWERPC_CPU(dev
);
10038 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10039 Error
*local_err
= NULL
;
10040 opc_handler_t
**table
, **table_2
;
10043 pcc
->parent_unrealize(dev
, &local_err
);
10044 if (local_err
!= NULL
) {
10045 error_propagate(errp
, local_err
);
10049 for (i
= 0; i
< PPC_CPU_OPCODES_LEN
; i
++) {
10050 if (cpu
->opcodes
[i
] == &invalid_handler
) {
10053 if (is_indirect_opcode(cpu
->opcodes
[i
])) {
10054 table
= ind_table(cpu
->opcodes
[i
]);
10055 for (j
= 0; j
< PPC_CPU_INDIRECT_OPCODES_LEN
; j
++) {
10056 if (table
[j
] == &invalid_handler
) {
10059 if (is_indirect_opcode(table
[j
])) {
10060 table_2
= ind_table(table
[j
]);
10061 for (k
= 0; k
< PPC_CPU_INDIRECT_OPCODES_LEN
; k
++) {
10062 if (table_2
[k
] != &invalid_handler
&&
10063 is_indirect_opcode(table_2
[k
])) {
10064 g_free((opc_handler_t
*)((uintptr_t)table_2
[k
] &
10068 g_free((opc_handler_t
*)((uintptr_t)table
[j
] &
10072 g_free((opc_handler_t
*)((uintptr_t)cpu
->opcodes
[i
] &
10078 static gint
ppc_cpu_compare_class_pvr(gconstpointer a
, gconstpointer b
)
10080 ObjectClass
*oc
= (ObjectClass
*)a
;
10081 uint32_t pvr
= *(uint32_t *)b
;
10082 PowerPCCPUClass
*pcc
= (PowerPCCPUClass
*)a
;
10084 /* -cpu host does a PVR lookup during construction */
10085 if (unlikely(strcmp(object_class_get_name(oc
),
10086 TYPE_HOST_POWERPC_CPU
) == 0)) {
10090 return pcc
->pvr
== pvr
? 0 : -1;
10093 PowerPCCPUClass
*ppc_cpu_class_by_pvr(uint32_t pvr
)
10095 GSList
*list
, *item
;
10096 PowerPCCPUClass
*pcc
= NULL
;
10098 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10099 item
= g_slist_find_custom(list
, &pvr
, ppc_cpu_compare_class_pvr
);
10100 if (item
!= NULL
) {
10101 pcc
= POWERPC_CPU_CLASS(item
->data
);
10103 g_slist_free(list
);
10108 static gint
ppc_cpu_compare_class_pvr_mask(gconstpointer a
, gconstpointer b
)
10110 ObjectClass
*oc
= (ObjectClass
*)a
;
10111 uint32_t pvr
= *(uint32_t *)b
;
10112 PowerPCCPUClass
*pcc
= (PowerPCCPUClass
*)a
;
10114 /* -cpu host does a PVR lookup during construction */
10115 if (unlikely(strcmp(object_class_get_name(oc
),
10116 TYPE_HOST_POWERPC_CPU
) == 0)) {
10120 if (pcc
->pvr_match(pcc
, pvr
)) {
10127 PowerPCCPUClass
*ppc_cpu_class_by_pvr_mask(uint32_t pvr
)
10129 GSList
*list
, *item
;
10130 PowerPCCPUClass
*pcc
= NULL
;
10132 list
= object_class_get_list(TYPE_POWERPC_CPU
, true);
10133 item
= g_slist_find_custom(list
, &pvr
, ppc_cpu_compare_class_pvr_mask
);
10134 if (item
!= NULL
) {
10135 pcc
= POWERPC_CPU_CLASS(item
->data
);
10137 g_slist_free(list
);
10142 static const char *ppc_cpu_lookup_alias(const char *alias
)
10146 for (ai
= 0; ppc_cpu_aliases
[ai
].alias
!= NULL
; ai
++) {
10147 if (strcmp(ppc_cpu_aliases
[ai
].alias
, alias
) == 0) {
10148 return ppc_cpu_aliases
[ai
].model
;
10155 static ObjectClass
*ppc_cpu_class_by_name(const char *name
)
10157 char *cpu_model
, *typename
;
10163 * Lookup by PVR if cpu_model is valid 8 digit hex number (excl:
10164 * 0x prefix if present)
10166 if (!qemu_strtoul(name
, &p
, 16, &pvr
)) {
10167 int len
= p
- name
;
10168 len
= (len
== 10) && (name
[1] == 'x') ? len
- 2 : len
;
10169 if ((len
== 8) && (*p
== '\0')) {
10170 return OBJECT_CLASS(ppc_cpu_class_by_pvr(pvr
));
10174 cpu_model
= g_ascii_strdown(name
, -1);
10175 p
= ppc_cpu_lookup_alias(cpu_model
);
10178 cpu_model
= g_strdup(p
);
10181 typename
= g_strdup_printf("%s" POWERPC_CPU_TYPE_SUFFIX
, cpu_model
);
10182 oc
= object_class_by_name(typename
);
10189 static void ppc_cpu_parse_featurestr(const char *type
, char *features
,
10192 Object
*machine
= qdev_get_machine();
10193 const PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(object_class_by_name(type
));
10199 if (object_property_find(machine
, "max-cpu-compat", NULL
)) {
10202 char *s
= features
;
10203 Error
*local_err
= NULL
;
10204 char *compat_str
= NULL
;
10207 * Backwards compatibility hack:
10209 * CPUs had a "compat=" property which didn't make sense for
10210 * anything except pseries. It was replaced by "max-cpu-compat"
10211 * machine option. This supports old command lines like
10212 * -cpu POWER8,compat=power7
10213 * By stripping the compat option and applying it to the machine
10214 * before passing it on to the cpu level parser.
10216 inpieces
= g_strsplit(features
, ",", 0);
10218 for (i
= 0; inpieces
[i
]; i
++) {
10219 if (g_str_has_prefix(inpieces
[i
], "compat=")) {
10220 compat_str
= inpieces
[i
];
10223 if ((i
!= 0) && (s
!= features
)) {
10224 s
= g_stpcpy(s
, ",");
10226 s
= g_stpcpy(s
, inpieces
[i
]);
10230 char *v
= compat_str
+ strlen("compat=");
10231 object_property_set_str(machine
, v
, "max-cpu-compat", &local_err
);
10233 g_strfreev(inpieces
);
10235 error_propagate(errp
, local_err
);
10240 /* do property processing with generic handler */
10241 pcc
->parent_parse_features(type
, features
, errp
);
10244 PowerPCCPUClass
*ppc_cpu_get_family_class(PowerPCCPUClass
*pcc
)
10246 ObjectClass
*oc
= OBJECT_CLASS(pcc
);
10248 while (oc
&& !object_class_is_abstract(oc
)) {
10249 oc
= object_class_get_parent(oc
);
10253 return POWERPC_CPU_CLASS(oc
);
10256 /* Sort by PVR, ordering special case "host" last. */
10257 static gint
ppc_cpu_list_compare(gconstpointer a
, gconstpointer b
)
10259 ObjectClass
*oc_a
= (ObjectClass
*)a
;
10260 ObjectClass
*oc_b
= (ObjectClass
*)b
;
10261 PowerPCCPUClass
*pcc_a
= POWERPC_CPU_CLASS(oc_a
);
10262 PowerPCCPUClass
*pcc_b
= POWERPC_CPU_CLASS(oc_b
);
10263 const char *name_a
= object_class_get_name(oc_a
);
10264 const char *name_b
= object_class_get_name(oc_b
);
10266 if (strcmp(name_a
, TYPE_HOST_POWERPC_CPU
) == 0) {
10268 } else if (strcmp(name_b
, TYPE_HOST_POWERPC_CPU
) == 0) {
10271 /* Avoid an integer overflow during subtraction */
10272 if (pcc_a
->pvr
< pcc_b
->pvr
) {
10274 } else if (pcc_a
->pvr
> pcc_b
->pvr
) {
10282 static void ppc_cpu_list_entry(gpointer data
, gpointer user_data
)
10284 ObjectClass
*oc
= data
;
10285 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10286 DeviceClass
*family
= DEVICE_CLASS(ppc_cpu_get_family_class(pcc
));
10287 const char *typename
= object_class_get_name(oc
);
10291 if (unlikely(strcmp(typename
, TYPE_HOST_POWERPC_CPU
) == 0)) {
10295 name
= g_strndup(typename
,
10296 strlen(typename
) - strlen(POWERPC_CPU_TYPE_SUFFIX
));
10297 qemu_printf("PowerPC %-16s PVR %08x\n", name
, pcc
->pvr
);
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_name(alias
->model
);
10302 if (alias_oc
!= oc
) {
10306 * If running with KVM, we might update the family alias later, so
10307 * avoid printing the wrong alias here and use "preferred" instead
10309 if (strcmp(alias
->alias
, family
->desc
) == 0) {
10310 qemu_printf("PowerPC %-16s (alias for preferred %s CPU)\n",
10311 alias
->alias
, family
->desc
);
10313 qemu_printf("PowerPC %-16s (alias for %s)\n",
10314 alias
->alias
, name
);
10320 void ppc_cpu_list(void)
10324 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10325 list
= g_slist_sort(list
, ppc_cpu_list_compare
);
10326 g_slist_foreach(list
, ppc_cpu_list_entry
, NULL
);
10327 g_slist_free(list
);
10331 qemu_printf("PowerPC %-16s\n", "host");
10335 static void ppc_cpu_defs_entry(gpointer data
, gpointer user_data
)
10337 ObjectClass
*oc
= data
;
10338 CpuDefinitionInfoList
**first
= user_data
;
10339 const char *typename
;
10340 CpuDefinitionInfoList
*entry
;
10341 CpuDefinitionInfo
*info
;
10343 typename
= object_class_get_name(oc
);
10344 info
= g_malloc0(sizeof(*info
));
10345 info
->name
= g_strndup(typename
,
10346 strlen(typename
) - strlen(POWERPC_CPU_TYPE_SUFFIX
));
10348 entry
= g_malloc0(sizeof(*entry
));
10349 entry
->value
= info
;
10350 entry
->next
= *first
;
10354 CpuDefinitionInfoList
*qmp_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_name(alias
->model
);
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 /* CPUClass::reset() */
10404 static void ppc_cpu_reset(CPUState
*s
)
10406 PowerPCCPU
*cpu
= POWERPC_CPU(s
);
10407 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10408 CPUPPCState
*env
= &cpu
->env
;
10412 pcc
->parent_reset(s
);
10414 msr
= (target_ulong
)0;
10415 msr
|= (target_ulong
)MSR_HVB
;
10416 msr
|= (target_ulong
)0 << MSR_AP
; /* TO BE CHECKED */
10417 msr
|= (target_ulong
)0 << MSR_SA
; /* TO BE CHECKED */
10418 msr
|= (target_ulong
)1 << MSR_EP
;
10419 #if defined(DO_SINGLE_STEP) && 0
10420 /* Single step trace mode */
10421 msr
|= (target_ulong
)1 << MSR_SE
;
10422 msr
|= (target_ulong
)1 << MSR_BE
;
10424 #if defined(CONFIG_USER_ONLY)
10425 msr
|= (target_ulong
)1 << MSR_FP
; /* Allow floating point usage */
10426 msr
|= (target_ulong
)1 << MSR_FE0
; /* Allow floating point exceptions */
10427 msr
|= (target_ulong
)1 << MSR_FE1
;
10428 msr
|= (target_ulong
)1 << MSR_VR
; /* Allow altivec usage */
10429 msr
|= (target_ulong
)1 << MSR_VSX
; /* Allow VSX usage */
10430 msr
|= (target_ulong
)1 << MSR_SPE
; /* Allow SPE usage */
10431 msr
|= (target_ulong
)1 << MSR_PR
;
10432 #if defined(TARGET_PPC64)
10433 msr
|= (target_ulong
)1 << MSR_TM
; /* Transactional memory */
10435 #if !defined(TARGET_WORDS_BIGENDIAN)
10436 msr
|= (target_ulong
)1 << MSR_LE
; /* Little-endian user mode */
10437 if (!((env
->msr_mask
>> MSR_LE
) & 1)) {
10438 fprintf(stderr
, "Selected CPU does not support little-endian.\n");
10444 #if defined(TARGET_PPC64)
10445 if (env
->mmu_model
& POWERPC_MMU_64
) {
10446 msr
|= (1ULL << MSR_SF
);
10450 hreg_store_msr(env
, msr
, 1);
10452 #if !defined(CONFIG_USER_ONLY)
10453 env
->nip
= env
->hreset_vector
| env
->excp_prefix
;
10454 if (env
->mmu_model
!= POWERPC_MMU_REAL
) {
10455 ppc_tlb_invalidate_all(env
);
10459 hreg_compute_hflags(env
);
10460 env
->reserve_addr
= (target_ulong
)-1ULL;
10461 /* Be sure no exception or interrupt is pending */
10462 env
->pending_interrupts
= 0;
10463 s
->exception_index
= POWERPC_EXCP_NONE
;
10464 env
->error_code
= 0;
10466 /* tininess for underflow is detected before rounding */
10467 set_float_detect_tininess(float_tininess_before_rounding
,
10470 for (i
= 0; i
< ARRAY_SIZE(env
->spr_cb
); i
++) {
10471 ppc_spr_t
*spr
= &env
->spr_cb
[i
];
10476 env
->spr
[i
] = spr
->default_value
;
10480 #ifndef CONFIG_USER_ONLY
10481 static bool ppc_cpu_is_big_endian(CPUState
*cs
)
10483 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10484 CPUPPCState
*env
= &cpu
->env
;
10486 cpu_synchronize_state(cs
);
10491 static void ppc_cpu_exec_enter(CPUState
*cs
)
10493 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10496 PPCVirtualHypervisorClass
*vhc
=
10497 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu
->vhyp
);
10498 vhc
->cpu_exec_enter(cpu
->vhyp
, cpu
);
10502 static void ppc_cpu_exec_exit(CPUState
*cs
)
10504 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10507 PPCVirtualHypervisorClass
*vhc
=
10508 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu
->vhyp
);
10509 vhc
->cpu_exec_exit(cpu
->vhyp
, cpu
);
10514 static void ppc_cpu_instance_init(Object
*obj
)
10516 PowerPCCPU
*cpu
= POWERPC_CPU(obj
);
10517 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10518 CPUPPCState
*env
= &cpu
->env
;
10520 cpu_set_cpustate_pointers(cpu
);
10521 cpu
->vcpu_id
= UNASSIGNED_CPU_INDEX
;
10523 env
->msr_mask
= pcc
->msr_mask
;
10524 env
->mmu_model
= pcc
->mmu_model
;
10525 env
->excp_model
= pcc
->excp_model
;
10526 env
->bus_model
= pcc
->bus_model
;
10527 env
->insns_flags
= pcc
->insns_flags
;
10528 env
->insns_flags2
= pcc
->insns_flags2
;
10529 env
->flags
= pcc
->flags
;
10530 env
->bfd_mach
= pcc
->bfd_mach
;
10531 env
->check_pow
= pcc
->check_pow
;
10534 * Mark HV mode as supported if the CPU has an MSR_HV bit in the
10535 * msr_mask. The mask can later be cleared by PAPR mode but the hv
10536 * mode support will remain, thus enforcing that we cannot use
10537 * priv. instructions in guest in PAPR mode. For 970 we currently
10538 * simply don't set HV in msr_mask thus simulating an "Apple mode"
10539 * 970. If we ever want to support 970 HV mode, we'll have to add
10540 * a processor attribute of some sort.
10542 #if !defined(CONFIG_USER_ONLY)
10543 env
->has_hv_mode
= !!(env
->msr_mask
& MSR_HVB
);
10546 ppc_hash64_init(cpu
);
10549 static void ppc_cpu_instance_finalize(Object
*obj
)
10551 PowerPCCPU
*cpu
= POWERPC_CPU(obj
);
10553 ppc_hash64_finalize(cpu
);
10556 static bool ppc_pvr_match_default(PowerPCCPUClass
*pcc
, uint32_t pvr
)
10558 return pcc
->pvr
== pvr
;
10561 static gchar
*ppc_gdb_arch_name(CPUState
*cs
)
10563 #if defined(TARGET_PPC64)
10564 return g_strdup("powerpc:common64");
10566 return g_strdup("powerpc:common");
10570 static void ppc_disas_set_info(CPUState
*cs
, disassemble_info
*info
)
10572 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10573 CPUPPCState
*env
= &cpu
->env
;
10575 if ((env
->hflags
>> MSR_LE
) & 1) {
10576 info
->endian
= BFD_ENDIAN_LITTLE
;
10578 info
->mach
= env
->bfd_mach
;
10579 if (!env
->bfd_mach
) {
10580 #ifdef TARGET_PPC64
10581 info
->mach
= bfd_mach_ppc64
;
10583 info
->mach
= bfd_mach_ppc
;
10586 info
->disassembler_options
= (char *)"any";
10587 info
->print_insn
= print_insn_ppc
;
10589 info
->cap_arch
= CS_ARCH_PPC
;
10590 #ifdef TARGET_PPC64
10591 info
->cap_mode
= CS_MODE_64
;
10595 static Property ppc_cpu_properties
[] = {
10596 DEFINE_PROP_BOOL("pre-2.8-migration", PowerPCCPU
, pre_2_8_migration
, false),
10597 DEFINE_PROP_BOOL("pre-2.10-migration", PowerPCCPU
, pre_2_10_migration
,
10599 DEFINE_PROP_BOOL("pre-3.0-migration", PowerPCCPU
, pre_3_0_migration
,
10601 DEFINE_PROP_END_OF_LIST(),
10604 static void ppc_cpu_class_init(ObjectClass
*oc
, void *data
)
10606 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10607 CPUClass
*cc
= CPU_CLASS(oc
);
10608 DeviceClass
*dc
= DEVICE_CLASS(oc
);
10610 device_class_set_parent_realize(dc
, ppc_cpu_realize
,
10611 &pcc
->parent_realize
);
10612 device_class_set_parent_unrealize(dc
, ppc_cpu_unrealize
,
10613 &pcc
->parent_unrealize
);
10614 pcc
->pvr_match
= ppc_pvr_match_default
;
10615 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_always
;
10616 dc
->props
= ppc_cpu_properties
;
10618 pcc
->parent_reset
= cc
->reset
;
10619 cc
->reset
= ppc_cpu_reset
;
10621 cc
->class_by_name
= ppc_cpu_class_by_name
;
10622 pcc
->parent_parse_features
= cc
->parse_features
;
10623 cc
->parse_features
= ppc_cpu_parse_featurestr
;
10624 cc
->has_work
= ppc_cpu_has_work
;
10625 cc
->do_interrupt
= ppc_cpu_do_interrupt
;
10626 cc
->cpu_exec_interrupt
= ppc_cpu_exec_interrupt
;
10627 cc
->dump_state
= ppc_cpu_dump_state
;
10628 cc
->dump_statistics
= ppc_cpu_dump_statistics
;
10629 cc
->set_pc
= ppc_cpu_set_pc
;
10630 cc
->gdb_read_register
= ppc_cpu_gdb_read_register
;
10631 cc
->gdb_write_register
= ppc_cpu_gdb_write_register
;
10632 cc
->do_unaligned_access
= ppc_cpu_do_unaligned_access
;
10633 #ifndef CONFIG_USER_ONLY
10634 cc
->get_phys_page_debug
= ppc_cpu_get_phys_page_debug
;
10635 cc
->vmsd
= &vmstate_ppc_cpu
;
10637 #if defined(CONFIG_SOFTMMU)
10638 cc
->write_elf64_note
= ppc64_cpu_write_elf64_note
;
10639 cc
->write_elf32_note
= ppc32_cpu_write_elf32_note
;
10642 cc
->gdb_num_core_regs
= 71;
10643 #ifndef CONFIG_USER_ONLY
10644 cc
->gdb_get_dynamic_xml
= ppc_gdb_get_dynamic_xml
;
10646 #ifdef USE_APPLE_GDB
10647 cc
->gdb_read_register
= ppc_cpu_gdb_read_register_apple
;
10648 cc
->gdb_write_register
= ppc_cpu_gdb_write_register_apple
;
10649 cc
->gdb_num_core_regs
= 71 + 32;
10652 cc
->gdb_arch_name
= ppc_gdb_arch_name
;
10653 #if defined(TARGET_PPC64)
10654 cc
->gdb_core_xml_file
= "power64-core.xml";
10656 cc
->gdb_core_xml_file
= "power-core.xml";
10658 #ifndef CONFIG_USER_ONLY
10659 cc
->virtio_is_big_endian
= ppc_cpu_is_big_endian
;
10662 cc
->tcg_initialize
= ppc_translate_init
;
10663 cc
->tlb_fill
= ppc_cpu_tlb_fill
;
10665 #ifndef CONFIG_USER_ONLY
10666 cc
->cpu_exec_enter
= ppc_cpu_exec_enter
;
10667 cc
->cpu_exec_exit
= ppc_cpu_exec_exit
;
10670 cc
->disas_set_info
= ppc_disas_set_info
;
10672 dc
->fw_name
= "PowerPC,UNKNOWN";
10675 static const TypeInfo ppc_cpu_type_info
= {
10676 .name
= TYPE_POWERPC_CPU
,
10677 .parent
= TYPE_CPU
,
10678 .instance_size
= sizeof(PowerPCCPU
),
10679 .instance_init
= ppc_cpu_instance_init
,
10680 .instance_finalize
= ppc_cpu_instance_finalize
,
10682 .class_size
= sizeof(PowerPCCPUClass
),
10683 .class_init
= ppc_cpu_class_init
,
10686 static const TypeInfo ppc_vhyp_type_info
= {
10687 .name
= TYPE_PPC_VIRTUAL_HYPERVISOR
,
10688 .parent
= TYPE_INTERFACE
,
10689 .class_size
= sizeof(PPCVirtualHypervisorClass
),
10692 static void ppc_cpu_register_types(void)
10694 type_register_static(&ppc_cpu_type_info
);
10695 type_register_static(&ppc_vhyp_type_info
);
10698 type_init(ppc_cpu_register_types
)