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
);
290 static void spr_write_purr(DisasContext
*ctx
, int sprn
, int gprn
)
292 gen_helper_store_purr(cpu_env
, cpu_gpr
[gprn
]);
296 static void spr_read_hdecr(DisasContext
*ctx
, int gprn
, int sprn
)
298 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
301 gen_helper_load_hdecr(cpu_gpr
[gprn
], cpu_env
);
302 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
304 gen_stop_exception(ctx
);
308 static void spr_write_hdecr(DisasContext
*ctx
, int sprn
, int gprn
)
310 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
313 gen_helper_store_hdecr(cpu_env
, cpu_gpr
[gprn
]);
314 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
316 gen_stop_exception(ctx
);
320 static void spr_read_vtb(DisasContext
*ctx
, int gprn
, int sprn
)
322 gen_helper_load_vtb(cpu_gpr
[gprn
], cpu_env
);
325 static void spr_write_vtb(DisasContext
*ctx
, int sprn
, int gprn
)
327 gen_helper_store_vtb(cpu_env
, cpu_gpr
[gprn
]);
330 static void spr_write_tbu40(DisasContext
*ctx
, int sprn
, int gprn
)
332 gen_helper_store_tbu40(cpu_env
, cpu_gpr
[gprn
]);
338 #if !defined(CONFIG_USER_ONLY)
339 /* IBAT0U...IBAT0U */
340 /* IBAT0L...IBAT7L */
341 static void spr_read_ibat(DisasContext
*ctx
, int gprn
, int sprn
)
343 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
,
344 offsetof(CPUPPCState
,
345 IBAT
[sprn
& 1][(sprn
- SPR_IBAT0U
) / 2]));
348 static void spr_read_ibat_h(DisasContext
*ctx
, int gprn
, int sprn
)
350 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
,
351 offsetof(CPUPPCState
,
352 IBAT
[sprn
& 1][((sprn
- SPR_IBAT4U
) / 2) + 4]));
355 static void spr_write_ibatu(DisasContext
*ctx
, int sprn
, int gprn
)
357 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0U
) / 2);
358 gen_helper_store_ibatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
359 tcg_temp_free_i32(t0
);
362 static void spr_write_ibatu_h(DisasContext
*ctx
, int sprn
, int gprn
)
364 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_IBAT4U
) / 2) + 4);
365 gen_helper_store_ibatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
366 tcg_temp_free_i32(t0
);
369 static void spr_write_ibatl(DisasContext
*ctx
, int sprn
, int gprn
)
371 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0L
) / 2);
372 gen_helper_store_ibatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
373 tcg_temp_free_i32(t0
);
376 static void spr_write_ibatl_h(DisasContext
*ctx
, int sprn
, int gprn
)
378 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_IBAT4L
) / 2) + 4);
379 gen_helper_store_ibatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
380 tcg_temp_free_i32(t0
);
383 /* DBAT0U...DBAT7U */
384 /* DBAT0L...DBAT7L */
385 static void spr_read_dbat(DisasContext
*ctx
, int gprn
, int sprn
)
387 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
,
388 offsetof(CPUPPCState
,
389 DBAT
[sprn
& 1][(sprn
- SPR_DBAT0U
) / 2]));
392 static void spr_read_dbat_h(DisasContext
*ctx
, int gprn
, int sprn
)
394 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
,
395 offsetof(CPUPPCState
,
396 DBAT
[sprn
& 1][((sprn
- SPR_DBAT4U
) / 2) + 4]));
399 static void spr_write_dbatu(DisasContext
*ctx
, int sprn
, int gprn
)
401 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_DBAT0U
) / 2);
402 gen_helper_store_dbatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
403 tcg_temp_free_i32(t0
);
406 static void spr_write_dbatu_h(DisasContext
*ctx
, int sprn
, int gprn
)
408 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_DBAT4U
) / 2) + 4);
409 gen_helper_store_dbatu(cpu_env
, t0
, cpu_gpr
[gprn
]);
410 tcg_temp_free_i32(t0
);
413 static void spr_write_dbatl(DisasContext
*ctx
, int sprn
, int gprn
)
415 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_DBAT0L
) / 2);
416 gen_helper_store_dbatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
417 tcg_temp_free_i32(t0
);
420 static void spr_write_dbatl_h(DisasContext
*ctx
, int sprn
, int gprn
)
422 TCGv_i32 t0
= tcg_const_i32(((sprn
- SPR_DBAT4L
) / 2) + 4);
423 gen_helper_store_dbatl(cpu_env
, t0
, cpu_gpr
[gprn
]);
424 tcg_temp_free_i32(t0
);
428 static void spr_write_sdr1(DisasContext
*ctx
, int sprn
, int gprn
)
430 gen_helper_store_sdr1(cpu_env
, cpu_gpr
[gprn
]);
433 #if defined(TARGET_PPC64)
434 /* 64 bits PowerPC specific SPRs */
436 static void spr_write_pidr(DisasContext
*ctx
, int sprn
, int gprn
)
438 gen_helper_store_pidr(cpu_env
, cpu_gpr
[gprn
]);
441 static void spr_write_lpidr(DisasContext
*ctx
, int sprn
, int gprn
)
443 gen_helper_store_lpidr(cpu_env
, cpu_gpr
[gprn
]);
446 static void spr_read_hior(DisasContext
*ctx
, int gprn
, int sprn
)
448 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
, offsetof(CPUPPCState
, excp_prefix
));
451 static void spr_write_hior(DisasContext
*ctx
, int sprn
, int gprn
)
453 TCGv t0
= tcg_temp_new();
454 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], 0x3FFFFF00000ULL
);
455 tcg_gen_st_tl(t0
, cpu_env
, offsetof(CPUPPCState
, excp_prefix
));
458 static void spr_write_ptcr(DisasContext
*ctx
, int sprn
, int gprn
)
460 gen_helper_store_ptcr(cpu_env
, cpu_gpr
[gprn
]);
463 static void spr_write_pcr(DisasContext
*ctx
, int sprn
, int gprn
)
465 gen_helper_store_pcr(cpu_env
, cpu_gpr
[gprn
]);
470 /* PowerPC 601 specific registers */
472 static void spr_read_601_rtcl(DisasContext
*ctx
, int gprn
, int sprn
)
474 gen_helper_load_601_rtcl(cpu_gpr
[gprn
], cpu_env
);
477 static void spr_read_601_rtcu(DisasContext
*ctx
, int gprn
, int sprn
)
479 gen_helper_load_601_rtcu(cpu_gpr
[gprn
], cpu_env
);
482 #if !defined(CONFIG_USER_ONLY)
483 static void spr_write_601_rtcu(DisasContext
*ctx
, int sprn
, int gprn
)
485 gen_helper_store_601_rtcu(cpu_env
, cpu_gpr
[gprn
]);
488 static void spr_write_601_rtcl(DisasContext
*ctx
, int sprn
, int gprn
)
490 gen_helper_store_601_rtcl(cpu_env
, cpu_gpr
[gprn
]);
493 static void spr_write_hid0_601(DisasContext
*ctx
, int sprn
, int gprn
)
495 gen_helper_store_hid0_601(cpu_env
, cpu_gpr
[gprn
]);
496 /* Must stop the translation as endianness may have changed */
497 gen_stop_exception(ctx
);
502 #if !defined(CONFIG_USER_ONLY)
503 static void spr_read_601_ubat(DisasContext
*ctx
, int gprn
, int sprn
)
505 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
,
506 offsetof(CPUPPCState
,
507 IBAT
[sprn
& 1][(sprn
- SPR_IBAT0U
) / 2]));
510 static void spr_write_601_ubatu(DisasContext
*ctx
, int sprn
, int gprn
)
512 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0U
) / 2);
513 gen_helper_store_601_batl(cpu_env
, t0
, cpu_gpr
[gprn
]);
514 tcg_temp_free_i32(t0
);
517 static void spr_write_601_ubatl(DisasContext
*ctx
, int sprn
, int gprn
)
519 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0U
) / 2);
520 gen_helper_store_601_batu(cpu_env
, t0
, cpu_gpr
[gprn
]);
521 tcg_temp_free_i32(t0
);
525 /* PowerPC 40x specific registers */
526 #if !defined(CONFIG_USER_ONLY)
527 static void spr_read_40x_pit(DisasContext
*ctx
, int gprn
, int sprn
)
529 gen_helper_load_40x_pit(cpu_gpr
[gprn
], cpu_env
);
532 static void spr_write_40x_pit(DisasContext
*ctx
, int sprn
, int gprn
)
534 gen_helper_store_40x_pit(cpu_env
, cpu_gpr
[gprn
]);
537 static void spr_write_40x_dbcr0(DisasContext
*ctx
, int sprn
, int gprn
)
539 gen_store_spr(sprn
, cpu_gpr
[gprn
]);
540 gen_helper_store_40x_dbcr0(cpu_env
, cpu_gpr
[gprn
]);
541 /* We must stop translation as we may have rebooted */
542 gen_stop_exception(ctx
);
545 static void spr_write_40x_sler(DisasContext
*ctx
, int sprn
, int gprn
)
547 gen_helper_store_40x_sler(cpu_env
, cpu_gpr
[gprn
]);
550 static void spr_write_booke_tcr(DisasContext
*ctx
, int sprn
, int gprn
)
552 gen_helper_store_booke_tcr(cpu_env
, cpu_gpr
[gprn
]);
555 static void spr_write_booke_tsr(DisasContext
*ctx
, int sprn
, int gprn
)
557 gen_helper_store_booke_tsr(cpu_env
, cpu_gpr
[gprn
]);
561 /* PowerPC 403 specific registers */
562 /* PBL1 / PBU1 / PBL2 / PBU2 */
563 #if !defined(CONFIG_USER_ONLY)
564 static void spr_read_403_pbr(DisasContext
*ctx
, int gprn
, int sprn
)
566 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
,
567 offsetof(CPUPPCState
, pb
[sprn
- SPR_403_PBL1
]));
570 static void spr_write_403_pbr(DisasContext
*ctx
, int sprn
, int gprn
)
572 TCGv_i32 t0
= tcg_const_i32(sprn
- SPR_403_PBL1
);
573 gen_helper_store_403_pbr(cpu_env
, t0
, cpu_gpr
[gprn
]);
574 tcg_temp_free_i32(t0
);
577 static void spr_write_pir(DisasContext
*ctx
, int sprn
, int gprn
)
579 TCGv t0
= tcg_temp_new();
580 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], 0xF);
581 gen_store_spr(SPR_PIR
, t0
);
586 /* SPE specific registers */
587 static void spr_read_spefscr(DisasContext
*ctx
, int gprn
, int sprn
)
589 TCGv_i32 t0
= tcg_temp_new_i32();
590 tcg_gen_ld_i32(t0
, cpu_env
, offsetof(CPUPPCState
, spe_fscr
));
591 tcg_gen_extu_i32_tl(cpu_gpr
[gprn
], t0
);
592 tcg_temp_free_i32(t0
);
595 static void spr_write_spefscr(DisasContext
*ctx
, int sprn
, int gprn
)
597 TCGv_i32 t0
= tcg_temp_new_i32();
598 tcg_gen_trunc_tl_i32(t0
, cpu_gpr
[gprn
]);
599 tcg_gen_st_i32(t0
, cpu_env
, offsetof(CPUPPCState
, spe_fscr
));
600 tcg_temp_free_i32(t0
);
603 #if !defined(CONFIG_USER_ONLY)
604 /* Callback used to write the exception vector base */
605 static void spr_write_excp_prefix(DisasContext
*ctx
, int sprn
, int gprn
)
607 TCGv t0
= tcg_temp_new();
608 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUPPCState
, ivpr_mask
));
609 tcg_gen_and_tl(t0
, t0
, cpu_gpr
[gprn
]);
610 tcg_gen_st_tl(t0
, cpu_env
, offsetof(CPUPPCState
, excp_prefix
));
611 gen_store_spr(sprn
, t0
);
615 static void spr_write_excp_vector(DisasContext
*ctx
, int sprn
, int gprn
)
619 if (sprn
>= SPR_BOOKE_IVOR0
&& sprn
<= SPR_BOOKE_IVOR15
) {
620 sprn_offs
= sprn
- SPR_BOOKE_IVOR0
;
621 } else if (sprn
>= SPR_BOOKE_IVOR32
&& sprn
<= SPR_BOOKE_IVOR37
) {
622 sprn_offs
= sprn
- SPR_BOOKE_IVOR32
+ 32;
623 } else if (sprn
>= SPR_BOOKE_IVOR38
&& sprn
<= SPR_BOOKE_IVOR42
) {
624 sprn_offs
= sprn
- SPR_BOOKE_IVOR38
+ 38;
626 printf("Trying to write an unknown exception vector %d %03x\n",
628 gen_inval_exception(ctx
, POWERPC_EXCP_PRIV_REG
);
632 TCGv t0
= tcg_temp_new();
633 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUPPCState
, ivor_mask
));
634 tcg_gen_and_tl(t0
, t0
, cpu_gpr
[gprn
]);
635 tcg_gen_st_tl(t0
, cpu_env
, offsetof(CPUPPCState
, excp_vectors
[sprn_offs
]));
636 gen_store_spr(sprn
, t0
);
641 static inline void vscr_init(CPUPPCState
*env
, uint32_t val
)
643 /* Altivec always uses round-to-nearest */
644 set_float_rounding_mode(float_round_nearest_even
, &env
->vec_status
);
645 helper_mtvscr(env
, val
);
648 #ifdef CONFIG_USER_ONLY
649 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
650 oea_read, oea_write, one_reg_id, initial_value) \
651 _spr_register(env, num, name, uea_read, uea_write, initial_value)
652 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
653 oea_read, oea_write, hea_read, hea_write, \
654 one_reg_id, initial_value) \
655 _spr_register(env, num, name, uea_read, uea_write, initial_value)
657 #if !defined(CONFIG_KVM)
658 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
659 oea_read, oea_write, one_reg_id, initial_value) \
660 _spr_register(env, num, name, uea_read, uea_write, \
661 oea_read, oea_write, oea_read, oea_write, initial_value)
662 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
663 oea_read, oea_write, hea_read, hea_write, \
664 one_reg_id, initial_value) \
665 _spr_register(env, num, name, uea_read, uea_write, \
666 oea_read, oea_write, hea_read, hea_write, initial_value)
668 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
669 oea_read, oea_write, one_reg_id, initial_value) \
670 _spr_register(env, num, name, uea_read, uea_write, \
671 oea_read, oea_write, oea_read, oea_write, \
672 one_reg_id, initial_value)
673 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
674 oea_read, oea_write, hea_read, hea_write, \
675 one_reg_id, initial_value) \
676 _spr_register(env, num, name, uea_read, uea_write, \
677 oea_read, oea_write, hea_read, hea_write, \
678 one_reg_id, initial_value)
682 #define spr_register(env, num, name, uea_read, uea_write, \
683 oea_read, oea_write, initial_value) \
684 spr_register_kvm(env, num, name, uea_read, uea_write, \
685 oea_read, oea_write, 0, initial_value)
687 #define spr_register_hv(env, num, name, uea_read, uea_write, \
688 oea_read, oea_write, hea_read, hea_write, \
690 spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
691 oea_read, oea_write, hea_read, hea_write, \
694 static inline void _spr_register(CPUPPCState
*env
, int num
,
696 void (*uea_read
)(DisasContext
*ctx
,
698 void (*uea_write
)(DisasContext
*ctx
,
700 #if !defined(CONFIG_USER_ONLY)
702 void (*oea_read
)(DisasContext
*ctx
,
704 void (*oea_write
)(DisasContext
*ctx
,
706 void (*hea_read
)(DisasContext
*opaque
,
708 void (*hea_write
)(DisasContext
*opaque
,
711 #if defined(CONFIG_KVM)
714 target_ulong initial_value
)
718 spr
= &env
->spr_cb
[num
];
719 if (spr
->name
!= NULL
|| env
->spr
[num
] != 0x00000000 ||
720 #if !defined(CONFIG_USER_ONLY)
721 spr
->oea_read
!= NULL
|| spr
->oea_write
!= NULL
||
723 spr
->uea_read
!= NULL
|| spr
->uea_write
!= NULL
) {
724 printf("Error: Trying to register SPR %d (%03x) twice !\n", num
, num
);
727 #if defined(PPC_DEBUG_SPR)
728 printf("*** register spr %d (%03x) %s val " TARGET_FMT_lx
"\n", num
, num
,
729 name
, initial_value
);
732 spr
->uea_read
= uea_read
;
733 spr
->uea_write
= uea_write
;
734 #if !defined(CONFIG_USER_ONLY)
735 spr
->oea_read
= oea_read
;
736 spr
->oea_write
= oea_write
;
737 spr
->hea_read
= hea_read
;
738 spr
->hea_write
= hea_write
;
740 #if defined(CONFIG_KVM)
741 spr
->one_reg_id
= one_reg_id
,
743 env
->spr
[num
] = spr
->default_value
= initial_value
;
746 /* Generic PowerPC SPRs */
747 static void gen_spr_generic(CPUPPCState
*env
)
749 /* Integer processing */
750 spr_register(env
, SPR_XER
, "XER",
751 &spr_read_xer
, &spr_write_xer
,
752 &spr_read_xer
, &spr_write_xer
,
755 spr_register(env
, SPR_LR
, "LR",
756 &spr_read_lr
, &spr_write_lr
,
757 &spr_read_lr
, &spr_write_lr
,
759 spr_register(env
, SPR_CTR
, "CTR",
760 &spr_read_ctr
, &spr_write_ctr
,
761 &spr_read_ctr
, &spr_write_ctr
,
763 /* Interrupt processing */
764 spr_register(env
, SPR_SRR0
, "SRR0",
765 SPR_NOACCESS
, SPR_NOACCESS
,
766 &spr_read_generic
, &spr_write_generic
,
768 spr_register(env
, SPR_SRR1
, "SRR1",
769 SPR_NOACCESS
, SPR_NOACCESS
,
770 &spr_read_generic
, &spr_write_generic
,
772 /* Processor control */
773 spr_register(env
, SPR_SPRG0
, "SPRG0",
774 SPR_NOACCESS
, SPR_NOACCESS
,
775 &spr_read_generic
, &spr_write_generic
,
777 spr_register(env
, SPR_SPRG1
, "SPRG1",
778 SPR_NOACCESS
, SPR_NOACCESS
,
779 &spr_read_generic
, &spr_write_generic
,
781 spr_register(env
, SPR_SPRG2
, "SPRG2",
782 SPR_NOACCESS
, SPR_NOACCESS
,
783 &spr_read_generic
, &spr_write_generic
,
785 spr_register(env
, SPR_SPRG3
, "SPRG3",
786 SPR_NOACCESS
, SPR_NOACCESS
,
787 &spr_read_generic
, &spr_write_generic
,
791 /* SPR common to all non-embedded PowerPC, including 601 */
792 static void gen_spr_ne_601(CPUPPCState
*env
)
794 /* Exception processing */
795 spr_register_kvm(env
, SPR_DSISR
, "DSISR",
796 SPR_NOACCESS
, SPR_NOACCESS
,
797 &spr_read_generic
, &spr_write_generic
,
798 KVM_REG_PPC_DSISR
, 0x00000000);
799 spr_register_kvm(env
, SPR_DAR
, "DAR",
800 SPR_NOACCESS
, SPR_NOACCESS
,
801 &spr_read_generic
, &spr_write_generic
,
802 KVM_REG_PPC_DAR
, 0x00000000);
804 spr_register(env
, SPR_DECR
, "DECR",
805 SPR_NOACCESS
, SPR_NOACCESS
,
806 &spr_read_decr
, &spr_write_decr
,
810 /* Storage Description Register 1 */
811 static void gen_spr_sdr1(CPUPPCState
*env
)
813 #ifndef CONFIG_USER_ONLY
814 if (env
->has_hv_mode
) {
816 * SDR1 is a hypervisor resource on CPUs which have a
819 spr_register_hv(env
, SPR_SDR1
, "SDR1",
820 SPR_NOACCESS
, SPR_NOACCESS
,
821 SPR_NOACCESS
, SPR_NOACCESS
,
822 &spr_read_generic
, &spr_write_sdr1
,
825 spr_register(env
, SPR_SDR1
, "SDR1",
826 SPR_NOACCESS
, SPR_NOACCESS
,
827 &spr_read_generic
, &spr_write_sdr1
,
834 static void gen_low_BATs(CPUPPCState
*env
)
836 #if !defined(CONFIG_USER_ONLY)
837 spr_register(env
, SPR_IBAT0U
, "IBAT0U",
838 SPR_NOACCESS
, SPR_NOACCESS
,
839 &spr_read_ibat
, &spr_write_ibatu
,
841 spr_register(env
, SPR_IBAT0L
, "IBAT0L",
842 SPR_NOACCESS
, SPR_NOACCESS
,
843 &spr_read_ibat
, &spr_write_ibatl
,
845 spr_register(env
, SPR_IBAT1U
, "IBAT1U",
846 SPR_NOACCESS
, SPR_NOACCESS
,
847 &spr_read_ibat
, &spr_write_ibatu
,
849 spr_register(env
, SPR_IBAT1L
, "IBAT1L",
850 SPR_NOACCESS
, SPR_NOACCESS
,
851 &spr_read_ibat
, &spr_write_ibatl
,
853 spr_register(env
, SPR_IBAT2U
, "IBAT2U",
854 SPR_NOACCESS
, SPR_NOACCESS
,
855 &spr_read_ibat
, &spr_write_ibatu
,
857 spr_register(env
, SPR_IBAT2L
, "IBAT2L",
858 SPR_NOACCESS
, SPR_NOACCESS
,
859 &spr_read_ibat
, &spr_write_ibatl
,
861 spr_register(env
, SPR_IBAT3U
, "IBAT3U",
862 SPR_NOACCESS
, SPR_NOACCESS
,
863 &spr_read_ibat
, &spr_write_ibatu
,
865 spr_register(env
, SPR_IBAT3L
, "IBAT3L",
866 SPR_NOACCESS
, SPR_NOACCESS
,
867 &spr_read_ibat
, &spr_write_ibatl
,
869 spr_register(env
, SPR_DBAT0U
, "DBAT0U",
870 SPR_NOACCESS
, SPR_NOACCESS
,
871 &spr_read_dbat
, &spr_write_dbatu
,
873 spr_register(env
, SPR_DBAT0L
, "DBAT0L",
874 SPR_NOACCESS
, SPR_NOACCESS
,
875 &spr_read_dbat
, &spr_write_dbatl
,
877 spr_register(env
, SPR_DBAT1U
, "DBAT1U",
878 SPR_NOACCESS
, SPR_NOACCESS
,
879 &spr_read_dbat
, &spr_write_dbatu
,
881 spr_register(env
, SPR_DBAT1L
, "DBAT1L",
882 SPR_NOACCESS
, SPR_NOACCESS
,
883 &spr_read_dbat
, &spr_write_dbatl
,
885 spr_register(env
, SPR_DBAT2U
, "DBAT2U",
886 SPR_NOACCESS
, SPR_NOACCESS
,
887 &spr_read_dbat
, &spr_write_dbatu
,
889 spr_register(env
, SPR_DBAT2L
, "DBAT2L",
890 SPR_NOACCESS
, SPR_NOACCESS
,
891 &spr_read_dbat
, &spr_write_dbatl
,
893 spr_register(env
, SPR_DBAT3U
, "DBAT3U",
894 SPR_NOACCESS
, SPR_NOACCESS
,
895 &spr_read_dbat
, &spr_write_dbatu
,
897 spr_register(env
, SPR_DBAT3L
, "DBAT3L",
898 SPR_NOACCESS
, SPR_NOACCESS
,
899 &spr_read_dbat
, &spr_write_dbatl
,
906 static void gen_high_BATs(CPUPPCState
*env
)
908 #if !defined(CONFIG_USER_ONLY)
909 spr_register(env
, SPR_IBAT4U
, "IBAT4U",
910 SPR_NOACCESS
, SPR_NOACCESS
,
911 &spr_read_ibat_h
, &spr_write_ibatu_h
,
913 spr_register(env
, SPR_IBAT4L
, "IBAT4L",
914 SPR_NOACCESS
, SPR_NOACCESS
,
915 &spr_read_ibat_h
, &spr_write_ibatl_h
,
917 spr_register(env
, SPR_IBAT5U
, "IBAT5U",
918 SPR_NOACCESS
, SPR_NOACCESS
,
919 &spr_read_ibat_h
, &spr_write_ibatu_h
,
921 spr_register(env
, SPR_IBAT5L
, "IBAT5L",
922 SPR_NOACCESS
, SPR_NOACCESS
,
923 &spr_read_ibat_h
, &spr_write_ibatl_h
,
925 spr_register(env
, SPR_IBAT6U
, "IBAT6U",
926 SPR_NOACCESS
, SPR_NOACCESS
,
927 &spr_read_ibat_h
, &spr_write_ibatu_h
,
929 spr_register(env
, SPR_IBAT6L
, "IBAT6L",
930 SPR_NOACCESS
, SPR_NOACCESS
,
931 &spr_read_ibat_h
, &spr_write_ibatl_h
,
933 spr_register(env
, SPR_IBAT7U
, "IBAT7U",
934 SPR_NOACCESS
, SPR_NOACCESS
,
935 &spr_read_ibat_h
, &spr_write_ibatu_h
,
937 spr_register(env
, SPR_IBAT7L
, "IBAT7L",
938 SPR_NOACCESS
, SPR_NOACCESS
,
939 &spr_read_ibat_h
, &spr_write_ibatl_h
,
941 spr_register(env
, SPR_DBAT4U
, "DBAT4U",
942 SPR_NOACCESS
, SPR_NOACCESS
,
943 &spr_read_dbat_h
, &spr_write_dbatu_h
,
945 spr_register(env
, SPR_DBAT4L
, "DBAT4L",
946 SPR_NOACCESS
, SPR_NOACCESS
,
947 &spr_read_dbat_h
, &spr_write_dbatl_h
,
949 spr_register(env
, SPR_DBAT5U
, "DBAT5U",
950 SPR_NOACCESS
, SPR_NOACCESS
,
951 &spr_read_dbat_h
, &spr_write_dbatu_h
,
953 spr_register(env
, SPR_DBAT5L
, "DBAT5L",
954 SPR_NOACCESS
, SPR_NOACCESS
,
955 &spr_read_dbat_h
, &spr_write_dbatl_h
,
957 spr_register(env
, SPR_DBAT6U
, "DBAT6U",
958 SPR_NOACCESS
, SPR_NOACCESS
,
959 &spr_read_dbat_h
, &spr_write_dbatu_h
,
961 spr_register(env
, SPR_DBAT6L
, "DBAT6L",
962 SPR_NOACCESS
, SPR_NOACCESS
,
963 &spr_read_dbat_h
, &spr_write_dbatl_h
,
965 spr_register(env
, SPR_DBAT7U
, "DBAT7U",
966 SPR_NOACCESS
, SPR_NOACCESS
,
967 &spr_read_dbat_h
, &spr_write_dbatu_h
,
969 spr_register(env
, SPR_DBAT7L
, "DBAT7L",
970 SPR_NOACCESS
, SPR_NOACCESS
,
971 &spr_read_dbat_h
, &spr_write_dbatl_h
,
977 /* Generic PowerPC time base */
978 static void gen_tbl(CPUPPCState
*env
)
980 spr_register(env
, SPR_VTBL
, "TBL",
981 &spr_read_tbl
, SPR_NOACCESS
,
982 &spr_read_tbl
, SPR_NOACCESS
,
984 spr_register(env
, SPR_TBL
, "TBL",
985 &spr_read_tbl
, SPR_NOACCESS
,
986 &spr_read_tbl
, &spr_write_tbl
,
988 spr_register(env
, SPR_VTBU
, "TBU",
989 &spr_read_tbu
, SPR_NOACCESS
,
990 &spr_read_tbu
, SPR_NOACCESS
,
992 spr_register(env
, SPR_TBU
, "TBU",
993 &spr_read_tbu
, SPR_NOACCESS
,
994 &spr_read_tbu
, &spr_write_tbu
,
998 /* Softare table search registers */
999 static void gen_6xx_7xx_soft_tlb(CPUPPCState
*env
, int nb_tlbs
, int nb_ways
)
1001 #if !defined(CONFIG_USER_ONLY)
1002 env
->nb_tlb
= nb_tlbs
;
1003 env
->nb_ways
= nb_ways
;
1005 env
->tlb_type
= TLB_6XX
;
1006 spr_register(env
, SPR_DMISS
, "DMISS",
1007 SPR_NOACCESS
, SPR_NOACCESS
,
1008 &spr_read_generic
, SPR_NOACCESS
,
1010 spr_register(env
, SPR_DCMP
, "DCMP",
1011 SPR_NOACCESS
, SPR_NOACCESS
,
1012 &spr_read_generic
, SPR_NOACCESS
,
1014 spr_register(env
, SPR_HASH1
, "HASH1",
1015 SPR_NOACCESS
, SPR_NOACCESS
,
1016 &spr_read_generic
, SPR_NOACCESS
,
1018 spr_register(env
, SPR_HASH2
, "HASH2",
1019 SPR_NOACCESS
, SPR_NOACCESS
,
1020 &spr_read_generic
, SPR_NOACCESS
,
1022 spr_register(env
, SPR_IMISS
, "IMISS",
1023 SPR_NOACCESS
, SPR_NOACCESS
,
1024 &spr_read_generic
, SPR_NOACCESS
,
1026 spr_register(env
, SPR_ICMP
, "ICMP",
1027 SPR_NOACCESS
, SPR_NOACCESS
,
1028 &spr_read_generic
, SPR_NOACCESS
,
1030 spr_register(env
, SPR_RPA
, "RPA",
1031 SPR_NOACCESS
, SPR_NOACCESS
,
1032 &spr_read_generic
, &spr_write_generic
,
1037 /* SPR common to MPC755 and G2 */
1038 static void gen_spr_G2_755(CPUPPCState
*env
)
1041 spr_register(env
, SPR_SPRG4
, "SPRG4",
1042 SPR_NOACCESS
, SPR_NOACCESS
,
1043 &spr_read_generic
, &spr_write_generic
,
1045 spr_register(env
, SPR_SPRG5
, "SPRG5",
1046 SPR_NOACCESS
, SPR_NOACCESS
,
1047 &spr_read_generic
, &spr_write_generic
,
1049 spr_register(env
, SPR_SPRG6
, "SPRG6",
1050 SPR_NOACCESS
, SPR_NOACCESS
,
1051 &spr_read_generic
, &spr_write_generic
,
1053 spr_register(env
, SPR_SPRG7
, "SPRG7",
1054 SPR_NOACCESS
, SPR_NOACCESS
,
1055 &spr_read_generic
, &spr_write_generic
,
1059 /* SPR common to all 7xx PowerPC implementations */
1060 static void gen_spr_7xx(CPUPPCState
*env
)
1063 /* XXX : not implemented */
1064 spr_register_kvm(env
, SPR_DABR
, "DABR",
1065 SPR_NOACCESS
, SPR_NOACCESS
,
1066 &spr_read_generic
, &spr_write_generic
,
1067 KVM_REG_PPC_DABR
, 0x00000000);
1068 /* XXX : not implemented */
1069 spr_register(env
, SPR_IABR
, "IABR",
1070 SPR_NOACCESS
, SPR_NOACCESS
,
1071 &spr_read_generic
, &spr_write_generic
,
1073 /* Cache management */
1074 /* XXX : not implemented */
1075 spr_register(env
, SPR_ICTC
, "ICTC",
1076 SPR_NOACCESS
, SPR_NOACCESS
,
1077 &spr_read_generic
, &spr_write_generic
,
1079 /* Performance monitors */
1080 /* XXX : not implemented */
1081 spr_register(env
, SPR_7XX_MMCR0
, "MMCR0",
1082 SPR_NOACCESS
, SPR_NOACCESS
,
1083 &spr_read_generic
, &spr_write_generic
,
1085 /* XXX : not implemented */
1086 spr_register(env
, SPR_7XX_MMCR1
, "MMCR1",
1087 SPR_NOACCESS
, SPR_NOACCESS
,
1088 &spr_read_generic
, &spr_write_generic
,
1090 /* XXX : not implemented */
1091 spr_register(env
, SPR_7XX_PMC1
, "PMC1",
1092 SPR_NOACCESS
, SPR_NOACCESS
,
1093 &spr_read_generic
, &spr_write_generic
,
1095 /* XXX : not implemented */
1096 spr_register(env
, SPR_7XX_PMC2
, "PMC2",
1097 SPR_NOACCESS
, SPR_NOACCESS
,
1098 &spr_read_generic
, &spr_write_generic
,
1100 /* XXX : not implemented */
1101 spr_register(env
, SPR_7XX_PMC3
, "PMC3",
1102 SPR_NOACCESS
, SPR_NOACCESS
,
1103 &spr_read_generic
, &spr_write_generic
,
1105 /* XXX : not implemented */
1106 spr_register(env
, SPR_7XX_PMC4
, "PMC4",
1107 SPR_NOACCESS
, SPR_NOACCESS
,
1108 &spr_read_generic
, &spr_write_generic
,
1110 /* XXX : not implemented */
1111 spr_register(env
, SPR_7XX_SIAR
, "SIAR",
1112 SPR_NOACCESS
, SPR_NOACCESS
,
1113 &spr_read_generic
, SPR_NOACCESS
,
1115 /* XXX : not implemented */
1116 spr_register(env
, SPR_7XX_UMMCR0
, "UMMCR0",
1117 &spr_read_ureg
, SPR_NOACCESS
,
1118 &spr_read_ureg
, SPR_NOACCESS
,
1120 /* XXX : not implemented */
1121 spr_register(env
, SPR_7XX_UMMCR1
, "UMMCR1",
1122 &spr_read_ureg
, SPR_NOACCESS
,
1123 &spr_read_ureg
, SPR_NOACCESS
,
1125 /* XXX : not implemented */
1126 spr_register(env
, SPR_7XX_UPMC1
, "UPMC1",
1127 &spr_read_ureg
, SPR_NOACCESS
,
1128 &spr_read_ureg
, SPR_NOACCESS
,
1130 /* XXX : not implemented */
1131 spr_register(env
, SPR_7XX_UPMC2
, "UPMC2",
1132 &spr_read_ureg
, SPR_NOACCESS
,
1133 &spr_read_ureg
, SPR_NOACCESS
,
1135 /* XXX : not implemented */
1136 spr_register(env
, SPR_7XX_UPMC3
, "UPMC3",
1137 &spr_read_ureg
, SPR_NOACCESS
,
1138 &spr_read_ureg
, SPR_NOACCESS
,
1140 /* XXX : not implemented */
1141 spr_register(env
, SPR_7XX_UPMC4
, "UPMC4",
1142 &spr_read_ureg
, SPR_NOACCESS
,
1143 &spr_read_ureg
, SPR_NOACCESS
,
1145 /* XXX : not implemented */
1146 spr_register(env
, SPR_7XX_USIAR
, "USIAR",
1147 &spr_read_ureg
, SPR_NOACCESS
,
1148 &spr_read_ureg
, SPR_NOACCESS
,
1150 /* External access control */
1151 /* XXX : not implemented */
1152 spr_register(env
, SPR_EAR
, "EAR",
1153 SPR_NOACCESS
, SPR_NOACCESS
,
1154 &spr_read_generic
, &spr_write_generic
,
1159 #ifndef CONFIG_USER_ONLY
1160 static void spr_write_amr(DisasContext
*ctx
, int sprn
, int gprn
)
1162 TCGv t0
= tcg_temp_new();
1163 TCGv t1
= tcg_temp_new();
1164 TCGv t2
= tcg_temp_new();
1167 * Note, the HV=1 PR=0 case is handled earlier by simply using
1168 * spr_write_generic for HV mode in the SPR table
1171 /* Build insertion mask into t1 based on context */
1173 gen_load_spr(t1
, SPR_UAMOR
);
1175 gen_load_spr(t1
, SPR_AMOR
);
1178 /* Mask new bits into t2 */
1179 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1181 /* Load AMR and clear new bits in t0 */
1182 gen_load_spr(t0
, SPR_AMR
);
1183 tcg_gen_andc_tl(t0
, t0
, t1
);
1185 /* Or'in new bits and write it out */
1186 tcg_gen_or_tl(t0
, t0
, t2
);
1187 gen_store_spr(SPR_AMR
, t0
);
1188 spr_store_dump_spr(SPR_AMR
);
1195 static void spr_write_uamor(DisasContext
*ctx
, int sprn
, int gprn
)
1197 TCGv t0
= tcg_temp_new();
1198 TCGv t1
= tcg_temp_new();
1199 TCGv t2
= tcg_temp_new();
1202 * Note, the HV=1 case is handled earlier by simply using
1203 * spr_write_generic for HV mode in the SPR table
1206 /* Build insertion mask into t1 based on context */
1207 gen_load_spr(t1
, SPR_AMOR
);
1209 /* Mask new bits into t2 */
1210 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1212 /* Load AMR and clear new bits in t0 */
1213 gen_load_spr(t0
, SPR_UAMOR
);
1214 tcg_gen_andc_tl(t0
, t0
, t1
);
1216 /* Or'in new bits and write it out */
1217 tcg_gen_or_tl(t0
, t0
, t2
);
1218 gen_store_spr(SPR_UAMOR
, t0
);
1219 spr_store_dump_spr(SPR_UAMOR
);
1226 static void spr_write_iamr(DisasContext
*ctx
, int sprn
, int gprn
)
1228 TCGv t0
= tcg_temp_new();
1229 TCGv t1
= tcg_temp_new();
1230 TCGv t2
= tcg_temp_new();
1233 * Note, the HV=1 case is handled earlier by simply using
1234 * spr_write_generic for HV mode in the SPR table
1237 /* Build insertion mask into t1 based on context */
1238 gen_load_spr(t1
, SPR_AMOR
);
1240 /* Mask new bits into t2 */
1241 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1243 /* Load AMR and clear new bits in t0 */
1244 gen_load_spr(t0
, SPR_IAMR
);
1245 tcg_gen_andc_tl(t0
, t0
, t1
);
1247 /* Or'in new bits and write it out */
1248 tcg_gen_or_tl(t0
, t0
, t2
);
1249 gen_store_spr(SPR_IAMR
, t0
);
1250 spr_store_dump_spr(SPR_IAMR
);
1256 #endif /* CONFIG_USER_ONLY */
1258 static void gen_spr_amr(CPUPPCState
*env
)
1260 #ifndef CONFIG_USER_ONLY
1262 * Virtual Page Class Key protection
1264 * The AMR is accessible either via SPR 13 or SPR 29. 13 is
1265 * userspace accessible, 29 is privileged. So we only need to set
1266 * the kvm ONE_REG id on one of them, we use 29
1268 spr_register(env
, SPR_UAMR
, "UAMR",
1269 &spr_read_generic
, &spr_write_amr
,
1270 &spr_read_generic
, &spr_write_amr
,
1272 spr_register_kvm_hv(env
, SPR_AMR
, "AMR",
1273 SPR_NOACCESS
, SPR_NOACCESS
,
1274 &spr_read_generic
, &spr_write_amr
,
1275 &spr_read_generic
, &spr_write_generic
,
1276 KVM_REG_PPC_AMR
, 0);
1277 spr_register_kvm_hv(env
, SPR_UAMOR
, "UAMOR",
1278 SPR_NOACCESS
, SPR_NOACCESS
,
1279 &spr_read_generic
, &spr_write_uamor
,
1280 &spr_read_generic
, &spr_write_generic
,
1281 KVM_REG_PPC_UAMOR
, 0);
1282 spr_register_hv(env
, SPR_AMOR
, "AMOR",
1283 SPR_NOACCESS
, SPR_NOACCESS
,
1284 SPR_NOACCESS
, SPR_NOACCESS
,
1285 &spr_read_generic
, &spr_write_generic
,
1287 #endif /* !CONFIG_USER_ONLY */
1290 static void gen_spr_iamr(CPUPPCState
*env
)
1292 #ifndef CONFIG_USER_ONLY
1293 spr_register_kvm_hv(env
, SPR_IAMR
, "IAMR",
1294 SPR_NOACCESS
, SPR_NOACCESS
,
1295 &spr_read_generic
, &spr_write_iamr
,
1296 &spr_read_generic
, &spr_write_generic
,
1297 KVM_REG_PPC_IAMR
, 0);
1298 #endif /* !CONFIG_USER_ONLY */
1300 #endif /* TARGET_PPC64 */
1302 #ifndef CONFIG_USER_ONLY
1303 static void spr_read_thrm(DisasContext
*ctx
, int gprn
, int sprn
)
1305 gen_helper_fixup_thrm(cpu_env
);
1306 gen_load_spr(cpu_gpr
[gprn
], sprn
);
1307 spr_load_dump_spr(sprn
);
1309 #endif /* !CONFIG_USER_ONLY */
1311 static void gen_spr_thrm(CPUPPCState
*env
)
1313 /* Thermal management */
1314 /* XXX : not implemented */
1315 spr_register(env
, SPR_THRM1
, "THRM1",
1316 SPR_NOACCESS
, SPR_NOACCESS
,
1317 &spr_read_thrm
, &spr_write_generic
,
1319 /* XXX : not implemented */
1320 spr_register(env
, SPR_THRM2
, "THRM2",
1321 SPR_NOACCESS
, SPR_NOACCESS
,
1322 &spr_read_thrm
, &spr_write_generic
,
1324 /* XXX : not implemented */
1325 spr_register(env
, SPR_THRM3
, "THRM3",
1326 SPR_NOACCESS
, SPR_NOACCESS
,
1327 &spr_read_thrm
, &spr_write_generic
,
1331 /* SPR specific to PowerPC 604 implementation */
1332 static void gen_spr_604(CPUPPCState
*env
)
1334 /* Processor identification */
1335 spr_register(env
, SPR_PIR
, "PIR",
1336 SPR_NOACCESS
, SPR_NOACCESS
,
1337 &spr_read_generic
, &spr_write_pir
,
1340 /* XXX : not implemented */
1341 spr_register(env
, SPR_IABR
, "IABR",
1342 SPR_NOACCESS
, SPR_NOACCESS
,
1343 &spr_read_generic
, &spr_write_generic
,
1345 /* XXX : not implemented */
1346 spr_register_kvm(env
, SPR_DABR
, "DABR",
1347 SPR_NOACCESS
, SPR_NOACCESS
,
1348 &spr_read_generic
, &spr_write_generic
,
1349 KVM_REG_PPC_DABR
, 0x00000000);
1350 /* Performance counters */
1351 /* XXX : not implemented */
1352 spr_register(env
, SPR_7XX_MMCR0
, "MMCR0",
1353 SPR_NOACCESS
, SPR_NOACCESS
,
1354 &spr_read_generic
, &spr_write_generic
,
1356 /* XXX : not implemented */
1357 spr_register(env
, SPR_7XX_PMC1
, "PMC1",
1358 SPR_NOACCESS
, SPR_NOACCESS
,
1359 &spr_read_generic
, &spr_write_generic
,
1361 /* XXX : not implemented */
1362 spr_register(env
, SPR_7XX_PMC2
, "PMC2",
1363 SPR_NOACCESS
, SPR_NOACCESS
,
1364 &spr_read_generic
, &spr_write_generic
,
1366 /* XXX : not implemented */
1367 spr_register(env
, SPR_7XX_SIAR
, "SIAR",
1368 SPR_NOACCESS
, SPR_NOACCESS
,
1369 &spr_read_generic
, SPR_NOACCESS
,
1371 /* XXX : not implemented */
1372 spr_register(env
, SPR_SDA
, "SDA",
1373 SPR_NOACCESS
, SPR_NOACCESS
,
1374 &spr_read_generic
, SPR_NOACCESS
,
1376 /* External access control */
1377 /* XXX : not implemented */
1378 spr_register(env
, SPR_EAR
, "EAR",
1379 SPR_NOACCESS
, SPR_NOACCESS
,
1380 &spr_read_generic
, &spr_write_generic
,
1384 /* SPR specific to PowerPC 603 implementation */
1385 static void gen_spr_603(CPUPPCState
*env
)
1387 /* External access control */
1388 /* XXX : not implemented */
1389 spr_register(env
, SPR_EAR
, "EAR",
1390 SPR_NOACCESS
, SPR_NOACCESS
,
1391 &spr_read_generic
, &spr_write_generic
,
1394 /* XXX : not implemented */
1395 spr_register(env
, SPR_IABR
, "IABR",
1396 SPR_NOACCESS
, SPR_NOACCESS
,
1397 &spr_read_generic
, &spr_write_generic
,
1402 /* SPR specific to PowerPC G2 implementation */
1403 static void gen_spr_G2(CPUPPCState
*env
)
1405 /* Memory base address */
1407 /* XXX : not implemented */
1408 spr_register(env
, SPR_MBAR
, "MBAR",
1409 SPR_NOACCESS
, SPR_NOACCESS
,
1410 &spr_read_generic
, &spr_write_generic
,
1412 /* Exception processing */
1413 spr_register(env
, SPR_BOOKE_CSRR0
, "CSRR0",
1414 SPR_NOACCESS
, SPR_NOACCESS
,
1415 &spr_read_generic
, &spr_write_generic
,
1417 spr_register(env
, SPR_BOOKE_CSRR1
, "CSRR1",
1418 SPR_NOACCESS
, SPR_NOACCESS
,
1419 &spr_read_generic
, &spr_write_generic
,
1422 /* XXX : not implemented */
1423 spr_register(env
, SPR_DABR
, "DABR",
1424 SPR_NOACCESS
, SPR_NOACCESS
,
1425 &spr_read_generic
, &spr_write_generic
,
1427 /* XXX : not implemented */
1428 spr_register(env
, SPR_DABR2
, "DABR2",
1429 SPR_NOACCESS
, SPR_NOACCESS
,
1430 &spr_read_generic
, &spr_write_generic
,
1432 /* XXX : not implemented */
1433 spr_register(env
, SPR_IABR
, "IABR",
1434 SPR_NOACCESS
, SPR_NOACCESS
,
1435 &spr_read_generic
, &spr_write_generic
,
1437 /* XXX : not implemented */
1438 spr_register(env
, SPR_IABR2
, "IABR2",
1439 SPR_NOACCESS
, SPR_NOACCESS
,
1440 &spr_read_generic
, &spr_write_generic
,
1442 /* XXX : not implemented */
1443 spr_register(env
, SPR_IBCR
, "IBCR",
1444 SPR_NOACCESS
, SPR_NOACCESS
,
1445 &spr_read_generic
, &spr_write_generic
,
1447 /* XXX : not implemented */
1448 spr_register(env
, SPR_DBCR
, "DBCR",
1449 SPR_NOACCESS
, SPR_NOACCESS
,
1450 &spr_read_generic
, &spr_write_generic
,
1454 /* SPR specific to PowerPC 602 implementation */
1455 static void gen_spr_602(CPUPPCState
*env
)
1458 /* XXX : not implemented */
1459 spr_register(env
, SPR_SER
, "SER",
1460 SPR_NOACCESS
, SPR_NOACCESS
,
1461 &spr_read_generic
, &spr_write_generic
,
1463 /* XXX : not implemented */
1464 spr_register(env
, SPR_SEBR
, "SEBR",
1465 SPR_NOACCESS
, SPR_NOACCESS
,
1466 &spr_read_generic
, &spr_write_generic
,
1468 /* XXX : not implemented */
1469 spr_register(env
, SPR_ESASRR
, "ESASRR",
1470 SPR_NOACCESS
, SPR_NOACCESS
,
1471 &spr_read_generic
, &spr_write_generic
,
1473 /* Floating point status */
1474 /* XXX : not implemented */
1475 spr_register(env
, SPR_SP
, "SP",
1476 SPR_NOACCESS
, SPR_NOACCESS
,
1477 &spr_read_generic
, &spr_write_generic
,
1479 /* XXX : not implemented */
1480 spr_register(env
, SPR_LT
, "LT",
1481 SPR_NOACCESS
, SPR_NOACCESS
,
1482 &spr_read_generic
, &spr_write_generic
,
1484 /* Watchdog timer */
1485 /* XXX : not implemented */
1486 spr_register(env
, SPR_TCR
, "TCR",
1487 SPR_NOACCESS
, SPR_NOACCESS
,
1488 &spr_read_generic
, &spr_write_generic
,
1490 /* Interrupt base */
1491 spr_register(env
, SPR_IBR
, "IBR",
1492 SPR_NOACCESS
, SPR_NOACCESS
,
1493 &spr_read_generic
, &spr_write_generic
,
1495 /* XXX : not implemented */
1496 spr_register(env
, SPR_IABR
, "IABR",
1497 SPR_NOACCESS
, SPR_NOACCESS
,
1498 &spr_read_generic
, &spr_write_generic
,
1502 /* SPR specific to PowerPC 601 implementation */
1503 static void gen_spr_601(CPUPPCState
*env
)
1505 /* Multiplication/division register */
1507 spr_register(env
, SPR_MQ
, "MQ",
1508 &spr_read_generic
, &spr_write_generic
,
1509 &spr_read_generic
, &spr_write_generic
,
1512 spr_register(env
, SPR_601_RTCU
, "RTCU",
1513 SPR_NOACCESS
, SPR_NOACCESS
,
1514 SPR_NOACCESS
, &spr_write_601_rtcu
,
1516 spr_register(env
, SPR_601_VRTCU
, "RTCU",
1517 &spr_read_601_rtcu
, SPR_NOACCESS
,
1518 &spr_read_601_rtcu
, SPR_NOACCESS
,
1520 spr_register(env
, SPR_601_RTCL
, "RTCL",
1521 SPR_NOACCESS
, SPR_NOACCESS
,
1522 SPR_NOACCESS
, &spr_write_601_rtcl
,
1524 spr_register(env
, SPR_601_VRTCL
, "RTCL",
1525 &spr_read_601_rtcl
, SPR_NOACCESS
,
1526 &spr_read_601_rtcl
, SPR_NOACCESS
,
1530 spr_register(env
, SPR_601_UDECR
, "UDECR",
1531 &spr_read_decr
, SPR_NOACCESS
,
1532 &spr_read_decr
, SPR_NOACCESS
,
1535 /* External access control */
1536 /* XXX : not implemented */
1537 spr_register(env
, SPR_EAR
, "EAR",
1538 SPR_NOACCESS
, SPR_NOACCESS
,
1539 &spr_read_generic
, &spr_write_generic
,
1541 /* Memory management */
1542 #if !defined(CONFIG_USER_ONLY)
1543 spr_register(env
, SPR_IBAT0U
, "IBAT0U",
1544 SPR_NOACCESS
, SPR_NOACCESS
,
1545 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1547 spr_register(env
, SPR_IBAT0L
, "IBAT0L",
1548 SPR_NOACCESS
, SPR_NOACCESS
,
1549 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1551 spr_register(env
, SPR_IBAT1U
, "IBAT1U",
1552 SPR_NOACCESS
, SPR_NOACCESS
,
1553 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1555 spr_register(env
, SPR_IBAT1L
, "IBAT1L",
1556 SPR_NOACCESS
, SPR_NOACCESS
,
1557 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1559 spr_register(env
, SPR_IBAT2U
, "IBAT2U",
1560 SPR_NOACCESS
, SPR_NOACCESS
,
1561 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1563 spr_register(env
, SPR_IBAT2L
, "IBAT2L",
1564 SPR_NOACCESS
, SPR_NOACCESS
,
1565 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1567 spr_register(env
, SPR_IBAT3U
, "IBAT3U",
1568 SPR_NOACCESS
, SPR_NOACCESS
,
1569 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1571 spr_register(env
, SPR_IBAT3L
, "IBAT3L",
1572 SPR_NOACCESS
, SPR_NOACCESS
,
1573 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1579 static void gen_spr_74xx(CPUPPCState
*env
)
1581 /* Processor identification */
1582 spr_register(env
, SPR_PIR
, "PIR",
1583 SPR_NOACCESS
, SPR_NOACCESS
,
1584 &spr_read_generic
, &spr_write_pir
,
1586 /* XXX : not implemented */
1587 spr_register(env
, SPR_74XX_MMCR2
, "MMCR2",
1588 SPR_NOACCESS
, SPR_NOACCESS
,
1589 &spr_read_generic
, &spr_write_generic
,
1591 /* XXX : not implemented */
1592 spr_register(env
, SPR_74XX_UMMCR2
, "UMMCR2",
1593 &spr_read_ureg
, SPR_NOACCESS
,
1594 &spr_read_ureg
, SPR_NOACCESS
,
1596 /* XXX: not implemented */
1597 spr_register(env
, SPR_BAMR
, "BAMR",
1598 SPR_NOACCESS
, SPR_NOACCESS
,
1599 &spr_read_generic
, &spr_write_generic
,
1601 /* XXX : not implemented */
1602 spr_register(env
, SPR_MSSCR0
, "MSSCR0",
1603 SPR_NOACCESS
, SPR_NOACCESS
,
1604 &spr_read_generic
, &spr_write_generic
,
1606 /* Hardware implementation registers */
1607 /* XXX : not implemented */
1608 spr_register(env
, SPR_HID0
, "HID0",
1609 SPR_NOACCESS
, SPR_NOACCESS
,
1610 &spr_read_generic
, &spr_write_generic
,
1612 /* XXX : not implemented */
1613 spr_register(env
, SPR_HID1
, "HID1",
1614 SPR_NOACCESS
, SPR_NOACCESS
,
1615 &spr_read_generic
, &spr_write_generic
,
1618 spr_register(env
, SPR_VRSAVE
, "VRSAVE",
1619 &spr_read_generic
, &spr_write_generic
,
1620 &spr_read_generic
, &spr_write_generic
,
1622 /* XXX : not implemented */
1623 spr_register(env
, SPR_L2CR
, "L2CR",
1624 SPR_NOACCESS
, SPR_NOACCESS
,
1625 &spr_read_generic
, spr_access_nop
,
1627 /* Not strictly an SPR */
1628 vscr_init(env
, 0x00010000);
1631 static void gen_l3_ctrl(CPUPPCState
*env
)
1634 /* XXX : not implemented */
1635 spr_register(env
, SPR_L3CR
, "L3CR",
1636 SPR_NOACCESS
, SPR_NOACCESS
,
1637 &spr_read_generic
, &spr_write_generic
,
1640 /* XXX : not implemented */
1641 spr_register(env
, SPR_L3ITCR0
, "L3ITCR0",
1642 SPR_NOACCESS
, SPR_NOACCESS
,
1643 &spr_read_generic
, &spr_write_generic
,
1646 /* XXX : not implemented */
1647 spr_register(env
, SPR_L3PM
, "L3PM",
1648 SPR_NOACCESS
, SPR_NOACCESS
,
1649 &spr_read_generic
, &spr_write_generic
,
1653 static void gen_74xx_soft_tlb(CPUPPCState
*env
, int nb_tlbs
, int nb_ways
)
1655 #if !defined(CONFIG_USER_ONLY)
1656 env
->nb_tlb
= nb_tlbs
;
1657 env
->nb_ways
= nb_ways
;
1659 env
->tlb_type
= TLB_6XX
;
1660 /* XXX : not implemented */
1661 spr_register(env
, SPR_PTEHI
, "PTEHI",
1662 SPR_NOACCESS
, SPR_NOACCESS
,
1663 &spr_read_generic
, &spr_write_generic
,
1665 /* XXX : not implemented */
1666 spr_register(env
, SPR_PTELO
, "PTELO",
1667 SPR_NOACCESS
, SPR_NOACCESS
,
1668 &spr_read_generic
, &spr_write_generic
,
1670 /* XXX : not implemented */
1671 spr_register(env
, SPR_TLBMISS
, "TLBMISS",
1672 SPR_NOACCESS
, SPR_NOACCESS
,
1673 &spr_read_generic
, &spr_write_generic
,
1678 #if !defined(CONFIG_USER_ONLY)
1679 static void spr_write_e500_l1csr0(DisasContext
*ctx
, int sprn
, int gprn
)
1681 TCGv t0
= tcg_temp_new();
1683 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], L1CSR0_DCE
| L1CSR0_CPE
);
1684 gen_store_spr(sprn
, t0
);
1688 static void spr_write_e500_l1csr1(DisasContext
*ctx
, int sprn
, int gprn
)
1690 TCGv t0
= tcg_temp_new();
1692 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], L1CSR1_ICE
| L1CSR1_CPE
);
1693 gen_store_spr(sprn
, t0
);
1697 static void spr_write_booke206_mmucsr0(DisasContext
*ctx
, int sprn
, int gprn
)
1699 gen_helper_booke206_tlbflush(cpu_env
, cpu_gpr
[gprn
]);
1702 static void spr_write_booke_pid(DisasContext
*ctx
, int sprn
, int gprn
)
1704 TCGv_i32 t0
= tcg_const_i32(sprn
);
1705 gen_helper_booke_setpid(cpu_env
, t0
, cpu_gpr
[gprn
]);
1706 tcg_temp_free_i32(t0
);
1708 static void spr_write_eplc(DisasContext
*ctx
, int sprn
, int gprn
)
1710 gen_helper_booke_set_eplc(cpu_env
, cpu_gpr
[gprn
]);
1712 static void spr_write_epsc(DisasContext
*ctx
, int sprn
, int gprn
)
1714 gen_helper_booke_set_epsc(cpu_env
, cpu_gpr
[gprn
]);
1719 static void gen_spr_usprg3(CPUPPCState
*env
)
1721 spr_register(env
, SPR_USPRG3
, "USPRG3",
1722 &spr_read_ureg
, SPR_NOACCESS
,
1723 &spr_read_ureg
, SPR_NOACCESS
,
1727 static void gen_spr_usprgh(CPUPPCState
*env
)
1729 spr_register(env
, SPR_USPRG4
, "USPRG4",
1730 &spr_read_ureg
, SPR_NOACCESS
,
1731 &spr_read_ureg
, SPR_NOACCESS
,
1733 spr_register(env
, SPR_USPRG5
, "USPRG5",
1734 &spr_read_ureg
, SPR_NOACCESS
,
1735 &spr_read_ureg
, SPR_NOACCESS
,
1737 spr_register(env
, SPR_USPRG6
, "USPRG6",
1738 &spr_read_ureg
, SPR_NOACCESS
,
1739 &spr_read_ureg
, SPR_NOACCESS
,
1741 spr_register(env
, SPR_USPRG7
, "USPRG7",
1742 &spr_read_ureg
, SPR_NOACCESS
,
1743 &spr_read_ureg
, SPR_NOACCESS
,
1747 /* PowerPC BookE SPR */
1748 static void gen_spr_BookE(CPUPPCState
*env
, uint64_t ivor_mask
)
1750 const char *ivor_names
[64] = {
1751 "IVOR0", "IVOR1", "IVOR2", "IVOR3",
1752 "IVOR4", "IVOR5", "IVOR6", "IVOR7",
1753 "IVOR8", "IVOR9", "IVOR10", "IVOR11",
1754 "IVOR12", "IVOR13", "IVOR14", "IVOR15",
1755 "IVOR16", "IVOR17", "IVOR18", "IVOR19",
1756 "IVOR20", "IVOR21", "IVOR22", "IVOR23",
1757 "IVOR24", "IVOR25", "IVOR26", "IVOR27",
1758 "IVOR28", "IVOR29", "IVOR30", "IVOR31",
1759 "IVOR32", "IVOR33", "IVOR34", "IVOR35",
1760 "IVOR36", "IVOR37", "IVOR38", "IVOR39",
1761 "IVOR40", "IVOR41", "IVOR42", "IVOR43",
1762 "IVOR44", "IVOR45", "IVOR46", "IVOR47",
1763 "IVOR48", "IVOR49", "IVOR50", "IVOR51",
1764 "IVOR52", "IVOR53", "IVOR54", "IVOR55",
1765 "IVOR56", "IVOR57", "IVOR58", "IVOR59",
1766 "IVOR60", "IVOR61", "IVOR62", "IVOR63",
1768 #define SPR_BOOKE_IVORxx (-1)
1769 int ivor_sprn
[64] = {
1770 SPR_BOOKE_IVOR0
, SPR_BOOKE_IVOR1
, SPR_BOOKE_IVOR2
, SPR_BOOKE_IVOR3
,
1771 SPR_BOOKE_IVOR4
, SPR_BOOKE_IVOR5
, SPR_BOOKE_IVOR6
, SPR_BOOKE_IVOR7
,
1772 SPR_BOOKE_IVOR8
, SPR_BOOKE_IVOR9
, SPR_BOOKE_IVOR10
, SPR_BOOKE_IVOR11
,
1773 SPR_BOOKE_IVOR12
, SPR_BOOKE_IVOR13
, SPR_BOOKE_IVOR14
, SPR_BOOKE_IVOR15
,
1774 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1775 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1776 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1777 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1778 SPR_BOOKE_IVOR32
, SPR_BOOKE_IVOR33
, SPR_BOOKE_IVOR34
, SPR_BOOKE_IVOR35
,
1779 SPR_BOOKE_IVOR36
, SPR_BOOKE_IVOR37
, SPR_BOOKE_IVOR38
, SPR_BOOKE_IVOR39
,
1780 SPR_BOOKE_IVOR40
, SPR_BOOKE_IVOR41
, SPR_BOOKE_IVOR42
, SPR_BOOKE_IVORxx
,
1781 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1782 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1783 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1784 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1785 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1789 /* Interrupt processing */
1790 spr_register(env
, SPR_BOOKE_CSRR0
, "CSRR0",
1791 SPR_NOACCESS
, SPR_NOACCESS
,
1792 &spr_read_generic
, &spr_write_generic
,
1794 spr_register(env
, SPR_BOOKE_CSRR1
, "CSRR1",
1795 SPR_NOACCESS
, SPR_NOACCESS
,
1796 &spr_read_generic
, &spr_write_generic
,
1799 /* XXX : not implemented */
1800 spr_register(env
, SPR_BOOKE_IAC1
, "IAC1",
1801 SPR_NOACCESS
, SPR_NOACCESS
,
1802 &spr_read_generic
, &spr_write_generic
,
1804 /* XXX : not implemented */
1805 spr_register(env
, SPR_BOOKE_IAC2
, "IAC2",
1806 SPR_NOACCESS
, SPR_NOACCESS
,
1807 &spr_read_generic
, &spr_write_generic
,
1809 /* XXX : not implemented */
1810 spr_register(env
, SPR_BOOKE_DAC1
, "DAC1",
1811 SPR_NOACCESS
, SPR_NOACCESS
,
1812 &spr_read_generic
, &spr_write_generic
,
1814 /* XXX : not implemented */
1815 spr_register(env
, SPR_BOOKE_DAC2
, "DAC2",
1816 SPR_NOACCESS
, SPR_NOACCESS
,
1817 &spr_read_generic
, &spr_write_generic
,
1819 /* XXX : not implemented */
1820 spr_register(env
, SPR_BOOKE_DBCR0
, "DBCR0",
1821 SPR_NOACCESS
, SPR_NOACCESS
,
1822 &spr_read_generic
, &spr_write_40x_dbcr0
,
1824 /* XXX : not implemented */
1825 spr_register(env
, SPR_BOOKE_DBCR1
, "DBCR1",
1826 SPR_NOACCESS
, SPR_NOACCESS
,
1827 &spr_read_generic
, &spr_write_generic
,
1829 /* XXX : not implemented */
1830 spr_register(env
, SPR_BOOKE_DBCR2
, "DBCR2",
1831 SPR_NOACCESS
, SPR_NOACCESS
,
1832 &spr_read_generic
, &spr_write_generic
,
1834 spr_register(env
, SPR_BOOKE_DSRR0
, "DSRR0",
1835 SPR_NOACCESS
, SPR_NOACCESS
,
1836 &spr_read_generic
, &spr_write_generic
,
1838 spr_register(env
, SPR_BOOKE_DSRR1
, "DSRR1",
1839 SPR_NOACCESS
, SPR_NOACCESS
,
1840 &spr_read_generic
, &spr_write_generic
,
1842 /* XXX : not implemented */
1843 spr_register(env
, SPR_BOOKE_DBSR
, "DBSR",
1844 SPR_NOACCESS
, SPR_NOACCESS
,
1845 &spr_read_generic
, &spr_write_clear
,
1847 spr_register(env
, SPR_BOOKE_DEAR
, "DEAR",
1848 SPR_NOACCESS
, SPR_NOACCESS
,
1849 &spr_read_generic
, &spr_write_generic
,
1851 spr_register(env
, SPR_BOOKE_ESR
, "ESR",
1852 SPR_NOACCESS
, SPR_NOACCESS
,
1853 &spr_read_generic
, &spr_write_generic
,
1855 spr_register(env
, SPR_BOOKE_IVPR
, "IVPR",
1856 SPR_NOACCESS
, SPR_NOACCESS
,
1857 &spr_read_generic
, &spr_write_excp_prefix
,
1859 /* Exception vectors */
1860 for (i
= 0; i
< 64; i
++) {
1861 if (ivor_mask
& (1ULL << i
)) {
1862 if (ivor_sprn
[i
] == SPR_BOOKE_IVORxx
) {
1863 fprintf(stderr
, "ERROR: IVOR %d SPR is not defined\n", i
);
1866 spr_register(env
, ivor_sprn
[i
], ivor_names
[i
],
1867 SPR_NOACCESS
, SPR_NOACCESS
,
1868 &spr_read_generic
, &spr_write_excp_vector
,
1872 spr_register(env
, SPR_BOOKE_PID
, "PID",
1873 SPR_NOACCESS
, SPR_NOACCESS
,
1874 &spr_read_generic
, &spr_write_booke_pid
,
1876 spr_register(env
, SPR_BOOKE_TCR
, "TCR",
1877 SPR_NOACCESS
, SPR_NOACCESS
,
1878 &spr_read_generic
, &spr_write_booke_tcr
,
1880 spr_register(env
, SPR_BOOKE_TSR
, "TSR",
1881 SPR_NOACCESS
, SPR_NOACCESS
,
1882 &spr_read_generic
, &spr_write_booke_tsr
,
1885 spr_register(env
, SPR_DECR
, "DECR",
1886 SPR_NOACCESS
, SPR_NOACCESS
,
1887 &spr_read_decr
, &spr_write_decr
,
1889 spr_register(env
, SPR_BOOKE_DECAR
, "DECAR",
1890 SPR_NOACCESS
, SPR_NOACCESS
,
1891 SPR_NOACCESS
, &spr_write_generic
,
1894 spr_register(env
, SPR_USPRG0
, "USPRG0",
1895 &spr_read_generic
, &spr_write_generic
,
1896 &spr_read_generic
, &spr_write_generic
,
1898 spr_register(env
, SPR_SPRG4
, "SPRG4",
1899 SPR_NOACCESS
, SPR_NOACCESS
,
1900 &spr_read_generic
, &spr_write_generic
,
1902 spr_register(env
, SPR_SPRG5
, "SPRG5",
1903 SPR_NOACCESS
, SPR_NOACCESS
,
1904 &spr_read_generic
, &spr_write_generic
,
1906 spr_register(env
, SPR_SPRG6
, "SPRG6",
1907 SPR_NOACCESS
, SPR_NOACCESS
,
1908 &spr_read_generic
, &spr_write_generic
,
1910 spr_register(env
, SPR_SPRG7
, "SPRG7",
1911 SPR_NOACCESS
, SPR_NOACCESS
,
1912 &spr_read_generic
, &spr_write_generic
,
1914 spr_register(env
, SPR_BOOKE_SPRG8
, "SPRG8",
1915 SPR_NOACCESS
, SPR_NOACCESS
,
1916 &spr_read_generic
, &spr_write_generic
,
1918 spr_register(env
, SPR_BOOKE_SPRG9
, "SPRG9",
1919 SPR_NOACCESS
, SPR_NOACCESS
,
1920 &spr_read_generic
, &spr_write_generic
,
1924 static inline uint32_t gen_tlbncfg(uint32_t assoc
, uint32_t minsize
,
1925 uint32_t maxsize
, uint32_t flags
,
1928 return (assoc
<< TLBnCFG_ASSOC_SHIFT
) |
1929 (minsize
<< TLBnCFG_MINSIZE_SHIFT
) |
1930 (maxsize
<< TLBnCFG_MAXSIZE_SHIFT
) |
1934 /* BookE 2.06 storage control registers */
1935 static void gen_spr_BookE206(CPUPPCState
*env
, uint32_t mas_mask
,
1936 uint32_t *tlbncfg
, uint32_t mmucfg
)
1938 #if !defined(CONFIG_USER_ONLY)
1939 const char *mas_names
[8] = {
1940 "MAS0", "MAS1", "MAS2", "MAS3", "MAS4", "MAS5", "MAS6", "MAS7",
1943 SPR_BOOKE_MAS0
, SPR_BOOKE_MAS1
, SPR_BOOKE_MAS2
, SPR_BOOKE_MAS3
,
1944 SPR_BOOKE_MAS4
, SPR_BOOKE_MAS5
, SPR_BOOKE_MAS6
, SPR_BOOKE_MAS7
,
1948 /* TLB assist registers */
1949 /* XXX : not implemented */
1950 for (i
= 0; i
< 8; i
++) {
1951 void (*uea_write
)(DisasContext
*ctx
, int sprn
, int gprn
) =
1952 &spr_write_generic32
;
1953 if (i
== 2 && (mas_mask
& (1 << i
)) && (env
->insns_flags
& PPC_64B
)) {
1954 uea_write
= &spr_write_generic
;
1956 if (mas_mask
& (1 << i
)) {
1957 spr_register(env
, mas_sprn
[i
], mas_names
[i
],
1958 SPR_NOACCESS
, SPR_NOACCESS
,
1959 &spr_read_generic
, uea_write
,
1963 if (env
->nb_pids
> 1) {
1964 /* XXX : not implemented */
1965 spr_register(env
, SPR_BOOKE_PID1
, "PID1",
1966 SPR_NOACCESS
, SPR_NOACCESS
,
1967 &spr_read_generic
, &spr_write_booke_pid
,
1970 if (env
->nb_pids
> 2) {
1971 /* XXX : not implemented */
1972 spr_register(env
, SPR_BOOKE_PID2
, "PID2",
1973 SPR_NOACCESS
, SPR_NOACCESS
,
1974 &spr_read_generic
, &spr_write_booke_pid
,
1978 spr_register(env
, SPR_BOOKE_EPLC
, "EPLC",
1979 SPR_NOACCESS
, SPR_NOACCESS
,
1980 &spr_read_generic
, &spr_write_eplc
,
1982 spr_register(env
, SPR_BOOKE_EPSC
, "EPSC",
1983 SPR_NOACCESS
, SPR_NOACCESS
,
1984 &spr_read_generic
, &spr_write_epsc
,
1987 /* XXX : not implemented */
1988 spr_register(env
, SPR_MMUCFG
, "MMUCFG",
1989 SPR_NOACCESS
, SPR_NOACCESS
,
1990 &spr_read_generic
, SPR_NOACCESS
,
1992 switch (env
->nb_ways
) {
1994 spr_register(env
, SPR_BOOKE_TLB3CFG
, "TLB3CFG",
1995 SPR_NOACCESS
, SPR_NOACCESS
,
1996 &spr_read_generic
, SPR_NOACCESS
,
2000 spr_register(env
, SPR_BOOKE_TLB2CFG
, "TLB2CFG",
2001 SPR_NOACCESS
, SPR_NOACCESS
,
2002 &spr_read_generic
, SPR_NOACCESS
,
2006 spr_register(env
, SPR_BOOKE_TLB1CFG
, "TLB1CFG",
2007 SPR_NOACCESS
, SPR_NOACCESS
,
2008 &spr_read_generic
, SPR_NOACCESS
,
2012 spr_register(env
, SPR_BOOKE_TLB0CFG
, "TLB0CFG",
2013 SPR_NOACCESS
, SPR_NOACCESS
,
2014 &spr_read_generic
, SPR_NOACCESS
,
2023 gen_spr_usprgh(env
);
2026 /* SPR specific to PowerPC 440 implementation */
2027 static void gen_spr_440(CPUPPCState
*env
)
2030 /* XXX : not implemented */
2031 spr_register(env
, SPR_440_DNV0
, "DNV0",
2032 SPR_NOACCESS
, SPR_NOACCESS
,
2033 &spr_read_generic
, &spr_write_generic
,
2035 /* XXX : not implemented */
2036 spr_register(env
, SPR_440_DNV1
, "DNV1",
2037 SPR_NOACCESS
, SPR_NOACCESS
,
2038 &spr_read_generic
, &spr_write_generic
,
2040 /* XXX : not implemented */
2041 spr_register(env
, SPR_440_DNV2
, "DNV2",
2042 SPR_NOACCESS
, SPR_NOACCESS
,
2043 &spr_read_generic
, &spr_write_generic
,
2045 /* XXX : not implemented */
2046 spr_register(env
, SPR_440_DNV3
, "DNV3",
2047 SPR_NOACCESS
, SPR_NOACCESS
,
2048 &spr_read_generic
, &spr_write_generic
,
2050 /* XXX : not implemented */
2051 spr_register(env
, SPR_440_DTV0
, "DTV0",
2052 SPR_NOACCESS
, SPR_NOACCESS
,
2053 &spr_read_generic
, &spr_write_generic
,
2055 /* XXX : not implemented */
2056 spr_register(env
, SPR_440_DTV1
, "DTV1",
2057 SPR_NOACCESS
, SPR_NOACCESS
,
2058 &spr_read_generic
, &spr_write_generic
,
2060 /* XXX : not implemented */
2061 spr_register(env
, SPR_440_DTV2
, "DTV2",
2062 SPR_NOACCESS
, SPR_NOACCESS
,
2063 &spr_read_generic
, &spr_write_generic
,
2065 /* XXX : not implemented */
2066 spr_register(env
, SPR_440_DTV3
, "DTV3",
2067 SPR_NOACCESS
, SPR_NOACCESS
,
2068 &spr_read_generic
, &spr_write_generic
,
2070 /* XXX : not implemented */
2071 spr_register(env
, SPR_440_DVLIM
, "DVLIM",
2072 SPR_NOACCESS
, SPR_NOACCESS
,
2073 &spr_read_generic
, &spr_write_generic
,
2075 /* XXX : not implemented */
2076 spr_register(env
, SPR_440_INV0
, "INV0",
2077 SPR_NOACCESS
, SPR_NOACCESS
,
2078 &spr_read_generic
, &spr_write_generic
,
2080 /* XXX : not implemented */
2081 spr_register(env
, SPR_440_INV1
, "INV1",
2082 SPR_NOACCESS
, SPR_NOACCESS
,
2083 &spr_read_generic
, &spr_write_generic
,
2085 /* XXX : not implemented */
2086 spr_register(env
, SPR_440_INV2
, "INV2",
2087 SPR_NOACCESS
, SPR_NOACCESS
,
2088 &spr_read_generic
, &spr_write_generic
,
2090 /* XXX : not implemented */
2091 spr_register(env
, SPR_440_INV3
, "INV3",
2092 SPR_NOACCESS
, SPR_NOACCESS
,
2093 &spr_read_generic
, &spr_write_generic
,
2095 /* XXX : not implemented */
2096 spr_register(env
, SPR_440_ITV0
, "ITV0",
2097 SPR_NOACCESS
, SPR_NOACCESS
,
2098 &spr_read_generic
, &spr_write_generic
,
2100 /* XXX : not implemented */
2101 spr_register(env
, SPR_440_ITV1
, "ITV1",
2102 SPR_NOACCESS
, SPR_NOACCESS
,
2103 &spr_read_generic
, &spr_write_generic
,
2105 /* XXX : not implemented */
2106 spr_register(env
, SPR_440_ITV2
, "ITV2",
2107 SPR_NOACCESS
, SPR_NOACCESS
,
2108 &spr_read_generic
, &spr_write_generic
,
2110 /* XXX : not implemented */
2111 spr_register(env
, SPR_440_ITV3
, "ITV3",
2112 SPR_NOACCESS
, SPR_NOACCESS
,
2113 &spr_read_generic
, &spr_write_generic
,
2115 /* XXX : not implemented */
2116 spr_register(env
, SPR_440_IVLIM
, "IVLIM",
2117 SPR_NOACCESS
, SPR_NOACCESS
,
2118 &spr_read_generic
, &spr_write_generic
,
2121 /* XXX : not implemented */
2122 spr_register(env
, SPR_BOOKE_DCDBTRH
, "DCDBTRH",
2123 SPR_NOACCESS
, SPR_NOACCESS
,
2124 &spr_read_generic
, SPR_NOACCESS
,
2126 /* XXX : not implemented */
2127 spr_register(env
, SPR_BOOKE_DCDBTRL
, "DCDBTRL",
2128 SPR_NOACCESS
, SPR_NOACCESS
,
2129 &spr_read_generic
, SPR_NOACCESS
,
2131 /* XXX : not implemented */
2132 spr_register(env
, SPR_BOOKE_ICDBDR
, "ICDBDR",
2133 SPR_NOACCESS
, SPR_NOACCESS
,
2134 &spr_read_generic
, SPR_NOACCESS
,
2136 /* XXX : not implemented */
2137 spr_register(env
, SPR_BOOKE_ICDBTRH
, "ICDBTRH",
2138 SPR_NOACCESS
, SPR_NOACCESS
,
2139 &spr_read_generic
, SPR_NOACCESS
,
2141 /* XXX : not implemented */
2142 spr_register(env
, SPR_BOOKE_ICDBTRL
, "ICDBTRL",
2143 SPR_NOACCESS
, SPR_NOACCESS
,
2144 &spr_read_generic
, SPR_NOACCESS
,
2146 /* XXX : not implemented */
2147 spr_register(env
, SPR_440_DBDR
, "DBDR",
2148 SPR_NOACCESS
, SPR_NOACCESS
,
2149 &spr_read_generic
, &spr_write_generic
,
2151 /* Processor control */
2152 spr_register(env
, SPR_4xx_CCR0
, "CCR0",
2153 SPR_NOACCESS
, SPR_NOACCESS
,
2154 &spr_read_generic
, &spr_write_generic
,
2156 spr_register(env
, SPR_440_RSTCFG
, "RSTCFG",
2157 SPR_NOACCESS
, SPR_NOACCESS
,
2158 &spr_read_generic
, SPR_NOACCESS
,
2160 /* Storage control */
2161 spr_register(env
, SPR_440_MMUCR
, "MMUCR",
2162 SPR_NOACCESS
, SPR_NOACCESS
,
2163 &spr_read_generic
, &spr_write_generic
,
2167 /* SPR shared between PowerPC 40x implementations */
2168 static void gen_spr_40x(CPUPPCState
*env
)
2171 /* not emulated, as QEMU do not emulate caches */
2172 spr_register(env
, SPR_40x_DCCR
, "DCCR",
2173 SPR_NOACCESS
, SPR_NOACCESS
,
2174 &spr_read_generic
, &spr_write_generic
,
2176 /* not emulated, as QEMU do not emulate caches */
2177 spr_register(env
, SPR_40x_ICCR
, "ICCR",
2178 SPR_NOACCESS
, SPR_NOACCESS
,
2179 &spr_read_generic
, &spr_write_generic
,
2181 /* not emulated, as QEMU do not emulate caches */
2182 spr_register(env
, SPR_BOOKE_ICDBDR
, "ICDBDR",
2183 SPR_NOACCESS
, SPR_NOACCESS
,
2184 &spr_read_generic
, SPR_NOACCESS
,
2187 spr_register(env
, SPR_40x_DEAR
, "DEAR",
2188 SPR_NOACCESS
, SPR_NOACCESS
,
2189 &spr_read_generic
, &spr_write_generic
,
2191 spr_register(env
, SPR_40x_ESR
, "ESR",
2192 SPR_NOACCESS
, SPR_NOACCESS
,
2193 &spr_read_generic
, &spr_write_generic
,
2195 spr_register(env
, SPR_40x_EVPR
, "EVPR",
2196 SPR_NOACCESS
, SPR_NOACCESS
,
2197 &spr_read_generic
, &spr_write_excp_prefix
,
2199 spr_register(env
, SPR_40x_SRR2
, "SRR2",
2200 &spr_read_generic
, &spr_write_generic
,
2201 &spr_read_generic
, &spr_write_generic
,
2203 spr_register(env
, SPR_40x_SRR3
, "SRR3",
2204 &spr_read_generic
, &spr_write_generic
,
2205 &spr_read_generic
, &spr_write_generic
,
2208 spr_register(env
, SPR_40x_PIT
, "PIT",
2209 SPR_NOACCESS
, SPR_NOACCESS
,
2210 &spr_read_40x_pit
, &spr_write_40x_pit
,
2212 spr_register(env
, SPR_40x_TCR
, "TCR",
2213 SPR_NOACCESS
, SPR_NOACCESS
,
2214 &spr_read_generic
, &spr_write_booke_tcr
,
2216 spr_register(env
, SPR_40x_TSR
, "TSR",
2217 SPR_NOACCESS
, SPR_NOACCESS
,
2218 &spr_read_generic
, &spr_write_booke_tsr
,
2222 /* SPR specific to PowerPC 405 implementation */
2223 static void gen_spr_405(CPUPPCState
*env
)
2226 spr_register(env
, SPR_40x_PID
, "PID",
2227 SPR_NOACCESS
, SPR_NOACCESS
,
2228 &spr_read_generic
, &spr_write_generic
,
2230 spr_register(env
, SPR_4xx_CCR0
, "CCR0",
2231 SPR_NOACCESS
, SPR_NOACCESS
,
2232 &spr_read_generic
, &spr_write_generic
,
2234 /* Debug interface */
2235 /* XXX : not implemented */
2236 spr_register(env
, SPR_40x_DBCR0
, "DBCR0",
2237 SPR_NOACCESS
, SPR_NOACCESS
,
2238 &spr_read_generic
, &spr_write_40x_dbcr0
,
2240 /* XXX : not implemented */
2241 spr_register(env
, SPR_405_DBCR1
, "DBCR1",
2242 SPR_NOACCESS
, SPR_NOACCESS
,
2243 &spr_read_generic
, &spr_write_generic
,
2245 /* XXX : not implemented */
2246 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2247 SPR_NOACCESS
, SPR_NOACCESS
,
2248 &spr_read_generic
, &spr_write_clear
,
2249 /* Last reset was system reset */
2251 /* XXX : not implemented */
2252 spr_register(env
, SPR_40x_DAC1
, "DAC1",
2253 SPR_NOACCESS
, SPR_NOACCESS
,
2254 &spr_read_generic
, &spr_write_generic
,
2256 spr_register(env
, SPR_40x_DAC2
, "DAC2",
2257 SPR_NOACCESS
, SPR_NOACCESS
,
2258 &spr_read_generic
, &spr_write_generic
,
2260 /* XXX : not implemented */
2261 spr_register(env
, SPR_405_DVC1
, "DVC1",
2262 SPR_NOACCESS
, SPR_NOACCESS
,
2263 &spr_read_generic
, &spr_write_generic
,
2265 /* XXX : not implemented */
2266 spr_register(env
, SPR_405_DVC2
, "DVC2",
2267 SPR_NOACCESS
, SPR_NOACCESS
,
2268 &spr_read_generic
, &spr_write_generic
,
2270 /* XXX : not implemented */
2271 spr_register(env
, SPR_40x_IAC1
, "IAC1",
2272 SPR_NOACCESS
, SPR_NOACCESS
,
2273 &spr_read_generic
, &spr_write_generic
,
2275 spr_register(env
, SPR_40x_IAC2
, "IAC2",
2276 SPR_NOACCESS
, SPR_NOACCESS
,
2277 &spr_read_generic
, &spr_write_generic
,
2279 /* XXX : not implemented */
2280 spr_register(env
, SPR_405_IAC3
, "IAC3",
2281 SPR_NOACCESS
, SPR_NOACCESS
,
2282 &spr_read_generic
, &spr_write_generic
,
2284 /* XXX : not implemented */
2285 spr_register(env
, SPR_405_IAC4
, "IAC4",
2286 SPR_NOACCESS
, SPR_NOACCESS
,
2287 &spr_read_generic
, &spr_write_generic
,
2289 /* Storage control */
2290 /* XXX: TODO: not implemented */
2291 spr_register(env
, SPR_405_SLER
, "SLER",
2292 SPR_NOACCESS
, SPR_NOACCESS
,
2293 &spr_read_generic
, &spr_write_40x_sler
,
2295 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2296 SPR_NOACCESS
, SPR_NOACCESS
,
2297 &spr_read_generic
, &spr_write_generic
,
2299 /* XXX : not implemented */
2300 spr_register(env
, SPR_405_SU0R
, "SU0R",
2301 SPR_NOACCESS
, SPR_NOACCESS
,
2302 &spr_read_generic
, &spr_write_generic
,
2305 spr_register(env
, SPR_USPRG0
, "USPRG0",
2306 &spr_read_ureg
, SPR_NOACCESS
,
2307 &spr_read_ureg
, SPR_NOACCESS
,
2309 spr_register(env
, SPR_SPRG4
, "SPRG4",
2310 SPR_NOACCESS
, SPR_NOACCESS
,
2311 &spr_read_generic
, &spr_write_generic
,
2313 spr_register(env
, SPR_SPRG5
, "SPRG5",
2314 SPR_NOACCESS
, SPR_NOACCESS
,
2315 spr_read_generic
, &spr_write_generic
,
2317 spr_register(env
, SPR_SPRG6
, "SPRG6",
2318 SPR_NOACCESS
, SPR_NOACCESS
,
2319 spr_read_generic
, &spr_write_generic
,
2321 spr_register(env
, SPR_SPRG7
, "SPRG7",
2322 SPR_NOACCESS
, SPR_NOACCESS
,
2323 spr_read_generic
, &spr_write_generic
,
2325 gen_spr_usprgh(env
);
2328 /* SPR shared between PowerPC 401 & 403 implementations */
2329 static void gen_spr_401_403(CPUPPCState
*env
)
2332 spr_register(env
, SPR_403_VTBL
, "TBL",
2333 &spr_read_tbl
, SPR_NOACCESS
,
2334 &spr_read_tbl
, SPR_NOACCESS
,
2336 spr_register(env
, SPR_403_TBL
, "TBL",
2337 SPR_NOACCESS
, SPR_NOACCESS
,
2338 SPR_NOACCESS
, &spr_write_tbl
,
2340 spr_register(env
, SPR_403_VTBU
, "TBU",
2341 &spr_read_tbu
, SPR_NOACCESS
,
2342 &spr_read_tbu
, SPR_NOACCESS
,
2344 spr_register(env
, SPR_403_TBU
, "TBU",
2345 SPR_NOACCESS
, SPR_NOACCESS
,
2346 SPR_NOACCESS
, &spr_write_tbu
,
2349 /* not emulated, as QEMU do not emulate caches */
2350 spr_register(env
, SPR_403_CDBCR
, "CDBCR",
2351 SPR_NOACCESS
, SPR_NOACCESS
,
2352 &spr_read_generic
, &spr_write_generic
,
2356 /* SPR specific to PowerPC 401 implementation */
2357 static void gen_spr_401(CPUPPCState
*env
)
2359 /* Debug interface */
2360 /* XXX : not implemented */
2361 spr_register(env
, SPR_40x_DBCR0
, "DBCR",
2362 SPR_NOACCESS
, SPR_NOACCESS
,
2363 &spr_read_generic
, &spr_write_40x_dbcr0
,
2365 /* XXX : not implemented */
2366 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2367 SPR_NOACCESS
, SPR_NOACCESS
,
2368 &spr_read_generic
, &spr_write_clear
,
2369 /* Last reset was system reset */
2371 /* XXX : not implemented */
2372 spr_register(env
, SPR_40x_DAC1
, "DAC",
2373 SPR_NOACCESS
, SPR_NOACCESS
,
2374 &spr_read_generic
, &spr_write_generic
,
2376 /* XXX : not implemented */
2377 spr_register(env
, SPR_40x_IAC1
, "IAC",
2378 SPR_NOACCESS
, SPR_NOACCESS
,
2379 &spr_read_generic
, &spr_write_generic
,
2381 /* Storage control */
2382 /* XXX: TODO: not implemented */
2383 spr_register(env
, SPR_405_SLER
, "SLER",
2384 SPR_NOACCESS
, SPR_NOACCESS
,
2385 &spr_read_generic
, &spr_write_40x_sler
,
2387 /* not emulated, as QEMU never does speculative access */
2388 spr_register(env
, SPR_40x_SGR
, "SGR",
2389 SPR_NOACCESS
, SPR_NOACCESS
,
2390 &spr_read_generic
, &spr_write_generic
,
2392 /* not emulated, as QEMU do not emulate caches */
2393 spr_register(env
, SPR_40x_DCWR
, "DCWR",
2394 SPR_NOACCESS
, SPR_NOACCESS
,
2395 &spr_read_generic
, &spr_write_generic
,
2399 static void gen_spr_401x2(CPUPPCState
*env
)
2402 spr_register(env
, SPR_40x_PID
, "PID",
2403 SPR_NOACCESS
, SPR_NOACCESS
,
2404 &spr_read_generic
, &spr_write_generic
,
2406 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2407 SPR_NOACCESS
, SPR_NOACCESS
,
2408 &spr_read_generic
, &spr_write_generic
,
2412 /* SPR specific to PowerPC 403 implementation */
2413 static void gen_spr_403(CPUPPCState
*env
)
2415 /* Debug interface */
2416 /* XXX : not implemented */
2417 spr_register(env
, SPR_40x_DBCR0
, "DBCR0",
2418 SPR_NOACCESS
, SPR_NOACCESS
,
2419 &spr_read_generic
, &spr_write_40x_dbcr0
,
2421 /* XXX : not implemented */
2422 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2423 SPR_NOACCESS
, SPR_NOACCESS
,
2424 &spr_read_generic
, &spr_write_clear
,
2425 /* Last reset was system reset */
2427 /* XXX : not implemented */
2428 spr_register(env
, SPR_40x_DAC1
, "DAC1",
2429 SPR_NOACCESS
, SPR_NOACCESS
,
2430 &spr_read_generic
, &spr_write_generic
,
2432 /* XXX : not implemented */
2433 spr_register(env
, SPR_40x_DAC2
, "DAC2",
2434 SPR_NOACCESS
, SPR_NOACCESS
,
2435 &spr_read_generic
, &spr_write_generic
,
2437 /* XXX : not implemented */
2438 spr_register(env
, SPR_40x_IAC1
, "IAC1",
2439 SPR_NOACCESS
, SPR_NOACCESS
,
2440 &spr_read_generic
, &spr_write_generic
,
2442 /* XXX : not implemented */
2443 spr_register(env
, SPR_40x_IAC2
, "IAC2",
2444 SPR_NOACCESS
, SPR_NOACCESS
,
2445 &spr_read_generic
, &spr_write_generic
,
2449 static void gen_spr_403_real(CPUPPCState
*env
)
2451 spr_register(env
, SPR_403_PBL1
, "PBL1",
2452 SPR_NOACCESS
, SPR_NOACCESS
,
2453 &spr_read_403_pbr
, &spr_write_403_pbr
,
2455 spr_register(env
, SPR_403_PBU1
, "PBU1",
2456 SPR_NOACCESS
, SPR_NOACCESS
,
2457 &spr_read_403_pbr
, &spr_write_403_pbr
,
2459 spr_register(env
, SPR_403_PBL2
, "PBL2",
2460 SPR_NOACCESS
, SPR_NOACCESS
,
2461 &spr_read_403_pbr
, &spr_write_403_pbr
,
2463 spr_register(env
, SPR_403_PBU2
, "PBU2",
2464 SPR_NOACCESS
, SPR_NOACCESS
,
2465 &spr_read_403_pbr
, &spr_write_403_pbr
,
2469 static void gen_spr_403_mmu(CPUPPCState
*env
)
2472 spr_register(env
, SPR_40x_PID
, "PID",
2473 SPR_NOACCESS
, SPR_NOACCESS
,
2474 &spr_read_generic
, &spr_write_generic
,
2476 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2477 SPR_NOACCESS
, SPR_NOACCESS
,
2478 &spr_read_generic
, &spr_write_generic
,
2482 /* SPR specific to PowerPC compression coprocessor extension */
2483 static void gen_spr_compress(CPUPPCState
*env
)
2485 /* XXX : not implemented */
2486 spr_register(env
, SPR_401_SKR
, "SKR",
2487 SPR_NOACCESS
, SPR_NOACCESS
,
2488 &spr_read_generic
, &spr_write_generic
,
2492 static void gen_spr_5xx_8xx(CPUPPCState
*env
)
2494 /* Exception processing */
2495 spr_register_kvm(env
, SPR_DSISR
, "DSISR",
2496 SPR_NOACCESS
, SPR_NOACCESS
,
2497 &spr_read_generic
, &spr_write_generic
,
2498 KVM_REG_PPC_DSISR
, 0x00000000);
2499 spr_register_kvm(env
, SPR_DAR
, "DAR",
2500 SPR_NOACCESS
, SPR_NOACCESS
,
2501 &spr_read_generic
, &spr_write_generic
,
2502 KVM_REG_PPC_DAR
, 0x00000000);
2504 spr_register(env
, SPR_DECR
, "DECR",
2505 SPR_NOACCESS
, SPR_NOACCESS
,
2506 &spr_read_decr
, &spr_write_decr
,
2508 /* XXX : not implemented */
2509 spr_register(env
, SPR_MPC_EIE
, "EIE",
2510 SPR_NOACCESS
, SPR_NOACCESS
,
2511 &spr_read_generic
, &spr_write_generic
,
2513 /* XXX : not implemented */
2514 spr_register(env
, SPR_MPC_EID
, "EID",
2515 SPR_NOACCESS
, SPR_NOACCESS
,
2516 &spr_read_generic
, &spr_write_generic
,
2518 /* XXX : not implemented */
2519 spr_register(env
, SPR_MPC_NRI
, "NRI",
2520 SPR_NOACCESS
, SPR_NOACCESS
,
2521 &spr_read_generic
, &spr_write_generic
,
2523 /* XXX : not implemented */
2524 spr_register(env
, SPR_MPC_CMPA
, "CMPA",
2525 SPR_NOACCESS
, SPR_NOACCESS
,
2526 &spr_read_generic
, &spr_write_generic
,
2528 /* XXX : not implemented */
2529 spr_register(env
, SPR_MPC_CMPB
, "CMPB",
2530 SPR_NOACCESS
, SPR_NOACCESS
,
2531 &spr_read_generic
, &spr_write_generic
,
2533 /* XXX : not implemented */
2534 spr_register(env
, SPR_MPC_CMPC
, "CMPC",
2535 SPR_NOACCESS
, SPR_NOACCESS
,
2536 &spr_read_generic
, &spr_write_generic
,
2538 /* XXX : not implemented */
2539 spr_register(env
, SPR_MPC_CMPD
, "CMPD",
2540 SPR_NOACCESS
, SPR_NOACCESS
,
2541 &spr_read_generic
, &spr_write_generic
,
2543 /* XXX : not implemented */
2544 spr_register(env
, SPR_MPC_ECR
, "ECR",
2545 SPR_NOACCESS
, SPR_NOACCESS
,
2546 &spr_read_generic
, &spr_write_generic
,
2548 /* XXX : not implemented */
2549 spr_register(env
, SPR_MPC_DER
, "DER",
2550 SPR_NOACCESS
, SPR_NOACCESS
,
2551 &spr_read_generic
, &spr_write_generic
,
2553 /* XXX : not implemented */
2554 spr_register(env
, SPR_MPC_COUNTA
, "COUNTA",
2555 SPR_NOACCESS
, SPR_NOACCESS
,
2556 &spr_read_generic
, &spr_write_generic
,
2558 /* XXX : not implemented */
2559 spr_register(env
, SPR_MPC_COUNTB
, "COUNTB",
2560 SPR_NOACCESS
, SPR_NOACCESS
,
2561 &spr_read_generic
, &spr_write_generic
,
2563 /* XXX : not implemented */
2564 spr_register(env
, SPR_MPC_CMPE
, "CMPE",
2565 SPR_NOACCESS
, SPR_NOACCESS
,
2566 &spr_read_generic
, &spr_write_generic
,
2568 /* XXX : not implemented */
2569 spr_register(env
, SPR_MPC_CMPF
, "CMPF",
2570 SPR_NOACCESS
, SPR_NOACCESS
,
2571 &spr_read_generic
, &spr_write_generic
,
2573 /* XXX : not implemented */
2574 spr_register(env
, SPR_MPC_CMPG
, "CMPG",
2575 SPR_NOACCESS
, SPR_NOACCESS
,
2576 &spr_read_generic
, &spr_write_generic
,
2578 /* XXX : not implemented */
2579 spr_register(env
, SPR_MPC_CMPH
, "CMPH",
2580 SPR_NOACCESS
, SPR_NOACCESS
,
2581 &spr_read_generic
, &spr_write_generic
,
2583 /* XXX : not implemented */
2584 spr_register(env
, SPR_MPC_LCTRL1
, "LCTRL1",
2585 SPR_NOACCESS
, SPR_NOACCESS
,
2586 &spr_read_generic
, &spr_write_generic
,
2588 /* XXX : not implemented */
2589 spr_register(env
, SPR_MPC_LCTRL2
, "LCTRL2",
2590 SPR_NOACCESS
, SPR_NOACCESS
,
2591 &spr_read_generic
, &spr_write_generic
,
2593 /* XXX : not implemented */
2594 spr_register(env
, SPR_MPC_BAR
, "BAR",
2595 SPR_NOACCESS
, SPR_NOACCESS
,
2596 &spr_read_generic
, &spr_write_generic
,
2598 /* XXX : not implemented */
2599 spr_register(env
, SPR_MPC_DPDR
, "DPDR",
2600 SPR_NOACCESS
, SPR_NOACCESS
,
2601 &spr_read_generic
, &spr_write_generic
,
2603 /* XXX : not implemented */
2604 spr_register(env
, SPR_MPC_IMMR
, "IMMR",
2605 SPR_NOACCESS
, SPR_NOACCESS
,
2606 &spr_read_generic
, &spr_write_generic
,
2610 static void gen_spr_5xx(CPUPPCState
*env
)
2612 /* XXX : not implemented */
2613 spr_register(env
, SPR_RCPU_MI_GRA
, "MI_GRA",
2614 SPR_NOACCESS
, SPR_NOACCESS
,
2615 &spr_read_generic
, &spr_write_generic
,
2617 /* XXX : not implemented */
2618 spr_register(env
, SPR_RCPU_L2U_GRA
, "L2U_GRA",
2619 SPR_NOACCESS
, SPR_NOACCESS
,
2620 &spr_read_generic
, &spr_write_generic
,
2622 /* XXX : not implemented */
2623 spr_register(env
, SPR_RPCU_BBCMCR
, "L2U_BBCMCR",
2624 SPR_NOACCESS
, SPR_NOACCESS
,
2625 &spr_read_generic
, &spr_write_generic
,
2627 /* XXX : not implemented */
2628 spr_register(env
, SPR_RCPU_L2U_MCR
, "L2U_MCR",
2629 SPR_NOACCESS
, SPR_NOACCESS
,
2630 &spr_read_generic
, &spr_write_generic
,
2632 /* XXX : not implemented */
2633 spr_register(env
, SPR_RCPU_MI_RBA0
, "MI_RBA0",
2634 SPR_NOACCESS
, SPR_NOACCESS
,
2635 &spr_read_generic
, &spr_write_generic
,
2637 /* XXX : not implemented */
2638 spr_register(env
, SPR_RCPU_MI_RBA1
, "MI_RBA1",
2639 SPR_NOACCESS
, SPR_NOACCESS
,
2640 &spr_read_generic
, &spr_write_generic
,
2642 /* XXX : not implemented */
2643 spr_register(env
, SPR_RCPU_MI_RBA2
, "MI_RBA2",
2644 SPR_NOACCESS
, SPR_NOACCESS
,
2645 &spr_read_generic
, &spr_write_generic
,
2647 /* XXX : not implemented */
2648 spr_register(env
, SPR_RCPU_MI_RBA3
, "MI_RBA3",
2649 SPR_NOACCESS
, SPR_NOACCESS
,
2650 &spr_read_generic
, &spr_write_generic
,
2652 /* XXX : not implemented */
2653 spr_register(env
, SPR_RCPU_L2U_RBA0
, "L2U_RBA0",
2654 SPR_NOACCESS
, SPR_NOACCESS
,
2655 &spr_read_generic
, &spr_write_generic
,
2657 /* XXX : not implemented */
2658 spr_register(env
, SPR_RCPU_L2U_RBA1
, "L2U_RBA1",
2659 SPR_NOACCESS
, SPR_NOACCESS
,
2660 &spr_read_generic
, &spr_write_generic
,
2662 /* XXX : not implemented */
2663 spr_register(env
, SPR_RCPU_L2U_RBA2
, "L2U_RBA2",
2664 SPR_NOACCESS
, SPR_NOACCESS
,
2665 &spr_read_generic
, &spr_write_generic
,
2667 /* XXX : not implemented */
2668 spr_register(env
, SPR_RCPU_L2U_RBA3
, "L2U_RBA3",
2669 SPR_NOACCESS
, SPR_NOACCESS
,
2670 &spr_read_generic
, &spr_write_generic
,
2672 /* XXX : not implemented */
2673 spr_register(env
, SPR_RCPU_MI_RA0
, "MI_RA0",
2674 SPR_NOACCESS
, SPR_NOACCESS
,
2675 &spr_read_generic
, &spr_write_generic
,
2677 /* XXX : not implemented */
2678 spr_register(env
, SPR_RCPU_MI_RA1
, "MI_RA1",
2679 SPR_NOACCESS
, SPR_NOACCESS
,
2680 &spr_read_generic
, &spr_write_generic
,
2682 /* XXX : not implemented */
2683 spr_register(env
, SPR_RCPU_MI_RA2
, "MI_RA2",
2684 SPR_NOACCESS
, SPR_NOACCESS
,
2685 &spr_read_generic
, &spr_write_generic
,
2687 /* XXX : not implemented */
2688 spr_register(env
, SPR_RCPU_MI_RA3
, "MI_RA3",
2689 SPR_NOACCESS
, SPR_NOACCESS
,
2690 &spr_read_generic
, &spr_write_generic
,
2692 /* XXX : not implemented */
2693 spr_register(env
, SPR_RCPU_L2U_RA0
, "L2U_RA0",
2694 SPR_NOACCESS
, SPR_NOACCESS
,
2695 &spr_read_generic
, &spr_write_generic
,
2697 /* XXX : not implemented */
2698 spr_register(env
, SPR_RCPU_L2U_RA1
, "L2U_RA1",
2699 SPR_NOACCESS
, SPR_NOACCESS
,
2700 &spr_read_generic
, &spr_write_generic
,
2702 /* XXX : not implemented */
2703 spr_register(env
, SPR_RCPU_L2U_RA2
, "L2U_RA2",
2704 SPR_NOACCESS
, SPR_NOACCESS
,
2705 &spr_read_generic
, &spr_write_generic
,
2707 /* XXX : not implemented */
2708 spr_register(env
, SPR_RCPU_L2U_RA3
, "L2U_RA3",
2709 SPR_NOACCESS
, SPR_NOACCESS
,
2710 &spr_read_generic
, &spr_write_generic
,
2712 /* XXX : not implemented */
2713 spr_register(env
, SPR_RCPU_FPECR
, "FPECR",
2714 SPR_NOACCESS
, SPR_NOACCESS
,
2715 &spr_read_generic
, &spr_write_generic
,
2719 static void gen_spr_8xx(CPUPPCState
*env
)
2721 /* XXX : not implemented */
2722 spr_register(env
, SPR_MPC_IC_CST
, "IC_CST",
2723 SPR_NOACCESS
, SPR_NOACCESS
,
2724 &spr_read_generic
, &spr_write_generic
,
2726 /* XXX : not implemented */
2727 spr_register(env
, SPR_MPC_IC_ADR
, "IC_ADR",
2728 SPR_NOACCESS
, SPR_NOACCESS
,
2729 &spr_read_generic
, &spr_write_generic
,
2731 /* XXX : not implemented */
2732 spr_register(env
, SPR_MPC_IC_DAT
, "IC_DAT",
2733 SPR_NOACCESS
, SPR_NOACCESS
,
2734 &spr_read_generic
, &spr_write_generic
,
2736 /* XXX : not implemented */
2737 spr_register(env
, SPR_MPC_DC_CST
, "DC_CST",
2738 SPR_NOACCESS
, SPR_NOACCESS
,
2739 &spr_read_generic
, &spr_write_generic
,
2741 /* XXX : not implemented */
2742 spr_register(env
, SPR_MPC_DC_ADR
, "DC_ADR",
2743 SPR_NOACCESS
, SPR_NOACCESS
,
2744 &spr_read_generic
, &spr_write_generic
,
2746 /* XXX : not implemented */
2747 spr_register(env
, SPR_MPC_DC_DAT
, "DC_DAT",
2748 SPR_NOACCESS
, SPR_NOACCESS
,
2749 &spr_read_generic
, &spr_write_generic
,
2751 /* XXX : not implemented */
2752 spr_register(env
, SPR_MPC_MI_CTR
, "MI_CTR",
2753 SPR_NOACCESS
, SPR_NOACCESS
,
2754 &spr_read_generic
, &spr_write_generic
,
2756 /* XXX : not implemented */
2757 spr_register(env
, SPR_MPC_MI_AP
, "MI_AP",
2758 SPR_NOACCESS
, SPR_NOACCESS
,
2759 &spr_read_generic
, &spr_write_generic
,
2761 /* XXX : not implemented */
2762 spr_register(env
, SPR_MPC_MI_EPN
, "MI_EPN",
2763 SPR_NOACCESS
, SPR_NOACCESS
,
2764 &spr_read_generic
, &spr_write_generic
,
2766 /* XXX : not implemented */
2767 spr_register(env
, SPR_MPC_MI_TWC
, "MI_TWC",
2768 SPR_NOACCESS
, SPR_NOACCESS
,
2769 &spr_read_generic
, &spr_write_generic
,
2771 /* XXX : not implemented */
2772 spr_register(env
, SPR_MPC_MI_RPN
, "MI_RPN",
2773 SPR_NOACCESS
, SPR_NOACCESS
,
2774 &spr_read_generic
, &spr_write_generic
,
2776 /* XXX : not implemented */
2777 spr_register(env
, SPR_MPC_MI_DBCAM
, "MI_DBCAM",
2778 SPR_NOACCESS
, SPR_NOACCESS
,
2779 &spr_read_generic
, &spr_write_generic
,
2781 /* XXX : not implemented */
2782 spr_register(env
, SPR_MPC_MI_DBRAM0
, "MI_DBRAM0",
2783 SPR_NOACCESS
, SPR_NOACCESS
,
2784 &spr_read_generic
, &spr_write_generic
,
2786 /* XXX : not implemented */
2787 spr_register(env
, SPR_MPC_MI_DBRAM1
, "MI_DBRAM1",
2788 SPR_NOACCESS
, SPR_NOACCESS
,
2789 &spr_read_generic
, &spr_write_generic
,
2791 /* XXX : not implemented */
2792 spr_register(env
, SPR_MPC_MD_CTR
, "MD_CTR",
2793 SPR_NOACCESS
, SPR_NOACCESS
,
2794 &spr_read_generic
, &spr_write_generic
,
2796 /* XXX : not implemented */
2797 spr_register(env
, SPR_MPC_MD_CASID
, "MD_CASID",
2798 SPR_NOACCESS
, SPR_NOACCESS
,
2799 &spr_read_generic
, &spr_write_generic
,
2801 /* XXX : not implemented */
2802 spr_register(env
, SPR_MPC_MD_AP
, "MD_AP",
2803 SPR_NOACCESS
, SPR_NOACCESS
,
2804 &spr_read_generic
, &spr_write_generic
,
2806 /* XXX : not implemented */
2807 spr_register(env
, SPR_MPC_MD_EPN
, "MD_EPN",
2808 SPR_NOACCESS
, SPR_NOACCESS
,
2809 &spr_read_generic
, &spr_write_generic
,
2811 /* XXX : not implemented */
2812 spr_register(env
, SPR_MPC_MD_TWB
, "MD_TWB",
2813 SPR_NOACCESS
, SPR_NOACCESS
,
2814 &spr_read_generic
, &spr_write_generic
,
2816 /* XXX : not implemented */
2817 spr_register(env
, SPR_MPC_MD_TWC
, "MD_TWC",
2818 SPR_NOACCESS
, SPR_NOACCESS
,
2819 &spr_read_generic
, &spr_write_generic
,
2821 /* XXX : not implemented */
2822 spr_register(env
, SPR_MPC_MD_RPN
, "MD_RPN",
2823 SPR_NOACCESS
, SPR_NOACCESS
,
2824 &spr_read_generic
, &spr_write_generic
,
2826 /* XXX : not implemented */
2827 spr_register(env
, SPR_MPC_MD_TW
, "MD_TW",
2828 SPR_NOACCESS
, SPR_NOACCESS
,
2829 &spr_read_generic
, &spr_write_generic
,
2831 /* XXX : not implemented */
2832 spr_register(env
, SPR_MPC_MD_DBCAM
, "MD_DBCAM",
2833 SPR_NOACCESS
, SPR_NOACCESS
,
2834 &spr_read_generic
, &spr_write_generic
,
2836 /* XXX : not implemented */
2837 spr_register(env
, SPR_MPC_MD_DBRAM0
, "MD_DBRAM0",
2838 SPR_NOACCESS
, SPR_NOACCESS
,
2839 &spr_read_generic
, &spr_write_generic
,
2841 /* XXX : not implemented */
2842 spr_register(env
, SPR_MPC_MD_DBRAM1
, "MD_DBRAM1",
2843 SPR_NOACCESS
, SPR_NOACCESS
,
2844 &spr_read_generic
, &spr_write_generic
,
2849 * AMR => SPR 29 (Power 2.04)
2850 * CTRL => SPR 136 (Power 2.04)
2851 * CTRL => SPR 152 (Power 2.04)
2852 * SCOMC => SPR 276 (64 bits ?)
2853 * SCOMD => SPR 277 (64 bits ?)
2854 * TBU40 => SPR 286 (Power 2.04 hypv)
2855 * HSPRG0 => SPR 304 (Power 2.04 hypv)
2856 * HSPRG1 => SPR 305 (Power 2.04 hypv)
2857 * HDSISR => SPR 306 (Power 2.04 hypv)
2858 * HDAR => SPR 307 (Power 2.04 hypv)
2859 * PURR => SPR 309 (Power 2.04 hypv)
2860 * HDEC => SPR 310 (Power 2.04 hypv)
2861 * HIOR => SPR 311 (hypv)
2862 * RMOR => SPR 312 (970)
2863 * HRMOR => SPR 313 (Power 2.04 hypv)
2864 * HSRR0 => SPR 314 (Power 2.04 hypv)
2865 * HSRR1 => SPR 315 (Power 2.04 hypv)
2866 * LPIDR => SPR 317 (970)
2867 * EPR => SPR 702 (Power 2.04 emb)
2868 * perf => 768-783 (Power 2.04)
2869 * perf => 784-799 (Power 2.04)
2870 * PPR => SPR 896 (Power 2.04)
2871 * DABRX => 1015 (Power 2.04 hypv)
2872 * FPECR => SPR 1022 (?)
2873 * ... and more (thermal management, performance counters, ...)
2876 /*****************************************************************************/
2877 /* Exception vectors models */
2878 static void init_excp_4xx_real(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_EXTERNAL
] = 0x00000500;
2884 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2885 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2886 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2887 env
->excp_vectors
[POWERPC_EXCP_PIT
] = 0x00001000;
2888 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00001010;
2889 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001020;
2890 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00002000;
2891 env
->ivor_mask
= 0x0000FFF0UL
;
2892 env
->ivpr_mask
= 0xFFFF0000UL
;
2893 /* Hardware reset vector */
2894 env
->hreset_vector
= 0xFFFFFFFCUL
;
2898 static void init_excp_4xx_softmmu(CPUPPCState
*env
)
2900 #if !defined(CONFIG_USER_ONLY)
2901 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000100;
2902 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2903 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2904 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2905 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2906 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2907 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2908 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2909 env
->excp_vectors
[POWERPC_EXCP_PIT
] = 0x00001000;
2910 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00001010;
2911 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001020;
2912 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00001100;
2913 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00001200;
2914 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00002000;
2915 env
->ivor_mask
= 0x0000FFF0UL
;
2916 env
->ivpr_mask
= 0xFFFF0000UL
;
2917 /* Hardware reset vector */
2918 env
->hreset_vector
= 0xFFFFFFFCUL
;
2922 static void init_excp_MPC5xx(CPUPPCState
*env
)
2924 #if !defined(CONFIG_USER_ONLY)
2925 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2926 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2927 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2928 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2929 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2930 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000900;
2931 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2932 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2933 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2934 env
->excp_vectors
[POWERPC_EXCP_FPA
] = 0x00000E00;
2935 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001000;
2936 env
->excp_vectors
[POWERPC_EXCP_DABR
] = 0x00001C00;
2937 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001C00;
2938 env
->excp_vectors
[POWERPC_EXCP_MEXTBR
] = 0x00001E00;
2939 env
->excp_vectors
[POWERPC_EXCP_NMEXTBR
] = 0x00001F00;
2940 env
->ivor_mask
= 0x0000FFF0UL
;
2941 env
->ivpr_mask
= 0xFFFF0000UL
;
2942 /* Hardware reset vector */
2943 env
->hreset_vector
= 0x00000100UL
;
2947 static void init_excp_MPC8xx(CPUPPCState
*env
)
2949 #if !defined(CONFIG_USER_ONLY)
2950 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2951 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2952 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2953 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2954 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2955 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2956 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2957 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000900;
2958 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2959 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2960 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2961 env
->excp_vectors
[POWERPC_EXCP_FPA
] = 0x00000E00;
2962 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001000;
2963 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00001100;
2964 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00001200;
2965 env
->excp_vectors
[POWERPC_EXCP_ITLBE
] = 0x00001300;
2966 env
->excp_vectors
[POWERPC_EXCP_DTLBE
] = 0x00001400;
2967 env
->excp_vectors
[POWERPC_EXCP_DABR
] = 0x00001C00;
2968 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001C00;
2969 env
->excp_vectors
[POWERPC_EXCP_MEXTBR
] = 0x00001E00;
2970 env
->excp_vectors
[POWERPC_EXCP_NMEXTBR
] = 0x00001F00;
2971 env
->ivor_mask
= 0x0000FFF0UL
;
2972 env
->ivpr_mask
= 0xFFFF0000UL
;
2973 /* Hardware reset vector */
2974 env
->hreset_vector
= 0x00000100UL
;
2978 static void init_excp_G2(CPUPPCState
*env
)
2980 #if !defined(CONFIG_USER_ONLY)
2981 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2982 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2983 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2984 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2985 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2986 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2987 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2988 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
2989 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2990 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000A00;
2991 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2992 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2993 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
2994 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
2995 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
2996 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
2997 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
2998 /* Hardware reset vector */
2999 env
->hreset_vector
= 0x00000100UL
;
3003 static void init_excp_e200(CPUPPCState
*env
, target_ulong ivpr_mask
)
3005 #if !defined(CONFIG_USER_ONLY)
3006 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000FFC;
3007 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000000;
3008 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000000;
3009 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000000;
3010 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000000;
3011 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000000;
3012 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000000;
3013 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000000;
3014 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000000;
3015 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000000;
3016 env
->excp_vectors
[POWERPC_EXCP_APU
] = 0x00000000;
3017 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000000;
3018 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00000000;
3019 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00000000;
3020 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00000000;
3021 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00000000;
3022 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00000000;
3023 env
->excp_vectors
[POWERPC_EXCP_SPEU
] = 0x00000000;
3024 env
->excp_vectors
[POWERPC_EXCP_EFPDI
] = 0x00000000;
3025 env
->excp_vectors
[POWERPC_EXCP_EFPRI
] = 0x00000000;
3026 env
->ivor_mask
= 0x0000FFF7UL
;
3027 env
->ivpr_mask
= ivpr_mask
;
3028 /* Hardware reset vector */
3029 env
->hreset_vector
= 0xFFFFFFFCUL
;
3033 static void init_excp_BookE(CPUPPCState
*env
)
3035 #if !defined(CONFIG_USER_ONLY)
3036 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000000;
3037 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000000;
3038 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000000;
3039 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000000;
3040 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000000;
3041 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000000;
3042 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000000;
3043 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000000;
3044 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000000;
3045 env
->excp_vectors
[POWERPC_EXCP_APU
] = 0x00000000;
3046 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000000;
3047 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00000000;
3048 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00000000;
3049 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00000000;
3050 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00000000;
3051 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00000000;
3052 env
->ivor_mask
= 0x0000FFF0UL
;
3053 env
->ivpr_mask
= 0xFFFF0000UL
;
3054 /* Hardware reset vector */
3055 env
->hreset_vector
= 0xFFFFFFFCUL
;
3059 static void init_excp_601(CPUPPCState
*env
)
3061 #if !defined(CONFIG_USER_ONLY)
3062 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3063 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3064 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3065 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3066 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3067 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3068 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3069 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3070 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3071 env
->excp_vectors
[POWERPC_EXCP_IO
] = 0x00000A00;
3072 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3073 env
->excp_vectors
[POWERPC_EXCP_RUNM
] = 0x00002000;
3074 /* Hardware reset vector */
3075 env
->hreset_vector
= 0x00000100UL
;
3079 static void init_excp_602(CPUPPCState
*env
)
3081 #if !defined(CONFIG_USER_ONLY)
3082 /* XXX: exception prefix has a special behavior on 602 */
3083 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3084 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3085 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3086 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3087 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3088 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3089 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3090 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3091 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3092 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3093 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3094 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3095 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3096 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3097 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3098 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3099 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001500;
3100 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001600;
3101 /* Hardware reset vector */
3102 env
->hreset_vector
= 0x00000100UL
;
3106 static void init_excp_603(CPUPPCState
*env
)
3108 #if !defined(CONFIG_USER_ONLY)
3109 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3110 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3111 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3112 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3113 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3114 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3115 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3116 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3117 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3118 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3119 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3120 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3121 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3122 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3123 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3124 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3125 /* Hardware reset vector */
3126 env
->hreset_vector
= 0x00000100UL
;
3130 static void init_excp_604(CPUPPCState
*env
)
3132 #if !defined(CONFIG_USER_ONLY)
3133 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3134 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3135 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3136 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3137 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3138 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3139 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3140 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3141 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3142 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3143 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3144 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3145 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3146 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3147 /* Hardware reset vector */
3148 env
->hreset_vector
= 0x00000100UL
;
3152 static void init_excp_7x0(CPUPPCState
*env
)
3154 #if !defined(CONFIG_USER_ONLY)
3155 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3156 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3157 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3158 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3159 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3160 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3161 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3162 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3163 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3164 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3165 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3166 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3167 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3168 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3169 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3170 /* Hardware reset vector */
3171 env
->hreset_vector
= 0x00000100UL
;
3175 static void init_excp_750cl(CPUPPCState
*env
)
3177 #if !defined(CONFIG_USER_ONLY)
3178 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3179 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3180 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3181 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3182 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3183 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3184 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3185 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3186 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3187 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3188 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3189 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3190 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3191 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3192 /* Hardware reset vector */
3193 env
->hreset_vector
= 0x00000100UL
;
3197 static void init_excp_750cx(CPUPPCState
*env
)
3199 #if !defined(CONFIG_USER_ONLY)
3200 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3201 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3202 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3203 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3204 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3205 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3206 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3207 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3208 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3209 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3210 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3211 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3212 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3213 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3214 /* Hardware reset vector */
3215 env
->hreset_vector
= 0x00000100UL
;
3219 /* XXX: Check if this is correct */
3220 static void init_excp_7x5(CPUPPCState
*env
)
3222 #if !defined(CONFIG_USER_ONLY)
3223 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3224 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3225 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3226 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3227 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3228 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3229 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3230 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3231 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3232 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3233 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3234 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3235 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3236 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3237 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3238 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3239 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3240 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3241 /* Hardware reset vector */
3242 env
->hreset_vector
= 0x00000100UL
;
3246 static void init_excp_7400(CPUPPCState
*env
)
3248 #if !defined(CONFIG_USER_ONLY)
3249 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3250 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3251 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3252 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3253 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3254 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3255 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3256 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3257 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3258 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3259 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3260 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3261 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3262 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3263 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3264 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001600;
3265 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3266 /* Hardware reset vector */
3267 env
->hreset_vector
= 0x00000100UL
;
3271 static void init_excp_7450(CPUPPCState
*env
)
3273 #if !defined(CONFIG_USER_ONLY)
3274 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3275 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3276 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3277 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3278 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3279 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3280 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3281 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3282 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3283 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3284 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3285 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3286 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3287 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3288 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3289 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3290 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3291 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3292 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001600;
3293 /* Hardware reset vector */
3294 env
->hreset_vector
= 0x00000100UL
;
3298 #if defined(TARGET_PPC64)
3299 static void init_excp_970(CPUPPCState
*env
)
3301 #if !defined(CONFIG_USER_ONLY)
3302 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3303 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3304 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3305 env
->excp_vectors
[POWERPC_EXCP_DSEG
] = 0x00000380;
3306 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3307 env
->excp_vectors
[POWERPC_EXCP_ISEG
] = 0x00000480;
3308 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3309 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3310 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3311 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3312 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3313 env
->excp_vectors
[POWERPC_EXCP_HDECR
] = 0x00000980;
3314 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3315 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3316 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3317 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3318 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3319 env
->excp_vectors
[POWERPC_EXCP_MAINT
] = 0x00001600;
3320 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001700;
3321 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001800;
3322 /* Hardware reset vector */
3323 env
->hreset_vector
= 0x0000000000000100ULL
;
3327 static void init_excp_POWER7(CPUPPCState
*env
)
3329 #if !defined(CONFIG_USER_ONLY)
3330 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3331 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3332 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3333 env
->excp_vectors
[POWERPC_EXCP_DSEG
] = 0x00000380;
3334 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3335 env
->excp_vectors
[POWERPC_EXCP_ISEG
] = 0x00000480;
3336 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3337 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3338 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3339 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3340 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3341 env
->excp_vectors
[POWERPC_EXCP_HDECR
] = 0x00000980;
3342 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3343 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3344 env
->excp_vectors
[POWERPC_EXCP_HDSI
] = 0x00000E00;
3345 env
->excp_vectors
[POWERPC_EXCP_HISI
] = 0x00000E20;
3346 env
->excp_vectors
[POWERPC_EXCP_HV_EMU
] = 0x00000E40;
3347 env
->excp_vectors
[POWERPC_EXCP_HV_MAINT
] = 0x00000E60;
3348 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3349 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3350 env
->excp_vectors
[POWERPC_EXCP_VSXU
] = 0x00000F40;
3351 /* Hardware reset vector */
3352 env
->hreset_vector
= 0x0000000000000100ULL
;
3356 static void init_excp_POWER8(CPUPPCState
*env
)
3358 init_excp_POWER7(env
);
3360 #if !defined(CONFIG_USER_ONLY)
3361 env
->excp_vectors
[POWERPC_EXCP_SDOOR
] = 0x00000A00;
3362 env
->excp_vectors
[POWERPC_EXCP_FU
] = 0x00000F60;
3363 env
->excp_vectors
[POWERPC_EXCP_HV_FU
] = 0x00000F80;
3364 env
->excp_vectors
[POWERPC_EXCP_SDOOR_HV
] = 0x00000E80;
3368 static void init_excp_POWER9(CPUPPCState
*env
)
3370 init_excp_POWER8(env
);
3372 #if !defined(CONFIG_USER_ONLY)
3373 env
->excp_vectors
[POWERPC_EXCP_HVIRT
] = 0x00000EA0;
3377 static void init_excp_POWER10(CPUPPCState
*env
)
3379 init_excp_POWER9(env
);
3384 /*****************************************************************************/
3385 /* Power management enable checks */
3386 static int check_pow_none(CPUPPCState
*env
)
3391 static int check_pow_nocheck(CPUPPCState
*env
)
3396 static int check_pow_hid0(CPUPPCState
*env
)
3398 if (env
->spr
[SPR_HID0
] & 0x00E00000) {
3405 static int check_pow_hid0_74xx(CPUPPCState
*env
)
3407 if (env
->spr
[SPR_HID0
] & 0x00600000) {
3414 static bool ppc_cpu_interrupts_big_endian_always(PowerPCCPU
*cpu
)
3420 static bool ppc_cpu_interrupts_big_endian_lpcr(PowerPCCPU
*cpu
)
3422 return !(cpu
->env
.spr
[SPR_LPCR
] & LPCR_ILE
);
3426 /*****************************************************************************/
3427 /* PowerPC implementations definitions */
3429 #define POWERPC_FAMILY(_name) \
3431 glue(glue(ppc_, _name), _cpu_family_class_init)(ObjectClass *, void *); \
3433 static const TypeInfo \
3434 glue(glue(ppc_, _name), _cpu_family_type_info) = { \
3435 .name = stringify(_name) "-family-" TYPE_POWERPC_CPU, \
3436 .parent = TYPE_POWERPC_CPU, \
3438 .class_init = glue(glue(ppc_, _name), _cpu_family_class_init), \
3441 static void glue(glue(ppc_, _name), _cpu_family_register_types)(void) \
3443 type_register_static( \
3444 &glue(glue(ppc_, _name), _cpu_family_type_info)); \
3447 type_init(glue(glue(ppc_, _name), _cpu_family_register_types)) \
3449 static void glue(glue(ppc_, _name), _cpu_family_class_init)
3451 static void init_proc_401(CPUPPCState
*env
)
3454 gen_spr_401_403(env
);
3456 init_excp_4xx_real(env
);
3457 env
->dcache_line_size
= 32;
3458 env
->icache_line_size
= 32;
3459 /* Allocate hardware IRQ controller */
3460 ppc40x_irq_init(env_archcpu(env
));
3462 SET_FIT_PERIOD(12, 16, 20, 24);
3463 SET_WDT_PERIOD(16, 20, 24, 28);
3466 POWERPC_FAMILY(401)(ObjectClass
*oc
, void *data
)
3468 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3469 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3471 dc
->desc
= "PowerPC 401";
3472 pcc
->init_proc
= init_proc_401
;
3473 pcc
->check_pow
= check_pow_nocheck
;
3474 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3475 PPC_WRTEE
| PPC_DCR
|
3476 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3478 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3479 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3480 pcc
->msr_mask
= (1ull << MSR_KEY
) |
3489 pcc
->mmu_model
= POWERPC_MMU_REAL
;
3490 pcc
->excp_model
= POWERPC_EXCP_40x
;
3491 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3492 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3493 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3494 POWERPC_FLAG_BUS_CLK
;
3497 static void init_proc_401x2(CPUPPCState
*env
)
3500 gen_spr_401_403(env
);
3502 gen_spr_compress(env
);
3503 /* Memory management */
3504 #if !defined(CONFIG_USER_ONLY)
3508 env
->tlb_type
= TLB_EMB
;
3510 init_excp_4xx_softmmu(env
);
3511 env
->dcache_line_size
= 32;
3512 env
->icache_line_size
= 32;
3513 /* Allocate hardware IRQ controller */
3514 ppc40x_irq_init(env_archcpu(env
));
3516 SET_FIT_PERIOD(12, 16, 20, 24);
3517 SET_WDT_PERIOD(16, 20, 24, 28);
3520 POWERPC_FAMILY(401x2
)(ObjectClass
*oc
, void *data
)
3522 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3523 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3525 dc
->desc
= "PowerPC 401x2";
3526 pcc
->init_proc
= init_proc_401x2
;
3527 pcc
->check_pow
= check_pow_nocheck
;
3528 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3529 PPC_DCR
| PPC_WRTEE
|
3530 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3531 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3532 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3533 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3534 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3535 pcc
->msr_mask
= (1ull << 20) |
3547 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3548 pcc
->excp_model
= POWERPC_EXCP_40x
;
3549 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3550 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3551 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3552 POWERPC_FLAG_BUS_CLK
;
3555 static void init_proc_401x3(CPUPPCState
*env
)
3558 gen_spr_401_403(env
);
3561 gen_spr_compress(env
);
3562 init_excp_4xx_softmmu(env
);
3563 env
->dcache_line_size
= 32;
3564 env
->icache_line_size
= 32;
3565 /* Allocate hardware IRQ controller */
3566 ppc40x_irq_init(env_archcpu(env
));
3568 SET_FIT_PERIOD(12, 16, 20, 24);
3569 SET_WDT_PERIOD(16, 20, 24, 28);
3572 POWERPC_FAMILY(401x3
)(ObjectClass
*oc
, void *data
)
3574 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3575 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3577 dc
->desc
= "PowerPC 401x3";
3578 pcc
->init_proc
= init_proc_401x3
;
3579 pcc
->check_pow
= check_pow_nocheck
;
3580 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3581 PPC_DCR
| PPC_WRTEE
|
3582 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3583 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3584 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3585 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3586 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3587 pcc
->msr_mask
= (1ull << 20) |
3600 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3601 pcc
->excp_model
= POWERPC_EXCP_40x
;
3602 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3603 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3604 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3605 POWERPC_FLAG_BUS_CLK
;
3608 static void init_proc_IOP480(CPUPPCState
*env
)
3611 gen_spr_401_403(env
);
3613 gen_spr_compress(env
);
3614 /* Memory management */
3615 #if !defined(CONFIG_USER_ONLY)
3619 env
->tlb_type
= TLB_EMB
;
3621 init_excp_4xx_softmmu(env
);
3622 env
->dcache_line_size
= 32;
3623 env
->icache_line_size
= 32;
3624 /* Allocate hardware IRQ controller */
3625 ppc40x_irq_init(env_archcpu(env
));
3627 SET_FIT_PERIOD(8, 12, 16, 20);
3628 SET_WDT_PERIOD(16, 20, 24, 28);
3631 POWERPC_FAMILY(IOP480
)(ObjectClass
*oc
, void *data
)
3633 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3634 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3636 dc
->desc
= "IOP480";
3637 pcc
->init_proc
= init_proc_IOP480
;
3638 pcc
->check_pow
= check_pow_nocheck
;
3639 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3640 PPC_DCR
| PPC_WRTEE
|
3641 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3642 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3643 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3644 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3645 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3646 pcc
->msr_mask
= (1ull << 20) |
3658 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3659 pcc
->excp_model
= POWERPC_EXCP_40x
;
3660 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3661 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3662 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3663 POWERPC_FLAG_BUS_CLK
;
3666 static void init_proc_403(CPUPPCState
*env
)
3669 gen_spr_401_403(env
);
3671 gen_spr_403_real(env
);
3672 init_excp_4xx_real(env
);
3673 env
->dcache_line_size
= 32;
3674 env
->icache_line_size
= 32;
3675 /* Allocate hardware IRQ controller */
3676 ppc40x_irq_init(env_archcpu(env
));
3678 SET_FIT_PERIOD(8, 12, 16, 20);
3679 SET_WDT_PERIOD(16, 20, 24, 28);
3682 POWERPC_FAMILY(403)(ObjectClass
*oc
, void *data
)
3684 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3685 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3687 dc
->desc
= "PowerPC 403";
3688 pcc
->init_proc
= init_proc_403
;
3689 pcc
->check_pow
= check_pow_nocheck
;
3690 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3691 PPC_DCR
| PPC_WRTEE
|
3692 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3694 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3695 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3696 pcc
->msr_mask
= (1ull << MSR_POW
) |
3705 pcc
->mmu_model
= POWERPC_MMU_REAL
;
3706 pcc
->excp_model
= POWERPC_EXCP_40x
;
3707 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3708 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3709 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_PX
|
3710 POWERPC_FLAG_BUS_CLK
;
3713 static void init_proc_403GCX(CPUPPCState
*env
)
3716 gen_spr_401_403(env
);
3718 gen_spr_403_real(env
);
3719 gen_spr_403_mmu(env
);
3720 /* Bus access control */
3721 /* not emulated, as QEMU never does speculative access */
3722 spr_register(env
, SPR_40x_SGR
, "SGR",
3723 SPR_NOACCESS
, SPR_NOACCESS
,
3724 &spr_read_generic
, &spr_write_generic
,
3726 /* not emulated, as QEMU do not emulate caches */
3727 spr_register(env
, SPR_40x_DCWR
, "DCWR",
3728 SPR_NOACCESS
, SPR_NOACCESS
,
3729 &spr_read_generic
, &spr_write_generic
,
3731 /* Memory management */
3732 #if !defined(CONFIG_USER_ONLY)
3736 env
->tlb_type
= TLB_EMB
;
3738 init_excp_4xx_softmmu(env
);
3739 env
->dcache_line_size
= 32;
3740 env
->icache_line_size
= 32;
3741 /* Allocate hardware IRQ controller */
3742 ppc40x_irq_init(env_archcpu(env
));
3744 SET_FIT_PERIOD(8, 12, 16, 20);
3745 SET_WDT_PERIOD(16, 20, 24, 28);
3748 POWERPC_FAMILY(403GCX
)(ObjectClass
*oc
, void *data
)
3750 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3751 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3753 dc
->desc
= "PowerPC 403 GCX";
3754 pcc
->init_proc
= init_proc_403GCX
;
3755 pcc
->check_pow
= check_pow_nocheck
;
3756 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3757 PPC_DCR
| PPC_WRTEE
|
3758 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3760 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3761 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3762 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3763 pcc
->msr_mask
= (1ull << MSR_POW
) |
3772 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3773 pcc
->excp_model
= POWERPC_EXCP_40x
;
3774 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3775 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3776 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_PX
|
3777 POWERPC_FLAG_BUS_CLK
;
3780 static void init_proc_405(CPUPPCState
*env
)
3786 /* Bus access control */
3787 /* not emulated, as QEMU never does speculative access */
3788 spr_register(env
, SPR_40x_SGR
, "SGR",
3789 SPR_NOACCESS
, SPR_NOACCESS
,
3790 &spr_read_generic
, &spr_write_generic
,
3792 /* not emulated, as QEMU do not emulate caches */
3793 spr_register(env
, SPR_40x_DCWR
, "DCWR",
3794 SPR_NOACCESS
, SPR_NOACCESS
,
3795 &spr_read_generic
, &spr_write_generic
,
3797 /* Memory management */
3798 #if !defined(CONFIG_USER_ONLY)
3802 env
->tlb_type
= TLB_EMB
;
3804 init_excp_4xx_softmmu(env
);
3805 env
->dcache_line_size
= 32;
3806 env
->icache_line_size
= 32;
3807 /* Allocate hardware IRQ controller */
3808 ppc40x_irq_init(env_archcpu(env
));
3810 SET_FIT_PERIOD(8, 12, 16, 20);
3811 SET_WDT_PERIOD(16, 20, 24, 28);
3814 POWERPC_FAMILY(405)(ObjectClass
*oc
, void *data
)
3816 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3817 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3819 dc
->desc
= "PowerPC 405";
3820 pcc
->init_proc
= init_proc_405
;
3821 pcc
->check_pow
= check_pow_nocheck
;
3822 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3823 PPC_DCR
| PPC_WRTEE
|
3824 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3825 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3826 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3827 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3828 PPC_4xx_COMMON
| PPC_405_MAC
| PPC_40x_EXCP
;
3829 pcc
->msr_mask
= (1ull << MSR_POW
) |
3838 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx
;
3839 pcc
->excp_model
= POWERPC_EXCP_40x
;
3840 pcc
->bus_model
= PPC_FLAGS_INPUT_405
;
3841 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3842 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3843 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3846 static void init_proc_440EP(CPUPPCState
*env
)
3850 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3852 gen_spr_usprgh(env
);
3853 /* Processor identification */
3854 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3855 SPR_NOACCESS
, SPR_NOACCESS
,
3856 &spr_read_generic
, &spr_write_pir
,
3858 /* XXX : not implemented */
3859 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
3860 SPR_NOACCESS
, SPR_NOACCESS
,
3861 &spr_read_generic
, &spr_write_generic
,
3863 /* XXX : not implemented */
3864 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
3865 SPR_NOACCESS
, SPR_NOACCESS
,
3866 &spr_read_generic
, &spr_write_generic
,
3868 /* XXX : not implemented */
3869 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
3870 SPR_NOACCESS
, SPR_NOACCESS
,
3871 &spr_read_generic
, &spr_write_generic
,
3873 /* XXX : not implemented */
3874 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
3875 SPR_NOACCESS
, SPR_NOACCESS
,
3876 &spr_read_generic
, &spr_write_generic
,
3878 /* XXX : not implemented */
3879 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
3880 SPR_NOACCESS
, SPR_NOACCESS
,
3881 &spr_read_generic
, &spr_write_generic
,
3883 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
3884 SPR_NOACCESS
, SPR_NOACCESS
,
3885 &spr_read_generic
, &spr_write_generic
,
3887 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
3888 SPR_NOACCESS
, SPR_NOACCESS
,
3889 &spr_read_generic
, &spr_write_generic
,
3891 /* XXX : not implemented */
3892 spr_register(env
, SPR_440_CCR1
, "CCR1",
3893 SPR_NOACCESS
, SPR_NOACCESS
,
3894 &spr_read_generic
, &spr_write_generic
,
3896 /* Memory management */
3897 #if !defined(CONFIG_USER_ONLY)
3901 env
->tlb_type
= TLB_EMB
;
3903 init_excp_BookE(env
);
3904 env
->dcache_line_size
= 32;
3905 env
->icache_line_size
= 32;
3906 ppc40x_irq_init(env_archcpu(env
));
3908 SET_FIT_PERIOD(12, 16, 20, 24);
3909 SET_WDT_PERIOD(20, 24, 28, 32);
3912 POWERPC_FAMILY(440EP
)(ObjectClass
*oc
, void *data
)
3914 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3915 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3917 dc
->desc
= "PowerPC 440 EP";
3918 pcc
->init_proc
= init_proc_440EP
;
3919 pcc
->check_pow
= check_pow_nocheck
;
3920 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3921 PPC_FLOAT
| PPC_FLOAT_FRES
| PPC_FLOAT_FSEL
|
3922 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
3924 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
3925 PPC_CACHE
| PPC_CACHE_ICBI
|
3926 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3927 PPC_MEM_TLBSYNC
| PPC_MFTB
|
3928 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3930 pcc
->msr_mask
= (1ull << MSR_POW
) |
3942 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3943 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3944 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3945 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3946 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3947 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3950 POWERPC_FAMILY(460EX
)(ObjectClass
*oc
, void *data
)
3952 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3953 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3955 dc
->desc
= "PowerPC 460 EX";
3956 pcc
->init_proc
= init_proc_440EP
;
3957 pcc
->check_pow
= check_pow_nocheck
;
3958 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3959 PPC_FLOAT
| PPC_FLOAT_FRES
| PPC_FLOAT_FSEL
|
3960 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
3962 PPC_DCR
| PPC_DCRX
| PPC_WRTEE
| PPC_RFMCI
|
3963 PPC_CACHE
| PPC_CACHE_ICBI
|
3964 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3965 PPC_MEM_TLBSYNC
| PPC_MFTB
|
3966 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3968 pcc
->msr_mask
= (1ull << MSR_POW
) |
3980 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3981 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3982 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3983 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3984 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3985 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3988 static void init_proc_440GP(CPUPPCState
*env
)
3992 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3994 gen_spr_usprgh(env
);
3995 /* Processor identification */
3996 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3997 SPR_NOACCESS
, SPR_NOACCESS
,
3998 &spr_read_generic
, &spr_write_pir
,
4000 /* XXX : not implemented */
4001 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4002 SPR_NOACCESS
, SPR_NOACCESS
,
4003 &spr_read_generic
, &spr_write_generic
,
4005 /* XXX : not implemented */
4006 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4007 SPR_NOACCESS
, SPR_NOACCESS
,
4008 &spr_read_generic
, &spr_write_generic
,
4010 /* XXX : not implemented */
4011 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
4012 SPR_NOACCESS
, SPR_NOACCESS
,
4013 &spr_read_generic
, &spr_write_generic
,
4015 /* XXX : not implemented */
4016 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
4017 SPR_NOACCESS
, SPR_NOACCESS
,
4018 &spr_read_generic
, &spr_write_generic
,
4020 /* Memory management */
4021 #if !defined(CONFIG_USER_ONLY)
4025 env
->tlb_type
= TLB_EMB
;
4027 init_excp_BookE(env
);
4028 env
->dcache_line_size
= 32;
4029 env
->icache_line_size
= 32;
4030 /* XXX: TODO: allocate internal IRQ controller */
4032 SET_FIT_PERIOD(12, 16, 20, 24);
4033 SET_WDT_PERIOD(20, 24, 28, 32);
4036 POWERPC_FAMILY(440GP
)(ObjectClass
*oc
, void *data
)
4038 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4039 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4041 dc
->desc
= "PowerPC 440 GP";
4042 pcc
->init_proc
= init_proc_440GP
;
4043 pcc
->check_pow
= check_pow_nocheck
;
4044 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4045 PPC_DCR
| PPC_DCRX
| PPC_WRTEE
| PPC_MFAPIDI
|
4046 PPC_CACHE
| PPC_CACHE_ICBI
|
4047 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4048 PPC_MEM_TLBSYNC
| PPC_TLBIVA
| PPC_MFTB
|
4049 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4051 pcc
->msr_mask
= (1ull << MSR_POW
) |
4063 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4064 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4065 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4066 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4067 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4068 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4071 static void init_proc_440x4(CPUPPCState
*env
)
4075 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
4077 gen_spr_usprgh(env
);
4078 /* Processor identification */
4079 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4080 SPR_NOACCESS
, SPR_NOACCESS
,
4081 &spr_read_generic
, &spr_write_pir
,
4083 /* XXX : not implemented */
4084 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4085 SPR_NOACCESS
, SPR_NOACCESS
,
4086 &spr_read_generic
, &spr_write_generic
,
4088 /* XXX : not implemented */
4089 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4090 SPR_NOACCESS
, SPR_NOACCESS
,
4091 &spr_read_generic
, &spr_write_generic
,
4093 /* XXX : not implemented */
4094 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
4095 SPR_NOACCESS
, SPR_NOACCESS
,
4096 &spr_read_generic
, &spr_write_generic
,
4098 /* XXX : not implemented */
4099 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
4100 SPR_NOACCESS
, SPR_NOACCESS
,
4101 &spr_read_generic
, &spr_write_generic
,
4103 /* Memory management */
4104 #if !defined(CONFIG_USER_ONLY)
4108 env
->tlb_type
= TLB_EMB
;
4110 init_excp_BookE(env
);
4111 env
->dcache_line_size
= 32;
4112 env
->icache_line_size
= 32;
4113 /* XXX: TODO: allocate internal IRQ controller */
4115 SET_FIT_PERIOD(12, 16, 20, 24);
4116 SET_WDT_PERIOD(20, 24, 28, 32);
4119 POWERPC_FAMILY(440x4
)(ObjectClass
*oc
, void *data
)
4121 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4122 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4124 dc
->desc
= "PowerPC 440x4";
4125 pcc
->init_proc
= init_proc_440x4
;
4126 pcc
->check_pow
= check_pow_nocheck
;
4127 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4128 PPC_DCR
| PPC_WRTEE
|
4129 PPC_CACHE
| PPC_CACHE_ICBI
|
4130 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4131 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4132 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4134 pcc
->msr_mask
= (1ull << MSR_POW
) |
4146 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4147 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4148 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4149 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4150 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4151 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4154 static void init_proc_440x5(CPUPPCState
*env
)
4158 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
4160 gen_spr_usprgh(env
);
4161 /* Processor identification */
4162 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4163 SPR_NOACCESS
, SPR_NOACCESS
,
4164 &spr_read_generic
, &spr_write_pir
,
4166 /* XXX : not implemented */
4167 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4168 SPR_NOACCESS
, SPR_NOACCESS
,
4169 &spr_read_generic
, &spr_write_generic
,
4171 /* XXX : not implemented */
4172 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4173 SPR_NOACCESS
, SPR_NOACCESS
,
4174 &spr_read_generic
, &spr_write_generic
,
4176 /* XXX : not implemented */
4177 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
4178 SPR_NOACCESS
, SPR_NOACCESS
,
4179 &spr_read_generic
, &spr_write_generic
,
4181 /* XXX : not implemented */
4182 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
4183 SPR_NOACCESS
, SPR_NOACCESS
,
4184 &spr_read_generic
, &spr_write_generic
,
4186 /* XXX : not implemented */
4187 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
4188 SPR_NOACCESS
, SPR_NOACCESS
,
4189 &spr_read_generic
, &spr_write_generic
,
4191 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
4192 SPR_NOACCESS
, SPR_NOACCESS
,
4193 &spr_read_generic
, &spr_write_generic
,
4195 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
4196 SPR_NOACCESS
, SPR_NOACCESS
,
4197 &spr_read_generic
, &spr_write_generic
,
4199 /* XXX : not implemented */
4200 spr_register(env
, SPR_440_CCR1
, "CCR1",
4201 SPR_NOACCESS
, SPR_NOACCESS
,
4202 &spr_read_generic
, &spr_write_generic
,
4204 /* Memory management */
4205 #if !defined(CONFIG_USER_ONLY)
4209 env
->tlb_type
= TLB_EMB
;
4211 init_excp_BookE(env
);
4212 env
->dcache_line_size
= 32;
4213 env
->icache_line_size
= 32;
4214 ppc40x_irq_init(env_archcpu(env
));
4216 SET_FIT_PERIOD(12, 16, 20, 24);
4217 SET_WDT_PERIOD(20, 24, 28, 32);
4220 POWERPC_FAMILY(440x5
)(ObjectClass
*oc
, void *data
)
4222 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4223 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4225 dc
->desc
= "PowerPC 440x5";
4226 pcc
->init_proc
= init_proc_440x5
;
4227 pcc
->check_pow
= check_pow_nocheck
;
4228 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4229 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
4230 PPC_CACHE
| PPC_CACHE_ICBI
|
4231 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4232 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4233 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4235 pcc
->msr_mask
= (1ull << MSR_POW
) |
4247 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4248 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4249 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4250 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4251 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4252 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4255 POWERPC_FAMILY(440x5wDFPU
)(ObjectClass
*oc
, void *data
)
4257 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4258 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4260 dc
->desc
= "PowerPC 440x5 with double precision FPU";
4261 pcc
->init_proc
= init_proc_440x5
;
4262 pcc
->check_pow
= check_pow_nocheck
;
4263 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4264 PPC_FLOAT
| PPC_FLOAT_FSQRT
|
4266 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
4267 PPC_CACHE
| PPC_CACHE_ICBI
|
4268 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4269 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4270 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4272 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
4273 pcc
->msr_mask
= (1ull << MSR_POW
) |
4285 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4286 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4287 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4288 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4289 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4290 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4293 static void init_proc_MPC5xx(CPUPPCState
*env
)
4297 gen_spr_5xx_8xx(env
);
4299 init_excp_MPC5xx(env
);
4300 env
->dcache_line_size
= 32;
4301 env
->icache_line_size
= 32;
4302 /* XXX: TODO: allocate internal IRQ controller */
4305 POWERPC_FAMILY(MPC5xx
)(ObjectClass
*oc
, void *data
)
4307 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4308 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4310 dc
->desc
= "Freescale 5xx cores (aka RCPU)";
4311 pcc
->init_proc
= init_proc_MPC5xx
;
4312 pcc
->check_pow
= check_pow_none
;
4313 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4314 PPC_MEM_EIEIO
| PPC_MEM_SYNC
|
4315 PPC_CACHE_ICBI
| PPC_FLOAT
| PPC_FLOAT_STFIWX
|
4317 pcc
->msr_mask
= (1ull << MSR_ILE
) |
4329 pcc
->mmu_model
= POWERPC_MMU_REAL
;
4330 pcc
->excp_model
= POWERPC_EXCP_603
;
4331 pcc
->bus_model
= PPC_FLAGS_INPUT_RCPU
;
4332 pcc
->bfd_mach
= bfd_mach_ppc_505
;
4333 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
4334 POWERPC_FLAG_BUS_CLK
;
4337 static void init_proc_MPC8xx(CPUPPCState
*env
)
4341 gen_spr_5xx_8xx(env
);
4343 init_excp_MPC8xx(env
);
4344 env
->dcache_line_size
= 32;
4345 env
->icache_line_size
= 32;
4346 /* XXX: TODO: allocate internal IRQ controller */
4349 POWERPC_FAMILY(MPC8xx
)(ObjectClass
*oc
, void *data
)
4351 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4352 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4354 dc
->desc
= "Freescale 8xx cores (aka PowerQUICC)";
4355 pcc
->init_proc
= init_proc_MPC8xx
;
4356 pcc
->check_pow
= check_pow_none
;
4357 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4358 PPC_MEM_EIEIO
| PPC_MEM_SYNC
|
4359 PPC_CACHE_ICBI
| PPC_MFTB
;
4360 pcc
->msr_mask
= (1ull << MSR_ILE
) |
4372 pcc
->mmu_model
= POWERPC_MMU_MPC8xx
;
4373 pcc
->excp_model
= POWERPC_EXCP_603
;
4374 pcc
->bus_model
= PPC_FLAGS_INPUT_RCPU
;
4375 pcc
->bfd_mach
= bfd_mach_ppc_860
;
4376 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
4377 POWERPC_FLAG_BUS_CLK
;
4380 /* Freescale 82xx cores (aka PowerQUICC-II) */
4382 static void init_proc_G2(CPUPPCState
*env
)
4384 gen_spr_ne_601(env
);
4386 gen_spr_G2_755(env
);
4390 /* External access control */
4391 /* XXX : not implemented */
4392 spr_register(env
, SPR_EAR
, "EAR",
4393 SPR_NOACCESS
, SPR_NOACCESS
,
4394 &spr_read_generic
, &spr_write_generic
,
4396 /* Hardware implementation register */
4397 /* XXX : not implemented */
4398 spr_register(env
, SPR_HID0
, "HID0",
4399 SPR_NOACCESS
, SPR_NOACCESS
,
4400 &spr_read_generic
, &spr_write_generic
,
4402 /* XXX : not implemented */
4403 spr_register(env
, SPR_HID1
, "HID1",
4404 SPR_NOACCESS
, SPR_NOACCESS
,
4405 &spr_read_generic
, &spr_write_generic
,
4407 /* XXX : not implemented */
4408 spr_register(env
, SPR_HID2
, "HID2",
4409 SPR_NOACCESS
, SPR_NOACCESS
,
4410 &spr_read_generic
, &spr_write_generic
,
4412 /* Memory management */
4415 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4417 env
->dcache_line_size
= 32;
4418 env
->icache_line_size
= 32;
4419 /* Allocate hardware IRQ controller */
4420 ppc6xx_irq_init(env_archcpu(env
));
4423 POWERPC_FAMILY(G2
)(ObjectClass
*oc
, void *data
)
4425 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4426 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4428 dc
->desc
= "PowerPC G2";
4429 pcc
->init_proc
= init_proc_G2
;
4430 pcc
->check_pow
= check_pow_hid0
;
4431 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4432 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4434 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4435 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4436 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4437 PPC_SEGMENT
| PPC_EXTERN
;
4438 pcc
->msr_mask
= (1ull << MSR_POW
) |
4439 (1ull << MSR_TGPR
) |
4453 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4454 pcc
->excp_model
= POWERPC_EXCP_G2
;
4455 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4456 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
4457 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4458 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4461 static void init_proc_G2LE(CPUPPCState
*env
)
4463 gen_spr_ne_601(env
);
4465 gen_spr_G2_755(env
);
4469 /* External access control */
4470 /* XXX : not implemented */
4471 spr_register(env
, SPR_EAR
, "EAR",
4472 SPR_NOACCESS
, SPR_NOACCESS
,
4473 &spr_read_generic
, &spr_write_generic
,
4475 /* Hardware implementation register */
4476 /* XXX : not implemented */
4477 spr_register(env
, SPR_HID0
, "HID0",
4478 SPR_NOACCESS
, SPR_NOACCESS
,
4479 &spr_read_generic
, &spr_write_generic
,
4481 /* XXX : not implemented */
4482 spr_register(env
, SPR_HID1
, "HID1",
4483 SPR_NOACCESS
, SPR_NOACCESS
,
4484 &spr_read_generic
, &spr_write_generic
,
4486 /* XXX : not implemented */
4487 spr_register(env
, SPR_HID2
, "HID2",
4488 SPR_NOACCESS
, SPR_NOACCESS
,
4489 &spr_read_generic
, &spr_write_generic
,
4492 /* Memory management */
4495 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4497 env
->dcache_line_size
= 32;
4498 env
->icache_line_size
= 32;
4499 /* Allocate hardware IRQ controller */
4500 ppc6xx_irq_init(env_archcpu(env
));
4503 POWERPC_FAMILY(G2LE
)(ObjectClass
*oc
, void *data
)
4505 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4506 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4508 dc
->desc
= "PowerPC G2LE";
4509 pcc
->init_proc
= init_proc_G2LE
;
4510 pcc
->check_pow
= check_pow_hid0
;
4511 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4512 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4514 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4515 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4516 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4517 PPC_SEGMENT
| PPC_EXTERN
;
4518 pcc
->msr_mask
= (1ull << MSR_POW
) |
4519 (1ull << MSR_TGPR
) |
4535 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4536 pcc
->excp_model
= POWERPC_EXCP_G2
;
4537 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4538 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
4539 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4540 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4543 static void init_proc_e200(CPUPPCState
*env
)
4547 gen_spr_BookE(env
, 0x000000070000FFFFULL
);
4548 /* XXX : not implemented */
4549 spr_register(env
, SPR_BOOKE_SPEFSCR
, "SPEFSCR",
4550 &spr_read_spefscr
, &spr_write_spefscr
,
4551 &spr_read_spefscr
, &spr_write_spefscr
,
4553 /* Memory management */
4554 gen_spr_BookE206(env
, 0x0000005D, NULL
, 0);
4555 /* XXX : not implemented */
4556 spr_register(env
, SPR_HID0
, "HID0",
4557 SPR_NOACCESS
, SPR_NOACCESS
,
4558 &spr_read_generic
, &spr_write_generic
,
4560 /* XXX : not implemented */
4561 spr_register(env
, SPR_HID1
, "HID1",
4562 SPR_NOACCESS
, SPR_NOACCESS
,
4563 &spr_read_generic
, &spr_write_generic
,
4565 /* XXX : not implemented */
4566 spr_register(env
, SPR_Exxx_ALTCTXCR
, "ALTCTXCR",
4567 SPR_NOACCESS
, SPR_NOACCESS
,
4568 &spr_read_generic
, &spr_write_generic
,
4570 /* XXX : not implemented */
4571 spr_register(env
, SPR_Exxx_BUCSR
, "BUCSR",
4572 SPR_NOACCESS
, SPR_NOACCESS
,
4573 &spr_read_generic
, &spr_write_generic
,
4575 /* XXX : not implemented */
4576 spr_register(env
, SPR_Exxx_CTXCR
, "CTXCR",
4577 SPR_NOACCESS
, SPR_NOACCESS
,
4578 &spr_read_generic
, &spr_write_generic
,
4580 /* XXX : not implemented */
4581 spr_register(env
, SPR_Exxx_DBCNT
, "DBCNT",
4582 SPR_NOACCESS
, SPR_NOACCESS
,
4583 &spr_read_generic
, &spr_write_generic
,
4585 /* XXX : not implemented */
4586 spr_register(env
, SPR_Exxx_DBCR3
, "DBCR3",
4587 SPR_NOACCESS
, SPR_NOACCESS
,
4588 &spr_read_generic
, &spr_write_generic
,
4590 /* XXX : not implemented */
4591 spr_register(env
, SPR_Exxx_L1CFG0
, "L1CFG0",
4592 &spr_read_generic
, SPR_NOACCESS
,
4593 &spr_read_generic
, SPR_NOACCESS
,
4595 /* XXX : not implemented */
4596 spr_register(env
, SPR_Exxx_L1CSR0
, "L1CSR0",
4597 SPR_NOACCESS
, SPR_NOACCESS
,
4598 &spr_read_generic
, &spr_write_generic
,
4600 /* XXX : not implemented */
4601 spr_register(env
, SPR_Exxx_L1FINV0
, "L1FINV0",
4602 SPR_NOACCESS
, SPR_NOACCESS
,
4603 &spr_read_generic
, &spr_write_generic
,
4605 /* XXX : not implemented */
4606 spr_register(env
, SPR_BOOKE_TLB0CFG
, "TLB0CFG",
4607 SPR_NOACCESS
, SPR_NOACCESS
,
4608 &spr_read_generic
, &spr_write_generic
,
4610 /* XXX : not implemented */
4611 spr_register(env
, SPR_BOOKE_TLB1CFG
, "TLB1CFG",
4612 SPR_NOACCESS
, SPR_NOACCESS
,
4613 &spr_read_generic
, &spr_write_generic
,
4615 /* XXX : not implemented */
4616 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4617 SPR_NOACCESS
, SPR_NOACCESS
,
4618 &spr_read_generic
, &spr_write_generic
,
4620 /* XXX : not implemented */
4621 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4622 SPR_NOACCESS
, SPR_NOACCESS
,
4623 &spr_read_generic
, &spr_write_generic
,
4625 /* XXX : not implemented */
4626 spr_register(env
, SPR_MMUCSR0
, "MMUCSR0",
4627 SPR_NOACCESS
, SPR_NOACCESS
,
4628 &spr_read_generic
, &spr_write_generic
,
4629 0x00000000); /* TOFIX */
4630 spr_register(env
, SPR_BOOKE_DSRR0
, "DSRR0",
4631 SPR_NOACCESS
, SPR_NOACCESS
,
4632 &spr_read_generic
, &spr_write_generic
,
4634 spr_register(env
, SPR_BOOKE_DSRR1
, "DSRR1",
4635 SPR_NOACCESS
, SPR_NOACCESS
,
4636 &spr_read_generic
, &spr_write_generic
,
4638 #if !defined(CONFIG_USER_ONLY)
4642 env
->tlb_type
= TLB_EMB
;
4644 init_excp_e200(env
, 0xFFFF0000UL
);
4645 env
->dcache_line_size
= 32;
4646 env
->icache_line_size
= 32;
4647 /* XXX: TODO: allocate internal IRQ controller */
4650 POWERPC_FAMILY(e200
)(ObjectClass
*oc
, void *data
)
4652 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4653 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4655 dc
->desc
= "e200 core";
4656 pcc
->init_proc
= init_proc_e200
;
4657 pcc
->check_pow
= check_pow_hid0
;
4659 * XXX: unimplemented instructions:
4666 * all SPE multiply-accumulate instructions
4668 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
4669 PPC_SPE
| PPC_SPE_SINGLE
|
4670 PPC_WRTEE
| PPC_RFDI
|
4671 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
4672 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4673 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
|
4675 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
4689 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
4690 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4691 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4692 pcc
->bfd_mach
= bfd_mach_ppc_860
;
4693 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
4694 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
4695 POWERPC_FLAG_BUS_CLK
;
4698 static void init_proc_e300(CPUPPCState
*env
)
4700 gen_spr_ne_601(env
);
4705 /* hardware implementation registers */
4706 /* XXX : not implemented */
4707 spr_register(env
, SPR_HID0
, "HID0",
4708 SPR_NOACCESS
, SPR_NOACCESS
,
4709 &spr_read_generic
, &spr_write_generic
,
4711 /* XXX : not implemented */
4712 spr_register(env
, SPR_HID1
, "HID1",
4713 SPR_NOACCESS
, SPR_NOACCESS
,
4714 &spr_read_generic
, &spr_write_generic
,
4716 /* XXX : not implemented */
4717 spr_register(env
, SPR_HID2
, "HID2",
4718 SPR_NOACCESS
, SPR_NOACCESS
,
4719 &spr_read_generic
, &spr_write_generic
,
4722 /* XXX : not implemented */
4723 spr_register(env
, SPR_DABR
, "DABR",
4724 SPR_NOACCESS
, SPR_NOACCESS
,
4725 &spr_read_generic
, &spr_write_generic
,
4727 /* XXX : not implemented */
4728 spr_register(env
, SPR_DABR2
, "DABR2",
4729 SPR_NOACCESS
, SPR_NOACCESS
,
4730 &spr_read_generic
, &spr_write_generic
,
4732 /* XXX : not implemented */
4733 spr_register(env
, SPR_IABR2
, "IABR2",
4734 SPR_NOACCESS
, SPR_NOACCESS
,
4735 &spr_read_generic
, &spr_write_generic
,
4737 /* XXX : not implemented */
4738 spr_register(env
, SPR_IBCR
, "IBCR",
4739 SPR_NOACCESS
, SPR_NOACCESS
,
4740 &spr_read_generic
, &spr_write_generic
,
4742 /* XXX : not implemented */
4743 spr_register(env
, SPR_DBCR
, "DBCR",
4744 SPR_NOACCESS
, SPR_NOACCESS
,
4745 &spr_read_generic
, &spr_write_generic
,
4747 /* Memory management */
4750 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4752 env
->dcache_line_size
= 32;
4753 env
->icache_line_size
= 32;
4754 /* Allocate hardware IRQ controller */
4755 ppc6xx_irq_init(env_archcpu(env
));
4758 POWERPC_FAMILY(e300
)(ObjectClass
*oc
, void *data
)
4760 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4761 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4763 dc
->desc
= "e300 core";
4764 pcc
->init_proc
= init_proc_e300
;
4765 pcc
->check_pow
= check_pow_hid0
;
4766 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4767 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4769 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4770 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4771 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4772 PPC_SEGMENT
| PPC_EXTERN
;
4773 pcc
->msr_mask
= (1ull << MSR_POW
) |
4774 (1ull << MSR_TGPR
) |
4790 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4791 pcc
->excp_model
= POWERPC_EXCP_603
;
4792 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4793 pcc
->bfd_mach
= bfd_mach_ppc_603
;
4794 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4795 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4798 #if !defined(CONFIG_USER_ONLY)
4799 static void spr_write_mas73(DisasContext
*ctx
, int sprn
, int gprn
)
4801 TCGv val
= tcg_temp_new();
4802 tcg_gen_ext32u_tl(val
, cpu_gpr
[gprn
]);
4803 gen_store_spr(SPR_BOOKE_MAS3
, val
);
4804 tcg_gen_shri_tl(val
, cpu_gpr
[gprn
], 32);
4805 gen_store_spr(SPR_BOOKE_MAS7
, val
);
4809 static void spr_read_mas73(DisasContext
*ctx
, int gprn
, int sprn
)
4811 TCGv mas7
= tcg_temp_new();
4812 TCGv mas3
= tcg_temp_new();
4813 gen_load_spr(mas7
, SPR_BOOKE_MAS7
);
4814 tcg_gen_shli_tl(mas7
, mas7
, 32);
4815 gen_load_spr(mas3
, SPR_BOOKE_MAS3
);
4816 tcg_gen_or_tl(cpu_gpr
[gprn
], mas3
, mas7
);
4817 tcg_temp_free(mas3
);
4818 tcg_temp_free(mas7
);
4823 enum fsl_e500_version
{
4831 static void init_proc_e500(CPUPPCState
*env
, int version
)
4833 uint32_t tlbncfg
[2];
4835 uint64_t ivpr_mask
= 0xFFFF0000ULL
;
4836 uint32_t l1cfg0
= 0x3800 /* 8 ways */
4837 | 0x0020; /* 32 kb */
4838 uint32_t l1cfg1
= 0x3800 /* 8 ways */
4839 | 0x0020; /* 32 kb */
4840 uint32_t mmucfg
= 0;
4841 #if !defined(CONFIG_USER_ONLY)
4848 * XXX The e500 doesn't implement IVOR7 and IVOR9, but doesn't
4849 * complain when accessing them.
4850 * gen_spr_BookE(env, 0x0000000F0000FD7FULL);
4856 ivor_mask
= 0x0000000F0000FFFFULL
;
4860 ivor_mask
= 0x000003FE0000FFFFULL
;
4863 ivor_mask
= 0x000003FF0000FFFFULL
;
4866 gen_spr_BookE(env
, ivor_mask
);
4867 gen_spr_usprg3(env
);
4868 /* Processor identification */
4869 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4870 SPR_NOACCESS
, SPR_NOACCESS
,
4871 &spr_read_generic
, &spr_write_pir
,
4873 /* XXX : not implemented */
4874 spr_register(env
, SPR_BOOKE_SPEFSCR
, "SPEFSCR",
4875 &spr_read_spefscr
, &spr_write_spefscr
,
4876 &spr_read_spefscr
, &spr_write_spefscr
,
4878 #if !defined(CONFIG_USER_ONLY)
4879 /* Memory management */
4885 tlbncfg
[0] = gen_tlbncfg(2, 1, 1, 0, 256);
4886 tlbncfg
[1] = gen_tlbncfg(16, 1, 9, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 16);
4889 tlbncfg
[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4890 tlbncfg
[1] = gen_tlbncfg(16, 1, 12, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 16);
4894 tlbncfg
[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4895 tlbncfg
[1] = gen_tlbncfg(64, 1, 12, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 64);
4900 tlbncfg
[0] = 0x08052400;
4901 tlbncfg
[1] = 0x40028040;
4904 cpu_abort(env_cpu(env
), "Unknown CPU: " TARGET_FMT_lx
"\n",
4912 env
->dcache_line_size
= 32;
4913 env
->icache_line_size
= 32;
4917 env
->dcache_line_size
= 64;
4918 env
->icache_line_size
= 64;
4919 l1cfg0
|= 0x1000000; /* 64 byte cache block size */
4920 l1cfg1
|= 0x1000000; /* 64 byte cache block size */
4923 env
->dcache_line_size
= 32;
4924 env
->icache_line_size
= 32;
4925 l1cfg0
|= 0x0F83820;
4926 l1cfg1
|= 0x0B83820;
4929 cpu_abort(env_cpu(env
), "Unknown CPU: " TARGET_FMT_lx
"\n",
4932 gen_spr_BookE206(env
, 0x000000DF, tlbncfg
, mmucfg
);
4933 /* XXX : not implemented */
4934 spr_register(env
, SPR_HID0
, "HID0",
4935 SPR_NOACCESS
, SPR_NOACCESS
,
4936 &spr_read_generic
, &spr_write_generic
,
4938 /* XXX : not implemented */
4939 spr_register(env
, SPR_HID1
, "HID1",
4940 SPR_NOACCESS
, SPR_NOACCESS
,
4941 &spr_read_generic
, &spr_write_generic
,
4943 /* XXX : not implemented */
4944 spr_register(env
, SPR_Exxx_BBEAR
, "BBEAR",
4945 SPR_NOACCESS
, SPR_NOACCESS
,
4946 &spr_read_generic
, &spr_write_generic
,
4948 /* XXX : not implemented */
4949 spr_register(env
, SPR_Exxx_BBTAR
, "BBTAR",
4950 SPR_NOACCESS
, SPR_NOACCESS
,
4951 &spr_read_generic
, &spr_write_generic
,
4953 /* XXX : not implemented */
4954 spr_register(env
, SPR_Exxx_MCAR
, "MCAR",
4955 SPR_NOACCESS
, SPR_NOACCESS
,
4956 &spr_read_generic
, &spr_write_generic
,
4958 /* XXX : not implemented */
4959 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
4960 SPR_NOACCESS
, SPR_NOACCESS
,
4961 &spr_read_generic
, &spr_write_generic
,
4963 /* XXX : not implemented */
4964 spr_register(env
, SPR_Exxx_NPIDR
, "NPIDR",
4965 SPR_NOACCESS
, SPR_NOACCESS
,
4966 &spr_read_generic
, &spr_write_generic
,
4968 /* XXX : not implemented */
4969 spr_register(env
, SPR_Exxx_BUCSR
, "BUCSR",
4970 SPR_NOACCESS
, SPR_NOACCESS
,
4971 &spr_read_generic
, &spr_write_generic
,
4973 /* XXX : not implemented */
4974 spr_register(env
, SPR_Exxx_L1CFG0
, "L1CFG0",
4975 &spr_read_generic
, SPR_NOACCESS
,
4976 &spr_read_generic
, SPR_NOACCESS
,
4978 spr_register(env
, SPR_Exxx_L1CFG1
, "L1CFG1",
4979 &spr_read_generic
, SPR_NOACCESS
,
4980 &spr_read_generic
, SPR_NOACCESS
,
4982 spr_register(env
, SPR_Exxx_L1CSR0
, "L1CSR0",
4983 SPR_NOACCESS
, SPR_NOACCESS
,
4984 &spr_read_generic
, &spr_write_e500_l1csr0
,
4986 spr_register(env
, SPR_Exxx_L1CSR1
, "L1CSR1",
4987 SPR_NOACCESS
, SPR_NOACCESS
,
4988 &spr_read_generic
, &spr_write_e500_l1csr1
,
4990 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
4991 SPR_NOACCESS
, SPR_NOACCESS
,
4992 &spr_read_generic
, &spr_write_generic
,
4994 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
4995 SPR_NOACCESS
, SPR_NOACCESS
,
4996 &spr_read_generic
, &spr_write_generic
,
4998 spr_register(env
, SPR_MMUCSR0
, "MMUCSR0",
4999 SPR_NOACCESS
, SPR_NOACCESS
,
5000 &spr_read_generic
, &spr_write_booke206_mmucsr0
,
5002 spr_register(env
, SPR_BOOKE_EPR
, "EPR",
5003 SPR_NOACCESS
, SPR_NOACCESS
,
5004 &spr_read_generic
, SPR_NOACCESS
,
5006 /* XXX better abstract into Emb.xxx features */
5007 if ((version
== fsl_e5500
) || (version
== fsl_e6500
)) {
5008 spr_register(env
, SPR_BOOKE_EPCR
, "EPCR",
5009 SPR_NOACCESS
, SPR_NOACCESS
,
5010 &spr_read_generic
, &spr_write_generic
,
5012 spr_register(env
, SPR_BOOKE_MAS7_MAS3
, "MAS7_MAS3",
5013 SPR_NOACCESS
, SPR_NOACCESS
,
5014 &spr_read_mas73
, &spr_write_mas73
,
5016 ivpr_mask
= (target_ulong
)~0xFFFFULL
;
5019 if (version
== fsl_e6500
) {
5020 /* Thread identification */
5021 spr_register(env
, SPR_TIR
, "TIR",
5022 SPR_NOACCESS
, SPR_NOACCESS
,
5023 &spr_read_generic
, SPR_NOACCESS
,
5025 spr_register(env
, SPR_BOOKE_TLB0PS
, "TLB0PS",
5026 SPR_NOACCESS
, SPR_NOACCESS
,
5027 &spr_read_generic
, SPR_NOACCESS
,
5029 spr_register(env
, SPR_BOOKE_TLB1PS
, "TLB1PS",
5030 SPR_NOACCESS
, SPR_NOACCESS
,
5031 &spr_read_generic
, SPR_NOACCESS
,
5035 #if !defined(CONFIG_USER_ONLY)
5037 env
->tlb_type
= TLB_MAS
;
5038 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
5039 env
->nb_tlb
+= booke206_tlb_size(env
, i
);
5043 init_excp_e200(env
, ivpr_mask
);
5044 /* Allocate hardware IRQ controller */
5045 ppce500_irq_init(env_archcpu(env
));
5048 static void init_proc_e500v1(CPUPPCState
*env
)
5050 init_proc_e500(env
, fsl_e500v1
);
5053 POWERPC_FAMILY(e500v1
)(ObjectClass
*oc
, void *data
)
5055 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5056 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5058 dc
->desc
= "e500v1 core";
5059 pcc
->init_proc
= init_proc_e500v1
;
5060 pcc
->check_pow
= check_pow_hid0
;
5061 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
5062 PPC_SPE
| PPC_SPE_SINGLE
|
5063 PPC_WRTEE
| PPC_RFDI
|
5064 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5065 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5066 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5067 pcc
->insns_flags2
= PPC2_BOOKE206
;
5068 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
5082 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5083 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5084 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5085 pcc
->bfd_mach
= bfd_mach_ppc_860
;
5086 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
5087 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
5088 POWERPC_FLAG_BUS_CLK
;
5091 static void init_proc_e500v2(CPUPPCState
*env
)
5093 init_proc_e500(env
, fsl_e500v2
);
5096 POWERPC_FAMILY(e500v2
)(ObjectClass
*oc
, void *data
)
5098 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5099 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5101 dc
->desc
= "e500v2 core";
5102 pcc
->init_proc
= init_proc_e500v2
;
5103 pcc
->check_pow
= check_pow_hid0
;
5104 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
5105 PPC_SPE
| PPC_SPE_SINGLE
| PPC_SPE_DOUBLE
|
5106 PPC_WRTEE
| PPC_RFDI
|
5107 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5108 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5109 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5110 pcc
->insns_flags2
= PPC2_BOOKE206
;
5111 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
5125 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5126 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5127 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5128 pcc
->bfd_mach
= bfd_mach_ppc_860
;
5129 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
5130 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
5131 POWERPC_FLAG_BUS_CLK
;
5134 static void init_proc_e500mc(CPUPPCState
*env
)
5136 init_proc_e500(env
, fsl_e500mc
);
5139 POWERPC_FAMILY(e500mc
)(ObjectClass
*oc
, void *data
)
5141 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5142 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5144 dc
->desc
= "e500mc core";
5145 pcc
->init_proc
= init_proc_e500mc
;
5146 pcc
->check_pow
= check_pow_none
;
5147 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5148 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5149 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5150 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5151 PPC_FLOAT
| PPC_FLOAT_FRES
|
5152 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5153 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5154 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5155 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
;
5156 pcc
->msr_mask
= (1ull << MSR_GS
) |
5157 (1ull << MSR_UCLE
) |
5170 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5171 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5172 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5173 /* FIXME: figure out the correct flag for e500mc */
5174 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5175 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5176 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5180 static void init_proc_e5500(CPUPPCState
*env
)
5182 init_proc_e500(env
, fsl_e5500
);
5185 POWERPC_FAMILY(e5500
)(ObjectClass
*oc
, void *data
)
5187 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5188 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5190 dc
->desc
= "e5500 core";
5191 pcc
->init_proc
= init_proc_e5500
;
5192 pcc
->check_pow
= check_pow_none
;
5193 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5194 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5195 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5196 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5197 PPC_FLOAT
| PPC_FLOAT_FRES
|
5198 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5199 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5200 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
|
5201 PPC_64B
| PPC_POPCNTB
| PPC_POPCNTWD
;
5202 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
| PPC2_PERM_ISA206
| \
5204 pcc
->msr_mask
= (1ull << MSR_CM
) |
5206 (1ull << MSR_UCLE
) |
5219 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5220 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5221 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5222 /* FIXME: figure out the correct flag for e5500 */
5223 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5224 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5225 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5228 static void init_proc_e6500(CPUPPCState
*env
)
5230 init_proc_e500(env
, fsl_e6500
);
5233 POWERPC_FAMILY(e6500
)(ObjectClass
*oc
, void *data
)
5235 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5236 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5238 dc
->desc
= "e6500 core";
5239 pcc
->init_proc
= init_proc_e6500
;
5240 pcc
->check_pow
= check_pow_none
;
5241 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5242 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5243 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5244 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5245 PPC_FLOAT
| PPC_FLOAT_FRES
|
5246 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5247 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5248 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
|
5249 PPC_64B
| PPC_POPCNTB
| PPC_POPCNTWD
| PPC_ALTIVEC
;
5250 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
| PPC2_PERM_ISA206
| \
5251 PPC2_FP_CVT_S64
| PPC2_ATOMIC_ISA206
;
5252 pcc
->msr_mask
= (1ull << MSR_CM
) |
5254 (1ull << MSR_UCLE
) |
5268 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5269 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5270 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5271 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5272 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5273 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_VRE
;
5278 /* Non-embedded PowerPC */
5280 #define POWERPC_MSRR_601 (0x0000000000001040ULL)
5282 static void init_proc_601(CPUPPCState
*env
)
5284 gen_spr_ne_601(env
);
5287 /* Hardware implementation registers */
5288 /* XXX : not implemented */
5289 spr_register(env
, SPR_HID0
, "HID0",
5290 SPR_NOACCESS
, SPR_NOACCESS
,
5291 &spr_read_generic
, &spr_write_hid0_601
,
5293 /* XXX : not implemented */
5294 spr_register(env
, SPR_HID1
, "HID1",
5295 SPR_NOACCESS
, SPR_NOACCESS
,
5296 &spr_read_generic
, &spr_write_generic
,
5298 /* XXX : not implemented */
5299 spr_register(env
, SPR_601_HID2
, "HID2",
5300 SPR_NOACCESS
, SPR_NOACCESS
,
5301 &spr_read_generic
, &spr_write_generic
,
5303 /* XXX : not implemented */
5304 spr_register(env
, SPR_601_HID5
, "HID5",
5305 SPR_NOACCESS
, SPR_NOACCESS
,
5306 &spr_read_generic
, &spr_write_generic
,
5308 /* Memory management */
5311 * XXX: beware that dcache line size is 64
5312 * but dcbz uses 32 bytes "sectors"
5313 * XXX: this breaks clcs instruction !
5315 env
->dcache_line_size
= 32;
5316 env
->icache_line_size
= 64;
5317 /* Allocate hardware IRQ controller */
5318 ppc6xx_irq_init(env_archcpu(env
));
5321 POWERPC_FAMILY(601)(ObjectClass
*oc
, void *data
)
5323 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5324 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5326 dc
->desc
= "PowerPC 601";
5327 pcc
->init_proc
= init_proc_601
;
5328 pcc
->check_pow
= check_pow_none
;
5329 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_POWER_BR
|
5331 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5332 PPC_MEM_SYNC
| PPC_MEM_EIEIO
| PPC_MEM_TLBIE
|
5333 PPC_SEGMENT
| PPC_EXTERN
;
5334 pcc
->msr_mask
= (1ull << MSR_EE
) |
5344 pcc
->mmu_model
= POWERPC_MMU_601
;
5345 #if defined(CONFIG_SOFTMMU)
5346 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5348 pcc
->excp_model
= POWERPC_EXCP_601
;
5349 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5350 pcc
->bfd_mach
= bfd_mach_ppc_601
;
5351 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_RTC_CLK
;
5354 #define POWERPC_MSRR_601v (0x0000000000001040ULL)
5356 static void init_proc_601v(CPUPPCState
*env
)
5359 /* XXX : not implemented */
5360 spr_register(env
, SPR_601_HID15
, "HID15",
5361 SPR_NOACCESS
, SPR_NOACCESS
,
5362 &spr_read_generic
, &spr_write_generic
,
5366 POWERPC_FAMILY(601v
)(ObjectClass
*oc
, void *data
)
5368 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5369 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5371 dc
->desc
= "PowerPC 601v";
5372 pcc
->init_proc
= init_proc_601v
;
5373 pcc
->check_pow
= check_pow_none
;
5374 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_POWER_BR
|
5376 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5377 PPC_MEM_SYNC
| PPC_MEM_EIEIO
| PPC_MEM_TLBIE
|
5378 PPC_SEGMENT
| PPC_EXTERN
;
5379 pcc
->msr_mask
= (1ull << MSR_EE
) |
5389 pcc
->mmu_model
= POWERPC_MMU_601
;
5390 #if defined(CONFIG_SOFTMMU)
5391 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5393 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5394 pcc
->bfd_mach
= bfd_mach_ppc_601
;
5395 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_RTC_CLK
;
5398 static void init_proc_602(CPUPPCState
*env
)
5400 gen_spr_ne_601(env
);
5405 /* hardware implementation registers */
5406 /* XXX : not implemented */
5407 spr_register(env
, SPR_HID0
, "HID0",
5408 SPR_NOACCESS
, SPR_NOACCESS
,
5409 &spr_read_generic
, &spr_write_generic
,
5411 /* XXX : not implemented */
5412 spr_register(env
, SPR_HID1
, "HID1",
5413 SPR_NOACCESS
, SPR_NOACCESS
,
5414 &spr_read_generic
, &spr_write_generic
,
5416 /* Memory management */
5418 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5420 env
->dcache_line_size
= 32;
5421 env
->icache_line_size
= 32;
5422 /* Allocate hardware IRQ controller */
5423 ppc6xx_irq_init(env_archcpu(env
));
5426 POWERPC_FAMILY(602)(ObjectClass
*oc
, void *data
)
5428 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5429 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5431 dc
->desc
= "PowerPC 602";
5432 pcc
->init_proc
= init_proc_602
;
5433 pcc
->check_pow
= check_pow_hid0
;
5434 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5435 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5436 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5437 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5438 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5439 PPC_MEM_TLBIE
| PPC_6xx_TLB
| PPC_MEM_TLBSYNC
|
5440 PPC_SEGMENT
| PPC_602_SPEC
;
5441 pcc
->msr_mask
= (1ull << MSR_VSX
) |
5444 (1ull << MSR_TGPR
) |
5459 /* XXX: 602 MMU is quite specific. Should add a special case */
5460 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5461 pcc
->excp_model
= POWERPC_EXCP_602
;
5462 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5463 pcc
->bfd_mach
= bfd_mach_ppc_602
;
5464 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5465 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5468 static void init_proc_603(CPUPPCState
*env
)
5470 gen_spr_ne_601(env
);
5475 /* hardware implementation registers */
5476 /* XXX : not implemented */
5477 spr_register(env
, SPR_HID0
, "HID0",
5478 SPR_NOACCESS
, SPR_NOACCESS
,
5479 &spr_read_generic
, &spr_write_generic
,
5481 /* XXX : not implemented */
5482 spr_register(env
, SPR_HID1
, "HID1",
5483 SPR_NOACCESS
, SPR_NOACCESS
,
5484 &spr_read_generic
, &spr_write_generic
,
5486 /* Memory management */
5488 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5490 env
->dcache_line_size
= 32;
5491 env
->icache_line_size
= 32;
5492 /* Allocate hardware IRQ controller */
5493 ppc6xx_irq_init(env_archcpu(env
));
5496 POWERPC_FAMILY(603)(ObjectClass
*oc
, void *data
)
5498 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5499 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5501 dc
->desc
= "PowerPC 603";
5502 pcc
->init_proc
= init_proc_603
;
5503 pcc
->check_pow
= check_pow_hid0
;
5504 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5505 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5506 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5507 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5508 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5509 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
5510 PPC_SEGMENT
| PPC_EXTERN
;
5511 pcc
->msr_mask
= (1ull << MSR_POW
) |
5512 (1ull << MSR_TGPR
) |
5527 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5528 pcc
->excp_model
= POWERPC_EXCP_603
;
5529 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5530 pcc
->bfd_mach
= bfd_mach_ppc_603
;
5531 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5532 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5535 static void init_proc_603E(CPUPPCState
*env
)
5537 gen_spr_ne_601(env
);
5542 /* hardware implementation registers */
5543 /* XXX : not implemented */
5544 spr_register(env
, SPR_HID0
, "HID0",
5545 SPR_NOACCESS
, SPR_NOACCESS
,
5546 &spr_read_generic
, &spr_write_generic
,
5548 /* XXX : not implemented */
5549 spr_register(env
, SPR_HID1
, "HID1",
5550 SPR_NOACCESS
, SPR_NOACCESS
,
5551 &spr_read_generic
, &spr_write_generic
,
5553 /* Memory management */
5555 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5557 env
->dcache_line_size
= 32;
5558 env
->icache_line_size
= 32;
5559 /* Allocate hardware IRQ controller */
5560 ppc6xx_irq_init(env_archcpu(env
));
5563 POWERPC_FAMILY(603E
)(ObjectClass
*oc
, void *data
)
5565 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5566 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5568 dc
->desc
= "PowerPC 603e";
5569 pcc
->init_proc
= init_proc_603E
;
5570 pcc
->check_pow
= check_pow_hid0
;
5571 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5572 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5573 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5574 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5575 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5576 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
5577 PPC_SEGMENT
| PPC_EXTERN
;
5578 pcc
->msr_mask
= (1ull << MSR_POW
) |
5579 (1ull << MSR_TGPR
) |
5594 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5595 pcc
->excp_model
= POWERPC_EXCP_603E
;
5596 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5597 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
5598 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5599 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5602 static void init_proc_604(CPUPPCState
*env
)
5604 gen_spr_ne_601(env
);
5609 /* Hardware implementation registers */
5610 /* XXX : not implemented */
5611 spr_register(env
, SPR_HID0
, "HID0",
5612 SPR_NOACCESS
, SPR_NOACCESS
,
5613 &spr_read_generic
, &spr_write_generic
,
5615 /* Memory management */
5618 env
->dcache_line_size
= 32;
5619 env
->icache_line_size
= 32;
5620 /* Allocate hardware IRQ controller */
5621 ppc6xx_irq_init(env_archcpu(env
));
5624 POWERPC_FAMILY(604)(ObjectClass
*oc
, void *data
)
5626 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5627 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5629 dc
->desc
= "PowerPC 604";
5630 pcc
->init_proc
= init_proc_604
;
5631 pcc
->check_pow
= check_pow_nocheck
;
5632 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5633 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5634 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5635 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5636 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5637 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5638 PPC_SEGMENT
| PPC_EXTERN
;
5639 pcc
->msr_mask
= (1ull << MSR_POW
) |
5655 pcc
->mmu_model
= POWERPC_MMU_32B
;
5656 #if defined(CONFIG_SOFTMMU)
5657 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5659 pcc
->excp_model
= POWERPC_EXCP_604
;
5660 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5661 pcc
->bfd_mach
= bfd_mach_ppc_604
;
5662 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5663 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5666 static void init_proc_604E(CPUPPCState
*env
)
5668 gen_spr_ne_601(env
);
5671 /* XXX : not implemented */
5672 spr_register(env
, SPR_7XX_MMCR1
, "MMCR1",
5673 SPR_NOACCESS
, SPR_NOACCESS
,
5674 &spr_read_generic
, &spr_write_generic
,
5676 /* XXX : not implemented */
5677 spr_register(env
, SPR_7XX_PMC3
, "PMC3",
5678 SPR_NOACCESS
, SPR_NOACCESS
,
5679 &spr_read_generic
, &spr_write_generic
,
5681 /* XXX : not implemented */
5682 spr_register(env
, SPR_7XX_PMC4
, "PMC4",
5683 SPR_NOACCESS
, SPR_NOACCESS
,
5684 &spr_read_generic
, &spr_write_generic
,
5688 /* Hardware implementation registers */
5689 /* XXX : not implemented */
5690 spr_register(env
, SPR_HID0
, "HID0",
5691 SPR_NOACCESS
, SPR_NOACCESS
,
5692 &spr_read_generic
, &spr_write_generic
,
5694 /* XXX : not implemented */
5695 spr_register(env
, SPR_HID1
, "HID1",
5696 SPR_NOACCESS
, SPR_NOACCESS
,
5697 &spr_read_generic
, &spr_write_generic
,
5699 /* Memory management */
5702 env
->dcache_line_size
= 32;
5703 env
->icache_line_size
= 32;
5704 /* Allocate hardware IRQ controller */
5705 ppc6xx_irq_init(env_archcpu(env
));
5708 POWERPC_FAMILY(604E
)(ObjectClass
*oc
, void *data
)
5710 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5711 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5713 dc
->desc
= "PowerPC 604E";
5714 pcc
->init_proc
= init_proc_604E
;
5715 pcc
->check_pow
= check_pow_nocheck
;
5716 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5717 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5718 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5719 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5720 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5721 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5722 PPC_SEGMENT
| PPC_EXTERN
;
5723 pcc
->msr_mask
= (1ull << MSR_POW
) |
5739 pcc
->mmu_model
= POWERPC_MMU_32B
;
5740 #if defined(CONFIG_SOFTMMU)
5741 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5743 pcc
->excp_model
= POWERPC_EXCP_604
;
5744 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5745 pcc
->bfd_mach
= bfd_mach_ppc_604
;
5746 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5747 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5750 static void init_proc_740(CPUPPCState
*env
)
5752 gen_spr_ne_601(env
);
5757 /* Thermal management */
5759 /* Hardware implementation registers */
5760 /* XXX : not implemented */
5761 spr_register(env
, SPR_HID0
, "HID0",
5762 SPR_NOACCESS
, SPR_NOACCESS
,
5763 &spr_read_generic
, &spr_write_generic
,
5765 /* XXX : not implemented */
5766 spr_register(env
, SPR_HID1
, "HID1",
5767 SPR_NOACCESS
, SPR_NOACCESS
,
5768 &spr_read_generic
, &spr_write_generic
,
5770 /* Memory management */
5773 env
->dcache_line_size
= 32;
5774 env
->icache_line_size
= 32;
5775 /* Allocate hardware IRQ controller */
5776 ppc6xx_irq_init(env_archcpu(env
));
5779 POWERPC_FAMILY(740)(ObjectClass
*oc
, void *data
)
5781 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5782 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5784 dc
->desc
= "PowerPC 740";
5785 pcc
->init_proc
= init_proc_740
;
5786 pcc
->check_pow
= check_pow_hid0
;
5787 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5788 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5789 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5790 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5791 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5792 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5793 PPC_SEGMENT
| PPC_EXTERN
;
5794 pcc
->msr_mask
= (1ull << MSR_POW
) |
5810 pcc
->mmu_model
= POWERPC_MMU_32B
;
5811 #if defined(CONFIG_SOFTMMU)
5812 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5814 pcc
->excp_model
= POWERPC_EXCP_7x0
;
5815 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5816 pcc
->bfd_mach
= bfd_mach_ppc_750
;
5817 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5818 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5821 static void init_proc_750(CPUPPCState
*env
)
5823 gen_spr_ne_601(env
);
5826 /* XXX : not implemented */
5827 spr_register(env
, SPR_L2CR
, "L2CR",
5828 SPR_NOACCESS
, SPR_NOACCESS
,
5829 &spr_read_generic
, spr_access_nop
,
5833 /* Thermal management */
5835 /* Hardware implementation registers */
5836 /* XXX : not implemented */
5837 spr_register(env
, SPR_HID0
, "HID0",
5838 SPR_NOACCESS
, SPR_NOACCESS
,
5839 &spr_read_generic
, &spr_write_generic
,
5841 /* XXX : not implemented */
5842 spr_register(env
, SPR_HID1
, "HID1",
5843 SPR_NOACCESS
, SPR_NOACCESS
,
5844 &spr_read_generic
, &spr_write_generic
,
5846 /* Memory management */
5849 * XXX: high BATs are also present but are known to be bugged on
5853 env
->dcache_line_size
= 32;
5854 env
->icache_line_size
= 32;
5855 /* Allocate hardware IRQ controller */
5856 ppc6xx_irq_init(env_archcpu(env
));
5859 POWERPC_FAMILY(750)(ObjectClass
*oc
, void *data
)
5861 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5862 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5864 dc
->desc
= "PowerPC 750";
5865 pcc
->init_proc
= init_proc_750
;
5866 pcc
->check_pow
= check_pow_hid0
;
5867 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5868 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5869 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5870 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5871 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5872 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5873 PPC_SEGMENT
| PPC_EXTERN
;
5874 pcc
->msr_mask
= (1ull << MSR_POW
) |
5890 pcc
->mmu_model
= POWERPC_MMU_32B
;
5891 #if defined(CONFIG_SOFTMMU)
5892 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5894 pcc
->excp_model
= POWERPC_EXCP_7x0
;
5895 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5896 pcc
->bfd_mach
= bfd_mach_ppc_750
;
5897 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5898 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5901 static void init_proc_750cl(CPUPPCState
*env
)
5903 gen_spr_ne_601(env
);
5906 /* XXX : not implemented */
5907 spr_register(env
, SPR_L2CR
, "L2CR",
5908 SPR_NOACCESS
, SPR_NOACCESS
,
5909 &spr_read_generic
, spr_access_nop
,
5913 /* Thermal management */
5914 /* Those registers are fake on 750CL */
5915 spr_register(env
, SPR_THRM1
, "THRM1",
5916 SPR_NOACCESS
, SPR_NOACCESS
,
5917 &spr_read_generic
, &spr_write_generic
,
5919 spr_register(env
, SPR_THRM2
, "THRM2",
5920 SPR_NOACCESS
, SPR_NOACCESS
,
5921 &spr_read_generic
, &spr_write_generic
,
5923 spr_register(env
, SPR_THRM3
, "THRM3",
5924 SPR_NOACCESS
, SPR_NOACCESS
,
5925 &spr_read_generic
, &spr_write_generic
,
5927 /* XXX: not implemented */
5928 spr_register(env
, SPR_750_TDCL
, "TDCL",
5929 SPR_NOACCESS
, SPR_NOACCESS
,
5930 &spr_read_generic
, &spr_write_generic
,
5932 spr_register(env
, SPR_750_TDCH
, "TDCH",
5933 SPR_NOACCESS
, SPR_NOACCESS
,
5934 &spr_read_generic
, &spr_write_generic
,
5937 /* XXX : not implemented */
5938 spr_register(env
, SPR_750_WPAR
, "WPAR",
5939 SPR_NOACCESS
, SPR_NOACCESS
,
5940 &spr_read_generic
, &spr_write_generic
,
5942 spr_register(env
, SPR_750_DMAL
, "DMAL",
5943 SPR_NOACCESS
, SPR_NOACCESS
,
5944 &spr_read_generic
, &spr_write_generic
,
5946 spr_register(env
, SPR_750_DMAU
, "DMAU",
5947 SPR_NOACCESS
, SPR_NOACCESS
,
5948 &spr_read_generic
, &spr_write_generic
,
5950 /* Hardware implementation registers */
5951 /* XXX : not implemented */
5952 spr_register(env
, SPR_HID0
, "HID0",
5953 SPR_NOACCESS
, SPR_NOACCESS
,
5954 &spr_read_generic
, &spr_write_generic
,
5956 /* XXX : not implemented */
5957 spr_register(env
, SPR_HID1
, "HID1",
5958 SPR_NOACCESS
, SPR_NOACCESS
,
5959 &spr_read_generic
, &spr_write_generic
,
5961 /* XXX : not implemented */
5962 spr_register(env
, SPR_750CL_HID2
, "HID2",
5963 SPR_NOACCESS
, SPR_NOACCESS
,
5964 &spr_read_generic
, &spr_write_generic
,
5966 /* XXX : not implemented */
5967 spr_register(env
, SPR_750CL_HID4
, "HID4",
5968 SPR_NOACCESS
, SPR_NOACCESS
,
5969 &spr_read_generic
, &spr_write_generic
,
5971 /* Quantization registers */
5972 /* XXX : not implemented */
5973 spr_register(env
, SPR_750_GQR0
, "GQR0",
5974 SPR_NOACCESS
, SPR_NOACCESS
,
5975 &spr_read_generic
, &spr_write_generic
,
5977 /* XXX : not implemented */
5978 spr_register(env
, SPR_750_GQR1
, "GQR1",
5979 SPR_NOACCESS
, SPR_NOACCESS
,
5980 &spr_read_generic
, &spr_write_generic
,
5982 /* XXX : not implemented */
5983 spr_register(env
, SPR_750_GQR2
, "GQR2",
5984 SPR_NOACCESS
, SPR_NOACCESS
,
5985 &spr_read_generic
, &spr_write_generic
,
5987 /* XXX : not implemented */
5988 spr_register(env
, SPR_750_GQR3
, "GQR3",
5989 SPR_NOACCESS
, SPR_NOACCESS
,
5990 &spr_read_generic
, &spr_write_generic
,
5992 /* XXX : not implemented */
5993 spr_register(env
, SPR_750_GQR4
, "GQR4",
5994 SPR_NOACCESS
, SPR_NOACCESS
,
5995 &spr_read_generic
, &spr_write_generic
,
5997 /* XXX : not implemented */
5998 spr_register(env
, SPR_750_GQR5
, "GQR5",
5999 SPR_NOACCESS
, SPR_NOACCESS
,
6000 &spr_read_generic
, &spr_write_generic
,
6002 /* XXX : not implemented */
6003 spr_register(env
, SPR_750_GQR6
, "GQR6",
6004 SPR_NOACCESS
, SPR_NOACCESS
,
6005 &spr_read_generic
, &spr_write_generic
,
6007 /* XXX : not implemented */
6008 spr_register(env
, SPR_750_GQR7
, "GQR7",
6009 SPR_NOACCESS
, SPR_NOACCESS
,
6010 &spr_read_generic
, &spr_write_generic
,
6012 /* Memory management */
6014 /* PowerPC 750cl has 8 DBATs and 8 IBATs */
6016 init_excp_750cl(env
);
6017 env
->dcache_line_size
= 32;
6018 env
->icache_line_size
= 32;
6019 /* Allocate hardware IRQ controller */
6020 ppc6xx_irq_init(env_archcpu(env
));
6023 POWERPC_FAMILY(750cl
)(ObjectClass
*oc
, void *data
)
6025 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6026 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6028 dc
->desc
= "PowerPC 750 CL";
6029 pcc
->init_proc
= init_proc_750cl
;
6030 pcc
->check_pow
= check_pow_hid0
;
6032 * XXX: not implemented:
6033 * cache lock instructions:
6035 * floating point paired instructions
6070 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6071 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6072 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6073 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6074 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6075 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6076 PPC_SEGMENT
| PPC_EXTERN
;
6077 pcc
->msr_mask
= (1ull << MSR_POW
) |
6093 pcc
->mmu_model
= POWERPC_MMU_32B
;
6094 #if defined(CONFIG_SOFTMMU)
6095 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6097 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6098 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6099 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6100 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6101 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6104 static void init_proc_750cx(CPUPPCState
*env
)
6106 gen_spr_ne_601(env
);
6109 /* XXX : not implemented */
6110 spr_register(env
, SPR_L2CR
, "L2CR",
6111 SPR_NOACCESS
, SPR_NOACCESS
,
6112 &spr_read_generic
, spr_access_nop
,
6116 /* Thermal management */
6118 /* This register is not implemented but is present for compatibility */
6119 spr_register(env
, SPR_SDA
, "SDA",
6120 SPR_NOACCESS
, SPR_NOACCESS
,
6121 &spr_read_generic
, &spr_write_generic
,
6123 /* Hardware implementation registers */
6124 /* XXX : not implemented */
6125 spr_register(env
, SPR_HID0
, "HID0",
6126 SPR_NOACCESS
, SPR_NOACCESS
,
6127 &spr_read_generic
, &spr_write_generic
,
6129 /* XXX : not implemented */
6130 spr_register(env
, SPR_HID1
, "HID1",
6131 SPR_NOACCESS
, SPR_NOACCESS
,
6132 &spr_read_generic
, &spr_write_generic
,
6134 /* Memory management */
6136 /* PowerPC 750cx has 8 DBATs and 8 IBATs */
6138 init_excp_750cx(env
);
6139 env
->dcache_line_size
= 32;
6140 env
->icache_line_size
= 32;
6141 /* Allocate hardware IRQ controller */
6142 ppc6xx_irq_init(env_archcpu(env
));
6145 POWERPC_FAMILY(750cx
)(ObjectClass
*oc
, void *data
)
6147 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6148 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6150 dc
->desc
= "PowerPC 750CX";
6151 pcc
->init_proc
= init_proc_750cx
;
6152 pcc
->check_pow
= check_pow_hid0
;
6153 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6154 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6155 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6156 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6157 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6158 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6159 PPC_SEGMENT
| PPC_EXTERN
;
6160 pcc
->msr_mask
= (1ull << MSR_POW
) |
6176 pcc
->mmu_model
= POWERPC_MMU_32B
;
6177 #if defined(CONFIG_SOFTMMU)
6178 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6180 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6181 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6182 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6183 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6184 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6187 static void init_proc_750fx(CPUPPCState
*env
)
6189 gen_spr_ne_601(env
);
6192 /* XXX : not implemented */
6193 spr_register(env
, SPR_L2CR
, "L2CR",
6194 SPR_NOACCESS
, SPR_NOACCESS
,
6195 &spr_read_generic
, spr_access_nop
,
6199 /* Thermal management */
6201 /* XXX : not implemented */
6202 spr_register(env
, SPR_750_THRM4
, "THRM4",
6203 SPR_NOACCESS
, SPR_NOACCESS
,
6204 &spr_read_generic
, &spr_write_generic
,
6206 /* Hardware implementation registers */
6207 /* XXX : not implemented */
6208 spr_register(env
, SPR_HID0
, "HID0",
6209 SPR_NOACCESS
, SPR_NOACCESS
,
6210 &spr_read_generic
, &spr_write_generic
,
6212 /* XXX : not implemented */
6213 spr_register(env
, SPR_HID1
, "HID1",
6214 SPR_NOACCESS
, SPR_NOACCESS
,
6215 &spr_read_generic
, &spr_write_generic
,
6217 /* XXX : not implemented */
6218 spr_register(env
, SPR_750FX_HID2
, "HID2",
6219 SPR_NOACCESS
, SPR_NOACCESS
,
6220 &spr_read_generic
, &spr_write_generic
,
6222 /* Memory management */
6224 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6227 env
->dcache_line_size
= 32;
6228 env
->icache_line_size
= 32;
6229 /* Allocate hardware IRQ controller */
6230 ppc6xx_irq_init(env_archcpu(env
));
6233 POWERPC_FAMILY(750fx
)(ObjectClass
*oc
, void *data
)
6235 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6236 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6238 dc
->desc
= "PowerPC 750FX";
6239 pcc
->init_proc
= init_proc_750fx
;
6240 pcc
->check_pow
= check_pow_hid0
;
6241 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6242 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6243 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6244 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6245 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6246 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6247 PPC_SEGMENT
| PPC_EXTERN
;
6248 pcc
->msr_mask
= (1ull << MSR_POW
) |
6264 pcc
->mmu_model
= POWERPC_MMU_32B
;
6265 #if defined(CONFIG_SOFTMMU)
6266 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6268 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6269 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6270 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6271 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6272 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6275 static void init_proc_750gx(CPUPPCState
*env
)
6277 gen_spr_ne_601(env
);
6280 /* XXX : not implemented (XXX: different from 750fx) */
6281 spr_register(env
, SPR_L2CR
, "L2CR",
6282 SPR_NOACCESS
, SPR_NOACCESS
,
6283 &spr_read_generic
, spr_access_nop
,
6287 /* Thermal management */
6289 /* XXX : not implemented */
6290 spr_register(env
, SPR_750_THRM4
, "THRM4",
6291 SPR_NOACCESS
, SPR_NOACCESS
,
6292 &spr_read_generic
, &spr_write_generic
,
6294 /* Hardware implementation registers */
6295 /* XXX : not implemented (XXX: different from 750fx) */
6296 spr_register(env
, SPR_HID0
, "HID0",
6297 SPR_NOACCESS
, SPR_NOACCESS
,
6298 &spr_read_generic
, &spr_write_generic
,
6300 /* XXX : not implemented */
6301 spr_register(env
, SPR_HID1
, "HID1",
6302 SPR_NOACCESS
, SPR_NOACCESS
,
6303 &spr_read_generic
, &spr_write_generic
,
6305 /* XXX : not implemented (XXX: different from 750fx) */
6306 spr_register(env
, SPR_750FX_HID2
, "HID2",
6307 SPR_NOACCESS
, SPR_NOACCESS
,
6308 &spr_read_generic
, &spr_write_generic
,
6310 /* Memory management */
6312 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6315 env
->dcache_line_size
= 32;
6316 env
->icache_line_size
= 32;
6317 /* Allocate hardware IRQ controller */
6318 ppc6xx_irq_init(env_archcpu(env
));
6321 POWERPC_FAMILY(750gx
)(ObjectClass
*oc
, void *data
)
6323 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6324 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6326 dc
->desc
= "PowerPC 750GX";
6327 pcc
->init_proc
= init_proc_750gx
;
6328 pcc
->check_pow
= check_pow_hid0
;
6329 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6330 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6331 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6332 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6333 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6334 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6335 PPC_SEGMENT
| PPC_EXTERN
;
6336 pcc
->msr_mask
= (1ull << MSR_POW
) |
6352 pcc
->mmu_model
= POWERPC_MMU_32B
;
6353 #if defined(CONFIG_SOFTMMU)
6354 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6356 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6357 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6358 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6359 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6360 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6363 static void init_proc_745(CPUPPCState
*env
)
6365 gen_spr_ne_601(env
);
6368 gen_spr_G2_755(env
);
6371 /* Thermal management */
6373 /* Hardware implementation registers */
6374 /* XXX : not implemented */
6375 spr_register(env
, SPR_HID0
, "HID0",
6376 SPR_NOACCESS
, SPR_NOACCESS
,
6377 &spr_read_generic
, &spr_write_generic
,
6379 /* XXX : not implemented */
6380 spr_register(env
, SPR_HID1
, "HID1",
6381 SPR_NOACCESS
, SPR_NOACCESS
,
6382 &spr_read_generic
, &spr_write_generic
,
6384 /* XXX : not implemented */
6385 spr_register(env
, SPR_HID2
, "HID2",
6386 SPR_NOACCESS
, SPR_NOACCESS
,
6387 &spr_read_generic
, &spr_write_generic
,
6389 /* Memory management */
6392 gen_6xx_7xx_soft_tlb(env
, 64, 2);
6394 env
->dcache_line_size
= 32;
6395 env
->icache_line_size
= 32;
6396 /* Allocate hardware IRQ controller */
6397 ppc6xx_irq_init(env_archcpu(env
));
6400 POWERPC_FAMILY(745)(ObjectClass
*oc
, void *data
)
6402 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6403 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6405 dc
->desc
= "PowerPC 745";
6406 pcc
->init_proc
= init_proc_745
;
6407 pcc
->check_pow
= check_pow_hid0
;
6408 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6409 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6410 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6411 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6412 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6413 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
6414 PPC_SEGMENT
| PPC_EXTERN
;
6415 pcc
->msr_mask
= (1ull << MSR_POW
) |
6431 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
6432 pcc
->excp_model
= POWERPC_EXCP_7x5
;
6433 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6434 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6435 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6436 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6439 static void init_proc_755(CPUPPCState
*env
)
6441 gen_spr_ne_601(env
);
6444 gen_spr_G2_755(env
);
6447 /* L2 cache control */
6448 /* XXX : not implemented */
6449 spr_register(env
, SPR_L2CR
, "L2CR",
6450 SPR_NOACCESS
, SPR_NOACCESS
,
6451 &spr_read_generic
, spr_access_nop
,
6453 /* XXX : not implemented */
6454 spr_register(env
, SPR_L2PMCR
, "L2PMCR",
6455 SPR_NOACCESS
, SPR_NOACCESS
,
6456 &spr_read_generic
, &spr_write_generic
,
6458 /* Thermal management */
6460 /* Hardware implementation registers */
6461 /* XXX : not implemented */
6462 spr_register(env
, SPR_HID0
, "HID0",
6463 SPR_NOACCESS
, SPR_NOACCESS
,
6464 &spr_read_generic
, &spr_write_generic
,
6466 /* XXX : not implemented */
6467 spr_register(env
, SPR_HID1
, "HID1",
6468 SPR_NOACCESS
, SPR_NOACCESS
,
6469 &spr_read_generic
, &spr_write_generic
,
6471 /* XXX : not implemented */
6472 spr_register(env
, SPR_HID2
, "HID2",
6473 SPR_NOACCESS
, SPR_NOACCESS
,
6474 &spr_read_generic
, &spr_write_generic
,
6476 /* Memory management */
6479 gen_6xx_7xx_soft_tlb(env
, 64, 2);
6481 env
->dcache_line_size
= 32;
6482 env
->icache_line_size
= 32;
6483 /* Allocate hardware IRQ controller */
6484 ppc6xx_irq_init(env_archcpu(env
));
6487 POWERPC_FAMILY(755)(ObjectClass
*oc
, void *data
)
6489 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6490 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6492 dc
->desc
= "PowerPC 755";
6493 pcc
->init_proc
= init_proc_755
;
6494 pcc
->check_pow
= check_pow_hid0
;
6495 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6496 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6497 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6498 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6499 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6500 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
6501 PPC_SEGMENT
| PPC_EXTERN
;
6502 pcc
->msr_mask
= (1ull << MSR_POW
) |
6518 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
6519 pcc
->excp_model
= POWERPC_EXCP_7x5
;
6520 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6521 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6522 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6523 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6526 static void init_proc_7400(CPUPPCState
*env
)
6528 gen_spr_ne_601(env
);
6533 /* 74xx specific SPR */
6535 /* XXX : not implemented */
6536 spr_register(env
, SPR_UBAMR
, "UBAMR",
6537 &spr_read_ureg
, SPR_NOACCESS
,
6538 &spr_read_ureg
, SPR_NOACCESS
,
6540 /* XXX: this seems not implemented on all revisions. */
6541 /* XXX : not implemented */
6542 spr_register(env
, SPR_MSSCR1
, "MSSCR1",
6543 SPR_NOACCESS
, SPR_NOACCESS
,
6544 &spr_read_generic
, &spr_write_generic
,
6546 /* Thermal management */
6548 /* Memory management */
6550 init_excp_7400(env
);
6551 env
->dcache_line_size
= 32;
6552 env
->icache_line_size
= 32;
6553 /* Allocate hardware IRQ controller */
6554 ppc6xx_irq_init(env_archcpu(env
));
6557 POWERPC_FAMILY(7400)(ObjectClass
*oc
, void *data
)
6559 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6560 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6562 dc
->desc
= "PowerPC 7400 (aka G4)";
6563 pcc
->init_proc
= init_proc_7400
;
6564 pcc
->check_pow
= check_pow_hid0
;
6565 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6566 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6567 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6569 PPC_CACHE
| PPC_CACHE_ICBI
|
6570 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6571 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6572 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6574 PPC_SEGMENT
| PPC_EXTERN
|
6576 pcc
->msr_mask
= (1ull << MSR_VR
) |
6593 pcc
->mmu_model
= POWERPC_MMU_32B
;
6594 #if defined(CONFIG_SOFTMMU)
6595 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6597 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6598 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6599 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6600 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6601 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6602 POWERPC_FLAG_BUS_CLK
;
6605 static void init_proc_7410(CPUPPCState
*env
)
6607 gen_spr_ne_601(env
);
6612 /* 74xx specific SPR */
6614 /* XXX : not implemented */
6615 spr_register(env
, SPR_UBAMR
, "UBAMR",
6616 &spr_read_ureg
, SPR_NOACCESS
,
6617 &spr_read_ureg
, SPR_NOACCESS
,
6619 /* Thermal management */
6622 /* XXX : not implemented */
6623 spr_register(env
, SPR_L2PMCR
, "L2PMCR",
6624 SPR_NOACCESS
, SPR_NOACCESS
,
6625 &spr_read_generic
, &spr_write_generic
,
6628 /* XXX : not implemented */
6629 spr_register(env
, SPR_LDSTDB
, "LDSTDB",
6630 SPR_NOACCESS
, SPR_NOACCESS
,
6631 &spr_read_generic
, &spr_write_generic
,
6633 /* Memory management */
6635 init_excp_7400(env
);
6636 env
->dcache_line_size
= 32;
6637 env
->icache_line_size
= 32;
6638 /* Allocate hardware IRQ controller */
6639 ppc6xx_irq_init(env_archcpu(env
));
6642 POWERPC_FAMILY(7410)(ObjectClass
*oc
, void *data
)
6644 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6645 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6647 dc
->desc
= "PowerPC 7410 (aka G4)";
6648 pcc
->init_proc
= init_proc_7410
;
6649 pcc
->check_pow
= check_pow_hid0
;
6650 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6651 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6652 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6654 PPC_CACHE
| PPC_CACHE_ICBI
|
6655 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6656 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6657 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6659 PPC_SEGMENT
| PPC_EXTERN
|
6661 pcc
->msr_mask
= (1ull << MSR_VR
) |
6678 pcc
->mmu_model
= POWERPC_MMU_32B
;
6679 #if defined(CONFIG_SOFTMMU)
6680 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6682 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6683 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6684 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6685 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6686 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6687 POWERPC_FLAG_BUS_CLK
;
6690 static void init_proc_7440(CPUPPCState
*env
)
6692 gen_spr_ne_601(env
);
6697 /* 74xx specific SPR */
6699 /* XXX : not implemented */
6700 spr_register(env
, SPR_UBAMR
, "UBAMR",
6701 &spr_read_ureg
, SPR_NOACCESS
,
6702 &spr_read_ureg
, SPR_NOACCESS
,
6705 /* XXX : not implemented */
6706 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6707 SPR_NOACCESS
, SPR_NOACCESS
,
6708 &spr_read_generic
, &spr_write_generic
,
6711 /* XXX : not implemented */
6712 spr_register(env
, SPR_ICTRL
, "ICTRL",
6713 SPR_NOACCESS
, SPR_NOACCESS
,
6714 &spr_read_generic
, &spr_write_generic
,
6717 /* XXX : not implemented */
6718 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6719 SPR_NOACCESS
, SPR_NOACCESS
,
6720 &spr_read_generic
, &spr_write_generic
,
6723 /* XXX : not implemented */
6724 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6725 SPR_NOACCESS
, SPR_NOACCESS
,
6726 &spr_read_generic
, &spr_write_generic
,
6728 /* XXX : not implemented */
6729 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6730 &spr_read_ureg
, SPR_NOACCESS
,
6731 &spr_read_ureg
, SPR_NOACCESS
,
6733 /* XXX : not implemented */
6734 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6735 SPR_NOACCESS
, SPR_NOACCESS
,
6736 &spr_read_generic
, &spr_write_generic
,
6738 /* XXX : not implemented */
6739 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6740 &spr_read_ureg
, SPR_NOACCESS
,
6741 &spr_read_ureg
, SPR_NOACCESS
,
6743 /* Memory management */
6745 gen_74xx_soft_tlb(env
, 128, 2);
6746 init_excp_7450(env
);
6747 env
->dcache_line_size
= 32;
6748 env
->icache_line_size
= 32;
6749 /* Allocate hardware IRQ controller */
6750 ppc6xx_irq_init(env_archcpu(env
));
6753 POWERPC_FAMILY(7440)(ObjectClass
*oc
, void *data
)
6755 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6756 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6758 dc
->desc
= "PowerPC 7440 (aka G4)";
6759 pcc
->init_proc
= init_proc_7440
;
6760 pcc
->check_pow
= check_pow_hid0_74xx
;
6761 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6762 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6763 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6765 PPC_CACHE
| PPC_CACHE_ICBI
|
6766 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6767 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6768 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6769 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6770 PPC_SEGMENT
| PPC_EXTERN
|
6772 pcc
->msr_mask
= (1ull << MSR_VR
) |
6789 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6790 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6791 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6792 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6793 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6794 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6795 POWERPC_FLAG_BUS_CLK
;
6798 static void init_proc_7450(CPUPPCState
*env
)
6800 gen_spr_ne_601(env
);
6805 /* 74xx specific SPR */
6807 /* Level 3 cache control */
6810 /* XXX : not implemented */
6811 spr_register(env
, SPR_L3ITCR1
, "L3ITCR1",
6812 SPR_NOACCESS
, SPR_NOACCESS
,
6813 &spr_read_generic
, &spr_write_generic
,
6816 /* XXX : not implemented */
6817 spr_register(env
, SPR_L3ITCR2
, "L3ITCR2",
6818 SPR_NOACCESS
, SPR_NOACCESS
,
6819 &spr_read_generic
, &spr_write_generic
,
6822 /* XXX : not implemented */
6823 spr_register(env
, SPR_L3ITCR3
, "L3ITCR3",
6824 SPR_NOACCESS
, SPR_NOACCESS
,
6825 &spr_read_generic
, &spr_write_generic
,
6828 /* XXX : not implemented */
6829 spr_register(env
, SPR_L3OHCR
, "L3OHCR",
6830 SPR_NOACCESS
, SPR_NOACCESS
,
6831 &spr_read_generic
, &spr_write_generic
,
6833 /* XXX : not implemented */
6834 spr_register(env
, SPR_UBAMR
, "UBAMR",
6835 &spr_read_ureg
, SPR_NOACCESS
,
6836 &spr_read_ureg
, SPR_NOACCESS
,
6839 /* XXX : not implemented */
6840 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6841 SPR_NOACCESS
, SPR_NOACCESS
,
6842 &spr_read_generic
, &spr_write_generic
,
6845 /* XXX : not implemented */
6846 spr_register(env
, SPR_ICTRL
, "ICTRL",
6847 SPR_NOACCESS
, SPR_NOACCESS
,
6848 &spr_read_generic
, &spr_write_generic
,
6851 /* XXX : not implemented */
6852 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6853 SPR_NOACCESS
, SPR_NOACCESS
,
6854 &spr_read_generic
, &spr_write_generic
,
6857 /* XXX : not implemented */
6858 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6859 SPR_NOACCESS
, SPR_NOACCESS
,
6860 &spr_read_generic
, &spr_write_generic
,
6862 /* XXX : not implemented */
6863 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6864 &spr_read_ureg
, SPR_NOACCESS
,
6865 &spr_read_ureg
, SPR_NOACCESS
,
6867 /* XXX : not implemented */
6868 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6869 SPR_NOACCESS
, SPR_NOACCESS
,
6870 &spr_read_generic
, &spr_write_generic
,
6872 /* XXX : not implemented */
6873 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6874 &spr_read_ureg
, SPR_NOACCESS
,
6875 &spr_read_ureg
, SPR_NOACCESS
,
6877 /* Memory management */
6879 gen_74xx_soft_tlb(env
, 128, 2);
6880 init_excp_7450(env
);
6881 env
->dcache_line_size
= 32;
6882 env
->icache_line_size
= 32;
6883 /* Allocate hardware IRQ controller */
6884 ppc6xx_irq_init(env_archcpu(env
));
6887 POWERPC_FAMILY(7450)(ObjectClass
*oc
, void *data
)
6889 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6890 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6892 dc
->desc
= "PowerPC 7450 (aka G4)";
6893 pcc
->init_proc
= init_proc_7450
;
6894 pcc
->check_pow
= check_pow_hid0_74xx
;
6895 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6896 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6897 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6899 PPC_CACHE
| PPC_CACHE_ICBI
|
6900 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6901 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6902 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6903 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6904 PPC_SEGMENT
| PPC_EXTERN
|
6906 pcc
->msr_mask
= (1ull << MSR_VR
) |
6923 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6924 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6925 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6926 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6927 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6928 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6929 POWERPC_FLAG_BUS_CLK
;
6932 static void init_proc_7445(CPUPPCState
*env
)
6934 gen_spr_ne_601(env
);
6939 /* 74xx specific SPR */
6942 /* XXX : not implemented */
6943 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6944 SPR_NOACCESS
, SPR_NOACCESS
,
6945 &spr_read_generic
, &spr_write_generic
,
6948 /* XXX : not implemented */
6949 spr_register(env
, SPR_ICTRL
, "ICTRL",
6950 SPR_NOACCESS
, SPR_NOACCESS
,
6951 &spr_read_generic
, &spr_write_generic
,
6954 /* XXX : not implemented */
6955 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6956 SPR_NOACCESS
, SPR_NOACCESS
,
6957 &spr_read_generic
, &spr_write_generic
,
6960 /* XXX : not implemented */
6961 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6962 SPR_NOACCESS
, SPR_NOACCESS
,
6963 &spr_read_generic
, &spr_write_generic
,
6965 /* XXX : not implemented */
6966 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6967 &spr_read_ureg
, SPR_NOACCESS
,
6968 &spr_read_ureg
, SPR_NOACCESS
,
6970 /* XXX : not implemented */
6971 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6972 SPR_NOACCESS
, SPR_NOACCESS
,
6973 &spr_read_generic
, &spr_write_generic
,
6975 /* XXX : not implemented */
6976 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6977 &spr_read_ureg
, SPR_NOACCESS
,
6978 &spr_read_ureg
, SPR_NOACCESS
,
6981 spr_register(env
, SPR_SPRG4
, "SPRG4",
6982 SPR_NOACCESS
, SPR_NOACCESS
,
6983 &spr_read_generic
, &spr_write_generic
,
6985 spr_register(env
, SPR_USPRG4
, "USPRG4",
6986 &spr_read_ureg
, SPR_NOACCESS
,
6987 &spr_read_ureg
, SPR_NOACCESS
,
6989 spr_register(env
, SPR_SPRG5
, "SPRG5",
6990 SPR_NOACCESS
, SPR_NOACCESS
,
6991 &spr_read_generic
, &spr_write_generic
,
6993 spr_register(env
, SPR_USPRG5
, "USPRG5",
6994 &spr_read_ureg
, SPR_NOACCESS
,
6995 &spr_read_ureg
, SPR_NOACCESS
,
6997 spr_register(env
, SPR_SPRG6
, "SPRG6",
6998 SPR_NOACCESS
, SPR_NOACCESS
,
6999 &spr_read_generic
, &spr_write_generic
,
7001 spr_register(env
, SPR_USPRG6
, "USPRG6",
7002 &spr_read_ureg
, SPR_NOACCESS
,
7003 &spr_read_ureg
, SPR_NOACCESS
,
7005 spr_register(env
, SPR_SPRG7
, "SPRG7",
7006 SPR_NOACCESS
, SPR_NOACCESS
,
7007 &spr_read_generic
, &spr_write_generic
,
7009 spr_register(env
, SPR_USPRG7
, "USPRG7",
7010 &spr_read_ureg
, SPR_NOACCESS
,
7011 &spr_read_ureg
, SPR_NOACCESS
,
7013 /* Memory management */
7016 gen_74xx_soft_tlb(env
, 128, 2);
7017 init_excp_7450(env
);
7018 env
->dcache_line_size
= 32;
7019 env
->icache_line_size
= 32;
7020 /* Allocate hardware IRQ controller */
7021 ppc6xx_irq_init(env_archcpu(env
));
7024 POWERPC_FAMILY(7445)(ObjectClass
*oc
, void *data
)
7026 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7027 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7029 dc
->desc
= "PowerPC 7445 (aka G4)";
7030 pcc
->init_proc
= init_proc_7445
;
7031 pcc
->check_pow
= check_pow_hid0_74xx
;
7032 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7033 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7034 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7036 PPC_CACHE
| PPC_CACHE_ICBI
|
7037 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7038 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7039 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7040 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7041 PPC_SEGMENT
| PPC_EXTERN
|
7043 pcc
->msr_mask
= (1ull << MSR_VR
) |
7060 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7061 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7062 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7063 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7064 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7065 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7066 POWERPC_FLAG_BUS_CLK
;
7069 static void init_proc_7455(CPUPPCState
*env
)
7071 gen_spr_ne_601(env
);
7076 /* 74xx specific SPR */
7078 /* Level 3 cache control */
7081 /* XXX : not implemented */
7082 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7083 SPR_NOACCESS
, SPR_NOACCESS
,
7084 &spr_read_generic
, &spr_write_generic
,
7087 /* XXX : not implemented */
7088 spr_register(env
, SPR_ICTRL
, "ICTRL",
7089 SPR_NOACCESS
, SPR_NOACCESS
,
7090 &spr_read_generic
, &spr_write_generic
,
7093 /* XXX : not implemented */
7094 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7095 SPR_NOACCESS
, SPR_NOACCESS
,
7096 &spr_read_generic
, &spr_write_generic
,
7099 /* XXX : not implemented */
7100 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7101 SPR_NOACCESS
, SPR_NOACCESS
,
7102 &spr_read_generic
, &spr_write_generic
,
7104 /* XXX : not implemented */
7105 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7106 &spr_read_ureg
, SPR_NOACCESS
,
7107 &spr_read_ureg
, SPR_NOACCESS
,
7109 /* XXX : not implemented */
7110 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7111 SPR_NOACCESS
, SPR_NOACCESS
,
7112 &spr_read_generic
, &spr_write_generic
,
7114 /* XXX : not implemented */
7115 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7116 &spr_read_ureg
, SPR_NOACCESS
,
7117 &spr_read_ureg
, SPR_NOACCESS
,
7120 spr_register(env
, SPR_SPRG4
, "SPRG4",
7121 SPR_NOACCESS
, SPR_NOACCESS
,
7122 &spr_read_generic
, &spr_write_generic
,
7124 spr_register(env
, SPR_USPRG4
, "USPRG4",
7125 &spr_read_ureg
, SPR_NOACCESS
,
7126 &spr_read_ureg
, SPR_NOACCESS
,
7128 spr_register(env
, SPR_SPRG5
, "SPRG5",
7129 SPR_NOACCESS
, SPR_NOACCESS
,
7130 &spr_read_generic
, &spr_write_generic
,
7132 spr_register(env
, SPR_USPRG5
, "USPRG5",
7133 &spr_read_ureg
, SPR_NOACCESS
,
7134 &spr_read_ureg
, SPR_NOACCESS
,
7136 spr_register(env
, SPR_SPRG6
, "SPRG6",
7137 SPR_NOACCESS
, SPR_NOACCESS
,
7138 &spr_read_generic
, &spr_write_generic
,
7140 spr_register(env
, SPR_USPRG6
, "USPRG6",
7141 &spr_read_ureg
, SPR_NOACCESS
,
7142 &spr_read_ureg
, SPR_NOACCESS
,
7144 spr_register(env
, SPR_SPRG7
, "SPRG7",
7145 SPR_NOACCESS
, SPR_NOACCESS
,
7146 &spr_read_generic
, &spr_write_generic
,
7148 spr_register(env
, SPR_USPRG7
, "USPRG7",
7149 &spr_read_ureg
, SPR_NOACCESS
,
7150 &spr_read_ureg
, SPR_NOACCESS
,
7152 /* Memory management */
7155 gen_74xx_soft_tlb(env
, 128, 2);
7156 init_excp_7450(env
);
7157 env
->dcache_line_size
= 32;
7158 env
->icache_line_size
= 32;
7159 /* Allocate hardware IRQ controller */
7160 ppc6xx_irq_init(env_archcpu(env
));
7163 POWERPC_FAMILY(7455)(ObjectClass
*oc
, void *data
)
7165 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7166 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7168 dc
->desc
= "PowerPC 7455 (aka G4)";
7169 pcc
->init_proc
= init_proc_7455
;
7170 pcc
->check_pow
= check_pow_hid0_74xx
;
7171 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7172 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7173 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7175 PPC_CACHE
| PPC_CACHE_ICBI
|
7176 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7177 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7178 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7179 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7180 PPC_SEGMENT
| PPC_EXTERN
|
7182 pcc
->msr_mask
= (1ull << MSR_VR
) |
7199 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7200 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7201 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7202 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7203 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7204 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7205 POWERPC_FLAG_BUS_CLK
;
7208 static void init_proc_7457(CPUPPCState
*env
)
7210 gen_spr_ne_601(env
);
7215 /* 74xx specific SPR */
7217 /* Level 3 cache control */
7220 /* XXX : not implemented */
7221 spr_register(env
, SPR_L3ITCR1
, "L3ITCR1",
7222 SPR_NOACCESS
, SPR_NOACCESS
,
7223 &spr_read_generic
, &spr_write_generic
,
7226 /* XXX : not implemented */
7227 spr_register(env
, SPR_L3ITCR2
, "L3ITCR2",
7228 SPR_NOACCESS
, SPR_NOACCESS
,
7229 &spr_read_generic
, &spr_write_generic
,
7232 /* XXX : not implemented */
7233 spr_register(env
, SPR_L3ITCR3
, "L3ITCR3",
7234 SPR_NOACCESS
, SPR_NOACCESS
,
7235 &spr_read_generic
, &spr_write_generic
,
7238 /* XXX : not implemented */
7239 spr_register(env
, SPR_L3OHCR
, "L3OHCR",
7240 SPR_NOACCESS
, SPR_NOACCESS
,
7241 &spr_read_generic
, &spr_write_generic
,
7244 /* XXX : not implemented */
7245 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7246 SPR_NOACCESS
, SPR_NOACCESS
,
7247 &spr_read_generic
, &spr_write_generic
,
7250 /* XXX : not implemented */
7251 spr_register(env
, SPR_ICTRL
, "ICTRL",
7252 SPR_NOACCESS
, SPR_NOACCESS
,
7253 &spr_read_generic
, &spr_write_generic
,
7256 /* XXX : not implemented */
7257 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7258 SPR_NOACCESS
, SPR_NOACCESS
,
7259 &spr_read_generic
, &spr_write_generic
,
7262 /* XXX : not implemented */
7263 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7264 SPR_NOACCESS
, SPR_NOACCESS
,
7265 &spr_read_generic
, &spr_write_generic
,
7267 /* XXX : not implemented */
7268 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7269 &spr_read_ureg
, SPR_NOACCESS
,
7270 &spr_read_ureg
, SPR_NOACCESS
,
7272 /* XXX : not implemented */
7273 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7274 SPR_NOACCESS
, SPR_NOACCESS
,
7275 &spr_read_generic
, &spr_write_generic
,
7277 /* XXX : not implemented */
7278 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7279 &spr_read_ureg
, SPR_NOACCESS
,
7280 &spr_read_ureg
, SPR_NOACCESS
,
7283 spr_register(env
, SPR_SPRG4
, "SPRG4",
7284 SPR_NOACCESS
, SPR_NOACCESS
,
7285 &spr_read_generic
, &spr_write_generic
,
7287 spr_register(env
, SPR_USPRG4
, "USPRG4",
7288 &spr_read_ureg
, SPR_NOACCESS
,
7289 &spr_read_ureg
, SPR_NOACCESS
,
7291 spr_register(env
, SPR_SPRG5
, "SPRG5",
7292 SPR_NOACCESS
, SPR_NOACCESS
,
7293 &spr_read_generic
, &spr_write_generic
,
7295 spr_register(env
, SPR_USPRG5
, "USPRG5",
7296 &spr_read_ureg
, SPR_NOACCESS
,
7297 &spr_read_ureg
, SPR_NOACCESS
,
7299 spr_register(env
, SPR_SPRG6
, "SPRG6",
7300 SPR_NOACCESS
, SPR_NOACCESS
,
7301 &spr_read_generic
, &spr_write_generic
,
7303 spr_register(env
, SPR_USPRG6
, "USPRG6",
7304 &spr_read_ureg
, SPR_NOACCESS
,
7305 &spr_read_ureg
, SPR_NOACCESS
,
7307 spr_register(env
, SPR_SPRG7
, "SPRG7",
7308 SPR_NOACCESS
, SPR_NOACCESS
,
7309 &spr_read_generic
, &spr_write_generic
,
7311 spr_register(env
, SPR_USPRG7
, "USPRG7",
7312 &spr_read_ureg
, SPR_NOACCESS
,
7313 &spr_read_ureg
, SPR_NOACCESS
,
7315 /* Memory management */
7318 gen_74xx_soft_tlb(env
, 128, 2);
7319 init_excp_7450(env
);
7320 env
->dcache_line_size
= 32;
7321 env
->icache_line_size
= 32;
7322 /* Allocate hardware IRQ controller */
7323 ppc6xx_irq_init(env_archcpu(env
));
7326 POWERPC_FAMILY(7457)(ObjectClass
*oc
, void *data
)
7328 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7329 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7331 dc
->desc
= "PowerPC 7457 (aka G4)";
7332 pcc
->init_proc
= init_proc_7457
;
7333 pcc
->check_pow
= check_pow_hid0_74xx
;
7334 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7335 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7336 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7338 PPC_CACHE
| PPC_CACHE_ICBI
|
7339 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7340 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7341 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7342 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7343 PPC_SEGMENT
| PPC_EXTERN
|
7345 pcc
->msr_mask
= (1ull << MSR_VR
) |
7362 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7363 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7364 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7365 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7366 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7367 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7368 POWERPC_FLAG_BUS_CLK
;
7371 static void init_proc_e600(CPUPPCState
*env
)
7373 gen_spr_ne_601(env
);
7378 /* 74xx specific SPR */
7380 /* XXX : not implemented */
7381 spr_register(env
, SPR_UBAMR
, "UBAMR",
7382 &spr_read_ureg
, SPR_NOACCESS
,
7383 &spr_read_ureg
, SPR_NOACCESS
,
7385 /* XXX : not implemented */
7386 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7387 SPR_NOACCESS
, SPR_NOACCESS
,
7388 &spr_read_generic
, &spr_write_generic
,
7390 /* XXX : not implemented */
7391 spr_register(env
, SPR_ICTRL
, "ICTRL",
7392 SPR_NOACCESS
, SPR_NOACCESS
,
7393 &spr_read_generic
, &spr_write_generic
,
7395 /* XXX : not implemented */
7396 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7397 SPR_NOACCESS
, SPR_NOACCESS
,
7398 &spr_read_generic
, &spr_write_generic
,
7400 /* XXX : not implemented */
7401 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7402 SPR_NOACCESS
, SPR_NOACCESS
,
7403 &spr_read_generic
, &spr_write_generic
,
7405 /* XXX : not implemented */
7406 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7407 &spr_read_ureg
, SPR_NOACCESS
,
7408 &spr_read_ureg
, SPR_NOACCESS
,
7410 /* XXX : not implemented */
7411 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7412 SPR_NOACCESS
, SPR_NOACCESS
,
7413 &spr_read_generic
, &spr_write_generic
,
7415 /* XXX : not implemented */
7416 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7417 &spr_read_ureg
, SPR_NOACCESS
,
7418 &spr_read_ureg
, SPR_NOACCESS
,
7421 spr_register(env
, SPR_SPRG4
, "SPRG4",
7422 SPR_NOACCESS
, SPR_NOACCESS
,
7423 &spr_read_generic
, &spr_write_generic
,
7425 spr_register(env
, SPR_USPRG4
, "USPRG4",
7426 &spr_read_ureg
, SPR_NOACCESS
,
7427 &spr_read_ureg
, SPR_NOACCESS
,
7429 spr_register(env
, SPR_SPRG5
, "SPRG5",
7430 SPR_NOACCESS
, SPR_NOACCESS
,
7431 &spr_read_generic
, &spr_write_generic
,
7433 spr_register(env
, SPR_USPRG5
, "USPRG5",
7434 &spr_read_ureg
, SPR_NOACCESS
,
7435 &spr_read_ureg
, SPR_NOACCESS
,
7437 spr_register(env
, SPR_SPRG6
, "SPRG6",
7438 SPR_NOACCESS
, SPR_NOACCESS
,
7439 &spr_read_generic
, &spr_write_generic
,
7441 spr_register(env
, SPR_USPRG6
, "USPRG6",
7442 &spr_read_ureg
, SPR_NOACCESS
,
7443 &spr_read_ureg
, SPR_NOACCESS
,
7445 spr_register(env
, SPR_SPRG7
, "SPRG7",
7446 SPR_NOACCESS
, SPR_NOACCESS
,
7447 &spr_read_generic
, &spr_write_generic
,
7449 spr_register(env
, SPR_USPRG7
, "USPRG7",
7450 &spr_read_ureg
, SPR_NOACCESS
,
7451 &spr_read_ureg
, SPR_NOACCESS
,
7453 /* Memory management */
7456 gen_74xx_soft_tlb(env
, 128, 2);
7457 init_excp_7450(env
);
7458 env
->dcache_line_size
= 32;
7459 env
->icache_line_size
= 32;
7460 /* Allocate hardware IRQ controller */
7461 ppc6xx_irq_init(env_archcpu(env
));
7464 POWERPC_FAMILY(e600
)(ObjectClass
*oc
, void *data
)
7466 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7467 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7469 dc
->desc
= "PowerPC e600";
7470 pcc
->init_proc
= init_proc_e600
;
7471 pcc
->check_pow
= check_pow_hid0_74xx
;
7472 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7473 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7474 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7476 PPC_CACHE
| PPC_CACHE_ICBI
|
7477 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7478 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7479 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7480 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7481 PPC_SEGMENT
| PPC_EXTERN
|
7483 pcc
->insns_flags2
= PPC_NONE
;
7484 pcc
->msr_mask
= (1ull << MSR_VR
) |
7501 pcc
->mmu_model
= POWERPC_MMU_32B
;
7502 #if defined(CONFIG_SOFTMMU)
7503 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
7505 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7506 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7507 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7508 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7509 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7510 POWERPC_FLAG_BUS_CLK
;
7513 #if defined(TARGET_PPC64)
7514 #if defined(CONFIG_USER_ONLY)
7515 #define POWERPC970_HID5_INIT 0x00000080
7517 #define POWERPC970_HID5_INIT 0x00000000
7520 static void gen_fscr_facility_check(DisasContext
*ctx
, int facility_sprn
,
7521 int bit
, int sprn
, int cause
)
7523 TCGv_i32 t1
= tcg_const_i32(bit
);
7524 TCGv_i32 t2
= tcg_const_i32(sprn
);
7525 TCGv_i32 t3
= tcg_const_i32(cause
);
7527 gen_helper_fscr_facility_check(cpu_env
, t1
, t2
, t3
);
7529 tcg_temp_free_i32(t3
);
7530 tcg_temp_free_i32(t2
);
7531 tcg_temp_free_i32(t1
);
7534 static void gen_msr_facility_check(DisasContext
*ctx
, int facility_sprn
,
7535 int bit
, int sprn
, int cause
)
7537 TCGv_i32 t1
= tcg_const_i32(bit
);
7538 TCGv_i32 t2
= tcg_const_i32(sprn
);
7539 TCGv_i32 t3
= tcg_const_i32(cause
);
7541 gen_helper_msr_facility_check(cpu_env
, t1
, t2
, t3
);
7543 tcg_temp_free_i32(t3
);
7544 tcg_temp_free_i32(t2
);
7545 tcg_temp_free_i32(t1
);
7548 static void spr_read_prev_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
7550 TCGv spr_up
= tcg_temp_new();
7551 TCGv spr
= tcg_temp_new();
7553 gen_load_spr(spr
, sprn
- 1);
7554 tcg_gen_shri_tl(spr_up
, spr
, 32);
7555 tcg_gen_ext32u_tl(cpu_gpr
[gprn
], spr_up
);
7558 tcg_temp_free(spr_up
);
7561 static void spr_write_prev_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
7563 TCGv spr
= tcg_temp_new();
7565 gen_load_spr(spr
, sprn
- 1);
7566 tcg_gen_deposit_tl(spr
, spr
, cpu_gpr
[gprn
], 32, 32);
7567 gen_store_spr(sprn
- 1, spr
);
7572 static int check_pow_970(CPUPPCState
*env
)
7574 if (env
->spr
[SPR_HID0
] & (HID0_DEEPNAP
| HID0_DOZE
| HID0_NAP
)) {
7581 static void gen_spr_970_hid(CPUPPCState
*env
)
7583 /* Hardware implementation registers */
7584 /* XXX : not implemented */
7585 spr_register(env
, SPR_HID0
, "HID0",
7586 SPR_NOACCESS
, SPR_NOACCESS
,
7587 &spr_read_generic
, &spr_write_clear
,
7589 spr_register(env
, SPR_HID1
, "HID1",
7590 SPR_NOACCESS
, SPR_NOACCESS
,
7591 &spr_read_generic
, &spr_write_generic
,
7593 spr_register(env
, SPR_970_HID5
, "HID5",
7594 SPR_NOACCESS
, SPR_NOACCESS
,
7595 &spr_read_generic
, &spr_write_generic
,
7596 POWERPC970_HID5_INIT
);
7599 static void gen_spr_970_hior(CPUPPCState
*env
)
7601 spr_register(env
, SPR_HIOR
, "SPR_HIOR",
7602 SPR_NOACCESS
, SPR_NOACCESS
,
7603 &spr_read_hior
, &spr_write_hior
,
7607 static void gen_spr_book3s_ctrl(CPUPPCState
*env
)
7609 spr_register(env
, SPR_CTRL
, "SPR_CTRL",
7610 SPR_NOACCESS
, SPR_NOACCESS
,
7611 SPR_NOACCESS
, &spr_write_generic
,
7613 spr_register(env
, SPR_UCTRL
, "SPR_UCTRL",
7614 &spr_read_ureg
, SPR_NOACCESS
,
7615 &spr_read_ureg
, SPR_NOACCESS
,
7619 static void gen_spr_book3s_altivec(CPUPPCState
*env
)
7621 if (!(env
->insns_flags
& PPC_ALTIVEC
)) {
7625 spr_register_kvm(env
, SPR_VRSAVE
, "VRSAVE",
7626 &spr_read_generic
, &spr_write_generic
,
7627 &spr_read_generic
, &spr_write_generic
,
7628 KVM_REG_PPC_VRSAVE
, 0x00000000);
7631 * Can't find information on what this should be on reset. This
7632 * value is the one used by 74xx processors.
7634 vscr_init(env
, 0x00010000);
7637 static void gen_spr_book3s_dbg(CPUPPCState
*env
)
7640 * TODO: different specs define different scopes for these,
7641 * will have to address this:
7642 * 970: super/write and super/read
7643 * powerisa 2.03..2.04: hypv/write and super/read.
7644 * powerisa 2.05 and newer: hypv/write and hypv/read.
7646 spr_register_kvm(env
, SPR_DABR
, "DABR",
7647 SPR_NOACCESS
, SPR_NOACCESS
,
7648 &spr_read_generic
, &spr_write_generic
,
7649 KVM_REG_PPC_DABR
, 0x00000000);
7650 spr_register_kvm(env
, SPR_DABRX
, "DABRX",
7651 SPR_NOACCESS
, SPR_NOACCESS
,
7652 &spr_read_generic
, &spr_write_generic
,
7653 KVM_REG_PPC_DABRX
, 0x00000000);
7656 static void gen_spr_book3s_207_dbg(CPUPPCState
*env
)
7658 spr_register_kvm_hv(env
, SPR_DAWR
, "DAWR",
7659 SPR_NOACCESS
, SPR_NOACCESS
,
7660 SPR_NOACCESS
, SPR_NOACCESS
,
7661 &spr_read_generic
, &spr_write_generic
,
7662 KVM_REG_PPC_DAWR
, 0x00000000);
7663 spr_register_kvm_hv(env
, SPR_DAWRX
, "DAWRX",
7664 SPR_NOACCESS
, SPR_NOACCESS
,
7665 SPR_NOACCESS
, SPR_NOACCESS
,
7666 &spr_read_generic
, &spr_write_generic
,
7667 KVM_REG_PPC_DAWRX
, 0x00000000);
7668 spr_register_kvm_hv(env
, SPR_CIABR
, "CIABR",
7669 SPR_NOACCESS
, SPR_NOACCESS
,
7670 SPR_NOACCESS
, SPR_NOACCESS
,
7671 &spr_read_generic
, &spr_write_generic
,
7672 KVM_REG_PPC_CIABR
, 0x00000000);
7675 static void gen_spr_970_dbg(CPUPPCState
*env
)
7678 spr_register(env
, SPR_IABR
, "IABR",
7679 SPR_NOACCESS
, SPR_NOACCESS
,
7680 &spr_read_generic
, &spr_write_generic
,
7684 static void gen_spr_book3s_pmu_sup(CPUPPCState
*env
)
7686 spr_register_kvm(env
, SPR_POWER_MMCR0
, "MMCR0",
7687 SPR_NOACCESS
, SPR_NOACCESS
,
7688 &spr_read_generic
, &spr_write_generic
,
7689 KVM_REG_PPC_MMCR0
, 0x00000000);
7690 spr_register_kvm(env
, SPR_POWER_MMCR1
, "MMCR1",
7691 SPR_NOACCESS
, SPR_NOACCESS
,
7692 &spr_read_generic
, &spr_write_generic
,
7693 KVM_REG_PPC_MMCR1
, 0x00000000);
7694 spr_register_kvm(env
, SPR_POWER_MMCRA
, "MMCRA",
7695 SPR_NOACCESS
, SPR_NOACCESS
,
7696 &spr_read_generic
, &spr_write_generic
,
7697 KVM_REG_PPC_MMCRA
, 0x00000000);
7698 spr_register_kvm(env
, SPR_POWER_PMC1
, "PMC1",
7699 SPR_NOACCESS
, SPR_NOACCESS
,
7700 &spr_read_generic
, &spr_write_generic
,
7701 KVM_REG_PPC_PMC1
, 0x00000000);
7702 spr_register_kvm(env
, SPR_POWER_PMC2
, "PMC2",
7703 SPR_NOACCESS
, SPR_NOACCESS
,
7704 &spr_read_generic
, &spr_write_generic
,
7705 KVM_REG_PPC_PMC2
, 0x00000000);
7706 spr_register_kvm(env
, SPR_POWER_PMC3
, "PMC3",
7707 SPR_NOACCESS
, SPR_NOACCESS
,
7708 &spr_read_generic
, &spr_write_generic
,
7709 KVM_REG_PPC_PMC3
, 0x00000000);
7710 spr_register_kvm(env
, SPR_POWER_PMC4
, "PMC4",
7711 SPR_NOACCESS
, SPR_NOACCESS
,
7712 &spr_read_generic
, &spr_write_generic
,
7713 KVM_REG_PPC_PMC4
, 0x00000000);
7714 spr_register_kvm(env
, SPR_POWER_PMC5
, "PMC5",
7715 SPR_NOACCESS
, SPR_NOACCESS
,
7716 &spr_read_generic
, &spr_write_generic
,
7717 KVM_REG_PPC_PMC5
, 0x00000000);
7718 spr_register_kvm(env
, SPR_POWER_PMC6
, "PMC6",
7719 SPR_NOACCESS
, SPR_NOACCESS
,
7720 &spr_read_generic
, &spr_write_generic
,
7721 KVM_REG_PPC_PMC6
, 0x00000000);
7722 spr_register_kvm(env
, SPR_POWER_SIAR
, "SIAR",
7723 SPR_NOACCESS
, SPR_NOACCESS
,
7724 &spr_read_generic
, &spr_write_generic
,
7725 KVM_REG_PPC_SIAR
, 0x00000000);
7726 spr_register_kvm(env
, SPR_POWER_SDAR
, "SDAR",
7727 SPR_NOACCESS
, SPR_NOACCESS
,
7728 &spr_read_generic
, &spr_write_generic
,
7729 KVM_REG_PPC_SDAR
, 0x00000000);
7732 static void gen_spr_book3s_pmu_user(CPUPPCState
*env
)
7734 spr_register(env
, SPR_POWER_UMMCR0
, "UMMCR0",
7735 &spr_read_ureg
, SPR_NOACCESS
,
7736 &spr_read_ureg
, &spr_write_ureg
,
7738 spr_register(env
, SPR_POWER_UMMCR1
, "UMMCR1",
7739 &spr_read_ureg
, SPR_NOACCESS
,
7740 &spr_read_ureg
, &spr_write_ureg
,
7742 spr_register(env
, SPR_POWER_UMMCRA
, "UMMCRA",
7743 &spr_read_ureg
, SPR_NOACCESS
,
7744 &spr_read_ureg
, &spr_write_ureg
,
7746 spr_register(env
, SPR_POWER_UPMC1
, "UPMC1",
7747 &spr_read_ureg
, SPR_NOACCESS
,
7748 &spr_read_ureg
, &spr_write_ureg
,
7750 spr_register(env
, SPR_POWER_UPMC2
, "UPMC2",
7751 &spr_read_ureg
, SPR_NOACCESS
,
7752 &spr_read_ureg
, &spr_write_ureg
,
7754 spr_register(env
, SPR_POWER_UPMC3
, "UPMC3",
7755 &spr_read_ureg
, SPR_NOACCESS
,
7756 &spr_read_ureg
, &spr_write_ureg
,
7758 spr_register(env
, SPR_POWER_UPMC4
, "UPMC4",
7759 &spr_read_ureg
, SPR_NOACCESS
,
7760 &spr_read_ureg
, &spr_write_ureg
,
7762 spr_register(env
, SPR_POWER_UPMC5
, "UPMC5",
7763 &spr_read_ureg
, SPR_NOACCESS
,
7764 &spr_read_ureg
, &spr_write_ureg
,
7766 spr_register(env
, SPR_POWER_UPMC6
, "UPMC6",
7767 &spr_read_ureg
, SPR_NOACCESS
,
7768 &spr_read_ureg
, &spr_write_ureg
,
7770 spr_register(env
, SPR_POWER_USIAR
, "USIAR",
7771 &spr_read_ureg
, SPR_NOACCESS
,
7772 &spr_read_ureg
, &spr_write_ureg
,
7774 spr_register(env
, SPR_POWER_USDAR
, "USDAR",
7775 &spr_read_ureg
, SPR_NOACCESS
,
7776 &spr_read_ureg
, &spr_write_ureg
,
7780 static void gen_spr_970_pmu_sup(CPUPPCState
*env
)
7782 spr_register_kvm(env
, SPR_970_PMC7
, "PMC7",
7783 SPR_NOACCESS
, SPR_NOACCESS
,
7784 &spr_read_generic
, &spr_write_generic
,
7785 KVM_REG_PPC_PMC7
, 0x00000000);
7786 spr_register_kvm(env
, SPR_970_PMC8
, "PMC8",
7787 SPR_NOACCESS
, SPR_NOACCESS
,
7788 &spr_read_generic
, &spr_write_generic
,
7789 KVM_REG_PPC_PMC8
, 0x00000000);
7792 static void gen_spr_970_pmu_user(CPUPPCState
*env
)
7794 spr_register(env
, SPR_970_UPMC7
, "UPMC7",
7795 &spr_read_ureg
, SPR_NOACCESS
,
7796 &spr_read_ureg
, &spr_write_ureg
,
7798 spr_register(env
, SPR_970_UPMC8
, "UPMC8",
7799 &spr_read_ureg
, SPR_NOACCESS
,
7800 &spr_read_ureg
, &spr_write_ureg
,
7804 static void gen_spr_power8_pmu_sup(CPUPPCState
*env
)
7806 spr_register_kvm(env
, SPR_POWER_MMCR2
, "MMCR2",
7807 SPR_NOACCESS
, SPR_NOACCESS
,
7808 &spr_read_generic
, &spr_write_generic
,
7809 KVM_REG_PPC_MMCR2
, 0x00000000);
7810 spr_register_kvm(env
, SPR_POWER_MMCRS
, "MMCRS",
7811 SPR_NOACCESS
, SPR_NOACCESS
,
7812 &spr_read_generic
, &spr_write_generic
,
7813 KVM_REG_PPC_MMCRS
, 0x00000000);
7814 spr_register_kvm(env
, SPR_POWER_SIER
, "SIER",
7815 SPR_NOACCESS
, SPR_NOACCESS
,
7816 &spr_read_generic
, &spr_write_generic
,
7817 KVM_REG_PPC_SIER
, 0x00000000);
7818 spr_register_kvm(env
, SPR_POWER_SPMC1
, "SPMC1",
7819 SPR_NOACCESS
, SPR_NOACCESS
,
7820 &spr_read_generic
, &spr_write_generic
,
7821 KVM_REG_PPC_SPMC1
, 0x00000000);
7822 spr_register_kvm(env
, SPR_POWER_SPMC2
, "SPMC2",
7823 SPR_NOACCESS
, SPR_NOACCESS
,
7824 &spr_read_generic
, &spr_write_generic
,
7825 KVM_REG_PPC_SPMC2
, 0x00000000);
7826 spr_register_kvm(env
, SPR_TACR
, "TACR",
7827 SPR_NOACCESS
, SPR_NOACCESS
,
7828 &spr_read_generic
, &spr_write_generic
,
7829 KVM_REG_PPC_TACR
, 0x00000000);
7830 spr_register_kvm(env
, SPR_TCSCR
, "TCSCR",
7831 SPR_NOACCESS
, SPR_NOACCESS
,
7832 &spr_read_generic
, &spr_write_generic
,
7833 KVM_REG_PPC_TCSCR
, 0x00000000);
7834 spr_register_kvm(env
, SPR_CSIGR
, "CSIGR",
7835 SPR_NOACCESS
, SPR_NOACCESS
,
7836 &spr_read_generic
, &spr_write_generic
,
7837 KVM_REG_PPC_CSIGR
, 0x00000000);
7840 static void gen_spr_power8_pmu_user(CPUPPCState
*env
)
7842 spr_register(env
, SPR_POWER_UMMCR2
, "UMMCR2",
7843 &spr_read_ureg
, SPR_NOACCESS
,
7844 &spr_read_ureg
, &spr_write_ureg
,
7846 spr_register(env
, SPR_POWER_USIER
, "USIER",
7847 &spr_read_generic
, SPR_NOACCESS
,
7848 &spr_read_generic
, &spr_write_generic
,
7852 static void gen_spr_power5p_ear(CPUPPCState
*env
)
7854 /* External access control */
7855 spr_register(env
, SPR_EAR
, "EAR",
7856 SPR_NOACCESS
, SPR_NOACCESS
,
7857 &spr_read_generic
, &spr_write_generic
,
7861 static void gen_spr_power5p_tb(CPUPPCState
*env
)
7863 /* TBU40 (High 40 bits of the Timebase register */
7864 spr_register_hv(env
, SPR_TBU40
, "TBU40",
7865 SPR_NOACCESS
, SPR_NOACCESS
,
7866 SPR_NOACCESS
, SPR_NOACCESS
,
7867 SPR_NOACCESS
, &spr_write_tbu40
,
7871 #if !defined(CONFIG_USER_ONLY)
7872 static void spr_write_hmer(DisasContext
*ctx
, int sprn
, int gprn
)
7874 TCGv hmer
= tcg_temp_new();
7876 gen_load_spr(hmer
, sprn
);
7877 tcg_gen_and_tl(hmer
, cpu_gpr
[gprn
], hmer
);
7878 gen_store_spr(sprn
, hmer
);
7879 spr_store_dump_spr(sprn
);
7880 tcg_temp_free(hmer
);
7883 static void spr_write_lpcr(DisasContext
*ctx
, int sprn
, int gprn
)
7885 gen_helper_store_lpcr(cpu_env
, cpu_gpr
[gprn
]);
7888 static void spr_write_970_hid4(DisasContext
*ctx
, int sprn
, int gprn
)
7890 #if defined(TARGET_PPC64)
7891 spr_write_generic(ctx
, sprn
, gprn
);
7892 gen_helper_store_lpcr(cpu_env
, cpu_gpr
[gprn
]);
7896 #endif /* !defined(CONFIG_USER_ONLY) */
7898 static void gen_spr_970_lpar(CPUPPCState
*env
)
7900 #if !defined(CONFIG_USER_ONLY)
7901 /* Logical partitionning */
7902 /* PPC970: HID4 is effectively the LPCR */
7903 spr_register(env
, SPR_970_HID4
, "HID4",
7904 SPR_NOACCESS
, SPR_NOACCESS
,
7905 &spr_read_generic
, &spr_write_970_hid4
,
7910 static void gen_spr_power5p_lpar(CPUPPCState
*env
)
7912 #if !defined(CONFIG_USER_ONLY)
7913 /* Logical partitionning */
7914 spr_register_kvm_hv(env
, SPR_LPCR
, "LPCR",
7915 SPR_NOACCESS
, SPR_NOACCESS
,
7916 SPR_NOACCESS
, SPR_NOACCESS
,
7917 &spr_read_generic
, &spr_write_lpcr
,
7918 KVM_REG_PPC_LPCR
, LPCR_LPES0
| LPCR_LPES1
);
7919 spr_register_hv(env
, SPR_HDEC
, "HDEC",
7920 SPR_NOACCESS
, SPR_NOACCESS
,
7921 SPR_NOACCESS
, SPR_NOACCESS
,
7922 &spr_read_hdecr
, &spr_write_hdecr
, 0);
7926 static void gen_spr_book3s_ids(CPUPPCState
*env
)
7928 /* FIXME: Will need to deal with thread vs core only SPRs */
7930 /* Processor identification */
7931 spr_register_hv(env
, SPR_PIR
, "PIR",
7932 SPR_NOACCESS
, SPR_NOACCESS
,
7933 &spr_read_generic
, SPR_NOACCESS
,
7934 &spr_read_generic
, NULL
,
7936 spr_register_hv(env
, SPR_HID0
, "HID0",
7937 SPR_NOACCESS
, SPR_NOACCESS
,
7938 SPR_NOACCESS
, SPR_NOACCESS
,
7939 &spr_read_generic
, &spr_write_generic
,
7941 spr_register_hv(env
, SPR_TSCR
, "TSCR",
7942 SPR_NOACCESS
, SPR_NOACCESS
,
7943 SPR_NOACCESS
, SPR_NOACCESS
,
7944 &spr_read_generic
, &spr_write_generic
,
7946 spr_register_hv(env
, SPR_HMER
, "HMER",
7947 SPR_NOACCESS
, SPR_NOACCESS
,
7948 SPR_NOACCESS
, SPR_NOACCESS
,
7949 &spr_read_generic
, &spr_write_hmer
,
7951 spr_register_hv(env
, SPR_HMEER
, "HMEER",
7952 SPR_NOACCESS
, SPR_NOACCESS
,
7953 SPR_NOACCESS
, SPR_NOACCESS
,
7954 &spr_read_generic
, &spr_write_generic
,
7956 spr_register_hv(env
, SPR_TFMR
, "TFMR",
7957 SPR_NOACCESS
, SPR_NOACCESS
,
7958 SPR_NOACCESS
, SPR_NOACCESS
,
7959 &spr_read_generic
, &spr_write_generic
,
7961 spr_register_hv(env
, SPR_LPIDR
, "LPIDR",
7962 SPR_NOACCESS
, SPR_NOACCESS
,
7963 SPR_NOACCESS
, SPR_NOACCESS
,
7964 &spr_read_generic
, &spr_write_lpidr
,
7966 spr_register_hv(env
, SPR_HFSCR
, "HFSCR",
7967 SPR_NOACCESS
, SPR_NOACCESS
,
7968 SPR_NOACCESS
, SPR_NOACCESS
,
7969 &spr_read_generic
, &spr_write_generic
,
7971 spr_register_hv(env
, SPR_MMCRC
, "MMCRC",
7972 SPR_NOACCESS
, SPR_NOACCESS
,
7973 SPR_NOACCESS
, SPR_NOACCESS
,
7974 &spr_read_generic
, &spr_write_generic
,
7976 spr_register_hv(env
, SPR_MMCRH
, "MMCRH",
7977 SPR_NOACCESS
, SPR_NOACCESS
,
7978 SPR_NOACCESS
, SPR_NOACCESS
,
7979 &spr_read_generic
, &spr_write_generic
,
7981 spr_register_hv(env
, SPR_HSPRG0
, "HSPRG0",
7982 SPR_NOACCESS
, SPR_NOACCESS
,
7983 SPR_NOACCESS
, SPR_NOACCESS
,
7984 &spr_read_generic
, &spr_write_generic
,
7986 spr_register_hv(env
, SPR_HSPRG1
, "HSPRG1",
7987 SPR_NOACCESS
, SPR_NOACCESS
,
7988 SPR_NOACCESS
, SPR_NOACCESS
,
7989 &spr_read_generic
, &spr_write_generic
,
7991 spr_register_hv(env
, SPR_HSRR0
, "HSRR0",
7992 SPR_NOACCESS
, SPR_NOACCESS
,
7993 SPR_NOACCESS
, SPR_NOACCESS
,
7994 &spr_read_generic
, &spr_write_generic
,
7996 spr_register_hv(env
, SPR_HSRR1
, "HSRR1",
7997 SPR_NOACCESS
, SPR_NOACCESS
,
7998 SPR_NOACCESS
, SPR_NOACCESS
,
7999 &spr_read_generic
, &spr_write_generic
,
8001 spr_register_hv(env
, SPR_HDAR
, "HDAR",
8002 SPR_NOACCESS
, SPR_NOACCESS
,
8003 SPR_NOACCESS
, SPR_NOACCESS
,
8004 &spr_read_generic
, &spr_write_generic
,
8006 spr_register_hv(env
, SPR_HDSISR
, "HDSISR",
8007 SPR_NOACCESS
, SPR_NOACCESS
,
8008 SPR_NOACCESS
, SPR_NOACCESS
,
8009 &spr_read_generic
, &spr_write_generic
,
8011 spr_register_hv(env
, SPR_RMOR
, "RMOR",
8012 SPR_NOACCESS
, SPR_NOACCESS
,
8013 SPR_NOACCESS
, SPR_NOACCESS
,
8014 &spr_read_generic
, &spr_write_generic
,
8016 spr_register_hv(env
, SPR_HRMOR
, "HRMOR",
8017 SPR_NOACCESS
, SPR_NOACCESS
,
8018 SPR_NOACCESS
, SPR_NOACCESS
,
8019 &spr_read_generic
, &spr_write_generic
,
8023 static void gen_spr_power8_ids(CPUPPCState
*env
)
8025 /* Thread identification */
8026 spr_register(env
, SPR_TIR
, "TIR",
8027 SPR_NOACCESS
, SPR_NOACCESS
,
8028 &spr_read_generic
, SPR_NOACCESS
,
8032 static void gen_spr_book3s_purr(CPUPPCState
*env
)
8034 #if !defined(CONFIG_USER_ONLY)
8035 /* PURR & SPURR: Hack - treat these as aliases for the TB for now */
8036 spr_register_kvm_hv(env
, SPR_PURR
, "PURR",
8037 &spr_read_purr
, SPR_NOACCESS
,
8038 &spr_read_purr
, SPR_NOACCESS
,
8039 &spr_read_purr
, &spr_write_purr
,
8040 KVM_REG_PPC_PURR
, 0x00000000);
8041 spr_register_kvm_hv(env
, SPR_SPURR
, "SPURR",
8042 &spr_read_purr
, SPR_NOACCESS
,
8043 &spr_read_purr
, SPR_NOACCESS
,
8044 &spr_read_purr
, &spr_write_purr
,
8045 KVM_REG_PPC_SPURR
, 0x00000000);
8049 static void gen_spr_power6_dbg(CPUPPCState
*env
)
8051 #if !defined(CONFIG_USER_ONLY)
8052 spr_register(env
, SPR_CFAR
, "SPR_CFAR",
8053 SPR_NOACCESS
, SPR_NOACCESS
,
8054 &spr_read_cfar
, &spr_write_cfar
,
8059 static void gen_spr_power5p_common(CPUPPCState
*env
)
8061 spr_register_kvm(env
, SPR_PPR
, "PPR",
8062 &spr_read_generic
, &spr_write_generic
,
8063 &spr_read_generic
, &spr_write_generic
,
8064 KVM_REG_PPC_PPR
, 0x00000000);
8067 static void gen_spr_power6_common(CPUPPCState
*env
)
8069 #if !defined(CONFIG_USER_ONLY)
8070 spr_register_kvm(env
, SPR_DSCR
, "SPR_DSCR",
8071 SPR_NOACCESS
, SPR_NOACCESS
,
8072 &spr_read_generic
, &spr_write_generic
,
8073 KVM_REG_PPC_DSCR
, 0x00000000);
8076 * Register PCR to report POWERPC_EXCP_PRIV_REG instead of
8077 * POWERPC_EXCP_INVAL_SPR in userspace. Permit hypervisor access.
8079 spr_register_hv(env
, SPR_PCR
, "PCR",
8080 SPR_NOACCESS
, SPR_NOACCESS
,
8081 SPR_NOACCESS
, SPR_NOACCESS
,
8082 &spr_read_generic
, &spr_write_pcr
,
8086 static void spr_read_tar(DisasContext
*ctx
, int gprn
, int sprn
)
8088 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_TAR
, sprn
, FSCR_IC_TAR
);
8089 spr_read_generic(ctx
, gprn
, sprn
);
8092 static void spr_write_tar(DisasContext
*ctx
, int sprn
, int gprn
)
8094 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_TAR
, sprn
, FSCR_IC_TAR
);
8095 spr_write_generic(ctx
, sprn
, gprn
);
8098 static void gen_spr_power8_tce_address_control(CPUPPCState
*env
)
8100 spr_register_kvm(env
, SPR_TAR
, "TAR",
8101 &spr_read_tar
, &spr_write_tar
,
8102 &spr_read_generic
, &spr_write_generic
,
8103 KVM_REG_PPC_TAR
, 0x00000000);
8106 static void spr_read_tm(DisasContext
*ctx
, int gprn
, int sprn
)
8108 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8109 spr_read_generic(ctx
, gprn
, sprn
);
8112 static void spr_write_tm(DisasContext
*ctx
, int sprn
, int gprn
)
8114 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8115 spr_write_generic(ctx
, sprn
, gprn
);
8118 static void spr_read_tm_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
8120 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8121 spr_read_prev_upper32(ctx
, gprn
, sprn
);
8124 static void spr_write_tm_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
8126 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8127 spr_write_prev_upper32(ctx
, sprn
, gprn
);
8130 static void gen_spr_power8_tm(CPUPPCState
*env
)
8132 spr_register_kvm(env
, SPR_TFHAR
, "TFHAR",
8133 &spr_read_tm
, &spr_write_tm
,
8134 &spr_read_tm
, &spr_write_tm
,
8135 KVM_REG_PPC_TFHAR
, 0x00000000);
8136 spr_register_kvm(env
, SPR_TFIAR
, "TFIAR",
8137 &spr_read_tm
, &spr_write_tm
,
8138 &spr_read_tm
, &spr_write_tm
,
8139 KVM_REG_PPC_TFIAR
, 0x00000000);
8140 spr_register_kvm(env
, SPR_TEXASR
, "TEXASR",
8141 &spr_read_tm
, &spr_write_tm
,
8142 &spr_read_tm
, &spr_write_tm
,
8143 KVM_REG_PPC_TEXASR
, 0x00000000);
8144 spr_register(env
, SPR_TEXASRU
, "TEXASRU",
8145 &spr_read_tm_upper32
, &spr_write_tm_upper32
,
8146 &spr_read_tm_upper32
, &spr_write_tm_upper32
,
8150 static void spr_read_ebb(DisasContext
*ctx
, int gprn
, int sprn
)
8152 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8153 spr_read_generic(ctx
, gprn
, sprn
);
8156 static void spr_write_ebb(DisasContext
*ctx
, int sprn
, int gprn
)
8158 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8159 spr_write_generic(ctx
, sprn
, gprn
);
8162 static void spr_read_ebb_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
8164 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8165 spr_read_prev_upper32(ctx
, gprn
, sprn
);
8168 static void spr_write_ebb_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
8170 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8171 spr_write_prev_upper32(ctx
, sprn
, gprn
);
8174 static void gen_spr_power8_ebb(CPUPPCState
*env
)
8176 spr_register(env
, SPR_BESCRS
, "BESCRS",
8177 &spr_read_ebb
, &spr_write_ebb
,
8178 &spr_read_generic
, &spr_write_generic
,
8180 spr_register(env
, SPR_BESCRSU
, "BESCRSU",
8181 &spr_read_ebb_upper32
, &spr_write_ebb_upper32
,
8182 &spr_read_prev_upper32
, &spr_write_prev_upper32
,
8184 spr_register(env
, SPR_BESCRR
, "BESCRR",
8185 &spr_read_ebb
, &spr_write_ebb
,
8186 &spr_read_generic
, &spr_write_generic
,
8188 spr_register(env
, SPR_BESCRRU
, "BESCRRU",
8189 &spr_read_ebb_upper32
, &spr_write_ebb_upper32
,
8190 &spr_read_prev_upper32
, &spr_write_prev_upper32
,
8192 spr_register_kvm(env
, SPR_EBBHR
, "EBBHR",
8193 &spr_read_ebb
, &spr_write_ebb
,
8194 &spr_read_generic
, &spr_write_generic
,
8195 KVM_REG_PPC_EBBHR
, 0x00000000);
8196 spr_register_kvm(env
, SPR_EBBRR
, "EBBRR",
8197 &spr_read_ebb
, &spr_write_ebb
,
8198 &spr_read_generic
, &spr_write_generic
,
8199 KVM_REG_PPC_EBBRR
, 0x00000000);
8200 spr_register_kvm(env
, SPR_BESCR
, "BESCR",
8201 &spr_read_ebb
, &spr_write_ebb
,
8202 &spr_read_generic
, &spr_write_generic
,
8203 KVM_REG_PPC_BESCR
, 0x00000000);
8206 /* Virtual Time Base */
8207 static void gen_spr_vtb(CPUPPCState
*env
)
8209 spr_register_kvm_hv(env
, SPR_VTB
, "VTB",
8210 SPR_NOACCESS
, SPR_NOACCESS
,
8211 &spr_read_vtb
, SPR_NOACCESS
,
8212 &spr_read_vtb
, &spr_write_vtb
,
8213 KVM_REG_PPC_VTB
, 0x00000000);
8216 static void gen_spr_power8_fscr(CPUPPCState
*env
)
8218 #if defined(CONFIG_USER_ONLY)
8219 target_ulong initval
= 1ULL << FSCR_TAR
;
8221 target_ulong initval
= 0;
8223 spr_register_kvm(env
, SPR_FSCR
, "FSCR",
8224 SPR_NOACCESS
, SPR_NOACCESS
,
8225 &spr_read_generic
, &spr_write_generic
,
8226 KVM_REG_PPC_FSCR
, initval
);
8229 static void gen_spr_power8_pspb(CPUPPCState
*env
)
8231 spr_register_kvm(env
, SPR_PSPB
, "PSPB",
8232 SPR_NOACCESS
, SPR_NOACCESS
,
8233 &spr_read_generic
, &spr_write_generic32
,
8234 KVM_REG_PPC_PSPB
, 0);
8237 static void gen_spr_power8_dpdes(CPUPPCState
*env
)
8239 #if !defined(CONFIG_USER_ONLY)
8240 /* Directed Privileged Door-bell Exception State, used for IPI */
8241 spr_register(env
, SPR_DPDES
, "DPDES",
8242 SPR_NOACCESS
, SPR_NOACCESS
,
8243 &spr_read_generic
, SPR_NOACCESS
,
8248 static void gen_spr_power8_ic(CPUPPCState
*env
)
8250 #if !defined(CONFIG_USER_ONLY)
8251 spr_register_hv(env
, SPR_IC
, "IC",
8252 SPR_NOACCESS
, SPR_NOACCESS
,
8253 &spr_read_generic
, SPR_NOACCESS
,
8254 &spr_read_generic
, &spr_write_generic
,
8259 static void gen_spr_power8_book4(CPUPPCState
*env
)
8261 /* Add a number of P8 book4 registers */
8262 #if !defined(CONFIG_USER_ONLY)
8263 spr_register_kvm(env
, SPR_ACOP
, "ACOP",
8264 SPR_NOACCESS
, SPR_NOACCESS
,
8265 &spr_read_generic
, &spr_write_generic
,
8266 KVM_REG_PPC_ACOP
, 0);
8267 spr_register_kvm(env
, SPR_BOOKS_PID
, "PID",
8268 SPR_NOACCESS
, SPR_NOACCESS
,
8269 &spr_read_generic
, &spr_write_pidr
,
8270 KVM_REG_PPC_PID
, 0);
8271 spr_register_kvm(env
, SPR_WORT
, "WORT",
8272 SPR_NOACCESS
, SPR_NOACCESS
,
8273 &spr_read_generic
, &spr_write_generic
,
8274 KVM_REG_PPC_WORT
, 0);
8278 static void gen_spr_power7_book4(CPUPPCState
*env
)
8280 /* Add a number of P7 book4 registers */
8281 #if !defined(CONFIG_USER_ONLY)
8282 spr_register_kvm(env
, SPR_ACOP
, "ACOP",
8283 SPR_NOACCESS
, SPR_NOACCESS
,
8284 &spr_read_generic
, &spr_write_generic
,
8285 KVM_REG_PPC_ACOP
, 0);
8286 spr_register_kvm(env
, SPR_BOOKS_PID
, "PID",
8287 SPR_NOACCESS
, SPR_NOACCESS
,
8288 &spr_read_generic
, &spr_write_generic
,
8289 KVM_REG_PPC_PID
, 0);
8293 static void gen_spr_power8_rpr(CPUPPCState
*env
)
8295 #if !defined(CONFIG_USER_ONLY)
8296 spr_register_hv(env
, SPR_RPR
, "RPR",
8297 SPR_NOACCESS
, SPR_NOACCESS
,
8298 SPR_NOACCESS
, SPR_NOACCESS
,
8299 &spr_read_generic
, &spr_write_generic
,
8300 0x00000103070F1F3F);
8304 static void gen_spr_power9_mmu(CPUPPCState
*env
)
8306 #if !defined(CONFIG_USER_ONLY)
8307 /* Partition Table Control */
8308 spr_register_kvm_hv(env
, SPR_PTCR
, "PTCR",
8309 SPR_NOACCESS
, SPR_NOACCESS
,
8310 SPR_NOACCESS
, SPR_NOACCESS
,
8311 &spr_read_generic
, &spr_write_ptcr
,
8312 KVM_REG_PPC_PTCR
, 0x00000000);
8313 /* Address Segment Descriptor Register */
8314 spr_register_hv(env
, SPR_ASDR
, "ASDR",
8315 SPR_NOACCESS
, SPR_NOACCESS
,
8316 SPR_NOACCESS
, SPR_NOACCESS
,
8317 &spr_read_generic
, &spr_write_generic
,
8318 0x0000000000000000);
8322 static void init_proc_book3s_common(CPUPPCState
*env
)
8324 gen_spr_ne_601(env
);
8326 gen_spr_usprg3(env
);
8327 gen_spr_book3s_altivec(env
);
8328 gen_spr_book3s_pmu_sup(env
);
8329 gen_spr_book3s_pmu_user(env
);
8330 gen_spr_book3s_ctrl(env
);
8333 static void init_proc_970(CPUPPCState
*env
)
8335 /* Common Registers */
8336 init_proc_book3s_common(env
);
8338 gen_spr_book3s_dbg(env
);
8340 /* 970 Specific Registers */
8341 gen_spr_970_hid(env
);
8342 gen_spr_970_hior(env
);
8344 gen_spr_970_pmu_sup(env
);
8345 gen_spr_970_pmu_user(env
);
8346 gen_spr_970_lpar(env
);
8347 gen_spr_970_dbg(env
);
8350 env
->dcache_line_size
= 128;
8351 env
->icache_line_size
= 128;
8353 /* Allocate hardware IRQ controller */
8355 ppc970_irq_init(env_archcpu(env
));
8358 POWERPC_FAMILY(970)(ObjectClass
*oc
, void *data
)
8360 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8361 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8363 dc
->desc
= "PowerPC 970";
8364 pcc
->init_proc
= init_proc_970
;
8365 pcc
->check_pow
= check_pow_970
;
8366 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
8367 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8368 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8370 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8371 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8372 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8373 PPC_64B
| PPC_ALTIVEC
|
8374 PPC_SEGMENT_64B
| PPC_SLBI
;
8375 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
8376 pcc
->msr_mask
= (1ull << MSR_SF
) |
8391 pcc
->mmu_model
= POWERPC_MMU_64B
;
8392 #if defined(CONFIG_SOFTMMU)
8393 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8394 pcc
->hash64_opts
= &ppc_hash64_opts_basic
;
8396 pcc
->excp_model
= POWERPC_EXCP_970
;
8397 pcc
->bus_model
= PPC_FLAGS_INPUT_970
;
8398 pcc
->bfd_mach
= bfd_mach_ppc64
;
8399 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8400 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8401 POWERPC_FLAG_BUS_CLK
;
8402 pcc
->l1_dcache_size
= 0x8000;
8403 pcc
->l1_icache_size
= 0x10000;
8406 static void init_proc_power5plus(CPUPPCState
*env
)
8408 /* Common Registers */
8409 init_proc_book3s_common(env
);
8411 gen_spr_book3s_dbg(env
);
8413 /* POWER5+ Specific Registers */
8414 gen_spr_970_hid(env
);
8415 gen_spr_970_hior(env
);
8417 gen_spr_970_pmu_sup(env
);
8418 gen_spr_970_pmu_user(env
);
8419 gen_spr_power5p_common(env
);
8420 gen_spr_power5p_lpar(env
);
8421 gen_spr_power5p_ear(env
);
8422 gen_spr_power5p_tb(env
);
8425 env
->dcache_line_size
= 128;
8426 env
->icache_line_size
= 128;
8428 /* Allocate hardware IRQ controller */
8430 ppc970_irq_init(env_archcpu(env
));
8433 POWERPC_FAMILY(POWER5P
)(ObjectClass
*oc
, void *data
)
8435 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8436 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8438 dc
->fw_name
= "PowerPC,POWER5";
8439 dc
->desc
= "POWER5+";
8440 pcc
->init_proc
= init_proc_power5plus
;
8441 pcc
->check_pow
= check_pow_970
;
8442 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
8443 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8444 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8446 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8447 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8448 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8450 PPC_SEGMENT_64B
| PPC_SLBI
;
8451 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
8452 pcc
->msr_mask
= (1ull << MSR_SF
) |
8467 pcc
->mmu_model
= POWERPC_MMU_2_03
;
8468 #if defined(CONFIG_SOFTMMU)
8469 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8470 pcc
->hash64_opts
= &ppc_hash64_opts_basic
;
8471 pcc
->lrg_decr_bits
= 32;
8473 pcc
->excp_model
= POWERPC_EXCP_970
;
8474 pcc
->bus_model
= PPC_FLAGS_INPUT_970
;
8475 pcc
->bfd_mach
= bfd_mach_ppc64
;
8476 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8477 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8478 POWERPC_FLAG_BUS_CLK
;
8479 pcc
->l1_dcache_size
= 0x8000;
8480 pcc
->l1_icache_size
= 0x10000;
8484 * The CPU used to have a "compat" property which set the
8485 * compatibility mode PVR. However, this was conceptually broken - it
8486 * only makes sense on the pseries machine type (otherwise the guest
8487 * owns the PCR and can control the compatibility mode itself). It's
8488 * been replaced with the 'max-cpu-compat' property on the pseries
8489 * machine type. For backwards compatibility, pseries specially
8490 * parses the -cpu parameter and converts old compat= parameters into
8491 * the appropriate machine parameters. This stub implementation of
8492 * the parameter catches any uses on explicitly created CPUs.
8494 static void getset_compat_deprecated(Object
*obj
, Visitor
*v
, const char *name
,
8495 void *opaque
, Error
**errp
)
8499 if (!qtest_enabled()) {
8500 warn_report("CPU 'compat' property is deprecated and has no effect; "
8501 "use max-cpu-compat machine property instead");
8503 visit_type_null(v
, name
, &null
, NULL
);
8504 qobject_unref(null
);
8507 static const PropertyInfo ppc_compat_deprecated_propinfo
= {
8509 .description
= "compatibility mode (deprecated)",
8510 .get
= getset_compat_deprecated
,
8511 .set
= getset_compat_deprecated
,
8513 static Property powerpc_servercpu_properties
[] = {
8516 .info
= &ppc_compat_deprecated_propinfo
,
8518 DEFINE_PROP_END_OF_LIST(),
8521 static void init_proc_POWER7(CPUPPCState
*env
)
8523 /* Common Registers */
8524 init_proc_book3s_common(env
);
8526 gen_spr_book3s_dbg(env
);
8528 /* POWER7 Specific Registers */
8529 gen_spr_book3s_ids(env
);
8531 gen_spr_book3s_purr(env
);
8532 gen_spr_power5p_common(env
);
8533 gen_spr_power5p_lpar(env
);
8534 gen_spr_power5p_ear(env
);
8535 gen_spr_power5p_tb(env
);
8536 gen_spr_power6_common(env
);
8537 gen_spr_power6_dbg(env
);
8538 gen_spr_power7_book4(env
);
8541 env
->dcache_line_size
= 128;
8542 env
->icache_line_size
= 128;
8544 /* Allocate hardware IRQ controller */
8545 init_excp_POWER7(env
);
8546 ppcPOWER7_irq_init(env_archcpu(env
));
8549 static bool ppc_pvr_match_power7(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8551 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER7P_BASE
) {
8554 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER7_BASE
) {
8560 static bool cpu_has_work_POWER7(CPUState
*cs
)
8562 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8563 CPUPPCState
*env
= &cpu
->env
;
8566 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8569 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8570 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE0
)) {
8573 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8574 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE1
)) {
8577 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
)) &&
8578 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE2
)) {
8581 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HMI
)) &&
8582 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE2
)) {
8585 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8590 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8594 POWERPC_FAMILY(POWER7
)(ObjectClass
*oc
, void *data
)
8596 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8597 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8598 CPUClass
*cc
= CPU_CLASS(oc
);
8600 dc
->fw_name
= "PowerPC,POWER7";
8601 dc
->desc
= "POWER7";
8602 dc
->props
= powerpc_servercpu_properties
;
8603 pcc
->pvr_match
= ppc_pvr_match_power7
;
8604 pcc
->pcr_mask
= PCR_VEC_DIS
| PCR_VSX_DIS
| PCR_COMPAT_2_05
;
8605 pcc
->pcr_supported
= PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8606 pcc
->init_proc
= init_proc_POWER7
;
8607 pcc
->check_pow
= check_pow_nocheck
;
8608 cc
->has_work
= cpu_has_work_POWER7
;
8609 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8610 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8611 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8612 PPC_FLOAT_FRSQRTES
|
8615 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8616 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8617 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8618 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
8619 PPC_SEGMENT_64B
| PPC_SLBI
|
8620 PPC_POPCNTB
| PPC_POPCNTWD
|
8622 pcc
->insns_flags2
= PPC2_VSX
| PPC2_DFP
| PPC2_DBRX
| PPC2_ISA205
|
8623 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8624 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8625 PPC2_FP_TST_ISA206
| PPC2_FP_CVT_S64
|
8627 pcc
->msr_mask
= (1ull << MSR_SF
) |
8643 pcc
->mmu_model
= POWERPC_MMU_2_06
;
8644 #if defined(CONFIG_SOFTMMU)
8645 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8646 pcc
->hash64_opts
= &ppc_hash64_opts_POWER7
;
8647 pcc
->lrg_decr_bits
= 32;
8649 pcc
->excp_model
= POWERPC_EXCP_POWER7
;
8650 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8651 pcc
->bfd_mach
= bfd_mach_ppc64
;
8652 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8653 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8654 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8656 pcc
->l1_dcache_size
= 0x8000;
8657 pcc
->l1_icache_size
= 0x8000;
8658 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8659 pcc
->lpcr_pm
= LPCR_P7_PECE0
| LPCR_P7_PECE1
| LPCR_P7_PECE2
;
8662 static void init_proc_POWER8(CPUPPCState
*env
)
8664 /* Common Registers */
8665 init_proc_book3s_common(env
);
8667 gen_spr_book3s_207_dbg(env
);
8669 /* POWER8 Specific Registers */
8670 gen_spr_book3s_ids(env
);
8673 gen_spr_book3s_purr(env
);
8674 gen_spr_power5p_common(env
);
8675 gen_spr_power5p_lpar(env
);
8676 gen_spr_power5p_ear(env
);
8677 gen_spr_power5p_tb(env
);
8678 gen_spr_power6_common(env
);
8679 gen_spr_power6_dbg(env
);
8680 gen_spr_power8_tce_address_control(env
);
8681 gen_spr_power8_ids(env
);
8682 gen_spr_power8_ebb(env
);
8683 gen_spr_power8_fscr(env
);
8684 gen_spr_power8_pmu_sup(env
);
8685 gen_spr_power8_pmu_user(env
);
8686 gen_spr_power8_tm(env
);
8687 gen_spr_power8_pspb(env
);
8688 gen_spr_power8_dpdes(env
);
8690 gen_spr_power8_ic(env
);
8691 gen_spr_power8_book4(env
);
8692 gen_spr_power8_rpr(env
);
8695 env
->dcache_line_size
= 128;
8696 env
->icache_line_size
= 128;
8698 /* Allocate hardware IRQ controller */
8699 init_excp_POWER8(env
);
8700 ppcPOWER7_irq_init(env_archcpu(env
));
8703 static bool ppc_pvr_match_power8(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8705 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8NVL_BASE
) {
8708 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8E_BASE
) {
8711 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8_BASE
) {
8717 static bool cpu_has_work_POWER8(CPUState
*cs
)
8719 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8720 CPUPPCState
*env
= &cpu
->env
;
8723 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8726 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8727 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE2
)) {
8730 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8731 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE3
)) {
8734 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
)) &&
8735 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE4
)) {
8738 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HMI
)) &&
8739 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE4
)) {
8742 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DOORBELL
)) &&
8743 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE0
)) {
8746 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HDOORBELL
)) &&
8747 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE1
)) {
8750 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8755 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8759 POWERPC_FAMILY(POWER8
)(ObjectClass
*oc
, void *data
)
8761 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8762 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8763 CPUClass
*cc
= CPU_CLASS(oc
);
8765 dc
->fw_name
= "PowerPC,POWER8";
8766 dc
->desc
= "POWER8";
8767 dc
->props
= powerpc_servercpu_properties
;
8768 pcc
->pvr_match
= ppc_pvr_match_power8
;
8769 pcc
->pcr_mask
= PCR_TM_DIS
| PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8770 pcc
->pcr_supported
= PCR_COMPAT_2_07
| PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8771 pcc
->init_proc
= init_proc_POWER8
;
8772 pcc
->check_pow
= check_pow_nocheck
;
8773 cc
->has_work
= cpu_has_work_POWER8
;
8774 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8775 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8776 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8777 PPC_FLOAT_FRSQRTES
|
8780 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8781 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8782 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8783 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
8784 PPC_SEGMENT_64B
| PPC_SLBI
|
8785 PPC_POPCNTB
| PPC_POPCNTWD
|
8787 pcc
->insns_flags2
= PPC2_VSX
| PPC2_VSX207
| PPC2_DFP
| PPC2_DBRX
|
8788 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8789 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8790 PPC2_FP_TST_ISA206
| PPC2_BCTAR_ISA207
|
8791 PPC2_LSQ_ISA207
| PPC2_ALTIVEC_207
|
8792 PPC2_ISA205
| PPC2_ISA207S
| PPC2_FP_CVT_S64
|
8793 PPC2_TM
| PPC2_PM_ISA206
;
8794 pcc
->msr_mask
= (1ull << MSR_SF
) |
8814 pcc
->mmu_model
= POWERPC_MMU_2_07
;
8815 #if defined(CONFIG_SOFTMMU)
8816 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8817 pcc
->hash64_opts
= &ppc_hash64_opts_POWER7
;
8818 pcc
->lrg_decr_bits
= 32;
8819 pcc
->n_host_threads
= 8;
8821 pcc
->excp_model
= POWERPC_EXCP_POWER8
;
8822 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8823 pcc
->bfd_mach
= bfd_mach_ppc64
;
8824 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8825 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8826 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8827 POWERPC_FLAG_VSX
| POWERPC_FLAG_TM
;
8828 pcc
->l1_dcache_size
= 0x8000;
8829 pcc
->l1_icache_size
= 0x8000;
8830 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8831 pcc
->lpcr_pm
= LPCR_P8_PECE0
| LPCR_P8_PECE1
| LPCR_P8_PECE2
|
8832 LPCR_P8_PECE3
| LPCR_P8_PECE4
;
8835 #ifdef CONFIG_SOFTMMU
8837 * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings
8838 * Encoded as array of int_32s in the form:
8839 * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
8841 * y -> radix mode supported page size (encoded as a shift)
8843 static struct ppc_radix_page_info POWER9_radix_page_info
= {
8846 0x0000000c, /* 4K - enc: 0x0 */
8847 0xa0000010, /* 64K - enc: 0x5 */
8848 0x20000015, /* 2M - enc: 0x1 */
8849 0x4000001e /* 1G - enc: 0x2 */
8852 #endif /* CONFIG_SOFTMMU */
8854 static void init_proc_POWER9(CPUPPCState
*env
)
8856 /* Common Registers */
8857 init_proc_book3s_common(env
);
8858 gen_spr_book3s_207_dbg(env
);
8860 /* POWER8 Specific Registers */
8861 gen_spr_book3s_ids(env
);
8864 gen_spr_book3s_purr(env
);
8865 gen_spr_power5p_common(env
);
8866 gen_spr_power5p_lpar(env
);
8867 gen_spr_power5p_ear(env
);
8868 gen_spr_power5p_tb(env
);
8869 gen_spr_power6_common(env
);
8870 gen_spr_power6_dbg(env
);
8871 gen_spr_power8_tce_address_control(env
);
8872 gen_spr_power8_ids(env
);
8873 gen_spr_power8_ebb(env
);
8874 gen_spr_power8_fscr(env
);
8875 gen_spr_power8_pmu_sup(env
);
8876 gen_spr_power8_pmu_user(env
);
8877 gen_spr_power8_tm(env
);
8878 gen_spr_power8_pspb(env
);
8879 gen_spr_power8_dpdes(env
);
8881 gen_spr_power8_ic(env
);
8882 gen_spr_power8_book4(env
);
8883 gen_spr_power8_rpr(env
);
8884 gen_spr_power9_mmu(env
);
8886 /* POWER9 Specific registers */
8887 spr_register_kvm(env
, SPR_TIDR
, "TIDR", NULL
, NULL
,
8888 spr_read_generic
, spr_write_generic
,
8889 KVM_REG_PPC_TIDR
, 0);
8891 /* FIXME: Filter fields properly based on privilege level */
8892 spr_register_kvm_hv(env
, SPR_PSSCR
, "PSSCR", NULL
, NULL
, NULL
, NULL
,
8893 spr_read_generic
, spr_write_generic
,
8894 KVM_REG_PPC_PSSCR
, 0);
8897 env
->dcache_line_size
= 128;
8898 env
->icache_line_size
= 128;
8900 /* Allocate hardware IRQ controller */
8901 init_excp_POWER9(env
);
8902 ppcPOWER9_irq_init(env_archcpu(env
));
8905 static bool ppc_pvr_match_power9(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8907 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER9_BASE
) {
8913 static bool cpu_has_work_POWER9(CPUState
*cs
)
8915 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8916 CPUPPCState
*env
= &cpu
->env
;
8919 uint64_t psscr
= env
->spr
[SPR_PSSCR
];
8921 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8925 /* If EC is clear, just return true on any pending interrupt */
8926 if (!(psscr
& PSSCR_EC
)) {
8929 /* External Exception */
8930 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8931 (env
->spr
[SPR_LPCR
] & LPCR_EEE
)) {
8932 bool heic
= !!(env
->spr
[SPR_LPCR
] & LPCR_HEIC
);
8933 if (heic
== 0 || !msr_hv
|| msr_pr
) {
8937 /* Decrementer Exception */
8938 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8939 (env
->spr
[SPR_LPCR
] & LPCR_DEE
)) {
8942 /* Machine Check or Hypervisor Maintenance Exception */
8943 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
|
8944 1u << PPC_INTERRUPT_HMI
)) && (env
->spr
[SPR_LPCR
] & LPCR_OEE
)) {
8947 /* Privileged Doorbell Exception */
8948 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DOORBELL
)) &&
8949 (env
->spr
[SPR_LPCR
] & LPCR_PDEE
)) {
8952 /* Hypervisor Doorbell Exception */
8953 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HDOORBELL
)) &&
8954 (env
->spr
[SPR_LPCR
] & LPCR_HDEE
)) {
8957 /* Hypervisor virtualization exception */
8958 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HVIRT
)) &&
8959 (env
->spr
[SPR_LPCR
] & LPCR_HVEE
)) {
8962 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8967 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8971 POWERPC_FAMILY(POWER9
)(ObjectClass
*oc
, void *data
)
8973 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8974 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8975 CPUClass
*cc
= CPU_CLASS(oc
);
8977 dc
->fw_name
= "PowerPC,POWER9";
8978 dc
->desc
= "POWER9";
8979 dc
->props
= powerpc_servercpu_properties
;
8980 pcc
->pvr_match
= ppc_pvr_match_power9
;
8981 pcc
->pcr_mask
= PCR_COMPAT_2_05
| PCR_COMPAT_2_06
| PCR_COMPAT_2_07
;
8982 pcc
->pcr_supported
= PCR_COMPAT_3_00
| PCR_COMPAT_2_07
| PCR_COMPAT_2_06
|
8984 pcc
->init_proc
= init_proc_POWER9
;
8985 pcc
->check_pow
= check_pow_nocheck
;
8986 cc
->has_work
= cpu_has_work_POWER9
;
8987 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8988 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8989 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8990 PPC_FLOAT_FRSQRTES
|
8993 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8994 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8996 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
8997 PPC_SEGMENT_64B
| PPC_SLBI
|
8998 PPC_POPCNTB
| PPC_POPCNTWD
|
9000 pcc
->insns_flags2
= PPC2_VSX
| PPC2_VSX207
| PPC2_DFP
| PPC2_DBRX
|
9001 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
9002 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
9003 PPC2_FP_TST_ISA206
| PPC2_BCTAR_ISA207
|
9004 PPC2_LSQ_ISA207
| PPC2_ALTIVEC_207
|
9005 PPC2_ISA205
| PPC2_ISA207S
| PPC2_FP_CVT_S64
|
9006 PPC2_TM
| PPC2_ISA300
| PPC2_PRCNTL
;
9007 pcc
->msr_mask
= (1ull << MSR_SF
) |
9025 pcc
->mmu_model
= POWERPC_MMU_3_00
;
9026 #if defined(CONFIG_SOFTMMU)
9027 pcc
->handle_mmu_fault
= ppc64_v3_handle_mmu_fault
;
9028 /* segment page size remain the same */
9029 pcc
->hash64_opts
= &ppc_hash64_opts_POWER7
;
9030 pcc
->radix_page_info
= &POWER9_radix_page_info
;
9031 pcc
->lrg_decr_bits
= 56;
9032 pcc
->n_host_threads
= 4;
9034 pcc
->excp_model
= POWERPC_EXCP_POWER9
;
9035 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER9
;
9036 pcc
->bfd_mach
= bfd_mach_ppc64
;
9037 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
9038 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
9039 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
9040 POWERPC_FLAG_VSX
| POWERPC_FLAG_TM
;
9041 pcc
->l1_dcache_size
= 0x8000;
9042 pcc
->l1_icache_size
= 0x8000;
9043 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
9044 pcc
->lpcr_pm
= LPCR_PDEE
| LPCR_HDEE
| LPCR_EEE
| LPCR_DEE
| LPCR_OEE
;
9047 #ifdef CONFIG_SOFTMMU
9049 * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings
9050 * Encoded as array of int_32s in the form:
9051 * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
9053 * y -> radix mode supported page size (encoded as a shift)
9055 static struct ppc_radix_page_info POWER10_radix_page_info
= {
9058 0x0000000c, /* 4K - enc: 0x0 */
9059 0xa0000010, /* 64K - enc: 0x5 */
9060 0x20000015, /* 2M - enc: 0x1 */
9061 0x4000001e /* 1G - enc: 0x2 */
9064 #endif /* CONFIG_SOFTMMU */
9066 static void init_proc_POWER10(CPUPPCState
*env
)
9068 /* Common Registers */
9069 init_proc_book3s_common(env
);
9070 gen_spr_book3s_207_dbg(env
);
9072 /* POWER8 Specific Registers */
9073 gen_spr_book3s_ids(env
);
9076 gen_spr_book3s_purr(env
);
9077 gen_spr_power5p_common(env
);
9078 gen_spr_power5p_lpar(env
);
9079 gen_spr_power5p_ear(env
);
9080 gen_spr_power6_common(env
);
9081 gen_spr_power6_dbg(env
);
9082 gen_spr_power8_tce_address_control(env
);
9083 gen_spr_power8_ids(env
);
9084 gen_spr_power8_ebb(env
);
9085 gen_spr_power8_fscr(env
);
9086 gen_spr_power8_pmu_sup(env
);
9087 gen_spr_power8_pmu_user(env
);
9088 gen_spr_power8_tm(env
);
9089 gen_spr_power8_pspb(env
);
9091 gen_spr_power8_ic(env
);
9092 gen_spr_power8_book4(env
);
9093 gen_spr_power8_rpr(env
);
9094 gen_spr_power9_mmu(env
);
9096 /* POWER9 Specific registers */
9097 spr_register_kvm(env
, SPR_TIDR
, "TIDR", NULL
, NULL
,
9098 spr_read_generic
, spr_write_generic
,
9099 KVM_REG_PPC_TIDR
, 0);
9101 /* FIXME: Filter fields properly based on privilege level */
9102 spr_register_kvm_hv(env
, SPR_PSSCR
, "PSSCR", NULL
, NULL
, NULL
, NULL
,
9103 spr_read_generic
, spr_write_generic
,
9104 KVM_REG_PPC_PSSCR
, 0);
9107 env
->dcache_line_size
= 128;
9108 env
->icache_line_size
= 128;
9110 /* Allocate hardware IRQ controller */
9111 init_excp_POWER10(env
);
9112 ppcPOWER9_irq_init(env_archcpu(env
));
9115 static bool ppc_pvr_match_power10(PowerPCCPUClass
*pcc
, uint32_t pvr
)
9117 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER10_BASE
) {
9123 static bool cpu_has_work_POWER10(CPUState
*cs
)
9125 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
9126 CPUPPCState
*env
= &cpu
->env
;
9129 uint64_t psscr
= env
->spr
[SPR_PSSCR
];
9131 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
9135 /* If EC is clear, just return true on any pending interrupt */
9136 if (!(psscr
& PSSCR_EC
)) {
9139 /* External Exception */
9140 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
9141 (env
->spr
[SPR_LPCR
] & LPCR_EEE
)) {
9142 bool heic
= !!(env
->spr
[SPR_LPCR
] & LPCR_HEIC
);
9143 if (heic
== 0 || !msr_hv
|| msr_pr
) {
9147 /* Decrementer Exception */
9148 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
9149 (env
->spr
[SPR_LPCR
] & LPCR_DEE
)) {
9152 /* Machine Check or Hypervisor Maintenance Exception */
9153 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
|
9154 1u << PPC_INTERRUPT_HMI
)) && (env
->spr
[SPR_LPCR
] & LPCR_OEE
)) {
9157 /* Privileged Doorbell Exception */
9158 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DOORBELL
)) &&
9159 (env
->spr
[SPR_LPCR
] & LPCR_PDEE
)) {
9162 /* Hypervisor Doorbell Exception */
9163 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HDOORBELL
)) &&
9164 (env
->spr
[SPR_LPCR
] & LPCR_HDEE
)) {
9167 /* Hypervisor virtualization exception */
9168 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HVIRT
)) &&
9169 (env
->spr
[SPR_LPCR
] & LPCR_HVEE
)) {
9172 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
9177 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
9181 POWERPC_FAMILY(POWER10
)(ObjectClass
*oc
, void *data
)
9183 DeviceClass
*dc
= DEVICE_CLASS(oc
);
9184 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
9185 CPUClass
*cc
= CPU_CLASS(oc
);
9187 dc
->fw_name
= "PowerPC,POWER10";
9188 dc
->desc
= "POWER10";
9189 dc
->props
= powerpc_servercpu_properties
;
9190 pcc
->pvr_match
= ppc_pvr_match_power10
;
9191 pcc
->pcr_mask
= PCR_COMPAT_2_05
| PCR_COMPAT_2_06
| PCR_COMPAT_2_07
|
9193 pcc
->pcr_supported
= PCR_COMPAT_3_10
| PCR_COMPAT_3_00
| PCR_COMPAT_2_07
|
9194 PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
9195 pcc
->init_proc
= init_proc_POWER10
;
9196 pcc
->check_pow
= check_pow_nocheck
;
9197 cc
->has_work
= cpu_has_work_POWER10
;
9198 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
9199 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
9200 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
9201 PPC_FLOAT_FRSQRTES
|
9204 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
9205 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
9207 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
9208 PPC_SEGMENT_64B
| PPC_SLBI
|
9209 PPC_POPCNTB
| PPC_POPCNTWD
|
9211 pcc
->insns_flags2
= PPC2_VSX
| PPC2_VSX207
| PPC2_DFP
| PPC2_DBRX
|
9212 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
9213 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
9214 PPC2_FP_TST_ISA206
| PPC2_BCTAR_ISA207
|
9215 PPC2_LSQ_ISA207
| PPC2_ALTIVEC_207
|
9216 PPC2_ISA205
| PPC2_ISA207S
| PPC2_FP_CVT_S64
|
9217 PPC2_TM
| PPC2_ISA300
| PPC2_PRCNTL
;
9218 pcc
->msr_mask
= (1ull << MSR_SF
) |
9236 pcc
->mmu_model
= POWERPC_MMU_3_00
;
9237 #if defined(CONFIG_SOFTMMU)
9238 pcc
->handle_mmu_fault
= ppc64_v3_handle_mmu_fault
;
9239 /* segment page size remain the same */
9240 pcc
->hash64_opts
= &ppc_hash64_opts_POWER7
;
9241 pcc
->radix_page_info
= &POWER10_radix_page_info
;
9242 pcc
->lrg_decr_bits
= 56;
9244 pcc
->excp_model
= POWERPC_EXCP_POWER9
;
9245 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER9
;
9246 pcc
->bfd_mach
= bfd_mach_ppc64
;
9247 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
9248 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
9249 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
9250 POWERPC_FLAG_VSX
| POWERPC_FLAG_TM
;
9251 pcc
->l1_dcache_size
= 0x8000;
9252 pcc
->l1_icache_size
= 0x8000;
9253 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
9254 pcc
->lpcr_pm
= LPCR_PDEE
| LPCR_HDEE
| LPCR_EEE
| LPCR_DEE
| LPCR_OEE
;
9257 #if !defined(CONFIG_USER_ONLY)
9258 void cpu_ppc_set_vhyp(PowerPCCPU
*cpu
, PPCVirtualHypervisor
*vhyp
)
9260 CPUPPCState
*env
= &cpu
->env
;
9265 * With a virtual hypervisor mode we never allow the CPU to go
9266 * hypervisor mode itself
9268 env
->msr_mask
&= ~MSR_HVB
;
9271 #endif /* !defined(CONFIG_USER_ONLY) */
9273 #endif /* defined(TARGET_PPC64) */
9275 /*****************************************************************************/
9276 /* Generic CPU instantiation routine */
9277 static void init_ppc_proc(PowerPCCPU
*cpu
)
9279 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9280 CPUPPCState
*env
= &cpu
->env
;
9281 #if !defined(CONFIG_USER_ONLY)
9284 env
->irq_inputs
= NULL
;
9285 /* Set all exception vectors to an invalid address */
9286 for (i
= 0; i
< POWERPC_EXCP_NB
; i
++) {
9287 env
->excp_vectors
[i
] = (target_ulong
)(-1ULL);
9289 env
->ivor_mask
= 0x00000000;
9290 env
->ivpr_mask
= 0x00000000;
9291 /* Default MMU definitions */
9295 env
->tlb_type
= TLB_NONE
;
9297 /* Register SPR common to all PowerPC implementations */
9298 gen_spr_generic(env
);
9299 spr_register(env
, SPR_PVR
, "PVR",
9300 /* Linux permits userspace to read PVR */
9301 #if defined(CONFIG_LINUX_USER)
9307 &spr_read_generic
, SPR_NOACCESS
,
9309 /* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
9310 if (pcc
->svr
!= POWERPC_SVR_NONE
) {
9311 if (pcc
->svr
& POWERPC_SVR_E500
) {
9312 spr_register(env
, SPR_E500_SVR
, "SVR",
9313 SPR_NOACCESS
, SPR_NOACCESS
,
9314 &spr_read_generic
, SPR_NOACCESS
,
9315 pcc
->svr
& ~POWERPC_SVR_E500
);
9317 spr_register(env
, SPR_SVR
, "SVR",
9318 SPR_NOACCESS
, SPR_NOACCESS
,
9319 &spr_read_generic
, SPR_NOACCESS
,
9323 /* PowerPC implementation specific initialisations (SPRs, timers, ...) */
9324 (*pcc
->init_proc
)(env
);
9326 #if !defined(CONFIG_USER_ONLY)
9327 ppc_gdb_gen_spr_xml(cpu
);
9330 /* MSR bits & flags consistency checks */
9331 if (env
->msr_mask
& (1 << 25)) {
9332 switch (env
->flags
& (POWERPC_FLAG_SPE
| POWERPC_FLAG_VRE
)) {
9333 case POWERPC_FLAG_SPE
:
9334 case POWERPC_FLAG_VRE
:
9337 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9338 "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n");
9341 } else if (env
->flags
& (POWERPC_FLAG_SPE
| POWERPC_FLAG_VRE
)) {
9342 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9343 "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n");
9346 if (env
->msr_mask
& (1 << 17)) {
9347 switch (env
->flags
& (POWERPC_FLAG_TGPR
| POWERPC_FLAG_CE
)) {
9348 case POWERPC_FLAG_TGPR
:
9349 case POWERPC_FLAG_CE
:
9352 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9353 "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n");
9356 } else if (env
->flags
& (POWERPC_FLAG_TGPR
| POWERPC_FLAG_CE
)) {
9357 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9358 "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n");
9361 if (env
->msr_mask
& (1 << 10)) {
9362 switch (env
->flags
& (POWERPC_FLAG_SE
| POWERPC_FLAG_DWE
|
9363 POWERPC_FLAG_UBLE
)) {
9364 case POWERPC_FLAG_SE
:
9365 case POWERPC_FLAG_DWE
:
9366 case POWERPC_FLAG_UBLE
:
9369 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9370 "Should define POWERPC_FLAG_SE or POWERPC_FLAG_DWE or "
9371 "POWERPC_FLAG_UBLE\n");
9374 } else if (env
->flags
& (POWERPC_FLAG_SE
| POWERPC_FLAG_DWE
|
9375 POWERPC_FLAG_UBLE
)) {
9376 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9377 "Should not define POWERPC_FLAG_SE nor POWERPC_FLAG_DWE nor "
9378 "POWERPC_FLAG_UBLE\n");
9381 if (env
->msr_mask
& (1 << 9)) {
9382 switch (env
->flags
& (POWERPC_FLAG_BE
| POWERPC_FLAG_DE
)) {
9383 case POWERPC_FLAG_BE
:
9384 case POWERPC_FLAG_DE
:
9387 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9388 "Should define POWERPC_FLAG_BE or POWERPC_FLAG_DE\n");
9391 } else if (env
->flags
& (POWERPC_FLAG_BE
| POWERPC_FLAG_DE
)) {
9392 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9393 "Should not define POWERPC_FLAG_BE nor POWERPC_FLAG_DE\n");
9396 if (env
->msr_mask
& (1 << 2)) {
9397 switch (env
->flags
& (POWERPC_FLAG_PX
| POWERPC_FLAG_PMM
)) {
9398 case POWERPC_FLAG_PX
:
9399 case POWERPC_FLAG_PMM
:
9402 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9403 "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n");
9406 } else if (env
->flags
& (POWERPC_FLAG_PX
| POWERPC_FLAG_PMM
)) {
9407 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9408 "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n");
9411 if ((env
->flags
& (POWERPC_FLAG_RTC_CLK
| POWERPC_FLAG_BUS_CLK
)) == 0) {
9412 fprintf(stderr
, "PowerPC flags inconsistency\n"
9413 "Should define the time-base and decrementer clock source\n");
9416 /* Allocate TLBs buffer when needed */
9417 #if !defined(CONFIG_USER_ONLY)
9418 if (env
->nb_tlb
!= 0) {
9419 int nb_tlb
= env
->nb_tlb
;
9420 if (env
->id_tlbs
!= 0) {
9423 switch (env
->tlb_type
) {
9425 env
->tlb
.tlb6
= g_new0(ppc6xx_tlb_t
, nb_tlb
);
9428 env
->tlb
.tlbe
= g_new0(ppcemb_tlb_t
, nb_tlb
);
9431 env
->tlb
.tlbm
= g_new0(ppcmas_tlb_t
, nb_tlb
);
9434 /* Pre-compute some useful values */
9435 env
->tlb_per_way
= env
->nb_tlb
/ env
->nb_ways
;
9437 if (env
->irq_inputs
== NULL
) {
9438 warn_report("no internal IRQ controller registered."
9439 " Attempt QEMU to crash very soon !");
9442 if (env
->check_pow
== NULL
) {
9443 warn_report("no power management check handler registered."
9444 " Attempt QEMU to crash very soon !");
9448 #if defined(PPC_DUMP_CPU)
9449 static void dump_ppc_sprs(CPUPPCState
*env
)
9452 #if !defined(CONFIG_USER_ONLY)
9458 printf("Special purpose registers:\n");
9459 for (i
= 0; i
< 32; i
++) {
9460 for (j
= 0; j
< 32; j
++) {
9462 spr
= &env
->spr_cb
[n
];
9463 uw
= spr
->uea_write
!= NULL
&& spr
->uea_write
!= SPR_NOACCESS
;
9464 ur
= spr
->uea_read
!= NULL
&& spr
->uea_read
!= SPR_NOACCESS
;
9465 #if !defined(CONFIG_USER_ONLY)
9466 sw
= spr
->oea_write
!= NULL
&& spr
->oea_write
!= SPR_NOACCESS
;
9467 sr
= spr
->oea_read
!= NULL
&& spr
->oea_read
!= SPR_NOACCESS
;
9468 if (sw
|| sr
|| uw
|| ur
) {
9469 printf("SPR: %4d (%03x) %-8s s%c%c u%c%c\n",
9470 (i
<< 5) | j
, (i
<< 5) | j
, spr
->name
,
9471 sw
? 'w' : '-', sr
? 'r' : '-',
9472 uw
? 'w' : '-', ur
? 'r' : '-');
9476 printf("SPR: %4d (%03x) %-8s u%c%c\n",
9477 (i
<< 5) | j
, (i
<< 5) | j
, spr
->name
,
9478 uw
? 'w' : '-', ur
? 'r' : '-');
9488 /*****************************************************************************/
9492 PPC_DIRECT
= 0, /* Opcode routine */
9493 PPC_INDIRECT
= 1, /* Indirect opcode table */
9496 #define PPC_OPCODE_MASK 0x3
9498 static inline int is_indirect_opcode(void *handler
)
9500 return ((uintptr_t)handler
& PPC_OPCODE_MASK
) == PPC_INDIRECT
;
9503 static inline opc_handler_t
**ind_table(void *handler
)
9505 return (opc_handler_t
**)((uintptr_t)handler
& ~PPC_OPCODE_MASK
);
9508 /* Instruction table creation */
9509 /* Opcodes tables creation */
9510 static void fill_new_table(opc_handler_t
**table
, int len
)
9514 for (i
= 0; i
< len
; i
++) {
9515 table
[i
] = &invalid_handler
;
9519 static int create_new_table(opc_handler_t
**table
, unsigned char idx
)
9521 opc_handler_t
**tmp
;
9523 tmp
= g_new(opc_handler_t
*, PPC_CPU_INDIRECT_OPCODES_LEN
);
9524 fill_new_table(tmp
, PPC_CPU_INDIRECT_OPCODES_LEN
);
9525 table
[idx
] = (opc_handler_t
*)((uintptr_t)tmp
| PPC_INDIRECT
);
9530 static int insert_in_table(opc_handler_t
**table
, unsigned char idx
,
9531 opc_handler_t
*handler
)
9533 if (table
[idx
] != &invalid_handler
) {
9536 table
[idx
] = handler
;
9541 static int register_direct_insn(opc_handler_t
**ppc_opcodes
,
9542 unsigned char idx
, opc_handler_t
*handler
)
9544 if (insert_in_table(ppc_opcodes
, idx
, handler
) < 0) {
9545 printf("*** ERROR: opcode %02x already assigned in main "
9546 "opcode table\n", idx
);
9547 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9548 printf(" Registered handler '%s' - new handler '%s'\n",
9549 ppc_opcodes
[idx
]->oname
, handler
->oname
);
9557 static int register_ind_in_table(opc_handler_t
**table
,
9558 unsigned char idx1
, unsigned char idx2
,
9559 opc_handler_t
*handler
)
9561 if (table
[idx1
] == &invalid_handler
) {
9562 if (create_new_table(table
, idx1
) < 0) {
9563 printf("*** ERROR: unable to create indirect table "
9564 "idx=%02x\n", idx1
);
9568 if (!is_indirect_opcode(table
[idx1
])) {
9569 printf("*** ERROR: idx %02x already assigned to a direct "
9571 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9572 printf(" Registered handler '%s' - new handler '%s'\n",
9573 ind_table(table
[idx1
])[idx2
]->oname
, handler
->oname
);
9578 if (handler
!= NULL
&&
9579 insert_in_table(ind_table(table
[idx1
]), idx2
, handler
) < 0) {
9580 printf("*** ERROR: opcode %02x already assigned in "
9581 "opcode table %02x\n", idx2
, idx1
);
9582 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9583 printf(" Registered handler '%s' - new handler '%s'\n",
9584 ind_table(table
[idx1
])[idx2
]->oname
, handler
->oname
);
9592 static int register_ind_insn(opc_handler_t
**ppc_opcodes
,
9593 unsigned char idx1
, unsigned char idx2
,
9594 opc_handler_t
*handler
)
9596 return register_ind_in_table(ppc_opcodes
, idx1
, idx2
, handler
);
9599 static int register_dblind_insn(opc_handler_t
**ppc_opcodes
,
9600 unsigned char idx1
, unsigned char idx2
,
9601 unsigned char idx3
, opc_handler_t
*handler
)
9603 if (register_ind_in_table(ppc_opcodes
, idx1
, idx2
, NULL
) < 0) {
9604 printf("*** ERROR: unable to join indirect table idx "
9605 "[%02x-%02x]\n", idx1
, idx2
);
9608 if (register_ind_in_table(ind_table(ppc_opcodes
[idx1
]), idx2
, idx3
,
9610 printf("*** ERROR: unable to insert opcode "
9611 "[%02x-%02x-%02x]\n", idx1
, idx2
, idx3
);
9618 static int register_trplind_insn(opc_handler_t
**ppc_opcodes
,
9619 unsigned char idx1
, unsigned char idx2
,
9620 unsigned char idx3
, unsigned char idx4
,
9621 opc_handler_t
*handler
)
9623 opc_handler_t
**table
;
9625 if (register_ind_in_table(ppc_opcodes
, idx1
, idx2
, NULL
) < 0) {
9626 printf("*** ERROR: unable to join indirect table idx "
9627 "[%02x-%02x]\n", idx1
, idx2
);
9630 table
= ind_table(ppc_opcodes
[idx1
]);
9631 if (register_ind_in_table(table
, idx2
, idx3
, NULL
) < 0) {
9632 printf("*** ERROR: unable to join 2nd-level indirect table idx "
9633 "[%02x-%02x-%02x]\n", idx1
, idx2
, idx3
);
9636 table
= ind_table(table
[idx2
]);
9637 if (register_ind_in_table(table
, idx3
, idx4
, handler
) < 0) {
9638 printf("*** ERROR: unable to insert opcode "
9639 "[%02x-%02x-%02x-%02x]\n", idx1
, idx2
, idx3
, idx4
);
9644 static int register_insn(opc_handler_t
**ppc_opcodes
, opcode_t
*insn
)
9646 if (insn
->opc2
!= 0xFF) {
9647 if (insn
->opc3
!= 0xFF) {
9648 if (insn
->opc4
!= 0xFF) {
9649 if (register_trplind_insn(ppc_opcodes
, insn
->opc1
, insn
->opc2
,
9650 insn
->opc3
, insn
->opc4
,
9651 &insn
->handler
) < 0) {
9655 if (register_dblind_insn(ppc_opcodes
, insn
->opc1
, insn
->opc2
,
9656 insn
->opc3
, &insn
->handler
) < 0) {
9661 if (register_ind_insn(ppc_opcodes
, insn
->opc1
,
9662 insn
->opc2
, &insn
->handler
) < 0) {
9667 if (register_direct_insn(ppc_opcodes
, insn
->opc1
, &insn
->handler
) < 0) {
9675 static int test_opcode_table(opc_handler_t
**table
, int len
)
9679 for (i
= 0, count
= 0; i
< len
; i
++) {
9680 /* Consistency fixup */
9681 if (table
[i
] == NULL
) {
9682 table
[i
] = &invalid_handler
;
9684 if (table
[i
] != &invalid_handler
) {
9685 if (is_indirect_opcode(table
[i
])) {
9686 tmp
= test_opcode_table(ind_table(table
[i
]),
9687 PPC_CPU_INDIRECT_OPCODES_LEN
);
9690 table
[i
] = &invalid_handler
;
9703 static void fix_opcode_tables(opc_handler_t
**ppc_opcodes
)
9705 if (test_opcode_table(ppc_opcodes
, PPC_CPU_OPCODES_LEN
) == 0) {
9706 printf("*** WARNING: no opcode defined !\n");
9710 /*****************************************************************************/
9711 static void create_ppc_opcodes(PowerPCCPU
*cpu
, Error
**errp
)
9713 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9716 fill_new_table(cpu
->opcodes
, PPC_CPU_OPCODES_LEN
);
9717 for (opc
= opcodes
; opc
< &opcodes
[ARRAY_SIZE(opcodes
)]; opc
++) {
9718 if (((opc
->handler
.type
& pcc
->insns_flags
) != 0) ||
9719 ((opc
->handler
.type2
& pcc
->insns_flags2
) != 0)) {
9720 if (register_insn(cpu
->opcodes
, opc
) < 0) {
9721 error_setg(errp
, "ERROR initializing PowerPC instruction "
9722 "0x%02x 0x%02x 0x%02x", opc
->opc1
, opc
->opc2
,
9728 fix_opcode_tables(cpu
->opcodes
);
9733 #if defined(PPC_DUMP_CPU)
9734 static void dump_ppc_insns(CPUPPCState
*env
)
9736 opc_handler_t
**table
, *handler
;
9738 uint8_t opc1
, opc2
, opc3
, opc4
;
9740 printf("Instructions set:\n");
9741 /* opc1 is 6 bits long */
9742 for (opc1
= 0x00; opc1
< PPC_CPU_OPCODES_LEN
; opc1
++) {
9743 table
= env
->opcodes
;
9744 handler
= table
[opc1
];
9745 if (is_indirect_opcode(handler
)) {
9746 /* opc2 is 5 bits long */
9747 for (opc2
= 0; opc2
< PPC_CPU_INDIRECT_OPCODES_LEN
; opc2
++) {
9748 table
= env
->opcodes
;
9749 handler
= env
->opcodes
[opc1
];
9750 table
= ind_table(handler
);
9751 handler
= table
[opc2
];
9752 if (is_indirect_opcode(handler
)) {
9753 table
= ind_table(handler
);
9754 /* opc3 is 5 bits long */
9755 for (opc3
= 0; opc3
< PPC_CPU_INDIRECT_OPCODES_LEN
;
9757 handler
= table
[opc3
];
9758 if (is_indirect_opcode(handler
)) {
9759 table
= ind_table(handler
);
9760 /* opc4 is 5 bits long */
9761 for (opc4
= 0; opc4
< PPC_CPU_INDIRECT_OPCODES_LEN
;
9763 handler
= table
[opc4
];
9764 if (handler
->handler
!= &gen_invalid
) {
9765 printf("INSN: %02x %02x %02x %02x -- "
9766 "(%02d %04d %02d) : %s\n",
9767 opc1
, opc2
, opc3
, opc4
,
9768 opc1
, (opc3
<< 5) | opc2
, opc4
,
9773 if (handler
->handler
!= &gen_invalid
) {
9774 /* Special hack to properly dump SPE insns */
9775 p
= strchr(handler
->oname
, '_');
9777 printf("INSN: %02x %02x %02x (%02d %04d) : "
9779 opc1
, opc2
, opc3
, opc1
,
9784 if ((p
- handler
->oname
) != strlen(q
)
9785 || (memcmp(handler
->oname
, q
, strlen(q
))
9787 /* First instruction */
9788 printf("INSN: %02x %02x %02x"
9789 "(%02d %04d) : %.*s\n",
9790 opc1
, opc2
<< 1, opc3
, opc1
,
9791 (opc3
<< 6) | (opc2
<< 1),
9792 (int)(p
- handler
->oname
),
9795 if (strcmp(p
+ 1, q
) != 0) {
9796 /* Second instruction */
9797 printf("INSN: %02x %02x %02x "
9798 "(%02d %04d) : %s\n", opc1
,
9799 (opc2
<< 1) | 1, opc3
, opc1
,
9800 (opc3
<< 6) | (opc2
<< 1) | 1,
9808 if (handler
->handler
!= &gen_invalid
) {
9809 printf("INSN: %02x %02x -- (%02d %04d) : %s\n",
9810 opc1
, opc2
, opc1
, opc2
, handler
->oname
);
9815 if (handler
->handler
!= &gen_invalid
) {
9816 printf("INSN: %02x -- -- (%02d ----) : %s\n",
9817 opc1
, opc1
, handler
->oname
);
9824 static bool avr_need_swap(CPUPPCState
*env
)
9826 #ifdef HOST_WORDS_BIGENDIAN
9833 #if !defined(CONFIG_USER_ONLY)
9834 static int gdb_find_spr_idx(CPUPPCState
*env
, int n
)
9838 for (i
= 0; i
< ARRAY_SIZE(env
->spr_cb
); i
++) {
9839 ppc_spr_t
*spr
= &env
->spr_cb
[i
];
9841 if (spr
->name
&& spr
->gdb_id
== n
) {
9848 static int gdb_get_spr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9853 reg
= gdb_find_spr_idx(env
, n
);
9858 len
= TARGET_LONG_SIZE
;
9859 stn_p(mem_buf
, len
, env
->spr
[reg
]);
9860 ppc_maybe_bswap_register(env
, mem_buf
, len
);
9864 static int gdb_set_spr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9869 reg
= gdb_find_spr_idx(env
, n
);
9874 len
= TARGET_LONG_SIZE
;
9875 ppc_maybe_bswap_register(env
, mem_buf
, len
);
9876 env
->spr
[reg
] = ldn_p(mem_buf
, len
);
9882 static int gdb_get_float_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9885 stfq_p(mem_buf
, *cpu_fpr_ptr(env
, n
));
9886 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9890 stl_p(mem_buf
, env
->fpscr
);
9891 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9897 static int gdb_set_float_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9900 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9901 *cpu_fpr_ptr(env
, n
) = ldfq_p(mem_buf
);
9905 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9906 helper_store_fpscr(env
, ldl_p(mem_buf
), 0xffffffff);
9912 static int gdb_get_avr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9915 ppc_avr_t
*avr
= cpu_avr_ptr(env
, n
);
9916 if (!avr_need_swap(env
)) {
9917 stq_p(mem_buf
, avr
->u64
[0]);
9918 stq_p(mem_buf
+ 8, avr
->u64
[1]);
9920 stq_p(mem_buf
, avr
->u64
[1]);
9921 stq_p(mem_buf
+ 8, avr
->u64
[0]);
9923 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9924 ppc_maybe_bswap_register(env
, mem_buf
+ 8, 8);
9928 stl_p(mem_buf
, helper_mfvscr(env
));
9929 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9933 stl_p(mem_buf
, (uint32_t)env
->spr
[SPR_VRSAVE
]);
9934 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9940 static int gdb_set_avr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9943 ppc_avr_t
*avr
= cpu_avr_ptr(env
, n
);
9944 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9945 ppc_maybe_bswap_register(env
, mem_buf
+ 8, 8);
9946 if (!avr_need_swap(env
)) {
9947 avr
->u64
[0] = ldq_p(mem_buf
);
9948 avr
->u64
[1] = ldq_p(mem_buf
+ 8);
9950 avr
->u64
[1] = ldq_p(mem_buf
);
9951 avr
->u64
[0] = ldq_p(mem_buf
+ 8);
9956 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9957 helper_mtvscr(env
, ldl_p(mem_buf
));
9961 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9962 env
->spr
[SPR_VRSAVE
] = (target_ulong
)ldl_p(mem_buf
);
9968 static int gdb_get_spe_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9971 #if defined(TARGET_PPC64)
9972 stl_p(mem_buf
, env
->gpr
[n
] >> 32);
9973 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9975 stl_p(mem_buf
, env
->gprh
[n
]);
9980 stq_p(mem_buf
, env
->spe_acc
);
9981 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9985 stl_p(mem_buf
, env
->spe_fscr
);
9986 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9992 static int gdb_set_spe_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9995 #if defined(TARGET_PPC64)
9996 target_ulong lo
= (uint32_t)env
->gpr
[n
];
9999 ppc_maybe_bswap_register(env
, mem_buf
, 4);
10001 hi
= (target_ulong
)ldl_p(mem_buf
) << 32;
10002 env
->gpr
[n
] = lo
| hi
;
10004 env
->gprh
[n
] = ldl_p(mem_buf
);
10009 ppc_maybe_bswap_register(env
, mem_buf
, 8);
10010 env
->spe_acc
= ldq_p(mem_buf
);
10014 ppc_maybe_bswap_register(env
, mem_buf
, 4);
10015 env
->spe_fscr
= ldl_p(mem_buf
);
10021 static int gdb_get_vsx_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
10024 stq_p(mem_buf
, *cpu_vsrl_ptr(env
, n
));
10025 ppc_maybe_bswap_register(env
, mem_buf
, 8);
10031 static int gdb_set_vsx_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
10034 ppc_maybe_bswap_register(env
, mem_buf
, 8);
10035 *cpu_vsrl_ptr(env
, n
) = ldq_p(mem_buf
);
10041 static int ppc_fixup_cpu(PowerPCCPU
*cpu
)
10043 CPUPPCState
*env
= &cpu
->env
;
10046 * TCG doesn't (yet) emulate some groups of instructions that are
10047 * implemented on some otherwise supported CPUs (e.g. VSX and
10048 * decimal floating point instructions on POWER7). We remove
10049 * unsupported instruction groups from the cpu state's instruction
10050 * masks and hope the guest can cope. For at least the pseries
10051 * machine, the unavailability of these instructions can be
10052 * advertised to the guest via the device tree.
10054 if ((env
->insns_flags
& ~PPC_TCG_INSNS
)
10055 || (env
->insns_flags2
& ~PPC_TCG_INSNS2
)) {
10056 warn_report("Disabling some instructions which are not "
10057 "emulated by TCG (0x%" PRIx64
", 0x%" PRIx64
")",
10058 env
->insns_flags
& ~PPC_TCG_INSNS
,
10059 env
->insns_flags2
& ~PPC_TCG_INSNS2
);
10061 env
->insns_flags
&= PPC_TCG_INSNS
;
10062 env
->insns_flags2
&= PPC_TCG_INSNS2
;
10066 static void ppc_cpu_realize(DeviceState
*dev
, Error
**errp
)
10068 CPUState
*cs
= CPU(dev
);
10069 PowerPCCPU
*cpu
= POWERPC_CPU(dev
);
10070 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10071 Error
*local_err
= NULL
;
10073 cpu_exec_realizefn(cs
, &local_err
);
10074 if (local_err
!= NULL
) {
10075 error_propagate(errp
, local_err
);
10078 if (cpu
->vcpu_id
== UNASSIGNED_CPU_INDEX
) {
10079 cpu
->vcpu_id
= cs
->cpu_index
;
10082 if (tcg_enabled()) {
10083 if (ppc_fixup_cpu(cpu
) != 0) {
10084 error_setg(errp
, "Unable to emulate selected CPU with TCG");
10089 create_ppc_opcodes(cpu
, &local_err
);
10090 if (local_err
!= NULL
) {
10091 error_propagate(errp
, local_err
);
10094 init_ppc_proc(cpu
);
10096 if (pcc
->insns_flags
& PPC_FLOAT
) {
10097 gdb_register_coprocessor(cs
, gdb_get_float_reg
, gdb_set_float_reg
,
10098 33, "power-fpu.xml", 0);
10100 if (pcc
->insns_flags
& PPC_ALTIVEC
) {
10101 gdb_register_coprocessor(cs
, gdb_get_avr_reg
, gdb_set_avr_reg
,
10102 34, "power-altivec.xml", 0);
10104 if (pcc
->insns_flags
& PPC_SPE
) {
10105 gdb_register_coprocessor(cs
, gdb_get_spe_reg
, gdb_set_spe_reg
,
10106 34, "power-spe.xml", 0);
10108 if (pcc
->insns_flags2
& PPC2_VSX
) {
10109 gdb_register_coprocessor(cs
, gdb_get_vsx_reg
, gdb_set_vsx_reg
,
10110 32, "power-vsx.xml", 0);
10112 #ifndef CONFIG_USER_ONLY
10113 gdb_register_coprocessor(cs
, gdb_get_spr_reg
, gdb_set_spr_reg
,
10114 pcc
->gdb_num_sprs
, "power-spr.xml", 0);
10116 qemu_init_vcpu(cs
);
10118 pcc
->parent_realize(dev
, errp
);
10120 #if defined(PPC_DUMP_CPU)
10122 CPUPPCState
*env
= &cpu
->env
;
10123 const char *mmu_model
, *excp_model
, *bus_model
;
10124 switch (env
->mmu_model
) {
10125 case POWERPC_MMU_32B
:
10126 mmu_model
= "PowerPC 32";
10128 case POWERPC_MMU_SOFT_6xx
:
10129 mmu_model
= "PowerPC 6xx/7xx with software driven TLBs";
10131 case POWERPC_MMU_SOFT_74xx
:
10132 mmu_model
= "PowerPC 74xx with software driven TLBs";
10134 case POWERPC_MMU_SOFT_4xx
:
10135 mmu_model
= "PowerPC 4xx with software driven TLBs";
10137 case POWERPC_MMU_SOFT_4xx_Z
:
10138 mmu_model
= "PowerPC 4xx with software driven TLBs "
10139 "and zones protections";
10141 case POWERPC_MMU_REAL
:
10142 mmu_model
= "PowerPC real mode only";
10144 case POWERPC_MMU_MPC8xx
:
10145 mmu_model
= "PowerPC MPC8xx";
10147 case POWERPC_MMU_BOOKE
:
10148 mmu_model
= "PowerPC BookE";
10150 case POWERPC_MMU_BOOKE206
:
10151 mmu_model
= "PowerPC BookE 2.06";
10153 case POWERPC_MMU_601
:
10154 mmu_model
= "PowerPC 601";
10156 #if defined(TARGET_PPC64)
10157 case POWERPC_MMU_64B
:
10158 mmu_model
= "PowerPC 64";
10162 mmu_model
= "Unknown or invalid";
10165 switch (env
->excp_model
) {
10166 case POWERPC_EXCP_STD
:
10167 excp_model
= "PowerPC";
10169 case POWERPC_EXCP_40x
:
10170 excp_model
= "PowerPC 40x";
10172 case POWERPC_EXCP_601
:
10173 excp_model
= "PowerPC 601";
10175 case POWERPC_EXCP_602
:
10176 excp_model
= "PowerPC 602";
10178 case POWERPC_EXCP_603
:
10179 excp_model
= "PowerPC 603";
10181 case POWERPC_EXCP_603E
:
10182 excp_model
= "PowerPC 603e";
10184 case POWERPC_EXCP_604
:
10185 excp_model
= "PowerPC 604";
10187 case POWERPC_EXCP_7x0
:
10188 excp_model
= "PowerPC 740/750";
10190 case POWERPC_EXCP_7x5
:
10191 excp_model
= "PowerPC 745/755";
10193 case POWERPC_EXCP_74xx
:
10194 excp_model
= "PowerPC 74xx";
10196 case POWERPC_EXCP_BOOKE
:
10197 excp_model
= "PowerPC BookE";
10199 #if defined(TARGET_PPC64)
10200 case POWERPC_EXCP_970
:
10201 excp_model
= "PowerPC 970";
10205 excp_model
= "Unknown or invalid";
10208 switch (env
->bus_model
) {
10209 case PPC_FLAGS_INPUT_6xx
:
10210 bus_model
= "PowerPC 6xx";
10212 case PPC_FLAGS_INPUT_BookE
:
10213 bus_model
= "PowerPC BookE";
10215 case PPC_FLAGS_INPUT_405
:
10216 bus_model
= "PowerPC 405";
10218 case PPC_FLAGS_INPUT_401
:
10219 bus_model
= "PowerPC 401/403";
10221 case PPC_FLAGS_INPUT_RCPU
:
10222 bus_model
= "RCPU / MPC8xx";
10224 #if defined(TARGET_PPC64)
10225 case PPC_FLAGS_INPUT_970
:
10226 bus_model
= "PowerPC 970";
10230 bus_model
= "Unknown or invalid";
10233 printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64
"\n"
10234 " MMU model : %s\n",
10235 object_class_get_name(OBJECT_CLASS(pcc
)),
10236 pcc
->pvr
, pcc
->msr_mask
, mmu_model
);
10237 #if !defined(CONFIG_USER_ONLY)
10238 if (env
->tlb
.tlb6
) {
10239 printf(" %d %s TLB in %d ways\n",
10240 env
->nb_tlb
, env
->id_tlbs
? "splitted" : "merged",
10244 printf(" Exceptions model : %s\n"
10245 " Bus model : %s\n",
10246 excp_model
, bus_model
);
10247 printf(" MSR features :\n");
10248 if (env
->flags
& POWERPC_FLAG_SPE
) {
10249 printf(" signal processing engine enable"
10251 } else if (env
->flags
& POWERPC_FLAG_VRE
) {
10252 printf(" vector processor enable\n");
10254 if (env
->flags
& POWERPC_FLAG_TGPR
) {
10255 printf(" temporary GPRs\n");
10256 } else if (env
->flags
& POWERPC_FLAG_CE
) {
10257 printf(" critical input enable\n");
10259 if (env
->flags
& POWERPC_FLAG_SE
) {
10260 printf(" single-step trace mode\n");
10261 } else if (env
->flags
& POWERPC_FLAG_DWE
) {
10262 printf(" debug wait enable\n");
10263 } else if (env
->flags
& POWERPC_FLAG_UBLE
) {
10264 printf(" user BTB lock enable\n");
10266 if (env
->flags
& POWERPC_FLAG_BE
) {
10267 printf(" branch-step trace mode\n");
10268 } else if (env
->flags
& POWERPC_FLAG_DE
) {
10269 printf(" debug interrupt enable\n");
10271 if (env
->flags
& POWERPC_FLAG_PX
) {
10272 printf(" inclusive protection\n");
10273 } else if (env
->flags
& POWERPC_FLAG_PMM
) {
10274 printf(" performance monitor mark\n");
10276 if (env
->flags
== POWERPC_FLAG_NONE
) {
10279 printf(" Time-base/decrementer clock source: %s\n",
10280 env
->flags
& POWERPC_FLAG_RTC_CLK
? "RTC clock" : "bus clock");
10281 dump_ppc_insns(env
);
10282 dump_ppc_sprs(env
);
10289 cpu_exec_unrealizefn(cs
);
10292 static void ppc_cpu_unrealize(DeviceState
*dev
, Error
**errp
)
10294 PowerPCCPU
*cpu
= POWERPC_CPU(dev
);
10295 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10296 Error
*local_err
= NULL
;
10297 opc_handler_t
**table
, **table_2
;
10300 pcc
->parent_unrealize(dev
, &local_err
);
10301 if (local_err
!= NULL
) {
10302 error_propagate(errp
, local_err
);
10306 for (i
= 0; i
< PPC_CPU_OPCODES_LEN
; i
++) {
10307 if (cpu
->opcodes
[i
] == &invalid_handler
) {
10310 if (is_indirect_opcode(cpu
->opcodes
[i
])) {
10311 table
= ind_table(cpu
->opcodes
[i
]);
10312 for (j
= 0; j
< PPC_CPU_INDIRECT_OPCODES_LEN
; j
++) {
10313 if (table
[j
] == &invalid_handler
) {
10316 if (is_indirect_opcode(table
[j
])) {
10317 table_2
= ind_table(table
[j
]);
10318 for (k
= 0; k
< PPC_CPU_INDIRECT_OPCODES_LEN
; k
++) {
10319 if (table_2
[k
] != &invalid_handler
&&
10320 is_indirect_opcode(table_2
[k
])) {
10321 g_free((opc_handler_t
*)((uintptr_t)table_2
[k
] &
10325 g_free((opc_handler_t
*)((uintptr_t)table
[j
] &
10329 g_free((opc_handler_t
*)((uintptr_t)cpu
->opcodes
[i
] &
10335 static gint
ppc_cpu_compare_class_pvr(gconstpointer a
, gconstpointer b
)
10337 ObjectClass
*oc
= (ObjectClass
*)a
;
10338 uint32_t pvr
= *(uint32_t *)b
;
10339 PowerPCCPUClass
*pcc
= (PowerPCCPUClass
*)a
;
10341 /* -cpu host does a PVR lookup during construction */
10342 if (unlikely(strcmp(object_class_get_name(oc
),
10343 TYPE_HOST_POWERPC_CPU
) == 0)) {
10347 return pcc
->pvr
== pvr
? 0 : -1;
10350 PowerPCCPUClass
*ppc_cpu_class_by_pvr(uint32_t pvr
)
10352 GSList
*list
, *item
;
10353 PowerPCCPUClass
*pcc
= NULL
;
10355 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10356 item
= g_slist_find_custom(list
, &pvr
, ppc_cpu_compare_class_pvr
);
10357 if (item
!= NULL
) {
10358 pcc
= POWERPC_CPU_CLASS(item
->data
);
10360 g_slist_free(list
);
10365 static gint
ppc_cpu_compare_class_pvr_mask(gconstpointer a
, gconstpointer b
)
10367 ObjectClass
*oc
= (ObjectClass
*)a
;
10368 uint32_t pvr
= *(uint32_t *)b
;
10369 PowerPCCPUClass
*pcc
= (PowerPCCPUClass
*)a
;
10371 /* -cpu host does a PVR lookup during construction */
10372 if (unlikely(strcmp(object_class_get_name(oc
),
10373 TYPE_HOST_POWERPC_CPU
) == 0)) {
10377 if (pcc
->pvr_match(pcc
, pvr
)) {
10384 PowerPCCPUClass
*ppc_cpu_class_by_pvr_mask(uint32_t pvr
)
10386 GSList
*list
, *item
;
10387 PowerPCCPUClass
*pcc
= NULL
;
10389 list
= object_class_get_list(TYPE_POWERPC_CPU
, true);
10390 item
= g_slist_find_custom(list
, &pvr
, ppc_cpu_compare_class_pvr_mask
);
10391 if (item
!= NULL
) {
10392 pcc
= POWERPC_CPU_CLASS(item
->data
);
10394 g_slist_free(list
);
10399 static const char *ppc_cpu_lookup_alias(const char *alias
)
10403 for (ai
= 0; ppc_cpu_aliases
[ai
].alias
!= NULL
; ai
++) {
10404 if (strcmp(ppc_cpu_aliases
[ai
].alias
, alias
) == 0) {
10405 return ppc_cpu_aliases
[ai
].model
;
10412 static ObjectClass
*ppc_cpu_class_by_name(const char *name
)
10414 char *cpu_model
, *typename
;
10420 * Lookup by PVR if cpu_model is valid 8 digit hex number (excl:
10421 * 0x prefix if present)
10423 if (!qemu_strtoul(name
, &p
, 16, &pvr
)) {
10424 int len
= p
- name
;
10425 len
= (len
== 10) && (name
[1] == 'x') ? len
- 2 : len
;
10426 if ((len
== 8) && (*p
== '\0')) {
10427 return OBJECT_CLASS(ppc_cpu_class_by_pvr(pvr
));
10431 cpu_model
= g_ascii_strdown(name
, -1);
10432 p
= ppc_cpu_lookup_alias(cpu_model
);
10435 cpu_model
= g_strdup(p
);
10438 typename
= g_strdup_printf("%s" POWERPC_CPU_TYPE_SUFFIX
, cpu_model
);
10439 oc
= object_class_by_name(typename
);
10446 static void ppc_cpu_parse_featurestr(const char *type
, char *features
,
10449 Object
*machine
= qdev_get_machine();
10450 const PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(object_class_by_name(type
));
10456 if (object_property_find(machine
, "max-cpu-compat", NULL
)) {
10459 char *s
= features
;
10460 Error
*local_err
= NULL
;
10461 char *compat_str
= NULL
;
10464 * Backwards compatibility hack:
10466 * CPUs had a "compat=" property which didn't make sense for
10467 * anything except pseries. It was replaced by "max-cpu-compat"
10468 * machine option. This supports old command lines like
10469 * -cpu POWER8,compat=power7
10470 * By stripping the compat option and applying it to the machine
10471 * before passing it on to the cpu level parser.
10473 inpieces
= g_strsplit(features
, ",", 0);
10475 for (i
= 0; inpieces
[i
]; i
++) {
10476 if (g_str_has_prefix(inpieces
[i
], "compat=")) {
10477 compat_str
= inpieces
[i
];
10480 if ((i
!= 0) && (s
!= features
)) {
10481 s
= g_stpcpy(s
, ",");
10483 s
= g_stpcpy(s
, inpieces
[i
]);
10487 char *v
= compat_str
+ strlen("compat=");
10488 object_property_set_str(machine
, v
, "max-cpu-compat", &local_err
);
10490 g_strfreev(inpieces
);
10492 error_propagate(errp
, local_err
);
10497 /* do property processing with generic handler */
10498 pcc
->parent_parse_features(type
, features
, errp
);
10501 PowerPCCPUClass
*ppc_cpu_get_family_class(PowerPCCPUClass
*pcc
)
10503 ObjectClass
*oc
= OBJECT_CLASS(pcc
);
10505 while (oc
&& !object_class_is_abstract(oc
)) {
10506 oc
= object_class_get_parent(oc
);
10510 return POWERPC_CPU_CLASS(oc
);
10513 /* Sort by PVR, ordering special case "host" last. */
10514 static gint
ppc_cpu_list_compare(gconstpointer a
, gconstpointer b
)
10516 ObjectClass
*oc_a
= (ObjectClass
*)a
;
10517 ObjectClass
*oc_b
= (ObjectClass
*)b
;
10518 PowerPCCPUClass
*pcc_a
= POWERPC_CPU_CLASS(oc_a
);
10519 PowerPCCPUClass
*pcc_b
= POWERPC_CPU_CLASS(oc_b
);
10520 const char *name_a
= object_class_get_name(oc_a
);
10521 const char *name_b
= object_class_get_name(oc_b
);
10523 if (strcmp(name_a
, TYPE_HOST_POWERPC_CPU
) == 0) {
10525 } else if (strcmp(name_b
, TYPE_HOST_POWERPC_CPU
) == 0) {
10528 /* Avoid an integer overflow during subtraction */
10529 if (pcc_a
->pvr
< pcc_b
->pvr
) {
10531 } else if (pcc_a
->pvr
> pcc_b
->pvr
) {
10539 static void ppc_cpu_list_entry(gpointer data
, gpointer user_data
)
10541 ObjectClass
*oc
= data
;
10542 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10543 DeviceClass
*family
= DEVICE_CLASS(ppc_cpu_get_family_class(pcc
));
10544 const char *typename
= object_class_get_name(oc
);
10548 if (unlikely(strcmp(typename
, TYPE_HOST_POWERPC_CPU
) == 0)) {
10552 name
= g_strndup(typename
,
10553 strlen(typename
) - strlen(POWERPC_CPU_TYPE_SUFFIX
));
10554 qemu_printf("PowerPC %-16s PVR %08x\n", name
, pcc
->pvr
);
10555 for (i
= 0; ppc_cpu_aliases
[i
].alias
!= NULL
; i
++) {
10556 PowerPCCPUAlias
*alias
= &ppc_cpu_aliases
[i
];
10557 ObjectClass
*alias_oc
= ppc_cpu_class_by_name(alias
->model
);
10559 if (alias_oc
!= oc
) {
10563 * If running with KVM, we might update the family alias later, so
10564 * avoid printing the wrong alias here and use "preferred" instead
10566 if (strcmp(alias
->alias
, family
->desc
) == 0) {
10567 qemu_printf("PowerPC %-16s (alias for preferred %s CPU)\n",
10568 alias
->alias
, family
->desc
);
10570 qemu_printf("PowerPC %-16s (alias for %s)\n",
10571 alias
->alias
, name
);
10577 void ppc_cpu_list(void)
10581 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10582 list
= g_slist_sort(list
, ppc_cpu_list_compare
);
10583 g_slist_foreach(list
, ppc_cpu_list_entry
, NULL
);
10584 g_slist_free(list
);
10588 qemu_printf("PowerPC %-16s\n", "host");
10592 static void ppc_cpu_defs_entry(gpointer data
, gpointer user_data
)
10594 ObjectClass
*oc
= data
;
10595 CpuDefinitionInfoList
**first
= user_data
;
10596 const char *typename
;
10597 CpuDefinitionInfoList
*entry
;
10598 CpuDefinitionInfo
*info
;
10600 typename
= object_class_get_name(oc
);
10601 info
= g_malloc0(sizeof(*info
));
10602 info
->name
= g_strndup(typename
,
10603 strlen(typename
) - strlen(POWERPC_CPU_TYPE_SUFFIX
));
10605 entry
= g_malloc0(sizeof(*entry
));
10606 entry
->value
= info
;
10607 entry
->next
= *first
;
10611 CpuDefinitionInfoList
*qmp_query_cpu_definitions(Error
**errp
)
10613 CpuDefinitionInfoList
*cpu_list
= NULL
;
10617 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10618 g_slist_foreach(list
, ppc_cpu_defs_entry
, &cpu_list
);
10619 g_slist_free(list
);
10621 for (i
= 0; ppc_cpu_aliases
[i
].alias
!= NULL
; i
++) {
10622 PowerPCCPUAlias
*alias
= &ppc_cpu_aliases
[i
];
10624 CpuDefinitionInfoList
*entry
;
10625 CpuDefinitionInfo
*info
;
10627 oc
= ppc_cpu_class_by_name(alias
->model
);
10632 info
= g_malloc0(sizeof(*info
));
10633 info
->name
= g_strdup(alias
->alias
);
10634 info
->q_typename
= g_strdup(object_class_get_name(oc
));
10636 entry
= g_malloc0(sizeof(*entry
));
10637 entry
->value
= info
;
10638 entry
->next
= cpu_list
;
10645 static void ppc_cpu_set_pc(CPUState
*cs
, vaddr value
)
10647 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10649 cpu
->env
.nip
= value
;
10652 static bool ppc_cpu_has_work(CPUState
*cs
)
10654 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10655 CPUPPCState
*env
= &cpu
->env
;
10657 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
10660 /* CPUClass::reset() */
10661 static void ppc_cpu_reset(CPUState
*s
)
10663 PowerPCCPU
*cpu
= POWERPC_CPU(s
);
10664 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10665 CPUPPCState
*env
= &cpu
->env
;
10669 pcc
->parent_reset(s
);
10671 msr
= (target_ulong
)0;
10672 msr
|= (target_ulong
)MSR_HVB
;
10673 msr
|= (target_ulong
)0 << MSR_AP
; /* TO BE CHECKED */
10674 msr
|= (target_ulong
)0 << MSR_SA
; /* TO BE CHECKED */
10675 msr
|= (target_ulong
)1 << MSR_EP
;
10676 #if defined(DO_SINGLE_STEP) && 0
10677 /* Single step trace mode */
10678 msr
|= (target_ulong
)1 << MSR_SE
;
10679 msr
|= (target_ulong
)1 << MSR_BE
;
10681 #if defined(CONFIG_USER_ONLY)
10682 msr
|= (target_ulong
)1 << MSR_FP
; /* Allow floating point usage */
10683 msr
|= (target_ulong
)1 << MSR_FE0
; /* Allow floating point exceptions */
10684 msr
|= (target_ulong
)1 << MSR_FE1
;
10685 msr
|= (target_ulong
)1 << MSR_VR
; /* Allow altivec usage */
10686 msr
|= (target_ulong
)1 << MSR_VSX
; /* Allow VSX usage */
10687 msr
|= (target_ulong
)1 << MSR_SPE
; /* Allow SPE usage */
10688 msr
|= (target_ulong
)1 << MSR_PR
;
10689 #if defined(TARGET_PPC64)
10690 msr
|= (target_ulong
)1 << MSR_TM
; /* Transactional memory */
10692 #if !defined(TARGET_WORDS_BIGENDIAN)
10693 msr
|= (target_ulong
)1 << MSR_LE
; /* Little-endian user mode */
10694 if (!((env
->msr_mask
>> MSR_LE
) & 1)) {
10695 fprintf(stderr
, "Selected CPU does not support little-endian.\n");
10701 #if defined(TARGET_PPC64)
10702 if (env
->mmu_model
& POWERPC_MMU_64
) {
10703 msr
|= (1ULL << MSR_SF
);
10707 hreg_store_msr(env
, msr
, 1);
10709 #if !defined(CONFIG_USER_ONLY)
10710 env
->nip
= env
->hreset_vector
| env
->excp_prefix
;
10711 if (env
->mmu_model
!= POWERPC_MMU_REAL
) {
10712 ppc_tlb_invalidate_all(env
);
10716 hreg_compute_hflags(env
);
10717 env
->reserve_addr
= (target_ulong
)-1ULL;
10718 /* Be sure no exception or interrupt is pending */
10719 env
->pending_interrupts
= 0;
10720 s
->exception_index
= POWERPC_EXCP_NONE
;
10721 env
->error_code
= 0;
10722 ppc_irq_reset(cpu
);
10724 /* tininess for underflow is detected before rounding */
10725 set_float_detect_tininess(float_tininess_before_rounding
,
10728 for (i
= 0; i
< ARRAY_SIZE(env
->spr_cb
); i
++) {
10729 ppc_spr_t
*spr
= &env
->spr_cb
[i
];
10734 env
->spr
[i
] = spr
->default_value
;
10738 #ifndef CONFIG_USER_ONLY
10739 static bool ppc_cpu_is_big_endian(CPUState
*cs
)
10741 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10742 CPUPPCState
*env
= &cpu
->env
;
10744 cpu_synchronize_state(cs
);
10749 static void ppc_cpu_exec_enter(CPUState
*cs
)
10751 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10754 PPCVirtualHypervisorClass
*vhc
=
10755 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu
->vhyp
);
10756 vhc
->cpu_exec_enter(cpu
->vhyp
, cpu
);
10760 static void ppc_cpu_exec_exit(CPUState
*cs
)
10762 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10765 PPCVirtualHypervisorClass
*vhc
=
10766 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu
->vhyp
);
10767 vhc
->cpu_exec_exit(cpu
->vhyp
, cpu
);
10772 static void ppc_cpu_instance_init(Object
*obj
)
10774 PowerPCCPU
*cpu
= POWERPC_CPU(obj
);
10775 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10776 CPUPPCState
*env
= &cpu
->env
;
10778 cpu_set_cpustate_pointers(cpu
);
10779 cpu
->vcpu_id
= UNASSIGNED_CPU_INDEX
;
10781 env
->msr_mask
= pcc
->msr_mask
;
10782 env
->mmu_model
= pcc
->mmu_model
;
10783 env
->excp_model
= pcc
->excp_model
;
10784 env
->bus_model
= pcc
->bus_model
;
10785 env
->insns_flags
= pcc
->insns_flags
;
10786 env
->insns_flags2
= pcc
->insns_flags2
;
10787 env
->flags
= pcc
->flags
;
10788 env
->bfd_mach
= pcc
->bfd_mach
;
10789 env
->check_pow
= pcc
->check_pow
;
10792 * Mark HV mode as supported if the CPU has an MSR_HV bit in the
10793 * msr_mask. The mask can later be cleared by PAPR mode but the hv
10794 * mode support will remain, thus enforcing that we cannot use
10795 * priv. instructions in guest in PAPR mode. For 970 we currently
10796 * simply don't set HV in msr_mask thus simulating an "Apple mode"
10797 * 970. If we ever want to support 970 HV mode, we'll have to add
10798 * a processor attribute of some sort.
10800 #if !defined(CONFIG_USER_ONLY)
10801 env
->has_hv_mode
= !!(env
->msr_mask
& MSR_HVB
);
10804 ppc_hash64_init(cpu
);
10807 static void ppc_cpu_instance_finalize(Object
*obj
)
10809 PowerPCCPU
*cpu
= POWERPC_CPU(obj
);
10811 ppc_hash64_finalize(cpu
);
10814 static bool ppc_pvr_match_default(PowerPCCPUClass
*pcc
, uint32_t pvr
)
10816 return pcc
->pvr
== pvr
;
10819 static gchar
*ppc_gdb_arch_name(CPUState
*cs
)
10821 #if defined(TARGET_PPC64)
10822 return g_strdup("powerpc:common64");
10824 return g_strdup("powerpc:common");
10828 static void ppc_disas_set_info(CPUState
*cs
, disassemble_info
*info
)
10830 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10831 CPUPPCState
*env
= &cpu
->env
;
10833 if ((env
->hflags
>> MSR_LE
) & 1) {
10834 info
->endian
= BFD_ENDIAN_LITTLE
;
10836 info
->mach
= env
->bfd_mach
;
10837 if (!env
->bfd_mach
) {
10838 #ifdef TARGET_PPC64
10839 info
->mach
= bfd_mach_ppc64
;
10841 info
->mach
= bfd_mach_ppc
;
10844 info
->disassembler_options
= (char *)"any";
10845 info
->print_insn
= print_insn_ppc
;
10847 info
->cap_arch
= CS_ARCH_PPC
;
10848 #ifdef TARGET_PPC64
10849 info
->cap_mode
= CS_MODE_64
;
10853 static Property ppc_cpu_properties
[] = {
10854 DEFINE_PROP_BOOL("pre-2.8-migration", PowerPCCPU
, pre_2_8_migration
, false),
10855 DEFINE_PROP_BOOL("pre-2.10-migration", PowerPCCPU
, pre_2_10_migration
,
10857 DEFINE_PROP_BOOL("pre-3.0-migration", PowerPCCPU
, pre_3_0_migration
,
10859 DEFINE_PROP_END_OF_LIST(),
10862 static void ppc_cpu_class_init(ObjectClass
*oc
, void *data
)
10864 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10865 CPUClass
*cc
= CPU_CLASS(oc
);
10866 DeviceClass
*dc
= DEVICE_CLASS(oc
);
10868 device_class_set_parent_realize(dc
, ppc_cpu_realize
,
10869 &pcc
->parent_realize
);
10870 device_class_set_parent_unrealize(dc
, ppc_cpu_unrealize
,
10871 &pcc
->parent_unrealize
);
10872 pcc
->pvr_match
= ppc_pvr_match_default
;
10873 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_always
;
10874 dc
->props
= ppc_cpu_properties
;
10876 pcc
->parent_reset
= cc
->reset
;
10877 cc
->reset
= ppc_cpu_reset
;
10879 cc
->class_by_name
= ppc_cpu_class_by_name
;
10880 pcc
->parent_parse_features
= cc
->parse_features
;
10881 cc
->parse_features
= ppc_cpu_parse_featurestr
;
10882 cc
->has_work
= ppc_cpu_has_work
;
10883 cc
->do_interrupt
= ppc_cpu_do_interrupt
;
10884 cc
->cpu_exec_interrupt
= ppc_cpu_exec_interrupt
;
10885 cc
->dump_state
= ppc_cpu_dump_state
;
10886 cc
->dump_statistics
= ppc_cpu_dump_statistics
;
10887 cc
->set_pc
= ppc_cpu_set_pc
;
10888 cc
->gdb_read_register
= ppc_cpu_gdb_read_register
;
10889 cc
->gdb_write_register
= ppc_cpu_gdb_write_register
;
10890 cc
->do_unaligned_access
= ppc_cpu_do_unaligned_access
;
10891 #ifndef CONFIG_USER_ONLY
10892 cc
->get_phys_page_debug
= ppc_cpu_get_phys_page_debug
;
10893 cc
->vmsd
= &vmstate_ppc_cpu
;
10895 #if defined(CONFIG_SOFTMMU)
10896 cc
->write_elf64_note
= ppc64_cpu_write_elf64_note
;
10897 cc
->write_elf32_note
= ppc32_cpu_write_elf32_note
;
10900 cc
->gdb_num_core_regs
= 71;
10901 #ifndef CONFIG_USER_ONLY
10902 cc
->gdb_get_dynamic_xml
= ppc_gdb_get_dynamic_xml
;
10904 #ifdef USE_APPLE_GDB
10905 cc
->gdb_read_register
= ppc_cpu_gdb_read_register_apple
;
10906 cc
->gdb_write_register
= ppc_cpu_gdb_write_register_apple
;
10907 cc
->gdb_num_core_regs
= 71 + 32;
10910 cc
->gdb_arch_name
= ppc_gdb_arch_name
;
10911 #if defined(TARGET_PPC64)
10912 cc
->gdb_core_xml_file
= "power64-core.xml";
10914 cc
->gdb_core_xml_file
= "power-core.xml";
10916 #ifndef CONFIG_USER_ONLY
10917 cc
->virtio_is_big_endian
= ppc_cpu_is_big_endian
;
10920 cc
->tcg_initialize
= ppc_translate_init
;
10921 cc
->tlb_fill
= ppc_cpu_tlb_fill
;
10923 #ifndef CONFIG_USER_ONLY
10924 cc
->cpu_exec_enter
= ppc_cpu_exec_enter
;
10925 cc
->cpu_exec_exit
= ppc_cpu_exec_exit
;
10928 cc
->disas_set_info
= ppc_disas_set_info
;
10930 dc
->fw_name
= "PowerPC,UNKNOWN";
10933 static const TypeInfo ppc_cpu_type_info
= {
10934 .name
= TYPE_POWERPC_CPU
,
10935 .parent
= TYPE_CPU
,
10936 .instance_size
= sizeof(PowerPCCPU
),
10937 .instance_init
= ppc_cpu_instance_init
,
10938 .instance_finalize
= ppc_cpu_instance_finalize
,
10940 .class_size
= sizeof(PowerPCCPUClass
),
10941 .class_init
= ppc_cpu_class_init
,
10944 static const TypeInfo ppc_vhyp_type_info
= {
10945 .name
= TYPE_PPC_VIRTUAL_HYPERVISOR
,
10946 .parent
= TYPE_INTERFACE
,
10947 .class_size
= sizeof(PPCVirtualHypervisorClass
),
10950 static void ppc_cpu_register_types(void)
10952 type_register_static(&ppc_cpu_type_info
);
10953 type_register_static(&ppc_vhyp_type_info
);
10956 type_init(ppc_cpu_register_types
)