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
]);
469 static void spr_read_dpdes(DisasContext
*ctx
, int gprn
, int sprn
)
471 gen_helper_load_dpdes(cpu_gpr
[gprn
], cpu_env
);
474 static void spr_write_dpdes(DisasContext
*ctx
, int sprn
, int gprn
)
476 gen_helper_store_dpdes(cpu_env
, cpu_gpr
[gprn
]);
481 /* PowerPC 601 specific registers */
483 static void spr_read_601_rtcl(DisasContext
*ctx
, int gprn
, int sprn
)
485 gen_helper_load_601_rtcl(cpu_gpr
[gprn
], cpu_env
);
488 static void spr_read_601_rtcu(DisasContext
*ctx
, int gprn
, int sprn
)
490 gen_helper_load_601_rtcu(cpu_gpr
[gprn
], cpu_env
);
493 #if !defined(CONFIG_USER_ONLY)
494 static void spr_write_601_rtcu(DisasContext
*ctx
, int sprn
, int gprn
)
496 gen_helper_store_601_rtcu(cpu_env
, cpu_gpr
[gprn
]);
499 static void spr_write_601_rtcl(DisasContext
*ctx
, int sprn
, int gprn
)
501 gen_helper_store_601_rtcl(cpu_env
, cpu_gpr
[gprn
]);
504 static void spr_write_hid0_601(DisasContext
*ctx
, int sprn
, int gprn
)
506 gen_helper_store_hid0_601(cpu_env
, cpu_gpr
[gprn
]);
507 /* Must stop the translation as endianness may have changed */
508 gen_stop_exception(ctx
);
513 #if !defined(CONFIG_USER_ONLY)
514 static void spr_read_601_ubat(DisasContext
*ctx
, int gprn
, int sprn
)
516 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
,
517 offsetof(CPUPPCState
,
518 IBAT
[sprn
& 1][(sprn
- SPR_IBAT0U
) / 2]));
521 static void spr_write_601_ubatu(DisasContext
*ctx
, int sprn
, int gprn
)
523 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0U
) / 2);
524 gen_helper_store_601_batl(cpu_env
, t0
, cpu_gpr
[gprn
]);
525 tcg_temp_free_i32(t0
);
528 static void spr_write_601_ubatl(DisasContext
*ctx
, int sprn
, int gprn
)
530 TCGv_i32 t0
= tcg_const_i32((sprn
- SPR_IBAT0U
) / 2);
531 gen_helper_store_601_batu(cpu_env
, t0
, cpu_gpr
[gprn
]);
532 tcg_temp_free_i32(t0
);
536 /* PowerPC 40x specific registers */
537 #if !defined(CONFIG_USER_ONLY)
538 static void spr_read_40x_pit(DisasContext
*ctx
, int gprn
, int sprn
)
540 gen_helper_load_40x_pit(cpu_gpr
[gprn
], cpu_env
);
543 static void spr_write_40x_pit(DisasContext
*ctx
, int sprn
, int gprn
)
545 gen_helper_store_40x_pit(cpu_env
, cpu_gpr
[gprn
]);
548 static void spr_write_40x_dbcr0(DisasContext
*ctx
, int sprn
, int gprn
)
550 gen_store_spr(sprn
, cpu_gpr
[gprn
]);
551 gen_helper_store_40x_dbcr0(cpu_env
, cpu_gpr
[gprn
]);
552 /* We must stop translation as we may have rebooted */
553 gen_stop_exception(ctx
);
556 static void spr_write_40x_sler(DisasContext
*ctx
, int sprn
, int gprn
)
558 gen_helper_store_40x_sler(cpu_env
, cpu_gpr
[gprn
]);
561 static void spr_write_booke_tcr(DisasContext
*ctx
, int sprn
, int gprn
)
563 gen_helper_store_booke_tcr(cpu_env
, cpu_gpr
[gprn
]);
566 static void spr_write_booke_tsr(DisasContext
*ctx
, int sprn
, int gprn
)
568 gen_helper_store_booke_tsr(cpu_env
, cpu_gpr
[gprn
]);
572 /* PowerPC 403 specific registers */
573 /* PBL1 / PBU1 / PBL2 / PBU2 */
574 #if !defined(CONFIG_USER_ONLY)
575 static void spr_read_403_pbr(DisasContext
*ctx
, int gprn
, int sprn
)
577 tcg_gen_ld_tl(cpu_gpr
[gprn
], cpu_env
,
578 offsetof(CPUPPCState
, pb
[sprn
- SPR_403_PBL1
]));
581 static void spr_write_403_pbr(DisasContext
*ctx
, int sprn
, int gprn
)
583 TCGv_i32 t0
= tcg_const_i32(sprn
- SPR_403_PBL1
);
584 gen_helper_store_403_pbr(cpu_env
, t0
, cpu_gpr
[gprn
]);
585 tcg_temp_free_i32(t0
);
588 static void spr_write_pir(DisasContext
*ctx
, int sprn
, int gprn
)
590 TCGv t0
= tcg_temp_new();
591 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], 0xF);
592 gen_store_spr(SPR_PIR
, t0
);
597 /* SPE specific registers */
598 static void spr_read_spefscr(DisasContext
*ctx
, int gprn
, int sprn
)
600 TCGv_i32 t0
= tcg_temp_new_i32();
601 tcg_gen_ld_i32(t0
, cpu_env
, offsetof(CPUPPCState
, spe_fscr
));
602 tcg_gen_extu_i32_tl(cpu_gpr
[gprn
], t0
);
603 tcg_temp_free_i32(t0
);
606 static void spr_write_spefscr(DisasContext
*ctx
, int sprn
, int gprn
)
608 TCGv_i32 t0
= tcg_temp_new_i32();
609 tcg_gen_trunc_tl_i32(t0
, cpu_gpr
[gprn
]);
610 tcg_gen_st_i32(t0
, cpu_env
, offsetof(CPUPPCState
, spe_fscr
));
611 tcg_temp_free_i32(t0
);
614 #if !defined(CONFIG_USER_ONLY)
615 /* Callback used to write the exception vector base */
616 static void spr_write_excp_prefix(DisasContext
*ctx
, int sprn
, int gprn
)
618 TCGv t0
= tcg_temp_new();
619 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUPPCState
, ivpr_mask
));
620 tcg_gen_and_tl(t0
, t0
, cpu_gpr
[gprn
]);
621 tcg_gen_st_tl(t0
, cpu_env
, offsetof(CPUPPCState
, excp_prefix
));
622 gen_store_spr(sprn
, t0
);
626 static void spr_write_excp_vector(DisasContext
*ctx
, int sprn
, int gprn
)
630 if (sprn
>= SPR_BOOKE_IVOR0
&& sprn
<= SPR_BOOKE_IVOR15
) {
631 sprn_offs
= sprn
- SPR_BOOKE_IVOR0
;
632 } else if (sprn
>= SPR_BOOKE_IVOR32
&& sprn
<= SPR_BOOKE_IVOR37
) {
633 sprn_offs
= sprn
- SPR_BOOKE_IVOR32
+ 32;
634 } else if (sprn
>= SPR_BOOKE_IVOR38
&& sprn
<= SPR_BOOKE_IVOR42
) {
635 sprn_offs
= sprn
- SPR_BOOKE_IVOR38
+ 38;
637 printf("Trying to write an unknown exception vector %d %03x\n",
639 gen_inval_exception(ctx
, POWERPC_EXCP_PRIV_REG
);
643 TCGv t0
= tcg_temp_new();
644 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUPPCState
, ivor_mask
));
645 tcg_gen_and_tl(t0
, t0
, cpu_gpr
[gprn
]);
646 tcg_gen_st_tl(t0
, cpu_env
, offsetof(CPUPPCState
, excp_vectors
[sprn_offs
]));
647 gen_store_spr(sprn
, t0
);
652 static inline void vscr_init(CPUPPCState
*env
, uint32_t val
)
654 /* Altivec always uses round-to-nearest */
655 set_float_rounding_mode(float_round_nearest_even
, &env
->vec_status
);
656 helper_mtvscr(env
, val
);
659 #ifdef CONFIG_USER_ONLY
660 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
661 oea_read, oea_write, one_reg_id, initial_value) \
662 _spr_register(env, num, name, uea_read, uea_write, initial_value)
663 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
664 oea_read, oea_write, hea_read, hea_write, \
665 one_reg_id, initial_value) \
666 _spr_register(env, num, name, uea_read, uea_write, initial_value)
668 #if !defined(CONFIG_KVM)
669 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
670 oea_read, oea_write, one_reg_id, initial_value) \
671 _spr_register(env, num, name, uea_read, uea_write, \
672 oea_read, oea_write, oea_read, oea_write, 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, initial_value)
679 #define spr_register_kvm(env, num, name, uea_read, uea_write, \
680 oea_read, oea_write, one_reg_id, initial_value) \
681 _spr_register(env, num, name, uea_read, uea_write, \
682 oea_read, oea_write, oea_read, oea_write, \
683 one_reg_id, initial_value)
684 #define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
685 oea_read, oea_write, hea_read, hea_write, \
686 one_reg_id, initial_value) \
687 _spr_register(env, num, name, uea_read, uea_write, \
688 oea_read, oea_write, hea_read, hea_write, \
689 one_reg_id, initial_value)
693 #define spr_register(env, num, name, uea_read, uea_write, \
694 oea_read, oea_write, initial_value) \
695 spr_register_kvm(env, num, name, uea_read, uea_write, \
696 oea_read, oea_write, 0, initial_value)
698 #define spr_register_hv(env, num, name, uea_read, uea_write, \
699 oea_read, oea_write, hea_read, hea_write, \
701 spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
702 oea_read, oea_write, hea_read, hea_write, \
705 static inline void _spr_register(CPUPPCState
*env
, int num
,
707 void (*uea_read
)(DisasContext
*ctx
,
709 void (*uea_write
)(DisasContext
*ctx
,
711 #if !defined(CONFIG_USER_ONLY)
713 void (*oea_read
)(DisasContext
*ctx
,
715 void (*oea_write
)(DisasContext
*ctx
,
717 void (*hea_read
)(DisasContext
*opaque
,
719 void (*hea_write
)(DisasContext
*opaque
,
722 #if defined(CONFIG_KVM)
725 target_ulong initial_value
)
729 spr
= &env
->spr_cb
[num
];
730 if (spr
->name
!= NULL
|| env
->spr
[num
] != 0x00000000 ||
731 #if !defined(CONFIG_USER_ONLY)
732 spr
->oea_read
!= NULL
|| spr
->oea_write
!= NULL
||
734 spr
->uea_read
!= NULL
|| spr
->uea_write
!= NULL
) {
735 printf("Error: Trying to register SPR %d (%03x) twice !\n", num
, num
);
738 #if defined(PPC_DEBUG_SPR)
739 printf("*** register spr %d (%03x) %s val " TARGET_FMT_lx
"\n", num
, num
,
740 name
, initial_value
);
743 spr
->uea_read
= uea_read
;
744 spr
->uea_write
= uea_write
;
745 #if !defined(CONFIG_USER_ONLY)
746 spr
->oea_read
= oea_read
;
747 spr
->oea_write
= oea_write
;
748 spr
->hea_read
= hea_read
;
749 spr
->hea_write
= hea_write
;
751 #if defined(CONFIG_KVM)
752 spr
->one_reg_id
= one_reg_id
,
754 env
->spr
[num
] = spr
->default_value
= initial_value
;
757 /* Generic PowerPC SPRs */
758 static void gen_spr_generic(CPUPPCState
*env
)
760 /* Integer processing */
761 spr_register(env
, SPR_XER
, "XER",
762 &spr_read_xer
, &spr_write_xer
,
763 &spr_read_xer
, &spr_write_xer
,
766 spr_register(env
, SPR_LR
, "LR",
767 &spr_read_lr
, &spr_write_lr
,
768 &spr_read_lr
, &spr_write_lr
,
770 spr_register(env
, SPR_CTR
, "CTR",
771 &spr_read_ctr
, &spr_write_ctr
,
772 &spr_read_ctr
, &spr_write_ctr
,
774 /* Interrupt processing */
775 spr_register(env
, SPR_SRR0
, "SRR0",
776 SPR_NOACCESS
, SPR_NOACCESS
,
777 &spr_read_generic
, &spr_write_generic
,
779 spr_register(env
, SPR_SRR1
, "SRR1",
780 SPR_NOACCESS
, SPR_NOACCESS
,
781 &spr_read_generic
, &spr_write_generic
,
783 /* Processor control */
784 spr_register(env
, SPR_SPRG0
, "SPRG0",
785 SPR_NOACCESS
, SPR_NOACCESS
,
786 &spr_read_generic
, &spr_write_generic
,
788 spr_register(env
, SPR_SPRG1
, "SPRG1",
789 SPR_NOACCESS
, SPR_NOACCESS
,
790 &spr_read_generic
, &spr_write_generic
,
792 spr_register(env
, SPR_SPRG2
, "SPRG2",
793 SPR_NOACCESS
, SPR_NOACCESS
,
794 &spr_read_generic
, &spr_write_generic
,
796 spr_register(env
, SPR_SPRG3
, "SPRG3",
797 SPR_NOACCESS
, SPR_NOACCESS
,
798 &spr_read_generic
, &spr_write_generic
,
802 /* SPR common to all non-embedded PowerPC, including 601 */
803 static void gen_spr_ne_601(CPUPPCState
*env
)
805 /* Exception processing */
806 spr_register_kvm(env
, SPR_DSISR
, "DSISR",
807 SPR_NOACCESS
, SPR_NOACCESS
,
808 &spr_read_generic
, &spr_write_generic
,
809 KVM_REG_PPC_DSISR
, 0x00000000);
810 spr_register_kvm(env
, SPR_DAR
, "DAR",
811 SPR_NOACCESS
, SPR_NOACCESS
,
812 &spr_read_generic
, &spr_write_generic
,
813 KVM_REG_PPC_DAR
, 0x00000000);
815 spr_register(env
, SPR_DECR
, "DECR",
816 SPR_NOACCESS
, SPR_NOACCESS
,
817 &spr_read_decr
, &spr_write_decr
,
821 /* Storage Description Register 1 */
822 static void gen_spr_sdr1(CPUPPCState
*env
)
824 #ifndef CONFIG_USER_ONLY
825 if (env
->has_hv_mode
) {
827 * SDR1 is a hypervisor resource on CPUs which have a
830 spr_register_hv(env
, SPR_SDR1
, "SDR1",
831 SPR_NOACCESS
, SPR_NOACCESS
,
832 SPR_NOACCESS
, SPR_NOACCESS
,
833 &spr_read_generic
, &spr_write_sdr1
,
836 spr_register(env
, SPR_SDR1
, "SDR1",
837 SPR_NOACCESS
, SPR_NOACCESS
,
838 &spr_read_generic
, &spr_write_sdr1
,
845 static void gen_low_BATs(CPUPPCState
*env
)
847 #if !defined(CONFIG_USER_ONLY)
848 spr_register(env
, SPR_IBAT0U
, "IBAT0U",
849 SPR_NOACCESS
, SPR_NOACCESS
,
850 &spr_read_ibat
, &spr_write_ibatu
,
852 spr_register(env
, SPR_IBAT0L
, "IBAT0L",
853 SPR_NOACCESS
, SPR_NOACCESS
,
854 &spr_read_ibat
, &spr_write_ibatl
,
856 spr_register(env
, SPR_IBAT1U
, "IBAT1U",
857 SPR_NOACCESS
, SPR_NOACCESS
,
858 &spr_read_ibat
, &spr_write_ibatu
,
860 spr_register(env
, SPR_IBAT1L
, "IBAT1L",
861 SPR_NOACCESS
, SPR_NOACCESS
,
862 &spr_read_ibat
, &spr_write_ibatl
,
864 spr_register(env
, SPR_IBAT2U
, "IBAT2U",
865 SPR_NOACCESS
, SPR_NOACCESS
,
866 &spr_read_ibat
, &spr_write_ibatu
,
868 spr_register(env
, SPR_IBAT2L
, "IBAT2L",
869 SPR_NOACCESS
, SPR_NOACCESS
,
870 &spr_read_ibat
, &spr_write_ibatl
,
872 spr_register(env
, SPR_IBAT3U
, "IBAT3U",
873 SPR_NOACCESS
, SPR_NOACCESS
,
874 &spr_read_ibat
, &spr_write_ibatu
,
876 spr_register(env
, SPR_IBAT3L
, "IBAT3L",
877 SPR_NOACCESS
, SPR_NOACCESS
,
878 &spr_read_ibat
, &spr_write_ibatl
,
880 spr_register(env
, SPR_DBAT0U
, "DBAT0U",
881 SPR_NOACCESS
, SPR_NOACCESS
,
882 &spr_read_dbat
, &spr_write_dbatu
,
884 spr_register(env
, SPR_DBAT0L
, "DBAT0L",
885 SPR_NOACCESS
, SPR_NOACCESS
,
886 &spr_read_dbat
, &spr_write_dbatl
,
888 spr_register(env
, SPR_DBAT1U
, "DBAT1U",
889 SPR_NOACCESS
, SPR_NOACCESS
,
890 &spr_read_dbat
, &spr_write_dbatu
,
892 spr_register(env
, SPR_DBAT1L
, "DBAT1L",
893 SPR_NOACCESS
, SPR_NOACCESS
,
894 &spr_read_dbat
, &spr_write_dbatl
,
896 spr_register(env
, SPR_DBAT2U
, "DBAT2U",
897 SPR_NOACCESS
, SPR_NOACCESS
,
898 &spr_read_dbat
, &spr_write_dbatu
,
900 spr_register(env
, SPR_DBAT2L
, "DBAT2L",
901 SPR_NOACCESS
, SPR_NOACCESS
,
902 &spr_read_dbat
, &spr_write_dbatl
,
904 spr_register(env
, SPR_DBAT3U
, "DBAT3U",
905 SPR_NOACCESS
, SPR_NOACCESS
,
906 &spr_read_dbat
, &spr_write_dbatu
,
908 spr_register(env
, SPR_DBAT3L
, "DBAT3L",
909 SPR_NOACCESS
, SPR_NOACCESS
,
910 &spr_read_dbat
, &spr_write_dbatl
,
917 static void gen_high_BATs(CPUPPCState
*env
)
919 #if !defined(CONFIG_USER_ONLY)
920 spr_register(env
, SPR_IBAT4U
, "IBAT4U",
921 SPR_NOACCESS
, SPR_NOACCESS
,
922 &spr_read_ibat_h
, &spr_write_ibatu_h
,
924 spr_register(env
, SPR_IBAT4L
, "IBAT4L",
925 SPR_NOACCESS
, SPR_NOACCESS
,
926 &spr_read_ibat_h
, &spr_write_ibatl_h
,
928 spr_register(env
, SPR_IBAT5U
, "IBAT5U",
929 SPR_NOACCESS
, SPR_NOACCESS
,
930 &spr_read_ibat_h
, &spr_write_ibatu_h
,
932 spr_register(env
, SPR_IBAT5L
, "IBAT5L",
933 SPR_NOACCESS
, SPR_NOACCESS
,
934 &spr_read_ibat_h
, &spr_write_ibatl_h
,
936 spr_register(env
, SPR_IBAT6U
, "IBAT6U",
937 SPR_NOACCESS
, SPR_NOACCESS
,
938 &spr_read_ibat_h
, &spr_write_ibatu_h
,
940 spr_register(env
, SPR_IBAT6L
, "IBAT6L",
941 SPR_NOACCESS
, SPR_NOACCESS
,
942 &spr_read_ibat_h
, &spr_write_ibatl_h
,
944 spr_register(env
, SPR_IBAT7U
, "IBAT7U",
945 SPR_NOACCESS
, SPR_NOACCESS
,
946 &spr_read_ibat_h
, &spr_write_ibatu_h
,
948 spr_register(env
, SPR_IBAT7L
, "IBAT7L",
949 SPR_NOACCESS
, SPR_NOACCESS
,
950 &spr_read_ibat_h
, &spr_write_ibatl_h
,
952 spr_register(env
, SPR_DBAT4U
, "DBAT4U",
953 SPR_NOACCESS
, SPR_NOACCESS
,
954 &spr_read_dbat_h
, &spr_write_dbatu_h
,
956 spr_register(env
, SPR_DBAT4L
, "DBAT4L",
957 SPR_NOACCESS
, SPR_NOACCESS
,
958 &spr_read_dbat_h
, &spr_write_dbatl_h
,
960 spr_register(env
, SPR_DBAT5U
, "DBAT5U",
961 SPR_NOACCESS
, SPR_NOACCESS
,
962 &spr_read_dbat_h
, &spr_write_dbatu_h
,
964 spr_register(env
, SPR_DBAT5L
, "DBAT5L",
965 SPR_NOACCESS
, SPR_NOACCESS
,
966 &spr_read_dbat_h
, &spr_write_dbatl_h
,
968 spr_register(env
, SPR_DBAT6U
, "DBAT6U",
969 SPR_NOACCESS
, SPR_NOACCESS
,
970 &spr_read_dbat_h
, &spr_write_dbatu_h
,
972 spr_register(env
, SPR_DBAT6L
, "DBAT6L",
973 SPR_NOACCESS
, SPR_NOACCESS
,
974 &spr_read_dbat_h
, &spr_write_dbatl_h
,
976 spr_register(env
, SPR_DBAT7U
, "DBAT7U",
977 SPR_NOACCESS
, SPR_NOACCESS
,
978 &spr_read_dbat_h
, &spr_write_dbatu_h
,
980 spr_register(env
, SPR_DBAT7L
, "DBAT7L",
981 SPR_NOACCESS
, SPR_NOACCESS
,
982 &spr_read_dbat_h
, &spr_write_dbatl_h
,
988 /* Generic PowerPC time base */
989 static void gen_tbl(CPUPPCState
*env
)
991 spr_register(env
, SPR_VTBL
, "TBL",
992 &spr_read_tbl
, SPR_NOACCESS
,
993 &spr_read_tbl
, SPR_NOACCESS
,
995 spr_register(env
, SPR_TBL
, "TBL",
996 &spr_read_tbl
, SPR_NOACCESS
,
997 &spr_read_tbl
, &spr_write_tbl
,
999 spr_register(env
, SPR_VTBU
, "TBU",
1000 &spr_read_tbu
, SPR_NOACCESS
,
1001 &spr_read_tbu
, SPR_NOACCESS
,
1003 spr_register(env
, SPR_TBU
, "TBU",
1004 &spr_read_tbu
, SPR_NOACCESS
,
1005 &spr_read_tbu
, &spr_write_tbu
,
1009 /* Softare table search registers */
1010 static void gen_6xx_7xx_soft_tlb(CPUPPCState
*env
, int nb_tlbs
, int nb_ways
)
1012 #if !defined(CONFIG_USER_ONLY)
1013 env
->nb_tlb
= nb_tlbs
;
1014 env
->nb_ways
= nb_ways
;
1016 env
->tlb_type
= TLB_6XX
;
1017 spr_register(env
, SPR_DMISS
, "DMISS",
1018 SPR_NOACCESS
, SPR_NOACCESS
,
1019 &spr_read_generic
, SPR_NOACCESS
,
1021 spr_register(env
, SPR_DCMP
, "DCMP",
1022 SPR_NOACCESS
, SPR_NOACCESS
,
1023 &spr_read_generic
, SPR_NOACCESS
,
1025 spr_register(env
, SPR_HASH1
, "HASH1",
1026 SPR_NOACCESS
, SPR_NOACCESS
,
1027 &spr_read_generic
, SPR_NOACCESS
,
1029 spr_register(env
, SPR_HASH2
, "HASH2",
1030 SPR_NOACCESS
, SPR_NOACCESS
,
1031 &spr_read_generic
, SPR_NOACCESS
,
1033 spr_register(env
, SPR_IMISS
, "IMISS",
1034 SPR_NOACCESS
, SPR_NOACCESS
,
1035 &spr_read_generic
, SPR_NOACCESS
,
1037 spr_register(env
, SPR_ICMP
, "ICMP",
1038 SPR_NOACCESS
, SPR_NOACCESS
,
1039 &spr_read_generic
, SPR_NOACCESS
,
1041 spr_register(env
, SPR_RPA
, "RPA",
1042 SPR_NOACCESS
, SPR_NOACCESS
,
1043 &spr_read_generic
, &spr_write_generic
,
1048 /* SPR common to MPC755 and G2 */
1049 static void gen_spr_G2_755(CPUPPCState
*env
)
1052 spr_register(env
, SPR_SPRG4
, "SPRG4",
1053 SPR_NOACCESS
, SPR_NOACCESS
,
1054 &spr_read_generic
, &spr_write_generic
,
1056 spr_register(env
, SPR_SPRG5
, "SPRG5",
1057 SPR_NOACCESS
, SPR_NOACCESS
,
1058 &spr_read_generic
, &spr_write_generic
,
1060 spr_register(env
, SPR_SPRG6
, "SPRG6",
1061 SPR_NOACCESS
, SPR_NOACCESS
,
1062 &spr_read_generic
, &spr_write_generic
,
1064 spr_register(env
, SPR_SPRG7
, "SPRG7",
1065 SPR_NOACCESS
, SPR_NOACCESS
,
1066 &spr_read_generic
, &spr_write_generic
,
1070 /* SPR common to all 7xx PowerPC implementations */
1071 static void gen_spr_7xx(CPUPPCState
*env
)
1074 /* XXX : not implemented */
1075 spr_register_kvm(env
, SPR_DABR
, "DABR",
1076 SPR_NOACCESS
, SPR_NOACCESS
,
1077 &spr_read_generic
, &spr_write_generic
,
1078 KVM_REG_PPC_DABR
, 0x00000000);
1079 /* XXX : not implemented */
1080 spr_register(env
, SPR_IABR
, "IABR",
1081 SPR_NOACCESS
, SPR_NOACCESS
,
1082 &spr_read_generic
, &spr_write_generic
,
1084 /* Cache management */
1085 /* XXX : not implemented */
1086 spr_register(env
, SPR_ICTC
, "ICTC",
1087 SPR_NOACCESS
, SPR_NOACCESS
,
1088 &spr_read_generic
, &spr_write_generic
,
1090 /* Performance monitors */
1091 /* XXX : not implemented */
1092 spr_register(env
, SPR_7XX_MMCR0
, "MMCR0",
1093 SPR_NOACCESS
, SPR_NOACCESS
,
1094 &spr_read_generic
, &spr_write_generic
,
1096 /* XXX : not implemented */
1097 spr_register(env
, SPR_7XX_MMCR1
, "MMCR1",
1098 SPR_NOACCESS
, SPR_NOACCESS
,
1099 &spr_read_generic
, &spr_write_generic
,
1101 /* XXX : not implemented */
1102 spr_register(env
, SPR_7XX_PMC1
, "PMC1",
1103 SPR_NOACCESS
, SPR_NOACCESS
,
1104 &spr_read_generic
, &spr_write_generic
,
1106 /* XXX : not implemented */
1107 spr_register(env
, SPR_7XX_PMC2
, "PMC2",
1108 SPR_NOACCESS
, SPR_NOACCESS
,
1109 &spr_read_generic
, &spr_write_generic
,
1111 /* XXX : not implemented */
1112 spr_register(env
, SPR_7XX_PMC3
, "PMC3",
1113 SPR_NOACCESS
, SPR_NOACCESS
,
1114 &spr_read_generic
, &spr_write_generic
,
1116 /* XXX : not implemented */
1117 spr_register(env
, SPR_7XX_PMC4
, "PMC4",
1118 SPR_NOACCESS
, SPR_NOACCESS
,
1119 &spr_read_generic
, &spr_write_generic
,
1121 /* XXX : not implemented */
1122 spr_register(env
, SPR_7XX_SIAR
, "SIAR",
1123 SPR_NOACCESS
, SPR_NOACCESS
,
1124 &spr_read_generic
, SPR_NOACCESS
,
1126 /* XXX : not implemented */
1127 spr_register(env
, SPR_7XX_UMMCR0
, "UMMCR0",
1128 &spr_read_ureg
, SPR_NOACCESS
,
1129 &spr_read_ureg
, SPR_NOACCESS
,
1131 /* XXX : not implemented */
1132 spr_register(env
, SPR_7XX_UMMCR1
, "UMMCR1",
1133 &spr_read_ureg
, SPR_NOACCESS
,
1134 &spr_read_ureg
, SPR_NOACCESS
,
1136 /* XXX : not implemented */
1137 spr_register(env
, SPR_7XX_UPMC1
, "UPMC1",
1138 &spr_read_ureg
, SPR_NOACCESS
,
1139 &spr_read_ureg
, SPR_NOACCESS
,
1141 /* XXX : not implemented */
1142 spr_register(env
, SPR_7XX_UPMC2
, "UPMC2",
1143 &spr_read_ureg
, SPR_NOACCESS
,
1144 &spr_read_ureg
, SPR_NOACCESS
,
1146 /* XXX : not implemented */
1147 spr_register(env
, SPR_7XX_UPMC3
, "UPMC3",
1148 &spr_read_ureg
, SPR_NOACCESS
,
1149 &spr_read_ureg
, SPR_NOACCESS
,
1151 /* XXX : not implemented */
1152 spr_register(env
, SPR_7XX_UPMC4
, "UPMC4",
1153 &spr_read_ureg
, SPR_NOACCESS
,
1154 &spr_read_ureg
, SPR_NOACCESS
,
1156 /* XXX : not implemented */
1157 spr_register(env
, SPR_7XX_USIAR
, "USIAR",
1158 &spr_read_ureg
, SPR_NOACCESS
,
1159 &spr_read_ureg
, SPR_NOACCESS
,
1161 /* External access control */
1162 /* XXX : not implemented */
1163 spr_register(env
, SPR_EAR
, "EAR",
1164 SPR_NOACCESS
, SPR_NOACCESS
,
1165 &spr_read_generic
, &spr_write_generic
,
1170 #ifndef CONFIG_USER_ONLY
1171 static void spr_write_amr(DisasContext
*ctx
, int sprn
, int gprn
)
1173 TCGv t0
= tcg_temp_new();
1174 TCGv t1
= tcg_temp_new();
1175 TCGv t2
= tcg_temp_new();
1178 * Note, the HV=1 PR=0 case is handled earlier by simply using
1179 * spr_write_generic for HV mode in the SPR table
1182 /* Build insertion mask into t1 based on context */
1184 gen_load_spr(t1
, SPR_UAMOR
);
1186 gen_load_spr(t1
, SPR_AMOR
);
1189 /* Mask new bits into t2 */
1190 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1192 /* Load AMR and clear new bits in t0 */
1193 gen_load_spr(t0
, SPR_AMR
);
1194 tcg_gen_andc_tl(t0
, t0
, t1
);
1196 /* Or'in new bits and write it out */
1197 tcg_gen_or_tl(t0
, t0
, t2
);
1198 gen_store_spr(SPR_AMR
, t0
);
1199 spr_store_dump_spr(SPR_AMR
);
1206 static void spr_write_uamor(DisasContext
*ctx
, int sprn
, int gprn
)
1208 TCGv t0
= tcg_temp_new();
1209 TCGv t1
= tcg_temp_new();
1210 TCGv t2
= tcg_temp_new();
1213 * Note, the HV=1 case is handled earlier by simply using
1214 * spr_write_generic for HV mode in the SPR table
1217 /* Build insertion mask into t1 based on context */
1218 gen_load_spr(t1
, SPR_AMOR
);
1220 /* Mask new bits into t2 */
1221 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1223 /* Load AMR and clear new bits in t0 */
1224 gen_load_spr(t0
, SPR_UAMOR
);
1225 tcg_gen_andc_tl(t0
, t0
, t1
);
1227 /* Or'in new bits and write it out */
1228 tcg_gen_or_tl(t0
, t0
, t2
);
1229 gen_store_spr(SPR_UAMOR
, t0
);
1230 spr_store_dump_spr(SPR_UAMOR
);
1237 static void spr_write_iamr(DisasContext
*ctx
, int sprn
, int gprn
)
1239 TCGv t0
= tcg_temp_new();
1240 TCGv t1
= tcg_temp_new();
1241 TCGv t2
= tcg_temp_new();
1244 * Note, the HV=1 case is handled earlier by simply using
1245 * spr_write_generic for HV mode in the SPR table
1248 /* Build insertion mask into t1 based on context */
1249 gen_load_spr(t1
, SPR_AMOR
);
1251 /* Mask new bits into t2 */
1252 tcg_gen_and_tl(t2
, t1
, cpu_gpr
[gprn
]);
1254 /* Load AMR and clear new bits in t0 */
1255 gen_load_spr(t0
, SPR_IAMR
);
1256 tcg_gen_andc_tl(t0
, t0
, t1
);
1258 /* Or'in new bits and write it out */
1259 tcg_gen_or_tl(t0
, t0
, t2
);
1260 gen_store_spr(SPR_IAMR
, t0
);
1261 spr_store_dump_spr(SPR_IAMR
);
1267 #endif /* CONFIG_USER_ONLY */
1269 static void gen_spr_amr(CPUPPCState
*env
)
1271 #ifndef CONFIG_USER_ONLY
1273 * Virtual Page Class Key protection
1275 * The AMR is accessible either via SPR 13 or SPR 29. 13 is
1276 * userspace accessible, 29 is privileged. So we only need to set
1277 * the kvm ONE_REG id on one of them, we use 29
1279 spr_register(env
, SPR_UAMR
, "UAMR",
1280 &spr_read_generic
, &spr_write_amr
,
1281 &spr_read_generic
, &spr_write_amr
,
1283 spr_register_kvm_hv(env
, SPR_AMR
, "AMR",
1284 SPR_NOACCESS
, SPR_NOACCESS
,
1285 &spr_read_generic
, &spr_write_amr
,
1286 &spr_read_generic
, &spr_write_generic
,
1287 KVM_REG_PPC_AMR
, 0);
1288 spr_register_kvm_hv(env
, SPR_UAMOR
, "UAMOR",
1289 SPR_NOACCESS
, SPR_NOACCESS
,
1290 &spr_read_generic
, &spr_write_uamor
,
1291 &spr_read_generic
, &spr_write_generic
,
1292 KVM_REG_PPC_UAMOR
, 0);
1293 spr_register_hv(env
, SPR_AMOR
, "AMOR",
1294 SPR_NOACCESS
, SPR_NOACCESS
,
1295 SPR_NOACCESS
, SPR_NOACCESS
,
1296 &spr_read_generic
, &spr_write_generic
,
1298 #endif /* !CONFIG_USER_ONLY */
1301 static void gen_spr_iamr(CPUPPCState
*env
)
1303 #ifndef CONFIG_USER_ONLY
1304 spr_register_kvm_hv(env
, SPR_IAMR
, "IAMR",
1305 SPR_NOACCESS
, SPR_NOACCESS
,
1306 &spr_read_generic
, &spr_write_iamr
,
1307 &spr_read_generic
, &spr_write_generic
,
1308 KVM_REG_PPC_IAMR
, 0);
1309 #endif /* !CONFIG_USER_ONLY */
1311 #endif /* TARGET_PPC64 */
1313 #ifndef CONFIG_USER_ONLY
1314 static void spr_read_thrm(DisasContext
*ctx
, int gprn
, int sprn
)
1316 gen_helper_fixup_thrm(cpu_env
);
1317 gen_load_spr(cpu_gpr
[gprn
], sprn
);
1318 spr_load_dump_spr(sprn
);
1320 #endif /* !CONFIG_USER_ONLY */
1322 static void gen_spr_thrm(CPUPPCState
*env
)
1324 /* Thermal management */
1325 /* XXX : not implemented */
1326 spr_register(env
, SPR_THRM1
, "THRM1",
1327 SPR_NOACCESS
, SPR_NOACCESS
,
1328 &spr_read_thrm
, &spr_write_generic
,
1330 /* XXX : not implemented */
1331 spr_register(env
, SPR_THRM2
, "THRM2",
1332 SPR_NOACCESS
, SPR_NOACCESS
,
1333 &spr_read_thrm
, &spr_write_generic
,
1335 /* XXX : not implemented */
1336 spr_register(env
, SPR_THRM3
, "THRM3",
1337 SPR_NOACCESS
, SPR_NOACCESS
,
1338 &spr_read_thrm
, &spr_write_generic
,
1342 /* SPR specific to PowerPC 604 implementation */
1343 static void gen_spr_604(CPUPPCState
*env
)
1345 /* Processor identification */
1346 spr_register(env
, SPR_PIR
, "PIR",
1347 SPR_NOACCESS
, SPR_NOACCESS
,
1348 &spr_read_generic
, &spr_write_pir
,
1351 /* XXX : not implemented */
1352 spr_register(env
, SPR_IABR
, "IABR",
1353 SPR_NOACCESS
, SPR_NOACCESS
,
1354 &spr_read_generic
, &spr_write_generic
,
1356 /* XXX : not implemented */
1357 spr_register_kvm(env
, SPR_DABR
, "DABR",
1358 SPR_NOACCESS
, SPR_NOACCESS
,
1359 &spr_read_generic
, &spr_write_generic
,
1360 KVM_REG_PPC_DABR
, 0x00000000);
1361 /* Performance counters */
1362 /* XXX : not implemented */
1363 spr_register(env
, SPR_7XX_MMCR0
, "MMCR0",
1364 SPR_NOACCESS
, SPR_NOACCESS
,
1365 &spr_read_generic
, &spr_write_generic
,
1367 /* XXX : not implemented */
1368 spr_register(env
, SPR_7XX_PMC1
, "PMC1",
1369 SPR_NOACCESS
, SPR_NOACCESS
,
1370 &spr_read_generic
, &spr_write_generic
,
1372 /* XXX : not implemented */
1373 spr_register(env
, SPR_7XX_PMC2
, "PMC2",
1374 SPR_NOACCESS
, SPR_NOACCESS
,
1375 &spr_read_generic
, &spr_write_generic
,
1377 /* XXX : not implemented */
1378 spr_register(env
, SPR_7XX_SIAR
, "SIAR",
1379 SPR_NOACCESS
, SPR_NOACCESS
,
1380 &spr_read_generic
, SPR_NOACCESS
,
1382 /* XXX : not implemented */
1383 spr_register(env
, SPR_SDA
, "SDA",
1384 SPR_NOACCESS
, SPR_NOACCESS
,
1385 &spr_read_generic
, SPR_NOACCESS
,
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
,
1395 /* SPR specific to PowerPC 603 implementation */
1396 static void gen_spr_603(CPUPPCState
*env
)
1398 /* External access control */
1399 /* XXX : not implemented */
1400 spr_register(env
, SPR_EAR
, "EAR",
1401 SPR_NOACCESS
, SPR_NOACCESS
,
1402 &spr_read_generic
, &spr_write_generic
,
1405 /* XXX : not implemented */
1406 spr_register(env
, SPR_IABR
, "IABR",
1407 SPR_NOACCESS
, SPR_NOACCESS
,
1408 &spr_read_generic
, &spr_write_generic
,
1413 /* SPR specific to PowerPC G2 implementation */
1414 static void gen_spr_G2(CPUPPCState
*env
)
1416 /* Memory base address */
1418 /* XXX : not implemented */
1419 spr_register(env
, SPR_MBAR
, "MBAR",
1420 SPR_NOACCESS
, SPR_NOACCESS
,
1421 &spr_read_generic
, &spr_write_generic
,
1423 /* Exception processing */
1424 spr_register(env
, SPR_BOOKE_CSRR0
, "CSRR0",
1425 SPR_NOACCESS
, SPR_NOACCESS
,
1426 &spr_read_generic
, &spr_write_generic
,
1428 spr_register(env
, SPR_BOOKE_CSRR1
, "CSRR1",
1429 SPR_NOACCESS
, SPR_NOACCESS
,
1430 &spr_read_generic
, &spr_write_generic
,
1433 /* XXX : not implemented */
1434 spr_register(env
, SPR_DABR
, "DABR",
1435 SPR_NOACCESS
, SPR_NOACCESS
,
1436 &spr_read_generic
, &spr_write_generic
,
1438 /* XXX : not implemented */
1439 spr_register(env
, SPR_DABR2
, "DABR2",
1440 SPR_NOACCESS
, SPR_NOACCESS
,
1441 &spr_read_generic
, &spr_write_generic
,
1443 /* XXX : not implemented */
1444 spr_register(env
, SPR_IABR
, "IABR",
1445 SPR_NOACCESS
, SPR_NOACCESS
,
1446 &spr_read_generic
, &spr_write_generic
,
1448 /* XXX : not implemented */
1449 spr_register(env
, SPR_IABR2
, "IABR2",
1450 SPR_NOACCESS
, SPR_NOACCESS
,
1451 &spr_read_generic
, &spr_write_generic
,
1453 /* XXX : not implemented */
1454 spr_register(env
, SPR_IBCR
, "IBCR",
1455 SPR_NOACCESS
, SPR_NOACCESS
,
1456 &spr_read_generic
, &spr_write_generic
,
1458 /* XXX : not implemented */
1459 spr_register(env
, SPR_DBCR
, "DBCR",
1460 SPR_NOACCESS
, SPR_NOACCESS
,
1461 &spr_read_generic
, &spr_write_generic
,
1465 /* SPR specific to PowerPC 602 implementation */
1466 static void gen_spr_602(CPUPPCState
*env
)
1469 /* XXX : not implemented */
1470 spr_register(env
, SPR_SER
, "SER",
1471 SPR_NOACCESS
, SPR_NOACCESS
,
1472 &spr_read_generic
, &spr_write_generic
,
1474 /* XXX : not implemented */
1475 spr_register(env
, SPR_SEBR
, "SEBR",
1476 SPR_NOACCESS
, SPR_NOACCESS
,
1477 &spr_read_generic
, &spr_write_generic
,
1479 /* XXX : not implemented */
1480 spr_register(env
, SPR_ESASRR
, "ESASRR",
1481 SPR_NOACCESS
, SPR_NOACCESS
,
1482 &spr_read_generic
, &spr_write_generic
,
1484 /* Floating point status */
1485 /* XXX : not implemented */
1486 spr_register(env
, SPR_SP
, "SP",
1487 SPR_NOACCESS
, SPR_NOACCESS
,
1488 &spr_read_generic
, &spr_write_generic
,
1490 /* XXX : not implemented */
1491 spr_register(env
, SPR_LT
, "LT",
1492 SPR_NOACCESS
, SPR_NOACCESS
,
1493 &spr_read_generic
, &spr_write_generic
,
1495 /* Watchdog timer */
1496 /* XXX : not implemented */
1497 spr_register(env
, SPR_TCR
, "TCR",
1498 SPR_NOACCESS
, SPR_NOACCESS
,
1499 &spr_read_generic
, &spr_write_generic
,
1501 /* Interrupt base */
1502 spr_register(env
, SPR_IBR
, "IBR",
1503 SPR_NOACCESS
, SPR_NOACCESS
,
1504 &spr_read_generic
, &spr_write_generic
,
1506 /* XXX : not implemented */
1507 spr_register(env
, SPR_IABR
, "IABR",
1508 SPR_NOACCESS
, SPR_NOACCESS
,
1509 &spr_read_generic
, &spr_write_generic
,
1513 /* SPR specific to PowerPC 601 implementation */
1514 static void gen_spr_601(CPUPPCState
*env
)
1516 /* Multiplication/division register */
1518 spr_register(env
, SPR_MQ
, "MQ",
1519 &spr_read_generic
, &spr_write_generic
,
1520 &spr_read_generic
, &spr_write_generic
,
1523 spr_register(env
, SPR_601_RTCU
, "RTCU",
1524 SPR_NOACCESS
, SPR_NOACCESS
,
1525 SPR_NOACCESS
, &spr_write_601_rtcu
,
1527 spr_register(env
, SPR_601_VRTCU
, "RTCU",
1528 &spr_read_601_rtcu
, SPR_NOACCESS
,
1529 &spr_read_601_rtcu
, SPR_NOACCESS
,
1531 spr_register(env
, SPR_601_RTCL
, "RTCL",
1532 SPR_NOACCESS
, SPR_NOACCESS
,
1533 SPR_NOACCESS
, &spr_write_601_rtcl
,
1535 spr_register(env
, SPR_601_VRTCL
, "RTCL",
1536 &spr_read_601_rtcl
, SPR_NOACCESS
,
1537 &spr_read_601_rtcl
, SPR_NOACCESS
,
1541 spr_register(env
, SPR_601_UDECR
, "UDECR",
1542 &spr_read_decr
, SPR_NOACCESS
,
1543 &spr_read_decr
, SPR_NOACCESS
,
1546 /* External access control */
1547 /* XXX : not implemented */
1548 spr_register(env
, SPR_EAR
, "EAR",
1549 SPR_NOACCESS
, SPR_NOACCESS
,
1550 &spr_read_generic
, &spr_write_generic
,
1552 /* Memory management */
1553 #if !defined(CONFIG_USER_ONLY)
1554 spr_register(env
, SPR_IBAT0U
, "IBAT0U",
1555 SPR_NOACCESS
, SPR_NOACCESS
,
1556 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1558 spr_register(env
, SPR_IBAT0L
, "IBAT0L",
1559 SPR_NOACCESS
, SPR_NOACCESS
,
1560 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1562 spr_register(env
, SPR_IBAT1U
, "IBAT1U",
1563 SPR_NOACCESS
, SPR_NOACCESS
,
1564 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1566 spr_register(env
, SPR_IBAT1L
, "IBAT1L",
1567 SPR_NOACCESS
, SPR_NOACCESS
,
1568 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1570 spr_register(env
, SPR_IBAT2U
, "IBAT2U",
1571 SPR_NOACCESS
, SPR_NOACCESS
,
1572 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1574 spr_register(env
, SPR_IBAT2L
, "IBAT2L",
1575 SPR_NOACCESS
, SPR_NOACCESS
,
1576 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1578 spr_register(env
, SPR_IBAT3U
, "IBAT3U",
1579 SPR_NOACCESS
, SPR_NOACCESS
,
1580 &spr_read_601_ubat
, &spr_write_601_ubatu
,
1582 spr_register(env
, SPR_IBAT3L
, "IBAT3L",
1583 SPR_NOACCESS
, SPR_NOACCESS
,
1584 &spr_read_601_ubat
, &spr_write_601_ubatl
,
1590 static void gen_spr_74xx(CPUPPCState
*env
)
1592 /* Processor identification */
1593 spr_register(env
, SPR_PIR
, "PIR",
1594 SPR_NOACCESS
, SPR_NOACCESS
,
1595 &spr_read_generic
, &spr_write_pir
,
1597 /* XXX : not implemented */
1598 spr_register(env
, SPR_74XX_MMCR2
, "MMCR2",
1599 SPR_NOACCESS
, SPR_NOACCESS
,
1600 &spr_read_generic
, &spr_write_generic
,
1602 /* XXX : not implemented */
1603 spr_register(env
, SPR_74XX_UMMCR2
, "UMMCR2",
1604 &spr_read_ureg
, SPR_NOACCESS
,
1605 &spr_read_ureg
, SPR_NOACCESS
,
1607 /* XXX: not implemented */
1608 spr_register(env
, SPR_BAMR
, "BAMR",
1609 SPR_NOACCESS
, SPR_NOACCESS
,
1610 &spr_read_generic
, &spr_write_generic
,
1612 /* XXX : not implemented */
1613 spr_register(env
, SPR_MSSCR0
, "MSSCR0",
1614 SPR_NOACCESS
, SPR_NOACCESS
,
1615 &spr_read_generic
, &spr_write_generic
,
1617 /* Hardware implementation registers */
1618 /* XXX : not implemented */
1619 spr_register(env
, SPR_HID0
, "HID0",
1620 SPR_NOACCESS
, SPR_NOACCESS
,
1621 &spr_read_generic
, &spr_write_generic
,
1623 /* XXX : not implemented */
1624 spr_register(env
, SPR_HID1
, "HID1",
1625 SPR_NOACCESS
, SPR_NOACCESS
,
1626 &spr_read_generic
, &spr_write_generic
,
1629 spr_register(env
, SPR_VRSAVE
, "VRSAVE",
1630 &spr_read_generic
, &spr_write_generic
,
1631 &spr_read_generic
, &spr_write_generic
,
1633 /* XXX : not implemented */
1634 spr_register(env
, SPR_L2CR
, "L2CR",
1635 SPR_NOACCESS
, SPR_NOACCESS
,
1636 &spr_read_generic
, spr_access_nop
,
1638 /* Not strictly an SPR */
1639 vscr_init(env
, 0x00010000);
1642 static void gen_l3_ctrl(CPUPPCState
*env
)
1645 /* XXX : not implemented */
1646 spr_register(env
, SPR_L3CR
, "L3CR",
1647 SPR_NOACCESS
, SPR_NOACCESS
,
1648 &spr_read_generic
, &spr_write_generic
,
1651 /* XXX : not implemented */
1652 spr_register(env
, SPR_L3ITCR0
, "L3ITCR0",
1653 SPR_NOACCESS
, SPR_NOACCESS
,
1654 &spr_read_generic
, &spr_write_generic
,
1657 /* XXX : not implemented */
1658 spr_register(env
, SPR_L3PM
, "L3PM",
1659 SPR_NOACCESS
, SPR_NOACCESS
,
1660 &spr_read_generic
, &spr_write_generic
,
1664 static void gen_74xx_soft_tlb(CPUPPCState
*env
, int nb_tlbs
, int nb_ways
)
1666 #if !defined(CONFIG_USER_ONLY)
1667 env
->nb_tlb
= nb_tlbs
;
1668 env
->nb_ways
= nb_ways
;
1670 env
->tlb_type
= TLB_6XX
;
1671 /* XXX : not implemented */
1672 spr_register(env
, SPR_PTEHI
, "PTEHI",
1673 SPR_NOACCESS
, SPR_NOACCESS
,
1674 &spr_read_generic
, &spr_write_generic
,
1676 /* XXX : not implemented */
1677 spr_register(env
, SPR_PTELO
, "PTELO",
1678 SPR_NOACCESS
, SPR_NOACCESS
,
1679 &spr_read_generic
, &spr_write_generic
,
1681 /* XXX : not implemented */
1682 spr_register(env
, SPR_TLBMISS
, "TLBMISS",
1683 SPR_NOACCESS
, SPR_NOACCESS
,
1684 &spr_read_generic
, &spr_write_generic
,
1689 #if !defined(CONFIG_USER_ONLY)
1690 static void spr_write_e500_l1csr0(DisasContext
*ctx
, int sprn
, int gprn
)
1692 TCGv t0
= tcg_temp_new();
1694 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], L1CSR0_DCE
| L1CSR0_CPE
);
1695 gen_store_spr(sprn
, t0
);
1699 static void spr_write_e500_l1csr1(DisasContext
*ctx
, int sprn
, int gprn
)
1701 TCGv t0
= tcg_temp_new();
1703 tcg_gen_andi_tl(t0
, cpu_gpr
[gprn
], L1CSR1_ICE
| L1CSR1_CPE
);
1704 gen_store_spr(sprn
, t0
);
1708 static void spr_write_booke206_mmucsr0(DisasContext
*ctx
, int sprn
, int gprn
)
1710 gen_helper_booke206_tlbflush(cpu_env
, cpu_gpr
[gprn
]);
1713 static void spr_write_booke_pid(DisasContext
*ctx
, int sprn
, int gprn
)
1715 TCGv_i32 t0
= tcg_const_i32(sprn
);
1716 gen_helper_booke_setpid(cpu_env
, t0
, cpu_gpr
[gprn
]);
1717 tcg_temp_free_i32(t0
);
1719 static void spr_write_eplc(DisasContext
*ctx
, int sprn
, int gprn
)
1721 gen_helper_booke_set_eplc(cpu_env
, cpu_gpr
[gprn
]);
1723 static void spr_write_epsc(DisasContext
*ctx
, int sprn
, int gprn
)
1725 gen_helper_booke_set_epsc(cpu_env
, cpu_gpr
[gprn
]);
1730 static void gen_spr_usprg3(CPUPPCState
*env
)
1732 spr_register(env
, SPR_USPRG3
, "USPRG3",
1733 &spr_read_ureg
, SPR_NOACCESS
,
1734 &spr_read_ureg
, SPR_NOACCESS
,
1738 static void gen_spr_usprgh(CPUPPCState
*env
)
1740 spr_register(env
, SPR_USPRG4
, "USPRG4",
1741 &spr_read_ureg
, SPR_NOACCESS
,
1742 &spr_read_ureg
, SPR_NOACCESS
,
1744 spr_register(env
, SPR_USPRG5
, "USPRG5",
1745 &spr_read_ureg
, SPR_NOACCESS
,
1746 &spr_read_ureg
, SPR_NOACCESS
,
1748 spr_register(env
, SPR_USPRG6
, "USPRG6",
1749 &spr_read_ureg
, SPR_NOACCESS
,
1750 &spr_read_ureg
, SPR_NOACCESS
,
1752 spr_register(env
, SPR_USPRG7
, "USPRG7",
1753 &spr_read_ureg
, SPR_NOACCESS
,
1754 &spr_read_ureg
, SPR_NOACCESS
,
1758 /* PowerPC BookE SPR */
1759 static void gen_spr_BookE(CPUPPCState
*env
, uint64_t ivor_mask
)
1761 const char *ivor_names
[64] = {
1762 "IVOR0", "IVOR1", "IVOR2", "IVOR3",
1763 "IVOR4", "IVOR5", "IVOR6", "IVOR7",
1764 "IVOR8", "IVOR9", "IVOR10", "IVOR11",
1765 "IVOR12", "IVOR13", "IVOR14", "IVOR15",
1766 "IVOR16", "IVOR17", "IVOR18", "IVOR19",
1767 "IVOR20", "IVOR21", "IVOR22", "IVOR23",
1768 "IVOR24", "IVOR25", "IVOR26", "IVOR27",
1769 "IVOR28", "IVOR29", "IVOR30", "IVOR31",
1770 "IVOR32", "IVOR33", "IVOR34", "IVOR35",
1771 "IVOR36", "IVOR37", "IVOR38", "IVOR39",
1772 "IVOR40", "IVOR41", "IVOR42", "IVOR43",
1773 "IVOR44", "IVOR45", "IVOR46", "IVOR47",
1774 "IVOR48", "IVOR49", "IVOR50", "IVOR51",
1775 "IVOR52", "IVOR53", "IVOR54", "IVOR55",
1776 "IVOR56", "IVOR57", "IVOR58", "IVOR59",
1777 "IVOR60", "IVOR61", "IVOR62", "IVOR63",
1779 #define SPR_BOOKE_IVORxx (-1)
1780 int ivor_sprn
[64] = {
1781 SPR_BOOKE_IVOR0
, SPR_BOOKE_IVOR1
, SPR_BOOKE_IVOR2
, SPR_BOOKE_IVOR3
,
1782 SPR_BOOKE_IVOR4
, SPR_BOOKE_IVOR5
, SPR_BOOKE_IVOR6
, SPR_BOOKE_IVOR7
,
1783 SPR_BOOKE_IVOR8
, SPR_BOOKE_IVOR9
, SPR_BOOKE_IVOR10
, SPR_BOOKE_IVOR11
,
1784 SPR_BOOKE_IVOR12
, SPR_BOOKE_IVOR13
, SPR_BOOKE_IVOR14
, SPR_BOOKE_IVOR15
,
1785 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1786 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1787 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1788 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1789 SPR_BOOKE_IVOR32
, SPR_BOOKE_IVOR33
, SPR_BOOKE_IVOR34
, SPR_BOOKE_IVOR35
,
1790 SPR_BOOKE_IVOR36
, SPR_BOOKE_IVOR37
, SPR_BOOKE_IVOR38
, SPR_BOOKE_IVOR39
,
1791 SPR_BOOKE_IVOR40
, SPR_BOOKE_IVOR41
, SPR_BOOKE_IVOR42
, SPR_BOOKE_IVORxx
,
1792 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1793 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1794 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1795 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1796 SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
, SPR_BOOKE_IVORxx
,
1800 /* Interrupt processing */
1801 spr_register(env
, SPR_BOOKE_CSRR0
, "CSRR0",
1802 SPR_NOACCESS
, SPR_NOACCESS
,
1803 &spr_read_generic
, &spr_write_generic
,
1805 spr_register(env
, SPR_BOOKE_CSRR1
, "CSRR1",
1806 SPR_NOACCESS
, SPR_NOACCESS
,
1807 &spr_read_generic
, &spr_write_generic
,
1810 /* XXX : not implemented */
1811 spr_register(env
, SPR_BOOKE_IAC1
, "IAC1",
1812 SPR_NOACCESS
, SPR_NOACCESS
,
1813 &spr_read_generic
, &spr_write_generic
,
1815 /* XXX : not implemented */
1816 spr_register(env
, SPR_BOOKE_IAC2
, "IAC2",
1817 SPR_NOACCESS
, SPR_NOACCESS
,
1818 &spr_read_generic
, &spr_write_generic
,
1820 /* XXX : not implemented */
1821 spr_register(env
, SPR_BOOKE_DAC1
, "DAC1",
1822 SPR_NOACCESS
, SPR_NOACCESS
,
1823 &spr_read_generic
, &spr_write_generic
,
1825 /* XXX : not implemented */
1826 spr_register(env
, SPR_BOOKE_DAC2
, "DAC2",
1827 SPR_NOACCESS
, SPR_NOACCESS
,
1828 &spr_read_generic
, &spr_write_generic
,
1830 /* XXX : not implemented */
1831 spr_register(env
, SPR_BOOKE_DBCR0
, "DBCR0",
1832 SPR_NOACCESS
, SPR_NOACCESS
,
1833 &spr_read_generic
, &spr_write_40x_dbcr0
,
1835 /* XXX : not implemented */
1836 spr_register(env
, SPR_BOOKE_DBCR1
, "DBCR1",
1837 SPR_NOACCESS
, SPR_NOACCESS
,
1838 &spr_read_generic
, &spr_write_generic
,
1840 /* XXX : not implemented */
1841 spr_register(env
, SPR_BOOKE_DBCR2
, "DBCR2",
1842 SPR_NOACCESS
, SPR_NOACCESS
,
1843 &spr_read_generic
, &spr_write_generic
,
1845 spr_register(env
, SPR_BOOKE_DSRR0
, "DSRR0",
1846 SPR_NOACCESS
, SPR_NOACCESS
,
1847 &spr_read_generic
, &spr_write_generic
,
1849 spr_register(env
, SPR_BOOKE_DSRR1
, "DSRR1",
1850 SPR_NOACCESS
, SPR_NOACCESS
,
1851 &spr_read_generic
, &spr_write_generic
,
1853 /* XXX : not implemented */
1854 spr_register(env
, SPR_BOOKE_DBSR
, "DBSR",
1855 SPR_NOACCESS
, SPR_NOACCESS
,
1856 &spr_read_generic
, &spr_write_clear
,
1858 spr_register(env
, SPR_BOOKE_DEAR
, "DEAR",
1859 SPR_NOACCESS
, SPR_NOACCESS
,
1860 &spr_read_generic
, &spr_write_generic
,
1862 spr_register(env
, SPR_BOOKE_ESR
, "ESR",
1863 SPR_NOACCESS
, SPR_NOACCESS
,
1864 &spr_read_generic
, &spr_write_generic
,
1866 spr_register(env
, SPR_BOOKE_IVPR
, "IVPR",
1867 SPR_NOACCESS
, SPR_NOACCESS
,
1868 &spr_read_generic
, &spr_write_excp_prefix
,
1870 /* Exception vectors */
1871 for (i
= 0; i
< 64; i
++) {
1872 if (ivor_mask
& (1ULL << i
)) {
1873 if (ivor_sprn
[i
] == SPR_BOOKE_IVORxx
) {
1874 fprintf(stderr
, "ERROR: IVOR %d SPR is not defined\n", i
);
1877 spr_register(env
, ivor_sprn
[i
], ivor_names
[i
],
1878 SPR_NOACCESS
, SPR_NOACCESS
,
1879 &spr_read_generic
, &spr_write_excp_vector
,
1883 spr_register(env
, SPR_BOOKE_PID
, "PID",
1884 SPR_NOACCESS
, SPR_NOACCESS
,
1885 &spr_read_generic
, &spr_write_booke_pid
,
1887 spr_register(env
, SPR_BOOKE_TCR
, "TCR",
1888 SPR_NOACCESS
, SPR_NOACCESS
,
1889 &spr_read_generic
, &spr_write_booke_tcr
,
1891 spr_register(env
, SPR_BOOKE_TSR
, "TSR",
1892 SPR_NOACCESS
, SPR_NOACCESS
,
1893 &spr_read_generic
, &spr_write_booke_tsr
,
1896 spr_register(env
, SPR_DECR
, "DECR",
1897 SPR_NOACCESS
, SPR_NOACCESS
,
1898 &spr_read_decr
, &spr_write_decr
,
1900 spr_register(env
, SPR_BOOKE_DECAR
, "DECAR",
1901 SPR_NOACCESS
, SPR_NOACCESS
,
1902 SPR_NOACCESS
, &spr_write_generic
,
1905 spr_register(env
, SPR_USPRG0
, "USPRG0",
1906 &spr_read_generic
, &spr_write_generic
,
1907 &spr_read_generic
, &spr_write_generic
,
1909 spr_register(env
, SPR_SPRG4
, "SPRG4",
1910 SPR_NOACCESS
, SPR_NOACCESS
,
1911 &spr_read_generic
, &spr_write_generic
,
1913 spr_register(env
, SPR_SPRG5
, "SPRG5",
1914 SPR_NOACCESS
, SPR_NOACCESS
,
1915 &spr_read_generic
, &spr_write_generic
,
1917 spr_register(env
, SPR_SPRG6
, "SPRG6",
1918 SPR_NOACCESS
, SPR_NOACCESS
,
1919 &spr_read_generic
, &spr_write_generic
,
1921 spr_register(env
, SPR_SPRG7
, "SPRG7",
1922 SPR_NOACCESS
, SPR_NOACCESS
,
1923 &spr_read_generic
, &spr_write_generic
,
1925 spr_register(env
, SPR_BOOKE_SPRG8
, "SPRG8",
1926 SPR_NOACCESS
, SPR_NOACCESS
,
1927 &spr_read_generic
, &spr_write_generic
,
1929 spr_register(env
, SPR_BOOKE_SPRG9
, "SPRG9",
1930 SPR_NOACCESS
, SPR_NOACCESS
,
1931 &spr_read_generic
, &spr_write_generic
,
1935 static inline uint32_t gen_tlbncfg(uint32_t assoc
, uint32_t minsize
,
1936 uint32_t maxsize
, uint32_t flags
,
1939 return (assoc
<< TLBnCFG_ASSOC_SHIFT
) |
1940 (minsize
<< TLBnCFG_MINSIZE_SHIFT
) |
1941 (maxsize
<< TLBnCFG_MAXSIZE_SHIFT
) |
1945 /* BookE 2.06 storage control registers */
1946 static void gen_spr_BookE206(CPUPPCState
*env
, uint32_t mas_mask
,
1947 uint32_t *tlbncfg
, uint32_t mmucfg
)
1949 #if !defined(CONFIG_USER_ONLY)
1950 const char *mas_names
[8] = {
1951 "MAS0", "MAS1", "MAS2", "MAS3", "MAS4", "MAS5", "MAS6", "MAS7",
1954 SPR_BOOKE_MAS0
, SPR_BOOKE_MAS1
, SPR_BOOKE_MAS2
, SPR_BOOKE_MAS3
,
1955 SPR_BOOKE_MAS4
, SPR_BOOKE_MAS5
, SPR_BOOKE_MAS6
, SPR_BOOKE_MAS7
,
1959 /* TLB assist registers */
1960 /* XXX : not implemented */
1961 for (i
= 0; i
< 8; i
++) {
1962 void (*uea_write
)(DisasContext
*ctx
, int sprn
, int gprn
) =
1963 &spr_write_generic32
;
1964 if (i
== 2 && (mas_mask
& (1 << i
)) && (env
->insns_flags
& PPC_64B
)) {
1965 uea_write
= &spr_write_generic
;
1967 if (mas_mask
& (1 << i
)) {
1968 spr_register(env
, mas_sprn
[i
], mas_names
[i
],
1969 SPR_NOACCESS
, SPR_NOACCESS
,
1970 &spr_read_generic
, uea_write
,
1974 if (env
->nb_pids
> 1) {
1975 /* XXX : not implemented */
1976 spr_register(env
, SPR_BOOKE_PID1
, "PID1",
1977 SPR_NOACCESS
, SPR_NOACCESS
,
1978 &spr_read_generic
, &spr_write_booke_pid
,
1981 if (env
->nb_pids
> 2) {
1982 /* XXX : not implemented */
1983 spr_register(env
, SPR_BOOKE_PID2
, "PID2",
1984 SPR_NOACCESS
, SPR_NOACCESS
,
1985 &spr_read_generic
, &spr_write_booke_pid
,
1989 spr_register(env
, SPR_BOOKE_EPLC
, "EPLC",
1990 SPR_NOACCESS
, SPR_NOACCESS
,
1991 &spr_read_generic
, &spr_write_eplc
,
1993 spr_register(env
, SPR_BOOKE_EPSC
, "EPSC",
1994 SPR_NOACCESS
, SPR_NOACCESS
,
1995 &spr_read_generic
, &spr_write_epsc
,
1998 /* XXX : not implemented */
1999 spr_register(env
, SPR_MMUCFG
, "MMUCFG",
2000 SPR_NOACCESS
, SPR_NOACCESS
,
2001 &spr_read_generic
, SPR_NOACCESS
,
2003 switch (env
->nb_ways
) {
2005 spr_register(env
, SPR_BOOKE_TLB3CFG
, "TLB3CFG",
2006 SPR_NOACCESS
, SPR_NOACCESS
,
2007 &spr_read_generic
, SPR_NOACCESS
,
2011 spr_register(env
, SPR_BOOKE_TLB2CFG
, "TLB2CFG",
2012 SPR_NOACCESS
, SPR_NOACCESS
,
2013 &spr_read_generic
, SPR_NOACCESS
,
2017 spr_register(env
, SPR_BOOKE_TLB1CFG
, "TLB1CFG",
2018 SPR_NOACCESS
, SPR_NOACCESS
,
2019 &spr_read_generic
, SPR_NOACCESS
,
2023 spr_register(env
, SPR_BOOKE_TLB0CFG
, "TLB0CFG",
2024 SPR_NOACCESS
, SPR_NOACCESS
,
2025 &spr_read_generic
, SPR_NOACCESS
,
2034 gen_spr_usprgh(env
);
2037 /* SPR specific to PowerPC 440 implementation */
2038 static void gen_spr_440(CPUPPCState
*env
)
2041 /* XXX : not implemented */
2042 spr_register(env
, SPR_440_DNV0
, "DNV0",
2043 SPR_NOACCESS
, SPR_NOACCESS
,
2044 &spr_read_generic
, &spr_write_generic
,
2046 /* XXX : not implemented */
2047 spr_register(env
, SPR_440_DNV1
, "DNV1",
2048 SPR_NOACCESS
, SPR_NOACCESS
,
2049 &spr_read_generic
, &spr_write_generic
,
2051 /* XXX : not implemented */
2052 spr_register(env
, SPR_440_DNV2
, "DNV2",
2053 SPR_NOACCESS
, SPR_NOACCESS
,
2054 &spr_read_generic
, &spr_write_generic
,
2056 /* XXX : not implemented */
2057 spr_register(env
, SPR_440_DNV3
, "DNV3",
2058 SPR_NOACCESS
, SPR_NOACCESS
,
2059 &spr_read_generic
, &spr_write_generic
,
2061 /* XXX : not implemented */
2062 spr_register(env
, SPR_440_DTV0
, "DTV0",
2063 SPR_NOACCESS
, SPR_NOACCESS
,
2064 &spr_read_generic
, &spr_write_generic
,
2066 /* XXX : not implemented */
2067 spr_register(env
, SPR_440_DTV1
, "DTV1",
2068 SPR_NOACCESS
, SPR_NOACCESS
,
2069 &spr_read_generic
, &spr_write_generic
,
2071 /* XXX : not implemented */
2072 spr_register(env
, SPR_440_DTV2
, "DTV2",
2073 SPR_NOACCESS
, SPR_NOACCESS
,
2074 &spr_read_generic
, &spr_write_generic
,
2076 /* XXX : not implemented */
2077 spr_register(env
, SPR_440_DTV3
, "DTV3",
2078 SPR_NOACCESS
, SPR_NOACCESS
,
2079 &spr_read_generic
, &spr_write_generic
,
2081 /* XXX : not implemented */
2082 spr_register(env
, SPR_440_DVLIM
, "DVLIM",
2083 SPR_NOACCESS
, SPR_NOACCESS
,
2084 &spr_read_generic
, &spr_write_generic
,
2086 /* XXX : not implemented */
2087 spr_register(env
, SPR_440_INV0
, "INV0",
2088 SPR_NOACCESS
, SPR_NOACCESS
,
2089 &spr_read_generic
, &spr_write_generic
,
2091 /* XXX : not implemented */
2092 spr_register(env
, SPR_440_INV1
, "INV1",
2093 SPR_NOACCESS
, SPR_NOACCESS
,
2094 &spr_read_generic
, &spr_write_generic
,
2096 /* XXX : not implemented */
2097 spr_register(env
, SPR_440_INV2
, "INV2",
2098 SPR_NOACCESS
, SPR_NOACCESS
,
2099 &spr_read_generic
, &spr_write_generic
,
2101 /* XXX : not implemented */
2102 spr_register(env
, SPR_440_INV3
, "INV3",
2103 SPR_NOACCESS
, SPR_NOACCESS
,
2104 &spr_read_generic
, &spr_write_generic
,
2106 /* XXX : not implemented */
2107 spr_register(env
, SPR_440_ITV0
, "ITV0",
2108 SPR_NOACCESS
, SPR_NOACCESS
,
2109 &spr_read_generic
, &spr_write_generic
,
2111 /* XXX : not implemented */
2112 spr_register(env
, SPR_440_ITV1
, "ITV1",
2113 SPR_NOACCESS
, SPR_NOACCESS
,
2114 &spr_read_generic
, &spr_write_generic
,
2116 /* XXX : not implemented */
2117 spr_register(env
, SPR_440_ITV2
, "ITV2",
2118 SPR_NOACCESS
, SPR_NOACCESS
,
2119 &spr_read_generic
, &spr_write_generic
,
2121 /* XXX : not implemented */
2122 spr_register(env
, SPR_440_ITV3
, "ITV3",
2123 SPR_NOACCESS
, SPR_NOACCESS
,
2124 &spr_read_generic
, &spr_write_generic
,
2126 /* XXX : not implemented */
2127 spr_register(env
, SPR_440_IVLIM
, "IVLIM",
2128 SPR_NOACCESS
, SPR_NOACCESS
,
2129 &spr_read_generic
, &spr_write_generic
,
2132 /* XXX : not implemented */
2133 spr_register(env
, SPR_BOOKE_DCDBTRH
, "DCDBTRH",
2134 SPR_NOACCESS
, SPR_NOACCESS
,
2135 &spr_read_generic
, SPR_NOACCESS
,
2137 /* XXX : not implemented */
2138 spr_register(env
, SPR_BOOKE_DCDBTRL
, "DCDBTRL",
2139 SPR_NOACCESS
, SPR_NOACCESS
,
2140 &spr_read_generic
, SPR_NOACCESS
,
2142 /* XXX : not implemented */
2143 spr_register(env
, SPR_BOOKE_ICDBDR
, "ICDBDR",
2144 SPR_NOACCESS
, SPR_NOACCESS
,
2145 &spr_read_generic
, SPR_NOACCESS
,
2147 /* XXX : not implemented */
2148 spr_register(env
, SPR_BOOKE_ICDBTRH
, "ICDBTRH",
2149 SPR_NOACCESS
, SPR_NOACCESS
,
2150 &spr_read_generic
, SPR_NOACCESS
,
2152 /* XXX : not implemented */
2153 spr_register(env
, SPR_BOOKE_ICDBTRL
, "ICDBTRL",
2154 SPR_NOACCESS
, SPR_NOACCESS
,
2155 &spr_read_generic
, SPR_NOACCESS
,
2157 /* XXX : not implemented */
2158 spr_register(env
, SPR_440_DBDR
, "DBDR",
2159 SPR_NOACCESS
, SPR_NOACCESS
,
2160 &spr_read_generic
, &spr_write_generic
,
2162 /* Processor control */
2163 spr_register(env
, SPR_4xx_CCR0
, "CCR0",
2164 SPR_NOACCESS
, SPR_NOACCESS
,
2165 &spr_read_generic
, &spr_write_generic
,
2167 spr_register(env
, SPR_440_RSTCFG
, "RSTCFG",
2168 SPR_NOACCESS
, SPR_NOACCESS
,
2169 &spr_read_generic
, SPR_NOACCESS
,
2171 /* Storage control */
2172 spr_register(env
, SPR_440_MMUCR
, "MMUCR",
2173 SPR_NOACCESS
, SPR_NOACCESS
,
2174 &spr_read_generic
, &spr_write_generic
,
2178 /* SPR shared between PowerPC 40x implementations */
2179 static void gen_spr_40x(CPUPPCState
*env
)
2182 /* not emulated, as QEMU do not emulate caches */
2183 spr_register(env
, SPR_40x_DCCR
, "DCCR",
2184 SPR_NOACCESS
, SPR_NOACCESS
,
2185 &spr_read_generic
, &spr_write_generic
,
2187 /* not emulated, as QEMU do not emulate caches */
2188 spr_register(env
, SPR_40x_ICCR
, "ICCR",
2189 SPR_NOACCESS
, SPR_NOACCESS
,
2190 &spr_read_generic
, &spr_write_generic
,
2192 /* not emulated, as QEMU do not emulate caches */
2193 spr_register(env
, SPR_BOOKE_ICDBDR
, "ICDBDR",
2194 SPR_NOACCESS
, SPR_NOACCESS
,
2195 &spr_read_generic
, SPR_NOACCESS
,
2198 spr_register(env
, SPR_40x_DEAR
, "DEAR",
2199 SPR_NOACCESS
, SPR_NOACCESS
,
2200 &spr_read_generic
, &spr_write_generic
,
2202 spr_register(env
, SPR_40x_ESR
, "ESR",
2203 SPR_NOACCESS
, SPR_NOACCESS
,
2204 &spr_read_generic
, &spr_write_generic
,
2206 spr_register(env
, SPR_40x_EVPR
, "EVPR",
2207 SPR_NOACCESS
, SPR_NOACCESS
,
2208 &spr_read_generic
, &spr_write_excp_prefix
,
2210 spr_register(env
, SPR_40x_SRR2
, "SRR2",
2211 &spr_read_generic
, &spr_write_generic
,
2212 &spr_read_generic
, &spr_write_generic
,
2214 spr_register(env
, SPR_40x_SRR3
, "SRR3",
2215 &spr_read_generic
, &spr_write_generic
,
2216 &spr_read_generic
, &spr_write_generic
,
2219 spr_register(env
, SPR_40x_PIT
, "PIT",
2220 SPR_NOACCESS
, SPR_NOACCESS
,
2221 &spr_read_40x_pit
, &spr_write_40x_pit
,
2223 spr_register(env
, SPR_40x_TCR
, "TCR",
2224 SPR_NOACCESS
, SPR_NOACCESS
,
2225 &spr_read_generic
, &spr_write_booke_tcr
,
2227 spr_register(env
, SPR_40x_TSR
, "TSR",
2228 SPR_NOACCESS
, SPR_NOACCESS
,
2229 &spr_read_generic
, &spr_write_booke_tsr
,
2233 /* SPR specific to PowerPC 405 implementation */
2234 static void gen_spr_405(CPUPPCState
*env
)
2237 spr_register(env
, SPR_40x_PID
, "PID",
2238 SPR_NOACCESS
, SPR_NOACCESS
,
2239 &spr_read_generic
, &spr_write_generic
,
2241 spr_register(env
, SPR_4xx_CCR0
, "CCR0",
2242 SPR_NOACCESS
, SPR_NOACCESS
,
2243 &spr_read_generic
, &spr_write_generic
,
2245 /* Debug interface */
2246 /* XXX : not implemented */
2247 spr_register(env
, SPR_40x_DBCR0
, "DBCR0",
2248 SPR_NOACCESS
, SPR_NOACCESS
,
2249 &spr_read_generic
, &spr_write_40x_dbcr0
,
2251 /* XXX : not implemented */
2252 spr_register(env
, SPR_405_DBCR1
, "DBCR1",
2253 SPR_NOACCESS
, SPR_NOACCESS
,
2254 &spr_read_generic
, &spr_write_generic
,
2256 /* XXX : not implemented */
2257 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2258 SPR_NOACCESS
, SPR_NOACCESS
,
2259 &spr_read_generic
, &spr_write_clear
,
2260 /* Last reset was system reset */
2262 /* XXX : not implemented */
2263 spr_register(env
, SPR_40x_DAC1
, "DAC1",
2264 SPR_NOACCESS
, SPR_NOACCESS
,
2265 &spr_read_generic
, &spr_write_generic
,
2267 spr_register(env
, SPR_40x_DAC2
, "DAC2",
2268 SPR_NOACCESS
, SPR_NOACCESS
,
2269 &spr_read_generic
, &spr_write_generic
,
2271 /* XXX : not implemented */
2272 spr_register(env
, SPR_405_DVC1
, "DVC1",
2273 SPR_NOACCESS
, SPR_NOACCESS
,
2274 &spr_read_generic
, &spr_write_generic
,
2276 /* XXX : not implemented */
2277 spr_register(env
, SPR_405_DVC2
, "DVC2",
2278 SPR_NOACCESS
, SPR_NOACCESS
,
2279 &spr_read_generic
, &spr_write_generic
,
2281 /* XXX : not implemented */
2282 spr_register(env
, SPR_40x_IAC1
, "IAC1",
2283 SPR_NOACCESS
, SPR_NOACCESS
,
2284 &spr_read_generic
, &spr_write_generic
,
2286 spr_register(env
, SPR_40x_IAC2
, "IAC2",
2287 SPR_NOACCESS
, SPR_NOACCESS
,
2288 &spr_read_generic
, &spr_write_generic
,
2290 /* XXX : not implemented */
2291 spr_register(env
, SPR_405_IAC3
, "IAC3",
2292 SPR_NOACCESS
, SPR_NOACCESS
,
2293 &spr_read_generic
, &spr_write_generic
,
2295 /* XXX : not implemented */
2296 spr_register(env
, SPR_405_IAC4
, "IAC4",
2297 SPR_NOACCESS
, SPR_NOACCESS
,
2298 &spr_read_generic
, &spr_write_generic
,
2300 /* Storage control */
2301 /* XXX: TODO: not implemented */
2302 spr_register(env
, SPR_405_SLER
, "SLER",
2303 SPR_NOACCESS
, SPR_NOACCESS
,
2304 &spr_read_generic
, &spr_write_40x_sler
,
2306 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2307 SPR_NOACCESS
, SPR_NOACCESS
,
2308 &spr_read_generic
, &spr_write_generic
,
2310 /* XXX : not implemented */
2311 spr_register(env
, SPR_405_SU0R
, "SU0R",
2312 SPR_NOACCESS
, SPR_NOACCESS
,
2313 &spr_read_generic
, &spr_write_generic
,
2316 spr_register(env
, SPR_USPRG0
, "USPRG0",
2317 &spr_read_ureg
, SPR_NOACCESS
,
2318 &spr_read_ureg
, SPR_NOACCESS
,
2320 spr_register(env
, SPR_SPRG4
, "SPRG4",
2321 SPR_NOACCESS
, SPR_NOACCESS
,
2322 &spr_read_generic
, &spr_write_generic
,
2324 spr_register(env
, SPR_SPRG5
, "SPRG5",
2325 SPR_NOACCESS
, SPR_NOACCESS
,
2326 spr_read_generic
, &spr_write_generic
,
2328 spr_register(env
, SPR_SPRG6
, "SPRG6",
2329 SPR_NOACCESS
, SPR_NOACCESS
,
2330 spr_read_generic
, &spr_write_generic
,
2332 spr_register(env
, SPR_SPRG7
, "SPRG7",
2333 SPR_NOACCESS
, SPR_NOACCESS
,
2334 spr_read_generic
, &spr_write_generic
,
2336 gen_spr_usprgh(env
);
2339 /* SPR shared between PowerPC 401 & 403 implementations */
2340 static void gen_spr_401_403(CPUPPCState
*env
)
2343 spr_register(env
, SPR_403_VTBL
, "TBL",
2344 &spr_read_tbl
, SPR_NOACCESS
,
2345 &spr_read_tbl
, SPR_NOACCESS
,
2347 spr_register(env
, SPR_403_TBL
, "TBL",
2348 SPR_NOACCESS
, SPR_NOACCESS
,
2349 SPR_NOACCESS
, &spr_write_tbl
,
2351 spr_register(env
, SPR_403_VTBU
, "TBU",
2352 &spr_read_tbu
, SPR_NOACCESS
,
2353 &spr_read_tbu
, SPR_NOACCESS
,
2355 spr_register(env
, SPR_403_TBU
, "TBU",
2356 SPR_NOACCESS
, SPR_NOACCESS
,
2357 SPR_NOACCESS
, &spr_write_tbu
,
2360 /* not emulated, as QEMU do not emulate caches */
2361 spr_register(env
, SPR_403_CDBCR
, "CDBCR",
2362 SPR_NOACCESS
, SPR_NOACCESS
,
2363 &spr_read_generic
, &spr_write_generic
,
2367 /* SPR specific to PowerPC 401 implementation */
2368 static void gen_spr_401(CPUPPCState
*env
)
2370 /* Debug interface */
2371 /* XXX : not implemented */
2372 spr_register(env
, SPR_40x_DBCR0
, "DBCR",
2373 SPR_NOACCESS
, SPR_NOACCESS
,
2374 &spr_read_generic
, &spr_write_40x_dbcr0
,
2376 /* XXX : not implemented */
2377 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2378 SPR_NOACCESS
, SPR_NOACCESS
,
2379 &spr_read_generic
, &spr_write_clear
,
2380 /* Last reset was system reset */
2382 /* XXX : not implemented */
2383 spr_register(env
, SPR_40x_DAC1
, "DAC",
2384 SPR_NOACCESS
, SPR_NOACCESS
,
2385 &spr_read_generic
, &spr_write_generic
,
2387 /* XXX : not implemented */
2388 spr_register(env
, SPR_40x_IAC1
, "IAC",
2389 SPR_NOACCESS
, SPR_NOACCESS
,
2390 &spr_read_generic
, &spr_write_generic
,
2392 /* Storage control */
2393 /* XXX: TODO: not implemented */
2394 spr_register(env
, SPR_405_SLER
, "SLER",
2395 SPR_NOACCESS
, SPR_NOACCESS
,
2396 &spr_read_generic
, &spr_write_40x_sler
,
2398 /* not emulated, as QEMU never does speculative access */
2399 spr_register(env
, SPR_40x_SGR
, "SGR",
2400 SPR_NOACCESS
, SPR_NOACCESS
,
2401 &spr_read_generic
, &spr_write_generic
,
2403 /* not emulated, as QEMU do not emulate caches */
2404 spr_register(env
, SPR_40x_DCWR
, "DCWR",
2405 SPR_NOACCESS
, SPR_NOACCESS
,
2406 &spr_read_generic
, &spr_write_generic
,
2410 static void gen_spr_401x2(CPUPPCState
*env
)
2413 spr_register(env
, SPR_40x_PID
, "PID",
2414 SPR_NOACCESS
, SPR_NOACCESS
,
2415 &spr_read_generic
, &spr_write_generic
,
2417 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2418 SPR_NOACCESS
, SPR_NOACCESS
,
2419 &spr_read_generic
, &spr_write_generic
,
2423 /* SPR specific to PowerPC 403 implementation */
2424 static void gen_spr_403(CPUPPCState
*env
)
2426 /* Debug interface */
2427 /* XXX : not implemented */
2428 spr_register(env
, SPR_40x_DBCR0
, "DBCR0",
2429 SPR_NOACCESS
, SPR_NOACCESS
,
2430 &spr_read_generic
, &spr_write_40x_dbcr0
,
2432 /* XXX : not implemented */
2433 spr_register(env
, SPR_40x_DBSR
, "DBSR",
2434 SPR_NOACCESS
, SPR_NOACCESS
,
2435 &spr_read_generic
, &spr_write_clear
,
2436 /* Last reset was system reset */
2438 /* XXX : not implemented */
2439 spr_register(env
, SPR_40x_DAC1
, "DAC1",
2440 SPR_NOACCESS
, SPR_NOACCESS
,
2441 &spr_read_generic
, &spr_write_generic
,
2443 /* XXX : not implemented */
2444 spr_register(env
, SPR_40x_DAC2
, "DAC2",
2445 SPR_NOACCESS
, SPR_NOACCESS
,
2446 &spr_read_generic
, &spr_write_generic
,
2448 /* XXX : not implemented */
2449 spr_register(env
, SPR_40x_IAC1
, "IAC1",
2450 SPR_NOACCESS
, SPR_NOACCESS
,
2451 &spr_read_generic
, &spr_write_generic
,
2453 /* XXX : not implemented */
2454 spr_register(env
, SPR_40x_IAC2
, "IAC2",
2455 SPR_NOACCESS
, SPR_NOACCESS
,
2456 &spr_read_generic
, &spr_write_generic
,
2460 static void gen_spr_403_real(CPUPPCState
*env
)
2462 spr_register(env
, SPR_403_PBL1
, "PBL1",
2463 SPR_NOACCESS
, SPR_NOACCESS
,
2464 &spr_read_403_pbr
, &spr_write_403_pbr
,
2466 spr_register(env
, SPR_403_PBU1
, "PBU1",
2467 SPR_NOACCESS
, SPR_NOACCESS
,
2468 &spr_read_403_pbr
, &spr_write_403_pbr
,
2470 spr_register(env
, SPR_403_PBL2
, "PBL2",
2471 SPR_NOACCESS
, SPR_NOACCESS
,
2472 &spr_read_403_pbr
, &spr_write_403_pbr
,
2474 spr_register(env
, SPR_403_PBU2
, "PBU2",
2475 SPR_NOACCESS
, SPR_NOACCESS
,
2476 &spr_read_403_pbr
, &spr_write_403_pbr
,
2480 static void gen_spr_403_mmu(CPUPPCState
*env
)
2483 spr_register(env
, SPR_40x_PID
, "PID",
2484 SPR_NOACCESS
, SPR_NOACCESS
,
2485 &spr_read_generic
, &spr_write_generic
,
2487 spr_register(env
, SPR_40x_ZPR
, "ZPR",
2488 SPR_NOACCESS
, SPR_NOACCESS
,
2489 &spr_read_generic
, &spr_write_generic
,
2493 /* SPR specific to PowerPC compression coprocessor extension */
2494 static void gen_spr_compress(CPUPPCState
*env
)
2496 /* XXX : not implemented */
2497 spr_register(env
, SPR_401_SKR
, "SKR",
2498 SPR_NOACCESS
, SPR_NOACCESS
,
2499 &spr_read_generic
, &spr_write_generic
,
2503 static void gen_spr_5xx_8xx(CPUPPCState
*env
)
2505 /* Exception processing */
2506 spr_register_kvm(env
, SPR_DSISR
, "DSISR",
2507 SPR_NOACCESS
, SPR_NOACCESS
,
2508 &spr_read_generic
, &spr_write_generic
,
2509 KVM_REG_PPC_DSISR
, 0x00000000);
2510 spr_register_kvm(env
, SPR_DAR
, "DAR",
2511 SPR_NOACCESS
, SPR_NOACCESS
,
2512 &spr_read_generic
, &spr_write_generic
,
2513 KVM_REG_PPC_DAR
, 0x00000000);
2515 spr_register(env
, SPR_DECR
, "DECR",
2516 SPR_NOACCESS
, SPR_NOACCESS
,
2517 &spr_read_decr
, &spr_write_decr
,
2519 /* XXX : not implemented */
2520 spr_register(env
, SPR_MPC_EIE
, "EIE",
2521 SPR_NOACCESS
, SPR_NOACCESS
,
2522 &spr_read_generic
, &spr_write_generic
,
2524 /* XXX : not implemented */
2525 spr_register(env
, SPR_MPC_EID
, "EID",
2526 SPR_NOACCESS
, SPR_NOACCESS
,
2527 &spr_read_generic
, &spr_write_generic
,
2529 /* XXX : not implemented */
2530 spr_register(env
, SPR_MPC_NRI
, "NRI",
2531 SPR_NOACCESS
, SPR_NOACCESS
,
2532 &spr_read_generic
, &spr_write_generic
,
2534 /* XXX : not implemented */
2535 spr_register(env
, SPR_MPC_CMPA
, "CMPA",
2536 SPR_NOACCESS
, SPR_NOACCESS
,
2537 &spr_read_generic
, &spr_write_generic
,
2539 /* XXX : not implemented */
2540 spr_register(env
, SPR_MPC_CMPB
, "CMPB",
2541 SPR_NOACCESS
, SPR_NOACCESS
,
2542 &spr_read_generic
, &spr_write_generic
,
2544 /* XXX : not implemented */
2545 spr_register(env
, SPR_MPC_CMPC
, "CMPC",
2546 SPR_NOACCESS
, SPR_NOACCESS
,
2547 &spr_read_generic
, &spr_write_generic
,
2549 /* XXX : not implemented */
2550 spr_register(env
, SPR_MPC_CMPD
, "CMPD",
2551 SPR_NOACCESS
, SPR_NOACCESS
,
2552 &spr_read_generic
, &spr_write_generic
,
2554 /* XXX : not implemented */
2555 spr_register(env
, SPR_MPC_ECR
, "ECR",
2556 SPR_NOACCESS
, SPR_NOACCESS
,
2557 &spr_read_generic
, &spr_write_generic
,
2559 /* XXX : not implemented */
2560 spr_register(env
, SPR_MPC_DER
, "DER",
2561 SPR_NOACCESS
, SPR_NOACCESS
,
2562 &spr_read_generic
, &spr_write_generic
,
2564 /* XXX : not implemented */
2565 spr_register(env
, SPR_MPC_COUNTA
, "COUNTA",
2566 SPR_NOACCESS
, SPR_NOACCESS
,
2567 &spr_read_generic
, &spr_write_generic
,
2569 /* XXX : not implemented */
2570 spr_register(env
, SPR_MPC_COUNTB
, "COUNTB",
2571 SPR_NOACCESS
, SPR_NOACCESS
,
2572 &spr_read_generic
, &spr_write_generic
,
2574 /* XXX : not implemented */
2575 spr_register(env
, SPR_MPC_CMPE
, "CMPE",
2576 SPR_NOACCESS
, SPR_NOACCESS
,
2577 &spr_read_generic
, &spr_write_generic
,
2579 /* XXX : not implemented */
2580 spr_register(env
, SPR_MPC_CMPF
, "CMPF",
2581 SPR_NOACCESS
, SPR_NOACCESS
,
2582 &spr_read_generic
, &spr_write_generic
,
2584 /* XXX : not implemented */
2585 spr_register(env
, SPR_MPC_CMPG
, "CMPG",
2586 SPR_NOACCESS
, SPR_NOACCESS
,
2587 &spr_read_generic
, &spr_write_generic
,
2589 /* XXX : not implemented */
2590 spr_register(env
, SPR_MPC_CMPH
, "CMPH",
2591 SPR_NOACCESS
, SPR_NOACCESS
,
2592 &spr_read_generic
, &spr_write_generic
,
2594 /* XXX : not implemented */
2595 spr_register(env
, SPR_MPC_LCTRL1
, "LCTRL1",
2596 SPR_NOACCESS
, SPR_NOACCESS
,
2597 &spr_read_generic
, &spr_write_generic
,
2599 /* XXX : not implemented */
2600 spr_register(env
, SPR_MPC_LCTRL2
, "LCTRL2",
2601 SPR_NOACCESS
, SPR_NOACCESS
,
2602 &spr_read_generic
, &spr_write_generic
,
2604 /* XXX : not implemented */
2605 spr_register(env
, SPR_MPC_BAR
, "BAR",
2606 SPR_NOACCESS
, SPR_NOACCESS
,
2607 &spr_read_generic
, &spr_write_generic
,
2609 /* XXX : not implemented */
2610 spr_register(env
, SPR_MPC_DPDR
, "DPDR",
2611 SPR_NOACCESS
, SPR_NOACCESS
,
2612 &spr_read_generic
, &spr_write_generic
,
2614 /* XXX : not implemented */
2615 spr_register(env
, SPR_MPC_IMMR
, "IMMR",
2616 SPR_NOACCESS
, SPR_NOACCESS
,
2617 &spr_read_generic
, &spr_write_generic
,
2621 static void gen_spr_5xx(CPUPPCState
*env
)
2623 /* XXX : not implemented */
2624 spr_register(env
, SPR_RCPU_MI_GRA
, "MI_GRA",
2625 SPR_NOACCESS
, SPR_NOACCESS
,
2626 &spr_read_generic
, &spr_write_generic
,
2628 /* XXX : not implemented */
2629 spr_register(env
, SPR_RCPU_L2U_GRA
, "L2U_GRA",
2630 SPR_NOACCESS
, SPR_NOACCESS
,
2631 &spr_read_generic
, &spr_write_generic
,
2633 /* XXX : not implemented */
2634 spr_register(env
, SPR_RPCU_BBCMCR
, "L2U_BBCMCR",
2635 SPR_NOACCESS
, SPR_NOACCESS
,
2636 &spr_read_generic
, &spr_write_generic
,
2638 /* XXX : not implemented */
2639 spr_register(env
, SPR_RCPU_L2U_MCR
, "L2U_MCR",
2640 SPR_NOACCESS
, SPR_NOACCESS
,
2641 &spr_read_generic
, &spr_write_generic
,
2643 /* XXX : not implemented */
2644 spr_register(env
, SPR_RCPU_MI_RBA0
, "MI_RBA0",
2645 SPR_NOACCESS
, SPR_NOACCESS
,
2646 &spr_read_generic
, &spr_write_generic
,
2648 /* XXX : not implemented */
2649 spr_register(env
, SPR_RCPU_MI_RBA1
, "MI_RBA1",
2650 SPR_NOACCESS
, SPR_NOACCESS
,
2651 &spr_read_generic
, &spr_write_generic
,
2653 /* XXX : not implemented */
2654 spr_register(env
, SPR_RCPU_MI_RBA2
, "MI_RBA2",
2655 SPR_NOACCESS
, SPR_NOACCESS
,
2656 &spr_read_generic
, &spr_write_generic
,
2658 /* XXX : not implemented */
2659 spr_register(env
, SPR_RCPU_MI_RBA3
, "MI_RBA3",
2660 SPR_NOACCESS
, SPR_NOACCESS
,
2661 &spr_read_generic
, &spr_write_generic
,
2663 /* XXX : not implemented */
2664 spr_register(env
, SPR_RCPU_L2U_RBA0
, "L2U_RBA0",
2665 SPR_NOACCESS
, SPR_NOACCESS
,
2666 &spr_read_generic
, &spr_write_generic
,
2668 /* XXX : not implemented */
2669 spr_register(env
, SPR_RCPU_L2U_RBA1
, "L2U_RBA1",
2670 SPR_NOACCESS
, SPR_NOACCESS
,
2671 &spr_read_generic
, &spr_write_generic
,
2673 /* XXX : not implemented */
2674 spr_register(env
, SPR_RCPU_L2U_RBA2
, "L2U_RBA2",
2675 SPR_NOACCESS
, SPR_NOACCESS
,
2676 &spr_read_generic
, &spr_write_generic
,
2678 /* XXX : not implemented */
2679 spr_register(env
, SPR_RCPU_L2U_RBA3
, "L2U_RBA3",
2680 SPR_NOACCESS
, SPR_NOACCESS
,
2681 &spr_read_generic
, &spr_write_generic
,
2683 /* XXX : not implemented */
2684 spr_register(env
, SPR_RCPU_MI_RA0
, "MI_RA0",
2685 SPR_NOACCESS
, SPR_NOACCESS
,
2686 &spr_read_generic
, &spr_write_generic
,
2688 /* XXX : not implemented */
2689 spr_register(env
, SPR_RCPU_MI_RA1
, "MI_RA1",
2690 SPR_NOACCESS
, SPR_NOACCESS
,
2691 &spr_read_generic
, &spr_write_generic
,
2693 /* XXX : not implemented */
2694 spr_register(env
, SPR_RCPU_MI_RA2
, "MI_RA2",
2695 SPR_NOACCESS
, SPR_NOACCESS
,
2696 &spr_read_generic
, &spr_write_generic
,
2698 /* XXX : not implemented */
2699 spr_register(env
, SPR_RCPU_MI_RA3
, "MI_RA3",
2700 SPR_NOACCESS
, SPR_NOACCESS
,
2701 &spr_read_generic
, &spr_write_generic
,
2703 /* XXX : not implemented */
2704 spr_register(env
, SPR_RCPU_L2U_RA0
, "L2U_RA0",
2705 SPR_NOACCESS
, SPR_NOACCESS
,
2706 &spr_read_generic
, &spr_write_generic
,
2708 /* XXX : not implemented */
2709 spr_register(env
, SPR_RCPU_L2U_RA1
, "L2U_RA1",
2710 SPR_NOACCESS
, SPR_NOACCESS
,
2711 &spr_read_generic
, &spr_write_generic
,
2713 /* XXX : not implemented */
2714 spr_register(env
, SPR_RCPU_L2U_RA2
, "L2U_RA2",
2715 SPR_NOACCESS
, SPR_NOACCESS
,
2716 &spr_read_generic
, &spr_write_generic
,
2718 /* XXX : not implemented */
2719 spr_register(env
, SPR_RCPU_L2U_RA3
, "L2U_RA3",
2720 SPR_NOACCESS
, SPR_NOACCESS
,
2721 &spr_read_generic
, &spr_write_generic
,
2723 /* XXX : not implemented */
2724 spr_register(env
, SPR_RCPU_FPECR
, "FPECR",
2725 SPR_NOACCESS
, SPR_NOACCESS
,
2726 &spr_read_generic
, &spr_write_generic
,
2730 static void gen_spr_8xx(CPUPPCState
*env
)
2732 /* XXX : not implemented */
2733 spr_register(env
, SPR_MPC_IC_CST
, "IC_CST",
2734 SPR_NOACCESS
, SPR_NOACCESS
,
2735 &spr_read_generic
, &spr_write_generic
,
2737 /* XXX : not implemented */
2738 spr_register(env
, SPR_MPC_IC_ADR
, "IC_ADR",
2739 SPR_NOACCESS
, SPR_NOACCESS
,
2740 &spr_read_generic
, &spr_write_generic
,
2742 /* XXX : not implemented */
2743 spr_register(env
, SPR_MPC_IC_DAT
, "IC_DAT",
2744 SPR_NOACCESS
, SPR_NOACCESS
,
2745 &spr_read_generic
, &spr_write_generic
,
2747 /* XXX : not implemented */
2748 spr_register(env
, SPR_MPC_DC_CST
, "DC_CST",
2749 SPR_NOACCESS
, SPR_NOACCESS
,
2750 &spr_read_generic
, &spr_write_generic
,
2752 /* XXX : not implemented */
2753 spr_register(env
, SPR_MPC_DC_ADR
, "DC_ADR",
2754 SPR_NOACCESS
, SPR_NOACCESS
,
2755 &spr_read_generic
, &spr_write_generic
,
2757 /* XXX : not implemented */
2758 spr_register(env
, SPR_MPC_DC_DAT
, "DC_DAT",
2759 SPR_NOACCESS
, SPR_NOACCESS
,
2760 &spr_read_generic
, &spr_write_generic
,
2762 /* XXX : not implemented */
2763 spr_register(env
, SPR_MPC_MI_CTR
, "MI_CTR",
2764 SPR_NOACCESS
, SPR_NOACCESS
,
2765 &spr_read_generic
, &spr_write_generic
,
2767 /* XXX : not implemented */
2768 spr_register(env
, SPR_MPC_MI_AP
, "MI_AP",
2769 SPR_NOACCESS
, SPR_NOACCESS
,
2770 &spr_read_generic
, &spr_write_generic
,
2772 /* XXX : not implemented */
2773 spr_register(env
, SPR_MPC_MI_EPN
, "MI_EPN",
2774 SPR_NOACCESS
, SPR_NOACCESS
,
2775 &spr_read_generic
, &spr_write_generic
,
2777 /* XXX : not implemented */
2778 spr_register(env
, SPR_MPC_MI_TWC
, "MI_TWC",
2779 SPR_NOACCESS
, SPR_NOACCESS
,
2780 &spr_read_generic
, &spr_write_generic
,
2782 /* XXX : not implemented */
2783 spr_register(env
, SPR_MPC_MI_RPN
, "MI_RPN",
2784 SPR_NOACCESS
, SPR_NOACCESS
,
2785 &spr_read_generic
, &spr_write_generic
,
2787 /* XXX : not implemented */
2788 spr_register(env
, SPR_MPC_MI_DBCAM
, "MI_DBCAM",
2789 SPR_NOACCESS
, SPR_NOACCESS
,
2790 &spr_read_generic
, &spr_write_generic
,
2792 /* XXX : not implemented */
2793 spr_register(env
, SPR_MPC_MI_DBRAM0
, "MI_DBRAM0",
2794 SPR_NOACCESS
, SPR_NOACCESS
,
2795 &spr_read_generic
, &spr_write_generic
,
2797 /* XXX : not implemented */
2798 spr_register(env
, SPR_MPC_MI_DBRAM1
, "MI_DBRAM1",
2799 SPR_NOACCESS
, SPR_NOACCESS
,
2800 &spr_read_generic
, &spr_write_generic
,
2802 /* XXX : not implemented */
2803 spr_register(env
, SPR_MPC_MD_CTR
, "MD_CTR",
2804 SPR_NOACCESS
, SPR_NOACCESS
,
2805 &spr_read_generic
, &spr_write_generic
,
2807 /* XXX : not implemented */
2808 spr_register(env
, SPR_MPC_MD_CASID
, "MD_CASID",
2809 SPR_NOACCESS
, SPR_NOACCESS
,
2810 &spr_read_generic
, &spr_write_generic
,
2812 /* XXX : not implemented */
2813 spr_register(env
, SPR_MPC_MD_AP
, "MD_AP",
2814 SPR_NOACCESS
, SPR_NOACCESS
,
2815 &spr_read_generic
, &spr_write_generic
,
2817 /* XXX : not implemented */
2818 spr_register(env
, SPR_MPC_MD_EPN
, "MD_EPN",
2819 SPR_NOACCESS
, SPR_NOACCESS
,
2820 &spr_read_generic
, &spr_write_generic
,
2822 /* XXX : not implemented */
2823 spr_register(env
, SPR_MPC_MD_TWB
, "MD_TWB",
2824 SPR_NOACCESS
, SPR_NOACCESS
,
2825 &spr_read_generic
, &spr_write_generic
,
2827 /* XXX : not implemented */
2828 spr_register(env
, SPR_MPC_MD_TWC
, "MD_TWC",
2829 SPR_NOACCESS
, SPR_NOACCESS
,
2830 &spr_read_generic
, &spr_write_generic
,
2832 /* XXX : not implemented */
2833 spr_register(env
, SPR_MPC_MD_RPN
, "MD_RPN",
2834 SPR_NOACCESS
, SPR_NOACCESS
,
2835 &spr_read_generic
, &spr_write_generic
,
2837 /* XXX : not implemented */
2838 spr_register(env
, SPR_MPC_MD_TW
, "MD_TW",
2839 SPR_NOACCESS
, SPR_NOACCESS
,
2840 &spr_read_generic
, &spr_write_generic
,
2842 /* XXX : not implemented */
2843 spr_register(env
, SPR_MPC_MD_DBCAM
, "MD_DBCAM",
2844 SPR_NOACCESS
, SPR_NOACCESS
,
2845 &spr_read_generic
, &spr_write_generic
,
2847 /* XXX : not implemented */
2848 spr_register(env
, SPR_MPC_MD_DBRAM0
, "MD_DBRAM0",
2849 SPR_NOACCESS
, SPR_NOACCESS
,
2850 &spr_read_generic
, &spr_write_generic
,
2852 /* XXX : not implemented */
2853 spr_register(env
, SPR_MPC_MD_DBRAM1
, "MD_DBRAM1",
2854 SPR_NOACCESS
, SPR_NOACCESS
,
2855 &spr_read_generic
, &spr_write_generic
,
2860 * AMR => SPR 29 (Power 2.04)
2861 * CTRL => SPR 136 (Power 2.04)
2862 * CTRL => SPR 152 (Power 2.04)
2863 * SCOMC => SPR 276 (64 bits ?)
2864 * SCOMD => SPR 277 (64 bits ?)
2865 * TBU40 => SPR 286 (Power 2.04 hypv)
2866 * HSPRG0 => SPR 304 (Power 2.04 hypv)
2867 * HSPRG1 => SPR 305 (Power 2.04 hypv)
2868 * HDSISR => SPR 306 (Power 2.04 hypv)
2869 * HDAR => SPR 307 (Power 2.04 hypv)
2870 * PURR => SPR 309 (Power 2.04 hypv)
2871 * HDEC => SPR 310 (Power 2.04 hypv)
2872 * HIOR => SPR 311 (hypv)
2873 * RMOR => SPR 312 (970)
2874 * HRMOR => SPR 313 (Power 2.04 hypv)
2875 * HSRR0 => SPR 314 (Power 2.04 hypv)
2876 * HSRR1 => SPR 315 (Power 2.04 hypv)
2877 * LPIDR => SPR 317 (970)
2878 * EPR => SPR 702 (Power 2.04 emb)
2879 * perf => 768-783 (Power 2.04)
2880 * perf => 784-799 (Power 2.04)
2881 * PPR => SPR 896 (Power 2.04)
2882 * DABRX => 1015 (Power 2.04 hypv)
2883 * FPECR => SPR 1022 (?)
2884 * ... and more (thermal management, performance counters, ...)
2887 /*****************************************************************************/
2888 /* Exception vectors models */
2889 static void init_excp_4xx_real(CPUPPCState
*env
)
2891 #if !defined(CONFIG_USER_ONLY)
2892 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000100;
2893 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2894 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2895 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2896 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2897 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2898 env
->excp_vectors
[POWERPC_EXCP_PIT
] = 0x00001000;
2899 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00001010;
2900 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001020;
2901 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00002000;
2902 env
->ivor_mask
= 0x0000FFF0UL
;
2903 env
->ivpr_mask
= 0xFFFF0000UL
;
2904 /* Hardware reset vector */
2905 env
->hreset_vector
= 0xFFFFFFFCUL
;
2909 static void init_excp_4xx_softmmu(CPUPPCState
*env
)
2911 #if !defined(CONFIG_USER_ONLY)
2912 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000100;
2913 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2914 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2915 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2916 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2917 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2918 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2919 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2920 env
->excp_vectors
[POWERPC_EXCP_PIT
] = 0x00001000;
2921 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00001010;
2922 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001020;
2923 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00001100;
2924 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00001200;
2925 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00002000;
2926 env
->ivor_mask
= 0x0000FFF0UL
;
2927 env
->ivpr_mask
= 0xFFFF0000UL
;
2928 /* Hardware reset vector */
2929 env
->hreset_vector
= 0xFFFFFFFCUL
;
2933 static void init_excp_MPC5xx(CPUPPCState
*env
)
2935 #if !defined(CONFIG_USER_ONLY)
2936 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2937 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2938 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2939 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2940 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2941 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000900;
2942 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2943 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2944 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2945 env
->excp_vectors
[POWERPC_EXCP_FPA
] = 0x00000E00;
2946 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001000;
2947 env
->excp_vectors
[POWERPC_EXCP_DABR
] = 0x00001C00;
2948 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001C00;
2949 env
->excp_vectors
[POWERPC_EXCP_MEXTBR
] = 0x00001E00;
2950 env
->excp_vectors
[POWERPC_EXCP_NMEXTBR
] = 0x00001F00;
2951 env
->ivor_mask
= 0x0000FFF0UL
;
2952 env
->ivpr_mask
= 0xFFFF0000UL
;
2953 /* Hardware reset vector */
2954 env
->hreset_vector
= 0x00000100UL
;
2958 static void init_excp_MPC8xx(CPUPPCState
*env
)
2960 #if !defined(CONFIG_USER_ONLY)
2961 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2962 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2963 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2964 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2965 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2966 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2967 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2968 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000900;
2969 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
2970 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
2971 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
2972 env
->excp_vectors
[POWERPC_EXCP_FPA
] = 0x00000E00;
2973 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001000;
2974 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00001100;
2975 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00001200;
2976 env
->excp_vectors
[POWERPC_EXCP_ITLBE
] = 0x00001300;
2977 env
->excp_vectors
[POWERPC_EXCP_DTLBE
] = 0x00001400;
2978 env
->excp_vectors
[POWERPC_EXCP_DABR
] = 0x00001C00;
2979 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001C00;
2980 env
->excp_vectors
[POWERPC_EXCP_MEXTBR
] = 0x00001E00;
2981 env
->excp_vectors
[POWERPC_EXCP_NMEXTBR
] = 0x00001F00;
2982 env
->ivor_mask
= 0x0000FFF0UL
;
2983 env
->ivpr_mask
= 0xFFFF0000UL
;
2984 /* Hardware reset vector */
2985 env
->hreset_vector
= 0x00000100UL
;
2989 static void init_excp_G2(CPUPPCState
*env
)
2991 #if !defined(CONFIG_USER_ONLY)
2992 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
2993 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
2994 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
2995 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
2996 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
2997 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
2998 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
2999 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3000 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3001 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000A00;
3002 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3003 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3004 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3005 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3006 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3007 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3008 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3009 /* Hardware reset vector */
3010 env
->hreset_vector
= 0x00000100UL
;
3014 static void init_excp_e200(CPUPPCState
*env
, target_ulong ivpr_mask
)
3016 #if !defined(CONFIG_USER_ONLY)
3017 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000FFC;
3018 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000000;
3019 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000000;
3020 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000000;
3021 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000000;
3022 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000000;
3023 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000000;
3024 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000000;
3025 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000000;
3026 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000000;
3027 env
->excp_vectors
[POWERPC_EXCP_APU
] = 0x00000000;
3028 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000000;
3029 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00000000;
3030 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00000000;
3031 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00000000;
3032 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00000000;
3033 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00000000;
3034 env
->excp_vectors
[POWERPC_EXCP_SPEU
] = 0x00000000;
3035 env
->excp_vectors
[POWERPC_EXCP_EFPDI
] = 0x00000000;
3036 env
->excp_vectors
[POWERPC_EXCP_EFPRI
] = 0x00000000;
3037 env
->ivor_mask
= 0x0000FFF7UL
;
3038 env
->ivpr_mask
= ivpr_mask
;
3039 /* Hardware reset vector */
3040 env
->hreset_vector
= 0xFFFFFFFCUL
;
3044 static void init_excp_BookE(CPUPPCState
*env
)
3046 #if !defined(CONFIG_USER_ONLY)
3047 env
->excp_vectors
[POWERPC_EXCP_CRITICAL
] = 0x00000000;
3048 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000000;
3049 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000000;
3050 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000000;
3051 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000000;
3052 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000000;
3053 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000000;
3054 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000000;
3055 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000000;
3056 env
->excp_vectors
[POWERPC_EXCP_APU
] = 0x00000000;
3057 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000000;
3058 env
->excp_vectors
[POWERPC_EXCP_FIT
] = 0x00000000;
3059 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00000000;
3060 env
->excp_vectors
[POWERPC_EXCP_DTLB
] = 0x00000000;
3061 env
->excp_vectors
[POWERPC_EXCP_ITLB
] = 0x00000000;
3062 env
->excp_vectors
[POWERPC_EXCP_DEBUG
] = 0x00000000;
3063 env
->ivor_mask
= 0x0000FFF0UL
;
3064 env
->ivpr_mask
= 0xFFFF0000UL
;
3065 /* Hardware reset vector */
3066 env
->hreset_vector
= 0xFFFFFFFCUL
;
3070 static void init_excp_601(CPUPPCState
*env
)
3072 #if !defined(CONFIG_USER_ONLY)
3073 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3074 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3075 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3076 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3077 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3078 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3079 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3080 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3081 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3082 env
->excp_vectors
[POWERPC_EXCP_IO
] = 0x00000A00;
3083 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3084 env
->excp_vectors
[POWERPC_EXCP_RUNM
] = 0x00002000;
3085 /* Hardware reset vector */
3086 env
->hreset_vector
= 0x00000100UL
;
3090 static void init_excp_602(CPUPPCState
*env
)
3092 #if !defined(CONFIG_USER_ONLY)
3093 /* XXX: exception prefix has a special behavior on 602 */
3094 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3095 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3096 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3097 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3098 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3099 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3100 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3101 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3102 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3103 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3104 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3105 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3106 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3107 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3108 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3109 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3110 env
->excp_vectors
[POWERPC_EXCP_WDT
] = 0x00001500;
3111 env
->excp_vectors
[POWERPC_EXCP_EMUL
] = 0x00001600;
3112 /* Hardware reset vector */
3113 env
->hreset_vector
= 0x00000100UL
;
3117 static void init_excp_603(CPUPPCState
*env
)
3119 #if !defined(CONFIG_USER_ONLY)
3120 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3121 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3122 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3123 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3124 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3125 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3126 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3127 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3128 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3129 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3130 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3131 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3132 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3133 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3134 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3135 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3136 /* Hardware reset vector */
3137 env
->hreset_vector
= 0x00000100UL
;
3141 static void init_excp_604(CPUPPCState
*env
)
3143 #if !defined(CONFIG_USER_ONLY)
3144 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3145 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3146 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3147 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3148 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3149 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3150 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3151 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3152 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3153 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3154 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3155 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3156 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3157 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3158 /* Hardware reset vector */
3159 env
->hreset_vector
= 0x00000100UL
;
3163 static void init_excp_7x0(CPUPPCState
*env
)
3165 #if !defined(CONFIG_USER_ONLY)
3166 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3167 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3168 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3169 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3170 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3171 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3172 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3173 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3174 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3175 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3176 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3177 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3178 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3179 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3180 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3181 /* Hardware reset vector */
3182 env
->hreset_vector
= 0x00000100UL
;
3186 static void init_excp_750cl(CPUPPCState
*env
)
3188 #if !defined(CONFIG_USER_ONLY)
3189 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3190 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3191 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3192 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3193 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3194 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3195 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3196 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3197 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3198 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3199 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3200 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3201 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3202 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3203 /* Hardware reset vector */
3204 env
->hreset_vector
= 0x00000100UL
;
3208 static void init_excp_750cx(CPUPPCState
*env
)
3210 #if !defined(CONFIG_USER_ONLY)
3211 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3212 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3213 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3214 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3215 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3216 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3217 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3218 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3219 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3220 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3221 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3222 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3223 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3224 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3225 /* Hardware reset vector */
3226 env
->hreset_vector
= 0x00000100UL
;
3230 /* XXX: Check if this is correct */
3231 static void init_excp_7x5(CPUPPCState
*env
)
3233 #if !defined(CONFIG_USER_ONLY)
3234 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3235 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3236 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3237 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3238 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3239 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3240 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3241 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3242 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3243 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3244 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3245 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3246 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3247 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3248 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3249 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3250 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3251 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3252 /* Hardware reset vector */
3253 env
->hreset_vector
= 0x00000100UL
;
3257 static void init_excp_7400(CPUPPCState
*env
)
3259 #if !defined(CONFIG_USER_ONLY)
3260 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3261 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3262 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3263 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3264 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3265 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3266 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3267 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3268 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3269 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3270 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3271 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3272 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3273 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3274 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3275 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001600;
3276 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001700;
3277 /* Hardware reset vector */
3278 env
->hreset_vector
= 0x00000100UL
;
3282 static void init_excp_7450(CPUPPCState
*env
)
3284 #if !defined(CONFIG_USER_ONLY)
3285 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3286 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3287 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3288 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3289 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3290 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3291 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3292 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3293 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3294 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3295 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3296 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3297 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3298 env
->excp_vectors
[POWERPC_EXCP_IFTLB
] = 0x00001000;
3299 env
->excp_vectors
[POWERPC_EXCP_DLTLB
] = 0x00001100;
3300 env
->excp_vectors
[POWERPC_EXCP_DSTLB
] = 0x00001200;
3301 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3302 env
->excp_vectors
[POWERPC_EXCP_SMI
] = 0x00001400;
3303 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001600;
3304 /* Hardware reset vector */
3305 env
->hreset_vector
= 0x00000100UL
;
3309 #if defined(TARGET_PPC64)
3310 static void init_excp_970(CPUPPCState
*env
)
3312 #if !defined(CONFIG_USER_ONLY)
3313 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3314 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3315 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3316 env
->excp_vectors
[POWERPC_EXCP_DSEG
] = 0x00000380;
3317 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3318 env
->excp_vectors
[POWERPC_EXCP_ISEG
] = 0x00000480;
3319 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3320 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3321 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3322 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3323 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3324 env
->excp_vectors
[POWERPC_EXCP_HDECR
] = 0x00000980;
3325 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3326 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3327 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3328 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3329 env
->excp_vectors
[POWERPC_EXCP_IABR
] = 0x00001300;
3330 env
->excp_vectors
[POWERPC_EXCP_MAINT
] = 0x00001600;
3331 env
->excp_vectors
[POWERPC_EXCP_VPUA
] = 0x00001700;
3332 env
->excp_vectors
[POWERPC_EXCP_THERM
] = 0x00001800;
3333 /* Hardware reset vector */
3334 env
->hreset_vector
= 0x0000000000000100ULL
;
3338 static void init_excp_POWER7(CPUPPCState
*env
)
3340 #if !defined(CONFIG_USER_ONLY)
3341 env
->excp_vectors
[POWERPC_EXCP_RESET
] = 0x00000100;
3342 env
->excp_vectors
[POWERPC_EXCP_MCHECK
] = 0x00000200;
3343 env
->excp_vectors
[POWERPC_EXCP_DSI
] = 0x00000300;
3344 env
->excp_vectors
[POWERPC_EXCP_DSEG
] = 0x00000380;
3345 env
->excp_vectors
[POWERPC_EXCP_ISI
] = 0x00000400;
3346 env
->excp_vectors
[POWERPC_EXCP_ISEG
] = 0x00000480;
3347 env
->excp_vectors
[POWERPC_EXCP_EXTERNAL
] = 0x00000500;
3348 env
->excp_vectors
[POWERPC_EXCP_ALIGN
] = 0x00000600;
3349 env
->excp_vectors
[POWERPC_EXCP_PROGRAM
] = 0x00000700;
3350 env
->excp_vectors
[POWERPC_EXCP_FPU
] = 0x00000800;
3351 env
->excp_vectors
[POWERPC_EXCP_DECR
] = 0x00000900;
3352 env
->excp_vectors
[POWERPC_EXCP_HDECR
] = 0x00000980;
3353 env
->excp_vectors
[POWERPC_EXCP_SYSCALL
] = 0x00000C00;
3354 env
->excp_vectors
[POWERPC_EXCP_TRACE
] = 0x00000D00;
3355 env
->excp_vectors
[POWERPC_EXCP_HDSI
] = 0x00000E00;
3356 env
->excp_vectors
[POWERPC_EXCP_HISI
] = 0x00000E20;
3357 env
->excp_vectors
[POWERPC_EXCP_HV_EMU
] = 0x00000E40;
3358 env
->excp_vectors
[POWERPC_EXCP_HV_MAINT
] = 0x00000E60;
3359 env
->excp_vectors
[POWERPC_EXCP_PERFM
] = 0x00000F00;
3360 env
->excp_vectors
[POWERPC_EXCP_VPU
] = 0x00000F20;
3361 env
->excp_vectors
[POWERPC_EXCP_VSXU
] = 0x00000F40;
3362 /* Hardware reset vector */
3363 env
->hreset_vector
= 0x0000000000000100ULL
;
3367 static void init_excp_POWER8(CPUPPCState
*env
)
3369 init_excp_POWER7(env
);
3371 #if !defined(CONFIG_USER_ONLY)
3372 env
->excp_vectors
[POWERPC_EXCP_SDOOR
] = 0x00000A00;
3373 env
->excp_vectors
[POWERPC_EXCP_FU
] = 0x00000F60;
3374 env
->excp_vectors
[POWERPC_EXCP_HV_FU
] = 0x00000F80;
3375 env
->excp_vectors
[POWERPC_EXCP_SDOOR_HV
] = 0x00000E80;
3379 static void init_excp_POWER9(CPUPPCState
*env
)
3381 init_excp_POWER8(env
);
3383 #if !defined(CONFIG_USER_ONLY)
3384 env
->excp_vectors
[POWERPC_EXCP_HVIRT
] = 0x00000EA0;
3388 static void init_excp_POWER10(CPUPPCState
*env
)
3390 init_excp_POWER9(env
);
3395 /*****************************************************************************/
3396 /* Power management enable checks */
3397 static int check_pow_none(CPUPPCState
*env
)
3402 static int check_pow_nocheck(CPUPPCState
*env
)
3407 static int check_pow_hid0(CPUPPCState
*env
)
3409 if (env
->spr
[SPR_HID0
] & 0x00E00000) {
3416 static int check_pow_hid0_74xx(CPUPPCState
*env
)
3418 if (env
->spr
[SPR_HID0
] & 0x00600000) {
3425 static bool ppc_cpu_interrupts_big_endian_always(PowerPCCPU
*cpu
)
3431 static bool ppc_cpu_interrupts_big_endian_lpcr(PowerPCCPU
*cpu
)
3433 return !(cpu
->env
.spr
[SPR_LPCR
] & LPCR_ILE
);
3437 /*****************************************************************************/
3438 /* PowerPC implementations definitions */
3440 #define POWERPC_FAMILY(_name) \
3442 glue(glue(ppc_, _name), _cpu_family_class_init)(ObjectClass *, void *); \
3444 static const TypeInfo \
3445 glue(glue(ppc_, _name), _cpu_family_type_info) = { \
3446 .name = stringify(_name) "-family-" TYPE_POWERPC_CPU, \
3447 .parent = TYPE_POWERPC_CPU, \
3449 .class_init = glue(glue(ppc_, _name), _cpu_family_class_init), \
3452 static void glue(glue(ppc_, _name), _cpu_family_register_types)(void) \
3454 type_register_static( \
3455 &glue(glue(ppc_, _name), _cpu_family_type_info)); \
3458 type_init(glue(glue(ppc_, _name), _cpu_family_register_types)) \
3460 static void glue(glue(ppc_, _name), _cpu_family_class_init)
3462 static void init_proc_401(CPUPPCState
*env
)
3465 gen_spr_401_403(env
);
3467 init_excp_4xx_real(env
);
3468 env
->dcache_line_size
= 32;
3469 env
->icache_line_size
= 32;
3470 /* Allocate hardware IRQ controller */
3471 ppc40x_irq_init(env_archcpu(env
));
3473 SET_FIT_PERIOD(12, 16, 20, 24);
3474 SET_WDT_PERIOD(16, 20, 24, 28);
3477 POWERPC_FAMILY(401)(ObjectClass
*oc
, void *data
)
3479 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3480 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3482 dc
->desc
= "PowerPC 401";
3483 pcc
->init_proc
= init_proc_401
;
3484 pcc
->check_pow
= check_pow_nocheck
;
3485 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3486 PPC_WRTEE
| PPC_DCR
|
3487 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3489 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3490 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3491 pcc
->msr_mask
= (1ull << MSR_KEY
) |
3500 pcc
->mmu_model
= POWERPC_MMU_REAL
;
3501 pcc
->excp_model
= POWERPC_EXCP_40x
;
3502 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3503 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3504 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3505 POWERPC_FLAG_BUS_CLK
;
3508 static void init_proc_401x2(CPUPPCState
*env
)
3511 gen_spr_401_403(env
);
3513 gen_spr_compress(env
);
3514 /* Memory management */
3515 #if !defined(CONFIG_USER_ONLY)
3519 env
->tlb_type
= TLB_EMB
;
3521 init_excp_4xx_softmmu(env
);
3522 env
->dcache_line_size
= 32;
3523 env
->icache_line_size
= 32;
3524 /* Allocate hardware IRQ controller */
3525 ppc40x_irq_init(env_archcpu(env
));
3527 SET_FIT_PERIOD(12, 16, 20, 24);
3528 SET_WDT_PERIOD(16, 20, 24, 28);
3531 POWERPC_FAMILY(401x2
)(ObjectClass
*oc
, void *data
)
3533 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3534 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3536 dc
->desc
= "PowerPC 401x2";
3537 pcc
->init_proc
= init_proc_401x2
;
3538 pcc
->check_pow
= check_pow_nocheck
;
3539 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3540 PPC_DCR
| PPC_WRTEE
|
3541 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3542 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3543 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3544 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3545 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3546 pcc
->msr_mask
= (1ull << 20) |
3558 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3559 pcc
->excp_model
= POWERPC_EXCP_40x
;
3560 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3561 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3562 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3563 POWERPC_FLAG_BUS_CLK
;
3566 static void init_proc_401x3(CPUPPCState
*env
)
3569 gen_spr_401_403(env
);
3572 gen_spr_compress(env
);
3573 init_excp_4xx_softmmu(env
);
3574 env
->dcache_line_size
= 32;
3575 env
->icache_line_size
= 32;
3576 /* Allocate hardware IRQ controller */
3577 ppc40x_irq_init(env_archcpu(env
));
3579 SET_FIT_PERIOD(12, 16, 20, 24);
3580 SET_WDT_PERIOD(16, 20, 24, 28);
3583 POWERPC_FAMILY(401x3
)(ObjectClass
*oc
, void *data
)
3585 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3586 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3588 dc
->desc
= "PowerPC 401x3";
3589 pcc
->init_proc
= init_proc_401x3
;
3590 pcc
->check_pow
= check_pow_nocheck
;
3591 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3592 PPC_DCR
| PPC_WRTEE
|
3593 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3594 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3595 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3596 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3597 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3598 pcc
->msr_mask
= (1ull << 20) |
3611 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3612 pcc
->excp_model
= POWERPC_EXCP_40x
;
3613 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3614 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3615 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3616 POWERPC_FLAG_BUS_CLK
;
3619 static void init_proc_IOP480(CPUPPCState
*env
)
3622 gen_spr_401_403(env
);
3624 gen_spr_compress(env
);
3625 /* Memory management */
3626 #if !defined(CONFIG_USER_ONLY)
3630 env
->tlb_type
= TLB_EMB
;
3632 init_excp_4xx_softmmu(env
);
3633 env
->dcache_line_size
= 32;
3634 env
->icache_line_size
= 32;
3635 /* Allocate hardware IRQ controller */
3636 ppc40x_irq_init(env_archcpu(env
));
3638 SET_FIT_PERIOD(8, 12, 16, 20);
3639 SET_WDT_PERIOD(16, 20, 24, 28);
3642 POWERPC_FAMILY(IOP480
)(ObjectClass
*oc
, void *data
)
3644 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3645 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3647 dc
->desc
= "IOP480";
3648 pcc
->init_proc
= init_proc_IOP480
;
3649 pcc
->check_pow
= check_pow_nocheck
;
3650 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3651 PPC_DCR
| PPC_WRTEE
|
3652 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3653 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3654 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3655 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3656 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3657 pcc
->msr_mask
= (1ull << 20) |
3669 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3670 pcc
->excp_model
= POWERPC_EXCP_40x
;
3671 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3672 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3673 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
3674 POWERPC_FLAG_BUS_CLK
;
3677 static void init_proc_403(CPUPPCState
*env
)
3680 gen_spr_401_403(env
);
3682 gen_spr_403_real(env
);
3683 init_excp_4xx_real(env
);
3684 env
->dcache_line_size
= 32;
3685 env
->icache_line_size
= 32;
3686 /* Allocate hardware IRQ controller */
3687 ppc40x_irq_init(env_archcpu(env
));
3689 SET_FIT_PERIOD(8, 12, 16, 20);
3690 SET_WDT_PERIOD(16, 20, 24, 28);
3693 POWERPC_FAMILY(403)(ObjectClass
*oc
, void *data
)
3695 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3696 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3698 dc
->desc
= "PowerPC 403";
3699 pcc
->init_proc
= init_proc_403
;
3700 pcc
->check_pow
= check_pow_nocheck
;
3701 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3702 PPC_DCR
| PPC_WRTEE
|
3703 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3705 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3706 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3707 pcc
->msr_mask
= (1ull << MSR_POW
) |
3716 pcc
->mmu_model
= POWERPC_MMU_REAL
;
3717 pcc
->excp_model
= POWERPC_EXCP_40x
;
3718 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3719 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3720 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_PX
|
3721 POWERPC_FLAG_BUS_CLK
;
3724 static void init_proc_403GCX(CPUPPCState
*env
)
3727 gen_spr_401_403(env
);
3729 gen_spr_403_real(env
);
3730 gen_spr_403_mmu(env
);
3731 /* Bus access control */
3732 /* not emulated, as QEMU never does speculative access */
3733 spr_register(env
, SPR_40x_SGR
, "SGR",
3734 SPR_NOACCESS
, SPR_NOACCESS
,
3735 &spr_read_generic
, &spr_write_generic
,
3737 /* not emulated, as QEMU do not emulate caches */
3738 spr_register(env
, SPR_40x_DCWR
, "DCWR",
3739 SPR_NOACCESS
, SPR_NOACCESS
,
3740 &spr_read_generic
, &spr_write_generic
,
3742 /* Memory management */
3743 #if !defined(CONFIG_USER_ONLY)
3747 env
->tlb_type
= TLB_EMB
;
3749 init_excp_4xx_softmmu(env
);
3750 env
->dcache_line_size
= 32;
3751 env
->icache_line_size
= 32;
3752 /* Allocate hardware IRQ controller */
3753 ppc40x_irq_init(env_archcpu(env
));
3755 SET_FIT_PERIOD(8, 12, 16, 20);
3756 SET_WDT_PERIOD(16, 20, 24, 28);
3759 POWERPC_FAMILY(403GCX
)(ObjectClass
*oc
, void *data
)
3761 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3762 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3764 dc
->desc
= "PowerPC 403 GCX";
3765 pcc
->init_proc
= init_proc_403GCX
;
3766 pcc
->check_pow
= check_pow_nocheck
;
3767 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3768 PPC_DCR
| PPC_WRTEE
|
3769 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3771 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3772 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3773 PPC_4xx_COMMON
| PPC_40x_EXCP
;
3774 pcc
->msr_mask
= (1ull << MSR_POW
) |
3783 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx_Z
;
3784 pcc
->excp_model
= POWERPC_EXCP_40x
;
3785 pcc
->bus_model
= PPC_FLAGS_INPUT_401
;
3786 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3787 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_PX
|
3788 POWERPC_FLAG_BUS_CLK
;
3791 static void init_proc_405(CPUPPCState
*env
)
3797 /* Bus access control */
3798 /* not emulated, as QEMU never does speculative access */
3799 spr_register(env
, SPR_40x_SGR
, "SGR",
3800 SPR_NOACCESS
, SPR_NOACCESS
,
3801 &spr_read_generic
, &spr_write_generic
,
3803 /* not emulated, as QEMU do not emulate caches */
3804 spr_register(env
, SPR_40x_DCWR
, "DCWR",
3805 SPR_NOACCESS
, SPR_NOACCESS
,
3806 &spr_read_generic
, &spr_write_generic
,
3808 /* Memory management */
3809 #if !defined(CONFIG_USER_ONLY)
3813 env
->tlb_type
= TLB_EMB
;
3815 init_excp_4xx_softmmu(env
);
3816 env
->dcache_line_size
= 32;
3817 env
->icache_line_size
= 32;
3818 /* Allocate hardware IRQ controller */
3819 ppc40x_irq_init(env_archcpu(env
));
3821 SET_FIT_PERIOD(8, 12, 16, 20);
3822 SET_WDT_PERIOD(16, 20, 24, 28);
3825 POWERPC_FAMILY(405)(ObjectClass
*oc
, void *data
)
3827 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3828 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3830 dc
->desc
= "PowerPC 405";
3831 pcc
->init_proc
= init_proc_405
;
3832 pcc
->check_pow
= check_pow_nocheck
;
3833 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
3834 PPC_DCR
| PPC_WRTEE
|
3835 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_40x_ICBT
|
3836 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3837 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
3838 PPC_40x_TLB
| PPC_MEM_TLBIA
| PPC_MEM_TLBSYNC
|
3839 PPC_4xx_COMMON
| PPC_405_MAC
| PPC_40x_EXCP
;
3840 pcc
->msr_mask
= (1ull << MSR_POW
) |
3849 pcc
->mmu_model
= POWERPC_MMU_SOFT_4xx
;
3850 pcc
->excp_model
= POWERPC_EXCP_40x
;
3851 pcc
->bus_model
= PPC_FLAGS_INPUT_405
;
3852 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3853 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3854 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3857 static void init_proc_440EP(CPUPPCState
*env
)
3861 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
3863 gen_spr_usprgh(env
);
3864 /* Processor identification */
3865 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
3866 SPR_NOACCESS
, SPR_NOACCESS
,
3867 &spr_read_generic
, &spr_write_pir
,
3869 /* XXX : not implemented */
3870 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
3871 SPR_NOACCESS
, SPR_NOACCESS
,
3872 &spr_read_generic
, &spr_write_generic
,
3874 /* XXX : not implemented */
3875 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
3876 SPR_NOACCESS
, SPR_NOACCESS
,
3877 &spr_read_generic
, &spr_write_generic
,
3879 /* XXX : not implemented */
3880 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
3881 SPR_NOACCESS
, SPR_NOACCESS
,
3882 &spr_read_generic
, &spr_write_generic
,
3884 /* XXX : not implemented */
3885 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
3886 SPR_NOACCESS
, SPR_NOACCESS
,
3887 &spr_read_generic
, &spr_write_generic
,
3889 /* XXX : not implemented */
3890 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
3891 SPR_NOACCESS
, SPR_NOACCESS
,
3892 &spr_read_generic
, &spr_write_generic
,
3894 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
3895 SPR_NOACCESS
, SPR_NOACCESS
,
3896 &spr_read_generic
, &spr_write_generic
,
3898 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
3899 SPR_NOACCESS
, SPR_NOACCESS
,
3900 &spr_read_generic
, &spr_write_generic
,
3902 /* XXX : not implemented */
3903 spr_register(env
, SPR_440_CCR1
, "CCR1",
3904 SPR_NOACCESS
, SPR_NOACCESS
,
3905 &spr_read_generic
, &spr_write_generic
,
3907 /* Memory management */
3908 #if !defined(CONFIG_USER_ONLY)
3912 env
->tlb_type
= TLB_EMB
;
3914 init_excp_BookE(env
);
3915 env
->dcache_line_size
= 32;
3916 env
->icache_line_size
= 32;
3917 ppc40x_irq_init(env_archcpu(env
));
3919 SET_FIT_PERIOD(12, 16, 20, 24);
3920 SET_WDT_PERIOD(20, 24, 28, 32);
3923 POWERPC_FAMILY(440EP
)(ObjectClass
*oc
, void *data
)
3925 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3926 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3928 dc
->desc
= "PowerPC 440 EP";
3929 pcc
->init_proc
= init_proc_440EP
;
3930 pcc
->check_pow
= check_pow_nocheck
;
3931 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3932 PPC_FLOAT
| PPC_FLOAT_FRES
| PPC_FLOAT_FSEL
|
3933 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
3935 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
3936 PPC_CACHE
| PPC_CACHE_ICBI
|
3937 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3938 PPC_MEM_TLBSYNC
| PPC_MFTB
|
3939 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3941 pcc
->msr_mask
= (1ull << MSR_POW
) |
3953 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3954 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3955 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3956 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3957 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3958 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3961 POWERPC_FAMILY(460EX
)(ObjectClass
*oc
, void *data
)
3963 DeviceClass
*dc
= DEVICE_CLASS(oc
);
3964 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
3966 dc
->desc
= "PowerPC 460 EX";
3967 pcc
->init_proc
= init_proc_440EP
;
3968 pcc
->check_pow
= check_pow_nocheck
;
3969 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
3970 PPC_FLOAT
| PPC_FLOAT_FRES
| PPC_FLOAT_FSEL
|
3971 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
3973 PPC_DCR
| PPC_DCRX
| PPC_WRTEE
| PPC_RFMCI
|
3974 PPC_CACHE
| PPC_CACHE_ICBI
|
3975 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
3976 PPC_MEM_TLBSYNC
| PPC_MFTB
|
3977 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
3979 pcc
->msr_mask
= (1ull << MSR_POW
) |
3991 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
3992 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
3993 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
3994 pcc
->bfd_mach
= bfd_mach_ppc_403
;
3995 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
3996 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
3999 static void init_proc_440GP(CPUPPCState
*env
)
4003 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
4005 gen_spr_usprgh(env
);
4006 /* Processor identification */
4007 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4008 SPR_NOACCESS
, SPR_NOACCESS
,
4009 &spr_read_generic
, &spr_write_pir
,
4011 /* XXX : not implemented */
4012 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4013 SPR_NOACCESS
, SPR_NOACCESS
,
4014 &spr_read_generic
, &spr_write_generic
,
4016 /* XXX : not implemented */
4017 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4018 SPR_NOACCESS
, SPR_NOACCESS
,
4019 &spr_read_generic
, &spr_write_generic
,
4021 /* XXX : not implemented */
4022 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
4023 SPR_NOACCESS
, SPR_NOACCESS
,
4024 &spr_read_generic
, &spr_write_generic
,
4026 /* XXX : not implemented */
4027 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
4028 SPR_NOACCESS
, SPR_NOACCESS
,
4029 &spr_read_generic
, &spr_write_generic
,
4031 /* Memory management */
4032 #if !defined(CONFIG_USER_ONLY)
4036 env
->tlb_type
= TLB_EMB
;
4038 init_excp_BookE(env
);
4039 env
->dcache_line_size
= 32;
4040 env
->icache_line_size
= 32;
4041 /* XXX: TODO: allocate internal IRQ controller */
4043 SET_FIT_PERIOD(12, 16, 20, 24);
4044 SET_WDT_PERIOD(20, 24, 28, 32);
4047 POWERPC_FAMILY(440GP
)(ObjectClass
*oc
, void *data
)
4049 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4050 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4052 dc
->desc
= "PowerPC 440 GP";
4053 pcc
->init_proc
= init_proc_440GP
;
4054 pcc
->check_pow
= check_pow_nocheck
;
4055 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4056 PPC_DCR
| PPC_DCRX
| PPC_WRTEE
| PPC_MFAPIDI
|
4057 PPC_CACHE
| PPC_CACHE_ICBI
|
4058 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4059 PPC_MEM_TLBSYNC
| PPC_TLBIVA
| PPC_MFTB
|
4060 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4062 pcc
->msr_mask
= (1ull << MSR_POW
) |
4074 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4075 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4076 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4077 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4078 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4079 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4082 static void init_proc_440x4(CPUPPCState
*env
)
4086 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
4088 gen_spr_usprgh(env
);
4089 /* Processor identification */
4090 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4091 SPR_NOACCESS
, SPR_NOACCESS
,
4092 &spr_read_generic
, &spr_write_pir
,
4094 /* XXX : not implemented */
4095 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4096 SPR_NOACCESS
, SPR_NOACCESS
,
4097 &spr_read_generic
, &spr_write_generic
,
4099 /* XXX : not implemented */
4100 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4101 SPR_NOACCESS
, SPR_NOACCESS
,
4102 &spr_read_generic
, &spr_write_generic
,
4104 /* XXX : not implemented */
4105 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
4106 SPR_NOACCESS
, SPR_NOACCESS
,
4107 &spr_read_generic
, &spr_write_generic
,
4109 /* XXX : not implemented */
4110 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
4111 SPR_NOACCESS
, SPR_NOACCESS
,
4112 &spr_read_generic
, &spr_write_generic
,
4114 /* Memory management */
4115 #if !defined(CONFIG_USER_ONLY)
4119 env
->tlb_type
= TLB_EMB
;
4121 init_excp_BookE(env
);
4122 env
->dcache_line_size
= 32;
4123 env
->icache_line_size
= 32;
4124 /* XXX: TODO: allocate internal IRQ controller */
4126 SET_FIT_PERIOD(12, 16, 20, 24);
4127 SET_WDT_PERIOD(20, 24, 28, 32);
4130 POWERPC_FAMILY(440x4
)(ObjectClass
*oc
, void *data
)
4132 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4133 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4135 dc
->desc
= "PowerPC 440x4";
4136 pcc
->init_proc
= init_proc_440x4
;
4137 pcc
->check_pow
= check_pow_nocheck
;
4138 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4139 PPC_DCR
| PPC_WRTEE
|
4140 PPC_CACHE
| PPC_CACHE_ICBI
|
4141 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4142 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4143 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4145 pcc
->msr_mask
= (1ull << MSR_POW
) |
4157 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4158 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4159 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4160 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4161 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4162 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4165 static void init_proc_440x5(CPUPPCState
*env
)
4169 gen_spr_BookE(env
, 0x000000000000FFFFULL
);
4171 gen_spr_usprgh(env
);
4172 /* Processor identification */
4173 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4174 SPR_NOACCESS
, SPR_NOACCESS
,
4175 &spr_read_generic
, &spr_write_pir
,
4177 /* XXX : not implemented */
4178 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4179 SPR_NOACCESS
, SPR_NOACCESS
,
4180 &spr_read_generic
, &spr_write_generic
,
4182 /* XXX : not implemented */
4183 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4184 SPR_NOACCESS
, SPR_NOACCESS
,
4185 &spr_read_generic
, &spr_write_generic
,
4187 /* XXX : not implemented */
4188 spr_register(env
, SPR_BOOKE_DVC1
, "DVC1",
4189 SPR_NOACCESS
, SPR_NOACCESS
,
4190 &spr_read_generic
, &spr_write_generic
,
4192 /* XXX : not implemented */
4193 spr_register(env
, SPR_BOOKE_DVC2
, "DVC2",
4194 SPR_NOACCESS
, SPR_NOACCESS
,
4195 &spr_read_generic
, &spr_write_generic
,
4197 /* XXX : not implemented */
4198 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
4199 SPR_NOACCESS
, SPR_NOACCESS
,
4200 &spr_read_generic
, &spr_write_generic
,
4202 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
4203 SPR_NOACCESS
, SPR_NOACCESS
,
4204 &spr_read_generic
, &spr_write_generic
,
4206 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
4207 SPR_NOACCESS
, SPR_NOACCESS
,
4208 &spr_read_generic
, &spr_write_generic
,
4210 /* XXX : not implemented */
4211 spr_register(env
, SPR_440_CCR1
, "CCR1",
4212 SPR_NOACCESS
, SPR_NOACCESS
,
4213 &spr_read_generic
, &spr_write_generic
,
4215 /* Memory management */
4216 #if !defined(CONFIG_USER_ONLY)
4220 env
->tlb_type
= TLB_EMB
;
4222 init_excp_BookE(env
);
4223 env
->dcache_line_size
= 32;
4224 env
->icache_line_size
= 32;
4225 ppc40x_irq_init(env_archcpu(env
));
4227 SET_FIT_PERIOD(12, 16, 20, 24);
4228 SET_WDT_PERIOD(20, 24, 28, 32);
4231 POWERPC_FAMILY(440x5
)(ObjectClass
*oc
, void *data
)
4233 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4234 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4236 dc
->desc
= "PowerPC 440x5";
4237 pcc
->init_proc
= init_proc_440x5
;
4238 pcc
->check_pow
= check_pow_nocheck
;
4239 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4240 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
4241 PPC_CACHE
| PPC_CACHE_ICBI
|
4242 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4243 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4244 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4246 pcc
->msr_mask
= (1ull << MSR_POW
) |
4258 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4259 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4260 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4261 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4262 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4263 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4266 POWERPC_FAMILY(440x5wDFPU
)(ObjectClass
*oc
, void *data
)
4268 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4269 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4271 dc
->desc
= "PowerPC 440x5 with double precision FPU";
4272 pcc
->init_proc
= init_proc_440x5
;
4273 pcc
->check_pow
= check_pow_nocheck
;
4274 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4275 PPC_FLOAT
| PPC_FLOAT_FSQRT
|
4277 PPC_DCR
| PPC_WRTEE
| PPC_RFMCI
|
4278 PPC_CACHE
| PPC_CACHE_ICBI
|
4279 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4280 PPC_MEM_TLBSYNC
| PPC_MFTB
|
4281 PPC_BOOKE
| PPC_4xx_COMMON
| PPC_405_MAC
|
4283 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
4284 pcc
->msr_mask
= (1ull << MSR_POW
) |
4296 pcc
->mmu_model
= POWERPC_MMU_BOOKE
;
4297 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4298 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4299 pcc
->bfd_mach
= bfd_mach_ppc_403
;
4300 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DWE
|
4301 POWERPC_FLAG_DE
| POWERPC_FLAG_BUS_CLK
;
4304 static void init_proc_MPC5xx(CPUPPCState
*env
)
4308 gen_spr_5xx_8xx(env
);
4310 init_excp_MPC5xx(env
);
4311 env
->dcache_line_size
= 32;
4312 env
->icache_line_size
= 32;
4313 /* XXX: TODO: allocate internal IRQ controller */
4316 POWERPC_FAMILY(MPC5xx
)(ObjectClass
*oc
, void *data
)
4318 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4319 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4321 dc
->desc
= "Freescale 5xx cores (aka RCPU)";
4322 pcc
->init_proc
= init_proc_MPC5xx
;
4323 pcc
->check_pow
= check_pow_none
;
4324 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4325 PPC_MEM_EIEIO
| PPC_MEM_SYNC
|
4326 PPC_CACHE_ICBI
| PPC_FLOAT
| PPC_FLOAT_STFIWX
|
4328 pcc
->msr_mask
= (1ull << MSR_ILE
) |
4340 pcc
->mmu_model
= POWERPC_MMU_REAL
;
4341 pcc
->excp_model
= POWERPC_EXCP_603
;
4342 pcc
->bus_model
= PPC_FLAGS_INPUT_RCPU
;
4343 pcc
->bfd_mach
= bfd_mach_ppc_505
;
4344 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
4345 POWERPC_FLAG_BUS_CLK
;
4348 static void init_proc_MPC8xx(CPUPPCState
*env
)
4352 gen_spr_5xx_8xx(env
);
4354 init_excp_MPC8xx(env
);
4355 env
->dcache_line_size
= 32;
4356 env
->icache_line_size
= 32;
4357 /* XXX: TODO: allocate internal IRQ controller */
4360 POWERPC_FAMILY(MPC8xx
)(ObjectClass
*oc
, void *data
)
4362 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4363 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4365 dc
->desc
= "Freescale 8xx cores (aka PowerQUICC)";
4366 pcc
->init_proc
= init_proc_MPC8xx
;
4367 pcc
->check_pow
= check_pow_none
;
4368 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
|
4369 PPC_MEM_EIEIO
| PPC_MEM_SYNC
|
4370 PPC_CACHE_ICBI
| PPC_MFTB
;
4371 pcc
->msr_mask
= (1ull << MSR_ILE
) |
4383 pcc
->mmu_model
= POWERPC_MMU_MPC8xx
;
4384 pcc
->excp_model
= POWERPC_EXCP_603
;
4385 pcc
->bus_model
= PPC_FLAGS_INPUT_RCPU
;
4386 pcc
->bfd_mach
= bfd_mach_ppc_860
;
4387 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
4388 POWERPC_FLAG_BUS_CLK
;
4391 /* Freescale 82xx cores (aka PowerQUICC-II) */
4393 static void init_proc_G2(CPUPPCState
*env
)
4395 gen_spr_ne_601(env
);
4397 gen_spr_G2_755(env
);
4401 /* External access control */
4402 /* XXX : not implemented */
4403 spr_register(env
, SPR_EAR
, "EAR",
4404 SPR_NOACCESS
, SPR_NOACCESS
,
4405 &spr_read_generic
, &spr_write_generic
,
4407 /* Hardware implementation register */
4408 /* XXX : not implemented */
4409 spr_register(env
, SPR_HID0
, "HID0",
4410 SPR_NOACCESS
, SPR_NOACCESS
,
4411 &spr_read_generic
, &spr_write_generic
,
4413 /* XXX : not implemented */
4414 spr_register(env
, SPR_HID1
, "HID1",
4415 SPR_NOACCESS
, SPR_NOACCESS
,
4416 &spr_read_generic
, &spr_write_generic
,
4418 /* XXX : not implemented */
4419 spr_register(env
, SPR_HID2
, "HID2",
4420 SPR_NOACCESS
, SPR_NOACCESS
,
4421 &spr_read_generic
, &spr_write_generic
,
4423 /* Memory management */
4426 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4428 env
->dcache_line_size
= 32;
4429 env
->icache_line_size
= 32;
4430 /* Allocate hardware IRQ controller */
4431 ppc6xx_irq_init(env_archcpu(env
));
4434 POWERPC_FAMILY(G2
)(ObjectClass
*oc
, void *data
)
4436 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4437 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4439 dc
->desc
= "PowerPC G2";
4440 pcc
->init_proc
= init_proc_G2
;
4441 pcc
->check_pow
= check_pow_hid0
;
4442 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4443 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4445 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4446 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4447 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4448 PPC_SEGMENT
| PPC_EXTERN
;
4449 pcc
->msr_mask
= (1ull << MSR_POW
) |
4450 (1ull << MSR_TGPR
) |
4464 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4465 pcc
->excp_model
= POWERPC_EXCP_G2
;
4466 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4467 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
4468 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4469 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4472 static void init_proc_G2LE(CPUPPCState
*env
)
4474 gen_spr_ne_601(env
);
4476 gen_spr_G2_755(env
);
4480 /* External access control */
4481 /* XXX : not implemented */
4482 spr_register(env
, SPR_EAR
, "EAR",
4483 SPR_NOACCESS
, SPR_NOACCESS
,
4484 &spr_read_generic
, &spr_write_generic
,
4486 /* Hardware implementation register */
4487 /* XXX : not implemented */
4488 spr_register(env
, SPR_HID0
, "HID0",
4489 SPR_NOACCESS
, SPR_NOACCESS
,
4490 &spr_read_generic
, &spr_write_generic
,
4492 /* XXX : not implemented */
4493 spr_register(env
, SPR_HID1
, "HID1",
4494 SPR_NOACCESS
, SPR_NOACCESS
,
4495 &spr_read_generic
, &spr_write_generic
,
4497 /* XXX : not implemented */
4498 spr_register(env
, SPR_HID2
, "HID2",
4499 SPR_NOACCESS
, SPR_NOACCESS
,
4500 &spr_read_generic
, &spr_write_generic
,
4503 /* Memory management */
4506 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4508 env
->dcache_line_size
= 32;
4509 env
->icache_line_size
= 32;
4510 /* Allocate hardware IRQ controller */
4511 ppc6xx_irq_init(env_archcpu(env
));
4514 POWERPC_FAMILY(G2LE
)(ObjectClass
*oc
, void *data
)
4516 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4517 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4519 dc
->desc
= "PowerPC G2LE";
4520 pcc
->init_proc
= init_proc_G2LE
;
4521 pcc
->check_pow
= check_pow_hid0
;
4522 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4523 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4525 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4526 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4527 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4528 PPC_SEGMENT
| PPC_EXTERN
;
4529 pcc
->msr_mask
= (1ull << MSR_POW
) |
4530 (1ull << MSR_TGPR
) |
4546 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4547 pcc
->excp_model
= POWERPC_EXCP_G2
;
4548 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4549 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
4550 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4551 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4554 static void init_proc_e200(CPUPPCState
*env
)
4558 gen_spr_BookE(env
, 0x000000070000FFFFULL
);
4559 /* XXX : not implemented */
4560 spr_register(env
, SPR_BOOKE_SPEFSCR
, "SPEFSCR",
4561 &spr_read_spefscr
, &spr_write_spefscr
,
4562 &spr_read_spefscr
, &spr_write_spefscr
,
4564 /* Memory management */
4565 gen_spr_BookE206(env
, 0x0000005D, NULL
, 0);
4566 /* XXX : not implemented */
4567 spr_register(env
, SPR_HID0
, "HID0",
4568 SPR_NOACCESS
, SPR_NOACCESS
,
4569 &spr_read_generic
, &spr_write_generic
,
4571 /* XXX : not implemented */
4572 spr_register(env
, SPR_HID1
, "HID1",
4573 SPR_NOACCESS
, SPR_NOACCESS
,
4574 &spr_read_generic
, &spr_write_generic
,
4576 /* XXX : not implemented */
4577 spr_register(env
, SPR_Exxx_ALTCTXCR
, "ALTCTXCR",
4578 SPR_NOACCESS
, SPR_NOACCESS
,
4579 &spr_read_generic
, &spr_write_generic
,
4581 /* XXX : not implemented */
4582 spr_register(env
, SPR_Exxx_BUCSR
, "BUCSR",
4583 SPR_NOACCESS
, SPR_NOACCESS
,
4584 &spr_read_generic
, &spr_write_generic
,
4586 /* XXX : not implemented */
4587 spr_register(env
, SPR_Exxx_CTXCR
, "CTXCR",
4588 SPR_NOACCESS
, SPR_NOACCESS
,
4589 &spr_read_generic
, &spr_write_generic
,
4591 /* XXX : not implemented */
4592 spr_register(env
, SPR_Exxx_DBCNT
, "DBCNT",
4593 SPR_NOACCESS
, SPR_NOACCESS
,
4594 &spr_read_generic
, &spr_write_generic
,
4596 /* XXX : not implemented */
4597 spr_register(env
, SPR_Exxx_DBCR3
, "DBCR3",
4598 SPR_NOACCESS
, SPR_NOACCESS
,
4599 &spr_read_generic
, &spr_write_generic
,
4601 /* XXX : not implemented */
4602 spr_register(env
, SPR_Exxx_L1CFG0
, "L1CFG0",
4603 &spr_read_generic
, SPR_NOACCESS
,
4604 &spr_read_generic
, SPR_NOACCESS
,
4606 /* XXX : not implemented */
4607 spr_register(env
, SPR_Exxx_L1CSR0
, "L1CSR0",
4608 SPR_NOACCESS
, SPR_NOACCESS
,
4609 &spr_read_generic
, &spr_write_generic
,
4611 /* XXX : not implemented */
4612 spr_register(env
, SPR_Exxx_L1FINV0
, "L1FINV0",
4613 SPR_NOACCESS
, SPR_NOACCESS
,
4614 &spr_read_generic
, &spr_write_generic
,
4616 /* XXX : not implemented */
4617 spr_register(env
, SPR_BOOKE_TLB0CFG
, "TLB0CFG",
4618 SPR_NOACCESS
, SPR_NOACCESS
,
4619 &spr_read_generic
, &spr_write_generic
,
4621 /* XXX : not implemented */
4622 spr_register(env
, SPR_BOOKE_TLB1CFG
, "TLB1CFG",
4623 SPR_NOACCESS
, SPR_NOACCESS
,
4624 &spr_read_generic
, &spr_write_generic
,
4626 /* XXX : not implemented */
4627 spr_register(env
, SPR_BOOKE_IAC3
, "IAC3",
4628 SPR_NOACCESS
, SPR_NOACCESS
,
4629 &spr_read_generic
, &spr_write_generic
,
4631 /* XXX : not implemented */
4632 spr_register(env
, SPR_BOOKE_IAC4
, "IAC4",
4633 SPR_NOACCESS
, SPR_NOACCESS
,
4634 &spr_read_generic
, &spr_write_generic
,
4636 /* XXX : not implemented */
4637 spr_register(env
, SPR_MMUCSR0
, "MMUCSR0",
4638 SPR_NOACCESS
, SPR_NOACCESS
,
4639 &spr_read_generic
, &spr_write_generic
,
4640 0x00000000); /* TOFIX */
4641 spr_register(env
, SPR_BOOKE_DSRR0
, "DSRR0",
4642 SPR_NOACCESS
, SPR_NOACCESS
,
4643 &spr_read_generic
, &spr_write_generic
,
4645 spr_register(env
, SPR_BOOKE_DSRR1
, "DSRR1",
4646 SPR_NOACCESS
, SPR_NOACCESS
,
4647 &spr_read_generic
, &spr_write_generic
,
4649 #if !defined(CONFIG_USER_ONLY)
4653 env
->tlb_type
= TLB_EMB
;
4655 init_excp_e200(env
, 0xFFFF0000UL
);
4656 env
->dcache_line_size
= 32;
4657 env
->icache_line_size
= 32;
4658 /* XXX: TODO: allocate internal IRQ controller */
4661 POWERPC_FAMILY(e200
)(ObjectClass
*oc
, void *data
)
4663 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4664 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4666 dc
->desc
= "e200 core";
4667 pcc
->init_proc
= init_proc_e200
;
4668 pcc
->check_pow
= check_pow_hid0
;
4670 * XXX: unimplemented instructions:
4677 * all SPE multiply-accumulate instructions
4679 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
4680 PPC_SPE
| PPC_SPE_SINGLE
|
4681 PPC_WRTEE
| PPC_RFDI
|
4682 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
4683 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
4684 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
|
4686 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
4700 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
4701 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
4702 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
4703 pcc
->bfd_mach
= bfd_mach_ppc_860
;
4704 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
4705 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
4706 POWERPC_FLAG_BUS_CLK
;
4709 static void init_proc_e300(CPUPPCState
*env
)
4711 gen_spr_ne_601(env
);
4716 /* hardware implementation registers */
4717 /* XXX : not implemented */
4718 spr_register(env
, SPR_HID0
, "HID0",
4719 SPR_NOACCESS
, SPR_NOACCESS
,
4720 &spr_read_generic
, &spr_write_generic
,
4722 /* XXX : not implemented */
4723 spr_register(env
, SPR_HID1
, "HID1",
4724 SPR_NOACCESS
, SPR_NOACCESS
,
4725 &spr_read_generic
, &spr_write_generic
,
4727 /* XXX : not implemented */
4728 spr_register(env
, SPR_HID2
, "HID2",
4729 SPR_NOACCESS
, SPR_NOACCESS
,
4730 &spr_read_generic
, &spr_write_generic
,
4733 /* XXX : not implemented */
4734 spr_register(env
, SPR_DABR
, "DABR",
4735 SPR_NOACCESS
, SPR_NOACCESS
,
4736 &spr_read_generic
, &spr_write_generic
,
4738 /* XXX : not implemented */
4739 spr_register(env
, SPR_DABR2
, "DABR2",
4740 SPR_NOACCESS
, SPR_NOACCESS
,
4741 &spr_read_generic
, &spr_write_generic
,
4743 /* XXX : not implemented */
4744 spr_register(env
, SPR_IABR2
, "IABR2",
4745 SPR_NOACCESS
, SPR_NOACCESS
,
4746 &spr_read_generic
, &spr_write_generic
,
4748 /* XXX : not implemented */
4749 spr_register(env
, SPR_IBCR
, "IBCR",
4750 SPR_NOACCESS
, SPR_NOACCESS
,
4751 &spr_read_generic
, &spr_write_generic
,
4753 /* XXX : not implemented */
4754 spr_register(env
, SPR_DBCR
, "DBCR",
4755 SPR_NOACCESS
, SPR_NOACCESS
,
4756 &spr_read_generic
, &spr_write_generic
,
4758 /* Memory management */
4761 gen_6xx_7xx_soft_tlb(env
, 64, 2);
4763 env
->dcache_line_size
= 32;
4764 env
->icache_line_size
= 32;
4765 /* Allocate hardware IRQ controller */
4766 ppc6xx_irq_init(env_archcpu(env
));
4769 POWERPC_FAMILY(e300
)(ObjectClass
*oc
, void *data
)
4771 DeviceClass
*dc
= DEVICE_CLASS(oc
);
4772 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
4774 dc
->desc
= "e300 core";
4775 pcc
->init_proc
= init_proc_e300
;
4776 pcc
->check_pow
= check_pow_hid0
;
4777 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
4778 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
4780 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
4781 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
4782 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
4783 PPC_SEGMENT
| PPC_EXTERN
;
4784 pcc
->msr_mask
= (1ull << MSR_POW
) |
4785 (1ull << MSR_TGPR
) |
4801 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
4802 pcc
->excp_model
= POWERPC_EXCP_603
;
4803 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
4804 pcc
->bfd_mach
= bfd_mach_ppc_603
;
4805 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
4806 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
4809 #if !defined(CONFIG_USER_ONLY)
4810 static void spr_write_mas73(DisasContext
*ctx
, int sprn
, int gprn
)
4812 TCGv val
= tcg_temp_new();
4813 tcg_gen_ext32u_tl(val
, cpu_gpr
[gprn
]);
4814 gen_store_spr(SPR_BOOKE_MAS3
, val
);
4815 tcg_gen_shri_tl(val
, cpu_gpr
[gprn
], 32);
4816 gen_store_spr(SPR_BOOKE_MAS7
, val
);
4820 static void spr_read_mas73(DisasContext
*ctx
, int gprn
, int sprn
)
4822 TCGv mas7
= tcg_temp_new();
4823 TCGv mas3
= tcg_temp_new();
4824 gen_load_spr(mas7
, SPR_BOOKE_MAS7
);
4825 tcg_gen_shli_tl(mas7
, mas7
, 32);
4826 gen_load_spr(mas3
, SPR_BOOKE_MAS3
);
4827 tcg_gen_or_tl(cpu_gpr
[gprn
], mas3
, mas7
);
4828 tcg_temp_free(mas3
);
4829 tcg_temp_free(mas7
);
4834 enum fsl_e500_version
{
4842 static void init_proc_e500(CPUPPCState
*env
, int version
)
4844 uint32_t tlbncfg
[2];
4846 uint64_t ivpr_mask
= 0xFFFF0000ULL
;
4847 uint32_t l1cfg0
= 0x3800 /* 8 ways */
4848 | 0x0020; /* 32 kb */
4849 uint32_t l1cfg1
= 0x3800 /* 8 ways */
4850 | 0x0020; /* 32 kb */
4851 uint32_t mmucfg
= 0;
4852 #if !defined(CONFIG_USER_ONLY)
4859 * XXX The e500 doesn't implement IVOR7 and IVOR9, but doesn't
4860 * complain when accessing them.
4861 * gen_spr_BookE(env, 0x0000000F0000FD7FULL);
4867 ivor_mask
= 0x0000000F0000FFFFULL
;
4871 ivor_mask
= 0x000003FE0000FFFFULL
;
4874 ivor_mask
= 0x000003FF0000FFFFULL
;
4877 gen_spr_BookE(env
, ivor_mask
);
4878 gen_spr_usprg3(env
);
4879 /* Processor identification */
4880 spr_register(env
, SPR_BOOKE_PIR
, "PIR",
4881 SPR_NOACCESS
, SPR_NOACCESS
,
4882 &spr_read_generic
, &spr_write_pir
,
4884 /* XXX : not implemented */
4885 spr_register(env
, SPR_BOOKE_SPEFSCR
, "SPEFSCR",
4886 &spr_read_spefscr
, &spr_write_spefscr
,
4887 &spr_read_spefscr
, &spr_write_spefscr
,
4889 #if !defined(CONFIG_USER_ONLY)
4890 /* Memory management */
4896 tlbncfg
[0] = gen_tlbncfg(2, 1, 1, 0, 256);
4897 tlbncfg
[1] = gen_tlbncfg(16, 1, 9, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 16);
4900 tlbncfg
[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4901 tlbncfg
[1] = gen_tlbncfg(16, 1, 12, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 16);
4905 tlbncfg
[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4906 tlbncfg
[1] = gen_tlbncfg(64, 1, 12, TLBnCFG_AVAIL
| TLBnCFG_IPROT
, 64);
4911 tlbncfg
[0] = 0x08052400;
4912 tlbncfg
[1] = 0x40028040;
4915 cpu_abort(env_cpu(env
), "Unknown CPU: " TARGET_FMT_lx
"\n",
4923 env
->dcache_line_size
= 32;
4924 env
->icache_line_size
= 32;
4928 env
->dcache_line_size
= 64;
4929 env
->icache_line_size
= 64;
4930 l1cfg0
|= 0x1000000; /* 64 byte cache block size */
4931 l1cfg1
|= 0x1000000; /* 64 byte cache block size */
4934 env
->dcache_line_size
= 32;
4935 env
->icache_line_size
= 32;
4936 l1cfg0
|= 0x0F83820;
4937 l1cfg1
|= 0x0B83820;
4940 cpu_abort(env_cpu(env
), "Unknown CPU: " TARGET_FMT_lx
"\n",
4943 gen_spr_BookE206(env
, 0x000000DF, tlbncfg
, mmucfg
);
4944 /* XXX : not implemented */
4945 spr_register(env
, SPR_HID0
, "HID0",
4946 SPR_NOACCESS
, SPR_NOACCESS
,
4947 &spr_read_generic
, &spr_write_generic
,
4949 /* XXX : not implemented */
4950 spr_register(env
, SPR_HID1
, "HID1",
4951 SPR_NOACCESS
, SPR_NOACCESS
,
4952 &spr_read_generic
, &spr_write_generic
,
4954 /* XXX : not implemented */
4955 spr_register(env
, SPR_Exxx_BBEAR
, "BBEAR",
4956 SPR_NOACCESS
, SPR_NOACCESS
,
4957 &spr_read_generic
, &spr_write_generic
,
4959 /* XXX : not implemented */
4960 spr_register(env
, SPR_Exxx_BBTAR
, "BBTAR",
4961 SPR_NOACCESS
, SPR_NOACCESS
,
4962 &spr_read_generic
, &spr_write_generic
,
4964 /* XXX : not implemented */
4965 spr_register(env
, SPR_Exxx_MCAR
, "MCAR",
4966 SPR_NOACCESS
, SPR_NOACCESS
,
4967 &spr_read_generic
, &spr_write_generic
,
4969 /* XXX : not implemented */
4970 spr_register(env
, SPR_BOOKE_MCSR
, "MCSR",
4971 SPR_NOACCESS
, SPR_NOACCESS
,
4972 &spr_read_generic
, &spr_write_generic
,
4974 /* XXX : not implemented */
4975 spr_register(env
, SPR_Exxx_NPIDR
, "NPIDR",
4976 SPR_NOACCESS
, SPR_NOACCESS
,
4977 &spr_read_generic
, &spr_write_generic
,
4979 /* XXX : not implemented */
4980 spr_register(env
, SPR_Exxx_BUCSR
, "BUCSR",
4981 SPR_NOACCESS
, SPR_NOACCESS
,
4982 &spr_read_generic
, &spr_write_generic
,
4984 /* XXX : not implemented */
4985 spr_register(env
, SPR_Exxx_L1CFG0
, "L1CFG0",
4986 &spr_read_generic
, SPR_NOACCESS
,
4987 &spr_read_generic
, SPR_NOACCESS
,
4989 spr_register(env
, SPR_Exxx_L1CFG1
, "L1CFG1",
4990 &spr_read_generic
, SPR_NOACCESS
,
4991 &spr_read_generic
, SPR_NOACCESS
,
4993 spr_register(env
, SPR_Exxx_L1CSR0
, "L1CSR0",
4994 SPR_NOACCESS
, SPR_NOACCESS
,
4995 &spr_read_generic
, &spr_write_e500_l1csr0
,
4997 spr_register(env
, SPR_Exxx_L1CSR1
, "L1CSR1",
4998 SPR_NOACCESS
, SPR_NOACCESS
,
4999 &spr_read_generic
, &spr_write_e500_l1csr1
,
5001 spr_register(env
, SPR_BOOKE_MCSRR0
, "MCSRR0",
5002 SPR_NOACCESS
, SPR_NOACCESS
,
5003 &spr_read_generic
, &spr_write_generic
,
5005 spr_register(env
, SPR_BOOKE_MCSRR1
, "MCSRR1",
5006 SPR_NOACCESS
, SPR_NOACCESS
,
5007 &spr_read_generic
, &spr_write_generic
,
5009 spr_register(env
, SPR_MMUCSR0
, "MMUCSR0",
5010 SPR_NOACCESS
, SPR_NOACCESS
,
5011 &spr_read_generic
, &spr_write_booke206_mmucsr0
,
5013 spr_register(env
, SPR_BOOKE_EPR
, "EPR",
5014 SPR_NOACCESS
, SPR_NOACCESS
,
5015 &spr_read_generic
, SPR_NOACCESS
,
5017 /* XXX better abstract into Emb.xxx features */
5018 if ((version
== fsl_e5500
) || (version
== fsl_e6500
)) {
5019 spr_register(env
, SPR_BOOKE_EPCR
, "EPCR",
5020 SPR_NOACCESS
, SPR_NOACCESS
,
5021 &spr_read_generic
, &spr_write_generic
,
5023 spr_register(env
, SPR_BOOKE_MAS7_MAS3
, "MAS7_MAS3",
5024 SPR_NOACCESS
, SPR_NOACCESS
,
5025 &spr_read_mas73
, &spr_write_mas73
,
5027 ivpr_mask
= (target_ulong
)~0xFFFFULL
;
5030 if (version
== fsl_e6500
) {
5031 /* Thread identification */
5032 spr_register(env
, SPR_TIR
, "TIR",
5033 SPR_NOACCESS
, SPR_NOACCESS
,
5034 &spr_read_generic
, SPR_NOACCESS
,
5036 spr_register(env
, SPR_BOOKE_TLB0PS
, "TLB0PS",
5037 SPR_NOACCESS
, SPR_NOACCESS
,
5038 &spr_read_generic
, SPR_NOACCESS
,
5040 spr_register(env
, SPR_BOOKE_TLB1PS
, "TLB1PS",
5041 SPR_NOACCESS
, SPR_NOACCESS
,
5042 &spr_read_generic
, SPR_NOACCESS
,
5046 #if !defined(CONFIG_USER_ONLY)
5048 env
->tlb_type
= TLB_MAS
;
5049 for (i
= 0; i
< BOOKE206_MAX_TLBN
; i
++) {
5050 env
->nb_tlb
+= booke206_tlb_size(env
, i
);
5054 init_excp_e200(env
, ivpr_mask
);
5055 /* Allocate hardware IRQ controller */
5056 ppce500_irq_init(env_archcpu(env
));
5059 static void init_proc_e500v1(CPUPPCState
*env
)
5061 init_proc_e500(env
, fsl_e500v1
);
5064 POWERPC_FAMILY(e500v1
)(ObjectClass
*oc
, void *data
)
5066 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5067 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5069 dc
->desc
= "e500v1 core";
5070 pcc
->init_proc
= init_proc_e500v1
;
5071 pcc
->check_pow
= check_pow_hid0
;
5072 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
5073 PPC_SPE
| PPC_SPE_SINGLE
|
5074 PPC_WRTEE
| PPC_RFDI
|
5075 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5076 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5077 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5078 pcc
->insns_flags2
= PPC2_BOOKE206
;
5079 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
5093 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5094 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5095 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5096 pcc
->bfd_mach
= bfd_mach_ppc_860
;
5097 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
5098 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
5099 POWERPC_FLAG_BUS_CLK
;
5102 static void init_proc_e500v2(CPUPPCState
*env
)
5104 init_proc_e500(env
, fsl_e500v2
);
5107 POWERPC_FAMILY(e500v2
)(ObjectClass
*oc
, void *data
)
5109 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5110 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5112 dc
->desc
= "e500v2 core";
5113 pcc
->init_proc
= init_proc_e500v2
;
5114 pcc
->check_pow
= check_pow_hid0
;
5115 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
|
5116 PPC_SPE
| PPC_SPE_SINGLE
| PPC_SPE_DOUBLE
|
5117 PPC_WRTEE
| PPC_RFDI
|
5118 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5119 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5120 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5121 pcc
->insns_flags2
= PPC2_BOOKE206
;
5122 pcc
->msr_mask
= (1ull << MSR_UCLE
) |
5136 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5137 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5138 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5139 pcc
->bfd_mach
= bfd_mach_ppc_860
;
5140 pcc
->flags
= POWERPC_FLAG_SPE
| POWERPC_FLAG_CE
|
5141 POWERPC_FLAG_UBLE
| POWERPC_FLAG_DE
|
5142 POWERPC_FLAG_BUS_CLK
;
5145 static void init_proc_e500mc(CPUPPCState
*env
)
5147 init_proc_e500(env
, fsl_e500mc
);
5150 POWERPC_FAMILY(e500mc
)(ObjectClass
*oc
, void *data
)
5152 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5153 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5155 dc
->desc
= "e500mc core";
5156 pcc
->init_proc
= init_proc_e500mc
;
5157 pcc
->check_pow
= check_pow_none
;
5158 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5159 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5160 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5161 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5162 PPC_FLOAT
| PPC_FLOAT_FRES
|
5163 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5164 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5165 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
;
5166 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
;
5167 pcc
->msr_mask
= (1ull << MSR_GS
) |
5168 (1ull << MSR_UCLE
) |
5181 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5182 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5183 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5184 /* FIXME: figure out the correct flag for e500mc */
5185 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5186 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5187 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5191 static void init_proc_e5500(CPUPPCState
*env
)
5193 init_proc_e500(env
, fsl_e5500
);
5196 POWERPC_FAMILY(e5500
)(ObjectClass
*oc
, void *data
)
5198 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5199 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5201 dc
->desc
= "e5500 core";
5202 pcc
->init_proc
= init_proc_e5500
;
5203 pcc
->check_pow
= check_pow_none
;
5204 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5205 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5206 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5207 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5208 PPC_FLOAT
| PPC_FLOAT_FRES
|
5209 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5210 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5211 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
|
5212 PPC_64B
| PPC_POPCNTB
| PPC_POPCNTWD
;
5213 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
| PPC2_PERM_ISA206
| \
5215 pcc
->msr_mask
= (1ull << MSR_CM
) |
5217 (1ull << MSR_UCLE
) |
5230 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5231 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5232 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5233 /* FIXME: figure out the correct flag for e5500 */
5234 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5235 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5236 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5239 static void init_proc_e6500(CPUPPCState
*env
)
5241 init_proc_e500(env
, fsl_e6500
);
5244 POWERPC_FAMILY(e6500
)(ObjectClass
*oc
, void *data
)
5246 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5247 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5249 dc
->desc
= "e6500 core";
5250 pcc
->init_proc
= init_proc_e6500
;
5251 pcc
->check_pow
= check_pow_none
;
5252 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_MFTB
|
5253 PPC_WRTEE
| PPC_RFDI
| PPC_RFMCI
|
5254 PPC_CACHE
| PPC_CACHE_LOCK
| PPC_CACHE_ICBI
|
5255 PPC_CACHE_DCBZ
| PPC_CACHE_DCBA
|
5256 PPC_FLOAT
| PPC_FLOAT_FRES
|
5257 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_FSEL
|
5258 PPC_FLOAT_STFIWX
| PPC_WAIT
|
5259 PPC_MEM_TLBSYNC
| PPC_TLBIVAX
| PPC_MEM_SYNC
|
5260 PPC_64B
| PPC_POPCNTB
| PPC_POPCNTWD
| PPC_ALTIVEC
;
5261 pcc
->insns_flags2
= PPC2_BOOKE206
| PPC2_PRCNTL
| PPC2_PERM_ISA206
| \
5262 PPC2_FP_CVT_S64
| PPC2_ATOMIC_ISA206
;
5263 pcc
->msr_mask
= (1ull << MSR_CM
) |
5265 (1ull << MSR_UCLE
) |
5279 pcc
->mmu_model
= POWERPC_MMU_BOOKE206
;
5280 pcc
->excp_model
= POWERPC_EXCP_BOOKE
;
5281 pcc
->bus_model
= PPC_FLAGS_INPUT_BookE
;
5282 pcc
->bfd_mach
= bfd_mach_ppc_e500
;
5283 pcc
->flags
= POWERPC_FLAG_CE
| POWERPC_FLAG_DE
|
5284 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_VRE
;
5289 /* Non-embedded PowerPC */
5291 #define POWERPC_MSRR_601 (0x0000000000001040ULL)
5293 static void init_proc_601(CPUPPCState
*env
)
5295 gen_spr_ne_601(env
);
5298 /* Hardware implementation registers */
5299 /* XXX : not implemented */
5300 spr_register(env
, SPR_HID0
, "HID0",
5301 SPR_NOACCESS
, SPR_NOACCESS
,
5302 &spr_read_generic
, &spr_write_hid0_601
,
5304 /* XXX : not implemented */
5305 spr_register(env
, SPR_HID1
, "HID1",
5306 SPR_NOACCESS
, SPR_NOACCESS
,
5307 &spr_read_generic
, &spr_write_generic
,
5309 /* XXX : not implemented */
5310 spr_register(env
, SPR_601_HID2
, "HID2",
5311 SPR_NOACCESS
, SPR_NOACCESS
,
5312 &spr_read_generic
, &spr_write_generic
,
5314 /* XXX : not implemented */
5315 spr_register(env
, SPR_601_HID5
, "HID5",
5316 SPR_NOACCESS
, SPR_NOACCESS
,
5317 &spr_read_generic
, &spr_write_generic
,
5319 /* Memory management */
5322 * XXX: beware that dcache line size is 64
5323 * but dcbz uses 32 bytes "sectors"
5324 * XXX: this breaks clcs instruction !
5326 env
->dcache_line_size
= 32;
5327 env
->icache_line_size
= 64;
5328 /* Allocate hardware IRQ controller */
5329 ppc6xx_irq_init(env_archcpu(env
));
5332 POWERPC_FAMILY(601)(ObjectClass
*oc
, void *data
)
5334 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5335 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5337 dc
->desc
= "PowerPC 601";
5338 pcc
->init_proc
= init_proc_601
;
5339 pcc
->check_pow
= check_pow_none
;
5340 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_POWER_BR
|
5342 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5343 PPC_MEM_SYNC
| PPC_MEM_EIEIO
| PPC_MEM_TLBIE
|
5344 PPC_SEGMENT
| PPC_EXTERN
;
5345 pcc
->msr_mask
= (1ull << MSR_EE
) |
5355 pcc
->mmu_model
= POWERPC_MMU_601
;
5356 #if defined(CONFIG_SOFTMMU)
5357 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5359 pcc
->excp_model
= POWERPC_EXCP_601
;
5360 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5361 pcc
->bfd_mach
= bfd_mach_ppc_601
;
5362 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_RTC_CLK
;
5365 #define POWERPC_MSRR_601v (0x0000000000001040ULL)
5367 static void init_proc_601v(CPUPPCState
*env
)
5370 /* XXX : not implemented */
5371 spr_register(env
, SPR_601_HID15
, "HID15",
5372 SPR_NOACCESS
, SPR_NOACCESS
,
5373 &spr_read_generic
, &spr_write_generic
,
5377 POWERPC_FAMILY(601v
)(ObjectClass
*oc
, void *data
)
5379 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5380 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5382 dc
->desc
= "PowerPC 601v";
5383 pcc
->init_proc
= init_proc_601v
;
5384 pcc
->check_pow
= check_pow_none
;
5385 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_POWER_BR
|
5387 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5388 PPC_MEM_SYNC
| PPC_MEM_EIEIO
| PPC_MEM_TLBIE
|
5389 PPC_SEGMENT
| PPC_EXTERN
;
5390 pcc
->msr_mask
= (1ull << MSR_EE
) |
5400 pcc
->mmu_model
= POWERPC_MMU_601
;
5401 #if defined(CONFIG_SOFTMMU)
5402 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5404 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5405 pcc
->bfd_mach
= bfd_mach_ppc_601
;
5406 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_RTC_CLK
;
5409 static void init_proc_602(CPUPPCState
*env
)
5411 gen_spr_ne_601(env
);
5416 /* hardware implementation registers */
5417 /* XXX : not implemented */
5418 spr_register(env
, SPR_HID0
, "HID0",
5419 SPR_NOACCESS
, SPR_NOACCESS
,
5420 &spr_read_generic
, &spr_write_generic
,
5422 /* XXX : not implemented */
5423 spr_register(env
, SPR_HID1
, "HID1",
5424 SPR_NOACCESS
, SPR_NOACCESS
,
5425 &spr_read_generic
, &spr_write_generic
,
5427 /* Memory management */
5429 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5431 env
->dcache_line_size
= 32;
5432 env
->icache_line_size
= 32;
5433 /* Allocate hardware IRQ controller */
5434 ppc6xx_irq_init(env_archcpu(env
));
5437 POWERPC_FAMILY(602)(ObjectClass
*oc
, void *data
)
5439 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5440 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5442 dc
->desc
= "PowerPC 602";
5443 pcc
->init_proc
= init_proc_602
;
5444 pcc
->check_pow
= check_pow_hid0
;
5445 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5446 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5447 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5448 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5449 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5450 PPC_MEM_TLBIE
| PPC_6xx_TLB
| PPC_MEM_TLBSYNC
|
5451 PPC_SEGMENT
| PPC_602_SPEC
;
5452 pcc
->msr_mask
= (1ull << MSR_VSX
) |
5455 (1ull << MSR_TGPR
) |
5470 /* XXX: 602 MMU is quite specific. Should add a special case */
5471 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5472 pcc
->excp_model
= POWERPC_EXCP_602
;
5473 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5474 pcc
->bfd_mach
= bfd_mach_ppc_602
;
5475 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5476 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5479 static void init_proc_603(CPUPPCState
*env
)
5481 gen_spr_ne_601(env
);
5486 /* hardware implementation registers */
5487 /* XXX : not implemented */
5488 spr_register(env
, SPR_HID0
, "HID0",
5489 SPR_NOACCESS
, SPR_NOACCESS
,
5490 &spr_read_generic
, &spr_write_generic
,
5492 /* XXX : not implemented */
5493 spr_register(env
, SPR_HID1
, "HID1",
5494 SPR_NOACCESS
, SPR_NOACCESS
,
5495 &spr_read_generic
, &spr_write_generic
,
5497 /* Memory management */
5499 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5501 env
->dcache_line_size
= 32;
5502 env
->icache_line_size
= 32;
5503 /* Allocate hardware IRQ controller */
5504 ppc6xx_irq_init(env_archcpu(env
));
5507 POWERPC_FAMILY(603)(ObjectClass
*oc
, void *data
)
5509 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5510 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5512 dc
->desc
= "PowerPC 603";
5513 pcc
->init_proc
= init_proc_603
;
5514 pcc
->check_pow
= check_pow_hid0
;
5515 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5516 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5517 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5518 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5519 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5520 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
5521 PPC_SEGMENT
| PPC_EXTERN
;
5522 pcc
->msr_mask
= (1ull << MSR_POW
) |
5523 (1ull << MSR_TGPR
) |
5538 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5539 pcc
->excp_model
= POWERPC_EXCP_603
;
5540 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5541 pcc
->bfd_mach
= bfd_mach_ppc_603
;
5542 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5543 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5546 static void init_proc_603E(CPUPPCState
*env
)
5548 gen_spr_ne_601(env
);
5553 /* hardware implementation registers */
5554 /* XXX : not implemented */
5555 spr_register(env
, SPR_HID0
, "HID0",
5556 SPR_NOACCESS
, SPR_NOACCESS
,
5557 &spr_read_generic
, &spr_write_generic
,
5559 /* XXX : not implemented */
5560 spr_register(env
, SPR_HID1
, "HID1",
5561 SPR_NOACCESS
, SPR_NOACCESS
,
5562 &spr_read_generic
, &spr_write_generic
,
5564 /* Memory management */
5566 gen_6xx_7xx_soft_tlb(env
, 64, 2);
5568 env
->dcache_line_size
= 32;
5569 env
->icache_line_size
= 32;
5570 /* Allocate hardware IRQ controller */
5571 ppc6xx_irq_init(env_archcpu(env
));
5574 POWERPC_FAMILY(603E
)(ObjectClass
*oc
, void *data
)
5576 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5577 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5579 dc
->desc
= "PowerPC 603e";
5580 pcc
->init_proc
= init_proc_603E
;
5581 pcc
->check_pow
= check_pow_hid0
;
5582 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5583 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5584 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5585 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5586 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5587 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
5588 PPC_SEGMENT
| PPC_EXTERN
;
5589 pcc
->msr_mask
= (1ull << MSR_POW
) |
5590 (1ull << MSR_TGPR
) |
5605 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
5606 pcc
->excp_model
= POWERPC_EXCP_603E
;
5607 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5608 pcc
->bfd_mach
= bfd_mach_ppc_ec603e
;
5609 pcc
->flags
= POWERPC_FLAG_TGPR
| POWERPC_FLAG_SE
|
5610 POWERPC_FLAG_BE
| POWERPC_FLAG_BUS_CLK
;
5613 static void init_proc_604(CPUPPCState
*env
)
5615 gen_spr_ne_601(env
);
5620 /* Hardware implementation registers */
5621 /* XXX : not implemented */
5622 spr_register(env
, SPR_HID0
, "HID0",
5623 SPR_NOACCESS
, SPR_NOACCESS
,
5624 &spr_read_generic
, &spr_write_generic
,
5626 /* Memory management */
5629 env
->dcache_line_size
= 32;
5630 env
->icache_line_size
= 32;
5631 /* Allocate hardware IRQ controller */
5632 ppc6xx_irq_init(env_archcpu(env
));
5635 POWERPC_FAMILY(604)(ObjectClass
*oc
, void *data
)
5637 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5638 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5640 dc
->desc
= "PowerPC 604";
5641 pcc
->init_proc
= init_proc_604
;
5642 pcc
->check_pow
= check_pow_nocheck
;
5643 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5644 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5645 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5646 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5647 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5648 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5649 PPC_SEGMENT
| PPC_EXTERN
;
5650 pcc
->msr_mask
= (1ull << MSR_POW
) |
5666 pcc
->mmu_model
= POWERPC_MMU_32B
;
5667 #if defined(CONFIG_SOFTMMU)
5668 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5670 pcc
->excp_model
= POWERPC_EXCP_604
;
5671 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5672 pcc
->bfd_mach
= bfd_mach_ppc_604
;
5673 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5674 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5677 static void init_proc_604E(CPUPPCState
*env
)
5679 gen_spr_ne_601(env
);
5682 /* XXX : not implemented */
5683 spr_register(env
, SPR_7XX_MMCR1
, "MMCR1",
5684 SPR_NOACCESS
, SPR_NOACCESS
,
5685 &spr_read_generic
, &spr_write_generic
,
5687 /* XXX : not implemented */
5688 spr_register(env
, SPR_7XX_PMC3
, "PMC3",
5689 SPR_NOACCESS
, SPR_NOACCESS
,
5690 &spr_read_generic
, &spr_write_generic
,
5692 /* XXX : not implemented */
5693 spr_register(env
, SPR_7XX_PMC4
, "PMC4",
5694 SPR_NOACCESS
, SPR_NOACCESS
,
5695 &spr_read_generic
, &spr_write_generic
,
5699 /* Hardware implementation registers */
5700 /* XXX : not implemented */
5701 spr_register(env
, SPR_HID0
, "HID0",
5702 SPR_NOACCESS
, SPR_NOACCESS
,
5703 &spr_read_generic
, &spr_write_generic
,
5705 /* XXX : not implemented */
5706 spr_register(env
, SPR_HID1
, "HID1",
5707 SPR_NOACCESS
, SPR_NOACCESS
,
5708 &spr_read_generic
, &spr_write_generic
,
5710 /* Memory management */
5713 env
->dcache_line_size
= 32;
5714 env
->icache_line_size
= 32;
5715 /* Allocate hardware IRQ controller */
5716 ppc6xx_irq_init(env_archcpu(env
));
5719 POWERPC_FAMILY(604E
)(ObjectClass
*oc
, void *data
)
5721 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5722 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5724 dc
->desc
= "PowerPC 604E";
5725 pcc
->init_proc
= init_proc_604E
;
5726 pcc
->check_pow
= check_pow_nocheck
;
5727 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5728 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5729 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5730 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5731 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5732 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5733 PPC_SEGMENT
| PPC_EXTERN
;
5734 pcc
->msr_mask
= (1ull << MSR_POW
) |
5750 pcc
->mmu_model
= POWERPC_MMU_32B
;
5751 #if defined(CONFIG_SOFTMMU)
5752 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5754 pcc
->excp_model
= POWERPC_EXCP_604
;
5755 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5756 pcc
->bfd_mach
= bfd_mach_ppc_604
;
5757 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5758 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5761 static void init_proc_740(CPUPPCState
*env
)
5763 gen_spr_ne_601(env
);
5768 /* Thermal management */
5770 /* Hardware implementation registers */
5771 /* XXX : not implemented */
5772 spr_register(env
, SPR_HID0
, "HID0",
5773 SPR_NOACCESS
, SPR_NOACCESS
,
5774 &spr_read_generic
, &spr_write_generic
,
5776 /* XXX : not implemented */
5777 spr_register(env
, SPR_HID1
, "HID1",
5778 SPR_NOACCESS
, SPR_NOACCESS
,
5779 &spr_read_generic
, &spr_write_generic
,
5781 /* Memory management */
5784 env
->dcache_line_size
= 32;
5785 env
->icache_line_size
= 32;
5786 /* Allocate hardware IRQ controller */
5787 ppc6xx_irq_init(env_archcpu(env
));
5790 POWERPC_FAMILY(740)(ObjectClass
*oc
, void *data
)
5792 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5793 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5795 dc
->desc
= "PowerPC 740";
5796 pcc
->init_proc
= init_proc_740
;
5797 pcc
->check_pow
= check_pow_hid0
;
5798 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5799 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5800 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5801 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5802 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5803 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5804 PPC_SEGMENT
| PPC_EXTERN
;
5805 pcc
->msr_mask
= (1ull << MSR_POW
) |
5821 pcc
->mmu_model
= POWERPC_MMU_32B
;
5822 #if defined(CONFIG_SOFTMMU)
5823 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5825 pcc
->excp_model
= POWERPC_EXCP_7x0
;
5826 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5827 pcc
->bfd_mach
= bfd_mach_ppc_750
;
5828 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5829 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5832 static void init_proc_750(CPUPPCState
*env
)
5834 gen_spr_ne_601(env
);
5837 /* XXX : not implemented */
5838 spr_register(env
, SPR_L2CR
, "L2CR",
5839 SPR_NOACCESS
, SPR_NOACCESS
,
5840 &spr_read_generic
, spr_access_nop
,
5844 /* Thermal management */
5846 /* Hardware implementation registers */
5847 /* XXX : not implemented */
5848 spr_register(env
, SPR_HID0
, "HID0",
5849 SPR_NOACCESS
, SPR_NOACCESS
,
5850 &spr_read_generic
, &spr_write_generic
,
5852 /* XXX : not implemented */
5853 spr_register(env
, SPR_HID1
, "HID1",
5854 SPR_NOACCESS
, SPR_NOACCESS
,
5855 &spr_read_generic
, &spr_write_generic
,
5857 /* Memory management */
5860 * XXX: high BATs are also present but are known to be bugged on
5864 env
->dcache_line_size
= 32;
5865 env
->icache_line_size
= 32;
5866 /* Allocate hardware IRQ controller */
5867 ppc6xx_irq_init(env_archcpu(env
));
5870 POWERPC_FAMILY(750)(ObjectClass
*oc
, void *data
)
5872 DeviceClass
*dc
= DEVICE_CLASS(oc
);
5873 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
5875 dc
->desc
= "PowerPC 750";
5876 pcc
->init_proc
= init_proc_750
;
5877 pcc
->check_pow
= check_pow_hid0
;
5878 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
5879 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
5880 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
5881 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
5882 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
5883 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
5884 PPC_SEGMENT
| PPC_EXTERN
;
5885 pcc
->msr_mask
= (1ull << MSR_POW
) |
5901 pcc
->mmu_model
= POWERPC_MMU_32B
;
5902 #if defined(CONFIG_SOFTMMU)
5903 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
5905 pcc
->excp_model
= POWERPC_EXCP_7x0
;
5906 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
5907 pcc
->bfd_mach
= bfd_mach_ppc_750
;
5908 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
5909 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
5912 static void init_proc_750cl(CPUPPCState
*env
)
5914 gen_spr_ne_601(env
);
5917 /* XXX : not implemented */
5918 spr_register(env
, SPR_L2CR
, "L2CR",
5919 SPR_NOACCESS
, SPR_NOACCESS
,
5920 &spr_read_generic
, spr_access_nop
,
5924 /* Thermal management */
5925 /* Those registers are fake on 750CL */
5926 spr_register(env
, SPR_THRM1
, "THRM1",
5927 SPR_NOACCESS
, SPR_NOACCESS
,
5928 &spr_read_generic
, &spr_write_generic
,
5930 spr_register(env
, SPR_THRM2
, "THRM2",
5931 SPR_NOACCESS
, SPR_NOACCESS
,
5932 &spr_read_generic
, &spr_write_generic
,
5934 spr_register(env
, SPR_THRM3
, "THRM3",
5935 SPR_NOACCESS
, SPR_NOACCESS
,
5936 &spr_read_generic
, &spr_write_generic
,
5938 /* XXX: not implemented */
5939 spr_register(env
, SPR_750_TDCL
, "TDCL",
5940 SPR_NOACCESS
, SPR_NOACCESS
,
5941 &spr_read_generic
, &spr_write_generic
,
5943 spr_register(env
, SPR_750_TDCH
, "TDCH",
5944 SPR_NOACCESS
, SPR_NOACCESS
,
5945 &spr_read_generic
, &spr_write_generic
,
5948 /* XXX : not implemented */
5949 spr_register(env
, SPR_750_WPAR
, "WPAR",
5950 SPR_NOACCESS
, SPR_NOACCESS
,
5951 &spr_read_generic
, &spr_write_generic
,
5953 spr_register(env
, SPR_750_DMAL
, "DMAL",
5954 SPR_NOACCESS
, SPR_NOACCESS
,
5955 &spr_read_generic
, &spr_write_generic
,
5957 spr_register(env
, SPR_750_DMAU
, "DMAU",
5958 SPR_NOACCESS
, SPR_NOACCESS
,
5959 &spr_read_generic
, &spr_write_generic
,
5961 /* Hardware implementation registers */
5962 /* XXX : not implemented */
5963 spr_register(env
, SPR_HID0
, "HID0",
5964 SPR_NOACCESS
, SPR_NOACCESS
,
5965 &spr_read_generic
, &spr_write_generic
,
5967 /* XXX : not implemented */
5968 spr_register(env
, SPR_HID1
, "HID1",
5969 SPR_NOACCESS
, SPR_NOACCESS
,
5970 &spr_read_generic
, &spr_write_generic
,
5972 /* XXX : not implemented */
5973 spr_register(env
, SPR_750CL_HID2
, "HID2",
5974 SPR_NOACCESS
, SPR_NOACCESS
,
5975 &spr_read_generic
, &spr_write_generic
,
5977 /* XXX : not implemented */
5978 spr_register(env
, SPR_750CL_HID4
, "HID4",
5979 SPR_NOACCESS
, SPR_NOACCESS
,
5980 &spr_read_generic
, &spr_write_generic
,
5982 /* Quantization registers */
5983 /* XXX : not implemented */
5984 spr_register(env
, SPR_750_GQR0
, "GQR0",
5985 SPR_NOACCESS
, SPR_NOACCESS
,
5986 &spr_read_generic
, &spr_write_generic
,
5988 /* XXX : not implemented */
5989 spr_register(env
, SPR_750_GQR1
, "GQR1",
5990 SPR_NOACCESS
, SPR_NOACCESS
,
5991 &spr_read_generic
, &spr_write_generic
,
5993 /* XXX : not implemented */
5994 spr_register(env
, SPR_750_GQR2
, "GQR2",
5995 SPR_NOACCESS
, SPR_NOACCESS
,
5996 &spr_read_generic
, &spr_write_generic
,
5998 /* XXX : not implemented */
5999 spr_register(env
, SPR_750_GQR3
, "GQR3",
6000 SPR_NOACCESS
, SPR_NOACCESS
,
6001 &spr_read_generic
, &spr_write_generic
,
6003 /* XXX : not implemented */
6004 spr_register(env
, SPR_750_GQR4
, "GQR4",
6005 SPR_NOACCESS
, SPR_NOACCESS
,
6006 &spr_read_generic
, &spr_write_generic
,
6008 /* XXX : not implemented */
6009 spr_register(env
, SPR_750_GQR5
, "GQR5",
6010 SPR_NOACCESS
, SPR_NOACCESS
,
6011 &spr_read_generic
, &spr_write_generic
,
6013 /* XXX : not implemented */
6014 spr_register(env
, SPR_750_GQR6
, "GQR6",
6015 SPR_NOACCESS
, SPR_NOACCESS
,
6016 &spr_read_generic
, &spr_write_generic
,
6018 /* XXX : not implemented */
6019 spr_register(env
, SPR_750_GQR7
, "GQR7",
6020 SPR_NOACCESS
, SPR_NOACCESS
,
6021 &spr_read_generic
, &spr_write_generic
,
6023 /* Memory management */
6025 /* PowerPC 750cl has 8 DBATs and 8 IBATs */
6027 init_excp_750cl(env
);
6028 env
->dcache_line_size
= 32;
6029 env
->icache_line_size
= 32;
6030 /* Allocate hardware IRQ controller */
6031 ppc6xx_irq_init(env_archcpu(env
));
6034 POWERPC_FAMILY(750cl
)(ObjectClass
*oc
, void *data
)
6036 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6037 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6039 dc
->desc
= "PowerPC 750 CL";
6040 pcc
->init_proc
= init_proc_750cl
;
6041 pcc
->check_pow
= check_pow_hid0
;
6043 * XXX: not implemented:
6044 * cache lock instructions:
6046 * floating point paired instructions
6081 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6082 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6083 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6084 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6085 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6086 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6087 PPC_SEGMENT
| PPC_EXTERN
;
6088 pcc
->msr_mask
= (1ull << MSR_POW
) |
6104 pcc
->mmu_model
= POWERPC_MMU_32B
;
6105 #if defined(CONFIG_SOFTMMU)
6106 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6108 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6109 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6110 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6111 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6112 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6115 static void init_proc_750cx(CPUPPCState
*env
)
6117 gen_spr_ne_601(env
);
6120 /* XXX : not implemented */
6121 spr_register(env
, SPR_L2CR
, "L2CR",
6122 SPR_NOACCESS
, SPR_NOACCESS
,
6123 &spr_read_generic
, spr_access_nop
,
6127 /* Thermal management */
6129 /* This register is not implemented but is present for compatibility */
6130 spr_register(env
, SPR_SDA
, "SDA",
6131 SPR_NOACCESS
, SPR_NOACCESS
,
6132 &spr_read_generic
, &spr_write_generic
,
6134 /* Hardware implementation registers */
6135 /* XXX : not implemented */
6136 spr_register(env
, SPR_HID0
, "HID0",
6137 SPR_NOACCESS
, SPR_NOACCESS
,
6138 &spr_read_generic
, &spr_write_generic
,
6140 /* XXX : not implemented */
6141 spr_register(env
, SPR_HID1
, "HID1",
6142 SPR_NOACCESS
, SPR_NOACCESS
,
6143 &spr_read_generic
, &spr_write_generic
,
6145 /* Memory management */
6147 /* PowerPC 750cx has 8 DBATs and 8 IBATs */
6149 init_excp_750cx(env
);
6150 env
->dcache_line_size
= 32;
6151 env
->icache_line_size
= 32;
6152 /* Allocate hardware IRQ controller */
6153 ppc6xx_irq_init(env_archcpu(env
));
6156 POWERPC_FAMILY(750cx
)(ObjectClass
*oc
, void *data
)
6158 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6159 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6161 dc
->desc
= "PowerPC 750CX";
6162 pcc
->init_proc
= init_proc_750cx
;
6163 pcc
->check_pow
= check_pow_hid0
;
6164 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6165 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6166 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6167 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6168 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6169 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6170 PPC_SEGMENT
| PPC_EXTERN
;
6171 pcc
->msr_mask
= (1ull << MSR_POW
) |
6187 pcc
->mmu_model
= POWERPC_MMU_32B
;
6188 #if defined(CONFIG_SOFTMMU)
6189 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6191 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6192 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6193 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6194 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6195 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6198 static void init_proc_750fx(CPUPPCState
*env
)
6200 gen_spr_ne_601(env
);
6203 /* XXX : not implemented */
6204 spr_register(env
, SPR_L2CR
, "L2CR",
6205 SPR_NOACCESS
, SPR_NOACCESS
,
6206 &spr_read_generic
, spr_access_nop
,
6210 /* Thermal management */
6212 /* XXX : not implemented */
6213 spr_register(env
, SPR_750_THRM4
, "THRM4",
6214 SPR_NOACCESS
, SPR_NOACCESS
,
6215 &spr_read_generic
, &spr_write_generic
,
6217 /* Hardware implementation registers */
6218 /* XXX : not implemented */
6219 spr_register(env
, SPR_HID0
, "HID0",
6220 SPR_NOACCESS
, SPR_NOACCESS
,
6221 &spr_read_generic
, &spr_write_generic
,
6223 /* XXX : not implemented */
6224 spr_register(env
, SPR_HID1
, "HID1",
6225 SPR_NOACCESS
, SPR_NOACCESS
,
6226 &spr_read_generic
, &spr_write_generic
,
6228 /* XXX : not implemented */
6229 spr_register(env
, SPR_750FX_HID2
, "HID2",
6230 SPR_NOACCESS
, SPR_NOACCESS
,
6231 &spr_read_generic
, &spr_write_generic
,
6233 /* Memory management */
6235 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6238 env
->dcache_line_size
= 32;
6239 env
->icache_line_size
= 32;
6240 /* Allocate hardware IRQ controller */
6241 ppc6xx_irq_init(env_archcpu(env
));
6244 POWERPC_FAMILY(750fx
)(ObjectClass
*oc
, void *data
)
6246 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6247 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6249 dc
->desc
= "PowerPC 750FX";
6250 pcc
->init_proc
= init_proc_750fx
;
6251 pcc
->check_pow
= check_pow_hid0
;
6252 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6253 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6254 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6255 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6256 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6257 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6258 PPC_SEGMENT
| PPC_EXTERN
;
6259 pcc
->msr_mask
= (1ull << MSR_POW
) |
6275 pcc
->mmu_model
= POWERPC_MMU_32B
;
6276 #if defined(CONFIG_SOFTMMU)
6277 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6279 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6280 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6281 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6282 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6283 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6286 static void init_proc_750gx(CPUPPCState
*env
)
6288 gen_spr_ne_601(env
);
6291 /* XXX : not implemented (XXX: different from 750fx) */
6292 spr_register(env
, SPR_L2CR
, "L2CR",
6293 SPR_NOACCESS
, SPR_NOACCESS
,
6294 &spr_read_generic
, spr_access_nop
,
6298 /* Thermal management */
6300 /* XXX : not implemented */
6301 spr_register(env
, SPR_750_THRM4
, "THRM4",
6302 SPR_NOACCESS
, SPR_NOACCESS
,
6303 &spr_read_generic
, &spr_write_generic
,
6305 /* Hardware implementation registers */
6306 /* XXX : not implemented (XXX: different from 750fx) */
6307 spr_register(env
, SPR_HID0
, "HID0",
6308 SPR_NOACCESS
, SPR_NOACCESS
,
6309 &spr_read_generic
, &spr_write_generic
,
6311 /* XXX : not implemented */
6312 spr_register(env
, SPR_HID1
, "HID1",
6313 SPR_NOACCESS
, SPR_NOACCESS
,
6314 &spr_read_generic
, &spr_write_generic
,
6316 /* XXX : not implemented (XXX: different from 750fx) */
6317 spr_register(env
, SPR_750FX_HID2
, "HID2",
6318 SPR_NOACCESS
, SPR_NOACCESS
,
6319 &spr_read_generic
, &spr_write_generic
,
6321 /* Memory management */
6323 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6326 env
->dcache_line_size
= 32;
6327 env
->icache_line_size
= 32;
6328 /* Allocate hardware IRQ controller */
6329 ppc6xx_irq_init(env_archcpu(env
));
6332 POWERPC_FAMILY(750gx
)(ObjectClass
*oc
, void *data
)
6334 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6335 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6337 dc
->desc
= "PowerPC 750GX";
6338 pcc
->init_proc
= init_proc_750gx
;
6339 pcc
->check_pow
= check_pow_hid0
;
6340 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6341 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6342 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6343 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6344 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6345 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6346 PPC_SEGMENT
| PPC_EXTERN
;
6347 pcc
->msr_mask
= (1ull << MSR_POW
) |
6363 pcc
->mmu_model
= POWERPC_MMU_32B
;
6364 #if defined(CONFIG_SOFTMMU)
6365 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6367 pcc
->excp_model
= POWERPC_EXCP_7x0
;
6368 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6369 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6370 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6371 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6374 static void init_proc_745(CPUPPCState
*env
)
6376 gen_spr_ne_601(env
);
6379 gen_spr_G2_755(env
);
6382 /* Thermal management */
6384 /* Hardware implementation registers */
6385 /* XXX : not implemented */
6386 spr_register(env
, SPR_HID0
, "HID0",
6387 SPR_NOACCESS
, SPR_NOACCESS
,
6388 &spr_read_generic
, &spr_write_generic
,
6390 /* XXX : not implemented */
6391 spr_register(env
, SPR_HID1
, "HID1",
6392 SPR_NOACCESS
, SPR_NOACCESS
,
6393 &spr_read_generic
, &spr_write_generic
,
6395 /* XXX : not implemented */
6396 spr_register(env
, SPR_HID2
, "HID2",
6397 SPR_NOACCESS
, SPR_NOACCESS
,
6398 &spr_read_generic
, &spr_write_generic
,
6400 /* Memory management */
6403 gen_6xx_7xx_soft_tlb(env
, 64, 2);
6405 env
->dcache_line_size
= 32;
6406 env
->icache_line_size
= 32;
6407 /* Allocate hardware IRQ controller */
6408 ppc6xx_irq_init(env_archcpu(env
));
6411 POWERPC_FAMILY(745)(ObjectClass
*oc
, void *data
)
6413 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6414 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6416 dc
->desc
= "PowerPC 745";
6417 pcc
->init_proc
= init_proc_745
;
6418 pcc
->check_pow
= check_pow_hid0
;
6419 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6420 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6421 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6422 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6423 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6424 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
6425 PPC_SEGMENT
| PPC_EXTERN
;
6426 pcc
->msr_mask
= (1ull << MSR_POW
) |
6442 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
6443 pcc
->excp_model
= POWERPC_EXCP_7x5
;
6444 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6445 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6446 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6447 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6450 static void init_proc_755(CPUPPCState
*env
)
6452 gen_spr_ne_601(env
);
6455 gen_spr_G2_755(env
);
6458 /* L2 cache control */
6459 /* XXX : not implemented */
6460 spr_register(env
, SPR_L2CR
, "L2CR",
6461 SPR_NOACCESS
, SPR_NOACCESS
,
6462 &spr_read_generic
, spr_access_nop
,
6464 /* XXX : not implemented */
6465 spr_register(env
, SPR_L2PMCR
, "L2PMCR",
6466 SPR_NOACCESS
, SPR_NOACCESS
,
6467 &spr_read_generic
, &spr_write_generic
,
6469 /* Thermal management */
6471 /* Hardware implementation registers */
6472 /* XXX : not implemented */
6473 spr_register(env
, SPR_HID0
, "HID0",
6474 SPR_NOACCESS
, SPR_NOACCESS
,
6475 &spr_read_generic
, &spr_write_generic
,
6477 /* XXX : not implemented */
6478 spr_register(env
, SPR_HID1
, "HID1",
6479 SPR_NOACCESS
, SPR_NOACCESS
,
6480 &spr_read_generic
, &spr_write_generic
,
6482 /* XXX : not implemented */
6483 spr_register(env
, SPR_HID2
, "HID2",
6484 SPR_NOACCESS
, SPR_NOACCESS
,
6485 &spr_read_generic
, &spr_write_generic
,
6487 /* Memory management */
6490 gen_6xx_7xx_soft_tlb(env
, 64, 2);
6492 env
->dcache_line_size
= 32;
6493 env
->icache_line_size
= 32;
6494 /* Allocate hardware IRQ controller */
6495 ppc6xx_irq_init(env_archcpu(env
));
6498 POWERPC_FAMILY(755)(ObjectClass
*oc
, void *data
)
6500 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6501 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6503 dc
->desc
= "PowerPC 755";
6504 pcc
->init_proc
= init_proc_755
;
6505 pcc
->check_pow
= check_pow_hid0
;
6506 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6507 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6508 PPC_FLOAT_FRSQRTE
| PPC_FLOAT_STFIWX
|
6509 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
6510 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6511 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
| PPC_6xx_TLB
|
6512 PPC_SEGMENT
| PPC_EXTERN
;
6513 pcc
->msr_mask
= (1ull << MSR_POW
) |
6529 pcc
->mmu_model
= POWERPC_MMU_SOFT_6xx
;
6530 pcc
->excp_model
= POWERPC_EXCP_7x5
;
6531 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6532 pcc
->bfd_mach
= bfd_mach_ppc_750
;
6533 pcc
->flags
= POWERPC_FLAG_SE
| POWERPC_FLAG_BE
|
6534 POWERPC_FLAG_PMM
| POWERPC_FLAG_BUS_CLK
;
6537 static void init_proc_7400(CPUPPCState
*env
)
6539 gen_spr_ne_601(env
);
6544 /* 74xx specific SPR */
6546 /* XXX : not implemented */
6547 spr_register(env
, SPR_UBAMR
, "UBAMR",
6548 &spr_read_ureg
, SPR_NOACCESS
,
6549 &spr_read_ureg
, SPR_NOACCESS
,
6551 /* XXX: this seems not implemented on all revisions. */
6552 /* XXX : not implemented */
6553 spr_register(env
, SPR_MSSCR1
, "MSSCR1",
6554 SPR_NOACCESS
, SPR_NOACCESS
,
6555 &spr_read_generic
, &spr_write_generic
,
6557 /* Thermal management */
6559 /* Memory management */
6561 init_excp_7400(env
);
6562 env
->dcache_line_size
= 32;
6563 env
->icache_line_size
= 32;
6564 /* Allocate hardware IRQ controller */
6565 ppc6xx_irq_init(env_archcpu(env
));
6568 POWERPC_FAMILY(7400)(ObjectClass
*oc
, void *data
)
6570 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6571 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6573 dc
->desc
= "PowerPC 7400 (aka G4)";
6574 pcc
->init_proc
= init_proc_7400
;
6575 pcc
->check_pow
= check_pow_hid0
;
6576 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6577 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6578 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6580 PPC_CACHE
| PPC_CACHE_ICBI
|
6581 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6582 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6583 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6585 PPC_SEGMENT
| PPC_EXTERN
|
6587 pcc
->msr_mask
= (1ull << MSR_VR
) |
6604 pcc
->mmu_model
= POWERPC_MMU_32B
;
6605 #if defined(CONFIG_SOFTMMU)
6606 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6608 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6609 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6610 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6611 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6612 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6613 POWERPC_FLAG_BUS_CLK
;
6616 static void init_proc_7410(CPUPPCState
*env
)
6618 gen_spr_ne_601(env
);
6623 /* 74xx specific SPR */
6625 /* XXX : not implemented */
6626 spr_register(env
, SPR_UBAMR
, "UBAMR",
6627 &spr_read_ureg
, SPR_NOACCESS
,
6628 &spr_read_ureg
, SPR_NOACCESS
,
6630 /* Thermal management */
6633 /* XXX : not implemented */
6634 spr_register(env
, SPR_L2PMCR
, "L2PMCR",
6635 SPR_NOACCESS
, SPR_NOACCESS
,
6636 &spr_read_generic
, &spr_write_generic
,
6639 /* XXX : not implemented */
6640 spr_register(env
, SPR_LDSTDB
, "LDSTDB",
6641 SPR_NOACCESS
, SPR_NOACCESS
,
6642 &spr_read_generic
, &spr_write_generic
,
6644 /* Memory management */
6646 init_excp_7400(env
);
6647 env
->dcache_line_size
= 32;
6648 env
->icache_line_size
= 32;
6649 /* Allocate hardware IRQ controller */
6650 ppc6xx_irq_init(env_archcpu(env
));
6653 POWERPC_FAMILY(7410)(ObjectClass
*oc
, void *data
)
6655 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6656 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6658 dc
->desc
= "PowerPC 7410 (aka G4)";
6659 pcc
->init_proc
= init_proc_7410
;
6660 pcc
->check_pow
= check_pow_hid0
;
6661 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6662 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6663 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6665 PPC_CACHE
| PPC_CACHE_ICBI
|
6666 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6667 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6668 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6670 PPC_SEGMENT
| PPC_EXTERN
|
6672 pcc
->msr_mask
= (1ull << MSR_VR
) |
6689 pcc
->mmu_model
= POWERPC_MMU_32B
;
6690 #if defined(CONFIG_SOFTMMU)
6691 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
6693 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6694 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6695 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6696 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6697 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6698 POWERPC_FLAG_BUS_CLK
;
6701 static void init_proc_7440(CPUPPCState
*env
)
6703 gen_spr_ne_601(env
);
6708 /* 74xx specific SPR */
6710 /* XXX : not implemented */
6711 spr_register(env
, SPR_UBAMR
, "UBAMR",
6712 &spr_read_ureg
, SPR_NOACCESS
,
6713 &spr_read_ureg
, SPR_NOACCESS
,
6716 /* XXX : not implemented */
6717 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6718 SPR_NOACCESS
, SPR_NOACCESS
,
6719 &spr_read_generic
, &spr_write_generic
,
6722 /* XXX : not implemented */
6723 spr_register(env
, SPR_ICTRL
, "ICTRL",
6724 SPR_NOACCESS
, SPR_NOACCESS
,
6725 &spr_read_generic
, &spr_write_generic
,
6728 /* XXX : not implemented */
6729 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6730 SPR_NOACCESS
, SPR_NOACCESS
,
6731 &spr_read_generic
, &spr_write_generic
,
6734 /* XXX : not implemented */
6735 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6736 SPR_NOACCESS
, SPR_NOACCESS
,
6737 &spr_read_generic
, &spr_write_generic
,
6739 /* XXX : not implemented */
6740 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6741 &spr_read_ureg
, SPR_NOACCESS
,
6742 &spr_read_ureg
, SPR_NOACCESS
,
6744 /* XXX : not implemented */
6745 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6746 SPR_NOACCESS
, SPR_NOACCESS
,
6747 &spr_read_generic
, &spr_write_generic
,
6749 /* XXX : not implemented */
6750 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6751 &spr_read_ureg
, SPR_NOACCESS
,
6752 &spr_read_ureg
, SPR_NOACCESS
,
6754 /* Memory management */
6756 gen_74xx_soft_tlb(env
, 128, 2);
6757 init_excp_7450(env
);
6758 env
->dcache_line_size
= 32;
6759 env
->icache_line_size
= 32;
6760 /* Allocate hardware IRQ controller */
6761 ppc6xx_irq_init(env_archcpu(env
));
6764 POWERPC_FAMILY(7440)(ObjectClass
*oc
, void *data
)
6766 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6767 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6769 dc
->desc
= "PowerPC 7440 (aka G4)";
6770 pcc
->init_proc
= init_proc_7440
;
6771 pcc
->check_pow
= check_pow_hid0_74xx
;
6772 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6773 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6774 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6776 PPC_CACHE
| PPC_CACHE_ICBI
|
6777 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6778 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6779 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6780 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6781 PPC_SEGMENT
| PPC_EXTERN
|
6783 pcc
->msr_mask
= (1ull << MSR_VR
) |
6800 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6801 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6802 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6803 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6804 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6805 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6806 POWERPC_FLAG_BUS_CLK
;
6809 static void init_proc_7450(CPUPPCState
*env
)
6811 gen_spr_ne_601(env
);
6816 /* 74xx specific SPR */
6818 /* Level 3 cache control */
6821 /* XXX : not implemented */
6822 spr_register(env
, SPR_L3ITCR1
, "L3ITCR1",
6823 SPR_NOACCESS
, SPR_NOACCESS
,
6824 &spr_read_generic
, &spr_write_generic
,
6827 /* XXX : not implemented */
6828 spr_register(env
, SPR_L3ITCR2
, "L3ITCR2",
6829 SPR_NOACCESS
, SPR_NOACCESS
,
6830 &spr_read_generic
, &spr_write_generic
,
6833 /* XXX : not implemented */
6834 spr_register(env
, SPR_L3ITCR3
, "L3ITCR3",
6835 SPR_NOACCESS
, SPR_NOACCESS
,
6836 &spr_read_generic
, &spr_write_generic
,
6839 /* XXX : not implemented */
6840 spr_register(env
, SPR_L3OHCR
, "L3OHCR",
6841 SPR_NOACCESS
, SPR_NOACCESS
,
6842 &spr_read_generic
, &spr_write_generic
,
6844 /* XXX : not implemented */
6845 spr_register(env
, SPR_UBAMR
, "UBAMR",
6846 &spr_read_ureg
, SPR_NOACCESS
,
6847 &spr_read_ureg
, SPR_NOACCESS
,
6850 /* XXX : not implemented */
6851 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6852 SPR_NOACCESS
, SPR_NOACCESS
,
6853 &spr_read_generic
, &spr_write_generic
,
6856 /* XXX : not implemented */
6857 spr_register(env
, SPR_ICTRL
, "ICTRL",
6858 SPR_NOACCESS
, SPR_NOACCESS
,
6859 &spr_read_generic
, &spr_write_generic
,
6862 /* XXX : not implemented */
6863 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6864 SPR_NOACCESS
, SPR_NOACCESS
,
6865 &spr_read_generic
, &spr_write_generic
,
6868 /* XXX : not implemented */
6869 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6870 SPR_NOACCESS
, SPR_NOACCESS
,
6871 &spr_read_generic
, &spr_write_generic
,
6873 /* XXX : not implemented */
6874 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6875 &spr_read_ureg
, SPR_NOACCESS
,
6876 &spr_read_ureg
, SPR_NOACCESS
,
6878 /* XXX : not implemented */
6879 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6880 SPR_NOACCESS
, SPR_NOACCESS
,
6881 &spr_read_generic
, &spr_write_generic
,
6883 /* XXX : not implemented */
6884 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6885 &spr_read_ureg
, SPR_NOACCESS
,
6886 &spr_read_ureg
, SPR_NOACCESS
,
6888 /* Memory management */
6890 gen_74xx_soft_tlb(env
, 128, 2);
6891 init_excp_7450(env
);
6892 env
->dcache_line_size
= 32;
6893 env
->icache_line_size
= 32;
6894 /* Allocate hardware IRQ controller */
6895 ppc6xx_irq_init(env_archcpu(env
));
6898 POWERPC_FAMILY(7450)(ObjectClass
*oc
, void *data
)
6900 DeviceClass
*dc
= DEVICE_CLASS(oc
);
6901 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
6903 dc
->desc
= "PowerPC 7450 (aka G4)";
6904 pcc
->init_proc
= init_proc_7450
;
6905 pcc
->check_pow
= check_pow_hid0_74xx
;
6906 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
6907 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
6908 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
6910 PPC_CACHE
| PPC_CACHE_ICBI
|
6911 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
6912 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
6913 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
6914 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
6915 PPC_SEGMENT
| PPC_EXTERN
|
6917 pcc
->msr_mask
= (1ull << MSR_VR
) |
6934 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
6935 pcc
->excp_model
= POWERPC_EXCP_74xx
;
6936 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
6937 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
6938 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
6939 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
6940 POWERPC_FLAG_BUS_CLK
;
6943 static void init_proc_7445(CPUPPCState
*env
)
6945 gen_spr_ne_601(env
);
6950 /* 74xx specific SPR */
6953 /* XXX : not implemented */
6954 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
6955 SPR_NOACCESS
, SPR_NOACCESS
,
6956 &spr_read_generic
, &spr_write_generic
,
6959 /* XXX : not implemented */
6960 spr_register(env
, SPR_ICTRL
, "ICTRL",
6961 SPR_NOACCESS
, SPR_NOACCESS
,
6962 &spr_read_generic
, &spr_write_generic
,
6965 /* XXX : not implemented */
6966 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
6967 SPR_NOACCESS
, SPR_NOACCESS
,
6968 &spr_read_generic
, &spr_write_generic
,
6971 /* XXX : not implemented */
6972 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
6973 SPR_NOACCESS
, SPR_NOACCESS
,
6974 &spr_read_generic
, &spr_write_generic
,
6976 /* XXX : not implemented */
6977 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
6978 &spr_read_ureg
, SPR_NOACCESS
,
6979 &spr_read_ureg
, SPR_NOACCESS
,
6981 /* XXX : not implemented */
6982 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
6983 SPR_NOACCESS
, SPR_NOACCESS
,
6984 &spr_read_generic
, &spr_write_generic
,
6986 /* XXX : not implemented */
6987 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
6988 &spr_read_ureg
, SPR_NOACCESS
,
6989 &spr_read_ureg
, SPR_NOACCESS
,
6992 spr_register(env
, SPR_SPRG4
, "SPRG4",
6993 SPR_NOACCESS
, SPR_NOACCESS
,
6994 &spr_read_generic
, &spr_write_generic
,
6996 spr_register(env
, SPR_USPRG4
, "USPRG4",
6997 &spr_read_ureg
, SPR_NOACCESS
,
6998 &spr_read_ureg
, SPR_NOACCESS
,
7000 spr_register(env
, SPR_SPRG5
, "SPRG5",
7001 SPR_NOACCESS
, SPR_NOACCESS
,
7002 &spr_read_generic
, &spr_write_generic
,
7004 spr_register(env
, SPR_USPRG5
, "USPRG5",
7005 &spr_read_ureg
, SPR_NOACCESS
,
7006 &spr_read_ureg
, SPR_NOACCESS
,
7008 spr_register(env
, SPR_SPRG6
, "SPRG6",
7009 SPR_NOACCESS
, SPR_NOACCESS
,
7010 &spr_read_generic
, &spr_write_generic
,
7012 spr_register(env
, SPR_USPRG6
, "USPRG6",
7013 &spr_read_ureg
, SPR_NOACCESS
,
7014 &spr_read_ureg
, SPR_NOACCESS
,
7016 spr_register(env
, SPR_SPRG7
, "SPRG7",
7017 SPR_NOACCESS
, SPR_NOACCESS
,
7018 &spr_read_generic
, &spr_write_generic
,
7020 spr_register(env
, SPR_USPRG7
, "USPRG7",
7021 &spr_read_ureg
, SPR_NOACCESS
,
7022 &spr_read_ureg
, SPR_NOACCESS
,
7024 /* Memory management */
7027 gen_74xx_soft_tlb(env
, 128, 2);
7028 init_excp_7450(env
);
7029 env
->dcache_line_size
= 32;
7030 env
->icache_line_size
= 32;
7031 /* Allocate hardware IRQ controller */
7032 ppc6xx_irq_init(env_archcpu(env
));
7035 POWERPC_FAMILY(7445)(ObjectClass
*oc
, void *data
)
7037 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7038 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7040 dc
->desc
= "PowerPC 7445 (aka G4)";
7041 pcc
->init_proc
= init_proc_7445
;
7042 pcc
->check_pow
= check_pow_hid0_74xx
;
7043 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7044 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7045 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7047 PPC_CACHE
| PPC_CACHE_ICBI
|
7048 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7049 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7050 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7051 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7052 PPC_SEGMENT
| PPC_EXTERN
|
7054 pcc
->msr_mask
= (1ull << MSR_VR
) |
7071 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7072 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7073 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7074 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7075 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7076 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7077 POWERPC_FLAG_BUS_CLK
;
7080 static void init_proc_7455(CPUPPCState
*env
)
7082 gen_spr_ne_601(env
);
7087 /* 74xx specific SPR */
7089 /* Level 3 cache control */
7092 /* XXX : not implemented */
7093 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7094 SPR_NOACCESS
, SPR_NOACCESS
,
7095 &spr_read_generic
, &spr_write_generic
,
7098 /* XXX : not implemented */
7099 spr_register(env
, SPR_ICTRL
, "ICTRL",
7100 SPR_NOACCESS
, SPR_NOACCESS
,
7101 &spr_read_generic
, &spr_write_generic
,
7104 /* XXX : not implemented */
7105 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7106 SPR_NOACCESS
, SPR_NOACCESS
,
7107 &spr_read_generic
, &spr_write_generic
,
7110 /* XXX : not implemented */
7111 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7112 SPR_NOACCESS
, SPR_NOACCESS
,
7113 &spr_read_generic
, &spr_write_generic
,
7115 /* XXX : not implemented */
7116 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7117 &spr_read_ureg
, SPR_NOACCESS
,
7118 &spr_read_ureg
, SPR_NOACCESS
,
7120 /* XXX : not implemented */
7121 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7122 SPR_NOACCESS
, SPR_NOACCESS
,
7123 &spr_read_generic
, &spr_write_generic
,
7125 /* XXX : not implemented */
7126 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7127 &spr_read_ureg
, SPR_NOACCESS
,
7128 &spr_read_ureg
, SPR_NOACCESS
,
7131 spr_register(env
, SPR_SPRG4
, "SPRG4",
7132 SPR_NOACCESS
, SPR_NOACCESS
,
7133 &spr_read_generic
, &spr_write_generic
,
7135 spr_register(env
, SPR_USPRG4
, "USPRG4",
7136 &spr_read_ureg
, SPR_NOACCESS
,
7137 &spr_read_ureg
, SPR_NOACCESS
,
7139 spr_register(env
, SPR_SPRG5
, "SPRG5",
7140 SPR_NOACCESS
, SPR_NOACCESS
,
7141 &spr_read_generic
, &spr_write_generic
,
7143 spr_register(env
, SPR_USPRG5
, "USPRG5",
7144 &spr_read_ureg
, SPR_NOACCESS
,
7145 &spr_read_ureg
, SPR_NOACCESS
,
7147 spr_register(env
, SPR_SPRG6
, "SPRG6",
7148 SPR_NOACCESS
, SPR_NOACCESS
,
7149 &spr_read_generic
, &spr_write_generic
,
7151 spr_register(env
, SPR_USPRG6
, "USPRG6",
7152 &spr_read_ureg
, SPR_NOACCESS
,
7153 &spr_read_ureg
, SPR_NOACCESS
,
7155 spr_register(env
, SPR_SPRG7
, "SPRG7",
7156 SPR_NOACCESS
, SPR_NOACCESS
,
7157 &spr_read_generic
, &spr_write_generic
,
7159 spr_register(env
, SPR_USPRG7
, "USPRG7",
7160 &spr_read_ureg
, SPR_NOACCESS
,
7161 &spr_read_ureg
, SPR_NOACCESS
,
7163 /* Memory management */
7166 gen_74xx_soft_tlb(env
, 128, 2);
7167 init_excp_7450(env
);
7168 env
->dcache_line_size
= 32;
7169 env
->icache_line_size
= 32;
7170 /* Allocate hardware IRQ controller */
7171 ppc6xx_irq_init(env_archcpu(env
));
7174 POWERPC_FAMILY(7455)(ObjectClass
*oc
, void *data
)
7176 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7177 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7179 dc
->desc
= "PowerPC 7455 (aka G4)";
7180 pcc
->init_proc
= init_proc_7455
;
7181 pcc
->check_pow
= check_pow_hid0_74xx
;
7182 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7183 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7184 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7186 PPC_CACHE
| PPC_CACHE_ICBI
|
7187 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7188 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7189 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7190 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7191 PPC_SEGMENT
| PPC_EXTERN
|
7193 pcc
->msr_mask
= (1ull << MSR_VR
) |
7210 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7211 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7212 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7213 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7214 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7215 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7216 POWERPC_FLAG_BUS_CLK
;
7219 static void init_proc_7457(CPUPPCState
*env
)
7221 gen_spr_ne_601(env
);
7226 /* 74xx specific SPR */
7228 /* Level 3 cache control */
7231 /* XXX : not implemented */
7232 spr_register(env
, SPR_L3ITCR1
, "L3ITCR1",
7233 SPR_NOACCESS
, SPR_NOACCESS
,
7234 &spr_read_generic
, &spr_write_generic
,
7237 /* XXX : not implemented */
7238 spr_register(env
, SPR_L3ITCR2
, "L3ITCR2",
7239 SPR_NOACCESS
, SPR_NOACCESS
,
7240 &spr_read_generic
, &spr_write_generic
,
7243 /* XXX : not implemented */
7244 spr_register(env
, SPR_L3ITCR3
, "L3ITCR3",
7245 SPR_NOACCESS
, SPR_NOACCESS
,
7246 &spr_read_generic
, &spr_write_generic
,
7249 /* XXX : not implemented */
7250 spr_register(env
, SPR_L3OHCR
, "L3OHCR",
7251 SPR_NOACCESS
, SPR_NOACCESS
,
7252 &spr_read_generic
, &spr_write_generic
,
7255 /* XXX : not implemented */
7256 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7257 SPR_NOACCESS
, SPR_NOACCESS
,
7258 &spr_read_generic
, &spr_write_generic
,
7261 /* XXX : not implemented */
7262 spr_register(env
, SPR_ICTRL
, "ICTRL",
7263 SPR_NOACCESS
, SPR_NOACCESS
,
7264 &spr_read_generic
, &spr_write_generic
,
7267 /* XXX : not implemented */
7268 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7269 SPR_NOACCESS
, SPR_NOACCESS
,
7270 &spr_read_generic
, &spr_write_generic
,
7273 /* XXX : not implemented */
7274 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7275 SPR_NOACCESS
, SPR_NOACCESS
,
7276 &spr_read_generic
, &spr_write_generic
,
7278 /* XXX : not implemented */
7279 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7280 &spr_read_ureg
, SPR_NOACCESS
,
7281 &spr_read_ureg
, SPR_NOACCESS
,
7283 /* XXX : not implemented */
7284 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7285 SPR_NOACCESS
, SPR_NOACCESS
,
7286 &spr_read_generic
, &spr_write_generic
,
7288 /* XXX : not implemented */
7289 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7290 &spr_read_ureg
, SPR_NOACCESS
,
7291 &spr_read_ureg
, SPR_NOACCESS
,
7294 spr_register(env
, SPR_SPRG4
, "SPRG4",
7295 SPR_NOACCESS
, SPR_NOACCESS
,
7296 &spr_read_generic
, &spr_write_generic
,
7298 spr_register(env
, SPR_USPRG4
, "USPRG4",
7299 &spr_read_ureg
, SPR_NOACCESS
,
7300 &spr_read_ureg
, SPR_NOACCESS
,
7302 spr_register(env
, SPR_SPRG5
, "SPRG5",
7303 SPR_NOACCESS
, SPR_NOACCESS
,
7304 &spr_read_generic
, &spr_write_generic
,
7306 spr_register(env
, SPR_USPRG5
, "USPRG5",
7307 &spr_read_ureg
, SPR_NOACCESS
,
7308 &spr_read_ureg
, SPR_NOACCESS
,
7310 spr_register(env
, SPR_SPRG6
, "SPRG6",
7311 SPR_NOACCESS
, SPR_NOACCESS
,
7312 &spr_read_generic
, &spr_write_generic
,
7314 spr_register(env
, SPR_USPRG6
, "USPRG6",
7315 &spr_read_ureg
, SPR_NOACCESS
,
7316 &spr_read_ureg
, SPR_NOACCESS
,
7318 spr_register(env
, SPR_SPRG7
, "SPRG7",
7319 SPR_NOACCESS
, SPR_NOACCESS
,
7320 &spr_read_generic
, &spr_write_generic
,
7322 spr_register(env
, SPR_USPRG7
, "USPRG7",
7323 &spr_read_ureg
, SPR_NOACCESS
,
7324 &spr_read_ureg
, SPR_NOACCESS
,
7326 /* Memory management */
7329 gen_74xx_soft_tlb(env
, 128, 2);
7330 init_excp_7450(env
);
7331 env
->dcache_line_size
= 32;
7332 env
->icache_line_size
= 32;
7333 /* Allocate hardware IRQ controller */
7334 ppc6xx_irq_init(env_archcpu(env
));
7337 POWERPC_FAMILY(7457)(ObjectClass
*oc
, void *data
)
7339 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7340 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7342 dc
->desc
= "PowerPC 7457 (aka G4)";
7343 pcc
->init_proc
= init_proc_7457
;
7344 pcc
->check_pow
= check_pow_hid0_74xx
;
7345 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7346 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7347 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7349 PPC_CACHE
| PPC_CACHE_ICBI
|
7350 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7351 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7352 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7353 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7354 PPC_SEGMENT
| PPC_EXTERN
|
7356 pcc
->msr_mask
= (1ull << MSR_VR
) |
7373 pcc
->mmu_model
= POWERPC_MMU_SOFT_74xx
;
7374 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7375 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7376 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7377 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7378 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7379 POWERPC_FLAG_BUS_CLK
;
7382 static void init_proc_e600(CPUPPCState
*env
)
7384 gen_spr_ne_601(env
);
7389 /* 74xx specific SPR */
7391 /* XXX : not implemented */
7392 spr_register(env
, SPR_UBAMR
, "UBAMR",
7393 &spr_read_ureg
, SPR_NOACCESS
,
7394 &spr_read_ureg
, SPR_NOACCESS
,
7396 /* XXX : not implemented */
7397 spr_register(env
, SPR_LDSTCR
, "LDSTCR",
7398 SPR_NOACCESS
, SPR_NOACCESS
,
7399 &spr_read_generic
, &spr_write_generic
,
7401 /* XXX : not implemented */
7402 spr_register(env
, SPR_ICTRL
, "ICTRL",
7403 SPR_NOACCESS
, SPR_NOACCESS
,
7404 &spr_read_generic
, &spr_write_generic
,
7406 /* XXX : not implemented */
7407 spr_register(env
, SPR_MSSSR0
, "MSSSR0",
7408 SPR_NOACCESS
, SPR_NOACCESS
,
7409 &spr_read_generic
, &spr_write_generic
,
7411 /* XXX : not implemented */
7412 spr_register(env
, SPR_7XX_PMC5
, "PMC5",
7413 SPR_NOACCESS
, SPR_NOACCESS
,
7414 &spr_read_generic
, &spr_write_generic
,
7416 /* XXX : not implemented */
7417 spr_register(env
, SPR_7XX_UPMC5
, "UPMC5",
7418 &spr_read_ureg
, SPR_NOACCESS
,
7419 &spr_read_ureg
, SPR_NOACCESS
,
7421 /* XXX : not implemented */
7422 spr_register(env
, SPR_7XX_PMC6
, "PMC6",
7423 SPR_NOACCESS
, SPR_NOACCESS
,
7424 &spr_read_generic
, &spr_write_generic
,
7426 /* XXX : not implemented */
7427 spr_register(env
, SPR_7XX_UPMC6
, "UPMC6",
7428 &spr_read_ureg
, SPR_NOACCESS
,
7429 &spr_read_ureg
, SPR_NOACCESS
,
7432 spr_register(env
, SPR_SPRG4
, "SPRG4",
7433 SPR_NOACCESS
, SPR_NOACCESS
,
7434 &spr_read_generic
, &spr_write_generic
,
7436 spr_register(env
, SPR_USPRG4
, "USPRG4",
7437 &spr_read_ureg
, SPR_NOACCESS
,
7438 &spr_read_ureg
, SPR_NOACCESS
,
7440 spr_register(env
, SPR_SPRG5
, "SPRG5",
7441 SPR_NOACCESS
, SPR_NOACCESS
,
7442 &spr_read_generic
, &spr_write_generic
,
7444 spr_register(env
, SPR_USPRG5
, "USPRG5",
7445 &spr_read_ureg
, SPR_NOACCESS
,
7446 &spr_read_ureg
, SPR_NOACCESS
,
7448 spr_register(env
, SPR_SPRG6
, "SPRG6",
7449 SPR_NOACCESS
, SPR_NOACCESS
,
7450 &spr_read_generic
, &spr_write_generic
,
7452 spr_register(env
, SPR_USPRG6
, "USPRG6",
7453 &spr_read_ureg
, SPR_NOACCESS
,
7454 &spr_read_ureg
, SPR_NOACCESS
,
7456 spr_register(env
, SPR_SPRG7
, "SPRG7",
7457 SPR_NOACCESS
, SPR_NOACCESS
,
7458 &spr_read_generic
, &spr_write_generic
,
7460 spr_register(env
, SPR_USPRG7
, "USPRG7",
7461 &spr_read_ureg
, SPR_NOACCESS
,
7462 &spr_read_ureg
, SPR_NOACCESS
,
7464 /* Memory management */
7467 gen_74xx_soft_tlb(env
, 128, 2);
7468 init_excp_7450(env
);
7469 env
->dcache_line_size
= 32;
7470 env
->icache_line_size
= 32;
7471 /* Allocate hardware IRQ controller */
7472 ppc6xx_irq_init(env_archcpu(env
));
7475 POWERPC_FAMILY(e600
)(ObjectClass
*oc
, void *data
)
7477 DeviceClass
*dc
= DEVICE_CLASS(oc
);
7478 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
7480 dc
->desc
= "PowerPC e600";
7481 pcc
->init_proc
= init_proc_e600
;
7482 pcc
->check_pow
= check_pow_hid0_74xx
;
7483 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
7484 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
7485 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
7487 PPC_CACHE
| PPC_CACHE_ICBI
|
7488 PPC_CACHE_DCBA
| PPC_CACHE_DCBZ
|
7489 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
7490 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
7491 PPC_MEM_TLBIA
| PPC_74xx_TLB
|
7492 PPC_SEGMENT
| PPC_EXTERN
|
7494 pcc
->insns_flags2
= PPC_NONE
;
7495 pcc
->msr_mask
= (1ull << MSR_VR
) |
7512 pcc
->mmu_model
= POWERPC_MMU_32B
;
7513 #if defined(CONFIG_SOFTMMU)
7514 pcc
->handle_mmu_fault
= ppc_hash32_handle_mmu_fault
;
7516 pcc
->excp_model
= POWERPC_EXCP_74xx
;
7517 pcc
->bus_model
= PPC_FLAGS_INPUT_6xx
;
7518 pcc
->bfd_mach
= bfd_mach_ppc_7400
;
7519 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
7520 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
7521 POWERPC_FLAG_BUS_CLK
;
7524 #if defined(TARGET_PPC64)
7525 #if defined(CONFIG_USER_ONLY)
7526 #define POWERPC970_HID5_INIT 0x00000080
7528 #define POWERPC970_HID5_INIT 0x00000000
7531 static void gen_fscr_facility_check(DisasContext
*ctx
, int facility_sprn
,
7532 int bit
, int sprn
, int cause
)
7534 TCGv_i32 t1
= tcg_const_i32(bit
);
7535 TCGv_i32 t2
= tcg_const_i32(sprn
);
7536 TCGv_i32 t3
= tcg_const_i32(cause
);
7538 gen_helper_fscr_facility_check(cpu_env
, t1
, t2
, t3
);
7540 tcg_temp_free_i32(t3
);
7541 tcg_temp_free_i32(t2
);
7542 tcg_temp_free_i32(t1
);
7545 static void gen_msr_facility_check(DisasContext
*ctx
, int facility_sprn
,
7546 int bit
, int sprn
, int cause
)
7548 TCGv_i32 t1
= tcg_const_i32(bit
);
7549 TCGv_i32 t2
= tcg_const_i32(sprn
);
7550 TCGv_i32 t3
= tcg_const_i32(cause
);
7552 gen_helper_msr_facility_check(cpu_env
, t1
, t2
, t3
);
7554 tcg_temp_free_i32(t3
);
7555 tcg_temp_free_i32(t2
);
7556 tcg_temp_free_i32(t1
);
7559 static void spr_read_prev_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
7561 TCGv spr_up
= tcg_temp_new();
7562 TCGv spr
= tcg_temp_new();
7564 gen_load_spr(spr
, sprn
- 1);
7565 tcg_gen_shri_tl(spr_up
, spr
, 32);
7566 tcg_gen_ext32u_tl(cpu_gpr
[gprn
], spr_up
);
7569 tcg_temp_free(spr_up
);
7572 static void spr_write_prev_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
7574 TCGv spr
= tcg_temp_new();
7576 gen_load_spr(spr
, sprn
- 1);
7577 tcg_gen_deposit_tl(spr
, spr
, cpu_gpr
[gprn
], 32, 32);
7578 gen_store_spr(sprn
- 1, spr
);
7583 static int check_pow_970(CPUPPCState
*env
)
7585 if (env
->spr
[SPR_HID0
] & (HID0_DEEPNAP
| HID0_DOZE
| HID0_NAP
)) {
7592 static void gen_spr_970_hid(CPUPPCState
*env
)
7594 /* Hardware implementation registers */
7595 /* XXX : not implemented */
7596 spr_register(env
, SPR_HID0
, "HID0",
7597 SPR_NOACCESS
, SPR_NOACCESS
,
7598 &spr_read_generic
, &spr_write_clear
,
7600 spr_register(env
, SPR_HID1
, "HID1",
7601 SPR_NOACCESS
, SPR_NOACCESS
,
7602 &spr_read_generic
, &spr_write_generic
,
7604 spr_register(env
, SPR_970_HID5
, "HID5",
7605 SPR_NOACCESS
, SPR_NOACCESS
,
7606 &spr_read_generic
, &spr_write_generic
,
7607 POWERPC970_HID5_INIT
);
7610 static void gen_spr_970_hior(CPUPPCState
*env
)
7612 spr_register(env
, SPR_HIOR
, "SPR_HIOR",
7613 SPR_NOACCESS
, SPR_NOACCESS
,
7614 &spr_read_hior
, &spr_write_hior
,
7618 static void gen_spr_book3s_ctrl(CPUPPCState
*env
)
7620 spr_register(env
, SPR_CTRL
, "SPR_CTRL",
7621 SPR_NOACCESS
, SPR_NOACCESS
,
7622 SPR_NOACCESS
, &spr_write_generic
,
7624 spr_register(env
, SPR_UCTRL
, "SPR_UCTRL",
7625 &spr_read_ureg
, SPR_NOACCESS
,
7626 &spr_read_ureg
, SPR_NOACCESS
,
7630 static void gen_spr_book3s_altivec(CPUPPCState
*env
)
7632 if (!(env
->insns_flags
& PPC_ALTIVEC
)) {
7636 spr_register_kvm(env
, SPR_VRSAVE
, "VRSAVE",
7637 &spr_read_generic
, &spr_write_generic
,
7638 &spr_read_generic
, &spr_write_generic
,
7639 KVM_REG_PPC_VRSAVE
, 0x00000000);
7642 * Can't find information on what this should be on reset. This
7643 * value is the one used by 74xx processors.
7645 vscr_init(env
, 0x00010000);
7648 static void gen_spr_book3s_dbg(CPUPPCState
*env
)
7651 * TODO: different specs define different scopes for these,
7652 * will have to address this:
7653 * 970: super/write and super/read
7654 * powerisa 2.03..2.04: hypv/write and super/read.
7655 * powerisa 2.05 and newer: hypv/write and hypv/read.
7657 spr_register_kvm(env
, SPR_DABR
, "DABR",
7658 SPR_NOACCESS
, SPR_NOACCESS
,
7659 &spr_read_generic
, &spr_write_generic
,
7660 KVM_REG_PPC_DABR
, 0x00000000);
7661 spr_register_kvm(env
, SPR_DABRX
, "DABRX",
7662 SPR_NOACCESS
, SPR_NOACCESS
,
7663 &spr_read_generic
, &spr_write_generic
,
7664 KVM_REG_PPC_DABRX
, 0x00000000);
7667 static void gen_spr_book3s_207_dbg(CPUPPCState
*env
)
7669 spr_register_kvm_hv(env
, SPR_DAWR
, "DAWR",
7670 SPR_NOACCESS
, SPR_NOACCESS
,
7671 SPR_NOACCESS
, SPR_NOACCESS
,
7672 &spr_read_generic
, &spr_write_generic
,
7673 KVM_REG_PPC_DAWR
, 0x00000000);
7674 spr_register_kvm_hv(env
, SPR_DAWRX
, "DAWRX",
7675 SPR_NOACCESS
, SPR_NOACCESS
,
7676 SPR_NOACCESS
, SPR_NOACCESS
,
7677 &spr_read_generic
, &spr_write_generic
,
7678 KVM_REG_PPC_DAWRX
, 0x00000000);
7679 spr_register_kvm_hv(env
, SPR_CIABR
, "CIABR",
7680 SPR_NOACCESS
, SPR_NOACCESS
,
7681 SPR_NOACCESS
, SPR_NOACCESS
,
7682 &spr_read_generic
, &spr_write_generic
,
7683 KVM_REG_PPC_CIABR
, 0x00000000);
7686 static void gen_spr_970_dbg(CPUPPCState
*env
)
7689 spr_register(env
, SPR_IABR
, "IABR",
7690 SPR_NOACCESS
, SPR_NOACCESS
,
7691 &spr_read_generic
, &spr_write_generic
,
7695 static void gen_spr_book3s_pmu_sup(CPUPPCState
*env
)
7697 spr_register_kvm(env
, SPR_POWER_MMCR0
, "MMCR0",
7698 SPR_NOACCESS
, SPR_NOACCESS
,
7699 &spr_read_generic
, &spr_write_generic
,
7700 KVM_REG_PPC_MMCR0
, 0x00000000);
7701 spr_register_kvm(env
, SPR_POWER_MMCR1
, "MMCR1",
7702 SPR_NOACCESS
, SPR_NOACCESS
,
7703 &spr_read_generic
, &spr_write_generic
,
7704 KVM_REG_PPC_MMCR1
, 0x00000000);
7705 spr_register_kvm(env
, SPR_POWER_MMCRA
, "MMCRA",
7706 SPR_NOACCESS
, SPR_NOACCESS
,
7707 &spr_read_generic
, &spr_write_generic
,
7708 KVM_REG_PPC_MMCRA
, 0x00000000);
7709 spr_register_kvm(env
, SPR_POWER_PMC1
, "PMC1",
7710 SPR_NOACCESS
, SPR_NOACCESS
,
7711 &spr_read_generic
, &spr_write_generic
,
7712 KVM_REG_PPC_PMC1
, 0x00000000);
7713 spr_register_kvm(env
, SPR_POWER_PMC2
, "PMC2",
7714 SPR_NOACCESS
, SPR_NOACCESS
,
7715 &spr_read_generic
, &spr_write_generic
,
7716 KVM_REG_PPC_PMC2
, 0x00000000);
7717 spr_register_kvm(env
, SPR_POWER_PMC3
, "PMC3",
7718 SPR_NOACCESS
, SPR_NOACCESS
,
7719 &spr_read_generic
, &spr_write_generic
,
7720 KVM_REG_PPC_PMC3
, 0x00000000);
7721 spr_register_kvm(env
, SPR_POWER_PMC4
, "PMC4",
7722 SPR_NOACCESS
, SPR_NOACCESS
,
7723 &spr_read_generic
, &spr_write_generic
,
7724 KVM_REG_PPC_PMC4
, 0x00000000);
7725 spr_register_kvm(env
, SPR_POWER_PMC5
, "PMC5",
7726 SPR_NOACCESS
, SPR_NOACCESS
,
7727 &spr_read_generic
, &spr_write_generic
,
7728 KVM_REG_PPC_PMC5
, 0x00000000);
7729 spr_register_kvm(env
, SPR_POWER_PMC6
, "PMC6",
7730 SPR_NOACCESS
, SPR_NOACCESS
,
7731 &spr_read_generic
, &spr_write_generic
,
7732 KVM_REG_PPC_PMC6
, 0x00000000);
7733 spr_register_kvm(env
, SPR_POWER_SIAR
, "SIAR",
7734 SPR_NOACCESS
, SPR_NOACCESS
,
7735 &spr_read_generic
, &spr_write_generic
,
7736 KVM_REG_PPC_SIAR
, 0x00000000);
7737 spr_register_kvm(env
, SPR_POWER_SDAR
, "SDAR",
7738 SPR_NOACCESS
, SPR_NOACCESS
,
7739 &spr_read_generic
, &spr_write_generic
,
7740 KVM_REG_PPC_SDAR
, 0x00000000);
7743 static void gen_spr_book3s_pmu_user(CPUPPCState
*env
)
7745 spr_register(env
, SPR_POWER_UMMCR0
, "UMMCR0",
7746 &spr_read_ureg
, SPR_NOACCESS
,
7747 &spr_read_ureg
, &spr_write_ureg
,
7749 spr_register(env
, SPR_POWER_UMMCR1
, "UMMCR1",
7750 &spr_read_ureg
, SPR_NOACCESS
,
7751 &spr_read_ureg
, &spr_write_ureg
,
7753 spr_register(env
, SPR_POWER_UMMCRA
, "UMMCRA",
7754 &spr_read_ureg
, SPR_NOACCESS
,
7755 &spr_read_ureg
, &spr_write_ureg
,
7757 spr_register(env
, SPR_POWER_UPMC1
, "UPMC1",
7758 &spr_read_ureg
, SPR_NOACCESS
,
7759 &spr_read_ureg
, &spr_write_ureg
,
7761 spr_register(env
, SPR_POWER_UPMC2
, "UPMC2",
7762 &spr_read_ureg
, SPR_NOACCESS
,
7763 &spr_read_ureg
, &spr_write_ureg
,
7765 spr_register(env
, SPR_POWER_UPMC3
, "UPMC3",
7766 &spr_read_ureg
, SPR_NOACCESS
,
7767 &spr_read_ureg
, &spr_write_ureg
,
7769 spr_register(env
, SPR_POWER_UPMC4
, "UPMC4",
7770 &spr_read_ureg
, SPR_NOACCESS
,
7771 &spr_read_ureg
, &spr_write_ureg
,
7773 spr_register(env
, SPR_POWER_UPMC5
, "UPMC5",
7774 &spr_read_ureg
, SPR_NOACCESS
,
7775 &spr_read_ureg
, &spr_write_ureg
,
7777 spr_register(env
, SPR_POWER_UPMC6
, "UPMC6",
7778 &spr_read_ureg
, SPR_NOACCESS
,
7779 &spr_read_ureg
, &spr_write_ureg
,
7781 spr_register(env
, SPR_POWER_USIAR
, "USIAR",
7782 &spr_read_ureg
, SPR_NOACCESS
,
7783 &spr_read_ureg
, &spr_write_ureg
,
7785 spr_register(env
, SPR_POWER_USDAR
, "USDAR",
7786 &spr_read_ureg
, SPR_NOACCESS
,
7787 &spr_read_ureg
, &spr_write_ureg
,
7791 static void gen_spr_970_pmu_sup(CPUPPCState
*env
)
7793 spr_register_kvm(env
, SPR_970_PMC7
, "PMC7",
7794 SPR_NOACCESS
, SPR_NOACCESS
,
7795 &spr_read_generic
, &spr_write_generic
,
7796 KVM_REG_PPC_PMC7
, 0x00000000);
7797 spr_register_kvm(env
, SPR_970_PMC8
, "PMC8",
7798 SPR_NOACCESS
, SPR_NOACCESS
,
7799 &spr_read_generic
, &spr_write_generic
,
7800 KVM_REG_PPC_PMC8
, 0x00000000);
7803 static void gen_spr_970_pmu_user(CPUPPCState
*env
)
7805 spr_register(env
, SPR_970_UPMC7
, "UPMC7",
7806 &spr_read_ureg
, SPR_NOACCESS
,
7807 &spr_read_ureg
, &spr_write_ureg
,
7809 spr_register(env
, SPR_970_UPMC8
, "UPMC8",
7810 &spr_read_ureg
, SPR_NOACCESS
,
7811 &spr_read_ureg
, &spr_write_ureg
,
7815 static void gen_spr_power8_pmu_sup(CPUPPCState
*env
)
7817 spr_register_kvm(env
, SPR_POWER_MMCR2
, "MMCR2",
7818 SPR_NOACCESS
, SPR_NOACCESS
,
7819 &spr_read_generic
, &spr_write_generic
,
7820 KVM_REG_PPC_MMCR2
, 0x00000000);
7821 spr_register_kvm(env
, SPR_POWER_MMCRS
, "MMCRS",
7822 SPR_NOACCESS
, SPR_NOACCESS
,
7823 &spr_read_generic
, &spr_write_generic
,
7824 KVM_REG_PPC_MMCRS
, 0x00000000);
7825 spr_register_kvm(env
, SPR_POWER_SIER
, "SIER",
7826 SPR_NOACCESS
, SPR_NOACCESS
,
7827 &spr_read_generic
, &spr_write_generic
,
7828 KVM_REG_PPC_SIER
, 0x00000000);
7829 spr_register_kvm(env
, SPR_POWER_SPMC1
, "SPMC1",
7830 SPR_NOACCESS
, SPR_NOACCESS
,
7831 &spr_read_generic
, &spr_write_generic
,
7832 KVM_REG_PPC_SPMC1
, 0x00000000);
7833 spr_register_kvm(env
, SPR_POWER_SPMC2
, "SPMC2",
7834 SPR_NOACCESS
, SPR_NOACCESS
,
7835 &spr_read_generic
, &spr_write_generic
,
7836 KVM_REG_PPC_SPMC2
, 0x00000000);
7837 spr_register_kvm(env
, SPR_TACR
, "TACR",
7838 SPR_NOACCESS
, SPR_NOACCESS
,
7839 &spr_read_generic
, &spr_write_generic
,
7840 KVM_REG_PPC_TACR
, 0x00000000);
7841 spr_register_kvm(env
, SPR_TCSCR
, "TCSCR",
7842 SPR_NOACCESS
, SPR_NOACCESS
,
7843 &spr_read_generic
, &spr_write_generic
,
7844 KVM_REG_PPC_TCSCR
, 0x00000000);
7845 spr_register_kvm(env
, SPR_CSIGR
, "CSIGR",
7846 SPR_NOACCESS
, SPR_NOACCESS
,
7847 &spr_read_generic
, &spr_write_generic
,
7848 KVM_REG_PPC_CSIGR
, 0x00000000);
7851 static void gen_spr_power8_pmu_user(CPUPPCState
*env
)
7853 spr_register(env
, SPR_POWER_UMMCR2
, "UMMCR2",
7854 &spr_read_ureg
, SPR_NOACCESS
,
7855 &spr_read_ureg
, &spr_write_ureg
,
7857 spr_register(env
, SPR_POWER_USIER
, "USIER",
7858 &spr_read_generic
, SPR_NOACCESS
,
7859 &spr_read_generic
, &spr_write_generic
,
7863 static void gen_spr_power5p_ear(CPUPPCState
*env
)
7865 /* External access control */
7866 spr_register(env
, SPR_EAR
, "EAR",
7867 SPR_NOACCESS
, SPR_NOACCESS
,
7868 &spr_read_generic
, &spr_write_generic
,
7872 static void gen_spr_power5p_tb(CPUPPCState
*env
)
7874 /* TBU40 (High 40 bits of the Timebase register */
7875 spr_register_hv(env
, SPR_TBU40
, "TBU40",
7876 SPR_NOACCESS
, SPR_NOACCESS
,
7877 SPR_NOACCESS
, SPR_NOACCESS
,
7878 SPR_NOACCESS
, &spr_write_tbu40
,
7882 #if !defined(CONFIG_USER_ONLY)
7883 static void spr_write_hmer(DisasContext
*ctx
, int sprn
, int gprn
)
7885 TCGv hmer
= tcg_temp_new();
7887 gen_load_spr(hmer
, sprn
);
7888 tcg_gen_and_tl(hmer
, cpu_gpr
[gprn
], hmer
);
7889 gen_store_spr(sprn
, hmer
);
7890 spr_store_dump_spr(sprn
);
7891 tcg_temp_free(hmer
);
7894 static void spr_write_lpcr(DisasContext
*ctx
, int sprn
, int gprn
)
7896 gen_helper_store_lpcr(cpu_env
, cpu_gpr
[gprn
]);
7899 static void spr_write_970_hid4(DisasContext
*ctx
, int sprn
, int gprn
)
7901 #if defined(TARGET_PPC64)
7902 spr_write_generic(ctx
, sprn
, gprn
);
7903 gen_helper_store_lpcr(cpu_env
, cpu_gpr
[gprn
]);
7907 #endif /* !defined(CONFIG_USER_ONLY) */
7909 static void gen_spr_970_lpar(CPUPPCState
*env
)
7911 #if !defined(CONFIG_USER_ONLY)
7912 /* Logical partitionning */
7913 /* PPC970: HID4 is effectively the LPCR */
7914 spr_register(env
, SPR_970_HID4
, "HID4",
7915 SPR_NOACCESS
, SPR_NOACCESS
,
7916 &spr_read_generic
, &spr_write_970_hid4
,
7921 static void gen_spr_power5p_lpar(CPUPPCState
*env
)
7923 #if !defined(CONFIG_USER_ONLY)
7924 /* Logical partitionning */
7925 spr_register_kvm_hv(env
, SPR_LPCR
, "LPCR",
7926 SPR_NOACCESS
, SPR_NOACCESS
,
7927 SPR_NOACCESS
, SPR_NOACCESS
,
7928 &spr_read_generic
, &spr_write_lpcr
,
7929 KVM_REG_PPC_LPCR
, LPCR_LPES0
| LPCR_LPES1
);
7930 spr_register_hv(env
, SPR_HDEC
, "HDEC",
7931 SPR_NOACCESS
, SPR_NOACCESS
,
7932 SPR_NOACCESS
, SPR_NOACCESS
,
7933 &spr_read_hdecr
, &spr_write_hdecr
, 0);
7937 static void gen_spr_book3s_ids(CPUPPCState
*env
)
7939 /* FIXME: Will need to deal with thread vs core only SPRs */
7941 /* Processor identification */
7942 spr_register_hv(env
, SPR_PIR
, "PIR",
7943 SPR_NOACCESS
, SPR_NOACCESS
,
7944 &spr_read_generic
, SPR_NOACCESS
,
7945 &spr_read_generic
, NULL
,
7947 spr_register_hv(env
, SPR_HID0
, "HID0",
7948 SPR_NOACCESS
, SPR_NOACCESS
,
7949 SPR_NOACCESS
, SPR_NOACCESS
,
7950 &spr_read_generic
, &spr_write_generic
,
7952 spr_register_hv(env
, SPR_TSCR
, "TSCR",
7953 SPR_NOACCESS
, SPR_NOACCESS
,
7954 SPR_NOACCESS
, SPR_NOACCESS
,
7955 &spr_read_generic
, &spr_write_generic
,
7957 spr_register_hv(env
, SPR_HMER
, "HMER",
7958 SPR_NOACCESS
, SPR_NOACCESS
,
7959 SPR_NOACCESS
, SPR_NOACCESS
,
7960 &spr_read_generic
, &spr_write_hmer
,
7962 spr_register_hv(env
, SPR_HMEER
, "HMEER",
7963 SPR_NOACCESS
, SPR_NOACCESS
,
7964 SPR_NOACCESS
, SPR_NOACCESS
,
7965 &spr_read_generic
, &spr_write_generic
,
7967 spr_register_hv(env
, SPR_TFMR
, "TFMR",
7968 SPR_NOACCESS
, SPR_NOACCESS
,
7969 SPR_NOACCESS
, SPR_NOACCESS
,
7970 &spr_read_generic
, &spr_write_generic
,
7972 spr_register_hv(env
, SPR_LPIDR
, "LPIDR",
7973 SPR_NOACCESS
, SPR_NOACCESS
,
7974 SPR_NOACCESS
, SPR_NOACCESS
,
7975 &spr_read_generic
, &spr_write_lpidr
,
7977 spr_register_hv(env
, SPR_HFSCR
, "HFSCR",
7978 SPR_NOACCESS
, SPR_NOACCESS
,
7979 SPR_NOACCESS
, SPR_NOACCESS
,
7980 &spr_read_generic
, &spr_write_generic
,
7982 spr_register_hv(env
, SPR_MMCRC
, "MMCRC",
7983 SPR_NOACCESS
, SPR_NOACCESS
,
7984 SPR_NOACCESS
, SPR_NOACCESS
,
7985 &spr_read_generic
, &spr_write_generic
,
7987 spr_register_hv(env
, SPR_MMCRH
, "MMCRH",
7988 SPR_NOACCESS
, SPR_NOACCESS
,
7989 SPR_NOACCESS
, SPR_NOACCESS
,
7990 &spr_read_generic
, &spr_write_generic
,
7992 spr_register_hv(env
, SPR_HSPRG0
, "HSPRG0",
7993 SPR_NOACCESS
, SPR_NOACCESS
,
7994 SPR_NOACCESS
, SPR_NOACCESS
,
7995 &spr_read_generic
, &spr_write_generic
,
7997 spr_register_hv(env
, SPR_HSPRG1
, "HSPRG1",
7998 SPR_NOACCESS
, SPR_NOACCESS
,
7999 SPR_NOACCESS
, SPR_NOACCESS
,
8000 &spr_read_generic
, &spr_write_generic
,
8002 spr_register_hv(env
, SPR_HSRR0
, "HSRR0",
8003 SPR_NOACCESS
, SPR_NOACCESS
,
8004 SPR_NOACCESS
, SPR_NOACCESS
,
8005 &spr_read_generic
, &spr_write_generic
,
8007 spr_register_hv(env
, SPR_HSRR1
, "HSRR1",
8008 SPR_NOACCESS
, SPR_NOACCESS
,
8009 SPR_NOACCESS
, SPR_NOACCESS
,
8010 &spr_read_generic
, &spr_write_generic
,
8012 spr_register_hv(env
, SPR_HDAR
, "HDAR",
8013 SPR_NOACCESS
, SPR_NOACCESS
,
8014 SPR_NOACCESS
, SPR_NOACCESS
,
8015 &spr_read_generic
, &spr_write_generic
,
8017 spr_register_hv(env
, SPR_HDSISR
, "HDSISR",
8018 SPR_NOACCESS
, SPR_NOACCESS
,
8019 SPR_NOACCESS
, SPR_NOACCESS
,
8020 &spr_read_generic
, &spr_write_generic
,
8022 spr_register_hv(env
, SPR_RMOR
, "RMOR",
8023 SPR_NOACCESS
, SPR_NOACCESS
,
8024 SPR_NOACCESS
, SPR_NOACCESS
,
8025 &spr_read_generic
, &spr_write_generic
,
8027 spr_register_hv(env
, SPR_HRMOR
, "HRMOR",
8028 SPR_NOACCESS
, SPR_NOACCESS
,
8029 SPR_NOACCESS
, SPR_NOACCESS
,
8030 &spr_read_generic
, &spr_write_generic
,
8034 static void gen_spr_power8_ids(CPUPPCState
*env
)
8036 /* Thread identification */
8037 spr_register(env
, SPR_TIR
, "TIR",
8038 SPR_NOACCESS
, SPR_NOACCESS
,
8039 &spr_read_generic
, SPR_NOACCESS
,
8043 static void gen_spr_book3s_purr(CPUPPCState
*env
)
8045 #if !defined(CONFIG_USER_ONLY)
8046 /* PURR & SPURR: Hack - treat these as aliases for the TB for now */
8047 spr_register_kvm_hv(env
, SPR_PURR
, "PURR",
8048 &spr_read_purr
, SPR_NOACCESS
,
8049 &spr_read_purr
, SPR_NOACCESS
,
8050 &spr_read_purr
, &spr_write_purr
,
8051 KVM_REG_PPC_PURR
, 0x00000000);
8052 spr_register_kvm_hv(env
, SPR_SPURR
, "SPURR",
8053 &spr_read_purr
, SPR_NOACCESS
,
8054 &spr_read_purr
, SPR_NOACCESS
,
8055 &spr_read_purr
, &spr_write_purr
,
8056 KVM_REG_PPC_SPURR
, 0x00000000);
8060 static void gen_spr_power6_dbg(CPUPPCState
*env
)
8062 #if !defined(CONFIG_USER_ONLY)
8063 spr_register(env
, SPR_CFAR
, "SPR_CFAR",
8064 SPR_NOACCESS
, SPR_NOACCESS
,
8065 &spr_read_cfar
, &spr_write_cfar
,
8070 static void gen_spr_power5p_common(CPUPPCState
*env
)
8072 spr_register_kvm(env
, SPR_PPR
, "PPR",
8073 &spr_read_generic
, &spr_write_generic
,
8074 &spr_read_generic
, &spr_write_generic
,
8075 KVM_REG_PPC_PPR
, 0x00000000);
8078 static void gen_spr_power6_common(CPUPPCState
*env
)
8080 #if !defined(CONFIG_USER_ONLY)
8081 spr_register_kvm(env
, SPR_DSCR
, "SPR_DSCR",
8082 SPR_NOACCESS
, SPR_NOACCESS
,
8083 &spr_read_generic
, &spr_write_generic
,
8084 KVM_REG_PPC_DSCR
, 0x00000000);
8087 * Register PCR to report POWERPC_EXCP_PRIV_REG instead of
8088 * POWERPC_EXCP_INVAL_SPR in userspace. Permit hypervisor access.
8090 spr_register_hv(env
, SPR_PCR
, "PCR",
8091 SPR_NOACCESS
, SPR_NOACCESS
,
8092 SPR_NOACCESS
, SPR_NOACCESS
,
8093 &spr_read_generic
, &spr_write_pcr
,
8097 static void spr_read_tar(DisasContext
*ctx
, int gprn
, int sprn
)
8099 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_TAR
, sprn
, FSCR_IC_TAR
);
8100 spr_read_generic(ctx
, gprn
, sprn
);
8103 static void spr_write_tar(DisasContext
*ctx
, int sprn
, int gprn
)
8105 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_TAR
, sprn
, FSCR_IC_TAR
);
8106 spr_write_generic(ctx
, sprn
, gprn
);
8109 static void gen_spr_power8_tce_address_control(CPUPPCState
*env
)
8111 spr_register_kvm(env
, SPR_TAR
, "TAR",
8112 &spr_read_tar
, &spr_write_tar
,
8113 &spr_read_generic
, &spr_write_generic
,
8114 KVM_REG_PPC_TAR
, 0x00000000);
8117 static void spr_read_tm(DisasContext
*ctx
, int gprn
, int sprn
)
8119 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8120 spr_read_generic(ctx
, gprn
, sprn
);
8123 static void spr_write_tm(DisasContext
*ctx
, int sprn
, int gprn
)
8125 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8126 spr_write_generic(ctx
, sprn
, gprn
);
8129 static void spr_read_tm_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
8131 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8132 spr_read_prev_upper32(ctx
, gprn
, sprn
);
8135 static void spr_write_tm_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
8137 gen_msr_facility_check(ctx
, SPR_FSCR
, MSR_TM
, sprn
, FSCR_IC_TM
);
8138 spr_write_prev_upper32(ctx
, sprn
, gprn
);
8141 static void gen_spr_power8_tm(CPUPPCState
*env
)
8143 spr_register_kvm(env
, SPR_TFHAR
, "TFHAR",
8144 &spr_read_tm
, &spr_write_tm
,
8145 &spr_read_tm
, &spr_write_tm
,
8146 KVM_REG_PPC_TFHAR
, 0x00000000);
8147 spr_register_kvm(env
, SPR_TFIAR
, "TFIAR",
8148 &spr_read_tm
, &spr_write_tm
,
8149 &spr_read_tm
, &spr_write_tm
,
8150 KVM_REG_PPC_TFIAR
, 0x00000000);
8151 spr_register_kvm(env
, SPR_TEXASR
, "TEXASR",
8152 &spr_read_tm
, &spr_write_tm
,
8153 &spr_read_tm
, &spr_write_tm
,
8154 KVM_REG_PPC_TEXASR
, 0x00000000);
8155 spr_register(env
, SPR_TEXASRU
, "TEXASRU",
8156 &spr_read_tm_upper32
, &spr_write_tm_upper32
,
8157 &spr_read_tm_upper32
, &spr_write_tm_upper32
,
8161 static void spr_read_ebb(DisasContext
*ctx
, int gprn
, int sprn
)
8163 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8164 spr_read_generic(ctx
, gprn
, sprn
);
8167 static void spr_write_ebb(DisasContext
*ctx
, int sprn
, int gprn
)
8169 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8170 spr_write_generic(ctx
, sprn
, gprn
);
8173 static void spr_read_ebb_upper32(DisasContext
*ctx
, int gprn
, int sprn
)
8175 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8176 spr_read_prev_upper32(ctx
, gprn
, sprn
);
8179 static void spr_write_ebb_upper32(DisasContext
*ctx
, int sprn
, int gprn
)
8181 gen_fscr_facility_check(ctx
, SPR_FSCR
, FSCR_EBB
, sprn
, FSCR_IC_EBB
);
8182 spr_write_prev_upper32(ctx
, sprn
, gprn
);
8185 static void gen_spr_power8_ebb(CPUPPCState
*env
)
8187 spr_register(env
, SPR_BESCRS
, "BESCRS",
8188 &spr_read_ebb
, &spr_write_ebb
,
8189 &spr_read_generic
, &spr_write_generic
,
8191 spr_register(env
, SPR_BESCRSU
, "BESCRSU",
8192 &spr_read_ebb_upper32
, &spr_write_ebb_upper32
,
8193 &spr_read_prev_upper32
, &spr_write_prev_upper32
,
8195 spr_register(env
, SPR_BESCRR
, "BESCRR",
8196 &spr_read_ebb
, &spr_write_ebb
,
8197 &spr_read_generic
, &spr_write_generic
,
8199 spr_register(env
, SPR_BESCRRU
, "BESCRRU",
8200 &spr_read_ebb_upper32
, &spr_write_ebb_upper32
,
8201 &spr_read_prev_upper32
, &spr_write_prev_upper32
,
8203 spr_register_kvm(env
, SPR_EBBHR
, "EBBHR",
8204 &spr_read_ebb
, &spr_write_ebb
,
8205 &spr_read_generic
, &spr_write_generic
,
8206 KVM_REG_PPC_EBBHR
, 0x00000000);
8207 spr_register_kvm(env
, SPR_EBBRR
, "EBBRR",
8208 &spr_read_ebb
, &spr_write_ebb
,
8209 &spr_read_generic
, &spr_write_generic
,
8210 KVM_REG_PPC_EBBRR
, 0x00000000);
8211 spr_register_kvm(env
, SPR_BESCR
, "BESCR",
8212 &spr_read_ebb
, &spr_write_ebb
,
8213 &spr_read_generic
, &spr_write_generic
,
8214 KVM_REG_PPC_BESCR
, 0x00000000);
8217 /* Virtual Time Base */
8218 static void gen_spr_vtb(CPUPPCState
*env
)
8220 spr_register_kvm_hv(env
, SPR_VTB
, "VTB",
8221 SPR_NOACCESS
, SPR_NOACCESS
,
8222 &spr_read_vtb
, SPR_NOACCESS
,
8223 &spr_read_vtb
, &spr_write_vtb
,
8224 KVM_REG_PPC_VTB
, 0x00000000);
8227 static void gen_spr_power8_fscr(CPUPPCState
*env
)
8229 #if defined(CONFIG_USER_ONLY)
8230 target_ulong initval
= 1ULL << FSCR_TAR
;
8232 target_ulong initval
= 0;
8234 spr_register_kvm(env
, SPR_FSCR
, "FSCR",
8235 SPR_NOACCESS
, SPR_NOACCESS
,
8236 &spr_read_generic
, &spr_write_generic
,
8237 KVM_REG_PPC_FSCR
, initval
);
8240 static void gen_spr_power8_pspb(CPUPPCState
*env
)
8242 spr_register_kvm(env
, SPR_PSPB
, "PSPB",
8243 SPR_NOACCESS
, SPR_NOACCESS
,
8244 &spr_read_generic
, &spr_write_generic32
,
8245 KVM_REG_PPC_PSPB
, 0);
8248 static void gen_spr_power8_dpdes(CPUPPCState
*env
)
8250 #if !defined(CONFIG_USER_ONLY)
8251 /* Directed Privileged Door-bell Exception State, used for IPI */
8252 spr_register_kvm_hv(env
, SPR_DPDES
, "DPDES",
8253 SPR_NOACCESS
, SPR_NOACCESS
,
8254 &spr_read_dpdes
, SPR_NOACCESS
,
8255 &spr_read_dpdes
, &spr_write_dpdes
,
8256 KVM_REG_PPC_DPDES
, 0x00000000);
8260 static void gen_spr_power8_ic(CPUPPCState
*env
)
8262 #if !defined(CONFIG_USER_ONLY)
8263 spr_register_hv(env
, SPR_IC
, "IC",
8264 SPR_NOACCESS
, SPR_NOACCESS
,
8265 &spr_read_generic
, SPR_NOACCESS
,
8266 &spr_read_generic
, &spr_write_generic
,
8271 static void gen_spr_power8_book4(CPUPPCState
*env
)
8273 /* Add a number of P8 book4 registers */
8274 #if !defined(CONFIG_USER_ONLY)
8275 spr_register_kvm(env
, SPR_ACOP
, "ACOP",
8276 SPR_NOACCESS
, SPR_NOACCESS
,
8277 &spr_read_generic
, &spr_write_generic
,
8278 KVM_REG_PPC_ACOP
, 0);
8279 spr_register_kvm(env
, SPR_BOOKS_PID
, "PID",
8280 SPR_NOACCESS
, SPR_NOACCESS
,
8281 &spr_read_generic
, &spr_write_pidr
,
8282 KVM_REG_PPC_PID
, 0);
8283 spr_register_kvm(env
, SPR_WORT
, "WORT",
8284 SPR_NOACCESS
, SPR_NOACCESS
,
8285 &spr_read_generic
, &spr_write_generic
,
8286 KVM_REG_PPC_WORT
, 0);
8290 static void gen_spr_power7_book4(CPUPPCState
*env
)
8292 /* Add a number of P7 book4 registers */
8293 #if !defined(CONFIG_USER_ONLY)
8294 spr_register_kvm(env
, SPR_ACOP
, "ACOP",
8295 SPR_NOACCESS
, SPR_NOACCESS
,
8296 &spr_read_generic
, &spr_write_generic
,
8297 KVM_REG_PPC_ACOP
, 0);
8298 spr_register_kvm(env
, SPR_BOOKS_PID
, "PID",
8299 SPR_NOACCESS
, SPR_NOACCESS
,
8300 &spr_read_generic
, &spr_write_generic
,
8301 KVM_REG_PPC_PID
, 0);
8305 static void gen_spr_power8_rpr(CPUPPCState
*env
)
8307 #if !defined(CONFIG_USER_ONLY)
8308 spr_register_hv(env
, SPR_RPR
, "RPR",
8309 SPR_NOACCESS
, SPR_NOACCESS
,
8310 SPR_NOACCESS
, SPR_NOACCESS
,
8311 &spr_read_generic
, &spr_write_generic
,
8312 0x00000103070F1F3F);
8316 static void gen_spr_power9_mmu(CPUPPCState
*env
)
8318 #if !defined(CONFIG_USER_ONLY)
8319 /* Partition Table Control */
8320 spr_register_kvm_hv(env
, SPR_PTCR
, "PTCR",
8321 SPR_NOACCESS
, SPR_NOACCESS
,
8322 SPR_NOACCESS
, SPR_NOACCESS
,
8323 &spr_read_generic
, &spr_write_ptcr
,
8324 KVM_REG_PPC_PTCR
, 0x00000000);
8325 /* Address Segment Descriptor Register */
8326 spr_register_hv(env
, SPR_ASDR
, "ASDR",
8327 SPR_NOACCESS
, SPR_NOACCESS
,
8328 SPR_NOACCESS
, SPR_NOACCESS
,
8329 &spr_read_generic
, &spr_write_generic
,
8330 0x0000000000000000);
8334 static void init_proc_book3s_common(CPUPPCState
*env
)
8336 gen_spr_ne_601(env
);
8338 gen_spr_usprg3(env
);
8339 gen_spr_book3s_altivec(env
);
8340 gen_spr_book3s_pmu_sup(env
);
8341 gen_spr_book3s_pmu_user(env
);
8342 gen_spr_book3s_ctrl(env
);
8345 static void init_proc_970(CPUPPCState
*env
)
8347 /* Common Registers */
8348 init_proc_book3s_common(env
);
8350 gen_spr_book3s_dbg(env
);
8352 /* 970 Specific Registers */
8353 gen_spr_970_hid(env
);
8354 gen_spr_970_hior(env
);
8356 gen_spr_970_pmu_sup(env
);
8357 gen_spr_970_pmu_user(env
);
8358 gen_spr_970_lpar(env
);
8359 gen_spr_970_dbg(env
);
8362 env
->dcache_line_size
= 128;
8363 env
->icache_line_size
= 128;
8365 /* Allocate hardware IRQ controller */
8367 ppc970_irq_init(env_archcpu(env
));
8370 POWERPC_FAMILY(970)(ObjectClass
*oc
, void *data
)
8372 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8373 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8375 dc
->desc
= "PowerPC 970";
8376 pcc
->init_proc
= init_proc_970
;
8377 pcc
->check_pow
= check_pow_970
;
8378 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
8379 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8380 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8382 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8383 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8384 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8385 PPC_64B
| PPC_ALTIVEC
|
8386 PPC_SEGMENT_64B
| PPC_SLBI
;
8387 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
8388 pcc
->msr_mask
= (1ull << MSR_SF
) |
8403 pcc
->mmu_model
= POWERPC_MMU_64B
;
8404 #if defined(CONFIG_SOFTMMU)
8405 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8406 pcc
->hash64_opts
= &ppc_hash64_opts_basic
;
8408 pcc
->excp_model
= POWERPC_EXCP_970
;
8409 pcc
->bus_model
= PPC_FLAGS_INPUT_970
;
8410 pcc
->bfd_mach
= bfd_mach_ppc64
;
8411 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8412 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8413 POWERPC_FLAG_BUS_CLK
;
8414 pcc
->l1_dcache_size
= 0x8000;
8415 pcc
->l1_icache_size
= 0x10000;
8418 static void init_proc_power5plus(CPUPPCState
*env
)
8420 /* Common Registers */
8421 init_proc_book3s_common(env
);
8423 gen_spr_book3s_dbg(env
);
8425 /* POWER5+ Specific Registers */
8426 gen_spr_970_hid(env
);
8427 gen_spr_970_hior(env
);
8429 gen_spr_970_pmu_sup(env
);
8430 gen_spr_970_pmu_user(env
);
8431 gen_spr_power5p_common(env
);
8432 gen_spr_power5p_lpar(env
);
8433 gen_spr_power5p_ear(env
);
8434 gen_spr_power5p_tb(env
);
8437 env
->dcache_line_size
= 128;
8438 env
->icache_line_size
= 128;
8440 /* Allocate hardware IRQ controller */
8442 ppc970_irq_init(env_archcpu(env
));
8445 POWERPC_FAMILY(POWER5P
)(ObjectClass
*oc
, void *data
)
8447 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8448 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8450 dc
->fw_name
= "PowerPC,POWER5";
8451 dc
->desc
= "POWER5+";
8452 pcc
->init_proc
= init_proc_power5plus
;
8453 pcc
->check_pow
= check_pow_970
;
8454 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_STRING
| PPC_MFTB
|
8455 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8456 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8458 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8459 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8460 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8462 PPC_SEGMENT_64B
| PPC_SLBI
;
8463 pcc
->insns_flags2
= PPC2_FP_CVT_S64
;
8464 pcc
->msr_mask
= (1ull << MSR_SF
) |
8479 pcc
->mmu_model
= POWERPC_MMU_2_03
;
8480 #if defined(CONFIG_SOFTMMU)
8481 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8482 pcc
->hash64_opts
= &ppc_hash64_opts_basic
;
8483 pcc
->lrg_decr_bits
= 32;
8485 pcc
->excp_model
= POWERPC_EXCP_970
;
8486 pcc
->bus_model
= PPC_FLAGS_INPUT_970
;
8487 pcc
->bfd_mach
= bfd_mach_ppc64
;
8488 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8489 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8490 POWERPC_FLAG_BUS_CLK
;
8491 pcc
->l1_dcache_size
= 0x8000;
8492 pcc
->l1_icache_size
= 0x10000;
8496 * The CPU used to have a "compat" property which set the
8497 * compatibility mode PVR. However, this was conceptually broken - it
8498 * only makes sense on the pseries machine type (otherwise the guest
8499 * owns the PCR and can control the compatibility mode itself). It's
8500 * been replaced with the 'max-cpu-compat' property on the pseries
8501 * machine type. For backwards compatibility, pseries specially
8502 * parses the -cpu parameter and converts old compat= parameters into
8503 * the appropriate machine parameters. This stub implementation of
8504 * the parameter catches any uses on explicitly created CPUs.
8506 static void getset_compat_deprecated(Object
*obj
, Visitor
*v
, const char *name
,
8507 void *opaque
, Error
**errp
)
8511 if (!qtest_enabled()) {
8512 warn_report("CPU 'compat' property is deprecated and has no effect; "
8513 "use max-cpu-compat machine property instead");
8515 visit_type_null(v
, name
, &null
, NULL
);
8516 qobject_unref(null
);
8519 static const PropertyInfo ppc_compat_deprecated_propinfo
= {
8521 .description
= "compatibility mode (deprecated)",
8522 .get
= getset_compat_deprecated
,
8523 .set
= getset_compat_deprecated
,
8525 static Property powerpc_servercpu_properties
[] = {
8528 .info
= &ppc_compat_deprecated_propinfo
,
8530 DEFINE_PROP_END_OF_LIST(),
8533 static void init_proc_POWER7(CPUPPCState
*env
)
8535 /* Common Registers */
8536 init_proc_book3s_common(env
);
8538 gen_spr_book3s_dbg(env
);
8540 /* POWER7 Specific Registers */
8541 gen_spr_book3s_ids(env
);
8543 gen_spr_book3s_purr(env
);
8544 gen_spr_power5p_common(env
);
8545 gen_spr_power5p_lpar(env
);
8546 gen_spr_power5p_ear(env
);
8547 gen_spr_power5p_tb(env
);
8548 gen_spr_power6_common(env
);
8549 gen_spr_power6_dbg(env
);
8550 gen_spr_power7_book4(env
);
8553 env
->dcache_line_size
= 128;
8554 env
->icache_line_size
= 128;
8556 /* Allocate hardware IRQ controller */
8557 init_excp_POWER7(env
);
8558 ppcPOWER7_irq_init(env_archcpu(env
));
8561 static bool ppc_pvr_match_power7(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8563 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER7P_BASE
) {
8566 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER7_BASE
) {
8572 static bool cpu_has_work_POWER7(CPUState
*cs
)
8574 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8575 CPUPPCState
*env
= &cpu
->env
;
8578 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8581 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8582 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE0
)) {
8585 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8586 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE1
)) {
8589 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
)) &&
8590 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE2
)) {
8593 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HMI
)) &&
8594 (env
->spr
[SPR_LPCR
] & LPCR_P7_PECE2
)) {
8597 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8602 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8606 POWERPC_FAMILY(POWER7
)(ObjectClass
*oc
, void *data
)
8608 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8609 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8610 CPUClass
*cc
= CPU_CLASS(oc
);
8612 dc
->fw_name
= "PowerPC,POWER7";
8613 dc
->desc
= "POWER7";
8614 device_class_set_props(dc
, powerpc_servercpu_properties
);
8615 pcc
->pvr_match
= ppc_pvr_match_power7
;
8616 pcc
->pcr_mask
= PCR_VEC_DIS
| PCR_VSX_DIS
| PCR_COMPAT_2_05
;
8617 pcc
->pcr_supported
= PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8618 pcc
->init_proc
= init_proc_POWER7
;
8619 pcc
->check_pow
= check_pow_nocheck
;
8620 cc
->has_work
= cpu_has_work_POWER7
;
8621 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8622 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8623 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8624 PPC_FLOAT_FRSQRTES
|
8627 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8628 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8629 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8630 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
8631 PPC_SEGMENT_64B
| PPC_SLBI
|
8632 PPC_POPCNTB
| PPC_POPCNTWD
|
8634 pcc
->insns_flags2
= PPC2_VSX
| PPC2_DFP
| PPC2_DBRX
| PPC2_ISA205
|
8635 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8636 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8637 PPC2_FP_TST_ISA206
| PPC2_FP_CVT_S64
|
8639 pcc
->msr_mask
= (1ull << MSR_SF
) |
8655 pcc
->mmu_model
= POWERPC_MMU_2_06
;
8656 #if defined(CONFIG_SOFTMMU)
8657 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8658 pcc
->hash64_opts
= &ppc_hash64_opts_POWER7
;
8659 pcc
->lrg_decr_bits
= 32;
8661 pcc
->excp_model
= POWERPC_EXCP_POWER7
;
8662 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8663 pcc
->bfd_mach
= bfd_mach_ppc64
;
8664 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8665 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8666 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8668 pcc
->l1_dcache_size
= 0x8000;
8669 pcc
->l1_icache_size
= 0x8000;
8670 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8671 pcc
->lpcr_pm
= LPCR_P7_PECE0
| LPCR_P7_PECE1
| LPCR_P7_PECE2
;
8674 static void init_proc_POWER8(CPUPPCState
*env
)
8676 /* Common Registers */
8677 init_proc_book3s_common(env
);
8679 gen_spr_book3s_207_dbg(env
);
8681 /* POWER8 Specific Registers */
8682 gen_spr_book3s_ids(env
);
8685 gen_spr_book3s_purr(env
);
8686 gen_spr_power5p_common(env
);
8687 gen_spr_power5p_lpar(env
);
8688 gen_spr_power5p_ear(env
);
8689 gen_spr_power5p_tb(env
);
8690 gen_spr_power6_common(env
);
8691 gen_spr_power6_dbg(env
);
8692 gen_spr_power8_tce_address_control(env
);
8693 gen_spr_power8_ids(env
);
8694 gen_spr_power8_ebb(env
);
8695 gen_spr_power8_fscr(env
);
8696 gen_spr_power8_pmu_sup(env
);
8697 gen_spr_power8_pmu_user(env
);
8698 gen_spr_power8_tm(env
);
8699 gen_spr_power8_pspb(env
);
8700 gen_spr_power8_dpdes(env
);
8702 gen_spr_power8_ic(env
);
8703 gen_spr_power8_book4(env
);
8704 gen_spr_power8_rpr(env
);
8707 env
->dcache_line_size
= 128;
8708 env
->icache_line_size
= 128;
8710 /* Allocate hardware IRQ controller */
8711 init_excp_POWER8(env
);
8712 ppcPOWER7_irq_init(env_archcpu(env
));
8715 static bool ppc_pvr_match_power8(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8717 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8NVL_BASE
) {
8720 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8E_BASE
) {
8723 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER8_BASE
) {
8729 static bool cpu_has_work_POWER8(CPUState
*cs
)
8731 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8732 CPUPPCState
*env
= &cpu
->env
;
8735 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8738 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8739 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE2
)) {
8742 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8743 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE3
)) {
8746 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
)) &&
8747 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE4
)) {
8750 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HMI
)) &&
8751 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE4
)) {
8754 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DOORBELL
)) &&
8755 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE0
)) {
8758 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HDOORBELL
)) &&
8759 (env
->spr
[SPR_LPCR
] & LPCR_P8_PECE1
)) {
8762 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8767 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8771 POWERPC_FAMILY(POWER8
)(ObjectClass
*oc
, void *data
)
8773 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8774 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8775 CPUClass
*cc
= CPU_CLASS(oc
);
8777 dc
->fw_name
= "PowerPC,POWER8";
8778 dc
->desc
= "POWER8";
8779 device_class_set_props(dc
, powerpc_servercpu_properties
);
8780 pcc
->pvr_match
= ppc_pvr_match_power8
;
8781 pcc
->pcr_mask
= PCR_TM_DIS
| PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8782 pcc
->pcr_supported
= PCR_COMPAT_2_07
| PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
8783 pcc
->init_proc
= init_proc_POWER8
;
8784 pcc
->check_pow
= check_pow_nocheck
;
8785 cc
->has_work
= cpu_has_work_POWER8
;
8786 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
8787 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
8788 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
8789 PPC_FLOAT_FRSQRTES
|
8792 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
8793 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
8794 PPC_MEM_TLBIE
| PPC_MEM_TLBSYNC
|
8795 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
8796 PPC_SEGMENT_64B
| PPC_SLBI
|
8797 PPC_POPCNTB
| PPC_POPCNTWD
|
8799 pcc
->insns_flags2
= PPC2_VSX
| PPC2_VSX207
| PPC2_DFP
| PPC2_DBRX
|
8800 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
8801 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
8802 PPC2_FP_TST_ISA206
| PPC2_BCTAR_ISA207
|
8803 PPC2_LSQ_ISA207
| PPC2_ALTIVEC_207
|
8804 PPC2_ISA205
| PPC2_ISA207S
| PPC2_FP_CVT_S64
|
8805 PPC2_TM
| PPC2_PM_ISA206
;
8806 pcc
->msr_mask
= (1ull << MSR_SF
) |
8826 pcc
->mmu_model
= POWERPC_MMU_2_07
;
8827 #if defined(CONFIG_SOFTMMU)
8828 pcc
->handle_mmu_fault
= ppc_hash64_handle_mmu_fault
;
8829 pcc
->hash64_opts
= &ppc_hash64_opts_POWER7
;
8830 pcc
->lrg_decr_bits
= 32;
8831 pcc
->n_host_threads
= 8;
8833 pcc
->excp_model
= POWERPC_EXCP_POWER8
;
8834 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER7
;
8835 pcc
->bfd_mach
= bfd_mach_ppc64
;
8836 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
8837 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
8838 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
8839 POWERPC_FLAG_VSX
| POWERPC_FLAG_TM
;
8840 pcc
->l1_dcache_size
= 0x8000;
8841 pcc
->l1_icache_size
= 0x8000;
8842 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
8843 pcc
->lpcr_pm
= LPCR_P8_PECE0
| LPCR_P8_PECE1
| LPCR_P8_PECE2
|
8844 LPCR_P8_PECE3
| LPCR_P8_PECE4
;
8847 #ifdef CONFIG_SOFTMMU
8849 * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings
8850 * Encoded as array of int_32s in the form:
8851 * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
8853 * y -> radix mode supported page size (encoded as a shift)
8855 static struct ppc_radix_page_info POWER9_radix_page_info
= {
8858 0x0000000c, /* 4K - enc: 0x0 */
8859 0xa0000010, /* 64K - enc: 0x5 */
8860 0x20000015, /* 2M - enc: 0x1 */
8861 0x4000001e /* 1G - enc: 0x2 */
8864 #endif /* CONFIG_SOFTMMU */
8866 static void init_proc_POWER9(CPUPPCState
*env
)
8868 /* Common Registers */
8869 init_proc_book3s_common(env
);
8870 gen_spr_book3s_207_dbg(env
);
8872 /* POWER8 Specific Registers */
8873 gen_spr_book3s_ids(env
);
8876 gen_spr_book3s_purr(env
);
8877 gen_spr_power5p_common(env
);
8878 gen_spr_power5p_lpar(env
);
8879 gen_spr_power5p_ear(env
);
8880 gen_spr_power5p_tb(env
);
8881 gen_spr_power6_common(env
);
8882 gen_spr_power6_dbg(env
);
8883 gen_spr_power8_tce_address_control(env
);
8884 gen_spr_power8_ids(env
);
8885 gen_spr_power8_ebb(env
);
8886 gen_spr_power8_fscr(env
);
8887 gen_spr_power8_pmu_sup(env
);
8888 gen_spr_power8_pmu_user(env
);
8889 gen_spr_power8_tm(env
);
8890 gen_spr_power8_pspb(env
);
8891 gen_spr_power8_dpdes(env
);
8893 gen_spr_power8_ic(env
);
8894 gen_spr_power8_book4(env
);
8895 gen_spr_power8_rpr(env
);
8896 gen_spr_power9_mmu(env
);
8898 /* POWER9 Specific registers */
8899 spr_register_kvm(env
, SPR_TIDR
, "TIDR", NULL
, NULL
,
8900 spr_read_generic
, spr_write_generic
,
8901 KVM_REG_PPC_TIDR
, 0);
8903 /* FIXME: Filter fields properly based on privilege level */
8904 spr_register_kvm_hv(env
, SPR_PSSCR
, "PSSCR", NULL
, NULL
, NULL
, NULL
,
8905 spr_read_generic
, spr_write_generic
,
8906 KVM_REG_PPC_PSSCR
, 0);
8909 env
->dcache_line_size
= 128;
8910 env
->icache_line_size
= 128;
8912 /* Allocate hardware IRQ controller */
8913 init_excp_POWER9(env
);
8914 ppcPOWER9_irq_init(env_archcpu(env
));
8917 static bool ppc_pvr_match_power9(PowerPCCPUClass
*pcc
, uint32_t pvr
)
8919 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER9_BASE
) {
8925 static bool cpu_has_work_POWER9(CPUState
*cs
)
8927 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
8928 CPUPPCState
*env
= &cpu
->env
;
8931 uint64_t psscr
= env
->spr
[SPR_PSSCR
];
8933 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
8937 /* If EC is clear, just return true on any pending interrupt */
8938 if (!(psscr
& PSSCR_EC
)) {
8941 /* External Exception */
8942 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
8943 (env
->spr
[SPR_LPCR
] & LPCR_EEE
)) {
8944 bool heic
= !!(env
->spr
[SPR_LPCR
] & LPCR_HEIC
);
8945 if (heic
== 0 || !msr_hv
|| msr_pr
) {
8949 /* Decrementer Exception */
8950 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
8951 (env
->spr
[SPR_LPCR
] & LPCR_DEE
)) {
8954 /* Machine Check or Hypervisor Maintenance Exception */
8955 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
|
8956 1u << PPC_INTERRUPT_HMI
)) && (env
->spr
[SPR_LPCR
] & LPCR_OEE
)) {
8959 /* Privileged Doorbell Exception */
8960 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DOORBELL
)) &&
8961 (env
->spr
[SPR_LPCR
] & LPCR_PDEE
)) {
8964 /* Hypervisor Doorbell Exception */
8965 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HDOORBELL
)) &&
8966 (env
->spr
[SPR_LPCR
] & LPCR_HDEE
)) {
8969 /* Hypervisor virtualization exception */
8970 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HVIRT
)) &&
8971 (env
->spr
[SPR_LPCR
] & LPCR_HVEE
)) {
8974 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
8979 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
8983 POWERPC_FAMILY(POWER9
)(ObjectClass
*oc
, void *data
)
8985 DeviceClass
*dc
= DEVICE_CLASS(oc
);
8986 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
8987 CPUClass
*cc
= CPU_CLASS(oc
);
8989 dc
->fw_name
= "PowerPC,POWER9";
8990 dc
->desc
= "POWER9";
8991 device_class_set_props(dc
, powerpc_servercpu_properties
);
8992 pcc
->pvr_match
= ppc_pvr_match_power9
;
8993 pcc
->pcr_mask
= PCR_COMPAT_2_05
| PCR_COMPAT_2_06
| PCR_COMPAT_2_07
;
8994 pcc
->pcr_supported
= PCR_COMPAT_3_00
| PCR_COMPAT_2_07
| PCR_COMPAT_2_06
|
8996 pcc
->init_proc
= init_proc_POWER9
;
8997 pcc
->check_pow
= check_pow_nocheck
;
8998 cc
->has_work
= cpu_has_work_POWER9
;
8999 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
9000 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
9001 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
9002 PPC_FLOAT_FRSQRTES
|
9005 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
9006 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
9008 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
9009 PPC_SEGMENT_64B
| PPC_SLBI
|
9010 PPC_POPCNTB
| PPC_POPCNTWD
|
9012 pcc
->insns_flags2
= PPC2_VSX
| PPC2_VSX207
| PPC2_DFP
| PPC2_DBRX
|
9013 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
9014 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
9015 PPC2_FP_TST_ISA206
| PPC2_BCTAR_ISA207
|
9016 PPC2_LSQ_ISA207
| PPC2_ALTIVEC_207
|
9017 PPC2_ISA205
| PPC2_ISA207S
| PPC2_FP_CVT_S64
|
9018 PPC2_TM
| PPC2_ISA300
| PPC2_PRCNTL
;
9019 pcc
->msr_mask
= (1ull << MSR_SF
) |
9037 pcc
->mmu_model
= POWERPC_MMU_3_00
;
9038 #if defined(CONFIG_SOFTMMU)
9039 pcc
->handle_mmu_fault
= ppc64_v3_handle_mmu_fault
;
9040 /* segment page size remain the same */
9041 pcc
->hash64_opts
= &ppc_hash64_opts_POWER7
;
9042 pcc
->radix_page_info
= &POWER9_radix_page_info
;
9043 pcc
->lrg_decr_bits
= 56;
9044 pcc
->n_host_threads
= 4;
9046 pcc
->excp_model
= POWERPC_EXCP_POWER9
;
9047 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER9
;
9048 pcc
->bfd_mach
= bfd_mach_ppc64
;
9049 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
9050 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
9051 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
9052 POWERPC_FLAG_VSX
| POWERPC_FLAG_TM
;
9053 pcc
->l1_dcache_size
= 0x8000;
9054 pcc
->l1_icache_size
= 0x8000;
9055 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
9056 pcc
->lpcr_pm
= LPCR_PDEE
| LPCR_HDEE
| LPCR_EEE
| LPCR_DEE
| LPCR_OEE
;
9059 #ifdef CONFIG_SOFTMMU
9061 * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings
9062 * Encoded as array of int_32s in the form:
9063 * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
9065 * y -> radix mode supported page size (encoded as a shift)
9067 static struct ppc_radix_page_info POWER10_radix_page_info
= {
9070 0x0000000c, /* 4K - enc: 0x0 */
9071 0xa0000010, /* 64K - enc: 0x5 */
9072 0x20000015, /* 2M - enc: 0x1 */
9073 0x4000001e /* 1G - enc: 0x2 */
9076 #endif /* CONFIG_SOFTMMU */
9078 static void init_proc_POWER10(CPUPPCState
*env
)
9080 /* Common Registers */
9081 init_proc_book3s_common(env
);
9082 gen_spr_book3s_207_dbg(env
);
9084 /* POWER8 Specific Registers */
9085 gen_spr_book3s_ids(env
);
9088 gen_spr_book3s_purr(env
);
9089 gen_spr_power5p_common(env
);
9090 gen_spr_power5p_lpar(env
);
9091 gen_spr_power5p_ear(env
);
9092 gen_spr_power6_common(env
);
9093 gen_spr_power6_dbg(env
);
9094 gen_spr_power8_tce_address_control(env
);
9095 gen_spr_power8_ids(env
);
9096 gen_spr_power8_ebb(env
);
9097 gen_spr_power8_fscr(env
);
9098 gen_spr_power8_pmu_sup(env
);
9099 gen_spr_power8_pmu_user(env
);
9100 gen_spr_power8_tm(env
);
9101 gen_spr_power8_pspb(env
);
9103 gen_spr_power8_ic(env
);
9104 gen_spr_power8_book4(env
);
9105 gen_spr_power8_rpr(env
);
9106 gen_spr_power9_mmu(env
);
9108 /* POWER9 Specific registers */
9109 spr_register_kvm(env
, SPR_TIDR
, "TIDR", NULL
, NULL
,
9110 spr_read_generic
, spr_write_generic
,
9111 KVM_REG_PPC_TIDR
, 0);
9113 /* FIXME: Filter fields properly based on privilege level */
9114 spr_register_kvm_hv(env
, SPR_PSSCR
, "PSSCR", NULL
, NULL
, NULL
, NULL
,
9115 spr_read_generic
, spr_write_generic
,
9116 KVM_REG_PPC_PSSCR
, 0);
9119 env
->dcache_line_size
= 128;
9120 env
->icache_line_size
= 128;
9122 /* Allocate hardware IRQ controller */
9123 init_excp_POWER10(env
);
9124 ppcPOWER9_irq_init(env_archcpu(env
));
9127 static bool ppc_pvr_match_power10(PowerPCCPUClass
*pcc
, uint32_t pvr
)
9129 if ((pvr
& CPU_POWERPC_POWER_SERVER_MASK
) == CPU_POWERPC_POWER10_BASE
) {
9135 static bool cpu_has_work_POWER10(CPUState
*cs
)
9137 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
9138 CPUPPCState
*env
= &cpu
->env
;
9141 uint64_t psscr
= env
->spr
[SPR_PSSCR
];
9143 if (!(cs
->interrupt_request
& CPU_INTERRUPT_HARD
)) {
9147 /* If EC is clear, just return true on any pending interrupt */
9148 if (!(psscr
& PSSCR_EC
)) {
9151 /* External Exception */
9152 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_EXT
)) &&
9153 (env
->spr
[SPR_LPCR
] & LPCR_EEE
)) {
9154 bool heic
= !!(env
->spr
[SPR_LPCR
] & LPCR_HEIC
);
9155 if (heic
== 0 || !msr_hv
|| msr_pr
) {
9159 /* Decrementer Exception */
9160 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DECR
)) &&
9161 (env
->spr
[SPR_LPCR
] & LPCR_DEE
)) {
9164 /* Machine Check or Hypervisor Maintenance Exception */
9165 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_MCK
|
9166 1u << PPC_INTERRUPT_HMI
)) && (env
->spr
[SPR_LPCR
] & LPCR_OEE
)) {
9169 /* Privileged Doorbell Exception */
9170 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_DOORBELL
)) &&
9171 (env
->spr
[SPR_LPCR
] & LPCR_PDEE
)) {
9174 /* Hypervisor Doorbell Exception */
9175 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HDOORBELL
)) &&
9176 (env
->spr
[SPR_LPCR
] & LPCR_HDEE
)) {
9179 /* Hypervisor virtualization exception */
9180 if ((env
->pending_interrupts
& (1u << PPC_INTERRUPT_HVIRT
)) &&
9181 (env
->spr
[SPR_LPCR
] & LPCR_HVEE
)) {
9184 if (env
->pending_interrupts
& (1u << PPC_INTERRUPT_RESET
)) {
9189 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
9193 POWERPC_FAMILY(POWER10
)(ObjectClass
*oc
, void *data
)
9195 DeviceClass
*dc
= DEVICE_CLASS(oc
);
9196 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
9197 CPUClass
*cc
= CPU_CLASS(oc
);
9199 dc
->fw_name
= "PowerPC,POWER10";
9200 dc
->desc
= "POWER10";
9201 device_class_set_props(dc
, powerpc_servercpu_properties
);
9202 pcc
->pvr_match
= ppc_pvr_match_power10
;
9203 pcc
->pcr_mask
= PCR_COMPAT_2_05
| PCR_COMPAT_2_06
| PCR_COMPAT_2_07
|
9205 pcc
->pcr_supported
= PCR_COMPAT_3_10
| PCR_COMPAT_3_00
| PCR_COMPAT_2_07
|
9206 PCR_COMPAT_2_06
| PCR_COMPAT_2_05
;
9207 pcc
->init_proc
= init_proc_POWER10
;
9208 pcc
->check_pow
= check_pow_nocheck
;
9209 cc
->has_work
= cpu_has_work_POWER10
;
9210 pcc
->insns_flags
= PPC_INSNS_BASE
| PPC_ISEL
| PPC_STRING
| PPC_MFTB
|
9211 PPC_FLOAT
| PPC_FLOAT_FSEL
| PPC_FLOAT_FRES
|
9212 PPC_FLOAT_FSQRT
| PPC_FLOAT_FRSQRTE
|
9213 PPC_FLOAT_FRSQRTES
|
9216 PPC_CACHE
| PPC_CACHE_ICBI
| PPC_CACHE_DCBZ
|
9217 PPC_MEM_SYNC
| PPC_MEM_EIEIO
|
9219 PPC_64B
| PPC_64H
| PPC_64BX
| PPC_ALTIVEC
|
9220 PPC_SEGMENT_64B
| PPC_SLBI
|
9221 PPC_POPCNTB
| PPC_POPCNTWD
|
9223 pcc
->insns_flags2
= PPC2_VSX
| PPC2_VSX207
| PPC2_DFP
| PPC2_DBRX
|
9224 PPC2_PERM_ISA206
| PPC2_DIVE_ISA206
|
9225 PPC2_ATOMIC_ISA206
| PPC2_FP_CVT_ISA206
|
9226 PPC2_FP_TST_ISA206
| PPC2_BCTAR_ISA207
|
9227 PPC2_LSQ_ISA207
| PPC2_ALTIVEC_207
|
9228 PPC2_ISA205
| PPC2_ISA207S
| PPC2_FP_CVT_S64
|
9229 PPC2_TM
| PPC2_ISA300
| PPC2_PRCNTL
;
9230 pcc
->msr_mask
= (1ull << MSR_SF
) |
9248 pcc
->mmu_model
= POWERPC_MMU_3_00
;
9249 #if defined(CONFIG_SOFTMMU)
9250 pcc
->handle_mmu_fault
= ppc64_v3_handle_mmu_fault
;
9251 /* segment page size remain the same */
9252 pcc
->hash64_opts
= &ppc_hash64_opts_POWER7
;
9253 pcc
->radix_page_info
= &POWER10_radix_page_info
;
9254 pcc
->lrg_decr_bits
= 56;
9256 pcc
->excp_model
= POWERPC_EXCP_POWER9
;
9257 pcc
->bus_model
= PPC_FLAGS_INPUT_POWER9
;
9258 pcc
->bfd_mach
= bfd_mach_ppc64
;
9259 pcc
->flags
= POWERPC_FLAG_VRE
| POWERPC_FLAG_SE
|
9260 POWERPC_FLAG_BE
| POWERPC_FLAG_PMM
|
9261 POWERPC_FLAG_BUS_CLK
| POWERPC_FLAG_CFAR
|
9262 POWERPC_FLAG_VSX
| POWERPC_FLAG_TM
;
9263 pcc
->l1_dcache_size
= 0x8000;
9264 pcc
->l1_icache_size
= 0x8000;
9265 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_lpcr
;
9266 pcc
->lpcr_pm
= LPCR_PDEE
| LPCR_HDEE
| LPCR_EEE
| LPCR_DEE
| LPCR_OEE
;
9269 #if !defined(CONFIG_USER_ONLY)
9270 void cpu_ppc_set_vhyp(PowerPCCPU
*cpu
, PPCVirtualHypervisor
*vhyp
)
9272 CPUPPCState
*env
= &cpu
->env
;
9277 * With a virtual hypervisor mode we never allow the CPU to go
9278 * hypervisor mode itself
9280 env
->msr_mask
&= ~MSR_HVB
;
9283 #endif /* !defined(CONFIG_USER_ONLY) */
9285 #endif /* defined(TARGET_PPC64) */
9287 /*****************************************************************************/
9288 /* Generic CPU instantiation routine */
9289 static void init_ppc_proc(PowerPCCPU
*cpu
)
9291 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9292 CPUPPCState
*env
= &cpu
->env
;
9293 #if !defined(CONFIG_USER_ONLY)
9296 env
->irq_inputs
= NULL
;
9297 /* Set all exception vectors to an invalid address */
9298 for (i
= 0; i
< POWERPC_EXCP_NB
; i
++) {
9299 env
->excp_vectors
[i
] = (target_ulong
)(-1ULL);
9301 env
->ivor_mask
= 0x00000000;
9302 env
->ivpr_mask
= 0x00000000;
9303 /* Default MMU definitions */
9307 env
->tlb_type
= TLB_NONE
;
9309 /* Register SPR common to all PowerPC implementations */
9310 gen_spr_generic(env
);
9311 spr_register(env
, SPR_PVR
, "PVR",
9312 /* Linux permits userspace to read PVR */
9313 #if defined(CONFIG_LINUX_USER)
9319 &spr_read_generic
, SPR_NOACCESS
,
9321 /* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
9322 if (pcc
->svr
!= POWERPC_SVR_NONE
) {
9323 if (pcc
->svr
& POWERPC_SVR_E500
) {
9324 spr_register(env
, SPR_E500_SVR
, "SVR",
9325 SPR_NOACCESS
, SPR_NOACCESS
,
9326 &spr_read_generic
, SPR_NOACCESS
,
9327 pcc
->svr
& ~POWERPC_SVR_E500
);
9329 spr_register(env
, SPR_SVR
, "SVR",
9330 SPR_NOACCESS
, SPR_NOACCESS
,
9331 &spr_read_generic
, SPR_NOACCESS
,
9335 /* PowerPC implementation specific initialisations (SPRs, timers, ...) */
9336 (*pcc
->init_proc
)(env
);
9338 #if !defined(CONFIG_USER_ONLY)
9339 ppc_gdb_gen_spr_xml(cpu
);
9342 /* MSR bits & flags consistency checks */
9343 if (env
->msr_mask
& (1 << 25)) {
9344 switch (env
->flags
& (POWERPC_FLAG_SPE
| POWERPC_FLAG_VRE
)) {
9345 case POWERPC_FLAG_SPE
:
9346 case POWERPC_FLAG_VRE
:
9349 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9350 "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n");
9353 } else if (env
->flags
& (POWERPC_FLAG_SPE
| POWERPC_FLAG_VRE
)) {
9354 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9355 "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n");
9358 if (env
->msr_mask
& (1 << 17)) {
9359 switch (env
->flags
& (POWERPC_FLAG_TGPR
| POWERPC_FLAG_CE
)) {
9360 case POWERPC_FLAG_TGPR
:
9361 case POWERPC_FLAG_CE
:
9364 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9365 "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n");
9368 } else if (env
->flags
& (POWERPC_FLAG_TGPR
| POWERPC_FLAG_CE
)) {
9369 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9370 "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n");
9373 if (env
->msr_mask
& (1 << 10)) {
9374 switch (env
->flags
& (POWERPC_FLAG_SE
| POWERPC_FLAG_DWE
|
9375 POWERPC_FLAG_UBLE
)) {
9376 case POWERPC_FLAG_SE
:
9377 case POWERPC_FLAG_DWE
:
9378 case POWERPC_FLAG_UBLE
:
9381 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9382 "Should define POWERPC_FLAG_SE or POWERPC_FLAG_DWE or "
9383 "POWERPC_FLAG_UBLE\n");
9386 } else if (env
->flags
& (POWERPC_FLAG_SE
| POWERPC_FLAG_DWE
|
9387 POWERPC_FLAG_UBLE
)) {
9388 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9389 "Should not define POWERPC_FLAG_SE nor POWERPC_FLAG_DWE nor "
9390 "POWERPC_FLAG_UBLE\n");
9393 if (env
->msr_mask
& (1 << 9)) {
9394 switch (env
->flags
& (POWERPC_FLAG_BE
| POWERPC_FLAG_DE
)) {
9395 case POWERPC_FLAG_BE
:
9396 case POWERPC_FLAG_DE
:
9399 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9400 "Should define POWERPC_FLAG_BE or POWERPC_FLAG_DE\n");
9403 } else if (env
->flags
& (POWERPC_FLAG_BE
| POWERPC_FLAG_DE
)) {
9404 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9405 "Should not define POWERPC_FLAG_BE nor POWERPC_FLAG_DE\n");
9408 if (env
->msr_mask
& (1 << 2)) {
9409 switch (env
->flags
& (POWERPC_FLAG_PX
| POWERPC_FLAG_PMM
)) {
9410 case POWERPC_FLAG_PX
:
9411 case POWERPC_FLAG_PMM
:
9414 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9415 "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n");
9418 } else if (env
->flags
& (POWERPC_FLAG_PX
| POWERPC_FLAG_PMM
)) {
9419 fprintf(stderr
, "PowerPC MSR definition inconsistency\n"
9420 "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n");
9423 if ((env
->flags
& (POWERPC_FLAG_RTC_CLK
| POWERPC_FLAG_BUS_CLK
)) == 0) {
9424 fprintf(stderr
, "PowerPC flags inconsistency\n"
9425 "Should define the time-base and decrementer clock source\n");
9428 /* Allocate TLBs buffer when needed */
9429 #if !defined(CONFIG_USER_ONLY)
9430 if (env
->nb_tlb
!= 0) {
9431 int nb_tlb
= env
->nb_tlb
;
9432 if (env
->id_tlbs
!= 0) {
9435 switch (env
->tlb_type
) {
9437 env
->tlb
.tlb6
= g_new0(ppc6xx_tlb_t
, nb_tlb
);
9440 env
->tlb
.tlbe
= g_new0(ppcemb_tlb_t
, nb_tlb
);
9443 env
->tlb
.tlbm
= g_new0(ppcmas_tlb_t
, nb_tlb
);
9446 /* Pre-compute some useful values */
9447 env
->tlb_per_way
= env
->nb_tlb
/ env
->nb_ways
;
9449 if (env
->irq_inputs
== NULL
) {
9450 warn_report("no internal IRQ controller registered."
9451 " Attempt QEMU to crash very soon !");
9454 if (env
->check_pow
== NULL
) {
9455 warn_report("no power management check handler registered."
9456 " Attempt QEMU to crash very soon !");
9460 #if defined(PPC_DUMP_CPU)
9461 static void dump_ppc_sprs(CPUPPCState
*env
)
9464 #if !defined(CONFIG_USER_ONLY)
9470 printf("Special purpose registers:\n");
9471 for (i
= 0; i
< 32; i
++) {
9472 for (j
= 0; j
< 32; j
++) {
9474 spr
= &env
->spr_cb
[n
];
9475 uw
= spr
->uea_write
!= NULL
&& spr
->uea_write
!= SPR_NOACCESS
;
9476 ur
= spr
->uea_read
!= NULL
&& spr
->uea_read
!= SPR_NOACCESS
;
9477 #if !defined(CONFIG_USER_ONLY)
9478 sw
= spr
->oea_write
!= NULL
&& spr
->oea_write
!= SPR_NOACCESS
;
9479 sr
= spr
->oea_read
!= NULL
&& spr
->oea_read
!= SPR_NOACCESS
;
9480 if (sw
|| sr
|| uw
|| ur
) {
9481 printf("SPR: %4d (%03x) %-8s s%c%c u%c%c\n",
9482 (i
<< 5) | j
, (i
<< 5) | j
, spr
->name
,
9483 sw
? 'w' : '-', sr
? 'r' : '-',
9484 uw
? 'w' : '-', ur
? 'r' : '-');
9488 printf("SPR: %4d (%03x) %-8s u%c%c\n",
9489 (i
<< 5) | j
, (i
<< 5) | j
, spr
->name
,
9490 uw
? 'w' : '-', ur
? 'r' : '-');
9500 /*****************************************************************************/
9504 PPC_DIRECT
= 0, /* Opcode routine */
9505 PPC_INDIRECT
= 1, /* Indirect opcode table */
9508 #define PPC_OPCODE_MASK 0x3
9510 static inline int is_indirect_opcode(void *handler
)
9512 return ((uintptr_t)handler
& PPC_OPCODE_MASK
) == PPC_INDIRECT
;
9515 static inline opc_handler_t
**ind_table(void *handler
)
9517 return (opc_handler_t
**)((uintptr_t)handler
& ~PPC_OPCODE_MASK
);
9520 /* Instruction table creation */
9521 /* Opcodes tables creation */
9522 static void fill_new_table(opc_handler_t
**table
, int len
)
9526 for (i
= 0; i
< len
; i
++) {
9527 table
[i
] = &invalid_handler
;
9531 static int create_new_table(opc_handler_t
**table
, unsigned char idx
)
9533 opc_handler_t
**tmp
;
9535 tmp
= g_new(opc_handler_t
*, PPC_CPU_INDIRECT_OPCODES_LEN
);
9536 fill_new_table(tmp
, PPC_CPU_INDIRECT_OPCODES_LEN
);
9537 table
[idx
] = (opc_handler_t
*)((uintptr_t)tmp
| PPC_INDIRECT
);
9542 static int insert_in_table(opc_handler_t
**table
, unsigned char idx
,
9543 opc_handler_t
*handler
)
9545 if (table
[idx
] != &invalid_handler
) {
9548 table
[idx
] = handler
;
9553 static int register_direct_insn(opc_handler_t
**ppc_opcodes
,
9554 unsigned char idx
, opc_handler_t
*handler
)
9556 if (insert_in_table(ppc_opcodes
, idx
, handler
) < 0) {
9557 printf("*** ERROR: opcode %02x already assigned in main "
9558 "opcode table\n", idx
);
9559 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9560 printf(" Registered handler '%s' - new handler '%s'\n",
9561 ppc_opcodes
[idx
]->oname
, handler
->oname
);
9569 static int register_ind_in_table(opc_handler_t
**table
,
9570 unsigned char idx1
, unsigned char idx2
,
9571 opc_handler_t
*handler
)
9573 if (table
[idx1
] == &invalid_handler
) {
9574 if (create_new_table(table
, idx1
) < 0) {
9575 printf("*** ERROR: unable to create indirect table "
9576 "idx=%02x\n", idx1
);
9580 if (!is_indirect_opcode(table
[idx1
])) {
9581 printf("*** ERROR: idx %02x already assigned to a direct "
9583 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9584 printf(" Registered handler '%s' - new handler '%s'\n",
9585 ind_table(table
[idx1
])[idx2
]->oname
, handler
->oname
);
9590 if (handler
!= NULL
&&
9591 insert_in_table(ind_table(table
[idx1
]), idx2
, handler
) < 0) {
9592 printf("*** ERROR: opcode %02x already assigned in "
9593 "opcode table %02x\n", idx2
, idx1
);
9594 #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9595 printf(" Registered handler '%s' - new handler '%s'\n",
9596 ind_table(table
[idx1
])[idx2
]->oname
, handler
->oname
);
9604 static int register_ind_insn(opc_handler_t
**ppc_opcodes
,
9605 unsigned char idx1
, unsigned char idx2
,
9606 opc_handler_t
*handler
)
9608 return register_ind_in_table(ppc_opcodes
, idx1
, idx2
, handler
);
9611 static int register_dblind_insn(opc_handler_t
**ppc_opcodes
,
9612 unsigned char idx1
, unsigned char idx2
,
9613 unsigned char idx3
, opc_handler_t
*handler
)
9615 if (register_ind_in_table(ppc_opcodes
, idx1
, idx2
, NULL
) < 0) {
9616 printf("*** ERROR: unable to join indirect table idx "
9617 "[%02x-%02x]\n", idx1
, idx2
);
9620 if (register_ind_in_table(ind_table(ppc_opcodes
[idx1
]), idx2
, idx3
,
9622 printf("*** ERROR: unable to insert opcode "
9623 "[%02x-%02x-%02x]\n", idx1
, idx2
, idx3
);
9630 static int register_trplind_insn(opc_handler_t
**ppc_opcodes
,
9631 unsigned char idx1
, unsigned char idx2
,
9632 unsigned char idx3
, unsigned char idx4
,
9633 opc_handler_t
*handler
)
9635 opc_handler_t
**table
;
9637 if (register_ind_in_table(ppc_opcodes
, idx1
, idx2
, NULL
) < 0) {
9638 printf("*** ERROR: unable to join indirect table idx "
9639 "[%02x-%02x]\n", idx1
, idx2
);
9642 table
= ind_table(ppc_opcodes
[idx1
]);
9643 if (register_ind_in_table(table
, idx2
, idx3
, NULL
) < 0) {
9644 printf("*** ERROR: unable to join 2nd-level indirect table idx "
9645 "[%02x-%02x-%02x]\n", idx1
, idx2
, idx3
);
9648 table
= ind_table(table
[idx2
]);
9649 if (register_ind_in_table(table
, idx3
, idx4
, handler
) < 0) {
9650 printf("*** ERROR: unable to insert opcode "
9651 "[%02x-%02x-%02x-%02x]\n", idx1
, idx2
, idx3
, idx4
);
9656 static int register_insn(opc_handler_t
**ppc_opcodes
, opcode_t
*insn
)
9658 if (insn
->opc2
!= 0xFF) {
9659 if (insn
->opc3
!= 0xFF) {
9660 if (insn
->opc4
!= 0xFF) {
9661 if (register_trplind_insn(ppc_opcodes
, insn
->opc1
, insn
->opc2
,
9662 insn
->opc3
, insn
->opc4
,
9663 &insn
->handler
) < 0) {
9667 if (register_dblind_insn(ppc_opcodes
, insn
->opc1
, insn
->opc2
,
9668 insn
->opc3
, &insn
->handler
) < 0) {
9673 if (register_ind_insn(ppc_opcodes
, insn
->opc1
,
9674 insn
->opc2
, &insn
->handler
) < 0) {
9679 if (register_direct_insn(ppc_opcodes
, insn
->opc1
, &insn
->handler
) < 0) {
9687 static int test_opcode_table(opc_handler_t
**table
, int len
)
9691 for (i
= 0, count
= 0; i
< len
; i
++) {
9692 /* Consistency fixup */
9693 if (table
[i
] == NULL
) {
9694 table
[i
] = &invalid_handler
;
9696 if (table
[i
] != &invalid_handler
) {
9697 if (is_indirect_opcode(table
[i
])) {
9698 tmp
= test_opcode_table(ind_table(table
[i
]),
9699 PPC_CPU_INDIRECT_OPCODES_LEN
);
9702 table
[i
] = &invalid_handler
;
9715 static void fix_opcode_tables(opc_handler_t
**ppc_opcodes
)
9717 if (test_opcode_table(ppc_opcodes
, PPC_CPU_OPCODES_LEN
) == 0) {
9718 printf("*** WARNING: no opcode defined !\n");
9722 /*****************************************************************************/
9723 static void create_ppc_opcodes(PowerPCCPU
*cpu
, Error
**errp
)
9725 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
9728 fill_new_table(cpu
->opcodes
, PPC_CPU_OPCODES_LEN
);
9729 for (opc
= opcodes
; opc
< &opcodes
[ARRAY_SIZE(opcodes
)]; opc
++) {
9730 if (((opc
->handler
.type
& pcc
->insns_flags
) != 0) ||
9731 ((opc
->handler
.type2
& pcc
->insns_flags2
) != 0)) {
9732 if (register_insn(cpu
->opcodes
, opc
) < 0) {
9733 error_setg(errp
, "ERROR initializing PowerPC instruction "
9734 "0x%02x 0x%02x 0x%02x", opc
->opc1
, opc
->opc2
,
9740 fix_opcode_tables(cpu
->opcodes
);
9745 #if defined(PPC_DUMP_CPU)
9746 static void dump_ppc_insns(CPUPPCState
*env
)
9748 opc_handler_t
**table
, *handler
;
9750 uint8_t opc1
, opc2
, opc3
, opc4
;
9752 printf("Instructions set:\n");
9753 /* opc1 is 6 bits long */
9754 for (opc1
= 0x00; opc1
< PPC_CPU_OPCODES_LEN
; opc1
++) {
9755 table
= env
->opcodes
;
9756 handler
= table
[opc1
];
9757 if (is_indirect_opcode(handler
)) {
9758 /* opc2 is 5 bits long */
9759 for (opc2
= 0; opc2
< PPC_CPU_INDIRECT_OPCODES_LEN
; opc2
++) {
9760 table
= env
->opcodes
;
9761 handler
= env
->opcodes
[opc1
];
9762 table
= ind_table(handler
);
9763 handler
= table
[opc2
];
9764 if (is_indirect_opcode(handler
)) {
9765 table
= ind_table(handler
);
9766 /* opc3 is 5 bits long */
9767 for (opc3
= 0; opc3
< PPC_CPU_INDIRECT_OPCODES_LEN
;
9769 handler
= table
[opc3
];
9770 if (is_indirect_opcode(handler
)) {
9771 table
= ind_table(handler
);
9772 /* opc4 is 5 bits long */
9773 for (opc4
= 0; opc4
< PPC_CPU_INDIRECT_OPCODES_LEN
;
9775 handler
= table
[opc4
];
9776 if (handler
->handler
!= &gen_invalid
) {
9777 printf("INSN: %02x %02x %02x %02x -- "
9778 "(%02d %04d %02d) : %s\n",
9779 opc1
, opc2
, opc3
, opc4
,
9780 opc1
, (opc3
<< 5) | opc2
, opc4
,
9785 if (handler
->handler
!= &gen_invalid
) {
9786 /* Special hack to properly dump SPE insns */
9787 p
= strchr(handler
->oname
, '_');
9789 printf("INSN: %02x %02x %02x (%02d %04d) : "
9791 opc1
, opc2
, opc3
, opc1
,
9796 if ((p
- handler
->oname
) != strlen(q
)
9797 || (memcmp(handler
->oname
, q
, strlen(q
))
9799 /* First instruction */
9800 printf("INSN: %02x %02x %02x"
9801 "(%02d %04d) : %.*s\n",
9802 opc1
, opc2
<< 1, opc3
, opc1
,
9803 (opc3
<< 6) | (opc2
<< 1),
9804 (int)(p
- handler
->oname
),
9807 if (strcmp(p
+ 1, q
) != 0) {
9808 /* Second instruction */
9809 printf("INSN: %02x %02x %02x "
9810 "(%02d %04d) : %s\n", opc1
,
9811 (opc2
<< 1) | 1, opc3
, opc1
,
9812 (opc3
<< 6) | (opc2
<< 1) | 1,
9820 if (handler
->handler
!= &gen_invalid
) {
9821 printf("INSN: %02x %02x -- (%02d %04d) : %s\n",
9822 opc1
, opc2
, opc1
, opc2
, handler
->oname
);
9827 if (handler
->handler
!= &gen_invalid
) {
9828 printf("INSN: %02x -- -- (%02d ----) : %s\n",
9829 opc1
, opc1
, handler
->oname
);
9836 static bool avr_need_swap(CPUPPCState
*env
)
9838 #ifdef HOST_WORDS_BIGENDIAN
9845 #if !defined(CONFIG_USER_ONLY)
9846 static int gdb_find_spr_idx(CPUPPCState
*env
, int n
)
9850 for (i
= 0; i
< ARRAY_SIZE(env
->spr_cb
); i
++) {
9851 ppc_spr_t
*spr
= &env
->spr_cb
[i
];
9853 if (spr
->name
&& spr
->gdb_id
== n
) {
9860 static int gdb_get_spr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9865 reg
= gdb_find_spr_idx(env
, n
);
9870 len
= TARGET_LONG_SIZE
;
9871 stn_p(mem_buf
, len
, env
->spr
[reg
]);
9872 ppc_maybe_bswap_register(env
, mem_buf
, len
);
9876 static int gdb_set_spr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9881 reg
= gdb_find_spr_idx(env
, n
);
9886 len
= TARGET_LONG_SIZE
;
9887 ppc_maybe_bswap_register(env
, mem_buf
, len
);
9888 env
->spr
[reg
] = ldn_p(mem_buf
, len
);
9894 static int gdb_get_float_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9897 stfq_p(mem_buf
, *cpu_fpr_ptr(env
, n
));
9898 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9902 stl_p(mem_buf
, env
->fpscr
);
9903 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9909 static int gdb_set_float_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9912 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9913 *cpu_fpr_ptr(env
, n
) = ldfq_p(mem_buf
);
9917 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9918 helper_store_fpscr(env
, ldl_p(mem_buf
), 0xffffffff);
9924 static int gdb_get_avr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9927 ppc_avr_t
*avr
= cpu_avr_ptr(env
, n
);
9928 if (!avr_need_swap(env
)) {
9929 stq_p(mem_buf
, avr
->u64
[0]);
9930 stq_p(mem_buf
+ 8, avr
->u64
[1]);
9932 stq_p(mem_buf
, avr
->u64
[1]);
9933 stq_p(mem_buf
+ 8, avr
->u64
[0]);
9935 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9936 ppc_maybe_bswap_register(env
, mem_buf
+ 8, 8);
9940 stl_p(mem_buf
, helper_mfvscr(env
));
9941 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9945 stl_p(mem_buf
, (uint32_t)env
->spr
[SPR_VRSAVE
]);
9946 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9952 static int gdb_set_avr_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9955 ppc_avr_t
*avr
= cpu_avr_ptr(env
, n
);
9956 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9957 ppc_maybe_bswap_register(env
, mem_buf
+ 8, 8);
9958 if (!avr_need_swap(env
)) {
9959 avr
->u64
[0] = ldq_p(mem_buf
);
9960 avr
->u64
[1] = ldq_p(mem_buf
+ 8);
9962 avr
->u64
[1] = ldq_p(mem_buf
);
9963 avr
->u64
[0] = ldq_p(mem_buf
+ 8);
9968 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9969 helper_mtvscr(env
, ldl_p(mem_buf
));
9973 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9974 env
->spr
[SPR_VRSAVE
] = (target_ulong
)ldl_p(mem_buf
);
9980 static int gdb_get_spe_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
9983 #if defined(TARGET_PPC64)
9984 stl_p(mem_buf
, env
->gpr
[n
] >> 32);
9985 ppc_maybe_bswap_register(env
, mem_buf
, 4);
9987 stl_p(mem_buf
, env
->gprh
[n
]);
9992 stq_p(mem_buf
, env
->spe_acc
);
9993 ppc_maybe_bswap_register(env
, mem_buf
, 8);
9997 stl_p(mem_buf
, env
->spe_fscr
);
9998 ppc_maybe_bswap_register(env
, mem_buf
, 4);
10004 static int gdb_set_spe_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
10007 #if defined(TARGET_PPC64)
10008 target_ulong lo
= (uint32_t)env
->gpr
[n
];
10011 ppc_maybe_bswap_register(env
, mem_buf
, 4);
10013 hi
= (target_ulong
)ldl_p(mem_buf
) << 32;
10014 env
->gpr
[n
] = lo
| hi
;
10016 env
->gprh
[n
] = ldl_p(mem_buf
);
10021 ppc_maybe_bswap_register(env
, mem_buf
, 8);
10022 env
->spe_acc
= ldq_p(mem_buf
);
10026 ppc_maybe_bswap_register(env
, mem_buf
, 4);
10027 env
->spe_fscr
= ldl_p(mem_buf
);
10033 static int gdb_get_vsx_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
10036 stq_p(mem_buf
, *cpu_vsrl_ptr(env
, n
));
10037 ppc_maybe_bswap_register(env
, mem_buf
, 8);
10043 static int gdb_set_vsx_reg(CPUPPCState
*env
, uint8_t *mem_buf
, int n
)
10046 ppc_maybe_bswap_register(env
, mem_buf
, 8);
10047 *cpu_vsrl_ptr(env
, n
) = ldq_p(mem_buf
);
10053 static int ppc_fixup_cpu(PowerPCCPU
*cpu
)
10055 CPUPPCState
*env
= &cpu
->env
;
10058 * TCG doesn't (yet) emulate some groups of instructions that are
10059 * implemented on some otherwise supported CPUs (e.g. VSX and
10060 * decimal floating point instructions on POWER7). We remove
10061 * unsupported instruction groups from the cpu state's instruction
10062 * masks and hope the guest can cope. For at least the pseries
10063 * machine, the unavailability of these instructions can be
10064 * advertised to the guest via the device tree.
10066 if ((env
->insns_flags
& ~PPC_TCG_INSNS
)
10067 || (env
->insns_flags2
& ~PPC_TCG_INSNS2
)) {
10068 warn_report("Disabling some instructions which are not "
10069 "emulated by TCG (0x%" PRIx64
", 0x%" PRIx64
")",
10070 env
->insns_flags
& ~PPC_TCG_INSNS
,
10071 env
->insns_flags2
& ~PPC_TCG_INSNS2
);
10073 env
->insns_flags
&= PPC_TCG_INSNS
;
10074 env
->insns_flags2
&= PPC_TCG_INSNS2
;
10078 static void ppc_cpu_realize(DeviceState
*dev
, Error
**errp
)
10080 CPUState
*cs
= CPU(dev
);
10081 PowerPCCPU
*cpu
= POWERPC_CPU(dev
);
10082 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10083 Error
*local_err
= NULL
;
10085 cpu_exec_realizefn(cs
, &local_err
);
10086 if (local_err
!= NULL
) {
10087 error_propagate(errp
, local_err
);
10090 if (cpu
->vcpu_id
== UNASSIGNED_CPU_INDEX
) {
10091 cpu
->vcpu_id
= cs
->cpu_index
;
10094 if (tcg_enabled()) {
10095 if (ppc_fixup_cpu(cpu
) != 0) {
10096 error_setg(errp
, "Unable to emulate selected CPU with TCG");
10101 create_ppc_opcodes(cpu
, &local_err
);
10102 if (local_err
!= NULL
) {
10103 error_propagate(errp
, local_err
);
10106 init_ppc_proc(cpu
);
10108 if (pcc
->insns_flags
& PPC_FLOAT
) {
10109 gdb_register_coprocessor(cs
, gdb_get_float_reg
, gdb_set_float_reg
,
10110 33, "power-fpu.xml", 0);
10112 if (pcc
->insns_flags
& PPC_ALTIVEC
) {
10113 gdb_register_coprocessor(cs
, gdb_get_avr_reg
, gdb_set_avr_reg
,
10114 34, "power-altivec.xml", 0);
10116 if (pcc
->insns_flags
& PPC_SPE
) {
10117 gdb_register_coprocessor(cs
, gdb_get_spe_reg
, gdb_set_spe_reg
,
10118 34, "power-spe.xml", 0);
10120 if (pcc
->insns_flags2
& PPC2_VSX
) {
10121 gdb_register_coprocessor(cs
, gdb_get_vsx_reg
, gdb_set_vsx_reg
,
10122 32, "power-vsx.xml", 0);
10124 #ifndef CONFIG_USER_ONLY
10125 gdb_register_coprocessor(cs
, gdb_get_spr_reg
, gdb_set_spr_reg
,
10126 pcc
->gdb_num_sprs
, "power-spr.xml", 0);
10128 qemu_init_vcpu(cs
);
10130 pcc
->parent_realize(dev
, errp
);
10132 #if defined(PPC_DUMP_CPU)
10134 CPUPPCState
*env
= &cpu
->env
;
10135 const char *mmu_model
, *excp_model
, *bus_model
;
10136 switch (env
->mmu_model
) {
10137 case POWERPC_MMU_32B
:
10138 mmu_model
= "PowerPC 32";
10140 case POWERPC_MMU_SOFT_6xx
:
10141 mmu_model
= "PowerPC 6xx/7xx with software driven TLBs";
10143 case POWERPC_MMU_SOFT_74xx
:
10144 mmu_model
= "PowerPC 74xx with software driven TLBs";
10146 case POWERPC_MMU_SOFT_4xx
:
10147 mmu_model
= "PowerPC 4xx with software driven TLBs";
10149 case POWERPC_MMU_SOFT_4xx_Z
:
10150 mmu_model
= "PowerPC 4xx with software driven TLBs "
10151 "and zones protections";
10153 case POWERPC_MMU_REAL
:
10154 mmu_model
= "PowerPC real mode only";
10156 case POWERPC_MMU_MPC8xx
:
10157 mmu_model
= "PowerPC MPC8xx";
10159 case POWERPC_MMU_BOOKE
:
10160 mmu_model
= "PowerPC BookE";
10162 case POWERPC_MMU_BOOKE206
:
10163 mmu_model
= "PowerPC BookE 2.06";
10165 case POWERPC_MMU_601
:
10166 mmu_model
= "PowerPC 601";
10168 #if defined(TARGET_PPC64)
10169 case POWERPC_MMU_64B
:
10170 mmu_model
= "PowerPC 64";
10174 mmu_model
= "Unknown or invalid";
10177 switch (env
->excp_model
) {
10178 case POWERPC_EXCP_STD
:
10179 excp_model
= "PowerPC";
10181 case POWERPC_EXCP_40x
:
10182 excp_model
= "PowerPC 40x";
10184 case POWERPC_EXCP_601
:
10185 excp_model
= "PowerPC 601";
10187 case POWERPC_EXCP_602
:
10188 excp_model
= "PowerPC 602";
10190 case POWERPC_EXCP_603
:
10191 excp_model
= "PowerPC 603";
10193 case POWERPC_EXCP_603E
:
10194 excp_model
= "PowerPC 603e";
10196 case POWERPC_EXCP_604
:
10197 excp_model
= "PowerPC 604";
10199 case POWERPC_EXCP_7x0
:
10200 excp_model
= "PowerPC 740/750";
10202 case POWERPC_EXCP_7x5
:
10203 excp_model
= "PowerPC 745/755";
10205 case POWERPC_EXCP_74xx
:
10206 excp_model
= "PowerPC 74xx";
10208 case POWERPC_EXCP_BOOKE
:
10209 excp_model
= "PowerPC BookE";
10211 #if defined(TARGET_PPC64)
10212 case POWERPC_EXCP_970
:
10213 excp_model
= "PowerPC 970";
10217 excp_model
= "Unknown or invalid";
10220 switch (env
->bus_model
) {
10221 case PPC_FLAGS_INPUT_6xx
:
10222 bus_model
= "PowerPC 6xx";
10224 case PPC_FLAGS_INPUT_BookE
:
10225 bus_model
= "PowerPC BookE";
10227 case PPC_FLAGS_INPUT_405
:
10228 bus_model
= "PowerPC 405";
10230 case PPC_FLAGS_INPUT_401
:
10231 bus_model
= "PowerPC 401/403";
10233 case PPC_FLAGS_INPUT_RCPU
:
10234 bus_model
= "RCPU / MPC8xx";
10236 #if defined(TARGET_PPC64)
10237 case PPC_FLAGS_INPUT_970
:
10238 bus_model
= "PowerPC 970";
10242 bus_model
= "Unknown or invalid";
10245 printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64
"\n"
10246 " MMU model : %s\n",
10247 object_class_get_name(OBJECT_CLASS(pcc
)),
10248 pcc
->pvr
, pcc
->msr_mask
, mmu_model
);
10249 #if !defined(CONFIG_USER_ONLY)
10250 if (env
->tlb
.tlb6
) {
10251 printf(" %d %s TLB in %d ways\n",
10252 env
->nb_tlb
, env
->id_tlbs
? "splitted" : "merged",
10256 printf(" Exceptions model : %s\n"
10257 " Bus model : %s\n",
10258 excp_model
, bus_model
);
10259 printf(" MSR features :\n");
10260 if (env
->flags
& POWERPC_FLAG_SPE
) {
10261 printf(" signal processing engine enable"
10263 } else if (env
->flags
& POWERPC_FLAG_VRE
) {
10264 printf(" vector processor enable\n");
10266 if (env
->flags
& POWERPC_FLAG_TGPR
) {
10267 printf(" temporary GPRs\n");
10268 } else if (env
->flags
& POWERPC_FLAG_CE
) {
10269 printf(" critical input enable\n");
10271 if (env
->flags
& POWERPC_FLAG_SE
) {
10272 printf(" single-step trace mode\n");
10273 } else if (env
->flags
& POWERPC_FLAG_DWE
) {
10274 printf(" debug wait enable\n");
10275 } else if (env
->flags
& POWERPC_FLAG_UBLE
) {
10276 printf(" user BTB lock enable\n");
10278 if (env
->flags
& POWERPC_FLAG_BE
) {
10279 printf(" branch-step trace mode\n");
10280 } else if (env
->flags
& POWERPC_FLAG_DE
) {
10281 printf(" debug interrupt enable\n");
10283 if (env
->flags
& POWERPC_FLAG_PX
) {
10284 printf(" inclusive protection\n");
10285 } else if (env
->flags
& POWERPC_FLAG_PMM
) {
10286 printf(" performance monitor mark\n");
10288 if (env
->flags
== POWERPC_FLAG_NONE
) {
10291 printf(" Time-base/decrementer clock source: %s\n",
10292 env
->flags
& POWERPC_FLAG_RTC_CLK
? "RTC clock" : "bus clock");
10293 dump_ppc_insns(env
);
10294 dump_ppc_sprs(env
);
10301 cpu_exec_unrealizefn(cs
);
10304 static void ppc_cpu_unrealize(DeviceState
*dev
, Error
**errp
)
10306 PowerPCCPU
*cpu
= POWERPC_CPU(dev
);
10307 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10308 Error
*local_err
= NULL
;
10309 opc_handler_t
**table
, **table_2
;
10312 pcc
->parent_unrealize(dev
, &local_err
);
10313 if (local_err
!= NULL
) {
10314 error_propagate(errp
, local_err
);
10318 for (i
= 0; i
< PPC_CPU_OPCODES_LEN
; i
++) {
10319 if (cpu
->opcodes
[i
] == &invalid_handler
) {
10322 if (is_indirect_opcode(cpu
->opcodes
[i
])) {
10323 table
= ind_table(cpu
->opcodes
[i
]);
10324 for (j
= 0; j
< PPC_CPU_INDIRECT_OPCODES_LEN
; j
++) {
10325 if (table
[j
] == &invalid_handler
) {
10328 if (is_indirect_opcode(table
[j
])) {
10329 table_2
= ind_table(table
[j
]);
10330 for (k
= 0; k
< PPC_CPU_INDIRECT_OPCODES_LEN
; k
++) {
10331 if (table_2
[k
] != &invalid_handler
&&
10332 is_indirect_opcode(table_2
[k
])) {
10333 g_free((opc_handler_t
*)((uintptr_t)table_2
[k
] &
10337 g_free((opc_handler_t
*)((uintptr_t)table
[j
] &
10341 g_free((opc_handler_t
*)((uintptr_t)cpu
->opcodes
[i
] &
10347 static gint
ppc_cpu_compare_class_pvr(gconstpointer a
, gconstpointer b
)
10349 ObjectClass
*oc
= (ObjectClass
*)a
;
10350 uint32_t pvr
= *(uint32_t *)b
;
10351 PowerPCCPUClass
*pcc
= (PowerPCCPUClass
*)a
;
10353 /* -cpu host does a PVR lookup during construction */
10354 if (unlikely(strcmp(object_class_get_name(oc
),
10355 TYPE_HOST_POWERPC_CPU
) == 0)) {
10359 return pcc
->pvr
== pvr
? 0 : -1;
10362 PowerPCCPUClass
*ppc_cpu_class_by_pvr(uint32_t pvr
)
10364 GSList
*list
, *item
;
10365 PowerPCCPUClass
*pcc
= NULL
;
10367 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10368 item
= g_slist_find_custom(list
, &pvr
, ppc_cpu_compare_class_pvr
);
10369 if (item
!= NULL
) {
10370 pcc
= POWERPC_CPU_CLASS(item
->data
);
10372 g_slist_free(list
);
10377 static gint
ppc_cpu_compare_class_pvr_mask(gconstpointer a
, gconstpointer b
)
10379 ObjectClass
*oc
= (ObjectClass
*)a
;
10380 uint32_t pvr
= *(uint32_t *)b
;
10381 PowerPCCPUClass
*pcc
= (PowerPCCPUClass
*)a
;
10383 /* -cpu host does a PVR lookup during construction */
10384 if (unlikely(strcmp(object_class_get_name(oc
),
10385 TYPE_HOST_POWERPC_CPU
) == 0)) {
10389 if (pcc
->pvr_match(pcc
, pvr
)) {
10396 PowerPCCPUClass
*ppc_cpu_class_by_pvr_mask(uint32_t pvr
)
10398 GSList
*list
, *item
;
10399 PowerPCCPUClass
*pcc
= NULL
;
10401 list
= object_class_get_list(TYPE_POWERPC_CPU
, true);
10402 item
= g_slist_find_custom(list
, &pvr
, ppc_cpu_compare_class_pvr_mask
);
10403 if (item
!= NULL
) {
10404 pcc
= POWERPC_CPU_CLASS(item
->data
);
10406 g_slist_free(list
);
10411 static const char *ppc_cpu_lookup_alias(const char *alias
)
10415 for (ai
= 0; ppc_cpu_aliases
[ai
].alias
!= NULL
; ai
++) {
10416 if (strcmp(ppc_cpu_aliases
[ai
].alias
, alias
) == 0) {
10417 return ppc_cpu_aliases
[ai
].model
;
10424 static ObjectClass
*ppc_cpu_class_by_name(const char *name
)
10426 char *cpu_model
, *typename
;
10432 * Lookup by PVR if cpu_model is valid 8 digit hex number (excl:
10433 * 0x prefix if present)
10435 if (!qemu_strtoul(name
, &p
, 16, &pvr
)) {
10436 int len
= p
- name
;
10437 len
= (len
== 10) && (name
[1] == 'x') ? len
- 2 : len
;
10438 if ((len
== 8) && (*p
== '\0')) {
10439 return OBJECT_CLASS(ppc_cpu_class_by_pvr(pvr
));
10443 cpu_model
= g_ascii_strdown(name
, -1);
10444 p
= ppc_cpu_lookup_alias(cpu_model
);
10447 cpu_model
= g_strdup(p
);
10450 typename
= g_strdup_printf("%s" POWERPC_CPU_TYPE_SUFFIX
, cpu_model
);
10451 oc
= object_class_by_name(typename
);
10458 static void ppc_cpu_parse_featurestr(const char *type
, char *features
,
10461 Object
*machine
= qdev_get_machine();
10462 const PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(object_class_by_name(type
));
10468 if (object_property_find(machine
, "max-cpu-compat", NULL
)) {
10471 char *s
= features
;
10472 Error
*local_err
= NULL
;
10473 char *compat_str
= NULL
;
10476 * Backwards compatibility hack:
10478 * CPUs had a "compat=" property which didn't make sense for
10479 * anything except pseries. It was replaced by "max-cpu-compat"
10480 * machine option. This supports old command lines like
10481 * -cpu POWER8,compat=power7
10482 * By stripping the compat option and applying it to the machine
10483 * before passing it on to the cpu level parser.
10485 inpieces
= g_strsplit(features
, ",", 0);
10487 for (i
= 0; inpieces
[i
]; i
++) {
10488 if (g_str_has_prefix(inpieces
[i
], "compat=")) {
10489 compat_str
= inpieces
[i
];
10492 if ((i
!= 0) && (s
!= features
)) {
10493 s
= g_stpcpy(s
, ",");
10495 s
= g_stpcpy(s
, inpieces
[i
]);
10499 char *v
= compat_str
+ strlen("compat=");
10500 object_property_set_str(machine
, v
, "max-cpu-compat", &local_err
);
10502 g_strfreev(inpieces
);
10504 error_propagate(errp
, local_err
);
10509 /* do property processing with generic handler */
10510 pcc
->parent_parse_features(type
, features
, errp
);
10513 PowerPCCPUClass
*ppc_cpu_get_family_class(PowerPCCPUClass
*pcc
)
10515 ObjectClass
*oc
= OBJECT_CLASS(pcc
);
10517 while (oc
&& !object_class_is_abstract(oc
)) {
10518 oc
= object_class_get_parent(oc
);
10522 return POWERPC_CPU_CLASS(oc
);
10525 /* Sort by PVR, ordering special case "host" last. */
10526 static gint
ppc_cpu_list_compare(gconstpointer a
, gconstpointer b
)
10528 ObjectClass
*oc_a
= (ObjectClass
*)a
;
10529 ObjectClass
*oc_b
= (ObjectClass
*)b
;
10530 PowerPCCPUClass
*pcc_a
= POWERPC_CPU_CLASS(oc_a
);
10531 PowerPCCPUClass
*pcc_b
= POWERPC_CPU_CLASS(oc_b
);
10532 const char *name_a
= object_class_get_name(oc_a
);
10533 const char *name_b
= object_class_get_name(oc_b
);
10535 if (strcmp(name_a
, TYPE_HOST_POWERPC_CPU
) == 0) {
10537 } else if (strcmp(name_b
, TYPE_HOST_POWERPC_CPU
) == 0) {
10540 /* Avoid an integer overflow during subtraction */
10541 if (pcc_a
->pvr
< pcc_b
->pvr
) {
10543 } else if (pcc_a
->pvr
> pcc_b
->pvr
) {
10551 static void ppc_cpu_list_entry(gpointer data
, gpointer user_data
)
10553 ObjectClass
*oc
= data
;
10554 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10555 DeviceClass
*family
= DEVICE_CLASS(ppc_cpu_get_family_class(pcc
));
10556 const char *typename
= object_class_get_name(oc
);
10560 if (unlikely(strcmp(typename
, TYPE_HOST_POWERPC_CPU
) == 0)) {
10564 name
= g_strndup(typename
,
10565 strlen(typename
) - strlen(POWERPC_CPU_TYPE_SUFFIX
));
10566 qemu_printf("PowerPC %-16s PVR %08x\n", name
, pcc
->pvr
);
10567 for (i
= 0; ppc_cpu_aliases
[i
].alias
!= NULL
; i
++) {
10568 PowerPCCPUAlias
*alias
= &ppc_cpu_aliases
[i
];
10569 ObjectClass
*alias_oc
= ppc_cpu_class_by_name(alias
->model
);
10571 if (alias_oc
!= oc
) {
10575 * If running with KVM, we might update the family alias later, so
10576 * avoid printing the wrong alias here and use "preferred" instead
10578 if (strcmp(alias
->alias
, family
->desc
) == 0) {
10579 qemu_printf("PowerPC %-16s (alias for preferred %s CPU)\n",
10580 alias
->alias
, family
->desc
);
10582 qemu_printf("PowerPC %-16s (alias for %s)\n",
10583 alias
->alias
, name
);
10589 void ppc_cpu_list(void)
10593 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10594 list
= g_slist_sort(list
, ppc_cpu_list_compare
);
10595 g_slist_foreach(list
, ppc_cpu_list_entry
, NULL
);
10596 g_slist_free(list
);
10600 qemu_printf("PowerPC %-16s\n", "host");
10604 static void ppc_cpu_defs_entry(gpointer data
, gpointer user_data
)
10606 ObjectClass
*oc
= data
;
10607 CpuDefinitionInfoList
**first
= user_data
;
10608 const char *typename
;
10609 CpuDefinitionInfoList
*entry
;
10610 CpuDefinitionInfo
*info
;
10612 typename
= object_class_get_name(oc
);
10613 info
= g_malloc0(sizeof(*info
));
10614 info
->name
= g_strndup(typename
,
10615 strlen(typename
) - strlen(POWERPC_CPU_TYPE_SUFFIX
));
10617 entry
= g_malloc0(sizeof(*entry
));
10618 entry
->value
= info
;
10619 entry
->next
= *first
;
10623 CpuDefinitionInfoList
*qmp_query_cpu_definitions(Error
**errp
)
10625 CpuDefinitionInfoList
*cpu_list
= NULL
;
10629 list
= object_class_get_list(TYPE_POWERPC_CPU
, false);
10630 g_slist_foreach(list
, ppc_cpu_defs_entry
, &cpu_list
);
10631 g_slist_free(list
);
10633 for (i
= 0; ppc_cpu_aliases
[i
].alias
!= NULL
; i
++) {
10634 PowerPCCPUAlias
*alias
= &ppc_cpu_aliases
[i
];
10636 CpuDefinitionInfoList
*entry
;
10637 CpuDefinitionInfo
*info
;
10639 oc
= ppc_cpu_class_by_name(alias
->model
);
10644 info
= g_malloc0(sizeof(*info
));
10645 info
->name
= g_strdup(alias
->alias
);
10646 info
->q_typename
= g_strdup(object_class_get_name(oc
));
10648 entry
= g_malloc0(sizeof(*entry
));
10649 entry
->value
= info
;
10650 entry
->next
= cpu_list
;
10657 static void ppc_cpu_set_pc(CPUState
*cs
, vaddr value
)
10659 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10661 cpu
->env
.nip
= value
;
10664 static bool ppc_cpu_has_work(CPUState
*cs
)
10666 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10667 CPUPPCState
*env
= &cpu
->env
;
10669 return msr_ee
&& (cs
->interrupt_request
& CPU_INTERRUPT_HARD
);
10672 /* CPUClass::reset() */
10673 static void ppc_cpu_reset(CPUState
*s
)
10675 PowerPCCPU
*cpu
= POWERPC_CPU(s
);
10676 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10677 CPUPPCState
*env
= &cpu
->env
;
10681 pcc
->parent_reset(s
);
10683 msr
= (target_ulong
)0;
10684 msr
|= (target_ulong
)MSR_HVB
;
10685 msr
|= (target_ulong
)0 << MSR_AP
; /* TO BE CHECKED */
10686 msr
|= (target_ulong
)0 << MSR_SA
; /* TO BE CHECKED */
10687 msr
|= (target_ulong
)1 << MSR_EP
;
10688 #if defined(DO_SINGLE_STEP) && 0
10689 /* Single step trace mode */
10690 msr
|= (target_ulong
)1 << MSR_SE
;
10691 msr
|= (target_ulong
)1 << MSR_BE
;
10693 #if defined(CONFIG_USER_ONLY)
10694 msr
|= (target_ulong
)1 << MSR_FP
; /* Allow floating point usage */
10695 msr
|= (target_ulong
)1 << MSR_FE0
; /* Allow floating point exceptions */
10696 msr
|= (target_ulong
)1 << MSR_FE1
;
10697 msr
|= (target_ulong
)1 << MSR_VR
; /* Allow altivec usage */
10698 msr
|= (target_ulong
)1 << MSR_VSX
; /* Allow VSX usage */
10699 msr
|= (target_ulong
)1 << MSR_SPE
; /* Allow SPE usage */
10700 msr
|= (target_ulong
)1 << MSR_PR
;
10701 #if defined(TARGET_PPC64)
10702 msr
|= (target_ulong
)1 << MSR_TM
; /* Transactional memory */
10704 #if !defined(TARGET_WORDS_BIGENDIAN)
10705 msr
|= (target_ulong
)1 << MSR_LE
; /* Little-endian user mode */
10706 if (!((env
->msr_mask
>> MSR_LE
) & 1)) {
10707 fprintf(stderr
, "Selected CPU does not support little-endian.\n");
10713 #if defined(TARGET_PPC64)
10714 if (env
->mmu_model
& POWERPC_MMU_64
) {
10715 msr
|= (1ULL << MSR_SF
);
10719 hreg_store_msr(env
, msr
, 1);
10721 #if !defined(CONFIG_USER_ONLY)
10722 env
->nip
= env
->hreset_vector
| env
->excp_prefix
;
10723 if (env
->mmu_model
!= POWERPC_MMU_REAL
) {
10724 ppc_tlb_invalidate_all(env
);
10728 hreg_compute_hflags(env
);
10729 env
->reserve_addr
= (target_ulong
)-1ULL;
10730 /* Be sure no exception or interrupt is pending */
10731 env
->pending_interrupts
= 0;
10732 s
->exception_index
= POWERPC_EXCP_NONE
;
10733 env
->error_code
= 0;
10734 ppc_irq_reset(cpu
);
10736 /* tininess for underflow is detected before rounding */
10737 set_float_detect_tininess(float_tininess_before_rounding
,
10740 for (i
= 0; i
< ARRAY_SIZE(env
->spr_cb
); i
++) {
10741 ppc_spr_t
*spr
= &env
->spr_cb
[i
];
10746 env
->spr
[i
] = spr
->default_value
;
10750 #ifndef CONFIG_USER_ONLY
10751 static bool ppc_cpu_is_big_endian(CPUState
*cs
)
10753 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10754 CPUPPCState
*env
= &cpu
->env
;
10756 cpu_synchronize_state(cs
);
10761 static void ppc_cpu_exec_enter(CPUState
*cs
)
10763 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10766 PPCVirtualHypervisorClass
*vhc
=
10767 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu
->vhyp
);
10768 vhc
->cpu_exec_enter(cpu
->vhyp
, cpu
);
10772 static void ppc_cpu_exec_exit(CPUState
*cs
)
10774 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10777 PPCVirtualHypervisorClass
*vhc
=
10778 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu
->vhyp
);
10779 vhc
->cpu_exec_exit(cpu
->vhyp
, cpu
);
10784 static void ppc_cpu_instance_init(Object
*obj
)
10786 PowerPCCPU
*cpu
= POWERPC_CPU(obj
);
10787 PowerPCCPUClass
*pcc
= POWERPC_CPU_GET_CLASS(cpu
);
10788 CPUPPCState
*env
= &cpu
->env
;
10790 cpu_set_cpustate_pointers(cpu
);
10791 cpu
->vcpu_id
= UNASSIGNED_CPU_INDEX
;
10793 env
->msr_mask
= pcc
->msr_mask
;
10794 env
->mmu_model
= pcc
->mmu_model
;
10795 env
->excp_model
= pcc
->excp_model
;
10796 env
->bus_model
= pcc
->bus_model
;
10797 env
->insns_flags
= pcc
->insns_flags
;
10798 env
->insns_flags2
= pcc
->insns_flags2
;
10799 env
->flags
= pcc
->flags
;
10800 env
->bfd_mach
= pcc
->bfd_mach
;
10801 env
->check_pow
= pcc
->check_pow
;
10804 * Mark HV mode as supported if the CPU has an MSR_HV bit in the
10805 * msr_mask. The mask can later be cleared by PAPR mode but the hv
10806 * mode support will remain, thus enforcing that we cannot use
10807 * priv. instructions in guest in PAPR mode. For 970 we currently
10808 * simply don't set HV in msr_mask thus simulating an "Apple mode"
10809 * 970. If we ever want to support 970 HV mode, we'll have to add
10810 * a processor attribute of some sort.
10812 #if !defined(CONFIG_USER_ONLY)
10813 env
->has_hv_mode
= !!(env
->msr_mask
& MSR_HVB
);
10816 ppc_hash64_init(cpu
);
10819 static void ppc_cpu_instance_finalize(Object
*obj
)
10821 PowerPCCPU
*cpu
= POWERPC_CPU(obj
);
10823 ppc_hash64_finalize(cpu
);
10826 static bool ppc_pvr_match_default(PowerPCCPUClass
*pcc
, uint32_t pvr
)
10828 return pcc
->pvr
== pvr
;
10831 static gchar
*ppc_gdb_arch_name(CPUState
*cs
)
10833 #if defined(TARGET_PPC64)
10834 return g_strdup("powerpc:common64");
10836 return g_strdup("powerpc:common");
10840 static void ppc_disas_set_info(CPUState
*cs
, disassemble_info
*info
)
10842 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
10843 CPUPPCState
*env
= &cpu
->env
;
10845 if ((env
->hflags
>> MSR_LE
) & 1) {
10846 info
->endian
= BFD_ENDIAN_LITTLE
;
10848 info
->mach
= env
->bfd_mach
;
10849 if (!env
->bfd_mach
) {
10850 #ifdef TARGET_PPC64
10851 info
->mach
= bfd_mach_ppc64
;
10853 info
->mach
= bfd_mach_ppc
;
10856 info
->disassembler_options
= (char *)"any";
10857 info
->print_insn
= print_insn_ppc
;
10859 info
->cap_arch
= CS_ARCH_PPC
;
10860 #ifdef TARGET_PPC64
10861 info
->cap_mode
= CS_MODE_64
;
10865 static Property ppc_cpu_properties
[] = {
10866 DEFINE_PROP_BOOL("pre-2.8-migration", PowerPCCPU
, pre_2_8_migration
, false),
10867 DEFINE_PROP_BOOL("pre-2.10-migration", PowerPCCPU
, pre_2_10_migration
,
10869 DEFINE_PROP_BOOL("pre-3.0-migration", PowerPCCPU
, pre_3_0_migration
,
10871 DEFINE_PROP_END_OF_LIST(),
10874 static void ppc_cpu_class_init(ObjectClass
*oc
, void *data
)
10876 PowerPCCPUClass
*pcc
= POWERPC_CPU_CLASS(oc
);
10877 CPUClass
*cc
= CPU_CLASS(oc
);
10878 DeviceClass
*dc
= DEVICE_CLASS(oc
);
10880 device_class_set_parent_realize(dc
, ppc_cpu_realize
,
10881 &pcc
->parent_realize
);
10882 device_class_set_parent_unrealize(dc
, ppc_cpu_unrealize
,
10883 &pcc
->parent_unrealize
);
10884 pcc
->pvr_match
= ppc_pvr_match_default
;
10885 pcc
->interrupts_big_endian
= ppc_cpu_interrupts_big_endian_always
;
10886 device_class_set_props(dc
, ppc_cpu_properties
);
10888 cpu_class_set_parent_reset(cc
, ppc_cpu_reset
, &pcc
->parent_reset
);
10890 cc
->class_by_name
= ppc_cpu_class_by_name
;
10891 pcc
->parent_parse_features
= cc
->parse_features
;
10892 cc
->parse_features
= ppc_cpu_parse_featurestr
;
10893 cc
->has_work
= ppc_cpu_has_work
;
10894 cc
->do_interrupt
= ppc_cpu_do_interrupt
;
10895 cc
->cpu_exec_interrupt
= ppc_cpu_exec_interrupt
;
10896 cc
->dump_state
= ppc_cpu_dump_state
;
10897 cc
->dump_statistics
= ppc_cpu_dump_statistics
;
10898 cc
->set_pc
= ppc_cpu_set_pc
;
10899 cc
->gdb_read_register
= ppc_cpu_gdb_read_register
;
10900 cc
->gdb_write_register
= ppc_cpu_gdb_write_register
;
10901 cc
->do_unaligned_access
= ppc_cpu_do_unaligned_access
;
10902 #ifndef CONFIG_USER_ONLY
10903 cc
->get_phys_page_debug
= ppc_cpu_get_phys_page_debug
;
10904 cc
->vmsd
= &vmstate_ppc_cpu
;
10906 #if defined(CONFIG_SOFTMMU)
10907 cc
->write_elf64_note
= ppc64_cpu_write_elf64_note
;
10908 cc
->write_elf32_note
= ppc32_cpu_write_elf32_note
;
10911 cc
->gdb_num_core_regs
= 71;
10912 #ifndef CONFIG_USER_ONLY
10913 cc
->gdb_get_dynamic_xml
= ppc_gdb_get_dynamic_xml
;
10915 #ifdef USE_APPLE_GDB
10916 cc
->gdb_read_register
= ppc_cpu_gdb_read_register_apple
;
10917 cc
->gdb_write_register
= ppc_cpu_gdb_write_register_apple
;
10918 cc
->gdb_num_core_regs
= 71 + 32;
10921 cc
->gdb_arch_name
= ppc_gdb_arch_name
;
10922 #if defined(TARGET_PPC64)
10923 cc
->gdb_core_xml_file
= "power64-core.xml";
10925 cc
->gdb_core_xml_file
= "power-core.xml";
10927 #ifndef CONFIG_USER_ONLY
10928 cc
->virtio_is_big_endian
= ppc_cpu_is_big_endian
;
10931 cc
->tcg_initialize
= ppc_translate_init
;
10932 cc
->tlb_fill
= ppc_cpu_tlb_fill
;
10934 #ifndef CONFIG_USER_ONLY
10935 cc
->cpu_exec_enter
= ppc_cpu_exec_enter
;
10936 cc
->cpu_exec_exit
= ppc_cpu_exec_exit
;
10939 cc
->disas_set_info
= ppc_disas_set_info
;
10941 dc
->fw_name
= "PowerPC,UNKNOWN";
10944 static const TypeInfo ppc_cpu_type_info
= {
10945 .name
= TYPE_POWERPC_CPU
,
10946 .parent
= TYPE_CPU
,
10947 .instance_size
= sizeof(PowerPCCPU
),
10948 .instance_init
= ppc_cpu_instance_init
,
10949 .instance_finalize
= ppc_cpu_instance_finalize
,
10951 .class_size
= sizeof(PowerPCCPUClass
),
10952 .class_init
= ppc_cpu_class_init
,
10955 static const TypeInfo ppc_vhyp_type_info
= {
10956 .name
= TYPE_PPC_VIRTUAL_HYPERVISOR
,
10957 .parent
= TYPE_INTERFACE
,
10958 .class_size
= sizeof(PPCVirtualHypervisorClass
),
10961 static void ppc_cpu_register_types(void)
10963 type_register_static(&ppc_cpu_type_info
);
10964 type_register_static(&ppc_vhyp_type_info
);
10967 type_init(ppc_cpu_register_types
)