]> git.ipfire.org Git - thirdparty/qemu.git/blame - target/ppc/translate_init.inc.c
Merge remote-tracking branch 'remotes/elmarco/tags/slirp-pull-request' into staging
[thirdparty/qemu.git] / target / ppc / translate_init.inc.c
CommitLineData
3fc6c082
FB
1/*
2 * PowerPC CPU initialization for qemu.
5fafdf24 3 *
76a66253 4 * Copyright (c) 2003-2007 Jocelyn Mayer
f7aa5583 5 * Copyright 2011 Freescale Semiconductor, Inc.
3fc6c082
FB
6 *
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.
11 *
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.
16 *
17 * You should have received a copy of the GNU Lesser General Public
8167ee88 18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
3fc6c082
FB
19 */
20
3979fca4 21#include "disas/dis-asm.h"
022c62cb 22#include "exec/gdbstub.h"
a1e98583 23#include "kvm_ppc.h"
9c17d615 24#include "sysemu/arch_init.h"
fe828a4d 25#include "sysemu/cpus.h"
b3946626 26#include "sysemu/hw_accel.h"
14a48c1d 27#include "sysemu/tcg.h"
953af181 28#include "cpu-models.h"
b632a148
DG
29#include "mmu-hash32.h"
30#include "mmu-hash64.h"
4a44d85e 31#include "qemu/error-report.h"
0b8fa32f 32#include "qemu/module.h"
0442428a 33#include "qemu/qemu-print.h"
e688df6b 34#include "qapi/error.h"
198a1032 35#include "qapi/qmp/qnull.h"
8dfa3a5e
AK
36#include "qapi/visitor.h"
37#include "hw/qdev-properties.h"
aa5a9e24 38#include "hw/ppc/ppc.h"
b2899495 39#include "mmu-book3s-v3.h"
7843c0d6 40#include "sysemu/qtest.h"
b376db77 41#include "qemu/cutils.h"
ac226899 42#include "disas/capstone.h"
24f91e81 43#include "fpu/softfloat.h"
7f7b4e7a 44#include "qapi/qapi-commands-machine-target.h"
237c0af0 45
1d28b5f6
DG
46/* #define PPC_DUMP_CPU */
47/* #define PPC_DEBUG_SPR */
48/* #define PPC_DUMP_SPR_ACCESSES */
b3cad3ab 49/* #define USE_APPLE_GDB */
3fc6c082 50
1d28b5f6
DG
51/*
52 * Generic callbacks:
3fc6c082
FB
53 * do nothing but store/retrieve spr value
54 */
91f477fd
AG
55static void spr_load_dump_spr(int sprn)
56{
57#ifdef PPC_DUMP_SPR_ACCESSES
58 TCGv_i32 t0 = tcg_const_i32(sprn);
edbe35e0 59 gen_helper_load_dump_spr(cpu_env, t0);
91f477fd
AG
60 tcg_temp_free_i32(t0);
61#endif
62}
63
1d28b5f6 64static void spr_read_generic(DisasContext *ctx, int gprn, int sprn)
a496775f 65{
45d827d2 66 gen_load_spr(cpu_gpr[gprn], sprn);
91f477fd
AG
67 spr_load_dump_spr(sprn);
68}
69
70static void spr_store_dump_spr(int sprn)
71{
45d827d2 72#ifdef PPC_DUMP_SPR_ACCESSES
91f477fd 73 TCGv_i32 t0 = tcg_const_i32(sprn);
edbe35e0 74 gen_helper_store_dump_spr(cpu_env, t0);
91f477fd 75 tcg_temp_free_i32(t0);
45d827d2 76#endif
a496775f
JM
77}
78
c364946d 79static void spr_write_generic(DisasContext *ctx, int sprn, int gprn)
a496775f 80{
45d827d2 81 gen_store_spr(sprn, cpu_gpr[gprn]);
91f477fd 82 spr_store_dump_spr(sprn);
45d827d2 83}
a496775f
JM
84
85#if !defined(CONFIG_USER_ONLY)
69b058c8 86static void spr_write_generic32(DisasContext *ctx, int sprn, int gprn)
ba38ab8d
AG
87{
88#ifdef TARGET_PPC64
89 TCGv t0 = tcg_temp_new();
90 tcg_gen_ext32u_tl(t0, cpu_gpr[gprn]);
91 gen_store_spr(sprn, t0);
92 tcg_temp_free(t0);
93 spr_store_dump_spr(sprn);
94#else
69b058c8 95 spr_write_generic(ctx, sprn, gprn);
ba38ab8d
AG
96#endif
97}
98
c364946d 99static void spr_write_clear(DisasContext *ctx, int sprn, int gprn)
a496775f 100{
45d827d2
AJ
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);
107 tcg_temp_free(t0);
108 tcg_temp_free(t1);
a496775f 109}
9633fcc6 110
69b058c8 111static void spr_access_nop(DisasContext *ctx, int sprn, int gprn)
9633fcc6
AG
112{
113}
114
a496775f
JM
115#endif
116
76a66253 117/* SPR common to all PowerPC */
3fc6c082 118/* XER */
c364946d 119static void spr_read_xer(DisasContext *ctx, int gprn, int sprn)
3fc6c082 120{
dd09c361 121 gen_read_xer(ctx, cpu_gpr[gprn]);
3fc6c082
FB
122}
123
c364946d 124static void spr_write_xer(DisasContext *ctx, int sprn, int gprn)
3fc6c082 125{
da91a00f 126 gen_write_xer(cpu_gpr[gprn]);
3fc6c082
FB
127}
128
129/* LR */
c364946d 130static void spr_read_lr(DisasContext *ctx, int gprn, int sprn)
3fc6c082 131{
45d827d2 132 tcg_gen_mov_tl(cpu_gpr[gprn], cpu_lr);
3fc6c082
FB
133}
134
c364946d 135static void spr_write_lr(DisasContext *ctx, int sprn, int gprn)
3fc6c082 136{
45d827d2 137 tcg_gen_mov_tl(cpu_lr, cpu_gpr[gprn]);
3fc6c082
FB
138}
139
697ab892
DG
140/* CFAR */
141#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
c364946d 142static void spr_read_cfar(DisasContext *ctx, int gprn, int sprn)
697ab892
DG
143{
144 tcg_gen_mov_tl(cpu_gpr[gprn], cpu_cfar);
145}
146
c364946d 147static void spr_write_cfar(DisasContext *ctx, int sprn, int gprn)
697ab892
DG
148{
149 tcg_gen_mov_tl(cpu_cfar, cpu_gpr[gprn]);
150}
151#endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
152
3fc6c082 153/* CTR */
c364946d 154static void spr_read_ctr(DisasContext *ctx, int gprn, int sprn)
3fc6c082 155{
45d827d2 156 tcg_gen_mov_tl(cpu_gpr[gprn], cpu_ctr);
3fc6c082
FB
157}
158
c364946d 159static void spr_write_ctr(DisasContext *ctx, int sprn, int gprn)
3fc6c082 160{
45d827d2 161 tcg_gen_mov_tl(cpu_ctr, cpu_gpr[gprn]);
3fc6c082
FB
162}
163
164/* User read access to SPR */
165/* USPRx */
166/* UMMCRx */
167/* UPMCx */
168/* USIA */
169/* UDECR */
c364946d 170static void spr_read_ureg(DisasContext *ctx, int gprn, int sprn)
3fc6c082 171{
45d827d2 172 gen_load_spr(cpu_gpr[gprn], sprn + 0x10);
3fc6c082
FB
173}
174
fd51ff63 175#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
69b058c8 176static void spr_write_ureg(DisasContext *ctx, int sprn, int gprn)
fd51ff63
AK
177{
178 gen_store_spr(sprn + 0x10, cpu_gpr[gprn]);
179}
180#endif
181
76a66253 182/* SPR common to all non-embedded PowerPC */
3fc6c082 183/* DECR */
76a66253 184#if !defined(CONFIG_USER_ONLY)
c364946d 185static void spr_read_decr(DisasContext *ctx, int gprn, int sprn)
3fc6c082 186{
b6bac4bc 187 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
630ecca0
TG
188 gen_io_start();
189 }
d0f1562d 190 gen_helper_load_decr(cpu_gpr[gprn], cpu_env);
b6bac4bc 191 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
69b058c8 192 gen_stop_exception(ctx);
630ecca0 193 }
3fc6c082
FB
194}
195
c364946d 196static void spr_write_decr(DisasContext *ctx, int sprn, int gprn)
3fc6c082 197{
b6bac4bc 198 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
630ecca0
TG
199 gen_io_start();
200 }
d0f1562d 201 gen_helper_store_decr(cpu_env, cpu_gpr[gprn]);
b6bac4bc 202 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
69b058c8 203 gen_stop_exception(ctx);
630ecca0 204 }
3fc6c082 205}
76a66253 206#endif
3fc6c082 207
76a66253 208/* SPR common to all non-embedded PowerPC, except 601 */
3fc6c082 209/* Time base */
c364946d 210static void spr_read_tbl(DisasContext *ctx, int gprn, int sprn)
3fc6c082 211{
b6bac4bc 212 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
630ecca0
TG
213 gen_io_start();
214 }
d0f1562d 215 gen_helper_load_tbl(cpu_gpr[gprn], cpu_env);
b6bac4bc 216 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
630ecca0 217 gen_io_end();
69b058c8 218 gen_stop_exception(ctx);
630ecca0 219 }
3fc6c082
FB
220}
221
c364946d 222static void spr_read_tbu(DisasContext *ctx, int gprn, int sprn)
3fc6c082 223{
b6bac4bc 224 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
630ecca0
TG
225 gen_io_start();
226 }
d0f1562d 227 gen_helper_load_tbu(cpu_gpr[gprn], cpu_env);
b6bac4bc 228 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
630ecca0 229 gen_io_end();
69b058c8 230 gen_stop_exception(ctx);
630ecca0 231 }
3fc6c082
FB
232}
233
1d28b5f6 234ATTRIBUTE_UNUSED
c364946d 235static void spr_read_atbl(DisasContext *ctx, int gprn, int sprn)
a062e36c 236{
d0f1562d 237 gen_helper_load_atbl(cpu_gpr[gprn], cpu_env);
a062e36c
JM
238}
239
1d28b5f6 240ATTRIBUTE_UNUSED
c364946d 241static void spr_read_atbu(DisasContext *ctx, int gprn, int sprn)
a062e36c 242{
d0f1562d 243 gen_helper_load_atbu(cpu_gpr[gprn], cpu_env);
a062e36c
JM
244}
245
76a66253 246#if !defined(CONFIG_USER_ONLY)
c364946d 247static void spr_write_tbl(DisasContext *ctx, int sprn, int gprn)
3fc6c082 248{
b6bac4bc 249 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
630ecca0
TG
250 gen_io_start();
251 }
d0f1562d 252 gen_helper_store_tbl(cpu_env, cpu_gpr[gprn]);
b6bac4bc 253 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
630ecca0 254 gen_io_end();
69b058c8 255 gen_stop_exception(ctx);
630ecca0 256 }
3fc6c082
FB
257}
258
c364946d 259static void spr_write_tbu(DisasContext *ctx, int sprn, int gprn)
3fc6c082 260{
b6bac4bc 261 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
630ecca0
TG
262 gen_io_start();
263 }
d0f1562d 264 gen_helper_store_tbu(cpu_env, cpu_gpr[gprn]);
b6bac4bc 265 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
630ecca0 266 gen_io_end();
69b058c8 267 gen_stop_exception(ctx);
630ecca0 268 }
3fc6c082 269}
a062e36c 270
1d28b5f6 271ATTRIBUTE_UNUSED
c364946d 272static void spr_write_atbl(DisasContext *ctx, int sprn, int gprn)
a062e36c 273{
d0f1562d 274 gen_helper_store_atbl(cpu_env, cpu_gpr[gprn]);
a062e36c
JM
275}
276
1d28b5f6 277ATTRIBUTE_UNUSED
c364946d 278static void spr_write_atbu(DisasContext *ctx, int sprn, int gprn)
a062e36c 279{
d0f1562d 280 gen_helper_store_atbu(cpu_env, cpu_gpr[gprn]);
a062e36c 281}
3a7f009a
DG
282
283#if defined(TARGET_PPC64)
1d28b5f6 284ATTRIBUTE_UNUSED
c364946d 285static void spr_read_purr(DisasContext *ctx, int gprn, int sprn)
3a7f009a 286{
d0f1562d 287 gen_helper_load_purr(cpu_gpr[gprn], cpu_env);
3a7f009a 288}
4b236b62 289
5cc7e69f
SJS
290static void spr_write_purr(DisasContext *ctx, int sprn, int gprn)
291{
292 gen_helper_store_purr(cpu_env, cpu_gpr[gprn]);
293}
294
4b236b62
BH
295/* HDECR */
296static void spr_read_hdecr(DisasContext *ctx, int gprn, int sprn)
297{
b6bac4bc 298 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
4b236b62
BH
299 gen_io_start();
300 }
301 gen_helper_load_hdecr(cpu_gpr[gprn], cpu_env);
b6bac4bc 302 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
4b236b62
BH
303 gen_io_end();
304 gen_stop_exception(ctx);
305 }
306}
307
308static void spr_write_hdecr(DisasContext *ctx, int sprn, int gprn)
309{
b6bac4bc 310 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
4b236b62
BH
311 gen_io_start();
312 }
313 gen_helper_store_hdecr(cpu_env, cpu_gpr[gprn]);
b6bac4bc 314 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
4b236b62
BH
315 gen_io_end();
316 gen_stop_exception(ctx);
317 }
318}
319
5d62725b
SJS
320static void spr_read_vtb(DisasContext *ctx, int gprn, int sprn)
321{
322 gen_helper_load_vtb(cpu_gpr[gprn], cpu_env);
323}
324
325static void spr_write_vtb(DisasContext *ctx, int sprn, int gprn)
326{
327 gen_helper_store_vtb(cpu_env, cpu_gpr[gprn]);
328}
329
f0ec31b1
SJS
330static void spr_write_tbu40(DisasContext *ctx, int sprn, int gprn)
331{
332 gen_helper_store_tbu40(cpu_env, cpu_gpr[gprn]);
333}
334
3a7f009a 335#endif
76a66253 336#endif
3fc6c082 337
76a66253 338#if !defined(CONFIG_USER_ONLY)
3fc6c082
FB
339/* IBAT0U...IBAT0U */
340/* IBAT0L...IBAT7L */
c364946d 341static void spr_read_ibat(DisasContext *ctx, int gprn, int sprn)
3fc6c082 342{
1d28b5f6
DG
343 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env,
344 offsetof(CPUPPCState,
345 IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2]));
3fc6c082
FB
346}
347
c364946d 348static void spr_read_ibat_h(DisasContext *ctx, int gprn, int sprn)
3fc6c082 349{
1d28b5f6
DG
350 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env,
351 offsetof(CPUPPCState,
352 IBAT[sprn & 1][((sprn - SPR_IBAT4U) / 2) + 4]));
3fc6c082
FB
353}
354
c364946d 355static void spr_write_ibatu(DisasContext *ctx, int sprn, int gprn)
3fc6c082 356{
45d827d2 357 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2);
c6c7cf05 358 gen_helper_store_ibatu(cpu_env, t0, cpu_gpr[gprn]);
45d827d2 359 tcg_temp_free_i32(t0);
3fc6c082
FB
360}
361
c364946d 362static void spr_write_ibatu_h(DisasContext *ctx, int sprn, int gprn)
3fc6c082 363{
8daf1781 364 TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_IBAT4U) / 2) + 4);
c6c7cf05 365 gen_helper_store_ibatu(cpu_env, t0, cpu_gpr[gprn]);
45d827d2 366 tcg_temp_free_i32(t0);
3fc6c082
FB
367}
368
c364946d 369static void spr_write_ibatl(DisasContext *ctx, int sprn, int gprn)
3fc6c082 370{
45d827d2 371 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0L) / 2);
c6c7cf05 372 gen_helper_store_ibatl(cpu_env, t0, cpu_gpr[gprn]);
45d827d2 373 tcg_temp_free_i32(t0);
3fc6c082
FB
374}
375
c364946d 376static void spr_write_ibatl_h(DisasContext *ctx, int sprn, int gprn)
3fc6c082 377{
8daf1781 378 TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_IBAT4L) / 2) + 4);
c6c7cf05 379 gen_helper_store_ibatl(cpu_env, t0, cpu_gpr[gprn]);
45d827d2 380 tcg_temp_free_i32(t0);
3fc6c082
FB
381}
382
383/* DBAT0U...DBAT7U */
384/* DBAT0L...DBAT7L */
c364946d 385static void spr_read_dbat(DisasContext *ctx, int gprn, int sprn)
3fc6c082 386{
1d28b5f6
DG
387 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env,
388 offsetof(CPUPPCState,
389 DBAT[sprn & 1][(sprn - SPR_DBAT0U) / 2]));
3fc6c082
FB
390}
391
c364946d 392static void spr_read_dbat_h(DisasContext *ctx, int gprn, int sprn)
3fc6c082 393{
1d28b5f6
DG
394 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env,
395 offsetof(CPUPPCState,
396 DBAT[sprn & 1][((sprn - SPR_DBAT4U) / 2) + 4]));
3fc6c082
FB
397}
398
c364946d 399static void spr_write_dbatu(DisasContext *ctx, int sprn, int gprn)
3fc6c082 400{
45d827d2 401 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_DBAT0U) / 2);
c6c7cf05 402 gen_helper_store_dbatu(cpu_env, t0, cpu_gpr[gprn]);
45d827d2 403 tcg_temp_free_i32(t0);
3fc6c082
FB
404}
405
c364946d 406static void spr_write_dbatu_h(DisasContext *ctx, int sprn, int gprn)
3fc6c082 407{
45d827d2 408 TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_DBAT4U) / 2) + 4);
c6c7cf05 409 gen_helper_store_dbatu(cpu_env, t0, cpu_gpr[gprn]);
45d827d2 410 tcg_temp_free_i32(t0);
3fc6c082
FB
411}
412
c364946d 413static void spr_write_dbatl(DisasContext *ctx, int sprn, int gprn)
3fc6c082 414{
45d827d2 415 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_DBAT0L) / 2);
c6c7cf05 416 gen_helper_store_dbatl(cpu_env, t0, cpu_gpr[gprn]);
45d827d2 417 tcg_temp_free_i32(t0);
3fc6c082
FB
418}
419
c364946d 420static void spr_write_dbatl_h(DisasContext *ctx, int sprn, int gprn)
3fc6c082 421{
45d827d2 422 TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_DBAT4L) / 2) + 4);
c6c7cf05 423 gen_helper_store_dbatl(cpu_env, t0, cpu_gpr[gprn]);
45d827d2 424 tcg_temp_free_i32(t0);
3fc6c082
FB
425}
426
427/* SDR1 */
c364946d 428static void spr_write_sdr1(DisasContext *ctx, int sprn, int gprn)
3fc6c082 429{
d523dd00 430 gen_helper_store_sdr1(cpu_env, cpu_gpr[gprn]);
3fc6c082
FB
431}
432
578bb252 433#if defined(TARGET_PPC64)
31b2b0f8
SJS
434/* 64 bits PowerPC specific SPRs */
435/* PIDR */
436static void spr_write_pidr(DisasContext *ctx, int sprn, int gprn)
437{
438 gen_helper_store_pidr(cpu_env, cpu_gpr[gprn]);
439}
440
c4dae9cd
BH
441static void spr_write_lpidr(DisasContext *ctx, int sprn, int gprn)
442{
443 gen_helper_store_lpidr(cpu_env, cpu_gpr[gprn]);
444}
445
c364946d 446static void spr_read_hior(DisasContext *ctx, int gprn, int sprn)
2adab7d6 447{
1328c2bf 448 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, excp_prefix));
2adab7d6
BS
449}
450
c364946d 451static void spr_write_hior(DisasContext *ctx, int sprn, int gprn)
2adab7d6
BS
452{
453 TCGv t0 = tcg_temp_new();
454 tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0x3FFFFF00000ULL);
1328c2bf 455 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, excp_prefix));
2adab7d6
BS
456 tcg_temp_free(t0);
457}
4a7518e0
CLG
458static void spr_write_ptcr(DisasContext *ctx, int sprn, int gprn)
459{
460 gen_helper_store_ptcr(cpu_env, cpu_gpr[gprn]);
461}
462
6b375544
JS
463static void spr_write_pcr(DisasContext *ctx, int sprn, int gprn)
464{
465 gen_helper_store_pcr(cpu_env, cpu_gpr[gprn]);
466}
5ba7ba1d
CLG
467
468/* DPDES */
469static void spr_read_dpdes(DisasContext *ctx, int gprn, int sprn)
470{
471 gen_helper_load_dpdes(cpu_gpr[gprn], cpu_env);
472}
473
474static void spr_write_dpdes(DisasContext *ctx, int sprn, int gprn)
475{
476 gen_helper_store_dpdes(cpu_env, cpu_gpr[gprn]);
477}
76a66253 478#endif
a750fc0b 479#endif
76a66253
JM
480
481/* PowerPC 601 specific registers */
482/* RTC */
c364946d 483static void spr_read_601_rtcl(DisasContext *ctx, int gprn, int sprn)
76a66253 484{
d0f1562d 485 gen_helper_load_601_rtcl(cpu_gpr[gprn], cpu_env);
76a66253
JM
486}
487
c364946d 488static void spr_read_601_rtcu(DisasContext *ctx, int gprn, int sprn)
76a66253 489{
d0f1562d 490 gen_helper_load_601_rtcu(cpu_gpr[gprn], cpu_env);
76a66253
JM
491}
492
493#if !defined(CONFIG_USER_ONLY)
c364946d 494static void spr_write_601_rtcu(DisasContext *ctx, int sprn, int gprn)
76a66253 495{
d0f1562d 496 gen_helper_store_601_rtcu(cpu_env, cpu_gpr[gprn]);
76a66253
JM
497}
498
c364946d 499static void spr_write_601_rtcl(DisasContext *ctx, int sprn, int gprn)
76a66253 500{
d0f1562d 501 gen_helper_store_601_rtcl(cpu_env, cpu_gpr[gprn]);
76a66253 502}
056401ea 503
c364946d 504static void spr_write_hid0_601(DisasContext *ctx, int sprn, int gprn)
056401ea 505{
d523dd00 506 gen_helper_store_hid0_601(cpu_env, cpu_gpr[gprn]);
056401ea 507 /* Must stop the translation as endianness may have changed */
e06fcd75 508 gen_stop_exception(ctx);
056401ea 509}
76a66253
JM
510#endif
511
512/* Unified bats */
513#if !defined(CONFIG_USER_ONLY)
c364946d 514static void spr_read_601_ubat(DisasContext *ctx, int gprn, int sprn)
76a66253 515{
1d28b5f6
DG
516 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env,
517 offsetof(CPUPPCState,
518 IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2]));
76a66253
JM
519}
520
c364946d 521static void spr_write_601_ubatu(DisasContext *ctx, int sprn, int gprn)
76a66253 522{
45d827d2 523 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2);
c6c7cf05 524 gen_helper_store_601_batl(cpu_env, t0, cpu_gpr[gprn]);
45d827d2 525 tcg_temp_free_i32(t0);
76a66253
JM
526}
527
c364946d 528static void spr_write_601_ubatl(DisasContext *ctx, int sprn, int gprn)
76a66253 529{
45d827d2 530 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2);
c6c7cf05 531 gen_helper_store_601_batu(cpu_env, t0, cpu_gpr[gprn]);
45d827d2 532 tcg_temp_free_i32(t0);
76a66253
JM
533}
534#endif
535
536/* PowerPC 40x specific registers */
537#if !defined(CONFIG_USER_ONLY)
c364946d 538static void spr_read_40x_pit(DisasContext *ctx, int gprn, int sprn)
76a66253 539{
d0f1562d 540 gen_helper_load_40x_pit(cpu_gpr[gprn], cpu_env);
76a66253
JM
541}
542
c364946d 543static void spr_write_40x_pit(DisasContext *ctx, int sprn, int gprn)
76a66253 544{
d0f1562d 545 gen_helper_store_40x_pit(cpu_env, cpu_gpr[gprn]);
76a66253
JM
546}
547
c364946d 548static void spr_write_40x_dbcr0(DisasContext *ctx, int sprn, int gprn)
8ecc7913 549{
0e3bf489 550 gen_store_spr(sprn, cpu_gpr[gprn]);
d523dd00 551 gen_helper_store_40x_dbcr0(cpu_env, cpu_gpr[gprn]);
8ecc7913 552 /* We must stop translation as we may have rebooted */
e06fcd75 553 gen_stop_exception(ctx);
8ecc7913
JM
554}
555
c364946d 556static void spr_write_40x_sler(DisasContext *ctx, int sprn, int gprn)
c294fc58 557{
d523dd00 558 gen_helper_store_40x_sler(cpu_env, cpu_gpr[gprn]);
c294fc58
JM
559}
560
c364946d 561static void spr_write_booke_tcr(DisasContext *ctx, int sprn, int gprn)
76a66253 562{
d0f1562d 563 gen_helper_store_booke_tcr(cpu_env, cpu_gpr[gprn]);
76a66253
JM
564}
565
c364946d 566static void spr_write_booke_tsr(DisasContext *ctx, int sprn, int gprn)
76a66253 567{
d0f1562d 568 gen_helper_store_booke_tsr(cpu_env, cpu_gpr[gprn]);
76a66253
JM
569}
570#endif
571
572/* PowerPC 403 specific registers */
573/* PBL1 / PBU1 / PBL2 / PBU2 */
574#if !defined(CONFIG_USER_ONLY)
c364946d 575static void spr_read_403_pbr(DisasContext *ctx, int gprn, int sprn)
76a66253 576{
1d28b5f6
DG
577 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env,
578 offsetof(CPUPPCState, pb[sprn - SPR_403_PBL1]));
76a66253
JM
579}
580
c364946d 581static void spr_write_403_pbr(DisasContext *ctx, int sprn, int gprn)
76a66253 582{
45d827d2 583 TCGv_i32 t0 = tcg_const_i32(sprn - SPR_403_PBL1);
d523dd00 584 gen_helper_store_403_pbr(cpu_env, t0, cpu_gpr[gprn]);
45d827d2 585 tcg_temp_free_i32(t0);
76a66253
JM
586}
587
c364946d 588static void spr_write_pir(DisasContext *ctx, int sprn, int gprn)
3fc6c082 589{
45d827d2
AJ
590 TCGv t0 = tcg_temp_new();
591 tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0xF);
592 gen_store_spr(SPR_PIR, t0);
593 tcg_temp_free(t0);
3fc6c082 594}
76a66253 595#endif
3fc6c082 596
d34defbc 597/* SPE specific registers */
c364946d 598static void spr_read_spefscr(DisasContext *ctx, int gprn, int sprn)
d34defbc
AJ
599{
600 TCGv_i32 t0 = tcg_temp_new_i32();
1328c2bf 601 tcg_gen_ld_i32(t0, cpu_env, offsetof(CPUPPCState, spe_fscr));
d34defbc
AJ
602 tcg_gen_extu_i32_tl(cpu_gpr[gprn], t0);
603 tcg_temp_free_i32(t0);
604}
605
c364946d 606static void spr_write_spefscr(DisasContext *ctx, int sprn, int gprn)
d34defbc
AJ
607{
608 TCGv_i32 t0 = tcg_temp_new_i32();
609 tcg_gen_trunc_tl_i32(t0, cpu_gpr[gprn]);
1328c2bf 610 tcg_gen_st_i32(t0, cpu_env, offsetof(CPUPPCState, spe_fscr));
d34defbc
AJ
611 tcg_temp_free_i32(t0);
612}
613
6f5d427d
JM
614#if !defined(CONFIG_USER_ONLY)
615/* Callback used to write the exception vector base */
c364946d 616static void spr_write_excp_prefix(DisasContext *ctx, int sprn, int gprn)
6f5d427d 617{
45d827d2 618 TCGv t0 = tcg_temp_new();
1328c2bf 619 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUPPCState, ivpr_mask));
45d827d2 620 tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]);
1328c2bf 621 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, excp_prefix));
45d827d2 622 gen_store_spr(sprn, t0);
69bd5820 623 tcg_temp_free(t0);
6f5d427d
JM
624}
625
c364946d 626static void spr_write_excp_vector(DisasContext *ctx, int sprn, int gprn)
6f5d427d 627{
e9205258 628 int sprn_offs;
6f5d427d
JM
629
630 if (sprn >= SPR_BOOKE_IVOR0 && sprn <= SPR_BOOKE_IVOR15) {
e9205258 631 sprn_offs = sprn - SPR_BOOKE_IVOR0;
6f5d427d 632 } else if (sprn >= SPR_BOOKE_IVOR32 && sprn <= SPR_BOOKE_IVOR37) {
e9205258
AG
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;
6f5d427d
JM
636 } else {
637 printf("Trying to write an unknown exception vector %d %03x\n",
638 sprn, sprn);
e06fcd75 639 gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
e9205258 640 return;
6f5d427d 641 }
e9205258
AG
642
643 TCGv t0 = tcg_temp_new();
1328c2bf 644 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUPPCState, ivor_mask));
e9205258 645 tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]);
1328c2bf 646 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, excp_vectors[sprn_offs]));
e9205258
AG
647 gen_store_spr(sprn, t0);
648 tcg_temp_free(t0);
6f5d427d
JM
649}
650#endif
651
c364946d 652static inline void vscr_init(CPUPPCState *env, uint32_t val)
cf8358c8 653{
cf8358c8
AJ
654 /* Altivec always uses round-to-nearest */
655 set_float_rounding_mode(float_round_nearest_even, &env->vec_status);
c5ba06a3 656 helper_mtvscr(env, val);
cf8358c8
AJ
657}
658
d67d40ea
DG
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)
eb94268e
BH
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)
d67d40ea
DG
667#else
668#if !defined(CONFIG_KVM)
669#define spr_register_kvm(env, num, name, uea_read, uea_write, \
eb94268e
BH
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) \
d67d40ea 676 _spr_register(env, num, name, uea_read, uea_write, \
eb94268e 677 oea_read, oea_write, hea_read, hea_write, initial_value)
76a66253 678#else
d67d40ea 679#define spr_register_kvm(env, num, name, uea_read, uea_write, \
eb94268e
BH
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) \
d67d40ea 687 _spr_register(env, num, name, uea_read, uea_write, \
eb94268e
BH
688 oea_read, oea_write, hea_read, hea_write, \
689 one_reg_id, initial_value)
d67d40ea
DG
690#endif
691#endif
692
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)
697
eb94268e
BH
698#define spr_register_hv(env, num, name, uea_read, uea_write, \
699 oea_read, oea_write, hea_read, hea_write, \
700 initial_value) \
701 spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
702 oea_read, oea_write, hea_read, hea_write, \
703 0, initial_value)
704
d67d40ea 705static inline void _spr_register(CPUPPCState *env, int num,
b55266b5 706 const char *name,
1d28b5f6
DG
707 void (*uea_read)(DisasContext *ctx,
708 int gprn, int sprn),
709 void (*uea_write)(DisasContext *ctx,
710 int sprn, int gprn),
d67d40ea
DG
711#if !defined(CONFIG_USER_ONLY)
712
1d28b5f6
DG
713 void (*oea_read)(DisasContext *ctx,
714 int gprn, int sprn),
715 void (*oea_write)(DisasContext *ctx,
716 int sprn, int gprn),
717 void (*hea_read)(DisasContext *opaque,
718 int gprn, int sprn),
719 void (*hea_write)(DisasContext *opaque,
720 int sprn, int gprn),
76a66253 721#endif
d67d40ea
DG
722#if defined(CONFIG_KVM)
723 uint64_t one_reg_id,
724#endif
725 target_ulong initial_value)
3fc6c082 726{
c227f099 727 ppc_spr_t *spr;
3fc6c082
FB
728
729 spr = &env->spr_cb[num];
1d28b5f6 730 if (spr->name != NULL || env->spr[num] != 0x00000000 ||
76a66253
JM
731#if !defined(CONFIG_USER_ONLY)
732 spr->oea_read != NULL || spr->oea_write != NULL ||
733#endif
734 spr->uea_read != NULL || spr->uea_write != NULL) {
3fc6c082
FB
735 printf("Error: Trying to register SPR %d (%03x) twice !\n", num, num);
736 exit(1);
737 }
738#if defined(PPC_DEBUG_SPR)
90e189ec
BS
739 printf("*** register spr %d (%03x) %s val " TARGET_FMT_lx "\n", num, num,
740 name, initial_value);
3fc6c082
FB
741#endif
742 spr->name = name;
743 spr->uea_read = uea_read;
744 spr->uea_write = uea_write;
76a66253 745#if !defined(CONFIG_USER_ONLY)
3fc6c082
FB
746 spr->oea_read = oea_read;
747 spr->oea_write = oea_write;
eb94268e
BH
748 spr->hea_read = hea_read;
749 spr->hea_write = hea_write;
7a7c05d7
AK
750#endif
751#if defined(CONFIG_KVM)
752 spr->one_reg_id = one_reg_id,
76a66253 753#endif
d197fdbc 754 env->spr[num] = spr->default_value = initial_value;
3fc6c082
FB
755}
756
757/* Generic PowerPC SPRs */
c364946d 758static void gen_spr_generic(CPUPPCState *env)
3fc6c082
FB
759{
760 /* Integer processing */
761 spr_register(env, SPR_XER, "XER",
762 &spr_read_xer, &spr_write_xer,
763 &spr_read_xer, &spr_write_xer,
764 0x00000000);
765 /* Branch contol */
766 spr_register(env, SPR_LR, "LR",
767 &spr_read_lr, &spr_write_lr,
768 &spr_read_lr, &spr_write_lr,
769 0x00000000);
770 spr_register(env, SPR_CTR, "CTR",
771 &spr_read_ctr, &spr_write_ctr,
772 &spr_read_ctr, &spr_write_ctr,
773 0x00000000);
774 /* Interrupt processing */
775 spr_register(env, SPR_SRR0, "SRR0",
776 SPR_NOACCESS, SPR_NOACCESS,
777 &spr_read_generic, &spr_write_generic,
778 0x00000000);
779 spr_register(env, SPR_SRR1, "SRR1",
780 SPR_NOACCESS, SPR_NOACCESS,
781 &spr_read_generic, &spr_write_generic,
782 0x00000000);
783 /* Processor control */
784 spr_register(env, SPR_SPRG0, "SPRG0",
785 SPR_NOACCESS, SPR_NOACCESS,
786 &spr_read_generic, &spr_write_generic,
787 0x00000000);
788 spr_register(env, SPR_SPRG1, "SPRG1",
789 SPR_NOACCESS, SPR_NOACCESS,
790 &spr_read_generic, &spr_write_generic,
791 0x00000000);
792 spr_register(env, SPR_SPRG2, "SPRG2",
793 SPR_NOACCESS, SPR_NOACCESS,
794 &spr_read_generic, &spr_write_generic,
795 0x00000000);
796 spr_register(env, SPR_SPRG3, "SPRG3",
797 SPR_NOACCESS, SPR_NOACCESS,
798 &spr_read_generic, &spr_write_generic,
799 0x00000000);
800}
801
802/* SPR common to all non-embedded PowerPC, including 601 */
4f4f28ff 803static void gen_spr_ne_601(CPUPPCState *env)
3fc6c082
FB
804{
805 /* Exception processing */
d67d40ea
DG
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);
3fc6c082
FB
814 /* Timer */
815 spr_register(env, SPR_DECR, "DECR",
816 SPR_NOACCESS, SPR_NOACCESS,
817 &spr_read_decr, &spr_write_decr,
818 0x00000000);
4f4f28ff
SJS
819}
820
821/* Storage Description Register 1 */
822static void gen_spr_sdr1(CPUPPCState *env)
823{
7d6250e3
DG
824#ifndef CONFIG_USER_ONLY
825 if (env->has_hv_mode) {
1d28b5f6
DG
826 /*
827 * SDR1 is a hypervisor resource on CPUs which have a
828 * hypervisor mode
829 */
7d6250e3
DG
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,
834 0x00000000);
835 } else {
836 spr_register(env, SPR_SDR1, "SDR1",
837 SPR_NOACCESS, SPR_NOACCESS,
838 &spr_read_generic, &spr_write_sdr1,
839 0x00000000);
840 }
841#endif
3fc6c082
FB
842}
843
844/* BATs 0-3 */
c364946d 845static void gen_low_BATs(CPUPPCState *env)
3fc6c082 846{
f2e63a42 847#if !defined(CONFIG_USER_ONLY)
3fc6c082
FB
848 spr_register(env, SPR_IBAT0U, "IBAT0U",
849 SPR_NOACCESS, SPR_NOACCESS,
850 &spr_read_ibat, &spr_write_ibatu,
851 0x00000000);
852 spr_register(env, SPR_IBAT0L, "IBAT0L",
853 SPR_NOACCESS, SPR_NOACCESS,
854 &spr_read_ibat, &spr_write_ibatl,
855 0x00000000);
856 spr_register(env, SPR_IBAT1U, "IBAT1U",
857 SPR_NOACCESS, SPR_NOACCESS,
858 &spr_read_ibat, &spr_write_ibatu,
859 0x00000000);
860 spr_register(env, SPR_IBAT1L, "IBAT1L",
861 SPR_NOACCESS, SPR_NOACCESS,
862 &spr_read_ibat, &spr_write_ibatl,
863 0x00000000);
864 spr_register(env, SPR_IBAT2U, "IBAT2U",
865 SPR_NOACCESS, SPR_NOACCESS,
866 &spr_read_ibat, &spr_write_ibatu,
867 0x00000000);
868 spr_register(env, SPR_IBAT2L, "IBAT2L",
869 SPR_NOACCESS, SPR_NOACCESS,
870 &spr_read_ibat, &spr_write_ibatl,
871 0x00000000);
872 spr_register(env, SPR_IBAT3U, "IBAT3U",
873 SPR_NOACCESS, SPR_NOACCESS,
874 &spr_read_ibat, &spr_write_ibatu,
875 0x00000000);
876 spr_register(env, SPR_IBAT3L, "IBAT3L",
877 SPR_NOACCESS, SPR_NOACCESS,
878 &spr_read_ibat, &spr_write_ibatl,
879 0x00000000);
880 spr_register(env, SPR_DBAT0U, "DBAT0U",
881 SPR_NOACCESS, SPR_NOACCESS,
882 &spr_read_dbat, &spr_write_dbatu,
883 0x00000000);
884 spr_register(env, SPR_DBAT0L, "DBAT0L",
885 SPR_NOACCESS, SPR_NOACCESS,
886 &spr_read_dbat, &spr_write_dbatl,
887 0x00000000);
888 spr_register(env, SPR_DBAT1U, "DBAT1U",
889 SPR_NOACCESS, SPR_NOACCESS,
890 &spr_read_dbat, &spr_write_dbatu,
891 0x00000000);
892 spr_register(env, SPR_DBAT1L, "DBAT1L",
893 SPR_NOACCESS, SPR_NOACCESS,
894 &spr_read_dbat, &spr_write_dbatl,
895 0x00000000);
896 spr_register(env, SPR_DBAT2U, "DBAT2U",
897 SPR_NOACCESS, SPR_NOACCESS,
898 &spr_read_dbat, &spr_write_dbatu,
899 0x00000000);
900 spr_register(env, SPR_DBAT2L, "DBAT2L",
901 SPR_NOACCESS, SPR_NOACCESS,
902 &spr_read_dbat, &spr_write_dbatl,
903 0x00000000);
904 spr_register(env, SPR_DBAT3U, "DBAT3U",
905 SPR_NOACCESS, SPR_NOACCESS,
906 &spr_read_dbat, &spr_write_dbatu,
907 0x00000000);
908 spr_register(env, SPR_DBAT3L, "DBAT3L",
909 SPR_NOACCESS, SPR_NOACCESS,
910 &spr_read_dbat, &spr_write_dbatl,
911 0x00000000);
a750fc0b 912 env->nb_BATs += 4;
f2e63a42 913#endif
3fc6c082
FB
914}
915
916/* BATs 4-7 */
c364946d 917static void gen_high_BATs(CPUPPCState *env)
3fc6c082 918{
f2e63a42 919#if !defined(CONFIG_USER_ONLY)
3fc6c082
FB
920 spr_register(env, SPR_IBAT4U, "IBAT4U",
921 SPR_NOACCESS, SPR_NOACCESS,
922 &spr_read_ibat_h, &spr_write_ibatu_h,
923 0x00000000);
924 spr_register(env, SPR_IBAT4L, "IBAT4L",
925 SPR_NOACCESS, SPR_NOACCESS,
926 &spr_read_ibat_h, &spr_write_ibatl_h,
927 0x00000000);
928 spr_register(env, SPR_IBAT5U, "IBAT5U",
929 SPR_NOACCESS, SPR_NOACCESS,
930 &spr_read_ibat_h, &spr_write_ibatu_h,
931 0x00000000);
932 spr_register(env, SPR_IBAT5L, "IBAT5L",
933 SPR_NOACCESS, SPR_NOACCESS,
934 &spr_read_ibat_h, &spr_write_ibatl_h,
935 0x00000000);
936 spr_register(env, SPR_IBAT6U, "IBAT6U",
937 SPR_NOACCESS, SPR_NOACCESS,
938 &spr_read_ibat_h, &spr_write_ibatu_h,
939 0x00000000);
940 spr_register(env, SPR_IBAT6L, "IBAT6L",
941 SPR_NOACCESS, SPR_NOACCESS,
942 &spr_read_ibat_h, &spr_write_ibatl_h,
943 0x00000000);
944 spr_register(env, SPR_IBAT7U, "IBAT7U",
945 SPR_NOACCESS, SPR_NOACCESS,
946 &spr_read_ibat_h, &spr_write_ibatu_h,
947 0x00000000);
948 spr_register(env, SPR_IBAT7L, "IBAT7L",
949 SPR_NOACCESS, SPR_NOACCESS,
950 &spr_read_ibat_h, &spr_write_ibatl_h,
951 0x00000000);
952 spr_register(env, SPR_DBAT4U, "DBAT4U",
953 SPR_NOACCESS, SPR_NOACCESS,
954 &spr_read_dbat_h, &spr_write_dbatu_h,
955 0x00000000);
956 spr_register(env, SPR_DBAT4L, "DBAT4L",
957 SPR_NOACCESS, SPR_NOACCESS,
958 &spr_read_dbat_h, &spr_write_dbatl_h,
959 0x00000000);
960 spr_register(env, SPR_DBAT5U, "DBAT5U",
961 SPR_NOACCESS, SPR_NOACCESS,
962 &spr_read_dbat_h, &spr_write_dbatu_h,
963 0x00000000);
964 spr_register(env, SPR_DBAT5L, "DBAT5L",
965 SPR_NOACCESS, SPR_NOACCESS,
966 &spr_read_dbat_h, &spr_write_dbatl_h,
967 0x00000000);
968 spr_register(env, SPR_DBAT6U, "DBAT6U",
969 SPR_NOACCESS, SPR_NOACCESS,
970 &spr_read_dbat_h, &spr_write_dbatu_h,
971 0x00000000);
972 spr_register(env, SPR_DBAT6L, "DBAT6L",
973 SPR_NOACCESS, SPR_NOACCESS,
974 &spr_read_dbat_h, &spr_write_dbatl_h,
975 0x00000000);
976 spr_register(env, SPR_DBAT7U, "DBAT7U",
977 SPR_NOACCESS, SPR_NOACCESS,
978 &spr_read_dbat_h, &spr_write_dbatu_h,
979 0x00000000);
980 spr_register(env, SPR_DBAT7L, "DBAT7L",
981 SPR_NOACCESS, SPR_NOACCESS,
982 &spr_read_dbat_h, &spr_write_dbatl_h,
983 0x00000000);
a750fc0b 984 env->nb_BATs += 4;
f2e63a42 985#endif
3fc6c082
FB
986}
987
988/* Generic PowerPC time base */
c364946d 989static void gen_tbl(CPUPPCState *env)
3fc6c082
FB
990{
991 spr_register(env, SPR_VTBL, "TBL",
992 &spr_read_tbl, SPR_NOACCESS,
993 &spr_read_tbl, SPR_NOACCESS,
994 0x00000000);
995 spr_register(env, SPR_TBL, "TBL",
de6a1dec
DI
996 &spr_read_tbl, SPR_NOACCESS,
997 &spr_read_tbl, &spr_write_tbl,
3fc6c082
FB
998 0x00000000);
999 spr_register(env, SPR_VTBU, "TBU",
1000 &spr_read_tbu, SPR_NOACCESS,
1001 &spr_read_tbu, SPR_NOACCESS,
1002 0x00000000);
1003 spr_register(env, SPR_TBU, "TBU",
de6a1dec
DI
1004 &spr_read_tbu, SPR_NOACCESS,
1005 &spr_read_tbu, &spr_write_tbu,
3fc6c082
FB
1006 0x00000000);
1007}
1008
76a66253 1009/* Softare table search registers */
c364946d 1010static void gen_6xx_7xx_soft_tlb(CPUPPCState *env, int nb_tlbs, int nb_ways)
76a66253 1011{
f2e63a42 1012#if !defined(CONFIG_USER_ONLY)
76a66253
JM
1013 env->nb_tlb = nb_tlbs;
1014 env->nb_ways = nb_ways;
1015 env->id_tlbs = 1;
1c53accc 1016 env->tlb_type = TLB_6XX;
76a66253
JM
1017 spr_register(env, SPR_DMISS, "DMISS",
1018 SPR_NOACCESS, SPR_NOACCESS,
1019 &spr_read_generic, SPR_NOACCESS,
1020 0x00000000);
1021 spr_register(env, SPR_DCMP, "DCMP",
1022 SPR_NOACCESS, SPR_NOACCESS,
1023 &spr_read_generic, SPR_NOACCESS,
1024 0x00000000);
1025 spr_register(env, SPR_HASH1, "HASH1",
1026 SPR_NOACCESS, SPR_NOACCESS,
1027 &spr_read_generic, SPR_NOACCESS,
1028 0x00000000);
1029 spr_register(env, SPR_HASH2, "HASH2",
1030 SPR_NOACCESS, SPR_NOACCESS,
1031 &spr_read_generic, SPR_NOACCESS,
1032 0x00000000);
1033 spr_register(env, SPR_IMISS, "IMISS",
1034 SPR_NOACCESS, SPR_NOACCESS,
1035 &spr_read_generic, SPR_NOACCESS,
1036 0x00000000);
1037 spr_register(env, SPR_ICMP, "ICMP",
1038 SPR_NOACCESS, SPR_NOACCESS,
1039 &spr_read_generic, SPR_NOACCESS,
1040 0x00000000);
1041 spr_register(env, SPR_RPA, "RPA",
1042 SPR_NOACCESS, SPR_NOACCESS,
1043 &spr_read_generic, &spr_write_generic,
1044 0x00000000);
f2e63a42 1045#endif
76a66253
JM
1046}
1047
1048/* SPR common to MPC755 and G2 */
c364946d 1049static void gen_spr_G2_755(CPUPPCState *env)
76a66253
JM
1050{
1051 /* SGPRs */
1052 spr_register(env, SPR_SPRG4, "SPRG4",
1053 SPR_NOACCESS, SPR_NOACCESS,
1054 &spr_read_generic, &spr_write_generic,
1055 0x00000000);
1056 spr_register(env, SPR_SPRG5, "SPRG5",
1057 SPR_NOACCESS, SPR_NOACCESS,
1058 &spr_read_generic, &spr_write_generic,
1059 0x00000000);
1060 spr_register(env, SPR_SPRG6, "SPRG6",
1061 SPR_NOACCESS, SPR_NOACCESS,
1062 &spr_read_generic, &spr_write_generic,
1063 0x00000000);
1064 spr_register(env, SPR_SPRG7, "SPRG7",
1065 SPR_NOACCESS, SPR_NOACCESS,
1066 &spr_read_generic, &spr_write_generic,
1067 0x00000000);
76a66253
JM
1068}
1069
3fc6c082 1070/* SPR common to all 7xx PowerPC implementations */
c364946d 1071static void gen_spr_7xx(CPUPPCState *env)
3fc6c082
FB
1072{
1073 /* Breakpoints */
1074 /* XXX : not implemented */
d67d40ea
DG
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);
3fc6c082
FB
1079 /* XXX : not implemented */
1080 spr_register(env, SPR_IABR, "IABR",
1081 SPR_NOACCESS, SPR_NOACCESS,
1082 &spr_read_generic, &spr_write_generic,
1083 0x00000000);
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,
1089 0x00000000);
1090 /* Performance monitors */
1091 /* XXX : not implemented */
cb8b8bf8 1092 spr_register(env, SPR_7XX_MMCR0, "MMCR0",
3fc6c082
FB
1093 SPR_NOACCESS, SPR_NOACCESS,
1094 &spr_read_generic, &spr_write_generic,
1095 0x00000000);
1096 /* XXX : not implemented */
cb8b8bf8 1097 spr_register(env, SPR_7XX_MMCR1, "MMCR1",
3fc6c082
FB
1098 SPR_NOACCESS, SPR_NOACCESS,
1099 &spr_read_generic, &spr_write_generic,
1100 0x00000000);
1101 /* XXX : not implemented */
cb8b8bf8 1102 spr_register(env, SPR_7XX_PMC1, "PMC1",
3fc6c082
FB
1103 SPR_NOACCESS, SPR_NOACCESS,
1104 &spr_read_generic, &spr_write_generic,
1105 0x00000000);
1106 /* XXX : not implemented */
cb8b8bf8 1107 spr_register(env, SPR_7XX_PMC2, "PMC2",
3fc6c082
FB
1108 SPR_NOACCESS, SPR_NOACCESS,
1109 &spr_read_generic, &spr_write_generic,
1110 0x00000000);
1111 /* XXX : not implemented */
cb8b8bf8 1112 spr_register(env, SPR_7XX_PMC3, "PMC3",
3fc6c082
FB
1113 SPR_NOACCESS, SPR_NOACCESS,
1114 &spr_read_generic, &spr_write_generic,
1115 0x00000000);
1116 /* XXX : not implemented */
cb8b8bf8 1117 spr_register(env, SPR_7XX_PMC4, "PMC4",
3fc6c082
FB
1118 SPR_NOACCESS, SPR_NOACCESS,
1119 &spr_read_generic, &spr_write_generic,
1120 0x00000000);
1121 /* XXX : not implemented */
cb8b8bf8 1122 spr_register(env, SPR_7XX_SIAR, "SIAR",
3fc6c082
FB
1123 SPR_NOACCESS, SPR_NOACCESS,
1124 &spr_read_generic, SPR_NOACCESS,
1125 0x00000000);
578bb252 1126 /* XXX : not implemented */
cb8b8bf8 1127 spr_register(env, SPR_7XX_UMMCR0, "UMMCR0",
3fc6c082
FB
1128 &spr_read_ureg, SPR_NOACCESS,
1129 &spr_read_ureg, SPR_NOACCESS,
1130 0x00000000);
578bb252 1131 /* XXX : not implemented */
cb8b8bf8 1132 spr_register(env, SPR_7XX_UMMCR1, "UMMCR1",
3fc6c082
FB
1133 &spr_read_ureg, SPR_NOACCESS,
1134 &spr_read_ureg, SPR_NOACCESS,
1135 0x00000000);
578bb252 1136 /* XXX : not implemented */
cb8b8bf8 1137 spr_register(env, SPR_7XX_UPMC1, "UPMC1",
3fc6c082
FB
1138 &spr_read_ureg, SPR_NOACCESS,
1139 &spr_read_ureg, SPR_NOACCESS,
1140 0x00000000);
578bb252 1141 /* XXX : not implemented */
cb8b8bf8 1142 spr_register(env, SPR_7XX_UPMC2, "UPMC2",
3fc6c082
FB
1143 &spr_read_ureg, SPR_NOACCESS,
1144 &spr_read_ureg, SPR_NOACCESS,
1145 0x00000000);
578bb252 1146 /* XXX : not implemented */
cb8b8bf8 1147 spr_register(env, SPR_7XX_UPMC3, "UPMC3",
3fc6c082
FB
1148 &spr_read_ureg, SPR_NOACCESS,
1149 &spr_read_ureg, SPR_NOACCESS,
1150 0x00000000);
578bb252 1151 /* XXX : not implemented */
cb8b8bf8 1152 spr_register(env, SPR_7XX_UPMC4, "UPMC4",
3fc6c082
FB
1153 &spr_read_ureg, SPR_NOACCESS,
1154 &spr_read_ureg, SPR_NOACCESS,
1155 0x00000000);
578bb252 1156 /* XXX : not implemented */
cb8b8bf8 1157 spr_register(env, SPR_7XX_USIAR, "USIAR",
3fc6c082
FB
1158 &spr_read_ureg, SPR_NOACCESS,
1159 &spr_read_ureg, SPR_NOACCESS,
1160 0x00000000);
a750fc0b 1161 /* External access control */
3fc6c082 1162 /* XXX : not implemented */
a750fc0b 1163 spr_register(env, SPR_EAR, "EAR",
3fc6c082
FB
1164 SPR_NOACCESS, SPR_NOACCESS,
1165 &spr_read_generic, &spr_write_generic,
1166 0x00000000);
a750fc0b
JM
1167}
1168
f80872e2
DG
1169#ifdef TARGET_PPC64
1170#ifndef CONFIG_USER_ONLY
97eaf30e 1171static void spr_write_amr(DisasContext *ctx, int sprn, int gprn)
f80872e2 1172{
97eaf30e
BH
1173 TCGv t0 = tcg_temp_new();
1174 TCGv t1 = tcg_temp_new();
1175 TCGv t2 = tcg_temp_new();
f80872e2 1176
1d28b5f6
DG
1177 /*
1178 * Note, the HV=1 PR=0 case is handled earlier by simply using
97eaf30e
BH
1179 * spr_write_generic for HV mode in the SPR table
1180 */
1181
1182 /* Build insertion mask into t1 based on context */
1183 if (ctx->pr) {
1184 gen_load_spr(t1, SPR_UAMOR);
1185 } else {
1186 gen_load_spr(t1, SPR_AMOR);
1187 }
1188
1189 /* Mask new bits into t2 */
1190 tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]);
1191
1192 /* Load AMR and clear new bits in t0 */
1193 gen_load_spr(t0, SPR_AMR);
1194 tcg_gen_andc_tl(t0, t0, t1);
1195
1196 /* Or'in new bits and write it out */
1197 tcg_gen_or_tl(t0, t0, t2);
1198 gen_store_spr(SPR_AMR, t0);
f80872e2 1199 spr_store_dump_spr(SPR_AMR);
97eaf30e
BH
1200
1201 tcg_temp_free(t0);
1202 tcg_temp_free(t1);
1203 tcg_temp_free(t2);
f80872e2
DG
1204}
1205
97eaf30e 1206static void spr_write_uamor(DisasContext *ctx, int sprn, int gprn)
f80872e2
DG
1207{
1208 TCGv t0 = tcg_temp_new();
97eaf30e
BH
1209 TCGv t1 = tcg_temp_new();
1210 TCGv t2 = tcg_temp_new();
1211
1d28b5f6
DG
1212 /*
1213 * Note, the HV=1 case is handled earlier by simply using
97eaf30e
BH
1214 * spr_write_generic for HV mode in the SPR table
1215 */
f80872e2 1216
97eaf30e
BH
1217 /* Build insertion mask into t1 based on context */
1218 gen_load_spr(t1, SPR_AMOR);
1219
1220 /* Mask new bits into t2 */
1221 tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]);
1222
1223 /* Load AMR and clear new bits in t0 */
f80872e2 1224 gen_load_spr(t0, SPR_UAMOR);
97eaf30e
BH
1225 tcg_gen_andc_tl(t0, t0, t1);
1226
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);
1231
1232 tcg_temp_free(t0);
1233 tcg_temp_free(t1);
1234 tcg_temp_free(t2);
f80872e2 1235}
a6eabb9e
BH
1236
1237static void spr_write_iamr(DisasContext *ctx, int sprn, int gprn)
1238{
1239 TCGv t0 = tcg_temp_new();
1240 TCGv t1 = tcg_temp_new();
1241 TCGv t2 = tcg_temp_new();
1242
1d28b5f6
DG
1243 /*
1244 * Note, the HV=1 case is handled earlier by simply using
a6eabb9e
BH
1245 * spr_write_generic for HV mode in the SPR table
1246 */
1247
1248 /* Build insertion mask into t1 based on context */
1249 gen_load_spr(t1, SPR_AMOR);
1250
1251 /* Mask new bits into t2 */
1252 tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]);
1253
1254 /* Load AMR and clear new bits in t0 */
1255 gen_load_spr(t0, SPR_IAMR);
1256 tcg_gen_andc_tl(t0, t0, t1);
1257
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);
1262
1263 tcg_temp_free(t0);
1264 tcg_temp_free(t1);
1265 tcg_temp_free(t2);
1266}
f80872e2
DG
1267#endif /* CONFIG_USER_ONLY */
1268
4f4f28ff 1269static void gen_spr_amr(CPUPPCState *env)
f80872e2
DG
1270{
1271#ifndef CONFIG_USER_ONLY
1d28b5f6
DG
1272 /*
1273 * Virtual Page Class Key protection
1274 *
1275 * The AMR is accessible either via SPR 13 or SPR 29. 13 is
f80872e2 1276 * userspace accessible, 29 is privileged. So we only need to set
1d28b5f6
DG
1277 * the kvm ONE_REG id on one of them, we use 29
1278 */
f80872e2 1279 spr_register(env, SPR_UAMR, "UAMR",
97eaf30e
BH
1280 &spr_read_generic, &spr_write_amr,
1281 &spr_read_generic, &spr_write_amr,
f80872e2 1282 0);
97eaf30e 1283 spr_register_kvm_hv(env, SPR_AMR, "AMR",
f80872e2 1284 SPR_NOACCESS, SPR_NOACCESS,
97eaf30e 1285 &spr_read_generic, &spr_write_amr,
f80872e2 1286 &spr_read_generic, &spr_write_generic,
0dc083fe 1287 KVM_REG_PPC_AMR, 0);
97eaf30e 1288 spr_register_kvm_hv(env, SPR_UAMOR, "UAMOR",
f80872e2 1289 SPR_NOACCESS, SPR_NOACCESS,
97eaf30e 1290 &spr_read_generic, &spr_write_uamor,
f80872e2
DG
1291 &spr_read_generic, &spr_write_generic,
1292 KVM_REG_PPC_UAMOR, 0);
f401dd32
BH
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,
1297 0);
4f4f28ff
SJS
1298#endif /* !CONFIG_USER_ONLY */
1299}
1300
1301static void gen_spr_iamr(CPUPPCState *env)
1302{
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);
f80872e2
DG
1309#endif /* !CONFIG_USER_ONLY */
1310}
1311#endif /* TARGET_PPC64 */
1312
f0278900
BH
1313#ifndef CONFIG_USER_ONLY
1314static void spr_read_thrm(DisasContext *ctx, int gprn, int sprn)
1315{
1316 gen_helper_fixup_thrm(cpu_env);
1317 gen_load_spr(cpu_gpr[gprn], sprn);
1318 spr_load_dump_spr(sprn);
1319}
1320#endif /* !CONFIG_USER_ONLY */
1321
c364946d 1322static void gen_spr_thrm(CPUPPCState *env)
a750fc0b
JM
1323{
1324 /* Thermal management */
3fc6c082 1325 /* XXX : not implemented */
a750fc0b 1326 spr_register(env, SPR_THRM1, "THRM1",
3fc6c082 1327 SPR_NOACCESS, SPR_NOACCESS,
f0278900 1328 &spr_read_thrm, &spr_write_generic,
3fc6c082
FB
1329 0x00000000);
1330 /* XXX : not implemented */
a750fc0b 1331 spr_register(env, SPR_THRM2, "THRM2",
3fc6c082 1332 SPR_NOACCESS, SPR_NOACCESS,
f0278900 1333 &spr_read_thrm, &spr_write_generic,
3fc6c082 1334 0x00000000);
3fc6c082 1335 /* XXX : not implemented */
a750fc0b 1336 spr_register(env, SPR_THRM3, "THRM3",
3fc6c082 1337 SPR_NOACCESS, SPR_NOACCESS,
f0278900 1338 &spr_read_thrm, &spr_write_generic,
3fc6c082
FB
1339 0x00000000);
1340}
1341
1342/* SPR specific to PowerPC 604 implementation */
c364946d 1343static void gen_spr_604(CPUPPCState *env)
3fc6c082
FB
1344{
1345 /* Processor identification */
1346 spr_register(env, SPR_PIR, "PIR",
1347 SPR_NOACCESS, SPR_NOACCESS,
1348 &spr_read_generic, &spr_write_pir,
1349 0x00000000);
1350 /* Breakpoints */
1351 /* XXX : not implemented */
1352 spr_register(env, SPR_IABR, "IABR",
1353 SPR_NOACCESS, SPR_NOACCESS,
1354 &spr_read_generic, &spr_write_generic,
1355 0x00000000);
1356 /* XXX : not implemented */
d67d40ea
DG
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);
3fc6c082
FB
1361 /* Performance counters */
1362 /* XXX : not implemented */
cb8b8bf8 1363 spr_register(env, SPR_7XX_MMCR0, "MMCR0",
3fc6c082
FB
1364 SPR_NOACCESS, SPR_NOACCESS,
1365 &spr_read_generic, &spr_write_generic,
1366 0x00000000);
1367 /* XXX : not implemented */
cb8b8bf8 1368 spr_register(env, SPR_7XX_PMC1, "PMC1",
3fc6c082
FB
1369 SPR_NOACCESS, SPR_NOACCESS,
1370 &spr_read_generic, &spr_write_generic,
1371 0x00000000);
1372 /* XXX : not implemented */
cb8b8bf8 1373 spr_register(env, SPR_7XX_PMC2, "PMC2",
3fc6c082
FB
1374 SPR_NOACCESS, SPR_NOACCESS,
1375 &spr_read_generic, &spr_write_generic,
1376 0x00000000);
1377 /* XXX : not implemented */
cb8b8bf8 1378 spr_register(env, SPR_7XX_SIAR, "SIAR",
3fc6c082
FB
1379 SPR_NOACCESS, SPR_NOACCESS,
1380 &spr_read_generic, SPR_NOACCESS,
1381 0x00000000);
1382 /* XXX : not implemented */
1383 spr_register(env, SPR_SDA, "SDA",
1384 SPR_NOACCESS, SPR_NOACCESS,
1385 &spr_read_generic, SPR_NOACCESS,
1386 0x00000000);
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,
1392 0x00000000);
1393}
1394
76a66253 1395/* SPR specific to PowerPC 603 implementation */
c364946d 1396static void gen_spr_603(CPUPPCState *env)
3fc6c082 1397{
76a66253
JM
1398 /* External access control */
1399 /* XXX : not implemented */
1400 spr_register(env, SPR_EAR, "EAR",
3fc6c082 1401 SPR_NOACCESS, SPR_NOACCESS,
76a66253
JM
1402 &spr_read_generic, &spr_write_generic,
1403 0x00000000);
2bc17322
FC
1404 /* Breakpoints */
1405 /* XXX : not implemented */
1406 spr_register(env, SPR_IABR, "IABR",
1407 SPR_NOACCESS, SPR_NOACCESS,
1408 &spr_read_generic, &spr_write_generic,
1409 0x00000000);
1410
3fc6c082
FB
1411}
1412
76a66253 1413/* SPR specific to PowerPC G2 implementation */
c364946d 1414static void gen_spr_G2(CPUPPCState *env)
3fc6c082 1415{
76a66253
JM
1416 /* Memory base address */
1417 /* MBAR */
578bb252 1418 /* XXX : not implemented */
76a66253
JM
1419 spr_register(env, SPR_MBAR, "MBAR",
1420 SPR_NOACCESS, SPR_NOACCESS,
1421 &spr_read_generic, &spr_write_generic,
1422 0x00000000);
76a66253 1423 /* Exception processing */
363be49c 1424 spr_register(env, SPR_BOOKE_CSRR0, "CSRR0",
76a66253
JM
1425 SPR_NOACCESS, SPR_NOACCESS,
1426 &spr_read_generic, &spr_write_generic,
1427 0x00000000);
363be49c 1428 spr_register(env, SPR_BOOKE_CSRR1, "CSRR1",
76a66253
JM
1429 SPR_NOACCESS, SPR_NOACCESS,
1430 &spr_read_generic, &spr_write_generic,
1431 0x00000000);
1432 /* Breakpoints */
1433 /* XXX : not implemented */
1434 spr_register(env, SPR_DABR, "DABR",
1435 SPR_NOACCESS, SPR_NOACCESS,
1436 &spr_read_generic, &spr_write_generic,
1437 0x00000000);
1438 /* XXX : not implemented */
1439 spr_register(env, SPR_DABR2, "DABR2",
1440 SPR_NOACCESS, SPR_NOACCESS,
1441 &spr_read_generic, &spr_write_generic,
1442 0x00000000);
1443 /* XXX : not implemented */
1444 spr_register(env, SPR_IABR, "IABR",
1445 SPR_NOACCESS, SPR_NOACCESS,
1446 &spr_read_generic, &spr_write_generic,
1447 0x00000000);
1448 /* XXX : not implemented */
1449 spr_register(env, SPR_IABR2, "IABR2",
1450 SPR_NOACCESS, SPR_NOACCESS,
1451 &spr_read_generic, &spr_write_generic,
1452 0x00000000);
1453 /* XXX : not implemented */
1454 spr_register(env, SPR_IBCR, "IBCR",
1455 SPR_NOACCESS, SPR_NOACCESS,
1456 &spr_read_generic, &spr_write_generic,
1457 0x00000000);
1458 /* XXX : not implemented */
1459 spr_register(env, SPR_DBCR, "DBCR",
1460 SPR_NOACCESS, SPR_NOACCESS,
1461 &spr_read_generic, &spr_write_generic,
1462 0x00000000);
1463}
1464
1465/* SPR specific to PowerPC 602 implementation */
c364946d 1466static void gen_spr_602(CPUPPCState *env)
76a66253
JM
1467{
1468 /* ESA registers */
1469 /* XXX : not implemented */
1470 spr_register(env, SPR_SER, "SER",
1471 SPR_NOACCESS, SPR_NOACCESS,
1472 &spr_read_generic, &spr_write_generic,
1473 0x00000000);
1474 /* XXX : not implemented */
1475 spr_register(env, SPR_SEBR, "SEBR",
1476 SPR_NOACCESS, SPR_NOACCESS,
1477 &spr_read_generic, &spr_write_generic,
1478 0x00000000);
1479 /* XXX : not implemented */
a750fc0b 1480 spr_register(env, SPR_ESASRR, "ESASRR",
76a66253
JM
1481 SPR_NOACCESS, SPR_NOACCESS,
1482 &spr_read_generic, &spr_write_generic,
1483 0x00000000);
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,
1489 0x00000000);
1490 /* XXX : not implemented */
1491 spr_register(env, SPR_LT, "LT",
1492 SPR_NOACCESS, SPR_NOACCESS,
1493 &spr_read_generic, &spr_write_generic,
1494 0x00000000);
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,
1500 0x00000000);
1501 /* Interrupt base */
1502 spr_register(env, SPR_IBR, "IBR",
1503 SPR_NOACCESS, SPR_NOACCESS,
1504 &spr_read_generic, &spr_write_generic,
1505 0x00000000);
a750fc0b
JM
1506 /* XXX : not implemented */
1507 spr_register(env, SPR_IABR, "IABR",
1508 SPR_NOACCESS, SPR_NOACCESS,
1509 &spr_read_generic, &spr_write_generic,
1510 0x00000000);
76a66253
JM
1511}
1512
1513/* SPR specific to PowerPC 601 implementation */
c364946d 1514static void gen_spr_601(CPUPPCState *env)
76a66253
JM
1515{
1516 /* Multiplication/division register */
1517 /* MQ */
1518 spr_register(env, SPR_MQ, "MQ",
1519 &spr_read_generic, &spr_write_generic,
1520 &spr_read_generic, &spr_write_generic,
1521 0x00000000);
1522 /* RTC registers */
1523 spr_register(env, SPR_601_RTCU, "RTCU",
1524 SPR_NOACCESS, SPR_NOACCESS,
1525 SPR_NOACCESS, &spr_write_601_rtcu,
1526 0x00000000);
1527 spr_register(env, SPR_601_VRTCU, "RTCU",
1528 &spr_read_601_rtcu, SPR_NOACCESS,
1529 &spr_read_601_rtcu, SPR_NOACCESS,
1530 0x00000000);
1531 spr_register(env, SPR_601_RTCL, "RTCL",
1532 SPR_NOACCESS, SPR_NOACCESS,
1533 SPR_NOACCESS, &spr_write_601_rtcl,
1534 0x00000000);
1535 spr_register(env, SPR_601_VRTCL, "RTCL",
1536 &spr_read_601_rtcl, SPR_NOACCESS,
1537 &spr_read_601_rtcl, SPR_NOACCESS,
1538 0x00000000);
1539 /* Timer */
1540#if 0 /* ? */
1541 spr_register(env, SPR_601_UDECR, "UDECR",
1542 &spr_read_decr, SPR_NOACCESS,
1543 &spr_read_decr, SPR_NOACCESS,
1544 0x00000000);
1545#endif
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,
1551 0x00000000);
1552 /* Memory management */
f2e63a42 1553#if !defined(CONFIG_USER_ONLY)
76a66253
JM
1554 spr_register(env, SPR_IBAT0U, "IBAT0U",
1555 SPR_NOACCESS, SPR_NOACCESS,
1556 &spr_read_601_ubat, &spr_write_601_ubatu,
1557 0x00000000);
1558 spr_register(env, SPR_IBAT0L, "IBAT0L",
1559 SPR_NOACCESS, SPR_NOACCESS,
1560 &spr_read_601_ubat, &spr_write_601_ubatl,
1561 0x00000000);
1562 spr_register(env, SPR_IBAT1U, "IBAT1U",
1563 SPR_NOACCESS, SPR_NOACCESS,
1564 &spr_read_601_ubat, &spr_write_601_ubatu,
1565 0x00000000);
1566 spr_register(env, SPR_IBAT1L, "IBAT1L",
1567 SPR_NOACCESS, SPR_NOACCESS,
1568 &spr_read_601_ubat, &spr_write_601_ubatl,
1569 0x00000000);
1570 spr_register(env, SPR_IBAT2U, "IBAT2U",
1571 SPR_NOACCESS, SPR_NOACCESS,
1572 &spr_read_601_ubat, &spr_write_601_ubatu,
1573 0x00000000);
1574 spr_register(env, SPR_IBAT2L, "IBAT2L",
1575 SPR_NOACCESS, SPR_NOACCESS,
1576 &spr_read_601_ubat, &spr_write_601_ubatl,
1577 0x00000000);
1578 spr_register(env, SPR_IBAT3U, "IBAT3U",
1579 SPR_NOACCESS, SPR_NOACCESS,
1580 &spr_read_601_ubat, &spr_write_601_ubatu,
1581 0x00000000);
1582 spr_register(env, SPR_IBAT3L, "IBAT3L",
1583 SPR_NOACCESS, SPR_NOACCESS,
1584 &spr_read_601_ubat, &spr_write_601_ubatl,
1585 0x00000000);
a750fc0b 1586 env->nb_BATs = 4;
f2e63a42 1587#endif
a750fc0b
JM
1588}
1589
c364946d 1590static void gen_spr_74xx(CPUPPCState *env)
a750fc0b
JM
1591{
1592 /* Processor identification */
1593 spr_register(env, SPR_PIR, "PIR",
1594 SPR_NOACCESS, SPR_NOACCESS,
1595 &spr_read_generic, &spr_write_pir,
1596 0x00000000);
1597 /* XXX : not implemented */
cb8b8bf8 1598 spr_register(env, SPR_74XX_MMCR2, "MMCR2",
a750fc0b
JM
1599 SPR_NOACCESS, SPR_NOACCESS,
1600 &spr_read_generic, &spr_write_generic,
1601 0x00000000);
578bb252 1602 /* XXX : not implemented */
cb8b8bf8 1603 spr_register(env, SPR_74XX_UMMCR2, "UMMCR2",
a750fc0b
JM
1604 &spr_read_ureg, SPR_NOACCESS,
1605 &spr_read_ureg, SPR_NOACCESS,
1606 0x00000000);
1607 /* XXX: not implemented */
1608 spr_register(env, SPR_BAMR, "BAMR",
1609 SPR_NOACCESS, SPR_NOACCESS,
1610 &spr_read_generic, &spr_write_generic,
1611 0x00000000);
578bb252 1612 /* XXX : not implemented */
a750fc0b
JM
1613 spr_register(env, SPR_MSSCR0, "MSSCR0",
1614 SPR_NOACCESS, SPR_NOACCESS,
1615 &spr_read_generic, &spr_write_generic,
1616 0x00000000);
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,
1622 0x00000000);
1623 /* XXX : not implemented */
1624 spr_register(env, SPR_HID1, "HID1",
1625 SPR_NOACCESS, SPR_NOACCESS,
1626 &spr_read_generic, &spr_write_generic,
1627 0x00000000);
1628 /* Altivec */
1629 spr_register(env, SPR_VRSAVE, "VRSAVE",
1630 &spr_read_generic, &spr_write_generic,
1631 &spr_read_generic, &spr_write_generic,
1632 0x00000000);
bd928eba
JM
1633 /* XXX : not implemented */
1634 spr_register(env, SPR_L2CR, "L2CR",
1635 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 1636 &spr_read_generic, spr_access_nop,
bd928eba 1637 0x00000000);
cf8358c8
AJ
1638 /* Not strictly an SPR */
1639 vscr_init(env, 0x00010000);
a750fc0b
JM
1640}
1641
c364946d 1642static void gen_l3_ctrl(CPUPPCState *env)
a750fc0b
JM
1643{
1644 /* L3CR */
1645 /* XXX : not implemented */
1646 spr_register(env, SPR_L3CR, "L3CR",
1647 SPR_NOACCESS, SPR_NOACCESS,
1648 &spr_read_generic, &spr_write_generic,
1649 0x00000000);
1650 /* L3ITCR0 */
578bb252 1651 /* XXX : not implemented */
a750fc0b
JM
1652 spr_register(env, SPR_L3ITCR0, "L3ITCR0",
1653 SPR_NOACCESS, SPR_NOACCESS,
1654 &spr_read_generic, &spr_write_generic,
1655 0x00000000);
a750fc0b 1656 /* L3PM */
578bb252 1657 /* XXX : not implemented */
a750fc0b
JM
1658 spr_register(env, SPR_L3PM, "L3PM",
1659 SPR_NOACCESS, SPR_NOACCESS,
1660 &spr_read_generic, &spr_write_generic,
1661 0x00000000);
1662}
a750fc0b 1663
c364946d 1664static void gen_74xx_soft_tlb(CPUPPCState *env, int nb_tlbs, int nb_ways)
a750fc0b 1665{
f2e63a42 1666#if !defined(CONFIG_USER_ONLY)
578bb252
JM
1667 env->nb_tlb = nb_tlbs;
1668 env->nb_ways = nb_ways;
1669 env->id_tlbs = 1;
1c53accc 1670 env->tlb_type = TLB_6XX;
578bb252 1671 /* XXX : not implemented */
a750fc0b
JM
1672 spr_register(env, SPR_PTEHI, "PTEHI",
1673 SPR_NOACCESS, SPR_NOACCESS,
1674 &spr_read_generic, &spr_write_generic,
1675 0x00000000);
578bb252 1676 /* XXX : not implemented */
a750fc0b
JM
1677 spr_register(env, SPR_PTELO, "PTELO",
1678 SPR_NOACCESS, SPR_NOACCESS,
1679 &spr_read_generic, &spr_write_generic,
1680 0x00000000);
578bb252 1681 /* XXX : not implemented */
a750fc0b
JM
1682 spr_register(env, SPR_TLBMISS, "TLBMISS",
1683 SPR_NOACCESS, SPR_NOACCESS,
1684 &spr_read_generic, &spr_write_generic,
1685 0x00000000);
f2e63a42 1686#endif
76a66253
JM
1687}
1688
01662f3e 1689#if !defined(CONFIG_USER_ONLY)
c364946d 1690static void spr_write_e500_l1csr0(DisasContext *ctx, int sprn, int gprn)
01662f3e
AG
1691{
1692 TCGv t0 = tcg_temp_new();
1693
ea71258d
AG
1694 tcg_gen_andi_tl(t0, cpu_gpr[gprn], L1CSR0_DCE | L1CSR0_CPE);
1695 gen_store_spr(sprn, t0);
1696 tcg_temp_free(t0);
1697}
1698
69b058c8 1699static void spr_write_e500_l1csr1(DisasContext *ctx, int sprn, int gprn)
ea71258d
AG
1700{
1701 TCGv t0 = tcg_temp_new();
1702
1703 tcg_gen_andi_tl(t0, cpu_gpr[gprn], L1CSR1_ICE | L1CSR1_CPE);
01662f3e
AG
1704 gen_store_spr(sprn, t0);
1705 tcg_temp_free(t0);
1706}
1707
c364946d 1708static void spr_write_booke206_mmucsr0(DisasContext *ctx, int sprn, int gprn)
01662f3e 1709{
a721d390 1710 gen_helper_booke206_tlbflush(cpu_env, cpu_gpr[gprn]);
01662f3e
AG
1711}
1712
c364946d 1713static void spr_write_booke_pid(DisasContext *ctx, int sprn, int gprn)
01662f3e 1714{
1ff7854e 1715 TCGv_i32 t0 = tcg_const_i32(sprn);
c6c7cf05 1716 gen_helper_booke_setpid(cpu_env, t0, cpu_gpr[gprn]);
1ff7854e 1717 tcg_temp_free_i32(t0);
01662f3e 1718}
50728199
RK
1719static void spr_write_eplc(DisasContext *ctx, int sprn, int gprn)
1720{
1721 gen_helper_booke_set_eplc(cpu_env, cpu_gpr[gprn]);
1722}
1723static void spr_write_epsc(DisasContext *ctx, int sprn, int gprn)
1724{
1725 gen_helper_booke_set_epsc(cpu_env, cpu_gpr[gprn]);
1726}
1727
01662f3e
AG
1728#endif
1729
c364946d 1730static void gen_spr_usprg3(CPUPPCState *env)
b1c897d5
BK
1731{
1732 spr_register(env, SPR_USPRG3, "USPRG3",
1733 &spr_read_ureg, SPR_NOACCESS,
1734 &spr_read_ureg, SPR_NOACCESS,
1735 0x00000000);
1736}
1737
c364946d 1738static void gen_spr_usprgh(CPUPPCState *env)
76a66253 1739{
80d11f44
JM
1740 spr_register(env, SPR_USPRG4, "USPRG4",
1741 &spr_read_ureg, SPR_NOACCESS,
1742 &spr_read_ureg, SPR_NOACCESS,
1743 0x00000000);
1744 spr_register(env, SPR_USPRG5, "USPRG5",
1745 &spr_read_ureg, SPR_NOACCESS,
1746 &spr_read_ureg, SPR_NOACCESS,
1747 0x00000000);
1748 spr_register(env, SPR_USPRG6, "USPRG6",
1749 &spr_read_ureg, SPR_NOACCESS,
1750 &spr_read_ureg, SPR_NOACCESS,
1751 0x00000000);
1752 spr_register(env, SPR_USPRG7, "USPRG7",
1753 &spr_read_ureg, SPR_NOACCESS,
1754 &spr_read_ureg, SPR_NOACCESS,
76a66253 1755 0x00000000);
80d11f44
JM
1756}
1757
1758/* PowerPC BookE SPR */
c364946d 1759static void gen_spr_BookE(CPUPPCState *env, uint64_t ivor_mask)
80d11f44 1760{
b55266b5 1761 const char *ivor_names[64] = {
80d11f44
JM
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",
1778 };
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,
e9205258
AG
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,
80d11f44
JM
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,
1797 };
1798 int i;
1799
76a66253 1800 /* Interrupt processing */
363be49c 1801 spr_register(env, SPR_BOOKE_CSRR0, "CSRR0",
76a66253
JM
1802 SPR_NOACCESS, SPR_NOACCESS,
1803 &spr_read_generic, &spr_write_generic,
1804 0x00000000);
363be49c
JM
1805 spr_register(env, SPR_BOOKE_CSRR1, "CSRR1",
1806 SPR_NOACCESS, SPR_NOACCESS,
1807 &spr_read_generic, &spr_write_generic,
1808 0x00000000);
76a66253
JM
1809 /* Debug */
1810 /* XXX : not implemented */
1811 spr_register(env, SPR_BOOKE_IAC1, "IAC1",
1812 SPR_NOACCESS, SPR_NOACCESS,
1813 &spr_read_generic, &spr_write_generic,
1814 0x00000000);
1815 /* XXX : not implemented */
1816 spr_register(env, SPR_BOOKE_IAC2, "IAC2",
1817 SPR_NOACCESS, SPR_NOACCESS,
1818 &spr_read_generic, &spr_write_generic,
1819 0x00000000);
1820 /* XXX : not implemented */
76a66253
JM
1821 spr_register(env, SPR_BOOKE_DAC1, "DAC1",
1822 SPR_NOACCESS, SPR_NOACCESS,
1823 &spr_read_generic, &spr_write_generic,
1824 0x00000000);
1825 /* XXX : not implemented */
1826 spr_register(env, SPR_BOOKE_DAC2, "DAC2",
1827 SPR_NOACCESS, SPR_NOACCESS,
1828 &spr_read_generic, &spr_write_generic,
1829 0x00000000);
1830 /* XXX : not implemented */
76a66253
JM
1831 spr_register(env, SPR_BOOKE_DBCR0, "DBCR0",
1832 SPR_NOACCESS, SPR_NOACCESS,
e598a9c5 1833 &spr_read_generic, &spr_write_40x_dbcr0,
76a66253
JM
1834 0x00000000);
1835 /* XXX : not implemented */
1836 spr_register(env, SPR_BOOKE_DBCR1, "DBCR1",
1837 SPR_NOACCESS, SPR_NOACCESS,
1838 &spr_read_generic, &spr_write_generic,
1839 0x00000000);
1840 /* XXX : not implemented */
1841 spr_register(env, SPR_BOOKE_DBCR2, "DBCR2",
1842 SPR_NOACCESS, SPR_NOACCESS,
1843 &spr_read_generic, &spr_write_generic,
1844 0x00000000);
0e3bf489
RK
1845 spr_register(env, SPR_BOOKE_DSRR0, "DSRR0",
1846 SPR_NOACCESS, SPR_NOACCESS,
1847 &spr_read_generic, &spr_write_generic,
1848 0x00000000);
1849 spr_register(env, SPR_BOOKE_DSRR1, "DSRR1",
1850 SPR_NOACCESS, SPR_NOACCESS,
1851 &spr_read_generic, &spr_write_generic,
1852 0x00000000);
76a66253
JM
1853 /* XXX : not implemented */
1854 spr_register(env, SPR_BOOKE_DBSR, "DBSR",
1855 SPR_NOACCESS, SPR_NOACCESS,
8ecc7913 1856 &spr_read_generic, &spr_write_clear,
76a66253
JM
1857 0x00000000);
1858 spr_register(env, SPR_BOOKE_DEAR, "DEAR",
1859 SPR_NOACCESS, SPR_NOACCESS,
1860 &spr_read_generic, &spr_write_generic,
1861 0x00000000);
1862 spr_register(env, SPR_BOOKE_ESR, "ESR",
1863 SPR_NOACCESS, SPR_NOACCESS,
1864 &spr_read_generic, &spr_write_generic,
1865 0x00000000);
363be49c
JM
1866 spr_register(env, SPR_BOOKE_IVPR, "IVPR",
1867 SPR_NOACCESS, SPR_NOACCESS,
6f5d427d 1868 &spr_read_generic, &spr_write_excp_prefix,
363be49c
JM
1869 0x00000000);
1870 /* Exception vectors */
80d11f44
JM
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);
1875 exit(1);
1876 }
1877 spr_register(env, ivor_sprn[i], ivor_names[i],
1878 SPR_NOACCESS, SPR_NOACCESS,
1879 &spr_read_generic, &spr_write_excp_vector,
1880 0x00000000);
1881 }
1882 }
76a66253
JM
1883 spr_register(env, SPR_BOOKE_PID, "PID",
1884 SPR_NOACCESS, SPR_NOACCESS,
01662f3e 1885 &spr_read_generic, &spr_write_booke_pid,
76a66253
JM
1886 0x00000000);
1887 spr_register(env, SPR_BOOKE_TCR, "TCR",
1888 SPR_NOACCESS, SPR_NOACCESS,
1889 &spr_read_generic, &spr_write_booke_tcr,
1890 0x00000000);
1891 spr_register(env, SPR_BOOKE_TSR, "TSR",
1892 SPR_NOACCESS, SPR_NOACCESS,
1893 &spr_read_generic, &spr_write_booke_tsr,
1894 0x00000000);
1895 /* Timer */
1896 spr_register(env, SPR_DECR, "DECR",
1897 SPR_NOACCESS, SPR_NOACCESS,
1898 &spr_read_decr, &spr_write_decr,
1899 0x00000000);
1900 spr_register(env, SPR_BOOKE_DECAR, "DECAR",
1901 SPR_NOACCESS, SPR_NOACCESS,
1902 SPR_NOACCESS, &spr_write_generic,
1903 0x00000000);
1904 /* SPRGs */
1905 spr_register(env, SPR_USPRG0, "USPRG0",
1906 &spr_read_generic, &spr_write_generic,
1907 &spr_read_generic, &spr_write_generic,
1908 0x00000000);
1909 spr_register(env, SPR_SPRG4, "SPRG4",
1910 SPR_NOACCESS, SPR_NOACCESS,
1911 &spr_read_generic, &spr_write_generic,
1912 0x00000000);
76a66253
JM
1913 spr_register(env, SPR_SPRG5, "SPRG5",
1914 SPR_NOACCESS, SPR_NOACCESS,
1915 &spr_read_generic, &spr_write_generic,
1916 0x00000000);
76a66253
JM
1917 spr_register(env, SPR_SPRG6, "SPRG6",
1918 SPR_NOACCESS, SPR_NOACCESS,
1919 &spr_read_generic, &spr_write_generic,
1920 0x00000000);
76a66253
JM
1921 spr_register(env, SPR_SPRG7, "SPRG7",
1922 SPR_NOACCESS, SPR_NOACCESS,
1923 &spr_read_generic, &spr_write_generic,
1924 0x00000000);
0e3bf489
RK
1925 spr_register(env, SPR_BOOKE_SPRG8, "SPRG8",
1926 SPR_NOACCESS, SPR_NOACCESS,
1927 &spr_read_generic, &spr_write_generic,
1928 0x00000000);
1929 spr_register(env, SPR_BOOKE_SPRG9, "SPRG9",
1930 SPR_NOACCESS, SPR_NOACCESS,
1931 &spr_read_generic, &spr_write_generic,
1932 0x00000000);
76a66253
JM
1933}
1934
01662f3e
AG
1935static inline uint32_t gen_tlbncfg(uint32_t assoc, uint32_t minsize,
1936 uint32_t maxsize, uint32_t flags,
1937 uint32_t nentries)
1938{
1939 return (assoc << TLBnCFG_ASSOC_SHIFT) |
1940 (minsize << TLBnCFG_MINSIZE_SHIFT) |
1941 (maxsize << TLBnCFG_MAXSIZE_SHIFT) |
1942 flags | nentries;
1943}
1944
1945/* BookE 2.06 storage control registers */
1946static void gen_spr_BookE206(CPUPPCState *env, uint32_t mas_mask,
d21ee633 1947 uint32_t *tlbncfg, uint32_t mmucfg)
363be49c 1948{
f2e63a42 1949#if !defined(CONFIG_USER_ONLY)
b55266b5 1950 const char *mas_names[8] = {
80d11f44
JM
1951 "MAS0", "MAS1", "MAS2", "MAS3", "MAS4", "MAS5", "MAS6", "MAS7",
1952 };
1953 int mas_sprn[8] = {
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,
1956 };
1957 int i;
1958
363be49c 1959 /* TLB assist registers */
578bb252 1960 /* XXX : not implemented */
80d11f44 1961 for (i = 0; i < 8; i++) {
1d28b5f6
DG
1962 void (*uea_write)(DisasContext *ctx, int sprn, int gprn) =
1963 &spr_write_generic32;
ba38ab8d
AG
1964 if (i == 2 && (mas_mask & (1 << i)) && (env->insns_flags & PPC_64B)) {
1965 uea_write = &spr_write_generic;
1966 }
80d11f44
JM
1967 if (mas_mask & (1 << i)) {
1968 spr_register(env, mas_sprn[i], mas_names[i],
1969 SPR_NOACCESS, SPR_NOACCESS,
ba38ab8d 1970 &spr_read_generic, uea_write,
80d11f44
JM
1971 0x00000000);
1972 }
1973 }
363be49c 1974 if (env->nb_pids > 1) {
578bb252 1975 /* XXX : not implemented */
363be49c
JM
1976 spr_register(env, SPR_BOOKE_PID1, "PID1",
1977 SPR_NOACCESS, SPR_NOACCESS,
01662f3e 1978 &spr_read_generic, &spr_write_booke_pid,
363be49c
JM
1979 0x00000000);
1980 }
1981 if (env->nb_pids > 2) {
578bb252 1982 /* XXX : not implemented */
363be49c
JM
1983 spr_register(env, SPR_BOOKE_PID2, "PID2",
1984 SPR_NOACCESS, SPR_NOACCESS,
01662f3e 1985 &spr_read_generic, &spr_write_booke_pid,
363be49c
JM
1986 0x00000000);
1987 }
50728199
RK
1988
1989 spr_register(env, SPR_BOOKE_EPLC, "EPLC",
1990 SPR_NOACCESS, SPR_NOACCESS,
1991 &spr_read_generic, &spr_write_eplc,
1992 0x00000000);
1993 spr_register(env, SPR_BOOKE_EPSC, "EPSC",
1994 SPR_NOACCESS, SPR_NOACCESS,
1995 &spr_read_generic, &spr_write_epsc,
1996 0x00000000);
1997
578bb252 1998 /* XXX : not implemented */
65f9ee8d 1999 spr_register(env, SPR_MMUCFG, "MMUCFG",
363be49c
JM
2000 SPR_NOACCESS, SPR_NOACCESS,
2001 &spr_read_generic, SPR_NOACCESS,
d21ee633 2002 mmucfg);
363be49c
JM
2003 switch (env->nb_ways) {
2004 case 4:
2005 spr_register(env, SPR_BOOKE_TLB3CFG, "TLB3CFG",
2006 SPR_NOACCESS, SPR_NOACCESS,
2007 &spr_read_generic, SPR_NOACCESS,
01662f3e 2008 tlbncfg[3]);
363be49c
JM
2009 /* Fallthru */
2010 case 3:
2011 spr_register(env, SPR_BOOKE_TLB2CFG, "TLB2CFG",
2012 SPR_NOACCESS, SPR_NOACCESS,
2013 &spr_read_generic, SPR_NOACCESS,
01662f3e 2014 tlbncfg[2]);
363be49c
JM
2015 /* Fallthru */
2016 case 2:
2017 spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG",
2018 SPR_NOACCESS, SPR_NOACCESS,
2019 &spr_read_generic, SPR_NOACCESS,
01662f3e 2020 tlbncfg[1]);
363be49c
JM
2021 /* Fallthru */
2022 case 1:
2023 spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG",
2024 SPR_NOACCESS, SPR_NOACCESS,
2025 &spr_read_generic, SPR_NOACCESS,
01662f3e 2026 tlbncfg[0]);
363be49c
JM
2027 /* Fallthru */
2028 case 0:
2029 default:
2030 break;
2031 }
f2e63a42 2032#endif
01662f3e
AG
2033
2034 gen_spr_usprgh(env);
363be49c
JM
2035}
2036
76a66253 2037/* SPR specific to PowerPC 440 implementation */
c364946d 2038static void gen_spr_440(CPUPPCState *env)
76a66253
JM
2039{
2040 /* Cache control */
2041 /* XXX : not implemented */
2042 spr_register(env, SPR_440_DNV0, "DNV0",
2043 SPR_NOACCESS, SPR_NOACCESS,
2044 &spr_read_generic, &spr_write_generic,
2045 0x00000000);
2046 /* XXX : not implemented */
2047 spr_register(env, SPR_440_DNV1, "DNV1",
2048 SPR_NOACCESS, SPR_NOACCESS,
2049 &spr_read_generic, &spr_write_generic,
2050 0x00000000);
2051 /* XXX : not implemented */
2052 spr_register(env, SPR_440_DNV2, "DNV2",
2053 SPR_NOACCESS, SPR_NOACCESS,
2054 &spr_read_generic, &spr_write_generic,
2055 0x00000000);
2056 /* XXX : not implemented */
2057 spr_register(env, SPR_440_DNV3, "DNV3",
2058 SPR_NOACCESS, SPR_NOACCESS,
2059 &spr_read_generic, &spr_write_generic,
2060 0x00000000);
2061 /* XXX : not implemented */
2662a059 2062 spr_register(env, SPR_440_DTV0, "DTV0",
76a66253
JM
2063 SPR_NOACCESS, SPR_NOACCESS,
2064 &spr_read_generic, &spr_write_generic,
2065 0x00000000);
2066 /* XXX : not implemented */
2662a059 2067 spr_register(env, SPR_440_DTV1, "DTV1",
76a66253
JM
2068 SPR_NOACCESS, SPR_NOACCESS,
2069 &spr_read_generic, &spr_write_generic,
2070 0x00000000);
2071 /* XXX : not implemented */
2662a059 2072 spr_register(env, SPR_440_DTV2, "DTV2",
76a66253
JM
2073 SPR_NOACCESS, SPR_NOACCESS,
2074 &spr_read_generic, &spr_write_generic,
2075 0x00000000);
2076 /* XXX : not implemented */
2662a059 2077 spr_register(env, SPR_440_DTV3, "DTV3",
76a66253
JM
2078 SPR_NOACCESS, SPR_NOACCESS,
2079 &spr_read_generic, &spr_write_generic,
2080 0x00000000);
2081 /* XXX : not implemented */
2082 spr_register(env, SPR_440_DVLIM, "DVLIM",
2083 SPR_NOACCESS, SPR_NOACCESS,
2084 &spr_read_generic, &spr_write_generic,
2085 0x00000000);
2086 /* XXX : not implemented */
2087 spr_register(env, SPR_440_INV0, "INV0",
2088 SPR_NOACCESS, SPR_NOACCESS,
2089 &spr_read_generic, &spr_write_generic,
2090 0x00000000);
2091 /* XXX : not implemented */
2092 spr_register(env, SPR_440_INV1, "INV1",
2093 SPR_NOACCESS, SPR_NOACCESS,
2094 &spr_read_generic, &spr_write_generic,
2095 0x00000000);
2096 /* XXX : not implemented */
2097 spr_register(env, SPR_440_INV2, "INV2",
2098 SPR_NOACCESS, SPR_NOACCESS,
2099 &spr_read_generic, &spr_write_generic,
2100 0x00000000);
2101 /* XXX : not implemented */
2102 spr_register(env, SPR_440_INV3, "INV3",
2103 SPR_NOACCESS, SPR_NOACCESS,
2104 &spr_read_generic, &spr_write_generic,
2105 0x00000000);
2106 /* XXX : not implemented */
2662a059 2107 spr_register(env, SPR_440_ITV0, "ITV0",
76a66253
JM
2108 SPR_NOACCESS, SPR_NOACCESS,
2109 &spr_read_generic, &spr_write_generic,
2110 0x00000000);
2111 /* XXX : not implemented */
2662a059 2112 spr_register(env, SPR_440_ITV1, "ITV1",
76a66253
JM
2113 SPR_NOACCESS, SPR_NOACCESS,
2114 &spr_read_generic, &spr_write_generic,
2115 0x00000000);
2116 /* XXX : not implemented */
2662a059 2117 spr_register(env, SPR_440_ITV2, "ITV2",
76a66253
JM
2118 SPR_NOACCESS, SPR_NOACCESS,
2119 &spr_read_generic, &spr_write_generic,
2120 0x00000000);
2121 /* XXX : not implemented */
2662a059 2122 spr_register(env, SPR_440_ITV3, "ITV3",
76a66253
JM
2123 SPR_NOACCESS, SPR_NOACCESS,
2124 &spr_read_generic, &spr_write_generic,
2125 0x00000000);
2126 /* XXX : not implemented */
2127 spr_register(env, SPR_440_IVLIM, "IVLIM",
2128 SPR_NOACCESS, SPR_NOACCESS,
2129 &spr_read_generic, &spr_write_generic,
2130 0x00000000);
2131 /* Cache debug */
2132 /* XXX : not implemented */
2662a059 2133 spr_register(env, SPR_BOOKE_DCDBTRH, "DCDBTRH",
76a66253
JM
2134 SPR_NOACCESS, SPR_NOACCESS,
2135 &spr_read_generic, SPR_NOACCESS,
2136 0x00000000);
2137 /* XXX : not implemented */
2662a059 2138 spr_register(env, SPR_BOOKE_DCDBTRL, "DCDBTRL",
76a66253
JM
2139 SPR_NOACCESS, SPR_NOACCESS,
2140 &spr_read_generic, SPR_NOACCESS,
2141 0x00000000);
2142 /* XXX : not implemented */
2662a059 2143 spr_register(env, SPR_BOOKE_ICDBDR, "ICDBDR",
76a66253
JM
2144 SPR_NOACCESS, SPR_NOACCESS,
2145 &spr_read_generic, SPR_NOACCESS,
2146 0x00000000);
2147 /* XXX : not implemented */
2662a059 2148 spr_register(env, SPR_BOOKE_ICDBTRH, "ICDBTRH",
76a66253
JM
2149 SPR_NOACCESS, SPR_NOACCESS,
2150 &spr_read_generic, SPR_NOACCESS,
2151 0x00000000);
2152 /* XXX : not implemented */
2662a059 2153 spr_register(env, SPR_BOOKE_ICDBTRL, "ICDBTRL",
76a66253
JM
2154 SPR_NOACCESS, SPR_NOACCESS,
2155 &spr_read_generic, SPR_NOACCESS,
2156 0x00000000);
2157 /* XXX : not implemented */
2158 spr_register(env, SPR_440_DBDR, "DBDR",
2159 SPR_NOACCESS, SPR_NOACCESS,
2160 &spr_read_generic, &spr_write_generic,
2161 0x00000000);
2162 /* Processor control */
2163 spr_register(env, SPR_4xx_CCR0, "CCR0",
2164 SPR_NOACCESS, SPR_NOACCESS,
2165 &spr_read_generic, &spr_write_generic,
2166 0x00000000);
2167 spr_register(env, SPR_440_RSTCFG, "RSTCFG",
2168 SPR_NOACCESS, SPR_NOACCESS,
2169 &spr_read_generic, SPR_NOACCESS,
2170 0x00000000);
2171 /* Storage control */
2172 spr_register(env, SPR_440_MMUCR, "MMUCR",
2173 SPR_NOACCESS, SPR_NOACCESS,
2174 &spr_read_generic, &spr_write_generic,
2175 0x00000000);
2176}
2177
2178/* SPR shared between PowerPC 40x implementations */
c364946d 2179static void gen_spr_40x(CPUPPCState *env)
76a66253
JM
2180{
2181 /* Cache */
5cbdb3a3 2182 /* not emulated, as QEMU do not emulate caches */
76a66253
JM
2183 spr_register(env, SPR_40x_DCCR, "DCCR",
2184 SPR_NOACCESS, SPR_NOACCESS,
2185 &spr_read_generic, &spr_write_generic,
2186 0x00000000);
5cbdb3a3 2187 /* not emulated, as QEMU do not emulate caches */
76a66253
JM
2188 spr_register(env, SPR_40x_ICCR, "ICCR",
2189 SPR_NOACCESS, SPR_NOACCESS,
2190 &spr_read_generic, &spr_write_generic,
2191 0x00000000);
5cbdb3a3 2192 /* not emulated, as QEMU do not emulate caches */
2662a059 2193 spr_register(env, SPR_BOOKE_ICDBDR, "ICDBDR",
76a66253
JM
2194 SPR_NOACCESS, SPR_NOACCESS,
2195 &spr_read_generic, SPR_NOACCESS,
2196 0x00000000);
76a66253
JM
2197 /* Exception */
2198 spr_register(env, SPR_40x_DEAR, "DEAR",
2199 SPR_NOACCESS, SPR_NOACCESS,
2200 &spr_read_generic, &spr_write_generic,
2201 0x00000000);
2202 spr_register(env, SPR_40x_ESR, "ESR",
2203 SPR_NOACCESS, SPR_NOACCESS,
2204 &spr_read_generic, &spr_write_generic,
2205 0x00000000);
2206 spr_register(env, SPR_40x_EVPR, "EVPR",
2207 SPR_NOACCESS, SPR_NOACCESS,
6f5d427d 2208 &spr_read_generic, &spr_write_excp_prefix,
76a66253
JM
2209 0x00000000);
2210 spr_register(env, SPR_40x_SRR2, "SRR2",
2211 &spr_read_generic, &spr_write_generic,
2212 &spr_read_generic, &spr_write_generic,
2213 0x00000000);
2214 spr_register(env, SPR_40x_SRR3, "SRR3",
2215 &spr_read_generic, &spr_write_generic,
2216 &spr_read_generic, &spr_write_generic,
2217 0x00000000);
2218 /* Timers */
2219 spr_register(env, SPR_40x_PIT, "PIT",
2220 SPR_NOACCESS, SPR_NOACCESS,
2221 &spr_read_40x_pit, &spr_write_40x_pit,
2222 0x00000000);
2223 spr_register(env, SPR_40x_TCR, "TCR",
2224 SPR_NOACCESS, SPR_NOACCESS,
2225 &spr_read_generic, &spr_write_booke_tcr,
2226 0x00000000);
2227 spr_register(env, SPR_40x_TSR, "TSR",
2228 SPR_NOACCESS, SPR_NOACCESS,
2229 &spr_read_generic, &spr_write_booke_tsr,
2230 0x00000000);
2662a059
JM
2231}
2232
2233/* SPR specific to PowerPC 405 implementation */
c364946d 2234static void gen_spr_405(CPUPPCState *env)
2662a059
JM
2235{
2236 /* MMU */
2237 spr_register(env, SPR_40x_PID, "PID",
76a66253
JM
2238 SPR_NOACCESS, SPR_NOACCESS,
2239 &spr_read_generic, &spr_write_generic,
2240 0x00000000);
2662a059 2241 spr_register(env, SPR_4xx_CCR0, "CCR0",
76a66253
JM
2242 SPR_NOACCESS, SPR_NOACCESS,
2243 &spr_read_generic, &spr_write_generic,
2662a059
JM
2244 0x00700000);
2245 /* Debug interface */
76a66253
JM
2246 /* XXX : not implemented */
2247 spr_register(env, SPR_40x_DBCR0, "DBCR0",
2248 SPR_NOACCESS, SPR_NOACCESS,
8ecc7913 2249 &spr_read_generic, &spr_write_40x_dbcr0,
76a66253
JM
2250 0x00000000);
2251 /* XXX : not implemented */
2662a059
JM
2252 spr_register(env, SPR_405_DBCR1, "DBCR1",
2253 SPR_NOACCESS, SPR_NOACCESS,
2254 &spr_read_generic, &spr_write_generic,
2255 0x00000000);
2256 /* XXX : not implemented */
76a66253
JM
2257 spr_register(env, SPR_40x_DBSR, "DBSR",
2258 SPR_NOACCESS, SPR_NOACCESS,
8ecc7913
JM
2259 &spr_read_generic, &spr_write_clear,
2260 /* Last reset was system reset */
76a66253
JM
2261 0x00000300);
2262 /* XXX : not implemented */
2662a059 2263 spr_register(env, SPR_40x_DAC1, "DAC1",
76a66253
JM
2264 SPR_NOACCESS, SPR_NOACCESS,
2265 &spr_read_generic, &spr_write_generic,
2266 0x00000000);
2662a059 2267 spr_register(env, SPR_40x_DAC2, "DAC2",
76a66253
JM
2268 SPR_NOACCESS, SPR_NOACCESS,
2269 &spr_read_generic, &spr_write_generic,
2270 0x00000000);
2662a059
JM
2271 /* XXX : not implemented */
2272 spr_register(env, SPR_405_DVC1, "DVC1",
76a66253
JM
2273 SPR_NOACCESS, SPR_NOACCESS,
2274 &spr_read_generic, &spr_write_generic,
2662a059 2275 0x00000000);
76a66253 2276 /* XXX : not implemented */
2662a059 2277 spr_register(env, SPR_405_DVC2, "DVC2",
76a66253
JM
2278 SPR_NOACCESS, SPR_NOACCESS,
2279 &spr_read_generic, &spr_write_generic,
2280 0x00000000);
2281 /* XXX : not implemented */
2662a059 2282 spr_register(env, SPR_40x_IAC1, "IAC1",
76a66253
JM
2283 SPR_NOACCESS, SPR_NOACCESS,
2284 &spr_read_generic, &spr_write_generic,
2285 0x00000000);
2662a059 2286 spr_register(env, SPR_40x_IAC2, "IAC2",
76a66253
JM
2287 SPR_NOACCESS, SPR_NOACCESS,
2288 &spr_read_generic, &spr_write_generic,
2289 0x00000000);
2290 /* XXX : not implemented */
2291 spr_register(env, SPR_405_IAC3, "IAC3",
2292 SPR_NOACCESS, SPR_NOACCESS,
2293 &spr_read_generic, &spr_write_generic,
2294 0x00000000);
2295 /* XXX : not implemented */
2296 spr_register(env, SPR_405_IAC4, "IAC4",
2297 SPR_NOACCESS, SPR_NOACCESS,
2298 &spr_read_generic, &spr_write_generic,
2299 0x00000000);
2300 /* Storage control */
035feb88 2301 /* XXX: TODO: not implemented */
76a66253
JM
2302 spr_register(env, SPR_405_SLER, "SLER",
2303 SPR_NOACCESS, SPR_NOACCESS,
c294fc58 2304 &spr_read_generic, &spr_write_40x_sler,
76a66253 2305 0x00000000);
2662a059
JM
2306 spr_register(env, SPR_40x_ZPR, "ZPR",
2307 SPR_NOACCESS, SPR_NOACCESS,
2308 &spr_read_generic, &spr_write_generic,
2309 0x00000000);
76a66253
JM
2310 /* XXX : not implemented */
2311 spr_register(env, SPR_405_SU0R, "SU0R",
2312 SPR_NOACCESS, SPR_NOACCESS,
2313 &spr_read_generic, &spr_write_generic,
2314 0x00000000);
2315 /* SPRG */
2316 spr_register(env, SPR_USPRG0, "USPRG0",
2317 &spr_read_ureg, SPR_NOACCESS,
2318 &spr_read_ureg, SPR_NOACCESS,
2319 0x00000000);
2320 spr_register(env, SPR_SPRG4, "SPRG4",
2321 SPR_NOACCESS, SPR_NOACCESS,
04f20795 2322 &spr_read_generic, &spr_write_generic,
76a66253 2323 0x00000000);
76a66253
JM
2324 spr_register(env, SPR_SPRG5, "SPRG5",
2325 SPR_NOACCESS, SPR_NOACCESS,
04f20795 2326 spr_read_generic, &spr_write_generic,
76a66253 2327 0x00000000);
76a66253
JM
2328 spr_register(env, SPR_SPRG6, "SPRG6",
2329 SPR_NOACCESS, SPR_NOACCESS,
04f20795 2330 spr_read_generic, &spr_write_generic,
76a66253 2331 0x00000000);
76a66253
JM
2332 spr_register(env, SPR_SPRG7, "SPRG7",
2333 SPR_NOACCESS, SPR_NOACCESS,
04f20795 2334 spr_read_generic, &spr_write_generic,
76a66253 2335 0x00000000);
80d11f44 2336 gen_spr_usprgh(env);
76a66253
JM
2337}
2338
2339/* SPR shared between PowerPC 401 & 403 implementations */
c364946d 2340static void gen_spr_401_403(CPUPPCState *env)
76a66253
JM
2341{
2342 /* Time base */
2343 spr_register(env, SPR_403_VTBL, "TBL",
2344 &spr_read_tbl, SPR_NOACCESS,
2345 &spr_read_tbl, SPR_NOACCESS,
2346 0x00000000);
2347 spr_register(env, SPR_403_TBL, "TBL",
2348 SPR_NOACCESS, SPR_NOACCESS,
2349 SPR_NOACCESS, &spr_write_tbl,
2350 0x00000000);
2351 spr_register(env, SPR_403_VTBU, "TBU",
2352 &spr_read_tbu, SPR_NOACCESS,
2353 &spr_read_tbu, SPR_NOACCESS,
2354 0x00000000);
2355 spr_register(env, SPR_403_TBU, "TBU",
2356 SPR_NOACCESS, SPR_NOACCESS,
2357 SPR_NOACCESS, &spr_write_tbu,
2358 0x00000000);
2359 /* Debug */
5cbdb3a3 2360 /* not emulated, as QEMU do not emulate caches */
76a66253
JM
2361 spr_register(env, SPR_403_CDBCR, "CDBCR",
2362 SPR_NOACCESS, SPR_NOACCESS,
2363 &spr_read_generic, &spr_write_generic,
2364 0x00000000);
2365}
2366
2662a059 2367/* SPR specific to PowerPC 401 implementation */
c364946d 2368static void gen_spr_401(CPUPPCState *env)
2662a059
JM
2369{
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,
2375 0x00000000);
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 */
2381 0x00000300);
2382 /* XXX : not implemented */
2383 spr_register(env, SPR_40x_DAC1, "DAC",
2384 SPR_NOACCESS, SPR_NOACCESS,
2385 &spr_read_generic, &spr_write_generic,
2386 0x00000000);
2387 /* XXX : not implemented */
2388 spr_register(env, SPR_40x_IAC1, "IAC",
2389 SPR_NOACCESS, SPR_NOACCESS,
2390 &spr_read_generic, &spr_write_generic,
2391 0x00000000);
2392 /* Storage control */
035feb88 2393 /* XXX: TODO: not implemented */
2662a059
JM
2394 spr_register(env, SPR_405_SLER, "SLER",
2395 SPR_NOACCESS, SPR_NOACCESS,
2396 &spr_read_generic, &spr_write_40x_sler,
2397 0x00000000);
5cbdb3a3 2398 /* not emulated, as QEMU never does speculative access */
035feb88
JM
2399 spr_register(env, SPR_40x_SGR, "SGR",
2400 SPR_NOACCESS, SPR_NOACCESS,
2401 &spr_read_generic, &spr_write_generic,
2402 0xFFFFFFFF);
5cbdb3a3 2403 /* not emulated, as QEMU do not emulate caches */
035feb88
JM
2404 spr_register(env, SPR_40x_DCWR, "DCWR",
2405 SPR_NOACCESS, SPR_NOACCESS,
2406 &spr_read_generic, &spr_write_generic,
2407 0x00000000);
2662a059
JM
2408}
2409
c364946d 2410static void gen_spr_401x2(CPUPPCState *env)
a750fc0b
JM
2411{
2412 gen_spr_401(env);
2413 spr_register(env, SPR_40x_PID, "PID",
2414 SPR_NOACCESS, SPR_NOACCESS,
2415 &spr_read_generic, &spr_write_generic,
2416 0x00000000);
2417 spr_register(env, SPR_40x_ZPR, "ZPR",
2418 SPR_NOACCESS, SPR_NOACCESS,
2419 &spr_read_generic, &spr_write_generic,
2420 0x00000000);
2421}
2422
76a66253 2423/* SPR specific to PowerPC 403 implementation */
c364946d 2424static void gen_spr_403(CPUPPCState *env)
76a66253 2425{
2662a059
JM
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,
2431 0x00000000);
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 */
2437 0x00000300);
2438 /* XXX : not implemented */
2439 spr_register(env, SPR_40x_DAC1, "DAC1",
2440 SPR_NOACCESS, SPR_NOACCESS,
2441 &spr_read_generic, &spr_write_generic,
2442 0x00000000);
578bb252 2443 /* XXX : not implemented */
2662a059
JM
2444 spr_register(env, SPR_40x_DAC2, "DAC2",
2445 SPR_NOACCESS, SPR_NOACCESS,
2446 &spr_read_generic, &spr_write_generic,
2447 0x00000000);
2448 /* XXX : not implemented */
2449 spr_register(env, SPR_40x_IAC1, "IAC1",
2450 SPR_NOACCESS, SPR_NOACCESS,
2451 &spr_read_generic, &spr_write_generic,
2452 0x00000000);
578bb252 2453 /* XXX : not implemented */
2662a059
JM
2454 spr_register(env, SPR_40x_IAC2, "IAC2",
2455 SPR_NOACCESS, SPR_NOACCESS,
2456 &spr_read_generic, &spr_write_generic,
2457 0x00000000);
a750fc0b
JM
2458}
2459
c364946d 2460static void gen_spr_403_real(CPUPPCState *env)
a750fc0b 2461{
76a66253
JM
2462 spr_register(env, SPR_403_PBL1, "PBL1",
2463 SPR_NOACCESS, SPR_NOACCESS,
2464 &spr_read_403_pbr, &spr_write_403_pbr,
2465 0x00000000);
2466 spr_register(env, SPR_403_PBU1, "PBU1",
2467 SPR_NOACCESS, SPR_NOACCESS,
2468 &spr_read_403_pbr, &spr_write_403_pbr,
2469 0x00000000);
2470 spr_register(env, SPR_403_PBL2, "PBL2",
2471 SPR_NOACCESS, SPR_NOACCESS,
2472 &spr_read_403_pbr, &spr_write_403_pbr,
2473 0x00000000);
2474 spr_register(env, SPR_403_PBU2, "PBU2",
2475 SPR_NOACCESS, SPR_NOACCESS,
2476 &spr_read_403_pbr, &spr_write_403_pbr,
2477 0x00000000);
a750fc0b
JM
2478}
2479
c364946d 2480static void gen_spr_403_mmu(CPUPPCState *env)
a750fc0b
JM
2481{
2482 /* MMU */
2483 spr_register(env, SPR_40x_PID, "PID",
2484 SPR_NOACCESS, SPR_NOACCESS,
2485 &spr_read_generic, &spr_write_generic,
2486 0x00000000);
2662a059 2487 spr_register(env, SPR_40x_ZPR, "ZPR",
76a66253
JM
2488 SPR_NOACCESS, SPR_NOACCESS,
2489 &spr_read_generic, &spr_write_generic,
2490 0x00000000);
2491}
2492
2493/* SPR specific to PowerPC compression coprocessor extension */
c364946d 2494static void gen_spr_compress(CPUPPCState *env)
76a66253 2495{
578bb252 2496 /* XXX : not implemented */
76a66253
JM
2497 spr_register(env, SPR_401_SKR, "SKR",
2498 SPR_NOACCESS, SPR_NOACCESS,
2499 &spr_read_generic, &spr_write_generic,
2500 0x00000000);
2501}
a750fc0b 2502
c364946d 2503static void gen_spr_5xx_8xx(CPUPPCState *env)
e1833e1f 2504{
80d11f44 2505 /* Exception processing */
d67d40ea
DG
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);
80d11f44
JM
2514 /* Timer */
2515 spr_register(env, SPR_DECR, "DECR",
2516 SPR_NOACCESS, SPR_NOACCESS,
2517 &spr_read_decr, &spr_write_decr,
2518 0x00000000);
2519 /* XXX : not implemented */
2520 spr_register(env, SPR_MPC_EIE, "EIE",
2521 SPR_NOACCESS, SPR_NOACCESS,
2522 &spr_read_generic, &spr_write_generic,
2523 0x00000000);
2524 /* XXX : not implemented */
2525 spr_register(env, SPR_MPC_EID, "EID",
2526 SPR_NOACCESS, SPR_NOACCESS,
2527 &spr_read_generic, &spr_write_generic,
2528 0x00000000);
2529 /* XXX : not implemented */
2530 spr_register(env, SPR_MPC_NRI, "NRI",
2531 SPR_NOACCESS, SPR_NOACCESS,
2532 &spr_read_generic, &spr_write_generic,
2533 0x00000000);
2534 /* XXX : not implemented */
2535 spr_register(env, SPR_MPC_CMPA, "CMPA",
2536 SPR_NOACCESS, SPR_NOACCESS,
2537 &spr_read_generic, &spr_write_generic,
2538 0x00000000);
2539 /* XXX : not implemented */
2540 spr_register(env, SPR_MPC_CMPB, "CMPB",
2541 SPR_NOACCESS, SPR_NOACCESS,
2542 &spr_read_generic, &spr_write_generic,
2543 0x00000000);
2544 /* XXX : not implemented */
2545 spr_register(env, SPR_MPC_CMPC, "CMPC",
2546 SPR_NOACCESS, SPR_NOACCESS,
2547 &spr_read_generic, &spr_write_generic,
2548 0x00000000);
2549 /* XXX : not implemented */
2550 spr_register(env, SPR_MPC_CMPD, "CMPD",
2551 SPR_NOACCESS, SPR_NOACCESS,
2552 &spr_read_generic, &spr_write_generic,
2553 0x00000000);
2554 /* XXX : not implemented */
2555 spr_register(env, SPR_MPC_ECR, "ECR",
2556 SPR_NOACCESS, SPR_NOACCESS,
2557 &spr_read_generic, &spr_write_generic,
2558 0x00000000);
2559 /* XXX : not implemented */
2560 spr_register(env, SPR_MPC_DER, "DER",
2561 SPR_NOACCESS, SPR_NOACCESS,
2562 &spr_read_generic, &spr_write_generic,
2563 0x00000000);
2564 /* XXX : not implemented */
2565 spr_register(env, SPR_MPC_COUNTA, "COUNTA",
2566 SPR_NOACCESS, SPR_NOACCESS,
2567 &spr_read_generic, &spr_write_generic,
2568 0x00000000);
2569 /* XXX : not implemented */
2570 spr_register(env, SPR_MPC_COUNTB, "COUNTB",
2571 SPR_NOACCESS, SPR_NOACCESS,
2572 &spr_read_generic, &spr_write_generic,
2573 0x00000000);
2574 /* XXX : not implemented */
2575 spr_register(env, SPR_MPC_CMPE, "CMPE",
2576 SPR_NOACCESS, SPR_NOACCESS,
2577 &spr_read_generic, &spr_write_generic,
2578 0x00000000);
2579 /* XXX : not implemented */
2580 spr_register(env, SPR_MPC_CMPF, "CMPF",
2581 SPR_NOACCESS, SPR_NOACCESS,
2582 &spr_read_generic, &spr_write_generic,
2583 0x00000000);
2584 /* XXX : not implemented */
2585 spr_register(env, SPR_MPC_CMPG, "CMPG",
2586 SPR_NOACCESS, SPR_NOACCESS,
2587 &spr_read_generic, &spr_write_generic,
2588 0x00000000);
2589 /* XXX : not implemented */
2590 spr_register(env, SPR_MPC_CMPH, "CMPH",
2591 SPR_NOACCESS, SPR_NOACCESS,
2592 &spr_read_generic, &spr_write_generic,
2593 0x00000000);
2594 /* XXX : not implemented */
2595 spr_register(env, SPR_MPC_LCTRL1, "LCTRL1",
2596 SPR_NOACCESS, SPR_NOACCESS,
2597 &spr_read_generic, &spr_write_generic,
2598 0x00000000);
2599 /* XXX : not implemented */
2600 spr_register(env, SPR_MPC_LCTRL2, "LCTRL2",
2601 SPR_NOACCESS, SPR_NOACCESS,
2602 &spr_read_generic, &spr_write_generic,
2603 0x00000000);
2604 /* XXX : not implemented */
2605 spr_register(env, SPR_MPC_BAR, "BAR",
2606 SPR_NOACCESS, SPR_NOACCESS,
2607 &spr_read_generic, &spr_write_generic,
2608 0x00000000);
2609 /* XXX : not implemented */
2610 spr_register(env, SPR_MPC_DPDR, "DPDR",
2611 SPR_NOACCESS, SPR_NOACCESS,
2612 &spr_read_generic, &spr_write_generic,
2613 0x00000000);
2614 /* XXX : not implemented */
2615 spr_register(env, SPR_MPC_IMMR, "IMMR",
2616 SPR_NOACCESS, SPR_NOACCESS,
2617 &spr_read_generic, &spr_write_generic,
2618 0x00000000);
2619}
2620
c364946d 2621static void gen_spr_5xx(CPUPPCState *env)
80d11f44
JM
2622{
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,
2627 0x00000000);
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,
2632 0x00000000);
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,
2637 0x00000000);
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,
2642 0x00000000);
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,
2647 0x00000000);
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,
2652 0x00000000);
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,
2657 0x00000000);
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,
2662 0x00000000);
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,
2667 0x00000000);
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,
2672 0x00000000);
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,
2677 0x00000000);
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,
2682 0x00000000);
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,
2687 0x00000000);
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,
2692 0x00000000);
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,
2697 0x00000000);
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,
2702 0x00000000);
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,
2707 0x00000000);
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,
2712 0x00000000);
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,
2717 0x00000000);
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,
2722 0x00000000);
2723 /* XXX : not implemented */
2724 spr_register(env, SPR_RCPU_FPECR, "FPECR",
2725 SPR_NOACCESS, SPR_NOACCESS,
2726 &spr_read_generic, &spr_write_generic,
2727 0x00000000);
2728}
2729
c364946d 2730static void gen_spr_8xx(CPUPPCState *env)
80d11f44
JM
2731{
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,
2736 0x00000000);
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,
2741 0x00000000);
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,
2746 0x00000000);
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,
2751 0x00000000);
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,
2756 0x00000000);
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,
2761 0x00000000);
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,
2766 0x00000000);
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,
2771 0x00000000);
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,
2776 0x00000000);
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,
2781 0x00000000);
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,
2786 0x00000000);
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,
2791 0x00000000);
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,
2796 0x00000000);
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,
2801 0x00000000);
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,
2806 0x00000000);
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,
2811 0x00000000);
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,
2816 0x00000000);
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,
2821 0x00000000);
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,
2826 0x00000000);
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,
2831 0x00000000);
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,
2836 0x00000000);
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,
2841 0x00000000);
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,
2846 0x00000000);
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,
2851 0x00000000);
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,
2856 0x00000000);
2857}
2858
80d11f44
JM
2859/*
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)
80d11f44 2877 * LPIDR => SPR 317 (970)
80d11f44
JM
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)
80d11f44
JM
2882 * DABRX => 1015 (Power 2.04 hypv)
2883 * FPECR => SPR 1022 (?)
2884 * ... and more (thermal management, performance counters, ...)
2885 */
2886
2887/*****************************************************************************/
2888/* Exception vectors models */
c364946d 2889static void init_excp_4xx_real(CPUPPCState *env)
80d11f44
JM
2890{
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;
80d11f44 2902 env->ivor_mask = 0x0000FFF0UL;
faadf50e 2903 env->ivpr_mask = 0xFFFF0000UL;
1c27f8fb
JM
2904 /* Hardware reset vector */
2905 env->hreset_vector = 0xFFFFFFFCUL;
e1833e1f
JM
2906#endif
2907}
2908
c364946d 2909static void init_excp_4xx_softmmu(CPUPPCState *env)
80d11f44
JM
2910{
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;
80d11f44
JM
2926 env->ivor_mask = 0x0000FFF0UL;
2927 env->ivpr_mask = 0xFFFF0000UL;
2928 /* Hardware reset vector */
2929 env->hreset_vector = 0xFFFFFFFCUL;
2930#endif
2931}
2932
c364946d 2933static void init_excp_MPC5xx(CPUPPCState *env)
80d11f44
JM
2934{
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;
80d11f44
JM
2951 env->ivor_mask = 0x0000FFF0UL;
2952 env->ivpr_mask = 0xFFFF0000UL;
2953 /* Hardware reset vector */
09d9828a 2954 env->hreset_vector = 0x00000100UL;
80d11f44
JM
2955#endif
2956}
2957
c364946d 2958static void init_excp_MPC8xx(CPUPPCState *env)
e1833e1f
JM
2959{
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;
80d11f44 2968 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000900;
e1833e1f 2969 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
e1833e1f 2970 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
80d11f44
JM
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;
80d11f44
JM
2982 env->ivor_mask = 0x0000FFF0UL;
2983 env->ivpr_mask = 0xFFFF0000UL;
1c27f8fb 2984 /* Hardware reset vector */
09d9828a 2985 env->hreset_vector = 0x00000100UL;
e1833e1f
JM
2986#endif
2987}
2988
c364946d 2989static void init_excp_G2(CPUPPCState *env)
e1833e1f
JM
2990{
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;
80d11f44 3001 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000A00;
e1833e1f
JM
3002 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3003 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
e1833e1f
JM
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;
80d11f44 3009 /* Hardware reset vector */
09d9828a 3010 env->hreset_vector = 0x00000100UL;
80d11f44
JM
3011#endif
3012}
3013
e9cd84b9 3014static void init_excp_e200(CPUPPCState *env, target_ulong ivpr_mask)
80d11f44
JM
3015{
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;
80d11f44 3037 env->ivor_mask = 0x0000FFF7UL;
e9cd84b9 3038 env->ivpr_mask = ivpr_mask;
80d11f44
JM
3039 /* Hardware reset vector */
3040 env->hreset_vector = 0xFFFFFFFCUL;
3041#endif
3042}
3043
c364946d 3044static void init_excp_BookE(CPUPPCState *env)
80d11f44
JM
3045{
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;
8412d112 3063 env->ivor_mask = 0x0000FFF0UL;
80d11f44
JM
3064 env->ivpr_mask = 0xFFFF0000UL;
3065 /* Hardware reset vector */
3066 env->hreset_vector = 0xFFFFFFFCUL;
3067#endif
3068}
3069
c364946d 3070static void init_excp_601(CPUPPCState *env)
80d11f44
JM
3071{
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;
1c27f8fb 3085 /* Hardware reset vector */
80d11f44 3086 env->hreset_vector = 0x00000100UL;
e1833e1f
JM
3087#endif
3088}
3089
c364946d 3090static void init_excp_602(CPUPPCState *env)
e1833e1f
JM
3091{
3092#if !defined(CONFIG_USER_ONLY)
082c6681 3093 /* XXX: exception prefix has a special behavior on 602 */
e1833e1f
JM
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;
80d11f44
JM
3110 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001500;
3111 env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001600;
1c27f8fb 3112 /* Hardware reset vector */
09d9828a 3113 env->hreset_vector = 0x00000100UL;
e1833e1f
JM
3114#endif
3115}
3116
c364946d 3117static void init_excp_603(CPUPPCState *env)
e1833e1f
JM
3118{
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;
e1833e1f
JM
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;
1c27f8fb 3136 /* Hardware reset vector */
09d9828a 3137 env->hreset_vector = 0x00000100UL;
e1833e1f
JM
3138#endif
3139}
3140
c364946d 3141static void init_excp_604(CPUPPCState *env)
e1833e1f
JM
3142{
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;
1c27f8fb 3158 /* Hardware reset vector */
2d3eb7bf 3159 env->hreset_vector = 0x00000100UL;
e1833e1f
JM
3160#endif
3161}
3162
c364946d 3163static void init_excp_7x0(CPUPPCState *env)
e1833e1f
JM
3164{
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;
bd928eba 3179 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
e1833e1f 3180 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
1c27f8fb 3181 /* Hardware reset vector */
09d9828a 3182 env->hreset_vector = 0x00000100UL;
e1833e1f
JM
3183#endif
3184}
3185
c364946d 3186static void init_excp_750cl(CPUPPCState *env)
e1833e1f
JM
3187{
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;
bd928eba 3203 /* Hardware reset vector */
09d9828a 3204 env->hreset_vector = 0x00000100UL;
bd928eba
JM
3205#endif
3206}
3207
c364946d 3208static void init_excp_750cx(CPUPPCState *env)
bd928eba
JM
3209{
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;
e1833e1f 3224 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
1c27f8fb 3225 /* Hardware reset vector */
09d9828a 3226 env->hreset_vector = 0x00000100UL;
e1833e1f
JM
3227#endif
3228}
3229
7a3a6927 3230/* XXX: Check if this is correct */
c364946d 3231static void init_excp_7x5(CPUPPCState *env)
7a3a6927
JM
3232{
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;
bd928eba 3245 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
7a3a6927
JM
3246 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
3247 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
3248 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
7a3a6927
JM
3249 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3250 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
bd928eba 3251 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
7a3a6927 3252 /* Hardware reset vector */
09d9828a 3253 env->hreset_vector = 0x00000100UL;
7a3a6927
JM
3254#endif
3255}
3256
c364946d 3257static void init_excp_7400(CPUPPCState *env)
e1833e1f
JM
3258{
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;
1c27f8fb 3277 /* Hardware reset vector */
09d9828a 3278 env->hreset_vector = 0x00000100UL;
e1833e1f
JM
3279#endif
3280}
3281
c364946d 3282static void init_excp_7450(CPUPPCState *env)
e1833e1f
JM
3283{
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;
1c27f8fb 3304 /* Hardware reset vector */
09d9828a 3305 env->hreset_vector = 0x00000100UL;
e1833e1f
JM
3306#endif
3307}
e1833e1f 3308
c364946d
DG
3309#if defined(TARGET_PPC64)
3310static void init_excp_970(CPUPPCState *env)
e1833e1f
JM
3311{
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;
e1833e1f 3324 env->excp_vectors[POWERPC_EXCP_HDECR] = 0x00000980;
e1833e1f
JM
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;
1c27f8fb
JM
3333 /* Hardware reset vector */
3334 env->hreset_vector = 0x0000000000000100ULL;
e1833e1f
JM
3335#endif
3336}
9d52e907 3337
c364946d 3338static void init_excp_POWER7(CPUPPCState *env)
9d52e907
DG
3339{
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;
f03a1af5
BH
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;
9d52e907
DG
3359 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3360 env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
1f29871c 3361 env->excp_vectors[POWERPC_EXCP_VSXU] = 0x00000F40;
9d52e907
DG
3362 /* Hardware reset vector */
3363 env->hreset_vector = 0x0000000000000100ULL;
3364#endif
3365}
f03a1af5
BH
3366
3367static void init_excp_POWER8(CPUPPCState *env)
3368{
3369 init_excp_POWER7(env);
3370
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;
3376#endif
3377}
3378
d8ce5fd6
BH
3379static void init_excp_POWER9(CPUPPCState *env)
3380{
3381 init_excp_POWER8(env);
3382
3383#if !defined(CONFIG_USER_ONLY)
3384 env->excp_vectors[POWERPC_EXCP_HVIRT] = 0x00000EA0;
3385#endif
3386}
3387
7d37b274
CLG
3388static void init_excp_POWER10(CPUPPCState *env)
3389{
3390 init_excp_POWER9(env);
3391}
3392
e1833e1f
JM
3393#endif
3394
2f462816
JM
3395/*****************************************************************************/
3396/* Power management enable checks */
c364946d 3397static int check_pow_none(CPUPPCState *env)
2f462816
JM
3398{
3399 return 0;
3400}
3401
c364946d 3402static int check_pow_nocheck(CPUPPCState *env)
2f462816
JM
3403{
3404 return 1;
3405}
3406
c364946d 3407static int check_pow_hid0(CPUPPCState *env)
2f462816 3408{
1d28b5f6 3409 if (env->spr[SPR_HID0] & 0x00E00000) {
2f462816 3410 return 1;
1d28b5f6 3411 }
2f462816
JM
3412
3413 return 0;
3414}
3415
c364946d 3416static int check_pow_hid0_74xx(CPUPPCState *env)
4e777442 3417{
1d28b5f6 3418 if (env->spr[SPR_HID0] & 0x00600000) {
4e777442 3419 return 1;
1d28b5f6 3420 }
4e777442
JM
3421
3422 return 0;
3423}
3424
382d2db6
GK
3425static bool ppc_cpu_interrupts_big_endian_always(PowerPCCPU *cpu)
3426{
3427 return true;
3428}
3429
3430#ifdef TARGET_PPC64
3431static bool ppc_cpu_interrupts_big_endian_lpcr(PowerPCCPU *cpu)
3432{
3433 return !(cpu->env.spr[SPR_LPCR] & LPCR_ILE);
3434}
3435#endif
3436
a750fc0b
JM
3437/*****************************************************************************/
3438/* PowerPC implementations definitions */
76a66253 3439
7856e3a4
AF
3440#define POWERPC_FAMILY(_name) \
3441 static void \
3442 glue(glue(ppc_, _name), _cpu_family_class_init)(ObjectClass *, void *); \
3443 \
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, \
3448 .abstract = true, \
3449 .class_init = glue(glue(ppc_, _name), _cpu_family_class_init), \
3450 }; \
3451 \
3452 static void glue(glue(ppc_, _name), _cpu_family_register_types)(void) \
3453 { \
3454 type_register_static( \
3455 &glue(glue(ppc_, _name), _cpu_family_type_info)); \
3456 } \
3457 \
3458 type_init(glue(glue(ppc_, _name), _cpu_family_register_types)) \
3459 \
3460 static void glue(glue(ppc_, _name), _cpu_family_class_init)
3461
c364946d 3462static void init_proc_401(CPUPPCState *env)
a750fc0b
JM
3463{
3464 gen_spr_40x(env);
3465 gen_spr_401_403(env);
3466 gen_spr_401(env);
e1833e1f 3467 init_excp_4xx_real(env);
d63001d1
JM
3468 env->dcache_line_size = 32;
3469 env->icache_line_size = 32;
4e290a0b 3470 /* Allocate hardware IRQ controller */
db70b311 3471 ppc40x_irq_init(env_archcpu(env));
ddd1055b
FC
3472
3473 SET_FIT_PERIOD(12, 16, 20, 24);
3474 SET_WDT_PERIOD(16, 20, 24, 28);
a750fc0b 3475}
76a66253 3476
7856e3a4
AF
3477POWERPC_FAMILY(401)(ObjectClass *oc, void *data)
3478{
ca5dff0a 3479 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3480 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3481
ca5dff0a 3482 dc->desc = "PowerPC 401";
7856e3a4
AF
3483 pcc->init_proc = init_proc_401;
3484 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
3485 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3486 PPC_WRTEE | PPC_DCR |
3487 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3488 PPC_CACHE_DCBZ |
3489 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3490 PPC_4xx_COMMON | PPC_40x_EXCP;
9df5a466
TM
3491 pcc->msr_mask = (1ull << MSR_KEY) |
3492 (1ull << MSR_POW) |
3493 (1ull << MSR_CE) |
3494 (1ull << MSR_ILE) |
3495 (1ull << MSR_EE) |
3496 (1ull << MSR_PR) |
3497 (1ull << MSR_ME) |
3498 (1ull << MSR_DE) |
3499 (1ull << MSR_LE);
ba9fd9f1
AF
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;
7856e3a4
AF
3506}
3507
c364946d 3508static void init_proc_401x2(CPUPPCState *env)
a750fc0b
JM
3509{
3510 gen_spr_40x(env);
3511 gen_spr_401_403(env);
3512 gen_spr_401x2(env);
3513 gen_spr_compress(env);
a750fc0b 3514 /* Memory management */
f2e63a42 3515#if !defined(CONFIG_USER_ONLY)
a750fc0b
JM
3516 env->nb_tlb = 64;
3517 env->nb_ways = 1;
3518 env->id_tlbs = 0;
1c53accc 3519 env->tlb_type = TLB_EMB;
f2e63a42 3520#endif
e1833e1f 3521 init_excp_4xx_softmmu(env);
d63001d1
JM
3522 env->dcache_line_size = 32;
3523 env->icache_line_size = 32;
4e290a0b 3524 /* Allocate hardware IRQ controller */
db70b311 3525 ppc40x_irq_init(env_archcpu(env));
ddd1055b
FC
3526
3527 SET_FIT_PERIOD(12, 16, 20, 24);
3528 SET_WDT_PERIOD(16, 20, 24, 28);
76a66253
JM
3529}
3530
7856e3a4
AF
3531POWERPC_FAMILY(401x2)(ObjectClass *oc, void *data)
3532{
ca5dff0a 3533 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3534 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3535
ca5dff0a 3536 dc->desc = "PowerPC 401x2";
7856e3a4
AF
3537 pcc->init_proc = init_proc_401x2;
3538 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
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;
9df5a466
TM
3546 pcc->msr_mask = (1ull << 20) |
3547 (1ull << MSR_KEY) |
3548 (1ull << MSR_POW) |
3549 (1ull << MSR_CE) |
3550 (1ull << MSR_ILE) |
3551 (1ull << MSR_EE) |
3552 (1ull << MSR_PR) |
3553 (1ull << MSR_ME) |
3554 (1ull << MSR_DE) |
3555 (1ull << MSR_IR) |
3556 (1ull << MSR_DR) |
3557 (1ull << MSR_LE);
ba9fd9f1
AF
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;
7856e3a4
AF
3564}
3565
c364946d 3566static void init_proc_401x3(CPUPPCState *env)
76a66253 3567{
4e290a0b
JM
3568 gen_spr_40x(env);
3569 gen_spr_401_403(env);
3570 gen_spr_401(env);
3571 gen_spr_401x2(env);
3572 gen_spr_compress(env);
e1833e1f 3573 init_excp_4xx_softmmu(env);
d63001d1
JM
3574 env->dcache_line_size = 32;
3575 env->icache_line_size = 32;
4e290a0b 3576 /* Allocate hardware IRQ controller */
db70b311 3577 ppc40x_irq_init(env_archcpu(env));
ddd1055b
FC
3578
3579 SET_FIT_PERIOD(12, 16, 20, 24);
3580 SET_WDT_PERIOD(16, 20, 24, 28);
3fc6c082 3581}
a750fc0b 3582
7856e3a4
AF
3583POWERPC_FAMILY(401x3)(ObjectClass *oc, void *data)
3584{
ca5dff0a 3585 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3586 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3587
ca5dff0a 3588 dc->desc = "PowerPC 401x3";
7856e3a4
AF
3589 pcc->init_proc = init_proc_401x3;
3590 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
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;
9df5a466
TM
3598 pcc->msr_mask = (1ull << 20) |
3599 (1ull << MSR_KEY) |
3600 (1ull << MSR_POW) |
3601 (1ull << MSR_CE) |
3602 (1ull << MSR_ILE) |
3603 (1ull << MSR_EE) |
3604 (1ull << MSR_PR) |
3605 (1ull << MSR_ME) |
3606 (1ull << MSR_DWE) |
3607 (1ull << MSR_DE) |
3608 (1ull << MSR_IR) |
3609 (1ull << MSR_DR) |
3610 (1ull << MSR_LE);
ba9fd9f1
AF
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;
7856e3a4
AF
3617}
3618
c364946d 3619static void init_proc_IOP480(CPUPPCState *env)
3fc6c082 3620{
a750fc0b
JM
3621 gen_spr_40x(env);
3622 gen_spr_401_403(env);
3623 gen_spr_401x2(env);
3624 gen_spr_compress(env);
a750fc0b 3625 /* Memory management */
f2e63a42 3626#if !defined(CONFIG_USER_ONLY)
a750fc0b
JM
3627 env->nb_tlb = 64;
3628 env->nb_ways = 1;
3629 env->id_tlbs = 0;
1c53accc 3630 env->tlb_type = TLB_EMB;
f2e63a42 3631#endif
e1833e1f 3632 init_excp_4xx_softmmu(env);
d63001d1
JM
3633 env->dcache_line_size = 32;
3634 env->icache_line_size = 32;
4e290a0b 3635 /* Allocate hardware IRQ controller */
db70b311 3636 ppc40x_irq_init(env_archcpu(env));
ddd1055b
FC
3637
3638 SET_FIT_PERIOD(8, 12, 16, 20);
3639 SET_WDT_PERIOD(16, 20, 24, 28);
3fc6c082
FB
3640}
3641
7856e3a4
AF
3642POWERPC_FAMILY(IOP480)(ObjectClass *oc, void *data)
3643{
ca5dff0a 3644 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3645 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3646
ca5dff0a 3647 dc->desc = "IOP480";
7856e3a4
AF
3648 pcc->init_proc = init_proc_IOP480;
3649 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
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;
9df5a466
TM
3657 pcc->msr_mask = (1ull << 20) |
3658 (1ull << MSR_KEY) |
3659 (1ull << MSR_POW) |
3660 (1ull << MSR_CE) |
3661 (1ull << MSR_ILE) |
3662 (1ull << MSR_EE) |
3663 (1ull << MSR_PR) |
3664 (1ull << MSR_ME) |
3665 (1ull << MSR_DE) |
3666 (1ull << MSR_IR) |
3667 (1ull << MSR_DR) |
3668 (1ull << MSR_LE);
ba9fd9f1
AF
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;
7856e3a4
AF
3675}
3676
c364946d 3677static void init_proc_403(CPUPPCState *env)
3fc6c082 3678{
a750fc0b
JM
3679 gen_spr_40x(env);
3680 gen_spr_401_403(env);
3681 gen_spr_403(env);
3682 gen_spr_403_real(env);
e1833e1f 3683 init_excp_4xx_real(env);
d63001d1
JM
3684 env->dcache_line_size = 32;
3685 env->icache_line_size = 32;
4e290a0b 3686 /* Allocate hardware IRQ controller */
db70b311 3687 ppc40x_irq_init(env_archcpu(env));
ddd1055b
FC
3688
3689 SET_FIT_PERIOD(8, 12, 16, 20);
3690 SET_WDT_PERIOD(16, 20, 24, 28);
3fc6c082
FB
3691}
3692
7856e3a4
AF
3693POWERPC_FAMILY(403)(ObjectClass *oc, void *data)
3694{
ca5dff0a 3695 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3696 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3697
ca5dff0a 3698 dc->desc = "PowerPC 403";
7856e3a4
AF
3699 pcc->init_proc = init_proc_403;
3700 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
3701 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3702 PPC_DCR | PPC_WRTEE |
3703 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3704 PPC_CACHE_DCBZ |
3705 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3706 PPC_4xx_COMMON | PPC_40x_EXCP;
9df5a466
TM
3707 pcc->msr_mask = (1ull << MSR_POW) |
3708 (1ull << MSR_CE) |
3709 (1ull << MSR_ILE) |
3710 (1ull << MSR_EE) |
3711 (1ull << MSR_PR) |
3712 (1ull << MSR_ME) |
3713 (1ull << MSR_PE) |
3714 (1ull << MSR_PX) |
3715 (1ull << MSR_LE);
ba9fd9f1
AF
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;
7856e3a4
AF
3722}
3723
c364946d 3724static void init_proc_403GCX(CPUPPCState *env)
3fc6c082 3725{
a750fc0b
JM
3726 gen_spr_40x(env);
3727 gen_spr_401_403(env);
3728 gen_spr_403(env);
3729 gen_spr_403_real(env);
3730 gen_spr_403_mmu(env);
3731 /* Bus access control */
5cbdb3a3 3732 /* not emulated, as QEMU never does speculative access */
a750fc0b
JM
3733 spr_register(env, SPR_40x_SGR, "SGR",
3734 SPR_NOACCESS, SPR_NOACCESS,
3735 &spr_read_generic, &spr_write_generic,
3736 0xFFFFFFFF);
5cbdb3a3 3737 /* not emulated, as QEMU do not emulate caches */
a750fc0b
JM
3738 spr_register(env, SPR_40x_DCWR, "DCWR",
3739 SPR_NOACCESS, SPR_NOACCESS,
3740 &spr_read_generic, &spr_write_generic,
3741 0x00000000);
3742 /* Memory management */
f2e63a42 3743#if !defined(CONFIG_USER_ONLY)
a750fc0b
JM
3744 env->nb_tlb = 64;
3745 env->nb_ways = 1;
3746 env->id_tlbs = 0;
1c53accc 3747 env->tlb_type = TLB_EMB;
f2e63a42 3748#endif
80d11f44
JM
3749 init_excp_4xx_softmmu(env);
3750 env->dcache_line_size = 32;
3751 env->icache_line_size = 32;
3752 /* Allocate hardware IRQ controller */
db70b311 3753 ppc40x_irq_init(env_archcpu(env));
ddd1055b
FC
3754
3755 SET_FIT_PERIOD(8, 12, 16, 20);
3756 SET_WDT_PERIOD(16, 20, 24, 28);
80d11f44
JM
3757}
3758
7856e3a4
AF
3759POWERPC_FAMILY(403GCX)(ObjectClass *oc, void *data)
3760{
ca5dff0a 3761 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3762 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3763
ca5dff0a 3764 dc->desc = "PowerPC 403 GCX";
7856e3a4
AF
3765 pcc->init_proc = init_proc_403GCX;
3766 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
3767 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3768 PPC_DCR | PPC_WRTEE |
3769 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3770 PPC_CACHE_DCBZ |
3771 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3772 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3773 PPC_4xx_COMMON | PPC_40x_EXCP;
9df5a466
TM
3774 pcc->msr_mask = (1ull << MSR_POW) |
3775 (1ull << MSR_CE) |
3776 (1ull << MSR_ILE) |
3777 (1ull << MSR_EE) |
3778 (1ull << MSR_PR) |
3779 (1ull << MSR_ME) |
3780 (1ull << MSR_PE) |
3781 (1ull << MSR_PX) |
3782 (1ull << MSR_LE);
ba9fd9f1
AF
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;
7856e3a4
AF
3789}
3790
c364946d 3791static void init_proc_405(CPUPPCState *env)
80d11f44
JM
3792{
3793 /* Time base */
3794 gen_tbl(env);
3795 gen_spr_40x(env);
3796 gen_spr_405(env);
3797 /* Bus access control */
5cbdb3a3 3798 /* not emulated, as QEMU never does speculative access */
80d11f44
JM
3799 spr_register(env, SPR_40x_SGR, "SGR",
3800 SPR_NOACCESS, SPR_NOACCESS,
3801 &spr_read_generic, &spr_write_generic,
3802 0xFFFFFFFF);
5cbdb3a3 3803 /* not emulated, as QEMU do not emulate caches */
80d11f44
JM
3804 spr_register(env, SPR_40x_DCWR, "DCWR",
3805 SPR_NOACCESS, SPR_NOACCESS,
3806 &spr_read_generic, &spr_write_generic,
3807 0x00000000);
3808 /* Memory management */
3809#if !defined(CONFIG_USER_ONLY)
3810 env->nb_tlb = 64;
3811 env->nb_ways = 1;
3812 env->id_tlbs = 0;
1c53accc 3813 env->tlb_type = TLB_EMB;
80d11f44
JM
3814#endif
3815 init_excp_4xx_softmmu(env);
3816 env->dcache_line_size = 32;
3817 env->icache_line_size = 32;
3818 /* Allocate hardware IRQ controller */
db70b311 3819 ppc40x_irq_init(env_archcpu(env));
ddd1055b
FC
3820
3821 SET_FIT_PERIOD(8, 12, 16, 20);
3822 SET_WDT_PERIOD(16, 20, 24, 28);
80d11f44
JM
3823}
3824
7856e3a4
AF
3825POWERPC_FAMILY(405)(ObjectClass *oc, void *data)
3826{
ca5dff0a 3827 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3828 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3829
ca5dff0a 3830 dc->desc = "PowerPC 405";
7856e3a4
AF
3831 pcc->init_proc = init_proc_405;
3832 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
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;
9df5a466
TM
3840 pcc->msr_mask = (1ull << MSR_POW) |
3841 (1ull << MSR_CE) |
3842 (1ull << MSR_EE) |
3843 (1ull << MSR_PR) |
3844 (1ull << MSR_FP) |
3845 (1ull << MSR_DWE) |
3846 (1ull << MSR_DE) |
3847 (1ull << MSR_IR) |
3848 (1ull << MSR_DR);
ba9fd9f1
AF
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;
7856e3a4
AF
3855}
3856
c364946d 3857static void init_proc_440EP(CPUPPCState *env)
80d11f44
JM
3858{
3859 /* Time base */
3860 gen_tbl(env);
3861 gen_spr_BookE(env, 0x000000000000FFFFULL);
3862 gen_spr_440(env);
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,
3868 0x00000000);
3869 /* XXX : not implemented */
3870 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
3871 SPR_NOACCESS, SPR_NOACCESS,
3872 &spr_read_generic, &spr_write_generic,
3873 0x00000000);
3874 /* XXX : not implemented */
3875 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
3876 SPR_NOACCESS, SPR_NOACCESS,
3877 &spr_read_generic, &spr_write_generic,
3878 0x00000000);
3879 /* XXX : not implemented */
3880 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
3881 SPR_NOACCESS, SPR_NOACCESS,
3882 &spr_read_generic, &spr_write_generic,
3883 0x00000000);
3884 /* XXX : not implemented */
3885 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
3886 SPR_NOACCESS, SPR_NOACCESS,
3887 &spr_read_generic, &spr_write_generic,
3888 0x00000000);
3889 /* XXX : not implemented */
3890 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
3891 SPR_NOACCESS, SPR_NOACCESS,
3892 &spr_read_generic, &spr_write_generic,
3893 0x00000000);
3894 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
3895 SPR_NOACCESS, SPR_NOACCESS,
3896 &spr_read_generic, &spr_write_generic,
3897 0x00000000);
3898 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
3899 SPR_NOACCESS, SPR_NOACCESS,
3900 &spr_read_generic, &spr_write_generic,
3901 0x00000000);
3902 /* XXX : not implemented */
3903 spr_register(env, SPR_440_CCR1, "CCR1",
3904 SPR_NOACCESS, SPR_NOACCESS,
3905 &spr_read_generic, &spr_write_generic,
3906 0x00000000);
3907 /* Memory management */
3908#if !defined(CONFIG_USER_ONLY)
3909 env->nb_tlb = 64;
3910 env->nb_ways = 1;
3911 env->id_tlbs = 0;
1c53accc 3912 env->tlb_type = TLB_EMB;
80d11f44
JM
3913#endif
3914 init_excp_BookE(env);
3915 env->dcache_line_size = 32;
3916 env->icache_line_size = 32;
db70b311 3917 ppc40x_irq_init(env_archcpu(env));
ddd1055b
FC
3918
3919 SET_FIT_PERIOD(12, 16, 20, 24);
3920 SET_WDT_PERIOD(20, 24, 28, 32);
80d11f44
JM
3921}
3922
7856e3a4
AF
3923POWERPC_FAMILY(440EP)(ObjectClass *oc, void *data)
3924{
ca5dff0a 3925 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3926 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3927
ca5dff0a 3928 dc->desc = "PowerPC 440 EP";
7856e3a4
AF
3929 pcc->init_proc = init_proc_440EP;
3930 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
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 |
3934 PPC_FLOAT_STFIWX |
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 |
3940 PPC_440_SPEC;
81bb29ac
BZ
3941 pcc->msr_mask = (1ull << MSR_POW) |
3942 (1ull << MSR_CE) |
3943 (1ull << MSR_EE) |
3944 (1ull << MSR_PR) |
3945 (1ull << MSR_FP) |
3946 (1ull << MSR_ME) |
3947 (1ull << MSR_FE0) |
3948 (1ull << MSR_DWE) |
3949 (1ull << MSR_DE) |
3950 (1ull << MSR_FE1) |
3951 (1ull << MSR_IR) |
3952 (1ull << MSR_DR);
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;
3959}
3960
3961POWERPC_FAMILY(460EX)(ObjectClass *oc, void *data)
3962{
3963 DeviceClass *dc = DEVICE_CLASS(oc);
3964 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3965
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 |
3972 PPC_FLOAT_STFIWX |
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 |
3978 PPC_440_SPEC;
9df5a466
TM
3979 pcc->msr_mask = (1ull << MSR_POW) |
3980 (1ull << MSR_CE) |
3981 (1ull << MSR_EE) |
3982 (1ull << MSR_PR) |
3983 (1ull << MSR_FP) |
3984 (1ull << MSR_ME) |
3985 (1ull << MSR_FE0) |
3986 (1ull << MSR_DWE) |
3987 (1ull << MSR_DE) |
3988 (1ull << MSR_FE1) |
3989 (1ull << MSR_IR) |
3990 (1ull << MSR_DR);
ba9fd9f1
AF
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;
7856e3a4
AF
3997}
3998
c364946d 3999static void init_proc_440GP(CPUPPCState *env)
80d11f44
JM
4000{
4001 /* Time base */
4002 gen_tbl(env);
4003 gen_spr_BookE(env, 0x000000000000FFFFULL);
4004 gen_spr_440(env);
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,
4010 0x00000000);
4011 /* XXX : not implemented */
4012 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4013 SPR_NOACCESS, SPR_NOACCESS,
4014 &spr_read_generic, &spr_write_generic,
4015 0x00000000);
4016 /* XXX : not implemented */
4017 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4018 SPR_NOACCESS, SPR_NOACCESS,
4019 &spr_read_generic, &spr_write_generic,
4020 0x00000000);
4021 /* XXX : not implemented */
4022 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
4023 SPR_NOACCESS, SPR_NOACCESS,
4024 &spr_read_generic, &spr_write_generic,
4025 0x00000000);
4026 /* XXX : not implemented */
4027 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
4028 SPR_NOACCESS, SPR_NOACCESS,
4029 &spr_read_generic, &spr_write_generic,
4030 0x00000000);
4031 /* Memory management */
4032#if !defined(CONFIG_USER_ONLY)
4033 env->nb_tlb = 64;
4034 env->nb_ways = 1;
4035 env->id_tlbs = 0;
1c53accc 4036 env->tlb_type = TLB_EMB;
80d11f44
JM
4037#endif
4038 init_excp_BookE(env);
4039 env->dcache_line_size = 32;
4040 env->icache_line_size = 32;
4041 /* XXX: TODO: allocate internal IRQ controller */
ddd1055b
FC
4042
4043 SET_FIT_PERIOD(12, 16, 20, 24);
4044 SET_WDT_PERIOD(20, 24, 28, 32);
80d11f44
JM
4045}
4046
7856e3a4
AF
4047POWERPC_FAMILY(440GP)(ObjectClass *oc, void *data)
4048{
ca5dff0a 4049 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4050 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4051
ca5dff0a 4052 dc->desc = "PowerPC 440 GP";
7856e3a4
AF
4053 pcc->init_proc = init_proc_440GP;
4054 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
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 |
4061 PPC_440_SPEC;
9df5a466
TM
4062 pcc->msr_mask = (1ull << MSR_POW) |
4063 (1ull << MSR_CE) |
4064 (1ull << MSR_EE) |
4065 (1ull << MSR_PR) |
4066 (1ull << MSR_FP) |
4067 (1ull << MSR_ME) |
4068 (1ull << MSR_FE0) |
4069 (1ull << MSR_DWE) |
4070 (1ull << MSR_DE) |
4071 (1ull << MSR_FE1) |
4072 (1ull << MSR_IR) |
4073 (1ull << MSR_DR);
ba9fd9f1
AF
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;
7856e3a4
AF
4080}
4081
c364946d 4082static void init_proc_440x4(CPUPPCState *env)
80d11f44
JM
4083{
4084 /* Time base */
4085 gen_tbl(env);
4086 gen_spr_BookE(env, 0x000000000000FFFFULL);
4087 gen_spr_440(env);
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,
4093 0x00000000);
4094 /* XXX : not implemented */
4095 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4096 SPR_NOACCESS, SPR_NOACCESS,
4097 &spr_read_generic, &spr_write_generic,
4098 0x00000000);
4099 /* XXX : not implemented */
4100 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4101 SPR_NOACCESS, SPR_NOACCESS,
4102 &spr_read_generic, &spr_write_generic,
4103 0x00000000);
4104 /* XXX : not implemented */
4105 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
4106 SPR_NOACCESS, SPR_NOACCESS,
4107 &spr_read_generic, &spr_write_generic,
4108 0x00000000);
4109 /* XXX : not implemented */
4110 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
4111 SPR_NOACCESS, SPR_NOACCESS,
4112 &spr_read_generic, &spr_write_generic,
4113 0x00000000);
4114 /* Memory management */
4115#if !defined(CONFIG_USER_ONLY)
4116 env->nb_tlb = 64;
4117 env->nb_ways = 1;
4118 env->id_tlbs = 0;
1c53accc 4119 env->tlb_type = TLB_EMB;
80d11f44
JM
4120#endif
4121 init_excp_BookE(env);
d63001d1
JM
4122 env->dcache_line_size = 32;
4123 env->icache_line_size = 32;
80d11f44 4124 /* XXX: TODO: allocate internal IRQ controller */
ddd1055b
FC
4125
4126 SET_FIT_PERIOD(12, 16, 20, 24);
4127 SET_WDT_PERIOD(20, 24, 28, 32);
3fc6c082
FB
4128}
4129
7856e3a4
AF
4130POWERPC_FAMILY(440x4)(ObjectClass *oc, void *data)
4131{
ca5dff0a 4132 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4133 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4134
ca5dff0a 4135 dc->desc = "PowerPC 440x4";
7856e3a4
AF
4136 pcc->init_proc = init_proc_440x4;
4137 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
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 |
4144 PPC_440_SPEC;
9df5a466
TM
4145 pcc->msr_mask = (1ull << MSR_POW) |
4146 (1ull << MSR_CE) |
4147 (1ull << MSR_EE) |
4148 (1ull << MSR_PR) |
4149 (1ull << MSR_FP) |
4150 (1ull << MSR_ME) |
4151 (1ull << MSR_FE0) |
4152 (1ull << MSR_DWE) |
4153 (1ull << MSR_DE) |
4154 (1ull << MSR_FE1) |
4155 (1ull << MSR_IR) |
4156 (1ull << MSR_DR);
ba9fd9f1
AF
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;
7856e3a4
AF
4163}
4164
c364946d 4165static void init_proc_440x5(CPUPPCState *env)
3fc6c082 4166{
a750fc0b
JM
4167 /* Time base */
4168 gen_tbl(env);
80d11f44
JM
4169 gen_spr_BookE(env, 0x000000000000FFFFULL);
4170 gen_spr_440(env);
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,
4176 0x00000000);
4177 /* XXX : not implemented */
4178 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
a750fc0b
JM
4179 SPR_NOACCESS, SPR_NOACCESS,
4180 &spr_read_generic, &spr_write_generic,
80d11f44
JM
4181 0x00000000);
4182 /* XXX : not implemented */
4183 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4184 SPR_NOACCESS, SPR_NOACCESS,
4185 &spr_read_generic, &spr_write_generic,
4186 0x00000000);
4187 /* XXX : not implemented */
4188 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
4189 SPR_NOACCESS, SPR_NOACCESS,
4190 &spr_read_generic, &spr_write_generic,
4191 0x00000000);
4192 /* XXX : not implemented */
4193 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
4194 SPR_NOACCESS, SPR_NOACCESS,
4195 &spr_read_generic, &spr_write_generic,
4196 0x00000000);
4197 /* XXX : not implemented */
4198 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
4199 SPR_NOACCESS, SPR_NOACCESS,
4200 &spr_read_generic, &spr_write_generic,
4201 0x00000000);
4202 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
4203 SPR_NOACCESS, SPR_NOACCESS,
4204 &spr_read_generic, &spr_write_generic,
4205 0x00000000);
4206 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
4207 SPR_NOACCESS, SPR_NOACCESS,
4208 &spr_read_generic, &spr_write_generic,
4209 0x00000000);
4210 /* XXX : not implemented */
4211 spr_register(env, SPR_440_CCR1, "CCR1",
a750fc0b
JM
4212 SPR_NOACCESS, SPR_NOACCESS,
4213 &spr_read_generic, &spr_write_generic,
4214 0x00000000);
4215 /* Memory management */
f2e63a42 4216#if !defined(CONFIG_USER_ONLY)
a750fc0b
JM
4217 env->nb_tlb = 64;
4218 env->nb_ways = 1;
4219 env->id_tlbs = 0;
1c53accc 4220 env->tlb_type = TLB_EMB;
f2e63a42 4221#endif
80d11f44 4222 init_excp_BookE(env);
d63001d1
JM
4223 env->dcache_line_size = 32;
4224 env->icache_line_size = 32;
db70b311 4225 ppc40x_irq_init(env_archcpu(env));
ddd1055b
FC
4226
4227 SET_FIT_PERIOD(12, 16, 20, 24);
4228 SET_WDT_PERIOD(20, 24, 28, 32);
3fc6c082
FB
4229}
4230
7856e3a4
AF
4231POWERPC_FAMILY(440x5)(ObjectClass *oc, void *data)
4232{
ca5dff0a 4233 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4234 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4235
ca5dff0a 4236 dc->desc = "PowerPC 440x5";
7856e3a4
AF
4237 pcc->init_proc = init_proc_440x5;
4238 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
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 |
4245 PPC_440_SPEC;
9df5a466
TM
4246 pcc->msr_mask = (1ull << MSR_POW) |
4247 (1ull << MSR_CE) |
4248 (1ull << MSR_EE) |
4249 (1ull << MSR_PR) |
4250 (1ull << MSR_FP) |
4251 (1ull << MSR_ME) |
4252 (1ull << MSR_FE0) |
4253 (1ull << MSR_DWE) |
4254 (1ull << MSR_DE) |
4255 (1ull << MSR_FE1) |
4256 (1ull << MSR_IR) |
4257 (1ull << MSR_DR);
ba9fd9f1
AF
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;
7856e3a4
AF
4264}
4265
b8c867ed
PM
4266POWERPC_FAMILY(440x5wDFPU)(ObjectClass *oc, void *data)
4267{
4268 DeviceClass *dc = DEVICE_CLASS(oc);
4269 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4270
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 |
4276 PPC_FLOAT_STFIWX |
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 |
4282 PPC_440_SPEC;
4283 pcc->insns_flags2 = PPC2_FP_CVT_S64;
9df5a466
TM
4284 pcc->msr_mask = (1ull << MSR_POW) |
4285 (1ull << MSR_CE) |
4286 (1ull << MSR_EE) |
4287 (1ull << MSR_PR) |
4288 (1ull << MSR_FP) |
4289 (1ull << MSR_ME) |
4290 (1ull << MSR_FE0) |
4291 (1ull << MSR_DWE) |
4292 (1ull << MSR_DE) |
4293 (1ull << MSR_FE1) |
4294 (1ull << MSR_IR) |
4295 (1ull << MSR_DR);
ba9fd9f1
AF
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;
7856e3a4
AF
4302}
4303
c364946d 4304static void init_proc_MPC5xx(CPUPPCState *env)
80d11f44
JM
4305{
4306 /* Time base */
4307 gen_tbl(env);
4308 gen_spr_5xx_8xx(env);
4309 gen_spr_5xx(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 */
4314}
4315
7856e3a4
AF
4316POWERPC_FAMILY(MPC5xx)(ObjectClass *oc, void *data)
4317{
ca5dff0a 4318 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4319 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4320
ca5dff0a 4321 dc->desc = "Freescale 5xx cores (aka RCPU)";
7856e3a4
AF
4322 pcc->init_proc = init_proc_MPC5xx;
4323 pcc->check_pow = check_pow_none;
53116ebf
AF
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 |
4327 PPC_MFTB;
9df5a466
TM
4328 pcc->msr_mask = (1ull << MSR_ILE) |
4329 (1ull << MSR_EE) |
4330 (1ull << MSR_PR) |
4331 (1ull << MSR_FP) |
4332 (1ull << MSR_ME) |
4333 (1ull << MSR_FE0) |
4334 (1ull << MSR_SE) |
4335 (1ull << MSR_DE) |
4336 (1ull << MSR_FE1) |
4337 (1ull << MSR_EP) |
4338 (1ull << MSR_RI) |
4339 (1ull << MSR_LE);
ba9fd9f1
AF
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;
7856e3a4
AF
4346}
4347
c364946d 4348static void init_proc_MPC8xx(CPUPPCState *env)
80d11f44
JM
4349{
4350 /* Time base */
4351 gen_tbl(env);
4352 gen_spr_5xx_8xx(env);
4353 gen_spr_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 */
4358}
4359
7856e3a4
AF
4360POWERPC_FAMILY(MPC8xx)(ObjectClass *oc, void *data)
4361{
ca5dff0a 4362 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4363 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4364
ca5dff0a 4365 dc->desc = "Freescale 8xx cores (aka PowerQUICC)";
7856e3a4
AF
4366 pcc->init_proc = init_proc_MPC8xx;
4367 pcc->check_pow = check_pow_none;
53116ebf
AF
4368 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4369 PPC_MEM_EIEIO | PPC_MEM_SYNC |
4370 PPC_CACHE_ICBI | PPC_MFTB;
9df5a466
TM
4371 pcc->msr_mask = (1ull << MSR_ILE) |
4372 (1ull << MSR_EE) |
4373 (1ull << MSR_PR) |
4374 (1ull << MSR_FP) |
4375 (1ull << MSR_ME) |
4376 (1ull << MSR_SE) |
4377 (1ull << MSR_DE) |
4378 (1ull << MSR_EP) |
4379 (1ull << MSR_IR) |
4380 (1ull << MSR_DR) |
4381 (1ull << MSR_RI) |
4382 (1ull << MSR_LE);
ba9fd9f1
AF
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;
7856e3a4
AF
4389}
4390
80d11f44 4391/* Freescale 82xx cores (aka PowerQUICC-II) */
ca5dff0a 4392
c364946d 4393static void init_proc_G2(CPUPPCState *env)
3fc6c082 4394{
80d11f44 4395 gen_spr_ne_601(env);
4f4f28ff 4396 gen_spr_sdr1(env);
80d11f44
JM
4397 gen_spr_G2_755(env);
4398 gen_spr_G2(env);
a750fc0b
JM
4399 /* Time base */
4400 gen_tbl(env);
bd928eba
JM
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,
4406 0x00000000);
80d11f44
JM
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,
4412 0x00000000);
4413 /* XXX : not implemented */
4414 spr_register(env, SPR_HID1, "HID1",
4415 SPR_NOACCESS, SPR_NOACCESS,
4416 &spr_read_generic, &spr_write_generic,
4417 0x00000000);
4418 /* XXX : not implemented */
4419 spr_register(env, SPR_HID2, "HID2",
4420 SPR_NOACCESS, SPR_NOACCESS,
4421 &spr_read_generic, &spr_write_generic,
4422 0x00000000);
a750fc0b 4423 /* Memory management */
80d11f44
JM
4424 gen_low_BATs(env);
4425 gen_high_BATs(env);
4426 gen_6xx_7xx_soft_tlb(env, 64, 2);
4427 init_excp_G2(env);
d63001d1
JM
4428 env->dcache_line_size = 32;
4429 env->icache_line_size = 32;
80d11f44 4430 /* Allocate hardware IRQ controller */
db70b311 4431 ppc6xx_irq_init(env_archcpu(env));
3fc6c082 4432}
a750fc0b 4433
7856e3a4
AF
4434POWERPC_FAMILY(G2)(ObjectClass *oc, void *data)
4435{
ca5dff0a 4436 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4437 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4438
ca5dff0a 4439 dc->desc = "PowerPC G2";
7856e3a4
AF
4440 pcc->init_proc = init_proc_G2;
4441 pcc->check_pow = check_pow_hid0;
53116ebf
AF
4442 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4443 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4444 PPC_FLOAT_STFIWX |
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;
9df5a466
TM
4449 pcc->msr_mask = (1ull << MSR_POW) |
4450 (1ull << MSR_TGPR) |
4451 (1ull << MSR_EE) |
4452 (1ull << MSR_PR) |
4453 (1ull << MSR_FP) |
4454 (1ull << MSR_ME) |
4455 (1ull << MSR_FE0) |
4456 (1ull << MSR_SE) |
4457 (1ull << MSR_DE) |
4458 (1ull << MSR_FE1) |
4459 (1ull << MSR_AL) |
4460 (1ull << MSR_EP) |
4461 (1ull << MSR_IR) |
4462 (1ull << MSR_DR) |
4463 (1ull << MSR_RI);
ba9fd9f1
AF
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;
7856e3a4
AF
4470}
4471
c364946d 4472static void init_proc_G2LE(CPUPPCState *env)
3fc6c082 4473{
80d11f44 4474 gen_spr_ne_601(env);
4f4f28ff 4475 gen_spr_sdr1(env);
80d11f44
JM
4476 gen_spr_G2_755(env);
4477 gen_spr_G2(env);
a750fc0b
JM
4478 /* Time base */
4479 gen_tbl(env);
bd928eba
JM
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,
4485 0x00000000);
80d11f44 4486 /* Hardware implementation register */
578bb252 4487 /* XXX : not implemented */
80d11f44 4488 spr_register(env, SPR_HID0, "HID0",
a750fc0b
JM
4489 SPR_NOACCESS, SPR_NOACCESS,
4490 &spr_read_generic, &spr_write_generic,
4491 0x00000000);
80d11f44
JM
4492 /* XXX : not implemented */
4493 spr_register(env, SPR_HID1, "HID1",
a750fc0b
JM
4494 SPR_NOACCESS, SPR_NOACCESS,
4495 &spr_read_generic, &spr_write_generic,
4496 0x00000000);
578bb252 4497 /* XXX : not implemented */
80d11f44 4498 spr_register(env, SPR_HID2, "HID2",
a750fc0b
JM
4499 SPR_NOACCESS, SPR_NOACCESS,
4500 &spr_read_generic, &spr_write_generic,
4501 0x00000000);
2bc17322 4502
a750fc0b 4503 /* Memory management */
80d11f44
JM
4504 gen_low_BATs(env);
4505 gen_high_BATs(env);
4506 gen_6xx_7xx_soft_tlb(env, 64, 2);
4507 init_excp_G2(env);
d63001d1
JM
4508 env->dcache_line_size = 32;
4509 env->icache_line_size = 32;
80d11f44 4510 /* Allocate hardware IRQ controller */
db70b311 4511 ppc6xx_irq_init(env_archcpu(env));
3fc6c082
FB
4512}
4513
7856e3a4
AF
4514POWERPC_FAMILY(G2LE)(ObjectClass *oc, void *data)
4515{
ca5dff0a 4516 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4517 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4518
ca5dff0a 4519 dc->desc = "PowerPC G2LE";
7856e3a4
AF
4520 pcc->init_proc = init_proc_G2LE;
4521 pcc->check_pow = check_pow_hid0;
53116ebf
AF
4522 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4523 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4524 PPC_FLOAT_STFIWX |
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;
9df5a466
TM
4529 pcc->msr_mask = (1ull << MSR_POW) |
4530 (1ull << MSR_TGPR) |
4531 (1ull << MSR_ILE) |
4532 (1ull << MSR_EE) |
4533 (1ull << MSR_PR) |
4534 (1ull << MSR_FP) |
4535 (1ull << MSR_ME) |
4536 (1ull << MSR_FE0) |
4537 (1ull << MSR_SE) |
4538 (1ull << MSR_DE) |
4539 (1ull << MSR_FE1) |
4540 (1ull << MSR_AL) |
4541 (1ull << MSR_EP) |
4542 (1ull << MSR_IR) |
4543 (1ull << MSR_DR) |
4544 (1ull << MSR_RI) |
4545 (1ull << MSR_LE);
ba9fd9f1
AF
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;
7856e3a4
AF
4552}
4553
c364946d 4554static void init_proc_e200(CPUPPCState *env)
3fc6c082 4555{
e1833e1f
JM
4556 /* Time base */
4557 gen_tbl(env);
80d11f44 4558 gen_spr_BookE(env, 0x000000070000FFFFULL);
578bb252 4559 /* XXX : not implemented */
80d11f44 4560 spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
d34defbc
AJ
4561 &spr_read_spefscr, &spr_write_spefscr,
4562 &spr_read_spefscr, &spr_write_spefscr,
e1833e1f 4563 0x00000000);
80d11f44 4564 /* Memory management */
d21ee633 4565 gen_spr_BookE206(env, 0x0000005D, NULL, 0);
80d11f44
JM
4566 /* XXX : not implemented */
4567 spr_register(env, SPR_HID0, "HID0",
e1833e1f
JM
4568 SPR_NOACCESS, SPR_NOACCESS,
4569 &spr_read_generic, &spr_write_generic,
4570 0x00000000);
80d11f44
JM
4571 /* XXX : not implemented */
4572 spr_register(env, SPR_HID1, "HID1",
e1833e1f
JM
4573 SPR_NOACCESS, SPR_NOACCESS,
4574 &spr_read_generic, &spr_write_generic,
4575 0x00000000);
578bb252 4576 /* XXX : not implemented */
80d11f44 4577 spr_register(env, SPR_Exxx_ALTCTXCR, "ALTCTXCR",
e1833e1f
JM
4578 SPR_NOACCESS, SPR_NOACCESS,
4579 &spr_read_generic, &spr_write_generic,
4580 0x00000000);
578bb252 4581 /* XXX : not implemented */
80d11f44
JM
4582 spr_register(env, SPR_Exxx_BUCSR, "BUCSR",
4583 SPR_NOACCESS, SPR_NOACCESS,
e1833e1f 4584 &spr_read_generic, &spr_write_generic,
80d11f44
JM
4585 0x00000000);
4586 /* XXX : not implemented */
4587 spr_register(env, SPR_Exxx_CTXCR, "CTXCR",
4588 SPR_NOACCESS, SPR_NOACCESS,
4589 &spr_read_generic, &spr_write_generic,
4590 0x00000000);
4591 /* XXX : not implemented */
4592 spr_register(env, SPR_Exxx_DBCNT, "DBCNT",
4593 SPR_NOACCESS, SPR_NOACCESS,
4594 &spr_read_generic, &spr_write_generic,
4595 0x00000000);
4596 /* XXX : not implemented */
4597 spr_register(env, SPR_Exxx_DBCR3, "DBCR3",
4598 SPR_NOACCESS, SPR_NOACCESS,
4599 &spr_read_generic, &spr_write_generic,
4600 0x00000000);
4601 /* XXX : not implemented */
4602 spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0",
deb05c4c
AG
4603 &spr_read_generic, SPR_NOACCESS,
4604 &spr_read_generic, SPR_NOACCESS,
80d11f44
JM
4605 0x00000000);
4606 /* XXX : not implemented */
4607 spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0",
4608 SPR_NOACCESS, SPR_NOACCESS,
4609 &spr_read_generic, &spr_write_generic,
4610 0x00000000);
4611 /* XXX : not implemented */
4612 spr_register(env, SPR_Exxx_L1FINV0, "L1FINV0",
4613 SPR_NOACCESS, SPR_NOACCESS,
4614 &spr_read_generic, &spr_write_generic,
4615 0x00000000);
4616 /* XXX : not implemented */
4617 spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG",
4618 SPR_NOACCESS, SPR_NOACCESS,
4619 &spr_read_generic, &spr_write_generic,
4620 0x00000000);
4621 /* XXX : not implemented */
4622 spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG",
4623 SPR_NOACCESS, SPR_NOACCESS,
4624 &spr_read_generic, &spr_write_generic,
4625 0x00000000);
4626 /* XXX : not implemented */
4627 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4628 SPR_NOACCESS, SPR_NOACCESS,
4629 &spr_read_generic, &spr_write_generic,
4630 0x00000000);
4631 /* XXX : not implemented */
4632 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4633 SPR_NOACCESS, SPR_NOACCESS,
4634 &spr_read_generic, &spr_write_generic,
4635 0x00000000);
01662f3e
AG
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 */
80d11f44
JM
4641 spr_register(env, SPR_BOOKE_DSRR0, "DSRR0",
4642 SPR_NOACCESS, SPR_NOACCESS,
4643 &spr_read_generic, &spr_write_generic,
4644 0x00000000);
4645 spr_register(env, SPR_BOOKE_DSRR1, "DSRR1",
4646 SPR_NOACCESS, SPR_NOACCESS,
e1833e1f
JM
4647 &spr_read_generic, &spr_write_generic,
4648 0x00000000);
f2e63a42 4649#if !defined(CONFIG_USER_ONLY)
e1833e1f
JM
4650 env->nb_tlb = 64;
4651 env->nb_ways = 1;
4652 env->id_tlbs = 0;
1c53accc 4653 env->tlb_type = TLB_EMB;
f2e63a42 4654#endif
e9cd84b9 4655 init_excp_e200(env, 0xFFFF0000UL);
d63001d1
JM
4656 env->dcache_line_size = 32;
4657 env->icache_line_size = 32;
e1833e1f 4658 /* XXX: TODO: allocate internal IRQ controller */
3fc6c082 4659}
a750fc0b 4660
7856e3a4
AF
4661POWERPC_FAMILY(e200)(ObjectClass *oc, void *data)
4662{
ca5dff0a 4663 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4664 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4665
ca5dff0a 4666 dc->desc = "e200 core";
7856e3a4
AF
4667 pcc->init_proc = init_proc_e200;
4668 pcc->check_pow = check_pow_hid0;
1d28b5f6
DG
4669 /*
4670 * XXX: unimplemented instructions:
53116ebf
AF
4671 * dcblc
4672 * dcbtlst
4673 * dcbtstls
4674 * icblc
4675 * icbtls
4676 * tlbivax
4677 * all SPE multiply-accumulate instructions
4678 */
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 |
4685 PPC_BOOKE;
9df5a466
TM
4686 pcc->msr_mask = (1ull << MSR_UCLE) |
4687 (1ull << MSR_SPE) |
4688 (1ull << MSR_POW) |
4689 (1ull << MSR_CE) |
4690 (1ull << MSR_EE) |
4691 (1ull << MSR_PR) |
4692 (1ull << MSR_FP) |
4693 (1ull << MSR_ME) |
4694 (1ull << MSR_FE0) |
4695 (1ull << MSR_DWE) |
4696 (1ull << MSR_DE) |
4697 (1ull << MSR_FE1) |
4698 (1ull << MSR_IR) |
4699 (1ull << MSR_DR);
ba9fd9f1
AF
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;
7856e3a4
AF
4707}
4708
c364946d 4709static void init_proc_e300(CPUPPCState *env)
3fc6c082 4710{
80d11f44 4711 gen_spr_ne_601(env);
4f4f28ff 4712 gen_spr_sdr1(env);
80d11f44 4713 gen_spr_603(env);
a750fc0b
JM
4714 /* Time base */
4715 gen_tbl(env);
80d11f44
JM
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,
4721 0x00000000);
4722 /* XXX : not implemented */
4723 spr_register(env, SPR_HID1, "HID1",
4724 SPR_NOACCESS, SPR_NOACCESS,
4725 &spr_read_generic, &spr_write_generic,
4726 0x00000000);
8daf1781
TM
4727 /* XXX : not implemented */
4728 spr_register(env, SPR_HID2, "HID2",
4729 SPR_NOACCESS, SPR_NOACCESS,
4730 &spr_read_generic, &spr_write_generic,
4731 0x00000000);
3ade1a05
FC
4732 /* Breakpoints */
4733 /* XXX : not implemented */
4734 spr_register(env, SPR_DABR, "DABR",
4735 SPR_NOACCESS, SPR_NOACCESS,
4736 &spr_read_generic, &spr_write_generic,
4737 0x00000000);
4738 /* XXX : not implemented */
4739 spr_register(env, SPR_DABR2, "DABR2",
4740 SPR_NOACCESS, SPR_NOACCESS,
4741 &spr_read_generic, &spr_write_generic,
4742 0x00000000);
4743 /* XXX : not implemented */
4744 spr_register(env, SPR_IABR2, "IABR2",
4745 SPR_NOACCESS, SPR_NOACCESS,
4746 &spr_read_generic, &spr_write_generic,
4747 0x00000000);
4748 /* XXX : not implemented */
4749 spr_register(env, SPR_IBCR, "IBCR",
4750 SPR_NOACCESS, SPR_NOACCESS,
4751 &spr_read_generic, &spr_write_generic,
4752 0x00000000);
4753 /* XXX : not implemented */
4754 spr_register(env, SPR_DBCR, "DBCR",
4755 SPR_NOACCESS, SPR_NOACCESS,
4756 &spr_read_generic, &spr_write_generic,
4757 0x00000000);
80d11f44
JM
4758 /* Memory management */
4759 gen_low_BATs(env);
8daf1781 4760 gen_high_BATs(env);
80d11f44
JM
4761 gen_6xx_7xx_soft_tlb(env, 64, 2);
4762 init_excp_603(env);
4763 env->dcache_line_size = 32;
4764 env->icache_line_size = 32;
4765 /* Allocate hardware IRQ controller */
db70b311 4766 ppc6xx_irq_init(env_archcpu(env));
80d11f44
JM
4767}
4768
7856e3a4
AF
4769POWERPC_FAMILY(e300)(ObjectClass *oc, void *data)
4770{
ca5dff0a 4771 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4772 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4773
ca5dff0a 4774 dc->desc = "e300 core";
7856e3a4
AF
4775 pcc->init_proc = init_proc_e300;
4776 pcc->check_pow = check_pow_hid0;
53116ebf
AF
4777 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4778 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4779 PPC_FLOAT_STFIWX |
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;
9df5a466
TM
4784 pcc->msr_mask = (1ull << MSR_POW) |
4785 (1ull << MSR_TGPR) |
4786 (1ull << MSR_ILE) |
4787 (1ull << MSR_EE) |
4788 (1ull << MSR_PR) |
4789 (1ull << MSR_FP) |
4790 (1ull << MSR_ME) |
4791 (1ull << MSR_FE0) |
4792 (1ull << MSR_SE) |
4793 (1ull << MSR_DE) |
4794 (1ull << MSR_FE1) |
4795 (1ull << MSR_AL) |
4796 (1ull << MSR_EP) |
4797 (1ull << MSR_IR) |
4798 (1ull << MSR_DR) |
4799 (1ull << MSR_RI) |
4800 (1ull << MSR_LE);
ba9fd9f1
AF
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;
7856e3a4
AF
4807}
4808
b81ccf8a 4809#if !defined(CONFIG_USER_ONLY)
69b058c8 4810static void spr_write_mas73(DisasContext *ctx, int sprn, int gprn)
b81ccf8a
AG
4811{
4812 TCGv val = tcg_temp_new();
4813 tcg_gen_ext32u_tl(val, cpu_gpr[gprn]);
4814 gen_store_spr(SPR_BOOKE_MAS3, val);
cfee0218 4815 tcg_gen_shri_tl(val, cpu_gpr[gprn], 32);
b81ccf8a
AG
4816 gen_store_spr(SPR_BOOKE_MAS7, val);
4817 tcg_temp_free(val);
4818}
4819
69b058c8 4820static void spr_read_mas73(DisasContext *ctx, int gprn, int sprn)
b81ccf8a
AG
4821{
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);
4830}
4831
b81ccf8a
AG
4832#endif
4833
f7aa5583
VS
4834enum fsl_e500_version {
4835 fsl_e500v1,
4836 fsl_e500v2,
4837 fsl_e500mc,
b81ccf8a 4838 fsl_e5500,
54a50dae 4839 fsl_e6500,
f7aa5583
VS
4840};
4841
c364946d 4842static void init_proc_e500(CPUPPCState *env, int version)
80d11f44 4843{
01662f3e 4844 uint32_t tlbncfg[2];
b81ccf8a 4845 uint64_t ivor_mask;
e9cd84b9 4846 uint64_t ivpr_mask = 0xFFFF0000ULL;
a496e8ee
AG
4847 uint32_t l1cfg0 = 0x3800 /* 8 ways */
4848 | 0x0020; /* 32 kb */
d2ea2bf7
AG
4849 uint32_t l1cfg1 = 0x3800 /* 8 ways */
4850 | 0x0020; /* 32 kb */
d21ee633 4851 uint32_t mmucfg = 0;
01662f3e
AG
4852#if !defined(CONFIG_USER_ONLY)
4853 int i;
4854#endif
4855
80d11f44
JM
4856 /* Time base */
4857 gen_tbl(env);
01662f3e
AG
4858 /*
4859 * XXX The e500 doesn't implement IVOR7 and IVOR9, but doesn't
4860 * complain when accessing them.
4861 * gen_spr_BookE(env, 0x0000000F0000FD7FULL);
4862 */
b81ccf8a 4863 switch (version) {
1d28b5f6
DG
4864 case fsl_e500v1:
4865 case fsl_e500v2:
4866 default:
4867 ivor_mask = 0x0000000F0000FFFFULL;
4868 break;
4869 case fsl_e500mc:
4870 case fsl_e5500:
4871 ivor_mask = 0x000003FE0000FFFFULL;
4872 break;
4873 case fsl_e6500:
4874 ivor_mask = 0x000003FF0000FFFFULL;
4875 break;
2c9732db
AG
4876 }
4877 gen_spr_BookE(env, ivor_mask);
b1c897d5 4878 gen_spr_usprg3(env);
80d11f44
JM
4879 /* Processor identification */
4880 spr_register(env, SPR_BOOKE_PIR, "PIR",
4881 SPR_NOACCESS, SPR_NOACCESS,
4882 &spr_read_generic, &spr_write_pir,
4883 0x00000000);
4884 /* XXX : not implemented */
4885 spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
d34defbc
AJ
4886 &spr_read_spefscr, &spr_write_spefscr,
4887 &spr_read_spefscr, &spr_write_spefscr,
80d11f44 4888 0x00000000);
892c587f 4889#if !defined(CONFIG_USER_ONLY)
80d11f44 4890 /* Memory management */
80d11f44 4891 env->nb_pids = 3;
01662f3e
AG
4892 env->nb_ways = 2;
4893 env->id_tlbs = 0;
4894 switch (version) {
f7aa5583 4895 case fsl_e500v1:
01662f3e
AG
4896 tlbncfg[0] = gen_tlbncfg(2, 1, 1, 0, 256);
4897 tlbncfg[1] = gen_tlbncfg(16, 1, 9, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16);
4898 break;
f7aa5583 4899 case fsl_e500v2:
01662f3e
AG
4900 tlbncfg[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4901 tlbncfg[1] = gen_tlbncfg(16, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16);
f7aa5583
VS
4902 break;
4903 case fsl_e500mc:
b81ccf8a 4904 case fsl_e5500:
f7aa5583
VS
4905 tlbncfg[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4906 tlbncfg[1] = gen_tlbncfg(64, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 64);
892c587f 4907 break;
54a50dae
KF
4908 case fsl_e6500:
4909 mmucfg = 0x6510B45;
4910 env->nb_pids = 1;
4911 tlbncfg[0] = 0x08052400;
4912 tlbncfg[1] = 0x40028040;
4913 break;
892c587f 4914 default:
db70b311 4915 cpu_abort(env_cpu(env), "Unknown CPU: " TARGET_FMT_lx "\n",
1d28b5f6 4916 env->spr[SPR_PVR]);
892c587f
AG
4917 }
4918#endif
4919 /* Cache sizes */
4920 switch (version) {
4921 case fsl_e500v1:
4922 case fsl_e500v2:
4923 env->dcache_line_size = 32;
4924 env->icache_line_size = 32;
4925 break;
4926 case fsl_e500mc:
b81ccf8a 4927 case fsl_e5500:
f7aa5583
VS
4928 env->dcache_line_size = 64;
4929 env->icache_line_size = 64;
a496e8ee 4930 l1cfg0 |= 0x1000000; /* 64 byte cache block size */
d2ea2bf7 4931 l1cfg1 |= 0x1000000; /* 64 byte cache block size */
01662f3e 4932 break;
54a50dae
KF
4933 case fsl_e6500:
4934 env->dcache_line_size = 32;
4935 env->icache_line_size = 32;
4936 l1cfg0 |= 0x0F83820;
4937 l1cfg1 |= 0x0B83820;
4938 break;
01662f3e 4939 default:
db70b311 4940 cpu_abort(env_cpu(env), "Unknown CPU: " TARGET_FMT_lx "\n",
1d28b5f6 4941 env->spr[SPR_PVR]);
01662f3e 4942 }
d21ee633 4943 gen_spr_BookE206(env, 0x000000DF, tlbncfg, mmucfg);
80d11f44
JM
4944 /* XXX : not implemented */
4945 spr_register(env, SPR_HID0, "HID0",
4946 SPR_NOACCESS, SPR_NOACCESS,
4947 &spr_read_generic, &spr_write_generic,
4948 0x00000000);
4949 /* XXX : not implemented */
4950 spr_register(env, SPR_HID1, "HID1",
4951 SPR_NOACCESS, SPR_NOACCESS,
4952 &spr_read_generic, &spr_write_generic,
4953 0x00000000);
4954 /* XXX : not implemented */
4955 spr_register(env, SPR_Exxx_BBEAR, "BBEAR",
4956 SPR_NOACCESS, SPR_NOACCESS,
4957 &spr_read_generic, &spr_write_generic,
4958 0x00000000);
4959 /* XXX : not implemented */
4960 spr_register(env, SPR_Exxx_BBTAR, "BBTAR",
4961 SPR_NOACCESS, SPR_NOACCESS,
4962 &spr_read_generic, &spr_write_generic,
4963 0x00000000);
4964 /* XXX : not implemented */
4965 spr_register(env, SPR_Exxx_MCAR, "MCAR",
4966 SPR_NOACCESS, SPR_NOACCESS,
4967 &spr_read_generic, &spr_write_generic,
4968 0x00000000);
578bb252 4969 /* XXX : not implemented */
a750fc0b
JM
4970 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
4971 SPR_NOACCESS, SPR_NOACCESS,
4972 &spr_read_generic, &spr_write_generic,
4973 0x00000000);
80d11f44
JM
4974 /* XXX : not implemented */
4975 spr_register(env, SPR_Exxx_NPIDR, "NPIDR",
a750fc0b
JM
4976 SPR_NOACCESS, SPR_NOACCESS,
4977 &spr_read_generic, &spr_write_generic,
4978 0x00000000);
80d11f44
JM
4979 /* XXX : not implemented */
4980 spr_register(env, SPR_Exxx_BUCSR, "BUCSR",
a750fc0b
JM
4981 SPR_NOACCESS, SPR_NOACCESS,
4982 &spr_read_generic, &spr_write_generic,
4983 0x00000000);
578bb252 4984 /* XXX : not implemented */
80d11f44 4985 spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0",
deb05c4c
AG
4986 &spr_read_generic, SPR_NOACCESS,
4987 &spr_read_generic, SPR_NOACCESS,
a496e8ee 4988 l1cfg0);
d2ea2bf7
AG
4989 spr_register(env, SPR_Exxx_L1CFG1, "L1CFG1",
4990 &spr_read_generic, SPR_NOACCESS,
4991 &spr_read_generic, SPR_NOACCESS,
4992 l1cfg1);
80d11f44
JM
4993 spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0",
4994 SPR_NOACCESS, SPR_NOACCESS,
01662f3e 4995 &spr_read_generic, &spr_write_e500_l1csr0,
80d11f44 4996 0x00000000);
80d11f44
JM
4997 spr_register(env, SPR_Exxx_L1CSR1, "L1CSR1",
4998 SPR_NOACCESS, SPR_NOACCESS,
ea71258d 4999 &spr_read_generic, &spr_write_e500_l1csr1,
80d11f44 5000 0x00000000);
80d11f44
JM
5001 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
5002 SPR_NOACCESS, SPR_NOACCESS,
5003 &spr_read_generic, &spr_write_generic,
5004 0x00000000);
5005 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
5006 SPR_NOACCESS, SPR_NOACCESS,
a750fc0b
JM
5007 &spr_read_generic, &spr_write_generic,
5008 0x00000000);
01662f3e
AG
5009 spr_register(env, SPR_MMUCSR0, "MMUCSR0",
5010 SPR_NOACCESS, SPR_NOACCESS,
5011 &spr_read_generic, &spr_write_booke206_mmucsr0,
5012 0x00000000);
b81ccf8a
AG
5013 spr_register(env, SPR_BOOKE_EPR, "EPR",
5014 SPR_NOACCESS, SPR_NOACCESS,
68c2dd70 5015 &spr_read_generic, SPR_NOACCESS,
b81ccf8a
AG
5016 0x00000000);
5017 /* XXX better abstract into Emb.xxx features */
54a50dae 5018 if ((version == fsl_e5500) || (version == fsl_e6500)) {
b81ccf8a
AG
5019 spr_register(env, SPR_BOOKE_EPCR, "EPCR",
5020 SPR_NOACCESS, SPR_NOACCESS,
5021 &spr_read_generic, &spr_write_generic,
5022 0x00000000);
5023 spr_register(env, SPR_BOOKE_MAS7_MAS3, "MAS7_MAS3",
5024 SPR_NOACCESS, SPR_NOACCESS,
5025 &spr_read_mas73, &spr_write_mas73,
5026 0x00000000);
5027 ivpr_mask = (target_ulong)~0xFFFFULL;
5028 }
01662f3e 5029
54a50dae 5030 if (version == fsl_e6500) {
54a50dae
KF
5031 /* Thread identification */
5032 spr_register(env, SPR_TIR, "TIR",
5033 SPR_NOACCESS, SPR_NOACCESS,
5034 &spr_read_generic, SPR_NOACCESS,
5035 0x00000000);
5036 spr_register(env, SPR_BOOKE_TLB0PS, "TLB0PS",
5037 SPR_NOACCESS, SPR_NOACCESS,
5038 &spr_read_generic, SPR_NOACCESS,
5039 0x00000004);
5040 spr_register(env, SPR_BOOKE_TLB1PS, "TLB1PS",
5041 SPR_NOACCESS, SPR_NOACCESS,
5042 &spr_read_generic, SPR_NOACCESS,
5043 0x7FFFFFFC);
5044 }
5045
f2e63a42 5046#if !defined(CONFIG_USER_ONLY)
01662f3e 5047 env->nb_tlb = 0;
1c53accc 5048 env->tlb_type = TLB_MAS;
01662f3e
AG
5049 for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
5050 env->nb_tlb += booke206_tlb_size(env, i);
5051 }
f2e63a42 5052#endif
01662f3e 5053
e9cd84b9 5054 init_excp_e200(env, ivpr_mask);
9fdc60bf 5055 /* Allocate hardware IRQ controller */
db70b311 5056 ppce500_irq_init(env_archcpu(env));
3fc6c082 5057}
a750fc0b 5058
01662f3e
AG
5059static void init_proc_e500v1(CPUPPCState *env)
5060{
f7aa5583 5061 init_proc_e500(env, fsl_e500v1);
01662f3e
AG
5062}
5063
7856e3a4
AF
5064POWERPC_FAMILY(e500v1)(ObjectClass *oc, void *data)
5065{
ca5dff0a 5066 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5067 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5068
ca5dff0a 5069 dc->desc = "e500v1 core";
7856e3a4
AF
5070 pcc->init_proc = init_proc_e500v1;
5071 pcc->check_pow = check_pow_hid0;
53116ebf
AF
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;
9df5a466
TM
5079 pcc->msr_mask = (1ull << MSR_UCLE) |
5080 (1ull << MSR_SPE) |
5081 (1ull << MSR_POW) |
5082 (1ull << MSR_CE) |
5083 (1ull << MSR_EE) |
5084 (1ull << MSR_PR) |
5085 (1ull << MSR_FP) |
5086 (1ull << MSR_ME) |
5087 (1ull << MSR_FE0) |
5088 (1ull << MSR_DWE) |
5089 (1ull << MSR_DE) |
5090 (1ull << MSR_FE1) |
5091 (1ull << MSR_IR) |
5092 (1ull << MSR_DR);
ba9fd9f1
AF
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;
7856e3a4
AF
5100}
5101
01662f3e
AG
5102static void init_proc_e500v2(CPUPPCState *env)
5103{
f7aa5583
VS
5104 init_proc_e500(env, fsl_e500v2);
5105}
5106
7856e3a4
AF
5107POWERPC_FAMILY(e500v2)(ObjectClass *oc, void *data)
5108{
ca5dff0a 5109 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5110 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5111
ca5dff0a 5112 dc->desc = "e500v2 core";
7856e3a4
AF
5113 pcc->init_proc = init_proc_e500v2;
5114 pcc->check_pow = check_pow_hid0;
53116ebf
AF
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;
9df5a466
TM
5122 pcc->msr_mask = (1ull << MSR_UCLE) |
5123 (1ull << MSR_SPE) |
5124 (1ull << MSR_POW) |
5125 (1ull << MSR_CE) |
5126 (1ull << MSR_EE) |
5127 (1ull << MSR_PR) |
5128 (1ull << MSR_FP) |
5129 (1ull << MSR_ME) |
5130 (1ull << MSR_FE0) |
5131 (1ull << MSR_DWE) |
5132 (1ull << MSR_DE) |
5133 (1ull << MSR_FE1) |
5134 (1ull << MSR_IR) |
5135 (1ull << MSR_DR);
ba9fd9f1
AF
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;
7856e3a4
AF
5143}
5144
f7aa5583
VS
5145static void init_proc_e500mc(CPUPPCState *env)
5146{
5147 init_proc_e500(env, fsl_e500mc);
01662f3e
AG
5148}
5149
7856e3a4
AF
5150POWERPC_FAMILY(e500mc)(ObjectClass *oc, void *data)
5151{
ca5dff0a 5152 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5153 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5154
ca5dff0a 5155 dc->desc = "e500mc core";
7856e3a4
AF
5156 pcc->init_proc = init_proc_e500mc;
5157 pcc->check_pow = check_pow_none;
2fff4bad 5158 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
53116ebf
AF
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;
9df5a466
TM
5167 pcc->msr_mask = (1ull << MSR_GS) |
5168 (1ull << MSR_UCLE) |
5169 (1ull << MSR_CE) |
5170 (1ull << MSR_EE) |
5171 (1ull << MSR_PR) |
5172 (1ull << MSR_FP) |
5173 (1ull << MSR_ME) |
5174 (1ull << MSR_FE0) |
5175 (1ull << MSR_DE) |
5176 (1ull << MSR_FE1) |
5177 (1ull << MSR_IR) |
5178 (1ull << MSR_DR) |
5179 (1ull << MSR_PX) |
5180 (1ull << MSR_RI);
ba9fd9f1
AF
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;
7856e3a4
AF
5188}
5189
b81ccf8a
AG
5190#ifdef TARGET_PPC64
5191static void init_proc_e5500(CPUPPCState *env)
5192{
5193 init_proc_e500(env, fsl_e5500);
5194}
7856e3a4
AF
5195
5196POWERPC_FAMILY(e5500)(ObjectClass *oc, void *data)
5197{
ca5dff0a 5198 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5199 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5200
ca5dff0a 5201 dc->desc = "e5500 core";
7856e3a4
AF
5202 pcc->init_proc = init_proc_e5500;
5203 pcc->check_pow = check_pow_none;
2fff4bad 5204 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
53116ebf
AF
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;
4171853c
PM
5213 pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL | PPC2_PERM_ISA206 | \
5214 PPC2_FP_CVT_S64;
9df5a466
TM
5215 pcc->msr_mask = (1ull << MSR_CM) |
5216 (1ull << MSR_GS) |
5217 (1ull << MSR_UCLE) |
5218 (1ull << MSR_CE) |
5219 (1ull << MSR_EE) |
5220 (1ull << MSR_PR) |
5221 (1ull << MSR_FP) |
5222 (1ull << MSR_ME) |
5223 (1ull << MSR_FE0) |
5224 (1ull << MSR_DE) |
5225 (1ull << MSR_FE1) |
5226 (1ull << MSR_IR) |
5227 (1ull << MSR_DR) |
5228 (1ull << MSR_PX) |
5229 (1ull << MSR_RI);
ba9fd9f1
AF
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;
7856e3a4 5237}
54a50dae
KF
5238
5239static void init_proc_e6500(CPUPPCState *env)
5240{
5241 init_proc_e500(env, fsl_e6500);
5242}
5243
5244POWERPC_FAMILY(e6500)(ObjectClass *oc, void *data)
5245{
5246 DeviceClass *dc = DEVICE_CLASS(oc);
5247 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5248
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) |
5264 (1ull << MSR_GS) |
5265 (1ull << MSR_UCLE) |
5266 (1ull << MSR_CE) |
5267 (1ull << MSR_EE) |
5268 (1ull << MSR_PR) |
5269 (1ull << MSR_FP) |
5270 (1ull << MSR_ME) |
5271 (1ull << MSR_FE0) |
5272 (1ull << MSR_DE) |
5273 (1ull << MSR_FE1) |
5274 (1ull << MSR_IS) |
5275 (1ull << MSR_DS) |
5276 (1ull << MSR_PX) |
5277 (1ull << MSR_RI) |
5278 (1ull << MSR_VR);
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;
5285}
5286
b81ccf8a
AG
5287#endif
5288
a750fc0b 5289/* Non-embedded PowerPC */
a750fc0b 5290
082c6681 5291#define POWERPC_MSRR_601 (0x0000000000001040ULL)
a750fc0b 5292
c364946d 5293static void init_proc_601(CPUPPCState *env)
3fc6c082 5294{
a750fc0b 5295 gen_spr_ne_601(env);
4f4f28ff 5296 gen_spr_sdr1(env);
a750fc0b
JM
5297 gen_spr_601(env);
5298 /* Hardware implementation registers */
5299 /* XXX : not implemented */
5300 spr_register(env, SPR_HID0, "HID0",
5301 SPR_NOACCESS, SPR_NOACCESS,
056401ea 5302 &spr_read_generic, &spr_write_hid0_601,
faadf50e 5303 0x80010080);
a750fc0b
JM
5304 /* XXX : not implemented */
5305 spr_register(env, SPR_HID1, "HID1",
5306 SPR_NOACCESS, SPR_NOACCESS,
5307 &spr_read_generic, &spr_write_generic,
5308 0x00000000);
5309 /* XXX : not implemented */
5310 spr_register(env, SPR_601_HID2, "HID2",
5311 SPR_NOACCESS, SPR_NOACCESS,
5312 &spr_read_generic, &spr_write_generic,
5313 0x00000000);
5314 /* XXX : not implemented */
5315 spr_register(env, SPR_601_HID5, "HID5",
5316 SPR_NOACCESS, SPR_NOACCESS,
5317 &spr_read_generic, &spr_write_generic,
5318 0x00000000);
a750fc0b 5319 /* Memory management */
e1833e1f 5320 init_excp_601(env);
1d28b5f6
DG
5321 /*
5322 * XXX: beware that dcache line size is 64
082c6681
JM
5323 * but dcbz uses 32 bytes "sectors"
5324 * XXX: this breaks clcs instruction !
5325 */
5326 env->dcache_line_size = 32;
d63001d1 5327 env->icache_line_size = 64;
faadf50e 5328 /* Allocate hardware IRQ controller */
db70b311 5329 ppc6xx_irq_init(env_archcpu(env));
3fc6c082
FB
5330}
5331
7856e3a4
AF
5332POWERPC_FAMILY(601)(ObjectClass *oc, void *data)
5333{
ca5dff0a 5334 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5335 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5336
ca5dff0a 5337 dc->desc = "PowerPC 601";
7856e3a4
AF
5338 pcc->init_proc = init_proc_601;
5339 pcc->check_pow = check_pow_none;
53116ebf
AF
5340 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
5341 PPC_FLOAT |
5342 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5343 PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
5344 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
5345 pcc->msr_mask = (1ull << MSR_EE) |
5346 (1ull << MSR_PR) |
5347 (1ull << MSR_FP) |
5348 (1ull << MSR_ME) |
5349 (1ull << MSR_FE0) |
5350 (1ull << MSR_SE) |
5351 (1ull << MSR_FE1) |
5352 (1ull << MSR_EP) |
5353 (1ull << MSR_IR) |
5354 (1ull << MSR_DR);
ba9fd9f1 5355 pcc->mmu_model = POWERPC_MMU_601;
b632a148
DG
5356#if defined(CONFIG_SOFTMMU)
5357 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5358#endif
ba9fd9f1
AF
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;
7856e3a4
AF
5363}
5364
082c6681 5365#define POWERPC_MSRR_601v (0x0000000000001040ULL)
082c6681 5366
c364946d 5367static void init_proc_601v(CPUPPCState *env)
082c6681
JM
5368{
5369 init_proc_601(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,
5374 0x00000000);
5375}
5376
7856e3a4
AF
5377POWERPC_FAMILY(601v)(ObjectClass *oc, void *data)
5378{
ca5dff0a 5379 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5380 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5381
ca5dff0a 5382 dc->desc = "PowerPC 601v";
7856e3a4
AF
5383 pcc->init_proc = init_proc_601v;
5384 pcc->check_pow = check_pow_none;
53116ebf
AF
5385 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
5386 PPC_FLOAT |
5387 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5388 PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
5389 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
5390 pcc->msr_mask = (1ull << MSR_EE) |
5391 (1ull << MSR_PR) |
5392 (1ull << MSR_FP) |
5393 (1ull << MSR_ME) |
5394 (1ull << MSR_FE0) |
5395 (1ull << MSR_SE) |
5396 (1ull << MSR_FE1) |
5397 (1ull << MSR_EP) |
5398 (1ull << MSR_IR) |
5399 (1ull << MSR_DR);
ba9fd9f1 5400 pcc->mmu_model = POWERPC_MMU_601;
b632a148
DG
5401#if defined(CONFIG_SOFTMMU)
5402 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5403#endif
ba9fd9f1
AF
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;
7856e3a4
AF
5407}
5408
c364946d 5409static void init_proc_602(CPUPPCState *env)
3fc6c082 5410{
a750fc0b 5411 gen_spr_ne_601(env);
4f4f28ff 5412 gen_spr_sdr1(env);
a750fc0b
JM
5413 gen_spr_602(env);
5414 /* Time base */
5415 gen_tbl(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,
5421 0x00000000);
5422 /* XXX : not implemented */
5423 spr_register(env, SPR_HID1, "HID1",
5424 SPR_NOACCESS, SPR_NOACCESS,
5425 &spr_read_generic, &spr_write_generic,
5426 0x00000000);
5427 /* Memory management */
5428 gen_low_BATs(env);
5429 gen_6xx_7xx_soft_tlb(env, 64, 2);
e1833e1f 5430 init_excp_602(env);
d63001d1
JM
5431 env->dcache_line_size = 32;
5432 env->icache_line_size = 32;
a750fc0b 5433 /* Allocate hardware IRQ controller */
db70b311 5434 ppc6xx_irq_init(env_archcpu(env));
a750fc0b 5435}
3fc6c082 5436
7856e3a4
AF
5437POWERPC_FAMILY(602)(ObjectClass *oc, void *data)
5438{
ca5dff0a 5439 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5440 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5441
ca5dff0a 5442 dc->desc = "PowerPC 602";
7856e3a4
AF
5443 pcc->init_proc = init_proc_602;
5444 pcc->check_pow = check_pow_hid0;
53116ebf
AF
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;
9df5a466
TM
5452 pcc->msr_mask = (1ull << MSR_VSX) |
5453 (1ull << MSR_SA) |
5454 (1ull << MSR_POW) |
5455 (1ull << MSR_TGPR) |
5456 (1ull << MSR_ILE) |
5457 (1ull << MSR_EE) |
5458 (1ull << MSR_PR) |
5459 (1ull << MSR_FP) |
5460 (1ull << MSR_ME) |
5461 (1ull << MSR_FE0) |
5462 (1ull << MSR_SE) |
5463 (1ull << MSR_DE) |
5464 (1ull << MSR_FE1) |
5465 (1ull << MSR_EP) |
5466 (1ull << MSR_IR) |
5467 (1ull << MSR_DR) |
5468 (1ull << MSR_RI) |
5469 (1ull << MSR_LE);
ba9fd9f1
AF
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;
7856e3a4
AF
5477}
5478
c364946d 5479static void init_proc_603(CPUPPCState *env)
a750fc0b
JM
5480{
5481 gen_spr_ne_601(env);
4f4f28ff 5482 gen_spr_sdr1(env);
a750fc0b
JM
5483 gen_spr_603(env);
5484 /* Time base */
5485 gen_tbl(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,
5491 0x00000000);
5492 /* XXX : not implemented */
5493 spr_register(env, SPR_HID1, "HID1",
5494 SPR_NOACCESS, SPR_NOACCESS,
5495 &spr_read_generic, &spr_write_generic,
5496 0x00000000);
5497 /* Memory management */
5498 gen_low_BATs(env);
5499 gen_6xx_7xx_soft_tlb(env, 64, 2);
e1833e1f 5500 init_excp_603(env);
d63001d1
JM
5501 env->dcache_line_size = 32;
5502 env->icache_line_size = 32;
a750fc0b 5503 /* Allocate hardware IRQ controller */
db70b311 5504 ppc6xx_irq_init(env_archcpu(env));
3fc6c082
FB
5505}
5506
7856e3a4
AF
5507POWERPC_FAMILY(603)(ObjectClass *oc, void *data)
5508{
ca5dff0a 5509 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5510 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5511
ca5dff0a 5512 dc->desc = "PowerPC 603";
7856e3a4
AF
5513 pcc->init_proc = init_proc_603;
5514 pcc->check_pow = check_pow_hid0;
53116ebf
AF
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;
9df5a466
TM
5522 pcc->msr_mask = (1ull << MSR_POW) |
5523 (1ull << MSR_TGPR) |
5524 (1ull << MSR_ILE) |
5525 (1ull << MSR_EE) |
5526 (1ull << MSR_PR) |
5527 (1ull << MSR_FP) |
5528 (1ull << MSR_ME) |
5529 (1ull << MSR_FE0) |
5530 (1ull << MSR_SE) |
5531 (1ull << MSR_DE) |
5532 (1ull << MSR_FE1) |
5533 (1ull << MSR_EP) |
5534 (1ull << MSR_IR) |
5535 (1ull << MSR_DR) |
5536 (1ull << MSR_RI) |
5537 (1ull << MSR_LE);
ba9fd9f1
AF
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;
7856e3a4
AF
5544}
5545
c364946d 5546static void init_proc_603E(CPUPPCState *env)
a750fc0b
JM
5547{
5548 gen_spr_ne_601(env);
4f4f28ff 5549 gen_spr_sdr1(env);
a750fc0b
JM
5550 gen_spr_603(env);
5551 /* Time base */
5552 gen_tbl(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,
5558 0x00000000);
5559 /* XXX : not implemented */
5560 spr_register(env, SPR_HID1, "HID1",
5561 SPR_NOACCESS, SPR_NOACCESS,
5562 &spr_read_generic, &spr_write_generic,
5563 0x00000000);
a750fc0b
JM
5564 /* Memory management */
5565 gen_low_BATs(env);
5566 gen_6xx_7xx_soft_tlb(env, 64, 2);
e1833e1f 5567 init_excp_603(env);
d63001d1
JM
5568 env->dcache_line_size = 32;
5569 env->icache_line_size = 32;
a750fc0b 5570 /* Allocate hardware IRQ controller */
db70b311 5571 ppc6xx_irq_init(env_archcpu(env));
a750fc0b
JM
5572}
5573
7856e3a4
AF
5574POWERPC_FAMILY(603E)(ObjectClass *oc, void *data)
5575{
ca5dff0a 5576 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5577 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5578
ca5dff0a 5579 dc->desc = "PowerPC 603e";
7856e3a4
AF
5580 pcc->init_proc = init_proc_603E;
5581 pcc->check_pow = check_pow_hid0;
53116ebf
AF
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;
9df5a466
TM
5589 pcc->msr_mask = (1ull << MSR_POW) |
5590 (1ull << MSR_TGPR) |
5591 (1ull << MSR_ILE) |
5592 (1ull << MSR_EE) |
5593 (1ull << MSR_PR) |
5594 (1ull << MSR_FP) |
5595 (1ull << MSR_ME) |
5596 (1ull << MSR_FE0) |
5597 (1ull << MSR_SE) |
5598 (1ull << MSR_DE) |
5599 (1ull << MSR_FE1) |
5600 (1ull << MSR_EP) |
5601 (1ull << MSR_IR) |
5602 (1ull << MSR_DR) |
5603 (1ull << MSR_RI) |
5604 (1ull << MSR_LE);
ba9fd9f1
AF
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;
7856e3a4
AF
5611}
5612
c364946d 5613static void init_proc_604(CPUPPCState *env)
a750fc0b
JM
5614{
5615 gen_spr_ne_601(env);
4f4f28ff 5616 gen_spr_sdr1(env);
a750fc0b
JM
5617 gen_spr_604(env);
5618 /* Time base */
5619 gen_tbl(env);
5620 /* Hardware implementation registers */
5621 /* XXX : not implemented */
082c6681
JM
5622 spr_register(env, SPR_HID0, "HID0",
5623 SPR_NOACCESS, SPR_NOACCESS,
5624 &spr_read_generic, &spr_write_generic,
5625 0x00000000);
5626 /* Memory management */
5627 gen_low_BATs(env);
5628 init_excp_604(env);
5629 env->dcache_line_size = 32;
5630 env->icache_line_size = 32;
5631 /* Allocate hardware IRQ controller */
db70b311 5632 ppc6xx_irq_init(env_archcpu(env));
082c6681
JM
5633}
5634
7856e3a4
AF
5635POWERPC_FAMILY(604)(ObjectClass *oc, void *data)
5636{
ca5dff0a 5637 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5638 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5639
ca5dff0a 5640 dc->desc = "PowerPC 604";
7856e3a4
AF
5641 pcc->init_proc = init_proc_604;
5642 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
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;
9df5a466
TM
5650 pcc->msr_mask = (1ull << MSR_POW) |
5651 (1ull << MSR_ILE) |
5652 (1ull << MSR_EE) |
5653 (1ull << MSR_PR) |
5654 (1ull << MSR_FP) |
5655 (1ull << MSR_ME) |
5656 (1ull << MSR_FE0) |
5657 (1ull << MSR_SE) |
5658 (1ull << MSR_DE) |
5659 (1ull << MSR_FE1) |
5660 (1ull << MSR_EP) |
5661 (1ull << MSR_IR) |
5662 (1ull << MSR_DR) |
5663 (1ull << MSR_PMM) |
5664 (1ull << MSR_RI) |
5665 (1ull << MSR_LE);
ba9fd9f1 5666 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
5667#if defined(CONFIG_SOFTMMU)
5668 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5669#endif
ba9fd9f1
AF
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;
7856e3a4
AF
5675}
5676
c364946d 5677static void init_proc_604E(CPUPPCState *env)
082c6681
JM
5678{
5679 gen_spr_ne_601(env);
4f4f28ff 5680 gen_spr_sdr1(env);
082c6681
JM
5681 gen_spr_604(env);
5682 /* XXX : not implemented */
cb8b8bf8 5683 spr_register(env, SPR_7XX_MMCR1, "MMCR1",
082c6681
JM
5684 SPR_NOACCESS, SPR_NOACCESS,
5685 &spr_read_generic, &spr_write_generic,
5686 0x00000000);
5687 /* XXX : not implemented */
cb8b8bf8 5688 spr_register(env, SPR_7XX_PMC3, "PMC3",
082c6681
JM
5689 SPR_NOACCESS, SPR_NOACCESS,
5690 &spr_read_generic, &spr_write_generic,
5691 0x00000000);
5692 /* XXX : not implemented */
cb8b8bf8 5693 spr_register(env, SPR_7XX_PMC4, "PMC4",
082c6681
JM
5694 SPR_NOACCESS, SPR_NOACCESS,
5695 &spr_read_generic, &spr_write_generic,
5696 0x00000000);
5697 /* Time base */
5698 gen_tbl(env);
5699 /* Hardware implementation registers */
5700 /* XXX : not implemented */
a750fc0b
JM
5701 spr_register(env, SPR_HID0, "HID0",
5702 SPR_NOACCESS, SPR_NOACCESS,
5703 &spr_read_generic, &spr_write_generic,
5704 0x00000000);
5705 /* XXX : not implemented */
5706 spr_register(env, SPR_HID1, "HID1",
5707 SPR_NOACCESS, SPR_NOACCESS,
5708 &spr_read_generic, &spr_write_generic,
5709 0x00000000);
5710 /* Memory management */
5711 gen_low_BATs(env);
e1833e1f 5712 init_excp_604(env);
d63001d1
JM
5713 env->dcache_line_size = 32;
5714 env->icache_line_size = 32;
a750fc0b 5715 /* Allocate hardware IRQ controller */
db70b311 5716 ppc6xx_irq_init(env_archcpu(env));
a750fc0b
JM
5717}
5718
7856e3a4
AF
5719POWERPC_FAMILY(604E)(ObjectClass *oc, void *data)
5720{
ca5dff0a 5721 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5722 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5723
ca5dff0a 5724 dc->desc = "PowerPC 604E";
7856e3a4
AF
5725 pcc->init_proc = init_proc_604E;
5726 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
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;
9df5a466
TM
5734 pcc->msr_mask = (1ull << MSR_POW) |
5735 (1ull << MSR_ILE) |
5736 (1ull << MSR_EE) |
5737 (1ull << MSR_PR) |
5738 (1ull << MSR_FP) |
5739 (1ull << MSR_ME) |
5740 (1ull << MSR_FE0) |
5741 (1ull << MSR_SE) |
5742 (1ull << MSR_DE) |
5743 (1ull << MSR_FE1) |
5744 (1ull << MSR_EP) |
5745 (1ull << MSR_IR) |
5746 (1ull << MSR_DR) |
5747 (1ull << MSR_PMM) |
5748 (1ull << MSR_RI) |
5749 (1ull << MSR_LE);
ba9fd9f1 5750 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
5751#if defined(CONFIG_SOFTMMU)
5752 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5753#endif
ba9fd9f1
AF
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;
7856e3a4
AF
5759}
5760
c364946d 5761static void init_proc_740(CPUPPCState *env)
a750fc0b
JM
5762{
5763 gen_spr_ne_601(env);
4f4f28ff 5764 gen_spr_sdr1(env);
a750fc0b
JM
5765 gen_spr_7xx(env);
5766 /* Time base */
5767 gen_tbl(env);
5768 /* Thermal management */
5769 gen_spr_thrm(env);
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,
5775 0x00000000);
5776 /* XXX : not implemented */
5777 spr_register(env, SPR_HID1, "HID1",
5778 SPR_NOACCESS, SPR_NOACCESS,
5779 &spr_read_generic, &spr_write_generic,
5780 0x00000000);
5781 /* Memory management */
5782 gen_low_BATs(env);
e1833e1f 5783 init_excp_7x0(env);
d63001d1
JM
5784 env->dcache_line_size = 32;
5785 env->icache_line_size = 32;
a750fc0b 5786 /* Allocate hardware IRQ controller */
db70b311 5787 ppc6xx_irq_init(env_archcpu(env));
a750fc0b
JM
5788}
5789
7856e3a4
AF
5790POWERPC_FAMILY(740)(ObjectClass *oc, void *data)
5791{
ca5dff0a 5792 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5793 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5794
ca5dff0a 5795 dc->desc = "PowerPC 740";
7856e3a4
AF
5796 pcc->init_proc = init_proc_740;
5797 pcc->check_pow = check_pow_hid0;
53116ebf
AF
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;
9df5a466
TM
5805 pcc->msr_mask = (1ull << MSR_POW) |
5806 (1ull << MSR_ILE) |
5807 (1ull << MSR_EE) |
5808 (1ull << MSR_PR) |
5809 (1ull << MSR_FP) |
5810 (1ull << MSR_ME) |
5811 (1ull << MSR_FE0) |
5812 (1ull << MSR_SE) |
5813 (1ull << MSR_DE) |
5814 (1ull << MSR_FE1) |
5815 (1ull << MSR_EP) |
5816 (1ull << MSR_IR) |
5817 (1ull << MSR_DR) |
5818 (1ull << MSR_PMM) |
5819 (1ull << MSR_RI) |
5820 (1ull << MSR_LE);
ba9fd9f1 5821 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
5822#if defined(CONFIG_SOFTMMU)
5823 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5824#endif
ba9fd9f1
AF
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;
7856e3a4
AF
5830}
5831
c364946d 5832static void init_proc_750(CPUPPCState *env)
bd928eba
JM
5833{
5834 gen_spr_ne_601(env);
4f4f28ff 5835 gen_spr_sdr1(env);
bd928eba
JM
5836 gen_spr_7xx(env);
5837 /* XXX : not implemented */
5838 spr_register(env, SPR_L2CR, "L2CR",
5839 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 5840 &spr_read_generic, spr_access_nop,
bd928eba
JM
5841 0x00000000);
5842 /* Time base */
5843 gen_tbl(env);
5844 /* Thermal management */
5845 gen_spr_thrm(env);
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,
5851 0x00000000);
5852 /* XXX : not implemented */
5853 spr_register(env, SPR_HID1, "HID1",
5854 SPR_NOACCESS, SPR_NOACCESS,
5855 &spr_read_generic, &spr_write_generic,
5856 0x00000000);
5857 /* Memory management */
5858 gen_low_BATs(env);
1d28b5f6
DG
5859 /*
5860 * XXX: high BATs are also present but are known to be bugged on
bd928eba
JM
5861 * die version 1.x
5862 */
5863 init_excp_7x0(env);
5864 env->dcache_line_size = 32;
5865 env->icache_line_size = 32;
5866 /* Allocate hardware IRQ controller */
db70b311 5867 ppc6xx_irq_init(env_archcpu(env));
bd928eba
JM
5868}
5869
7856e3a4
AF
5870POWERPC_FAMILY(750)(ObjectClass *oc, void *data)
5871{
ca5dff0a 5872 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5873 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5874
ca5dff0a 5875 dc->desc = "PowerPC 750";
7856e3a4
AF
5876 pcc->init_proc = init_proc_750;
5877 pcc->check_pow = check_pow_hid0;
53116ebf
AF
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;
9df5a466
TM
5885 pcc->msr_mask = (1ull << MSR_POW) |
5886 (1ull << MSR_ILE) |
5887 (1ull << MSR_EE) |
5888 (1ull << MSR_PR) |
5889 (1ull << MSR_FP) |
5890 (1ull << MSR_ME) |
5891 (1ull << MSR_FE0) |
5892 (1ull << MSR_SE) |
5893 (1ull << MSR_DE) |
5894 (1ull << MSR_FE1) |
5895 (1ull << MSR_EP) |
5896 (1ull << MSR_IR) |
5897 (1ull << MSR_DR) |
5898 (1ull << MSR_PMM) |
5899 (1ull << MSR_RI) |
5900 (1ull << MSR_LE);
ba9fd9f1 5901 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
5902#if defined(CONFIG_SOFTMMU)
5903 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5904#endif
ba9fd9f1
AF
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;
7856e3a4
AF
5910}
5911
c364946d 5912static void init_proc_750cl(CPUPPCState *env)
bd928eba
JM
5913{
5914 gen_spr_ne_601(env);
4f4f28ff 5915 gen_spr_sdr1(env);
bd928eba
JM
5916 gen_spr_7xx(env);
5917 /* XXX : not implemented */
5918 spr_register(env, SPR_L2CR, "L2CR",
5919 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 5920 &spr_read_generic, spr_access_nop,
bd928eba
JM
5921 0x00000000);
5922 /* Time base */
5923 gen_tbl(env);
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,
5929 0x00000000);
5930 spr_register(env, SPR_THRM2, "THRM2",
5931 SPR_NOACCESS, SPR_NOACCESS,
5932 &spr_read_generic, &spr_write_generic,
5933 0x00000000);
5934 spr_register(env, SPR_THRM3, "THRM3",
5935 SPR_NOACCESS, SPR_NOACCESS,
5936 &spr_read_generic, &spr_write_generic,
5937 0x00000000);
5938 /* XXX: not implemented */
5939 spr_register(env, SPR_750_TDCL, "TDCL",
5940 SPR_NOACCESS, SPR_NOACCESS,
5941 &spr_read_generic, &spr_write_generic,
5942 0x00000000);
5943 spr_register(env, SPR_750_TDCH, "TDCH",
5944 SPR_NOACCESS, SPR_NOACCESS,
5945 &spr_read_generic, &spr_write_generic,
5946 0x00000000);
5947 /* DMA */
5948 /* XXX : not implemented */
5949 spr_register(env, SPR_750_WPAR, "WPAR",
5950 SPR_NOACCESS, SPR_NOACCESS,
5951 &spr_read_generic, &spr_write_generic,
5952 0x00000000);
5953 spr_register(env, SPR_750_DMAL, "DMAL",
5954 SPR_NOACCESS, SPR_NOACCESS,
5955 &spr_read_generic, &spr_write_generic,
5956 0x00000000);
5957 spr_register(env, SPR_750_DMAU, "DMAU",
5958 SPR_NOACCESS, SPR_NOACCESS,
5959 &spr_read_generic, &spr_write_generic,
5960 0x00000000);
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,
5966 0x00000000);
5967 /* XXX : not implemented */
5968 spr_register(env, SPR_HID1, "HID1",
5969 SPR_NOACCESS, SPR_NOACCESS,
5970 &spr_read_generic, &spr_write_generic,
5971 0x00000000);
5972 /* XXX : not implemented */
5973 spr_register(env, SPR_750CL_HID2, "HID2",
5974 SPR_NOACCESS, SPR_NOACCESS,
5975 &spr_read_generic, &spr_write_generic,
5976 0x00000000);
5977 /* XXX : not implemented */
5978 spr_register(env, SPR_750CL_HID4, "HID4",
5979 SPR_NOACCESS, SPR_NOACCESS,
5980 &spr_read_generic, &spr_write_generic,
5981 0x00000000);
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,
5987 0x00000000);
5988 /* XXX : not implemented */
5989 spr_register(env, SPR_750_GQR1, "GQR1",
5990 SPR_NOACCESS, SPR_NOACCESS,
5991 &spr_read_generic, &spr_write_generic,
5992 0x00000000);
5993 /* XXX : not implemented */
5994 spr_register(env, SPR_750_GQR2, "GQR2",
5995 SPR_NOACCESS, SPR_NOACCESS,
5996 &spr_read_generic, &spr_write_generic,
5997 0x00000000);
5998 /* XXX : not implemented */
5999 spr_register(env, SPR_750_GQR3, "GQR3",
6000 SPR_NOACCESS, SPR_NOACCESS,
6001 &spr_read_generic, &spr_write_generic,
6002 0x00000000);
6003 /* XXX : not implemented */
6004 spr_register(env, SPR_750_GQR4, "GQR4",
6005 SPR_NOACCESS, SPR_NOACCESS,
6006 &spr_read_generic, &spr_write_generic,
6007 0x00000000);
6008 /* XXX : not implemented */
6009 spr_register(env, SPR_750_GQR5, "GQR5",
6010 SPR_NOACCESS, SPR_NOACCESS,
6011 &spr_read_generic, &spr_write_generic,
6012 0x00000000);
6013 /* XXX : not implemented */
6014 spr_register(env, SPR_750_GQR6, "GQR6",
6015 SPR_NOACCESS, SPR_NOACCESS,
6016 &spr_read_generic, &spr_write_generic,
6017 0x00000000);
6018 /* XXX : not implemented */
6019 spr_register(env, SPR_750_GQR7, "GQR7",
6020 SPR_NOACCESS, SPR_NOACCESS,
6021 &spr_read_generic, &spr_write_generic,
6022 0x00000000);
6023 /* Memory management */
6024 gen_low_BATs(env);
6025 /* PowerPC 750cl has 8 DBATs and 8 IBATs */
6026 gen_high_BATs(env);
6027 init_excp_750cl(env);
6028 env->dcache_line_size = 32;
6029 env->icache_line_size = 32;
6030 /* Allocate hardware IRQ controller */
db70b311 6031 ppc6xx_irq_init(env_archcpu(env));
bd928eba
JM
6032}
6033
7856e3a4
AF
6034POWERPC_FAMILY(750cl)(ObjectClass *oc, void *data)
6035{
ca5dff0a 6036 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6037 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6038
ca5dff0a 6039 dc->desc = "PowerPC 750 CL";
7856e3a4
AF
6040 pcc->init_proc = init_proc_750cl;
6041 pcc->check_pow = check_pow_hid0;
1d28b5f6
DG
6042 /*
6043 * XXX: not implemented:
53116ebf
AF
6044 * cache lock instructions:
6045 * dcbz_l
6046 * floating point paired instructions
6047 * psq_lux
6048 * psq_lx
6049 * psq_stux
6050 * psq_stx
6051 * ps_abs
6052 * ps_add
6053 * ps_cmpo0
6054 * ps_cmpo1
6055 * ps_cmpu0
6056 * ps_cmpu1
6057 * ps_div
6058 * ps_madd
6059 * ps_madds0
6060 * ps_madds1
6061 * ps_merge00
6062 * ps_merge01
6063 * ps_merge10
6064 * ps_merge11
6065 * ps_mr
6066 * ps_msub
6067 * ps_mul
6068 * ps_muls0
6069 * ps_muls1
6070 * ps_nabs
6071 * ps_neg
6072 * ps_nmadd
6073 * ps_nmsub
6074 * ps_res
6075 * ps_rsqrte
6076 * ps_sel
6077 * ps_sub
6078 * ps_sum0
6079 * ps_sum1
6080 */
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;
9df5a466
TM
6088 pcc->msr_mask = (1ull << MSR_POW) |
6089 (1ull << MSR_ILE) |
6090 (1ull << MSR_EE) |
6091 (1ull << MSR_PR) |
6092 (1ull << MSR_FP) |
6093 (1ull << MSR_ME) |
6094 (1ull << MSR_FE0) |
6095 (1ull << MSR_SE) |
6096 (1ull << MSR_DE) |
6097 (1ull << MSR_FE1) |
6098 (1ull << MSR_EP) |
6099 (1ull << MSR_IR) |
6100 (1ull << MSR_DR) |
6101 (1ull << MSR_PMM) |
6102 (1ull << MSR_RI) |
6103 (1ull << MSR_LE);
ba9fd9f1 6104 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
6105#if defined(CONFIG_SOFTMMU)
6106 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6107#endif
ba9fd9f1
AF
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;
7856e3a4
AF
6113}
6114
c364946d 6115static void init_proc_750cx(CPUPPCState *env)
bd928eba
JM
6116{
6117 gen_spr_ne_601(env);
4f4f28ff 6118 gen_spr_sdr1(env);
bd928eba
JM
6119 gen_spr_7xx(env);
6120 /* XXX : not implemented */
6121 spr_register(env, SPR_L2CR, "L2CR",
6122 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 6123 &spr_read_generic, spr_access_nop,
bd928eba
JM
6124 0x00000000);
6125 /* Time base */
6126 gen_tbl(env);
6127 /* Thermal management */
6128 gen_spr_thrm(env);
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,
6133 0x00000000);
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,
6139 0x00000000);
6140 /* XXX : not implemented */
6141 spr_register(env, SPR_HID1, "HID1",
6142 SPR_NOACCESS, SPR_NOACCESS,
6143 &spr_read_generic, &spr_write_generic,
6144 0x00000000);
6145 /* Memory management */
6146 gen_low_BATs(env);
4e777442
JM
6147 /* PowerPC 750cx has 8 DBATs and 8 IBATs */
6148 gen_high_BATs(env);
bd928eba
JM
6149 init_excp_750cx(env);
6150 env->dcache_line_size = 32;
6151 env->icache_line_size = 32;
6152 /* Allocate hardware IRQ controller */
db70b311 6153 ppc6xx_irq_init(env_archcpu(env));
bd928eba
JM
6154}
6155
7856e3a4
AF
6156POWERPC_FAMILY(750cx)(ObjectClass *oc, void *data)
6157{
ca5dff0a 6158 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6159 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6160
ca5dff0a 6161 dc->desc = "PowerPC 750CX";
7856e3a4
AF
6162 pcc->init_proc = init_proc_750cx;
6163 pcc->check_pow = check_pow_hid0;
53116ebf
AF
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;
9df5a466
TM
6171 pcc->msr_mask = (1ull << MSR_POW) |
6172 (1ull << MSR_ILE) |
6173 (1ull << MSR_EE) |
6174 (1ull << MSR_PR) |
6175 (1ull << MSR_FP) |
6176 (1ull << MSR_ME) |
6177 (1ull << MSR_FE0) |
6178 (1ull << MSR_SE) |
6179 (1ull << MSR_DE) |
6180 (1ull << MSR_FE1) |
6181 (1ull << MSR_EP) |
6182 (1ull << MSR_IR) |
6183 (1ull << MSR_DR) |
6184 (1ull << MSR_PMM) |
6185 (1ull << MSR_RI) |
6186 (1ull << MSR_LE);
ba9fd9f1 6187 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
6188#if defined(CONFIG_SOFTMMU)
6189 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6190#endif
ba9fd9f1
AF
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;
7856e3a4
AF
6196}
6197
c364946d 6198static void init_proc_750fx(CPUPPCState *env)
a750fc0b
JM
6199{
6200 gen_spr_ne_601(env);
4f4f28ff 6201 gen_spr_sdr1(env);
a750fc0b 6202 gen_spr_7xx(env);
bd928eba
JM
6203 /* XXX : not implemented */
6204 spr_register(env, SPR_L2CR, "L2CR",
6205 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 6206 &spr_read_generic, spr_access_nop,
bd928eba 6207 0x00000000);
a750fc0b
JM
6208 /* Time base */
6209 gen_tbl(env);
6210 /* Thermal management */
6211 gen_spr_thrm(env);
bd928eba
JM
6212 /* XXX : not implemented */
6213 spr_register(env, SPR_750_THRM4, "THRM4",
6214 SPR_NOACCESS, SPR_NOACCESS,
6215 &spr_read_generic, &spr_write_generic,
6216 0x00000000);
a750fc0b
JM
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,
6222 0x00000000);
6223 /* XXX : not implemented */
6224 spr_register(env, SPR_HID1, "HID1",
6225 SPR_NOACCESS, SPR_NOACCESS,
6226 &spr_read_generic, &spr_write_generic,
6227 0x00000000);
6228 /* XXX : not implemented */
bd928eba 6229 spr_register(env, SPR_750FX_HID2, "HID2",
a750fc0b
JM
6230 SPR_NOACCESS, SPR_NOACCESS,
6231 &spr_read_generic, &spr_write_generic,
6232 0x00000000);
6233 /* Memory management */
6234 gen_low_BATs(env);
6235 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6236 gen_high_BATs(env);
bd928eba 6237 init_excp_7x0(env);
d63001d1
JM
6238 env->dcache_line_size = 32;
6239 env->icache_line_size = 32;
a750fc0b 6240 /* Allocate hardware IRQ controller */
db70b311 6241 ppc6xx_irq_init(env_archcpu(env));
a750fc0b
JM
6242}
6243
7856e3a4
AF
6244POWERPC_FAMILY(750fx)(ObjectClass *oc, void *data)
6245{
ca5dff0a 6246 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6247 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6248
ca5dff0a 6249 dc->desc = "PowerPC 750FX";
7856e3a4
AF
6250 pcc->init_proc = init_proc_750fx;
6251 pcc->check_pow = check_pow_hid0;
53116ebf
AF
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;
9df5a466
TM
6259 pcc->msr_mask = (1ull << MSR_POW) |
6260 (1ull << MSR_ILE) |
6261 (1ull << MSR_EE) |
6262 (1ull << MSR_PR) |
6263 (1ull << MSR_FP) |
6264 (1ull << MSR_ME) |
6265 (1ull << MSR_FE0) |
6266 (1ull << MSR_SE) |
6267 (1ull << MSR_DE) |
6268 (1ull << MSR_FE1) |
6269 (1ull << MSR_EP) |
6270 (1ull << MSR_IR) |
6271 (1ull << MSR_DR) |
6272 (1ull << MSR_PMM) |
6273 (1ull << MSR_RI) |
6274 (1ull << MSR_LE);
ba9fd9f1 6275 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
6276#if defined(CONFIG_SOFTMMU)
6277 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6278#endif
ba9fd9f1
AF
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;
7856e3a4
AF
6284}
6285
c364946d 6286static void init_proc_750gx(CPUPPCState *env)
bd928eba
JM
6287{
6288 gen_spr_ne_601(env);
4f4f28ff 6289 gen_spr_sdr1(env);
bd928eba
JM
6290 gen_spr_7xx(env);
6291 /* XXX : not implemented (XXX: different from 750fx) */
6292 spr_register(env, SPR_L2CR, "L2CR",
6293 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 6294 &spr_read_generic, spr_access_nop,
bd928eba
JM
6295 0x00000000);
6296 /* Time base */
6297 gen_tbl(env);
6298 /* Thermal management */
6299 gen_spr_thrm(env);
6300 /* XXX : not implemented */
6301 spr_register(env, SPR_750_THRM4, "THRM4",
6302 SPR_NOACCESS, SPR_NOACCESS,
6303 &spr_read_generic, &spr_write_generic,
6304 0x00000000);
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,
6310 0x00000000);
6311 /* XXX : not implemented */
6312 spr_register(env, SPR_HID1, "HID1",
6313 SPR_NOACCESS, SPR_NOACCESS,
6314 &spr_read_generic, &spr_write_generic,
6315 0x00000000);
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,
6320 0x00000000);
6321 /* Memory management */
6322 gen_low_BATs(env);
6323 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6324 gen_high_BATs(env);
6325 init_excp_7x0(env);
6326 env->dcache_line_size = 32;
6327 env->icache_line_size = 32;
6328 /* Allocate hardware IRQ controller */
db70b311 6329 ppc6xx_irq_init(env_archcpu(env));
bd928eba
JM
6330}
6331
7856e3a4
AF
6332POWERPC_FAMILY(750gx)(ObjectClass *oc, void *data)
6333{
ca5dff0a 6334 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6335 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6336
ca5dff0a 6337 dc->desc = "PowerPC 750GX";
7856e3a4
AF
6338 pcc->init_proc = init_proc_750gx;
6339 pcc->check_pow = check_pow_hid0;
53116ebf
AF
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;
9df5a466
TM
6347 pcc->msr_mask = (1ull << MSR_POW) |
6348 (1ull << MSR_ILE) |
6349 (1ull << MSR_EE) |
6350 (1ull << MSR_PR) |
6351 (1ull << MSR_FP) |
6352 (1ull << MSR_ME) |
6353 (1ull << MSR_FE0) |
6354 (1ull << MSR_SE) |
6355 (1ull << MSR_DE) |
6356 (1ull << MSR_FE1) |
6357 (1ull << MSR_EP) |
6358 (1ull << MSR_IR) |
6359 (1ull << MSR_DR) |
6360 (1ull << MSR_PMM) |
6361 (1ull << MSR_RI) |
6362 (1ull << MSR_LE);
ba9fd9f1 6363 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
6364#if defined(CONFIG_SOFTMMU)
6365 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6366#endif
ba9fd9f1
AF
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;
7856e3a4
AF
6372}
6373
c364946d 6374static void init_proc_745(CPUPPCState *env)
bd928eba
JM
6375{
6376 gen_spr_ne_601(env);
4f4f28ff 6377 gen_spr_sdr1(env);
bd928eba
JM
6378 gen_spr_7xx(env);
6379 gen_spr_G2_755(env);
6380 /* Time base */
6381 gen_tbl(env);
6382 /* Thermal management */
6383 gen_spr_thrm(env);
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,
6389 0x00000000);
6390 /* XXX : not implemented */
6391 spr_register(env, SPR_HID1, "HID1",
6392 SPR_NOACCESS, SPR_NOACCESS,
6393 &spr_read_generic, &spr_write_generic,
6394 0x00000000);
6395 /* XXX : not implemented */
6396 spr_register(env, SPR_HID2, "HID2",
6397 SPR_NOACCESS, SPR_NOACCESS,
6398 &spr_read_generic, &spr_write_generic,
6399 0x00000000);
6400 /* Memory management */
6401 gen_low_BATs(env);
6402 gen_high_BATs(env);
6403 gen_6xx_7xx_soft_tlb(env, 64, 2);
6404 init_excp_7x5(env);
6405 env->dcache_line_size = 32;
6406 env->icache_line_size = 32;
6407 /* Allocate hardware IRQ controller */
db70b311 6408 ppc6xx_irq_init(env_archcpu(env));
bd928eba
JM
6409}
6410
7856e3a4
AF
6411POWERPC_FAMILY(745)(ObjectClass *oc, void *data)
6412{
ca5dff0a 6413 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6414 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6415
ca5dff0a 6416 dc->desc = "PowerPC 745";
7856e3a4
AF
6417 pcc->init_proc = init_proc_745;
6418 pcc->check_pow = check_pow_hid0;
53116ebf
AF
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;
9df5a466
TM
6426 pcc->msr_mask = (1ull << MSR_POW) |
6427 (1ull << MSR_ILE) |
6428 (1ull << MSR_EE) |
6429 (1ull << MSR_PR) |
6430 (1ull << MSR_FP) |
6431 (1ull << MSR_ME) |
6432 (1ull << MSR_FE0) |
6433 (1ull << MSR_SE) |
6434 (1ull << MSR_DE) |
6435 (1ull << MSR_FE1) |
6436 (1ull << MSR_EP) |
6437 (1ull << MSR_IR) |
6438 (1ull << MSR_DR) |
6439 (1ull << MSR_PMM) |
6440 (1ull << MSR_RI) |
6441 (1ull << MSR_LE);
ba9fd9f1
AF
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;
7856e3a4
AF
6448}
6449
c364946d 6450static void init_proc_755(CPUPPCState *env)
a750fc0b
JM
6451{
6452 gen_spr_ne_601(env);
4f4f28ff 6453 gen_spr_sdr1(env);
bd928eba 6454 gen_spr_7xx(env);
a750fc0b
JM
6455 gen_spr_G2_755(env);
6456 /* Time base */
6457 gen_tbl(env);
6458 /* L2 cache control */
6459 /* XXX : not implemented */
bd928eba 6460 spr_register(env, SPR_L2CR, "L2CR",
a750fc0b 6461 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 6462 &spr_read_generic, spr_access_nop,
a750fc0b
JM
6463 0x00000000);
6464 /* XXX : not implemented */
6465 spr_register(env, SPR_L2PMCR, "L2PMCR",
6466 SPR_NOACCESS, SPR_NOACCESS,
6467 &spr_read_generic, &spr_write_generic,
6468 0x00000000);
bd928eba
JM
6469 /* Thermal management */
6470 gen_spr_thrm(env);
a750fc0b
JM
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,
6476 0x00000000);
6477 /* XXX : not implemented */
6478 spr_register(env, SPR_HID1, "HID1",
6479 SPR_NOACCESS, SPR_NOACCESS,
6480 &spr_read_generic, &spr_write_generic,
6481 0x00000000);
6482 /* XXX : not implemented */
6483 spr_register(env, SPR_HID2, "HID2",
6484 SPR_NOACCESS, SPR_NOACCESS,
6485 &spr_read_generic, &spr_write_generic,
6486 0x00000000);
6487 /* Memory management */
6488 gen_low_BATs(env);
6489 gen_high_BATs(env);
6490 gen_6xx_7xx_soft_tlb(env, 64, 2);
7a3a6927 6491 init_excp_7x5(env);
d63001d1
JM
6492 env->dcache_line_size = 32;
6493 env->icache_line_size = 32;
a750fc0b 6494 /* Allocate hardware IRQ controller */
db70b311 6495 ppc6xx_irq_init(env_archcpu(env));
a750fc0b
JM
6496}
6497
7856e3a4
AF
6498POWERPC_FAMILY(755)(ObjectClass *oc, void *data)
6499{
ca5dff0a 6500 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6501 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6502
ca5dff0a 6503 dc->desc = "PowerPC 755";
7856e3a4
AF
6504 pcc->init_proc = init_proc_755;
6505 pcc->check_pow = check_pow_hid0;
53116ebf
AF
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;
9df5a466
TM
6513 pcc->msr_mask = (1ull << MSR_POW) |
6514 (1ull << MSR_ILE) |
6515 (1ull << MSR_EE) |
6516 (1ull << MSR_PR) |
6517 (1ull << MSR_FP) |
6518 (1ull << MSR_ME) |
6519 (1ull << MSR_FE0) |
6520 (1ull << MSR_SE) |
6521 (1ull << MSR_DE) |
6522 (1ull << MSR_FE1) |
6523 (1ull << MSR_EP) |
6524 (1ull << MSR_IR) |
6525 (1ull << MSR_DR) |
6526 (1ull << MSR_PMM) |
6527 (1ull << MSR_RI) |
6528 (1ull << MSR_LE);
ba9fd9f1
AF
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;
7856e3a4
AF
6535}
6536
c364946d 6537static void init_proc_7400(CPUPPCState *env)
a750fc0b
JM
6538{
6539 gen_spr_ne_601(env);
4f4f28ff 6540 gen_spr_sdr1(env);
a750fc0b
JM
6541 gen_spr_7xx(env);
6542 /* Time base */
6543 gen_tbl(env);
6544 /* 74xx specific SPR */
6545 gen_spr_74xx(env);
4e777442
JM
6546 /* XXX : not implemented */
6547 spr_register(env, SPR_UBAMR, "UBAMR",
6548 &spr_read_ureg, SPR_NOACCESS,
6549 &spr_read_ureg, SPR_NOACCESS,
6550 0x00000000);
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,
6556 0x00000000);
a750fc0b
JM
6557 /* Thermal management */
6558 gen_spr_thrm(env);
6559 /* Memory management */
6560 gen_low_BATs(env);
e1833e1f 6561 init_excp_7400(env);
d63001d1
JM
6562 env->dcache_line_size = 32;
6563 env->icache_line_size = 32;
a750fc0b 6564 /* Allocate hardware IRQ controller */
db70b311 6565 ppc6xx_irq_init(env_archcpu(env));
a750fc0b
JM
6566}
6567
7856e3a4
AF
6568POWERPC_FAMILY(7400)(ObjectClass *oc, void *data)
6569{
ca5dff0a 6570 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6571 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6572
ca5dff0a 6573 dc->desc = "PowerPC 7400 (aka G4)";
7856e3a4
AF
6574 pcc->init_proc = init_proc_7400;
6575 pcc->check_pow = check_pow_hid0;
53116ebf
AF
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 |
6579 PPC_FLOAT_STFIWX |
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 |
6584 PPC_MEM_TLBIA |
6585 PPC_SEGMENT | PPC_EXTERN |
6586 PPC_ALTIVEC;
9df5a466
TM
6587 pcc->msr_mask = (1ull << MSR_VR) |
6588 (1ull << MSR_POW) |
6589 (1ull << MSR_ILE) |
6590 (1ull << MSR_EE) |
6591 (1ull << MSR_PR) |
6592 (1ull << MSR_FP) |
6593 (1ull << MSR_ME) |
6594 (1ull << MSR_FE0) |
6595 (1ull << MSR_SE) |
6596 (1ull << MSR_DE) |
6597 (1ull << MSR_FE1) |
6598 (1ull << MSR_EP) |
6599 (1ull << MSR_IR) |
6600 (1ull << MSR_DR) |
6601 (1ull << MSR_PMM) |
6602 (1ull << MSR_RI) |
6603 (1ull << MSR_LE);
ba9fd9f1 6604 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
6605#if defined(CONFIG_SOFTMMU)
6606 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6607#endif
ba9fd9f1
AF
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;
7856e3a4
AF
6614}
6615
c364946d 6616static void init_proc_7410(CPUPPCState *env)
a750fc0b
JM
6617{
6618 gen_spr_ne_601(env);
4f4f28ff 6619 gen_spr_sdr1(env);
a750fc0b
JM
6620 gen_spr_7xx(env);
6621 /* Time base */
6622 gen_tbl(env);
6623 /* 74xx specific SPR */
6624 gen_spr_74xx(env);
4e777442
JM
6625 /* XXX : not implemented */
6626 spr_register(env, SPR_UBAMR, "UBAMR",
6627 &spr_read_ureg, SPR_NOACCESS,
6628 &spr_read_ureg, SPR_NOACCESS,
6629 0x00000000);
a750fc0b
JM
6630 /* Thermal management */
6631 gen_spr_thrm(env);
6632 /* L2PMCR */
6633 /* XXX : not implemented */
6634 spr_register(env, SPR_L2PMCR, "L2PMCR",
6635 SPR_NOACCESS, SPR_NOACCESS,
6636 &spr_read_generic, &spr_write_generic,
6637 0x00000000);
6638 /* LDSTDB */
6639 /* XXX : not implemented */
6640 spr_register(env, SPR_LDSTDB, "LDSTDB",
6641 SPR_NOACCESS, SPR_NOACCESS,
6642 &spr_read_generic, &spr_write_generic,
6643 0x00000000);
6644 /* Memory management */
6645 gen_low_BATs(env);
e1833e1f 6646 init_excp_7400(env);
d63001d1
JM
6647 env->dcache_line_size = 32;
6648 env->icache_line_size = 32;
a750fc0b 6649 /* Allocate hardware IRQ controller */
db70b311 6650 ppc6xx_irq_init(env_archcpu(env));
a750fc0b
JM
6651}
6652
7856e3a4
AF
6653POWERPC_FAMILY(7410)(ObjectClass *oc, void *data)
6654{
ca5dff0a 6655 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6656 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6657
ca5dff0a 6658 dc->desc = "PowerPC 7410 (aka G4)";
7856e3a4
AF
6659 pcc->init_proc = init_proc_7410;
6660 pcc->check_pow = check_pow_hid0;
53116ebf
AF
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 |
6664 PPC_FLOAT_STFIWX |
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 |
6669 PPC_MEM_TLBIA |
6670 PPC_SEGMENT | PPC_EXTERN |
6671 PPC_ALTIVEC;
9df5a466
TM
6672 pcc->msr_mask = (1ull << MSR_VR) |
6673 (1ull << MSR_POW) |
6674 (1ull << MSR_ILE) |
6675 (1ull << MSR_EE) |
6676 (1ull << MSR_PR) |
6677 (1ull << MSR_FP) |
6678 (1ull << MSR_ME) |
6679 (1ull << MSR_FE0) |
6680 (1ull << MSR_SE) |
6681 (1ull << MSR_DE) |
6682 (1ull << MSR_FE1) |
6683 (1ull << MSR_EP) |
6684 (1ull << MSR_IR) |
6685 (1ull << MSR_DR) |
6686 (1ull << MSR_PMM) |
6687 (1ull << MSR_RI) |
6688 (1ull << MSR_LE);
ba9fd9f1 6689 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
6690#if defined(CONFIG_SOFTMMU)
6691 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6692#endif
ba9fd9f1
AF
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;
7856e3a4
AF
6699}
6700
c364946d 6701static void init_proc_7440(CPUPPCState *env)
a750fc0b
JM
6702{
6703 gen_spr_ne_601(env);
4f4f28ff 6704 gen_spr_sdr1(env);
a750fc0b
JM
6705 gen_spr_7xx(env);
6706 /* Time base */
6707 gen_tbl(env);
6708 /* 74xx specific SPR */
6709 gen_spr_74xx(env);
4e777442
JM
6710 /* XXX : not implemented */
6711 spr_register(env, SPR_UBAMR, "UBAMR",
6712 &spr_read_ureg, SPR_NOACCESS,
6713 &spr_read_ureg, SPR_NOACCESS,
6714 0x00000000);
a750fc0b
JM
6715 /* LDSTCR */
6716 /* XXX : not implemented */
6717 spr_register(env, SPR_LDSTCR, "LDSTCR",
6718 SPR_NOACCESS, SPR_NOACCESS,
6719 &spr_read_generic, &spr_write_generic,
6720 0x00000000);
6721 /* ICTRL */
6722 /* XXX : not implemented */
6723 spr_register(env, SPR_ICTRL, "ICTRL",
6724 SPR_NOACCESS, SPR_NOACCESS,
6725 &spr_read_generic, &spr_write_generic,
6726 0x00000000);
6727 /* MSSSR0 */
578bb252 6728 /* XXX : not implemented */
a750fc0b
JM
6729 spr_register(env, SPR_MSSSR0, "MSSSR0",
6730 SPR_NOACCESS, SPR_NOACCESS,
6731 &spr_read_generic, &spr_write_generic,
6732 0x00000000);
6733 /* PMC */
6734 /* XXX : not implemented */
cb8b8bf8 6735 spr_register(env, SPR_7XX_PMC5, "PMC5",
a750fc0b
JM
6736 SPR_NOACCESS, SPR_NOACCESS,
6737 &spr_read_generic, &spr_write_generic,
6738 0x00000000);
578bb252 6739 /* XXX : not implemented */
cb8b8bf8 6740 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
a750fc0b
JM
6741 &spr_read_ureg, SPR_NOACCESS,
6742 &spr_read_ureg, SPR_NOACCESS,
6743 0x00000000);
578bb252 6744 /* XXX : not implemented */
cb8b8bf8 6745 spr_register(env, SPR_7XX_PMC6, "PMC6",
a750fc0b
JM
6746 SPR_NOACCESS, SPR_NOACCESS,
6747 &spr_read_generic, &spr_write_generic,
6748 0x00000000);
578bb252 6749 /* XXX : not implemented */
cb8b8bf8 6750 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
a750fc0b
JM
6751 &spr_read_ureg, SPR_NOACCESS,
6752 &spr_read_ureg, SPR_NOACCESS,
6753 0x00000000);
6754 /* Memory management */
6755 gen_low_BATs(env);
578bb252 6756 gen_74xx_soft_tlb(env, 128, 2);
1c27f8fb 6757 init_excp_7450(env);
d63001d1
JM
6758 env->dcache_line_size = 32;
6759 env->icache_line_size = 32;
a750fc0b 6760 /* Allocate hardware IRQ controller */
db70b311 6761 ppc6xx_irq_init(env_archcpu(env));
a750fc0b 6762}
a750fc0b 6763
7856e3a4
AF
6764POWERPC_FAMILY(7440)(ObjectClass *oc, void *data)
6765{
ca5dff0a 6766 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6767 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6768
ca5dff0a 6769 dc->desc = "PowerPC 7440 (aka G4)";
7856e3a4
AF
6770 pcc->init_proc = init_proc_7440;
6771 pcc->check_pow = check_pow_hid0_74xx;
53116ebf
AF
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 |
6775 PPC_FLOAT_STFIWX |
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 |
6782 PPC_ALTIVEC;
9df5a466
TM
6783 pcc->msr_mask = (1ull << MSR_VR) |
6784 (1ull << MSR_POW) |
6785 (1ull << MSR_ILE) |
6786 (1ull << MSR_EE) |
6787 (1ull << MSR_PR) |
6788 (1ull << MSR_FP) |
6789 (1ull << MSR_ME) |
6790 (1ull << MSR_FE0) |
6791 (1ull << MSR_SE) |
6792 (1ull << MSR_DE) |
6793 (1ull << MSR_FE1) |
6794 (1ull << MSR_EP) |
6795 (1ull << MSR_IR) |
6796 (1ull << MSR_DR) |
6797 (1ull << MSR_PMM) |
6798 (1ull << MSR_RI) |
6799 (1ull << MSR_LE);
ba9fd9f1
AF
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;
7856e3a4
AF
6807}
6808
c364946d 6809static void init_proc_7450(CPUPPCState *env)
a750fc0b
JM
6810{
6811 gen_spr_ne_601(env);
4f4f28ff 6812 gen_spr_sdr1(env);
a750fc0b
JM
6813 gen_spr_7xx(env);
6814 /* Time base */
6815 gen_tbl(env);
6816 /* 74xx specific SPR */
6817 gen_spr_74xx(env);
6818 /* Level 3 cache control */
6819 gen_l3_ctrl(env);
4e777442
JM
6820 /* L3ITCR1 */
6821 /* XXX : not implemented */
6822 spr_register(env, SPR_L3ITCR1, "L3ITCR1",
6823 SPR_NOACCESS, SPR_NOACCESS,
6824 &spr_read_generic, &spr_write_generic,
6825 0x00000000);
6826 /* L3ITCR2 */
6827 /* XXX : not implemented */
6828 spr_register(env, SPR_L3ITCR2, "L3ITCR2",
6829 SPR_NOACCESS, SPR_NOACCESS,
6830 &spr_read_generic, &spr_write_generic,
6831 0x00000000);
6832 /* L3ITCR3 */
6833 /* XXX : not implemented */
6834 spr_register(env, SPR_L3ITCR3, "L3ITCR3",
6835 SPR_NOACCESS, SPR_NOACCESS,
6836 &spr_read_generic, &spr_write_generic,
6837 0x00000000);
6838 /* L3OHCR */
6839 /* XXX : not implemented */
6840 spr_register(env, SPR_L3OHCR, "L3OHCR",
6841 SPR_NOACCESS, SPR_NOACCESS,
6842 &spr_read_generic, &spr_write_generic,
6843 0x00000000);
6844 /* XXX : not implemented */
6845 spr_register(env, SPR_UBAMR, "UBAMR",
6846 &spr_read_ureg, SPR_NOACCESS,
6847 &spr_read_ureg, SPR_NOACCESS,
6848 0x00000000);
a750fc0b
JM
6849 /* LDSTCR */
6850 /* XXX : not implemented */
6851 spr_register(env, SPR_LDSTCR, "LDSTCR",
6852 SPR_NOACCESS, SPR_NOACCESS,
6853 &spr_read_generic, &spr_write_generic,
6854 0x00000000);
6855 /* ICTRL */
6856 /* XXX : not implemented */
6857 spr_register(env, SPR_ICTRL, "ICTRL",
6858 SPR_NOACCESS, SPR_NOACCESS,
6859 &spr_read_generic, &spr_write_generic,
6860 0x00000000);
6861 /* MSSSR0 */
578bb252 6862 /* XXX : not implemented */
a750fc0b
JM
6863 spr_register(env, SPR_MSSSR0, "MSSSR0",
6864 SPR_NOACCESS, SPR_NOACCESS,
6865 &spr_read_generic, &spr_write_generic,
6866 0x00000000);
6867 /* PMC */
6868 /* XXX : not implemented */
cb8b8bf8 6869 spr_register(env, SPR_7XX_PMC5, "PMC5",
a750fc0b
JM
6870 SPR_NOACCESS, SPR_NOACCESS,
6871 &spr_read_generic, &spr_write_generic,
6872 0x00000000);
578bb252 6873 /* XXX : not implemented */
cb8b8bf8 6874 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
a750fc0b
JM
6875 &spr_read_ureg, SPR_NOACCESS,
6876 &spr_read_ureg, SPR_NOACCESS,
6877 0x00000000);
578bb252 6878 /* XXX : not implemented */
cb8b8bf8 6879 spr_register(env, SPR_7XX_PMC6, "PMC6",
a750fc0b
JM
6880 SPR_NOACCESS, SPR_NOACCESS,
6881 &spr_read_generic, &spr_write_generic,
6882 0x00000000);
578bb252 6883 /* XXX : not implemented */
cb8b8bf8 6884 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
a750fc0b
JM
6885 &spr_read_ureg, SPR_NOACCESS,
6886 &spr_read_ureg, SPR_NOACCESS,
6887 0x00000000);
6888 /* Memory management */
6889 gen_low_BATs(env);
578bb252 6890 gen_74xx_soft_tlb(env, 128, 2);
e1833e1f 6891 init_excp_7450(env);
d63001d1
JM
6892 env->dcache_line_size = 32;
6893 env->icache_line_size = 32;
a750fc0b 6894 /* Allocate hardware IRQ controller */
db70b311 6895 ppc6xx_irq_init(env_archcpu(env));
a750fc0b 6896}
a750fc0b 6897
7856e3a4
AF
6898POWERPC_FAMILY(7450)(ObjectClass *oc, void *data)
6899{
ca5dff0a 6900 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6901 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6902
ca5dff0a 6903 dc->desc = "PowerPC 7450 (aka G4)";
7856e3a4
AF
6904 pcc->init_proc = init_proc_7450;
6905 pcc->check_pow = check_pow_hid0_74xx;
53116ebf
AF
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 |
6909 PPC_FLOAT_STFIWX |
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 |
6916 PPC_ALTIVEC;
9df5a466
TM
6917 pcc->msr_mask = (1ull << MSR_VR) |
6918 (1ull << MSR_POW) |
6919 (1ull << MSR_ILE) |
6920 (1ull << MSR_EE) |
6921 (1ull << MSR_PR) |
6922 (1ull << MSR_FP) |
6923 (1ull << MSR_ME) |
6924 (1ull << MSR_FE0) |
6925 (1ull << MSR_SE) |
6926 (1ull << MSR_DE) |
6927 (1ull << MSR_FE1) |
6928 (1ull << MSR_EP) |
6929 (1ull << MSR_IR) |
6930 (1ull << MSR_DR) |
6931 (1ull << MSR_PMM) |
6932 (1ull << MSR_RI) |
6933 (1ull << MSR_LE);
ba9fd9f1
AF
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;
7856e3a4
AF
6941}
6942
c364946d 6943static void init_proc_7445(CPUPPCState *env)
a750fc0b
JM
6944{
6945 gen_spr_ne_601(env);
4f4f28ff 6946 gen_spr_sdr1(env);
a750fc0b
JM
6947 gen_spr_7xx(env);
6948 /* Time base */
6949 gen_tbl(env);
6950 /* 74xx specific SPR */
6951 gen_spr_74xx(env);
6952 /* LDSTCR */
6953 /* XXX : not implemented */
6954 spr_register(env, SPR_LDSTCR, "LDSTCR",
6955 SPR_NOACCESS, SPR_NOACCESS,
6956 &spr_read_generic, &spr_write_generic,
6957 0x00000000);
6958 /* ICTRL */
6959 /* XXX : not implemented */
6960 spr_register(env, SPR_ICTRL, "ICTRL",
6961 SPR_NOACCESS, SPR_NOACCESS,
6962 &spr_read_generic, &spr_write_generic,
6963 0x00000000);
6964 /* MSSSR0 */
578bb252 6965 /* XXX : not implemented */
a750fc0b
JM
6966 spr_register(env, SPR_MSSSR0, "MSSSR0",
6967 SPR_NOACCESS, SPR_NOACCESS,
6968 &spr_read_generic, &spr_write_generic,
6969 0x00000000);
6970 /* PMC */
6971 /* XXX : not implemented */
cb8b8bf8 6972 spr_register(env, SPR_7XX_PMC5, "PMC5",
a750fc0b
JM
6973 SPR_NOACCESS, SPR_NOACCESS,
6974 &spr_read_generic, &spr_write_generic,
6975 0x00000000);
578bb252 6976 /* XXX : not implemented */
cb8b8bf8 6977 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
a750fc0b
JM
6978 &spr_read_ureg, SPR_NOACCESS,
6979 &spr_read_ureg, SPR_NOACCESS,
6980 0x00000000);
578bb252 6981 /* XXX : not implemented */
cb8b8bf8 6982 spr_register(env, SPR_7XX_PMC6, "PMC6",
a750fc0b
JM
6983 SPR_NOACCESS, SPR_NOACCESS,
6984 &spr_read_generic, &spr_write_generic,
6985 0x00000000);
578bb252 6986 /* XXX : not implemented */
cb8b8bf8 6987 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
a750fc0b
JM
6988 &spr_read_ureg, SPR_NOACCESS,
6989 &spr_read_ureg, SPR_NOACCESS,
6990 0x00000000);
6991 /* SPRGs */
6992 spr_register(env, SPR_SPRG4, "SPRG4",
6993 SPR_NOACCESS, SPR_NOACCESS,
6994 &spr_read_generic, &spr_write_generic,
6995 0x00000000);
6996 spr_register(env, SPR_USPRG4, "USPRG4",
6997 &spr_read_ureg, SPR_NOACCESS,
6998 &spr_read_ureg, SPR_NOACCESS,
6999 0x00000000);
7000 spr_register(env, SPR_SPRG5, "SPRG5",
7001 SPR_NOACCESS, SPR_NOACCESS,
7002 &spr_read_generic, &spr_write_generic,
7003 0x00000000);
7004 spr_register(env, SPR_USPRG5, "USPRG5",
7005 &spr_read_ureg, SPR_NOACCESS,
7006 &spr_read_ureg, SPR_NOACCESS,
7007 0x00000000);
7008 spr_register(env, SPR_SPRG6, "SPRG6",
7009 SPR_NOACCESS, SPR_NOACCESS,
7010 &spr_read_generic, &spr_write_generic,
7011 0x00000000);
7012 spr_register(env, SPR_USPRG6, "USPRG6",
7013 &spr_read_ureg, SPR_NOACCESS,
7014 &spr_read_ureg, SPR_NOACCESS,
7015 0x00000000);
7016 spr_register(env, SPR_SPRG7, "SPRG7",
7017 SPR_NOACCESS, SPR_NOACCESS,
7018 &spr_read_generic, &spr_write_generic,
7019 0x00000000);
7020 spr_register(env, SPR_USPRG7, "USPRG7",
7021 &spr_read_ureg, SPR_NOACCESS,
7022 &spr_read_ureg, SPR_NOACCESS,
7023 0x00000000);
7024 /* Memory management */
7025 gen_low_BATs(env);
7026 gen_high_BATs(env);
578bb252 7027 gen_74xx_soft_tlb(env, 128, 2);
e1833e1f 7028 init_excp_7450(env);
d63001d1
JM
7029 env->dcache_line_size = 32;
7030 env->icache_line_size = 32;
a750fc0b 7031 /* Allocate hardware IRQ controller */
db70b311 7032 ppc6xx_irq_init(env_archcpu(env));
a750fc0b 7033}
a750fc0b 7034
7856e3a4
AF
7035POWERPC_FAMILY(7445)(ObjectClass *oc, void *data)
7036{
ca5dff0a 7037 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
7038 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7039
ca5dff0a 7040 dc->desc = "PowerPC 7445 (aka G4)";
7856e3a4
AF
7041 pcc->init_proc = init_proc_7445;
7042 pcc->check_pow = check_pow_hid0_74xx;
53116ebf
AF
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 |
7046 PPC_FLOAT_STFIWX |
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 |
7053 PPC_ALTIVEC;
9df5a466
TM
7054 pcc->msr_mask = (1ull << MSR_VR) |
7055 (1ull << MSR_POW) |
7056 (1ull << MSR_ILE) |
7057 (1ull << MSR_EE) |
7058 (1ull << MSR_PR) |
7059 (1ull << MSR_FP) |
7060 (1ull << MSR_ME) |
7061 (1ull << MSR_FE0) |
7062 (1ull << MSR_SE) |
7063 (1ull << MSR_DE) |
7064 (1ull << MSR_FE1) |
7065 (1ull << MSR_EP) |
7066 (1ull << MSR_IR) |
7067 (1ull << MSR_DR) |
7068 (1ull << MSR_PMM) |
7069 (1ull << MSR_RI) |
7070 (1ull << MSR_LE);
ba9fd9f1
AF
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;
7856e3a4
AF
7078}
7079
c364946d 7080static void init_proc_7455(CPUPPCState *env)
a750fc0b
JM
7081{
7082 gen_spr_ne_601(env);
4f4f28ff 7083 gen_spr_sdr1(env);
a750fc0b
JM
7084 gen_spr_7xx(env);
7085 /* Time base */
7086 gen_tbl(env);
7087 /* 74xx specific SPR */
7088 gen_spr_74xx(env);
7089 /* Level 3 cache control */
7090 gen_l3_ctrl(env);
7091 /* LDSTCR */
7092 /* XXX : not implemented */
7093 spr_register(env, SPR_LDSTCR, "LDSTCR",
7094 SPR_NOACCESS, SPR_NOACCESS,
7095 &spr_read_generic, &spr_write_generic,
7096 0x00000000);
7097 /* ICTRL */
7098 /* XXX : not implemented */
7099 spr_register(env, SPR_ICTRL, "ICTRL",
7100 SPR_NOACCESS, SPR_NOACCESS,
7101 &spr_read_generic, &spr_write_generic,
7102 0x00000000);
7103 /* MSSSR0 */
578bb252 7104 /* XXX : not implemented */
a750fc0b
JM
7105 spr_register(env, SPR_MSSSR0, "MSSSR0",
7106 SPR_NOACCESS, SPR_NOACCESS,
7107 &spr_read_generic, &spr_write_generic,
7108 0x00000000);
7109 /* PMC */
7110 /* XXX : not implemented */
cb8b8bf8 7111 spr_register(env, SPR_7XX_PMC5, "PMC5",
a750fc0b
JM
7112 SPR_NOACCESS, SPR_NOACCESS,
7113 &spr_read_generic, &spr_write_generic,
7114 0x00000000);
578bb252 7115 /* XXX : not implemented */
cb8b8bf8 7116 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
a750fc0b
JM
7117 &spr_read_ureg, SPR_NOACCESS,
7118 &spr_read_ureg, SPR_NOACCESS,
7119 0x00000000);
578bb252 7120 /* XXX : not implemented */
cb8b8bf8 7121 spr_register(env, SPR_7XX_PMC6, "PMC6",
a750fc0b
JM
7122 SPR_NOACCESS, SPR_NOACCESS,
7123 &spr_read_generic, &spr_write_generic,
7124 0x00000000);
578bb252 7125 /* XXX : not implemented */
cb8b8bf8 7126 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
a750fc0b
JM
7127 &spr_read_ureg, SPR_NOACCESS,
7128 &spr_read_ureg, SPR_NOACCESS,
7129 0x00000000);
7130 /* SPRGs */
7131 spr_register(env, SPR_SPRG4, "SPRG4",
7132 SPR_NOACCESS, SPR_NOACCESS,
7133 &spr_read_generic, &spr_write_generic,
7134 0x00000000);
7135 spr_register(env, SPR_USPRG4, "USPRG4",
7136 &spr_read_ureg, SPR_NOACCESS,
7137 &spr_read_ureg, SPR_NOACCESS,
7138 0x00000000);
7139 spr_register(env, SPR_SPRG5, "SPRG5",
7140 SPR_NOACCESS, SPR_NOACCESS,
7141 &spr_read_generic, &spr_write_generic,
7142 0x00000000);
7143 spr_register(env, SPR_USPRG5, "USPRG5",
7144 &spr_read_ureg, SPR_NOACCESS,
7145 &spr_read_ureg, SPR_NOACCESS,
7146 0x00000000);
7147 spr_register(env, SPR_SPRG6, "SPRG6",
7148 SPR_NOACCESS, SPR_NOACCESS,
7149 &spr_read_generic, &spr_write_generic,
7150 0x00000000);
7151 spr_register(env, SPR_USPRG6, "USPRG6",
7152 &spr_read_ureg, SPR_NOACCESS,
7153 &spr_read_ureg, SPR_NOACCESS,
7154 0x00000000);
7155 spr_register(env, SPR_SPRG7, "SPRG7",
7156 SPR_NOACCESS, SPR_NOACCESS,
7157 &spr_read_generic, &spr_write_generic,
7158 0x00000000);
7159 spr_register(env, SPR_USPRG7, "USPRG7",
7160 &spr_read_ureg, SPR_NOACCESS,
7161 &spr_read_ureg, SPR_NOACCESS,
7162 0x00000000);
7163 /* Memory management */
7164 gen_low_BATs(env);
7165 gen_high_BATs(env);
578bb252 7166 gen_74xx_soft_tlb(env, 128, 2);
e1833e1f 7167 init_excp_7450(env);
d63001d1
JM
7168 env->dcache_line_size = 32;
7169 env->icache_line_size = 32;
a750fc0b 7170 /* Allocate hardware IRQ controller */
db70b311 7171 ppc6xx_irq_init(env_archcpu(env));
a750fc0b 7172}
a750fc0b 7173
7856e3a4
AF
7174POWERPC_FAMILY(7455)(ObjectClass *oc, void *data)
7175{
ca5dff0a 7176 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
7177 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7178
ca5dff0a 7179 dc->desc = "PowerPC 7455 (aka G4)";
7856e3a4
AF
7180 pcc->init_proc = init_proc_7455;
7181 pcc->check_pow = check_pow_hid0_74xx;
53116ebf
AF
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 |
7185 PPC_FLOAT_STFIWX |
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 |
7192 PPC_ALTIVEC;
9df5a466
TM
7193 pcc->msr_mask = (1ull << MSR_VR) |
7194 (1ull << MSR_POW) |
7195 (1ull << MSR_ILE) |
7196 (1ull << MSR_EE) |
7197 (1ull << MSR_PR) |
7198 (1ull << MSR_FP) |
7199 (1ull << MSR_ME) |
7200 (1ull << MSR_FE0) |
7201 (1ull << MSR_SE) |
7202 (1ull << MSR_DE) |
7203 (1ull << MSR_FE1) |
7204 (1ull << MSR_EP) |
7205 (1ull << MSR_IR) |
7206 (1ull << MSR_DR) |
7207 (1ull << MSR_PMM) |
7208 (1ull << MSR_RI) |
7209 (1ull << MSR_LE);
ba9fd9f1
AF
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;
7856e3a4
AF
7217}
7218
c364946d 7219static void init_proc_7457(CPUPPCState *env)
4e777442
JM
7220{
7221 gen_spr_ne_601(env);
4f4f28ff 7222 gen_spr_sdr1(env);
4e777442
JM
7223 gen_spr_7xx(env);
7224 /* Time base */
7225 gen_tbl(env);
7226 /* 74xx specific SPR */
7227 gen_spr_74xx(env);
7228 /* Level 3 cache control */
7229 gen_l3_ctrl(env);
7230 /* L3ITCR1 */
7231 /* XXX : not implemented */
7232 spr_register(env, SPR_L3ITCR1, "L3ITCR1",
7233 SPR_NOACCESS, SPR_NOACCESS,
7234 &spr_read_generic, &spr_write_generic,
7235 0x00000000);
7236 /* L3ITCR2 */
7237 /* XXX : not implemented */
7238 spr_register(env, SPR_L3ITCR2, "L3ITCR2",
7239 SPR_NOACCESS, SPR_NOACCESS,
7240 &spr_read_generic, &spr_write_generic,
7241 0x00000000);
7242 /* L3ITCR3 */
7243 /* XXX : not implemented */
7244 spr_register(env, SPR_L3ITCR3, "L3ITCR3",
7245 SPR_NOACCESS, SPR_NOACCESS,
7246 &spr_read_generic, &spr_write_generic,
7247 0x00000000);
7248 /* L3OHCR */
7249 /* XXX : not implemented */
7250 spr_register(env, SPR_L3OHCR, "L3OHCR",
7251 SPR_NOACCESS, SPR_NOACCESS,
7252 &spr_read_generic, &spr_write_generic,
7253 0x00000000);
7254 /* LDSTCR */
7255 /* XXX : not implemented */
7256 spr_register(env, SPR_LDSTCR, "LDSTCR",
7257 SPR_NOACCESS, SPR_NOACCESS,
7258 &spr_read_generic, &spr_write_generic,
7259 0x00000000);
7260 /* ICTRL */
7261 /* XXX : not implemented */
7262 spr_register(env, SPR_ICTRL, "ICTRL",
7263 SPR_NOACCESS, SPR_NOACCESS,
7264 &spr_read_generic, &spr_write_generic,
7265 0x00000000);
7266 /* MSSSR0 */
7267 /* XXX : not implemented */
7268 spr_register(env, SPR_MSSSR0, "MSSSR0",
7269 SPR_NOACCESS, SPR_NOACCESS,
7270 &spr_read_generic, &spr_write_generic,
7271 0x00000000);
7272 /* PMC */
7273 /* XXX : not implemented */
cb8b8bf8 7274 spr_register(env, SPR_7XX_PMC5, "PMC5",
4e777442
JM
7275 SPR_NOACCESS, SPR_NOACCESS,
7276 &spr_read_generic, &spr_write_generic,
7277 0x00000000);
7278 /* XXX : not implemented */
cb8b8bf8 7279 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
4e777442
JM
7280 &spr_read_ureg, SPR_NOACCESS,
7281 &spr_read_ureg, SPR_NOACCESS,
7282 0x00000000);
7283 /* XXX : not implemented */
cb8b8bf8 7284 spr_register(env, SPR_7XX_PMC6, "PMC6",
4e777442
JM
7285 SPR_NOACCESS, SPR_NOACCESS,
7286 &spr_read_generic, &spr_write_generic,
7287 0x00000000);
7288 /* XXX : not implemented */
cb8b8bf8 7289 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
4e777442
JM
7290 &spr_read_ureg, SPR_NOACCESS,
7291 &spr_read_ureg, SPR_NOACCESS,
7292 0x00000000);
7293 /* SPRGs */
7294 spr_register(env, SPR_SPRG4, "SPRG4",
7295 SPR_NOACCESS, SPR_NOACCESS,
7296 &spr_read_generic, &spr_write_generic,
7297 0x00000000);
7298 spr_register(env, SPR_USPRG4, "USPRG4",
7299 &spr_read_ureg, SPR_NOACCESS,
7300 &spr_read_ureg, SPR_NOACCESS,
7301 0x00000000);
7302 spr_register(env, SPR_SPRG5, "SPRG5",
7303 SPR_NOACCESS, SPR_NOACCESS,
7304 &spr_read_generic, &spr_write_generic,
7305 0x00000000);
7306 spr_register(env, SPR_USPRG5, "USPRG5",
7307 &spr_read_ureg, SPR_NOACCESS,
7308 &spr_read_ureg, SPR_NOACCESS,
7309 0x00000000);
7310 spr_register(env, SPR_SPRG6, "SPRG6",
7311 SPR_NOACCESS, SPR_NOACCESS,
7312 &spr_read_generic, &spr_write_generic,
7313 0x00000000);
7314 spr_register(env, SPR_USPRG6, "USPRG6",
7315 &spr_read_ureg, SPR_NOACCESS,
7316 &spr_read_ureg, SPR_NOACCESS,
7317 0x00000000);
7318 spr_register(env, SPR_SPRG7, "SPRG7",
7319 SPR_NOACCESS, SPR_NOACCESS,
7320 &spr_read_generic, &spr_write_generic,
7321 0x00000000);
7322 spr_register(env, SPR_USPRG7, "USPRG7",
7323 &spr_read_ureg, SPR_NOACCESS,
7324 &spr_read_ureg, SPR_NOACCESS,
7325 0x00000000);
7326 /* Memory management */
7327 gen_low_BATs(env);
7328 gen_high_BATs(env);
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 */
db70b311 7334 ppc6xx_irq_init(env_archcpu(env));
4e777442
JM
7335}
7336
7856e3a4
AF
7337POWERPC_FAMILY(7457)(ObjectClass *oc, void *data)
7338{
ca5dff0a 7339 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
7340 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7341
ca5dff0a 7342 dc->desc = "PowerPC 7457 (aka G4)";
7856e3a4
AF
7343 pcc->init_proc = init_proc_7457;
7344 pcc->check_pow = check_pow_hid0_74xx;
53116ebf
AF
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 |
7348 PPC_FLOAT_STFIWX |
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 |
7355 PPC_ALTIVEC;
9df5a466
TM
7356 pcc->msr_mask = (1ull << MSR_VR) |
7357 (1ull << MSR_POW) |
7358 (1ull << MSR_ILE) |
7359 (1ull << MSR_EE) |
7360 (1ull << MSR_PR) |
7361 (1ull << MSR_FP) |
7362 (1ull << MSR_ME) |
7363 (1ull << MSR_FE0) |
7364 (1ull << MSR_SE) |
7365 (1ull << MSR_DE) |
7366 (1ull << MSR_FE1) |
7367 (1ull << MSR_EP) |
7368 (1ull << MSR_IR) |
7369 (1ull << MSR_DR) |
7370 (1ull << MSR_PMM) |
7371 (1ull << MSR_RI) |
7372 (1ull << MSR_LE);
ba9fd9f1
AF
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;
7856e3a4
AF
7380}
7381
c364946d 7382static void init_proc_e600(CPUPPCState *env)
7162bdea
JG
7383{
7384 gen_spr_ne_601(env);
4f4f28ff 7385 gen_spr_sdr1(env);
7162bdea
JG
7386 gen_spr_7xx(env);
7387 /* Time base */
7388 gen_tbl(env);
7389 /* 74xx specific SPR */
7390 gen_spr_74xx(env);
7391 /* XXX : not implemented */
7392 spr_register(env, SPR_UBAMR, "UBAMR",
7393 &spr_read_ureg, SPR_NOACCESS,
7394 &spr_read_ureg, SPR_NOACCESS,
7395 0x00000000);
7396 /* XXX : not implemented */
7397 spr_register(env, SPR_LDSTCR, "LDSTCR",
7398 SPR_NOACCESS, SPR_NOACCESS,
7399 &spr_read_generic, &spr_write_generic,
7400 0x00000000);
7401 /* XXX : not implemented */
7402 spr_register(env, SPR_ICTRL, "ICTRL",
7403 SPR_NOACCESS, SPR_NOACCESS,
7404 &spr_read_generic, &spr_write_generic,
7405 0x00000000);
7406 /* XXX : not implemented */
7407 spr_register(env, SPR_MSSSR0, "MSSSR0",
7408 SPR_NOACCESS, SPR_NOACCESS,
7409 &spr_read_generic, &spr_write_generic,
7410 0x00000000);
7411 /* XXX : not implemented */
cb8b8bf8 7412 spr_register(env, SPR_7XX_PMC5, "PMC5",
7162bdea
JG
7413 SPR_NOACCESS, SPR_NOACCESS,
7414 &spr_read_generic, &spr_write_generic,
7415 0x00000000);
7416 /* XXX : not implemented */
cb8b8bf8 7417 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
7162bdea
JG
7418 &spr_read_ureg, SPR_NOACCESS,
7419 &spr_read_ureg, SPR_NOACCESS,
7420 0x00000000);
7421 /* XXX : not implemented */
cb8b8bf8 7422 spr_register(env, SPR_7XX_PMC6, "PMC6",
7162bdea
JG
7423 SPR_NOACCESS, SPR_NOACCESS,
7424 &spr_read_generic, &spr_write_generic,
7425 0x00000000);
7426 /* XXX : not implemented */
cb8b8bf8 7427 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
7162bdea
JG
7428 &spr_read_ureg, SPR_NOACCESS,
7429 &spr_read_ureg, SPR_NOACCESS,
7430 0x00000000);
7431 /* SPRGs */
7432 spr_register(env, SPR_SPRG4, "SPRG4",
7433 SPR_NOACCESS, SPR_NOACCESS,
7434 &spr_read_generic, &spr_write_generic,
7435 0x00000000);
7436 spr_register(env, SPR_USPRG4, "USPRG4",
7437 &spr_read_ureg, SPR_NOACCESS,
7438 &spr_read_ureg, SPR_NOACCESS,
7439 0x00000000);
7440 spr_register(env, SPR_SPRG5, "SPRG5",
7441 SPR_NOACCESS, SPR_NOACCESS,
7442 &spr_read_generic, &spr_write_generic,
7443 0x00000000);
7444 spr_register(env, SPR_USPRG5, "USPRG5",
7445 &spr_read_ureg, SPR_NOACCESS,
7446 &spr_read_ureg, SPR_NOACCESS,
7447 0x00000000);
7448 spr_register(env, SPR_SPRG6, "SPRG6",
7449 SPR_NOACCESS, SPR_NOACCESS,
7450 &spr_read_generic, &spr_write_generic,
7451 0x00000000);
7452 spr_register(env, SPR_USPRG6, "USPRG6",
7453 &spr_read_ureg, SPR_NOACCESS,
7454 &spr_read_ureg, SPR_NOACCESS,
7455 0x00000000);
7456 spr_register(env, SPR_SPRG7, "SPRG7",
7457 SPR_NOACCESS, SPR_NOACCESS,
7458 &spr_read_generic, &spr_write_generic,
7459 0x00000000);
7460 spr_register(env, SPR_USPRG7, "USPRG7",
7461 &spr_read_ureg, SPR_NOACCESS,
7462 &spr_read_ureg, SPR_NOACCESS,
7463 0x00000000);
7464 /* Memory management */
7465 gen_low_BATs(env);
7466 gen_high_BATs(env);
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 */
db70b311 7472 ppc6xx_irq_init(env_archcpu(env));
7162bdea
JG
7473}
7474
7475POWERPC_FAMILY(e600)(ObjectClass *oc, void *data)
7476{
7477 DeviceClass *dc = DEVICE_CLASS(oc);
7478 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7479
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 |
7486 PPC_FLOAT_STFIWX |
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 |
7493 PPC_ALTIVEC;
7494 pcc->insns_flags2 = PPC_NONE;
9df5a466
TM
7495 pcc->msr_mask = (1ull << MSR_VR) |
7496 (1ull << MSR_POW) |
7497 (1ull << MSR_ILE) |
7498 (1ull << MSR_EE) |
7499 (1ull << MSR_PR) |
7500 (1ull << MSR_FP) |
7501 (1ull << MSR_ME) |
7502 (1ull << MSR_FE0) |
7503 (1ull << MSR_SE) |
7504 (1ull << MSR_DE) |
7505 (1ull << MSR_FE1) |
7506 (1ull << MSR_EP) |
7507 (1ull << MSR_IR) |
7508 (1ull << MSR_DR) |
7509 (1ull << MSR_PMM) |
7510 (1ull << MSR_RI) |
7511 (1ull << MSR_LE);
7162bdea
JG
7512 pcc->mmu_model = POWERPC_MMU_32B;
7513#if defined(CONFIG_SOFTMMU)
7514 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
7515#endif
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;
7522}
7523
c364946d 7524#if defined(TARGET_PPC64)
417bf010
JM
7525#if defined(CONFIG_USER_ONLY)
7526#define POWERPC970_HID5_INIT 0x00000080
7527#else
7528#define POWERPC970_HID5_INIT 0x00000000
7529#endif
7530
69b058c8
PB
7531static void gen_fscr_facility_check(DisasContext *ctx, int facility_sprn,
7532 int bit, int sprn, int cause)
45ed0be1
AK
7533{
7534 TCGv_i32 t1 = tcg_const_i32(bit);
7535 TCGv_i32 t2 = tcg_const_i32(sprn);
7536 TCGv_i32 t3 = tcg_const_i32(cause);
7537
45ed0be1
AK
7538 gen_helper_fscr_facility_check(cpu_env, t1, t2, t3);
7539
7540 tcg_temp_free_i32(t3);
7541 tcg_temp_free_i32(t2);
7542 tcg_temp_free_i32(t1);
7543}
7544
69b058c8
PB
7545static void gen_msr_facility_check(DisasContext *ctx, int facility_sprn,
7546 int bit, int sprn, int cause)
cdcdda27
AK
7547{
7548 TCGv_i32 t1 = tcg_const_i32(bit);
7549 TCGv_i32 t2 = tcg_const_i32(sprn);
7550 TCGv_i32 t3 = tcg_const_i32(cause);
7551
cdcdda27
AK
7552 gen_helper_msr_facility_check(cpu_env, t1, t2, t3);
7553
7554 tcg_temp_free_i32(t3);
7555 tcg_temp_free_i32(t2);
7556 tcg_temp_free_i32(t1);
7557}
7558
69b058c8 7559static void spr_read_prev_upper32(DisasContext *ctx, int gprn, int sprn)
cdcdda27
AK
7560{
7561 TCGv spr_up = tcg_temp_new();
7562 TCGv spr = tcg_temp_new();
7563
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);
7567
7568 tcg_temp_free(spr);
7569 tcg_temp_free(spr_up);
7570}
7571
69b058c8 7572static void spr_write_prev_upper32(DisasContext *ctx, int sprn, int gprn)
cdcdda27
AK
7573{
7574 TCGv spr = tcg_temp_new();
7575
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);
7579
7580 tcg_temp_free(spr);
7581}
7582
c364946d 7583static int check_pow_970(CPUPPCState *env)
2f462816 7584{
bbc01ca7 7585 if (env->spr[SPR_HID0] & (HID0_DEEPNAP | HID0_DOZE | HID0_NAP)) {
2f462816 7586 return 1;
bbc01ca7 7587 }
2f462816
JM
7588
7589 return 0;
7590}
7591
42382f62 7592static void gen_spr_970_hid(CPUPPCState *env)
a750fc0b 7593{
a750fc0b
JM
7594 /* Hardware implementation registers */
7595 /* XXX : not implemented */
7596 spr_register(env, SPR_HID0, "HID0",
7597 SPR_NOACCESS, SPR_NOACCESS,
06403421 7598 &spr_read_generic, &spr_write_clear,
d63001d1 7599 0x60000000);
a750fc0b
JM
7600 spr_register(env, SPR_HID1, "HID1",
7601 SPR_NOACCESS, SPR_NOACCESS,
7602 &spr_read_generic, &spr_write_generic,
7603 0x00000000);
e57448f1
JM
7604 spr_register(env, SPR_970_HID5, "HID5",
7605 SPR_NOACCESS, SPR_NOACCESS,
7606 &spr_read_generic, &spr_write_generic,
417bf010 7607 POWERPC970_HID5_INIT);
42382f62
AK
7608}
7609
7610static void gen_spr_970_hior(CPUPPCState *env)
7611{
12de9a39
JM
7612 spr_register(env, SPR_HIOR, "SPR_HIOR",
7613 SPR_NOACCESS, SPR_NOACCESS,
2adab7d6
BS
7614 &spr_read_hior, &spr_write_hior,
7615 0x00000000);
42382f62 7616}
7856e3a4 7617
4f4f28ff 7618static void gen_spr_book3s_ctrl(CPUPPCState *env)
42382f62 7619{
4e98d8cf
BS
7620 spr_register(env, SPR_CTRL, "SPR_CTRL",
7621 SPR_NOACCESS, SPR_NOACCESS,
4e381819 7622 SPR_NOACCESS, &spr_write_generic,
4e98d8cf
BS
7623 0x00000000);
7624 spr_register(env, SPR_UCTRL, "SPR_UCTRL",
eb16dd9c
AK
7625 &spr_read_ureg, SPR_NOACCESS,
7626 &spr_read_ureg, SPR_NOACCESS,
4e98d8cf 7627 0x00000000);
42382f62
AK
7628}
7629
7630static void gen_spr_book3s_altivec(CPUPPCState *env)
7631{
7632 if (!(env->insns_flags & PPC_ALTIVEC)) {
7633 return;
7634 }
7635
7303f83d
AK
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);
42382f62 7640
1d28b5f6
DG
7641 /*
7642 * Can't find information on what this should be on reset. This
7643 * value is the one used by 74xx processors.
7644 */
42382f62
AK
7645 vscr_init(env, 0x00010000);
7646}
7647
fd51ff63
AK
7648static void gen_spr_book3s_dbg(CPUPPCState *env)
7649{
cd9adfdd
AK
7650 /*
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.
7656 */
fd51ff63
AK
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);
cd9adfdd
AK
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);
fd51ff63
AK
7665}
7666
f401dd32
BH
7667static void gen_spr_book3s_207_dbg(CPUPPCState *env)
7668{
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);
eb5ceb4d
BH
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);
f401dd32
BH
7684}
7685
fd51ff63
AK
7686static void gen_spr_970_dbg(CPUPPCState *env)
7687{
7688 /* Breakpoints */
7689 spr_register(env, SPR_IABR, "IABR",
7690 SPR_NOACCESS, SPR_NOACCESS,
7691 &spr_read_generic, &spr_write_generic,
7692 0x00000000);
7693}
7694
7695static void gen_spr_book3s_pmu_sup(CPUPPCState *env)
7696{
83cc6f8c
AK
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);
fd51ff63
AK
7741}
7742
7743static void gen_spr_book3s_pmu_user(CPUPPCState *env)
7744{
7745 spr_register(env, SPR_POWER_UMMCR0, "UMMCR0",
7746 &spr_read_ureg, SPR_NOACCESS,
7747 &spr_read_ureg, &spr_write_ureg,
7748 0x00000000);
7749 spr_register(env, SPR_POWER_UMMCR1, "UMMCR1",
7750 &spr_read_ureg, SPR_NOACCESS,
7751 &spr_read_ureg, &spr_write_ureg,
7752 0x00000000);
077850b0
AK
7753 spr_register(env, SPR_POWER_UMMCRA, "UMMCRA",
7754 &spr_read_ureg, SPR_NOACCESS,
7755 &spr_read_ureg, &spr_write_ureg,
7756 0x00000000);
fd51ff63
AK
7757 spr_register(env, SPR_POWER_UPMC1, "UPMC1",
7758 &spr_read_ureg, SPR_NOACCESS,
7759 &spr_read_ureg, &spr_write_ureg,
7760 0x00000000);
7761 spr_register(env, SPR_POWER_UPMC2, "UPMC2",
7762 &spr_read_ureg, SPR_NOACCESS,
7763 &spr_read_ureg, &spr_write_ureg,
7764 0x00000000);
7765 spr_register(env, SPR_POWER_UPMC3, "UPMC3",
7766 &spr_read_ureg, SPR_NOACCESS,
7767 &spr_read_ureg, &spr_write_ureg,
7768 0x00000000);
7769 spr_register(env, SPR_POWER_UPMC4, "UPMC4",
7770 &spr_read_ureg, SPR_NOACCESS,
7771 &spr_read_ureg, &spr_write_ureg,
7772 0x00000000);
077850b0
AK
7773 spr_register(env, SPR_POWER_UPMC5, "UPMC5",
7774 &spr_read_ureg, SPR_NOACCESS,
7775 &spr_read_ureg, &spr_write_ureg,
7776 0x00000000);
7777 spr_register(env, SPR_POWER_UPMC6, "UPMC6",
7778 &spr_read_ureg, SPR_NOACCESS,
7779 &spr_read_ureg, &spr_write_ureg,
7780 0x00000000);
fd51ff63
AK
7781 spr_register(env, SPR_POWER_USIAR, "USIAR",
7782 &spr_read_ureg, SPR_NOACCESS,
7783 &spr_read_ureg, &spr_write_ureg,
7784 0x00000000);
077850b0
AK
7785 spr_register(env, SPR_POWER_USDAR, "USDAR",
7786 &spr_read_ureg, SPR_NOACCESS,
7787 &spr_read_ureg, &spr_write_ureg,
7788 0x00000000);
fd51ff63
AK
7789}
7790
c36c97f8
AK
7791static void gen_spr_970_pmu_sup(CPUPPCState *env)
7792{
83cc6f8c
AK
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);
c36c97f8
AK
7801}
7802
7803static void gen_spr_970_pmu_user(CPUPPCState *env)
7804{
7805 spr_register(env, SPR_970_UPMC7, "UPMC7",
7806 &spr_read_ureg, SPR_NOACCESS,
7807 &spr_read_ureg, &spr_write_ureg,
7808 0x00000000);
7809 spr_register(env, SPR_970_UPMC8, "UPMC8",
7810 &spr_read_ureg, SPR_NOACCESS,
7811 &spr_read_ureg, &spr_write_ureg,
7812 0x00000000);
7813}
7814
70c53407
AK
7815static void gen_spr_power8_pmu_sup(CPUPPCState *env)
7816{
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);
14646457
BH
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);
70c53407
AK
7849}
7850
7851static void gen_spr_power8_pmu_user(CPUPPCState *env)
7852{
7853 spr_register(env, SPR_POWER_UMMCR2, "UMMCR2",
7854 &spr_read_ureg, SPR_NOACCESS,
7855 &spr_read_ureg, &spr_write_ureg,
7856 0x00000000);
14646457
BH
7857 spr_register(env, SPR_POWER_USIER, "USIER",
7858 &spr_read_generic, SPR_NOACCESS,
7859 &spr_read_generic, &spr_write_generic,
7860 0x00000000);
70c53407
AK
7861}
7862
fd51ff63
AK
7863static void gen_spr_power5p_ear(CPUPPCState *env)
7864{
7865 /* External access control */
7866 spr_register(env, SPR_EAR, "EAR",
7867 SPR_NOACCESS, SPR_NOACCESS,
7868 &spr_read_generic, &spr_write_generic,
7869 0x00000000);
7870}
7871
f0ec31b1
SJS
7872static void gen_spr_power5p_tb(CPUPPCState *env)
7873{
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,
7879 0x00000000);
7880}
7881
8eeb330c
BH
7882#if !defined(CONFIG_USER_ONLY)
7883static void spr_write_hmer(DisasContext *ctx, int sprn, int gprn)
7884{
7885 TCGv hmer = tcg_temp_new();
7886
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);
7892}
4b3fc377
BH
7893
7894static void spr_write_lpcr(DisasContext *ctx, int sprn, int gprn)
7895{
7896 gen_helper_store_lpcr(cpu_env, cpu_gpr[gprn]);
7897}
4b3fc377
BH
7898#endif /* !defined(CONFIG_USER_ONLY) */
7899
7900static void gen_spr_970_lpar(CPUPPCState *env)
7901{
7902#if !defined(CONFIG_USER_ONLY)
19acd4b6
DG
7903 /*
7904 * PPC970: HID4 covers things later controlled by the LPCR and
7905 * RMOR in later CPUs, but with a different encoding. We only
7906 * support the 970 in "Apple mode" which has all hypervisor
7907 * facilities disabled by strapping, so we can basically just
7908 * ignore it
7909 */
4b3fc377
BH
7910 spr_register(env, SPR_970_HID4, "HID4",
7911 SPR_NOACCESS, SPR_NOACCESS,
19acd4b6 7912 &spr_read_generic, &spr_write_generic,
4b3fc377
BH
7913 0x00000000);
7914#endif
7915}
7916
7917static void gen_spr_power5p_lpar(CPUPPCState *env)
7918{
7919#if !defined(CONFIG_USER_ONLY)
7920 /* Logical partitionning */
635dff20
BH
7921 spr_register_kvm_hv(env, SPR_LPCR, "LPCR",
7922 SPR_NOACCESS, SPR_NOACCESS,
7923 SPR_NOACCESS, SPR_NOACCESS,
7924 &spr_read_generic, &spr_write_lpcr,
7925 KVM_REG_PPC_LPCR, LPCR_LPES0 | LPCR_LPES1);
4b236b62
BH
7926 spr_register_hv(env, SPR_HDEC, "HDEC",
7927 SPR_NOACCESS, SPR_NOACCESS,
7928 SPR_NOACCESS, SPR_NOACCESS,
7929 &spr_read_hdecr, &spr_write_hdecr, 0);
8eeb330c 7930#endif
4b3fc377 7931}
8eeb330c 7932
e61716aa
AK
7933static void gen_spr_book3s_ids(CPUPPCState *env)
7934{
8eeb330c
BH
7935 /* FIXME: Will need to deal with thread vs core only SPRs */
7936
e61716aa 7937 /* Processor identification */
8eeb330c 7938 spr_register_hv(env, SPR_PIR, "PIR",
e61716aa 7939 SPR_NOACCESS, SPR_NOACCESS,
bfda32a8 7940 &spr_read_generic, SPR_NOACCESS,
8eeb330c
BH
7941 &spr_read_generic, NULL,
7942 0x00000000);
7943 spr_register_hv(env, SPR_HID0, "HID0",
7944 SPR_NOACCESS, SPR_NOACCESS,
7945 SPR_NOACCESS, SPR_NOACCESS,
7946 &spr_read_generic, &spr_write_generic,
7947 0x00000000);
7948 spr_register_hv(env, SPR_TSCR, "TSCR",
7949 SPR_NOACCESS, SPR_NOACCESS,
7950 SPR_NOACCESS, SPR_NOACCESS,
7951 &spr_read_generic, &spr_write_generic,
7952 0x00000000);
7953 spr_register_hv(env, SPR_HMER, "HMER",
7954 SPR_NOACCESS, SPR_NOACCESS,
7955 SPR_NOACCESS, SPR_NOACCESS,
7956 &spr_read_generic, &spr_write_hmer,
7957 0x00000000);
7958 spr_register_hv(env, SPR_HMEER, "HMEER",
7959 SPR_NOACCESS, SPR_NOACCESS,
7960 SPR_NOACCESS, SPR_NOACCESS,
7961 &spr_read_generic, &spr_write_generic,
7962 0x00000000);
7963 spr_register_hv(env, SPR_TFMR, "TFMR",
7964 SPR_NOACCESS, SPR_NOACCESS,
7965 SPR_NOACCESS, SPR_NOACCESS,
7966 &spr_read_generic, &spr_write_generic,
7967 0x00000000);
7968 spr_register_hv(env, SPR_LPIDR, "LPIDR",
7969 SPR_NOACCESS, SPR_NOACCESS,
7970 SPR_NOACCESS, SPR_NOACCESS,
c4dae9cd 7971 &spr_read_generic, &spr_write_lpidr,
8eeb330c
BH
7972 0x00000000);
7973 spr_register_hv(env, SPR_HFSCR, "HFSCR",
7974 SPR_NOACCESS, SPR_NOACCESS,
7975 SPR_NOACCESS, SPR_NOACCESS,
7976 &spr_read_generic, &spr_write_generic,
7977 0x00000000);
7978 spr_register_hv(env, SPR_MMCRC, "MMCRC",
7979 SPR_NOACCESS, SPR_NOACCESS,
7980 SPR_NOACCESS, SPR_NOACCESS,
7981 &spr_read_generic, &spr_write_generic,
7982 0x00000000);
7983 spr_register_hv(env, SPR_MMCRH, "MMCRH",
7984 SPR_NOACCESS, SPR_NOACCESS,
7985 SPR_NOACCESS, SPR_NOACCESS,
7986 &spr_read_generic, &spr_write_generic,
7987 0x00000000);
7988 spr_register_hv(env, SPR_HSPRG0, "HSPRG0",
7989 SPR_NOACCESS, SPR_NOACCESS,
7990 SPR_NOACCESS, SPR_NOACCESS,
7991 &spr_read_generic, &spr_write_generic,
7992 0x00000000);
7993 spr_register_hv(env, SPR_HSPRG1, "HSPRG1",
7994 SPR_NOACCESS, SPR_NOACCESS,
7995 SPR_NOACCESS, SPR_NOACCESS,
7996 &spr_read_generic, &spr_write_generic,
7997 0x00000000);
7998 spr_register_hv(env, SPR_HSRR0, "HSRR0",
7999 SPR_NOACCESS, SPR_NOACCESS,
8000 SPR_NOACCESS, SPR_NOACCESS,
8001 &spr_read_generic, &spr_write_generic,
8002 0x00000000);
8003 spr_register_hv(env, SPR_HSRR1, "HSRR1",
8004 SPR_NOACCESS, SPR_NOACCESS,
8005 SPR_NOACCESS, SPR_NOACCESS,
8006 &spr_read_generic, &spr_write_generic,
8007 0x00000000);
8008 spr_register_hv(env, SPR_HDAR, "HDAR",
8009 SPR_NOACCESS, SPR_NOACCESS,
8010 SPR_NOACCESS, SPR_NOACCESS,
8011 &spr_read_generic, &spr_write_generic,
8012 0x00000000);
8013 spr_register_hv(env, SPR_HDSISR, "HDSISR",
8014 SPR_NOACCESS, SPR_NOACCESS,
8015 SPR_NOACCESS, SPR_NOACCESS,
8016 &spr_read_generic, &spr_write_generic,
8017 0x00000000);
51671009 8018 spr_register_hv(env, SPR_HRMOR, "HRMOR",
8eeb330c
BH
8019 SPR_NOACCESS, SPR_NOACCESS,
8020 SPR_NOACCESS, SPR_NOACCESS,
8021 &spr_read_generic, &spr_write_generic,
8022 0x00000000);
51671009
DG
8023}
8024
8025static void gen_spr_rmor(CPUPPCState *env)
8026{
8027 spr_register_hv(env, SPR_RMOR, "RMOR",
8eeb330c
BH
8028 SPR_NOACCESS, SPR_NOACCESS,
8029 SPR_NOACCESS, SPR_NOACCESS,
8030 &spr_read_generic, &spr_write_generic,
e61716aa
AK
8031 0x00000000);
8032}
8033
d1a721ab
AK
8034static void gen_spr_power8_ids(CPUPPCState *env)
8035{
8036 /* Thread identification */
8037 spr_register(env, SPR_TIR, "TIR",
8038 SPR_NOACCESS, SPR_NOACCESS,
8039 &spr_read_generic, SPR_NOACCESS,
8040 0x00000000);
8041}
8042
e61716aa
AK
8043static void gen_spr_book3s_purr(CPUPPCState *env)
8044{
8045#if !defined(CONFIG_USER_ONLY)
8046 /* PURR & SPURR: Hack - treat these as aliases for the TB for now */
5cc7e69f
SJS
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);
e61716aa
AK
8057#endif
8058}
8059
5db7d4fa
AK
8060static void gen_spr_power6_dbg(CPUPPCState *env)
8061{
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,
8066 0x00000000);
8067#endif
8068}
8069
8070static void gen_spr_power5p_common(CPUPPCState *env)
8071{
7303f83d
AK
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);
5db7d4fa
AK
8076}
8077
8078static void gen_spr_power6_common(CPUPPCState *env)
8079{
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);
8085#endif
8086 /*
8087 * Register PCR to report POWERPC_EXCP_PRIV_REG instead of
6b375544 8088 * POWERPC_EXCP_INVAL_SPR in userspace. Permit hypervisor access.
5db7d4fa 8089 */
6b375544 8090 spr_register_hv(env, SPR_PCR, "PCR",
5db7d4fa
AK
8091 SPR_NOACCESS, SPR_NOACCESS,
8092 SPR_NOACCESS, SPR_NOACCESS,
6b375544 8093 &spr_read_generic, &spr_write_pcr,
5db7d4fa
AK
8094 0x00000000);
8095}
8096
69b058c8 8097static void spr_read_tar(DisasContext *ctx, int gprn, int sprn)
45ed0be1 8098{
69b058c8
PB
8099 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_TAR, sprn, FSCR_IC_TAR);
8100 spr_read_generic(ctx, gprn, sprn);
45ed0be1
AK
8101}
8102
69b058c8 8103static void spr_write_tar(DisasContext *ctx, int sprn, int gprn)
45ed0be1 8104{
69b058c8
PB
8105 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_TAR, sprn, FSCR_IC_TAR);
8106 spr_write_generic(ctx, sprn, gprn);
45ed0be1
AK
8107}
8108
768167ab
AK
8109static void gen_spr_power8_tce_address_control(CPUPPCState *env)
8110{
1e440cbc
TH
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);
768167ab
AK
8115}
8116
69b058c8 8117static void spr_read_tm(DisasContext *ctx, int gprn, int sprn)
cdcdda27 8118{
69b058c8
PB
8119 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8120 spr_read_generic(ctx, gprn, sprn);
cdcdda27
AK
8121}
8122
69b058c8 8123static void spr_write_tm(DisasContext *ctx, int sprn, int gprn)
cdcdda27 8124{
69b058c8
PB
8125 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8126 spr_write_generic(ctx, sprn, gprn);
cdcdda27
AK
8127}
8128
69b058c8 8129static void spr_read_tm_upper32(DisasContext *ctx, int gprn, int sprn)
cdcdda27 8130{
69b058c8
PB
8131 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8132 spr_read_prev_upper32(ctx, gprn, sprn);
cdcdda27
AK
8133}
8134
69b058c8 8135static void spr_write_tm_upper32(DisasContext *ctx, int sprn, int gprn)
cdcdda27 8136{
69b058c8
PB
8137 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8138 spr_write_prev_upper32(ctx, sprn, gprn);
cdcdda27
AK
8139}
8140
8141static void gen_spr_power8_tm(CPUPPCState *env)
8142{
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,
8158 0x00000000);
8159}
8160
69b058c8 8161static void spr_read_ebb(DisasContext *ctx, int gprn, int sprn)
4ee4a03b 8162{
69b058c8
PB
8163 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8164 spr_read_generic(ctx, gprn, sprn);
4ee4a03b
AK
8165}
8166
69b058c8 8167static void spr_write_ebb(DisasContext *ctx, int sprn, int gprn)
4ee4a03b 8168{
69b058c8
PB
8169 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8170 spr_write_generic(ctx, sprn, gprn);
4ee4a03b
AK
8171}
8172
69b058c8 8173static void spr_read_ebb_upper32(DisasContext *ctx, int gprn, int sprn)
4ee4a03b 8174{
69b058c8
PB
8175 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8176 spr_read_prev_upper32(ctx, gprn, sprn);
4ee4a03b
AK
8177}
8178
69b058c8 8179static void spr_write_ebb_upper32(DisasContext *ctx, int sprn, int gprn)
4ee4a03b 8180{
69b058c8
PB
8181 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8182 spr_write_prev_upper32(ctx, sprn, gprn);
4ee4a03b
AK
8183}
8184
8185static void gen_spr_power8_ebb(CPUPPCState *env)
8186{
8187 spr_register(env, SPR_BESCRS, "BESCRS",
8188 &spr_read_ebb, &spr_write_ebb,
8189 &spr_read_generic, &spr_write_generic,
8190 0x00000000);
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,
8194 0x00000000);
8195 spr_register(env, SPR_BESCRR, "BESCRR",
8196 &spr_read_ebb, &spr_write_ebb,
8197 &spr_read_generic, &spr_write_generic,
8198 0x00000000);
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,
8202 0x00000000);
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);
8215}
8216
3ba55e39
CB
8217/* Virtual Time Base */
8218static void gen_spr_vtb(CPUPPCState *env)
8219{
5d62725b
SJS
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);
3ba55e39
CB
8225}
8226
7019cb3d
AK
8227static void gen_spr_power8_fscr(CPUPPCState *env)
8228{
45ed0be1
AK
8229#if defined(CONFIG_USER_ONLY)
8230 target_ulong initval = 1ULL << FSCR_TAR;
8231#else
8232 target_ulong initval = 0;
8233#endif
7019cb3d
AK
8234 spr_register_kvm(env, SPR_FSCR, "FSCR",
8235 SPR_NOACCESS, SPR_NOACCESS,
8236 &spr_read_generic, &spr_write_generic,
45ed0be1 8237 KVM_REG_PPC_FSCR, initval);
7019cb3d
AK
8238}
8239
d6f1445f
TH
8240static void gen_spr_power8_pspb(CPUPPCState *env)
8241{
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);
8246}
8247
cfc61ba6
AK
8248static void gen_spr_power8_dpdes(CPUPPCState *env)
8249{
8250#if !defined(CONFIG_USER_ONLY)
8251 /* Directed Privileged Door-bell Exception State, used for IPI */
5ba7ba1d
CLG
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);
cfc61ba6
AK
8257#endif
8258}
8259
21a558be
BH
8260static void gen_spr_power8_ic(CPUPPCState *env)
8261{
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,
8267 0);
9d0e5c8c
CLG
8268#endif
8269}
8270
8271static void gen_spr_power8_book4(CPUPPCState *env)
8272{
8273 /* Add a number of P8 book4 registers */
8274#if !defined(CONFIG_USER_ONLY)
9c1cf38d
BH
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,
31b2b0f8 8281 &spr_read_generic, &spr_write_pidr,
9c1cf38d
BH
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);
21a558be
BH
8287#endif
8288}
8289
8eb0f563
BH
8290static void gen_spr_power7_book4(CPUPPCState *env)
8291{
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);
8302#endif
8303}
8304
8eeb330c
BH
8305static void gen_spr_power8_rpr(CPUPPCState *env)
8306{
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);
8313#endif
8314}
8315
4a7518e0
CLG
8316static void gen_spr_power9_mmu(CPUPPCState *env)
8317{
8318#if !defined(CONFIG_USER_ONLY)
8319 /* Partition Table Control */
56de52ca
SJS
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);
32d0f0d8
SJS
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);
4a7518e0
CLG
8331#endif
8332}
8333
4f4f28ff 8334static void init_proc_book3s_common(CPUPPCState *env)
42382f62
AK
8335{
8336 gen_spr_ne_601(env);
42382f62 8337 gen_tbl(env);
b1c897d5 8338 gen_spr_usprg3(env);
42382f62 8339 gen_spr_book3s_altivec(env);
fd51ff63
AK
8340 gen_spr_book3s_pmu_sup(env);
8341 gen_spr_book3s_pmu_user(env);
4f4f28ff
SJS
8342 gen_spr_book3s_ctrl(env);
8343}
fd51ff63 8344
4f4f28ff
SJS
8345static void init_proc_970(CPUPPCState *env)
8346{
8347 /* Common Registers */
8348 init_proc_book3s_common(env);
8349 gen_spr_sdr1(env);
8350 gen_spr_book3s_dbg(env);
8351
8352 /* 970 Specific Registers */
8353 gen_spr_970_hid(env);
8354 gen_spr_970_hior(env);
8355 gen_low_BATs(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);
8360
8361 /* env variables */
d63001d1
JM
8362 env->dcache_line_size = 128;
8363 env->icache_line_size = 128;
a750fc0b 8364
4f4f28ff
SJS
8365 /* Allocate hardware IRQ controller */
8366 init_excp_970(env);
db70b311 8367 ppc970_irq_init(env_archcpu(env));
7488d481
AK
8368}
8369
bbc01ca7 8370POWERPC_FAMILY(970)(ObjectClass *oc, void *data)
7856e3a4 8371{
ca5dff0a 8372 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
8373 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8374
bbc01ca7
AK
8375 dc->desc = "PowerPC 970";
8376 pcc->init_proc = init_proc_970;
8377 pcc->check_pow = check_pow_970;
53116ebf
AF
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 |
8381 PPC_FLOAT_STFIWX |
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;
4171853c 8387 pcc->insns_flags2 = PPC2_FP_CVT_S64;
9df5a466
TM
8388 pcc->msr_mask = (1ull << MSR_SF) |
8389 (1ull << MSR_VR) |
8390 (1ull << MSR_POW) |
8391 (1ull << MSR_EE) |
8392 (1ull << MSR_PR) |
8393 (1ull << MSR_FP) |
8394 (1ull << MSR_ME) |
8395 (1ull << MSR_FE0) |
8396 (1ull << MSR_SE) |
8397 (1ull << MSR_DE) |
8398 (1ull << MSR_FE1) |
8399 (1ull << MSR_IR) |
8400 (1ull << MSR_DR) |
8401 (1ull << MSR_PMM) |
8402 (1ull << MSR_RI);
ba9fd9f1 8403 pcc->mmu_model = POWERPC_MMU_64B;
b632a148
DG
8404#if defined(CONFIG_SOFTMMU)
8405 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
21e405f1 8406 pcc->hash64_opts = &ppc_hash64_opts_basic;
b632a148 8407#endif
ba9fd9f1
AF
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;
06f6e124
AG
8414 pcc->l1_dcache_size = 0x8000;
8415 pcc->l1_icache_size = 0x10000;
7856e3a4
AF
8416}
8417
35ebcb2b
AF
8418static void init_proc_power5plus(CPUPPCState *env)
8419{
4f4f28ff
SJS
8420 /* Common Registers */
8421 init_proc_book3s_common(env);
8422 gen_spr_sdr1(env);
8423 gen_spr_book3s_dbg(env);
8424
8425 /* POWER5+ Specific Registers */
8426 gen_spr_970_hid(env);
8427 gen_spr_970_hior(env);
8428 gen_low_BATs(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);
f0ec31b1 8434 gen_spr_power5p_tb(env);
4f4f28ff
SJS
8435
8436 /* env variables */
4f4f28ff
SJS
8437 env->dcache_line_size = 128;
8438 env->icache_line_size = 128;
8439
8440 /* Allocate hardware IRQ controller */
8441 init_excp_970(env);
db70b311 8442 ppc970_irq_init(env_archcpu(env));
35ebcb2b
AF
8443}
8444
8445POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data)
8446{
8447 DeviceClass *dc = DEVICE_CLASS(oc);
8448 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8449
793826cd 8450 dc->fw_name = "PowerPC,POWER5";
35ebcb2b
AF
8451 dc->desc = "POWER5+";
8452 pcc->init_proc = init_proc_power5plus;
90618f4f 8453 pcc->check_pow = check_pow_970;
35ebcb2b
AF
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 |
8457 PPC_FLOAT_STFIWX |
8458 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8459 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8460 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
8461 PPC_64B |
8462 PPC_SEGMENT_64B | PPC_SLBI;
4171853c 8463 pcc->insns_flags2 = PPC2_FP_CVT_S64;
9df5a466
TM
8464 pcc->msr_mask = (1ull << MSR_SF) |
8465 (1ull << MSR_VR) |
8466 (1ull << MSR_POW) |
8467 (1ull << MSR_EE) |
8468 (1ull << MSR_PR) |
8469 (1ull << MSR_FP) |
8470 (1ull << MSR_ME) |
8471 (1ull << MSR_FE0) |
8472 (1ull << MSR_SE) |
8473 (1ull << MSR_DE) |
8474 (1ull << MSR_FE1) |
8475 (1ull << MSR_IR) |
8476 (1ull << MSR_DR) |
8477 (1ull << MSR_PMM) |
8478 (1ull << MSR_RI);
e232eccc
DG
8479 pcc->lpcr_mask = LPCR_RMLS | LPCR_ILE | LPCR_LPES0 | LPCR_LPES1 |
8480 LPCR_RMI | LPCR_HDICE;
aa4bb587 8481 pcc->mmu_model = POWERPC_MMU_2_03;
35ebcb2b
AF
8482#if defined(CONFIG_SOFTMMU)
8483 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
21e405f1 8484 pcc->hash64_opts = &ppc_hash64_opts_basic;
a8dafa52 8485 pcc->lrg_decr_bits = 32;
35ebcb2b
AF
8486#endif
8487 pcc->excp_model = POWERPC_EXCP_970;
8488 pcc->bus_model = PPC_FLAGS_INPUT_970;
8489 pcc->bfd_mach = bfd_mach_ppc64;
8490 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8491 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8492 POWERPC_FLAG_BUS_CLK;
06f6e124
AG
8493 pcc->l1_dcache_size = 0x8000;
8494 pcc->l1_icache_size = 0x10000;
35ebcb2b
AF
8495}
8496
c364946d 8497static void init_proc_POWER7(CPUPPCState *env)
9d52e907 8498{
4f4f28ff
SJS
8499 /* Common Registers */
8500 init_proc_book3s_common(env);
8501 gen_spr_sdr1(env);
8502 gen_spr_book3s_dbg(env);
8503
8504 /* POWER7 Specific Registers */
8505 gen_spr_book3s_ids(env);
51671009 8506 gen_spr_rmor(env);
4f4f28ff
SJS
8507 gen_spr_amr(env);
8508 gen_spr_book3s_purr(env);
8509 gen_spr_power5p_common(env);
8510 gen_spr_power5p_lpar(env);
8511 gen_spr_power5p_ear(env);
f0ec31b1 8512 gen_spr_power5p_tb(env);
4f4f28ff
SJS
8513 gen_spr_power6_common(env);
8514 gen_spr_power6_dbg(env);
8515 gen_spr_power7_book4(env);
8516
8517 /* env variables */
4f4f28ff
SJS
8518 env->dcache_line_size = 128;
8519 env->icache_line_size = 128;
8520
8521 /* Allocate hardware IRQ controller */
8522 init_excp_POWER7(env);
db70b311 8523 ppcPOWER7_irq_init(env_archcpu(env));
9d52e907 8524}
9d52e907 8525
03ae4133
AK
8526static bool ppc_pvr_match_power7(PowerPCCPUClass *pcc, uint32_t pvr)
8527{
8528 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7P_BASE) {
8529 return true;
8530 }
8531 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7_BASE) {
8532 return true;
8533 }
8534 return false;
8535}
8536
7778a575
BH
8537static bool cpu_has_work_POWER7(CPUState *cs)
8538{
8539 PowerPCCPU *cpu = POWERPC_CPU(cs);
8540 CPUPPCState *env = &cpu->env;
8541
8542 if (cs->halted) {
8543 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
8544 return false;
8545 }
8546 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
8547 (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) {
8548 return true;
8549 }
8550 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
8551 (env->spr[SPR_LPCR] & LPCR_P7_PECE1)) {
8552 return true;
8553 }
8554 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
8555 (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
8556 return true;
8557 }
8558 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
8559 (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
8560 return true;
8561 }
8562 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
8563 return true;
8564 }
8565 return false;
8566 } else {
8567 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
8568 }
8569}
8570
7856e3a4
AF
8571POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
8572{
ca5dff0a 8573 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4 8574 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7778a575 8575 CPUClass *cc = CPU_CLASS(oc);
7856e3a4 8576
793826cd 8577 dc->fw_name = "PowerPC,POWER7";
ca5dff0a 8578 dc->desc = "POWER7";
03ae4133 8579 pcc->pvr_match = ppc_pvr_match_power7;
8cd2ce7a
TH
8580 pcc->pcr_mask = PCR_VEC_DIS | PCR_VSX_DIS | PCR_COMPAT_2_05;
8581 pcc->pcr_supported = PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
7856e3a4
AF
8582 pcc->init_proc = init_proc_POWER7;
8583 pcc->check_pow = check_pow_nocheck;
7778a575 8584 cc->has_work = cpu_has_work_POWER7;
e71ec2e9 8585 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
53116ebf
AF
8586 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8587 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
ce8ca30b 8588 PPC_FLOAT_FRSQRTES |
53116ebf 8589 PPC_FLOAT_STFIWX |
c7386080 8590 PPC_FLOAT_EXT |
53116ebf
AF
8591 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8592 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8593 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
dfdd3e43 8594 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
53116ebf 8595 PPC_SEGMENT_64B | PPC_SLBI |
b7815375
BH
8596 PPC_POPCNTB | PPC_POPCNTWD |
8597 PPC_CILDST;
86ba37ed 8598 pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
1fa6c533 8599 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
29a0e4e9 8600 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
7778a575
BH
8601 PPC2_FP_TST_ISA206 | PPC2_FP_CVT_S64 |
8602 PPC2_PM_ISA206;
9df5a466
TM
8603 pcc->msr_mask = (1ull << MSR_SF) |
8604 (1ull << MSR_VR) |
8605 (1ull << MSR_VSX) |
8606 (1ull << MSR_EE) |
8607 (1ull << MSR_PR) |
8608 (1ull << MSR_FP) |
8609 (1ull << MSR_ME) |
8610 (1ull << MSR_FE0) |
8611 (1ull << MSR_SE) |
8612 (1ull << MSR_DE) |
8613 (1ull << MSR_FE1) |
8614 (1ull << MSR_IR) |
8615 (1ull << MSR_DR) |
8616 (1ull << MSR_PMM) |
8617 (1ull << MSR_RI) |
8618 (1ull << MSR_LE);
e232eccc
DG
8619 pcc->lpcr_mask = LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_DPFD |
8620 LPCR_VRMASD | LPCR_RMLS | LPCR_ILE |
8621 LPCR_P7_PECE0 | LPCR_P7_PECE1 | LPCR_P7_PECE2 |
8622 LPCR_MER | LPCR_TC |
8623 LPCR_LPES0 | LPCR_LPES1 | LPCR_HDICE;
8624 pcc->lpcr_pm = LPCR_P7_PECE0 | LPCR_P7_PECE1 | LPCR_P7_PECE2;
ba9fd9f1 8625 pcc->mmu_model = POWERPC_MMU_2_06;
b632a148
DG
8626#if defined(CONFIG_SOFTMMU)
8627 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
b07c59f7 8628 pcc->hash64_opts = &ppc_hash64_opts_POWER7;
a8dafa52 8629 pcc->lrg_decr_bits = 32;
b650d6a2
AK
8630#endif
8631 pcc->excp_model = POWERPC_EXCP_POWER7;
8632 pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
8633 pcc->bfd_mach = bfd_mach_ppc64;
8634 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8635 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8636 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
8637 POWERPC_FLAG_VSX;
8638 pcc->l1_dcache_size = 0x8000;
8639 pcc->l1_icache_size = 0x8000;
382d2db6 8640 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
b650d6a2
AK
8641}
8642
60511041
TM
8643static void init_proc_POWER8(CPUPPCState *env)
8644{
4f4f28ff
SJS
8645 /* Common Registers */
8646 init_proc_book3s_common(env);
8647 gen_spr_sdr1(env);
8648 gen_spr_book3s_207_dbg(env);
8649
8650 /* POWER8 Specific Registers */
8651 gen_spr_book3s_ids(env);
51671009 8652 gen_spr_rmor(env);
4f4f28ff
SJS
8653 gen_spr_amr(env);
8654 gen_spr_iamr(env);
8655 gen_spr_book3s_purr(env);
8656 gen_spr_power5p_common(env);
8657 gen_spr_power5p_lpar(env);
8658 gen_spr_power5p_ear(env);
f0ec31b1 8659 gen_spr_power5p_tb(env);
4f4f28ff
SJS
8660 gen_spr_power6_common(env);
8661 gen_spr_power6_dbg(env);
8662 gen_spr_power8_tce_address_control(env);
8663 gen_spr_power8_ids(env);
8664 gen_spr_power8_ebb(env);
8665 gen_spr_power8_fscr(env);
8666 gen_spr_power8_pmu_sup(env);
8667 gen_spr_power8_pmu_user(env);
8668 gen_spr_power8_tm(env);
8669 gen_spr_power8_pspb(env);
cfc61ba6 8670 gen_spr_power8_dpdes(env);
4f4f28ff
SJS
8671 gen_spr_vtb(env);
8672 gen_spr_power8_ic(env);
8673 gen_spr_power8_book4(env);
8674 gen_spr_power8_rpr(env);
8675
8676 /* env variables */
4f4f28ff
SJS
8677 env->dcache_line_size = 128;
8678 env->icache_line_size = 128;
8679
8680 /* Allocate hardware IRQ controller */
8681 init_excp_POWER8(env);
db70b311 8682 ppcPOWER7_irq_init(env_archcpu(env));
60511041
TM
8683}
8684
03ae4133
AK
8685static bool ppc_pvr_match_power8(PowerPCCPUClass *pcc, uint32_t pvr)
8686{
a88dced8
AK
8687 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8NVL_BASE) {
8688 return true;
8689 }
03ae4133
AK
8690 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8E_BASE) {
8691 return true;
8692 }
8693 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8_BASE) {
8694 return true;
8695 }
8696 return false;
8697}
8698
7778a575
BH
8699static bool cpu_has_work_POWER8(CPUState *cs)
8700{
8701 PowerPCCPU *cpu = POWERPC_CPU(cs);
8702 CPUPPCState *env = &cpu->env;
8703
8704 if (cs->halted) {
8705 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
8706 return false;
8707 }
8708 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
8709 (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) {
8710 return true;
8711 }
8712 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
8713 (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) {
8714 return true;
8715 }
8716 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
8717 (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
8718 return true;
8719 }
8720 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
8721 (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
8722 return true;
8723 }
8724 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
8725 (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) {
8726 return true;
8727 }
8728 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
8729 (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) {
8730 return true;
8731 }
8732 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
8733 return true;
8734 }
8735 return false;
8736 } else {
8737 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
8738 }
8739}
8740
b60c6007 8741POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
8d43ea1c
PS
8742{
8743 DeviceClass *dc = DEVICE_CLASS(oc);
8744 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7778a575 8745 CPUClass *cc = CPU_CLASS(oc);
8d43ea1c 8746
793826cd 8747 dc->fw_name = "PowerPC,POWER8";
b60c6007 8748 dc->desc = "POWER8";
03ae4133 8749 pcc->pvr_match = ppc_pvr_match_power8;
8cd2ce7a
TH
8750 pcc->pcr_mask = PCR_TM_DIS | PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
8751 pcc->pcr_supported = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
60511041 8752 pcc->init_proc = init_proc_POWER8;
8d43ea1c 8753 pcc->check_pow = check_pow_nocheck;
7778a575 8754 cc->has_work = cpu_has_work_POWER8;
536492eb 8755 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
8d43ea1c
PS
8756 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8757 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
ce8ca30b 8758 PPC_FLOAT_FRSQRTES |
8d43ea1c 8759 PPC_FLOAT_STFIWX |
c7386080 8760 PPC_FLOAT_EXT |
8d43ea1c
PS
8761 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8762 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8763 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
4e080611 8764 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
8d43ea1c 8765 PPC_SEGMENT_64B | PPC_SLBI |
b7815375
BH
8766 PPC_POPCNTB | PPC_POPCNTWD |
8767 PPC_CILDST;
86ba37ed 8768 pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
1fa6c533 8769 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
29a0e4e9 8770 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
38a85337 8771 PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
df99d30d 8772 PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
3e28c5e3 8773 PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
7778a575 8774 PPC2_TM | PPC2_PM_ISA206;
9df5a466 8775 pcc->msr_mask = (1ull << MSR_SF) |
23513f81 8776 (1ull << MSR_HV) |
cdcdda27 8777 (1ull << MSR_TM) |
9df5a466
TM
8778 (1ull << MSR_VR) |
8779 (1ull << MSR_VSX) |
8780 (1ull << MSR_EE) |
8781 (1ull << MSR_PR) |
8782 (1ull << MSR_FP) |
8783 (1ull << MSR_ME) |
8784 (1ull << MSR_FE0) |
8785 (1ull << MSR_SE) |
8786 (1ull << MSR_DE) |
8787 (1ull << MSR_FE1) |
8788 (1ull << MSR_IR) |
8789 (1ull << MSR_DR) |
8790 (1ull << MSR_PMM) |
8791 (1ull << MSR_RI) |
21b786f6
SG
8792 (1ull << MSR_TS0) |
8793 (1ull << MSR_TS1) |
9df5a466 8794 (1ull << MSR_LE);
e232eccc
DG
8795 pcc->lpcr_mask = LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV |
8796 LPCR_DPFD | LPCR_VRMASD | LPCR_RMLS | LPCR_ILE |
8797 LPCR_AIL | LPCR_ONL | LPCR_P8_PECE0 | LPCR_P8_PECE1 |
8798 LPCR_P8_PECE2 | LPCR_P8_PECE3 | LPCR_P8_PECE4 |
8799 LPCR_MER | LPCR_TC | LPCR_LPES0 | LPCR_HDICE;
8800 pcc->lpcr_pm = LPCR_P8_PECE0 | LPCR_P8_PECE1 | LPCR_P8_PECE2 |
8801 LPCR_P8_PECE3 | LPCR_P8_PECE4;
aa4bb587 8802 pcc->mmu_model = POWERPC_MMU_2_07;
8d43ea1c
PS
8803#if defined(CONFIG_SOFTMMU)
8804 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
b07c59f7 8805 pcc->hash64_opts = &ppc_hash64_opts_POWER7;
a8dafa52 8806 pcc->lrg_decr_bits = 32;
289af4ac 8807 pcc->n_host_threads = 8;
706d6467
AK
8808#endif
8809 pcc->excp_model = POWERPC_EXCP_POWER8;
8810 pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
8811 pcc->bfd_mach = bfd_mach_ppc64;
8812 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8813 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8814 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
8815 POWERPC_FLAG_VSX | POWERPC_FLAG_TM;
8816 pcc->l1_dcache_size = 0x8000;
8817 pcc->l1_icache_size = 0x8000;
8818 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
8819}
4f4f28ff 8820
ccd531b9
SJS
8821#ifdef CONFIG_SOFTMMU
8822/*
8823 * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings
8824 * Encoded as array of int_32s in the form:
8825 * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
8826 * x -> AP encoding
8827 * y -> radix mode supported page size (encoded as a shift)
8828 */
8829static struct ppc_radix_page_info POWER9_radix_page_info = {
8830 .count = 4,
8831 .entries = {
8832 0x0000000c, /* 4K - enc: 0x0 */
8833 0xa0000010, /* 64K - enc: 0x5 */
8834 0x20000015, /* 2M - enc: 0x1 */
8835 0x4000001e /* 1G - enc: 0x2 */
8836 }
8837};
8838#endif /* CONFIG_SOFTMMU */
8839
706d6467
AK
8840static void init_proc_POWER9(CPUPPCState *env)
8841{
4f4f28ff
SJS
8842 /* Common Registers */
8843 init_proc_book3s_common(env);
8844 gen_spr_book3s_207_dbg(env);
8845
8846 /* POWER8 Specific Registers */
8847 gen_spr_book3s_ids(env);
8848 gen_spr_amr(env);
8849 gen_spr_iamr(env);
8850 gen_spr_book3s_purr(env);
8851 gen_spr_power5p_common(env);
8852 gen_spr_power5p_lpar(env);
8853 gen_spr_power5p_ear(env);
f0ec31b1 8854 gen_spr_power5p_tb(env);
4f4f28ff
SJS
8855 gen_spr_power6_common(env);
8856 gen_spr_power6_dbg(env);
8857 gen_spr_power8_tce_address_control(env);
8858 gen_spr_power8_ids(env);
8859 gen_spr_power8_ebb(env);
8860 gen_spr_power8_fscr(env);
8861 gen_spr_power8_pmu_sup(env);
8862 gen_spr_power8_pmu_user(env);
8863 gen_spr_power8_tm(env);
8864 gen_spr_power8_pspb(env);
cfc61ba6 8865 gen_spr_power8_dpdes(env);
4f4f28ff
SJS
8866 gen_spr_vtb(env);
8867 gen_spr_power8_ic(env);
8868 gen_spr_power8_book4(env);
8869 gen_spr_power8_rpr(env);
4a7518e0 8870 gen_spr_power9_mmu(env);
4f4f28ff 8871
650f3287
DG
8872 /* POWER9 Specific registers */
8873 spr_register_kvm(env, SPR_TIDR, "TIDR", NULL, NULL,
8874 spr_read_generic, spr_write_generic,
8875 KVM_REG_PPC_TIDR, 0);
8876
b8af5b2d
DG
8877 /* FIXME: Filter fields properly based on privilege level */
8878 spr_register_kvm_hv(env, SPR_PSSCR, "PSSCR", NULL, NULL, NULL, NULL,
8879 spr_read_generic, spr_write_generic,
8880 KVM_REG_PPC_PSSCR, 0);
8881
4f4f28ff 8882 /* env variables */
4f4f28ff
SJS
8883 env->dcache_line_size = 128;
8884 env->icache_line_size = 128;
8885
8886 /* Allocate hardware IRQ controller */
d8ce5fd6 8887 init_excp_POWER9(env);
db70b311 8888 ppcPOWER9_irq_init(env_archcpu(env));
706d6467
AK
8889}
8890
8891static bool ppc_pvr_match_power9(PowerPCCPUClass *pcc, uint32_t pvr)
8892{
8893 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER9_BASE) {
8894 return true;
8895 }
8896 return false;
8897}
8898
6f46dcb3
SJS
8899static bool cpu_has_work_POWER9(CPUState *cs)
8900{
8901 PowerPCCPU *cpu = POWERPC_CPU(cs);
8902 CPUPPCState *env = &cpu->env;
8903
8904 if (cs->halted) {
21c0d66a
BH
8905 uint64_t psscr = env->spr[SPR_PSSCR];
8906
6f46dcb3
SJS
8907 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
8908 return false;
8909 }
21c0d66a
BH
8910
8911 /* If EC is clear, just return true on any pending interrupt */
8912 if (!(psscr & PSSCR_EC)) {
8913 return true;
8914 }
6f46dcb3
SJS
8915 /* External Exception */
8916 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
8917 (env->spr[SPR_LPCR] & LPCR_EEE)) {
6eebe6dc
BH
8918 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
8919 if (heic == 0 || !msr_hv || msr_pr) {
8920 return true;
8921 }
6f46dcb3
SJS
8922 }
8923 /* Decrementer Exception */
8924 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
8925 (env->spr[SPR_LPCR] & LPCR_DEE)) {
8926 return true;
8927 }
8928 /* Machine Check or Hypervisor Maintenance Exception */
8929 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK |
8930 1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) {
8931 return true;
8932 }
8933 /* Privileged Doorbell Exception */
8934 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
8935 (env->spr[SPR_LPCR] & LPCR_PDEE)) {
8936 return true;
8937 }
8938 /* Hypervisor Doorbell Exception */
8939 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
8940 (env->spr[SPR_LPCR] & LPCR_HDEE)) {
8941 return true;
8942 }
d8ce5fd6
BH
8943 /* Hypervisor virtualization exception */
8944 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HVIRT)) &&
8945 (env->spr[SPR_LPCR] & LPCR_HVEE)) {
8946 return true;
8947 }
6f46dcb3
SJS
8948 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
8949 return true;
8950 }
8951 return false;
8952 } else {
8953 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
8954 }
8955}
8956
706d6467
AK
8957POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
8958{
8959 DeviceClass *dc = DEVICE_CLASS(oc);
8960 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6f46dcb3 8961 CPUClass *cc = CPU_CLASS(oc);
706d6467
AK
8962
8963 dc->fw_name = "PowerPC,POWER9";
8964 dc->desc = "POWER9";
706d6467
AK
8965 pcc->pvr_match = ppc_pvr_match_power9;
8966 pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07;
216c944e
SJS
8967 pcc->pcr_supported = PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 |
8968 PCR_COMPAT_2_05;
706d6467
AK
8969 pcc->init_proc = init_proc_POWER9;
8970 pcc->check_pow = check_pow_nocheck;
6f46dcb3 8971 cc->has_work = cpu_has_work_POWER9;
706d6467
AK
8972 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
8973 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8974 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
8975 PPC_FLOAT_FRSQRTES |
8976 PPC_FLOAT_STFIWX |
8977 PPC_FLOAT_EXT |
8978 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8979 PPC_MEM_SYNC | PPC_MEM_EIEIO |
c8830502 8980 PPC_MEM_TLBSYNC |
da874d90 8981 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
706d6467
AK
8982 PPC_SEGMENT_64B | PPC_SLBI |
8983 PPC_POPCNTB | PPC_POPCNTWD |
8984 PPC_CILDST;
8985 pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
8986 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
8987 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
8988 PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
8989 PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
8990 PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
316aed64 8991 PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL;
706d6467 8992 pcc->msr_mask = (1ull << MSR_SF) |
23513f81 8993 (1ull << MSR_HV) |
706d6467
AK
8994 (1ull << MSR_TM) |
8995 (1ull << MSR_VR) |
8996 (1ull << MSR_VSX) |
8997 (1ull << MSR_EE) |
8998 (1ull << MSR_PR) |
8999 (1ull << MSR_FP) |
9000 (1ull << MSR_ME) |
9001 (1ull << MSR_FE0) |
9002 (1ull << MSR_SE) |
9003 (1ull << MSR_DE) |
9004 (1ull << MSR_FE1) |
9005 (1ull << MSR_IR) |
9006 (1ull << MSR_DR) |
9007 (1ull << MSR_PMM) |
9008 (1ull << MSR_RI) |
9009 (1ull << MSR_LE);
e232eccc
DG
9010 pcc->lpcr_mask = LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD |
9011 (LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL |
9012 LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR | LPCR_LD |
9013 (LPCR_PECE_L_MASK & (LPCR_PDEE | LPCR_HDEE | LPCR_EEE |
9014 LPCR_DEE | LPCR_OEE))
9015 | LPCR_MER | LPCR_GTSE | LPCR_TC |
9016 LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE | LPCR_HDICE;
9017 pcc->lpcr_pm = LPCR_PDEE | LPCR_HDEE | LPCR_EEE | LPCR_DEE | LPCR_OEE;
86cf1e9f 9018 pcc->mmu_model = POWERPC_MMU_3_00;
706d6467 9019#if defined(CONFIG_SOFTMMU)
b2899495 9020 pcc->handle_mmu_fault = ppc64_v3_handle_mmu_fault;
706d6467 9021 /* segment page size remain the same */
b07c59f7 9022 pcc->hash64_opts = &ppc_hash64_opts_POWER7;
ccd531b9 9023 pcc->radix_page_info = &POWER9_radix_page_info;
a8dafa52 9024 pcc->lrg_decr_bits = 56;
289af4ac 9025 pcc->n_host_threads = 4;
8d43ea1c 9026#endif
a790e82b 9027 pcc->excp_model = POWERPC_EXCP_POWER9;
67afe775 9028 pcc->bus_model = PPC_FLAGS_INPUT_POWER9;
8d43ea1c
PS
9029 pcc->bfd_mach = bfd_mach_ppc64;
9030 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
9031 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
74f23997 9032 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
3e28c5e3 9033 POWERPC_FLAG_VSX | POWERPC_FLAG_TM;
8d43ea1c
PS
9034 pcc->l1_dcache_size = 0x8000;
9035 pcc->l1_icache_size = 0x8000;
382d2db6 9036 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
8d43ea1c 9037}
a750fc0b 9038
7d37b274
CLG
9039#ifdef CONFIG_SOFTMMU
9040/*
9041 * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings
9042 * Encoded as array of int_32s in the form:
9043 * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
9044 * x -> AP encoding
9045 * y -> radix mode supported page size (encoded as a shift)
9046 */
9047static struct ppc_radix_page_info POWER10_radix_page_info = {
9048 .count = 4,
9049 .entries = {
9050 0x0000000c, /* 4K - enc: 0x0 */
9051 0xa0000010, /* 64K - enc: 0x5 */
9052 0x20000015, /* 2M - enc: 0x1 */
9053 0x4000001e /* 1G - enc: 0x2 */
9054 }
9055};
9056#endif /* CONFIG_SOFTMMU */
9057
9058static void init_proc_POWER10(CPUPPCState *env)
9059{
9060 /* Common Registers */
9061 init_proc_book3s_common(env);
9062 gen_spr_book3s_207_dbg(env);
9063
9064 /* POWER8 Specific Registers */
9065 gen_spr_book3s_ids(env);
9066 gen_spr_amr(env);
9067 gen_spr_iamr(env);
9068 gen_spr_book3s_purr(env);
9069 gen_spr_power5p_common(env);
9070 gen_spr_power5p_lpar(env);
9071 gen_spr_power5p_ear(env);
9072 gen_spr_power6_common(env);
9073 gen_spr_power6_dbg(env);
9074 gen_spr_power8_tce_address_control(env);
9075 gen_spr_power8_ids(env);
9076 gen_spr_power8_ebb(env);
9077 gen_spr_power8_fscr(env);
9078 gen_spr_power8_pmu_sup(env);
9079 gen_spr_power8_pmu_user(env);
9080 gen_spr_power8_tm(env);
9081 gen_spr_power8_pspb(env);
9082 gen_spr_vtb(env);
9083 gen_spr_power8_ic(env);
9084 gen_spr_power8_book4(env);
9085 gen_spr_power8_rpr(env);
9086 gen_spr_power9_mmu(env);
9087
9088 /* POWER9 Specific registers */
9089 spr_register_kvm(env, SPR_TIDR, "TIDR", NULL, NULL,
9090 spr_read_generic, spr_write_generic,
9091 KVM_REG_PPC_TIDR, 0);
9092
9093 /* FIXME: Filter fields properly based on privilege level */
9094 spr_register_kvm_hv(env, SPR_PSSCR, "PSSCR", NULL, NULL, NULL, NULL,
9095 spr_read_generic, spr_write_generic,
9096 KVM_REG_PPC_PSSCR, 0);
9097
9098 /* env variables */
9099 env->dcache_line_size = 128;
9100 env->icache_line_size = 128;
9101
9102 /* Allocate hardware IRQ controller */
9103 init_excp_POWER10(env);
9104 ppcPOWER9_irq_init(env_archcpu(env));
9105}
9106
9107static bool ppc_pvr_match_power10(PowerPCCPUClass *pcc, uint32_t pvr)
9108{
9109 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER10_BASE) {
9110 return true;
9111 }
9112 return false;
9113}
9114
9115static bool cpu_has_work_POWER10(CPUState *cs)
9116{
9117 PowerPCCPU *cpu = POWERPC_CPU(cs);
9118 CPUPPCState *env = &cpu->env;
9119
9120 if (cs->halted) {
9121 uint64_t psscr = env->spr[SPR_PSSCR];
9122
9123 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
9124 return false;
9125 }
9126
9127 /* If EC is clear, just return true on any pending interrupt */
9128 if (!(psscr & PSSCR_EC)) {
9129 return true;
9130 }
9131 /* External Exception */
9132 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
9133 (env->spr[SPR_LPCR] & LPCR_EEE)) {
9134 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
9135 if (heic == 0 || !msr_hv || msr_pr) {
9136 return true;
9137 }
9138 }
9139 /* Decrementer Exception */
9140 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
9141 (env->spr[SPR_LPCR] & LPCR_DEE)) {
9142 return true;
9143 }
9144 /* Machine Check or Hypervisor Maintenance Exception */
9145 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK |
9146 1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) {
9147 return true;
9148 }
9149 /* Privileged Doorbell Exception */
9150 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
9151 (env->spr[SPR_LPCR] & LPCR_PDEE)) {
9152 return true;
9153 }
9154 /* Hypervisor Doorbell Exception */
9155 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
9156 (env->spr[SPR_LPCR] & LPCR_HDEE)) {
9157 return true;
9158 }
9159 /* Hypervisor virtualization exception */
9160 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HVIRT)) &&
9161 (env->spr[SPR_LPCR] & LPCR_HVEE)) {
9162 return true;
9163 }
9164 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
9165 return true;
9166 }
9167 return false;
9168 } else {
9169 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
9170 }
9171}
9172
9173POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data)
9174{
9175 DeviceClass *dc = DEVICE_CLASS(oc);
9176 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
9177 CPUClass *cc = CPU_CLASS(oc);
9178
9179 dc->fw_name = "PowerPC,POWER10";
9180 dc->desc = "POWER10";
7d37b274
CLG
9181 pcc->pvr_match = ppc_pvr_match_power10;
9182 pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07 |
9183 PCR_COMPAT_3_00;
9184 pcc->pcr_supported = PCR_COMPAT_3_10 | PCR_COMPAT_3_00 | PCR_COMPAT_2_07 |
9185 PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
9186 pcc->init_proc = init_proc_POWER10;
9187 pcc->check_pow = check_pow_nocheck;
9188 cc->has_work = cpu_has_work_POWER10;
9189 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
9190 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
9191 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
9192 PPC_FLOAT_FRSQRTES |
9193 PPC_FLOAT_STFIWX |
9194 PPC_FLOAT_EXT |
9195 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
9196 PPC_MEM_SYNC | PPC_MEM_EIEIO |
9197 PPC_MEM_TLBSYNC |
9198 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
9199 PPC_SEGMENT_64B | PPC_SLBI |
9200 PPC_POPCNTB | PPC_POPCNTWD |
9201 PPC_CILDST;
9202 pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
9203 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
9204 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
9205 PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
9206 PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
9207 PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
9208 PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL;
9209 pcc->msr_mask = (1ull << MSR_SF) |
23513f81 9210 (1ull << MSR_HV) |
7d37b274
CLG
9211 (1ull << MSR_TM) |
9212 (1ull << MSR_VR) |
9213 (1ull << MSR_VSX) |
9214 (1ull << MSR_EE) |
9215 (1ull << MSR_PR) |
9216 (1ull << MSR_FP) |
9217 (1ull << MSR_ME) |
9218 (1ull << MSR_FE0) |
9219 (1ull << MSR_SE) |
9220 (1ull << MSR_DE) |
9221 (1ull << MSR_FE1) |
9222 (1ull << MSR_IR) |
9223 (1ull << MSR_DR) |
9224 (1ull << MSR_PMM) |
9225 (1ull << MSR_RI) |
9226 (1ull << MSR_LE);
e232eccc
DG
9227 pcc->lpcr_mask = LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD |
9228 (LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL |
9229 LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR | LPCR_LD |
9230 (LPCR_PECE_L_MASK & (LPCR_PDEE | LPCR_HDEE | LPCR_EEE |
9231 LPCR_DEE | LPCR_OEE))
9232 | LPCR_MER | LPCR_GTSE | LPCR_TC |
9233 LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE | LPCR_HDICE;
9234 pcc->lpcr_pm = LPCR_PDEE | LPCR_HDEE | LPCR_EEE | LPCR_DEE | LPCR_OEE;
7d37b274
CLG
9235 pcc->mmu_model = POWERPC_MMU_3_00;
9236#if defined(CONFIG_SOFTMMU)
9237 pcc->handle_mmu_fault = ppc64_v3_handle_mmu_fault;
9238 /* segment page size remain the same */
9239 pcc->hash64_opts = &ppc_hash64_opts_POWER7;
9240 pcc->radix_page_info = &POWER10_radix_page_info;
9241 pcc->lrg_decr_bits = 56;
9242#endif
9243 pcc->excp_model = POWERPC_EXCP_POWER9;
9244 pcc->bus_model = PPC_FLAGS_INPUT_POWER9;
9245 pcc->bfd_mach = bfd_mach_ppc64;
9246 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
9247 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
9248 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
9249 POWERPC_FLAG_VSX | POWERPC_FLAG_TM;
9250 pcc->l1_dcache_size = 0x8000;
9251 pcc->l1_icache_size = 0x8000;
9252 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
7d37b274
CLG
9253}
9254
26a7f129 9255#if !defined(CONFIG_USER_ONLY)
da20aed1 9256void cpu_ppc_set_vhyp(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp)
26a7f129
BH
9257{
9258 CPUPPCState *env = &cpu->env;
9259
b7b0b1f1
DG
9260 cpu->vhyp = vhyp;
9261
4550f6a5
DG
9262 /*
9263 * With a virtual hypervisor mode we never allow the CPU to go
9264 * hypervisor mode itself
26a7f129 9265 */
4550f6a5 9266 env->msr_mask &= ~MSR_HVB;
26a7f129
BH
9267}
9268
9269#endif /* !defined(CONFIG_USER_ONLY) */
9270
c364946d 9271#endif /* defined(TARGET_PPC64) */
fd5ed418 9272
a750fc0b 9273/*****************************************************************************/
60b14d95 9274/* Generic CPU instantiation routine */
cfe34f44 9275static void init_ppc_proc(PowerPCCPU *cpu)
a750fc0b 9276{
cfe34f44
AF
9277 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
9278 CPUPPCState *env = &cpu->env;
a750fc0b 9279#if !defined(CONFIG_USER_ONLY)
e1833e1f
JM
9280 int i;
9281
a750fc0b 9282 env->irq_inputs = NULL;
e1833e1f 9283 /* Set all exception vectors to an invalid address */
1d28b5f6 9284 for (i = 0; i < POWERPC_EXCP_NB; i++) {
e1833e1f 9285 env->excp_vectors[i] = (target_ulong)(-1ULL);
1d28b5f6 9286 }
e1833e1f
JM
9287 env->ivor_mask = 0x00000000;
9288 env->ivpr_mask = 0x00000000;
a750fc0b
JM
9289 /* Default MMU definitions */
9290 env->nb_BATs = 0;
9291 env->nb_tlb = 0;
9292 env->nb_ways = 0;
1c53accc 9293 env->tlb_type = TLB_NONE;
f2e63a42 9294#endif
a750fc0b
JM
9295 /* Register SPR common to all PowerPC implementations */
9296 gen_spr_generic(env);
9297 spr_register(env, SPR_PVR, "PVR",
a139aa17
NF
9298 /* Linux permits userspace to read PVR */
9299#if defined(CONFIG_LINUX_USER)
9300 &spr_read_generic,
9301#else
9302 SPR_NOACCESS,
9303#endif
9304 SPR_NOACCESS,
a750fc0b 9305 &spr_read_generic, SPR_NOACCESS,
cfe34f44 9306 pcc->pvr);
80d11f44 9307 /* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
cfe34f44
AF
9308 if (pcc->svr != POWERPC_SVR_NONE) {
9309 if (pcc->svr & POWERPC_SVR_E500) {
80d11f44
JM
9310 spr_register(env, SPR_E500_SVR, "SVR",
9311 SPR_NOACCESS, SPR_NOACCESS,
9312 &spr_read_generic, SPR_NOACCESS,
cfe34f44 9313 pcc->svr & ~POWERPC_SVR_E500);
80d11f44
JM
9314 } else {
9315 spr_register(env, SPR_SVR, "SVR",
9316 SPR_NOACCESS, SPR_NOACCESS,
9317 &spr_read_generic, SPR_NOACCESS,
cfe34f44 9318 pcc->svr);
80d11f44
JM
9319 }
9320 }
a750fc0b 9321 /* PowerPC implementation specific initialisations (SPRs, timers, ...) */
cfe34f44 9322 (*pcc->init_proc)(env);
2cf3eb6d 9323
707c7c2e
FR
9324#if !defined(CONFIG_USER_ONLY)
9325 ppc_gdb_gen_spr_xml(cpu);
9326#endif
9327
25ba3a68
JM
9328 /* MSR bits & flags consistency checks */
9329 if (env->msr_mask & (1 << 25)) {
9330 switch (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
9331 case POWERPC_FLAG_SPE:
9332 case POWERPC_FLAG_VRE:
9333 break;
9334 default:
9335 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9336 "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n");
9337 exit(1);
9338 }
9339 } else if (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
9340 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9341 "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n");
9342 exit(1);
9343 }
9344 if (env->msr_mask & (1 << 17)) {
9345 switch (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
9346 case POWERPC_FLAG_TGPR:
9347 case POWERPC_FLAG_CE:
9348 break;
9349 default:
9350 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9351 "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n");
9352 exit(1);
9353 }
9354 } else if (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
9355 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9356 "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n");
9357 exit(1);
9358 }
9359 if (env->msr_mask & (1 << 10)) {
9360 switch (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
9361 POWERPC_FLAG_UBLE)) {
9362 case POWERPC_FLAG_SE:
9363 case POWERPC_FLAG_DWE:
9364 case POWERPC_FLAG_UBLE:
9365 break;
9366 default:
9367 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9368 "Should define POWERPC_FLAG_SE or POWERPC_FLAG_DWE or "
9369 "POWERPC_FLAG_UBLE\n");
9370 exit(1);
9371 }
9372 } else if (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
9373 POWERPC_FLAG_UBLE)) {
9374 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9375 "Should not define POWERPC_FLAG_SE nor POWERPC_FLAG_DWE nor "
9376 "POWERPC_FLAG_UBLE\n");
9377 exit(1);
9378 }
9379 if (env->msr_mask & (1 << 9)) {
9380 switch (env->flags & (POWERPC_FLAG_BE | POWERPC_FLAG_DE)) {
9381 case POWERPC_FLAG_BE:
9382 case POWERPC_FLAG_DE:
9383 break;
9384 default:
9385 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9386 "Should define POWERPC_FLAG_BE or POWERPC_FLAG_DE\n");
9387 exit(1);
9388 }
9389 } else if (env->flags & (POWERPC_FLAG_BE | POWERPC_FLAG_DE)) {
9390 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9391 "Should not define POWERPC_FLAG_BE nor POWERPC_FLAG_DE\n");
9392 exit(1);
9393 }
9394 if (env->msr_mask & (1 << 2)) {
9395 switch (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
9396 case POWERPC_FLAG_PX:
9397 case POWERPC_FLAG_PMM:
9398 break;
9399 default:
9400 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9401 "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n");
9402 exit(1);
9403 }
9404 } else if (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
9405 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9406 "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n");
9407 exit(1);
9408 }
4018bae9
JM
9409 if ((env->flags & (POWERPC_FLAG_RTC_CLK | POWERPC_FLAG_BUS_CLK)) == 0) {
9410 fprintf(stderr, "PowerPC flags inconsistency\n"
9411 "Should define the time-base and decrementer clock source\n");
9412 exit(1);
9413 }
a750fc0b 9414 /* Allocate TLBs buffer when needed */
f2e63a42 9415#if !defined(CONFIG_USER_ONLY)
a750fc0b
JM
9416 if (env->nb_tlb != 0) {
9417 int nb_tlb = env->nb_tlb;
1d28b5f6 9418 if (env->id_tlbs != 0) {
a750fc0b 9419 nb_tlb *= 2;
1d28b5f6 9420 }
1c53accc
AG
9421 switch (env->tlb_type) {
9422 case TLB_6XX:
cc226c06 9423 env->tlb.tlb6 = g_new0(ppc6xx_tlb_t, nb_tlb);
1c53accc
AG
9424 break;
9425 case TLB_EMB:
cc226c06 9426 env->tlb.tlbe = g_new0(ppcemb_tlb_t, nb_tlb);
1c53accc
AG
9427 break;
9428 case TLB_MAS:
cc226c06 9429 env->tlb.tlbm = g_new0(ppcmas_tlb_t, nb_tlb);
1c53accc
AG
9430 break;
9431 }
a750fc0b
JM
9432 /* Pre-compute some useful values */
9433 env->tlb_per_way = env->nb_tlb / env->nb_ways;
9434 }
a750fc0b 9435 if (env->irq_inputs == NULL) {
8297be80
AF
9436 warn_report("no internal IRQ controller registered."
9437 " Attempt QEMU to crash very soon !");
a750fc0b
JM
9438 }
9439#endif
2f462816 9440 if (env->check_pow == NULL) {
b62e39b4 9441 warn_report("no power management check handler registered."
8297be80 9442 " Attempt QEMU to crash very soon !");
2f462816 9443 }
a750fc0b
JM
9444}
9445
9446#if defined(PPC_DUMP_CPU)
c364946d 9447static void dump_ppc_sprs(CPUPPCState *env)
a750fc0b
JM
9448{
9449 ppc_spr_t *spr;
9450#if !defined(CONFIG_USER_ONLY)
9451 uint32_t sr, sw;
9452#endif
9453 uint32_t ur, uw;
9454 int i, j, n;
9455
9456 printf("Special purpose registers:\n");
9457 for (i = 0; i < 32; i++) {
9458 for (j = 0; j < 32; j++) {
9459 n = (i << 5) | j;
9460 spr = &env->spr_cb[n];
9461 uw = spr->uea_write != NULL && spr->uea_write != SPR_NOACCESS;
9462 ur = spr->uea_read != NULL && spr->uea_read != SPR_NOACCESS;
9463#if !defined(CONFIG_USER_ONLY)
9464 sw = spr->oea_write != NULL && spr->oea_write != SPR_NOACCESS;
9465 sr = spr->oea_read != NULL && spr->oea_read != SPR_NOACCESS;
9466 if (sw || sr || uw || ur) {
9467 printf("SPR: %4d (%03x) %-8s s%c%c u%c%c\n",
9468 (i << 5) | j, (i << 5) | j, spr->name,
9469 sw ? 'w' : '-', sr ? 'r' : '-',
9470 uw ? 'w' : '-', ur ? 'r' : '-');
9471 }
9472#else
9473 if (uw || ur) {
9474 printf("SPR: %4d (%03x) %-8s u%c%c\n",
9475 (i << 5) | j, (i << 5) | j, spr->name,
9476 uw ? 'w' : '-', ur ? 'r' : '-');
9477 }
9478#endif
9479 }
9480 }
9481 fflush(stdout);
9482 fflush(stderr);
9483}
9484#endif
9485
9486/*****************************************************************************/
a750fc0b 9487
a750fc0b
JM
9488/* Opcode types */
9489enum {
9490 PPC_DIRECT = 0, /* Opcode routine */
9491 PPC_INDIRECT = 1, /* Indirect opcode table */
9492};
9493
54ff58bb
BR
9494#define PPC_OPCODE_MASK 0x3
9495
c364946d 9496static inline int is_indirect_opcode(void *handler)
a750fc0b 9497{
54ff58bb 9498 return ((uintptr_t)handler & PPC_OPCODE_MASK) == PPC_INDIRECT;
a750fc0b
JM
9499}
9500
c227f099 9501static inline opc_handler_t **ind_table(void *handler)
a750fc0b 9502{
54ff58bb 9503 return (opc_handler_t **)((uintptr_t)handler & ~PPC_OPCODE_MASK);
a750fc0b
JM
9504}
9505
9506/* Instruction table creation */
9507/* Opcodes tables creation */
c364946d 9508static void fill_new_table(opc_handler_t **table, int len)
a750fc0b
JM
9509{
9510 int i;
9511
1d28b5f6 9512 for (i = 0; i < len; i++) {
a750fc0b 9513 table[i] = &invalid_handler;
1d28b5f6 9514 }
a750fc0b
JM
9515}
9516
c364946d 9517static int create_new_table(opc_handler_t **table, unsigned char idx)
a750fc0b 9518{
c227f099 9519 opc_handler_t **tmp;
a750fc0b 9520
54ff58bb
BR
9521 tmp = g_new(opc_handler_t *, PPC_CPU_INDIRECT_OPCODES_LEN);
9522 fill_new_table(tmp, PPC_CPU_INDIRECT_OPCODES_LEN);
5724753e 9523 table[idx] = (opc_handler_t *)((uintptr_t)tmp | PPC_INDIRECT);
a750fc0b
JM
9524
9525 return 0;
9526}
9527
c364946d 9528static int insert_in_table(opc_handler_t **table, unsigned char idx,
c227f099 9529 opc_handler_t *handler)
a750fc0b 9530{
1d28b5f6 9531 if (table[idx] != &invalid_handler) {
a750fc0b 9532 return -1;
1d28b5f6 9533 }
a750fc0b
JM
9534 table[idx] = handler;
9535
9536 return 0;
9537}
9538
c364946d
DG
9539static int register_direct_insn(opc_handler_t **ppc_opcodes,
9540 unsigned char idx, opc_handler_t *handler)
a750fc0b
JM
9541{
9542 if (insert_in_table(ppc_opcodes, idx, handler) < 0) {
9543 printf("*** ERROR: opcode %02x already assigned in main "
9544 "opcode table\n", idx);
4c1b1bfe
JM
9545#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9546 printf(" Registered handler '%s' - new handler '%s'\n",
9547 ppc_opcodes[idx]->oname, handler->oname);
9548#endif
a750fc0b
JM
9549 return -1;
9550 }
9551
9552 return 0;
9553}
9554
c364946d
DG
9555static int register_ind_in_table(opc_handler_t **table,
9556 unsigned char idx1, unsigned char idx2,
9557 opc_handler_t *handler)
a750fc0b
JM
9558{
9559 if (table[idx1] == &invalid_handler) {
9560 if (create_new_table(table, idx1) < 0) {
9561 printf("*** ERROR: unable to create indirect table "
9562 "idx=%02x\n", idx1);
9563 return -1;
9564 }
9565 } else {
9566 if (!is_indirect_opcode(table[idx1])) {
9567 printf("*** ERROR: idx %02x already assigned to a direct "
9568 "opcode\n", idx1);
4c1b1bfe
JM
9569#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9570 printf(" Registered handler '%s' - new handler '%s'\n",
9571 ind_table(table[idx1])[idx2]->oname, handler->oname);
9572#endif
a750fc0b
JM
9573 return -1;
9574 }
3a607854 9575 }
a750fc0b
JM
9576 if (handler != NULL &&
9577 insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) {
9578 printf("*** ERROR: opcode %02x already assigned in "
9579 "opcode table %02x\n", idx2, idx1);
4c1b1bfe
JM
9580#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9581 printf(" Registered handler '%s' - new handler '%s'\n",
9582 ind_table(table[idx1])[idx2]->oname, handler->oname);
9583#endif
a750fc0b 9584 return -1;
3a607854 9585 }
a750fc0b
JM
9586
9587 return 0;
9588}
9589
c364946d
DG
9590static int register_ind_insn(opc_handler_t **ppc_opcodes,
9591 unsigned char idx1, unsigned char idx2,
9592 opc_handler_t *handler)
a750fc0b 9593{
74c373e4 9594 return register_ind_in_table(ppc_opcodes, idx1, idx2, handler);
a750fc0b
JM
9595}
9596
c364946d
DG
9597static int register_dblind_insn(opc_handler_t **ppc_opcodes,
9598 unsigned char idx1, unsigned char idx2,
9599 unsigned char idx3, opc_handler_t *handler)
a750fc0b
JM
9600{
9601 if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
9602 printf("*** ERROR: unable to join indirect table idx "
9603 "[%02x-%02x]\n", idx1, idx2);
9604 return -1;
9605 }
9606 if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3,
9607 handler) < 0) {
9608 printf("*** ERROR: unable to insert opcode "
9609 "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
9610 return -1;
9611 }
9612
9613 return 0;
9614}
9615
323ad19b
ND
9616static int register_trplind_insn(opc_handler_t **ppc_opcodes,
9617 unsigned char idx1, unsigned char idx2,
9618 unsigned char idx3, unsigned char idx4,
9619 opc_handler_t *handler)
9620{
9621 opc_handler_t **table;
9622
9623 if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
9624 printf("*** ERROR: unable to join indirect table idx "
9625 "[%02x-%02x]\n", idx1, idx2);
9626 return -1;
9627 }
9628 table = ind_table(ppc_opcodes[idx1]);
9629 if (register_ind_in_table(table, idx2, idx3, NULL) < 0) {
9630 printf("*** ERROR: unable to join 2nd-level indirect table idx "
9631 "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
9632 return -1;
9633 }
9634 table = ind_table(table[idx2]);
9635 if (register_ind_in_table(table, idx3, idx4, handler) < 0) {
9636 printf("*** ERROR: unable to insert opcode "
9637 "[%02x-%02x-%02x-%02x]\n", idx1, idx2, idx3, idx4);
9638 return -1;
9639 }
9640 return 0;
9641}
c364946d 9642static int register_insn(opc_handler_t **ppc_opcodes, opcode_t *insn)
a750fc0b
JM
9643{
9644 if (insn->opc2 != 0xFF) {
9645 if (insn->opc3 != 0xFF) {
323ad19b
ND
9646 if (insn->opc4 != 0xFF) {
9647 if (register_trplind_insn(ppc_opcodes, insn->opc1, insn->opc2,
9648 insn->opc3, insn->opc4,
9649 &insn->handler) < 0) {
9650 return -1;
9651 }
9652 } else {
9653 if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2,
1d28b5f6 9654 insn->opc3, &insn->handler) < 0) {
323ad19b 9655 return -1;
1d28b5f6 9656 }
323ad19b 9657 }
a750fc0b
JM
9658 } else {
9659 if (register_ind_insn(ppc_opcodes, insn->opc1,
1d28b5f6 9660 insn->opc2, &insn->handler) < 0) {
a750fc0b 9661 return -1;
1d28b5f6 9662 }
a750fc0b
JM
9663 }
9664 } else {
1d28b5f6 9665 if (register_direct_insn(ppc_opcodes, insn->opc1, &insn->handler) < 0) {
a750fc0b 9666 return -1;
1d28b5f6 9667 }
a750fc0b
JM
9668 }
9669
9670 return 0;
9671}
9672
c364946d 9673static int test_opcode_table(opc_handler_t **table, int len)
a750fc0b
JM
9674{
9675 int i, count, tmp;
9676
9677 for (i = 0, count = 0; i < len; i++) {
9678 /* Consistency fixup */
1d28b5f6 9679 if (table[i] == NULL) {
a750fc0b 9680 table[i] = &invalid_handler;
1d28b5f6 9681 }
a750fc0b
JM
9682 if (table[i] != &invalid_handler) {
9683 if (is_indirect_opcode(table[i])) {
54ff58bb
BR
9684 tmp = test_opcode_table(ind_table(table[i]),
9685 PPC_CPU_INDIRECT_OPCODES_LEN);
a750fc0b
JM
9686 if (tmp == 0) {
9687 free(table[i]);
9688 table[i] = &invalid_handler;
9689 } else {
9690 count++;
9691 }
9692 } else {
9693 count++;
9694 }
9695 }
9696 }
9697
9698 return count;
9699}
9700
c364946d 9701static void fix_opcode_tables(opc_handler_t **ppc_opcodes)
a750fc0b 9702{
1d28b5f6 9703 if (test_opcode_table(ppc_opcodes, PPC_CPU_OPCODES_LEN) == 0) {
a750fc0b 9704 printf("*** WARNING: no opcode defined !\n");
1d28b5f6 9705 }
a750fc0b
JM
9706}
9707
9708/*****************************************************************************/
2985b86b 9709static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp)
a750fc0b 9710{
2985b86b 9711 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
c227f099 9712 opcode_t *opc;
a750fc0b 9713
28876bf2 9714 fill_new_table(cpu->opcodes, PPC_CPU_OPCODES_LEN);
5c55ff99 9715 for (opc = opcodes; opc < &opcodes[ARRAY_SIZE(opcodes)]; opc++) {
cfe34f44
AF
9716 if (((opc->handler.type & pcc->insns_flags) != 0) ||
9717 ((opc->handler.type2 & pcc->insns_flags2) != 0)) {
28876bf2 9718 if (register_insn(cpu->opcodes, opc) < 0) {
2985b86b 9719 error_setg(errp, "ERROR initializing PowerPC instruction "
312fd5f2 9720 "0x%02x 0x%02x 0x%02x", opc->opc1, opc->opc2,
2985b86b
AF
9721 opc->opc3);
9722 return;
a750fc0b
JM
9723 }
9724 }
9725 }
28876bf2 9726 fix_opcode_tables(cpu->opcodes);
a750fc0b
JM
9727 fflush(stdout);
9728 fflush(stderr);
a750fc0b
JM
9729}
9730
9731#if defined(PPC_DUMP_CPU)
c364946d 9732static void dump_ppc_insns(CPUPPCState *env)
a750fc0b 9733{
c227f099 9734 opc_handler_t **table, *handler;
b55266b5 9735 const char *p, *q;
323ad19b 9736 uint8_t opc1, opc2, opc3, opc4;
a750fc0b
JM
9737
9738 printf("Instructions set:\n");
9739 /* opc1 is 6 bits long */
54ff58bb 9740 for (opc1 = 0x00; opc1 < PPC_CPU_OPCODES_LEN; opc1++) {
a750fc0b
JM
9741 table = env->opcodes;
9742 handler = table[opc1];
9743 if (is_indirect_opcode(handler)) {
9744 /* opc2 is 5 bits long */
54ff58bb 9745 for (opc2 = 0; opc2 < PPC_CPU_INDIRECT_OPCODES_LEN; opc2++) {
a750fc0b
JM
9746 table = env->opcodes;
9747 handler = env->opcodes[opc1];
9748 table = ind_table(handler);
9749 handler = table[opc2];
9750 if (is_indirect_opcode(handler)) {
9751 table = ind_table(handler);
9752 /* opc3 is 5 bits long */
54ff58bb
BR
9753 for (opc3 = 0; opc3 < PPC_CPU_INDIRECT_OPCODES_LEN;
9754 opc3++) {
a750fc0b 9755 handler = table[opc3];
323ad19b
ND
9756 if (is_indirect_opcode(handler)) {
9757 table = ind_table(handler);
9758 /* opc4 is 5 bits long */
9759 for (opc4 = 0; opc4 < PPC_CPU_INDIRECT_OPCODES_LEN;
9760 opc4++) {
9761 handler = table[opc4];
9762 if (handler->handler != &gen_invalid) {
9763 printf("INSN: %02x %02x %02x %02x -- "
9764 "(%02d %04d %02d) : %s\n",
9765 opc1, opc2, opc3, opc4,
9766 opc1, (opc3 << 5) | opc2, opc4,
4c1b1bfe
JM
9767 handler->oname);
9768 }
323ad19b
ND
9769 }
9770 } else {
9771 if (handler->handler != &gen_invalid) {
9772 /* Special hack to properly dump SPE insns */
9773 p = strchr(handler->oname, '_');
9774 if (p == NULL) {
4c1b1bfe
JM
9775 printf("INSN: %02x %02x %02x (%02d %04d) : "
9776 "%s\n",
323ad19b
ND
9777 opc1, opc2, opc3, opc1,
9778 (opc3 << 5) | opc2,
9779 handler->oname);
9780 } else {
9781 q = "speundef";
9782 if ((p - handler->oname) != strlen(q)
9783 || (memcmp(handler->oname, q, strlen(q))
9784 != 0)) {
9785 /* First instruction */
9786 printf("INSN: %02x %02x %02x"
9787 "(%02d %04d) : %.*s\n",
9788 opc1, opc2 << 1, opc3, opc1,
9789 (opc3 << 6) | (opc2 << 1),
9790 (int)(p - handler->oname),
9791 handler->oname);
9792 }
9793 if (strcmp(p + 1, q) != 0) {
9794 /* Second instruction */
9795 printf("INSN: %02x %02x %02x "
9796 "(%02d %04d) : %s\n", opc1,
9797 (opc2 << 1) | 1, opc3, opc1,
9798 (opc3 << 6) | (opc2 << 1) | 1,
9799 p + 1);
9800 }
4c1b1bfe
JM
9801 }
9802 }
a750fc0b
JM
9803 }
9804 }
9805 } else {
9806 if (handler->handler != &gen_invalid) {
9807 printf("INSN: %02x %02x -- (%02d %04d) : %s\n",
9808 opc1, opc2, opc1, opc2, handler->oname);
9809 }
9810 }
9811 }
9812 } else {
9813 if (handler->handler != &gen_invalid) {
9814 printf("INSN: %02x -- -- (%02d ----) : %s\n",
9815 opc1, opc1, handler->oname);
9816 }
9817 }
9818 }
9819}
3a607854 9820#endif
a750fc0b 9821
87601e2d
GK
9822static bool avr_need_swap(CPUPPCState *env)
9823{
9824#ifdef HOST_WORDS_BIGENDIAN
ea499e71 9825 return msr_le;
87601e2d 9826#else
ea499e71 9827 return !msr_le;
87601e2d
GK
9828#endif
9829}
9830
707c7c2e
FR
9831#if !defined(CONFIG_USER_ONLY)
9832static int gdb_find_spr_idx(CPUPPCState *env, int n)
9833{
9834 int i;
9835
9836 for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
9837 ppc_spr_t *spr = &env->spr_cb[i];
9838
9839 if (spr->name && spr->gdb_id == n) {
9840 return i;
9841 }
9842 }
9843 return -1;
9844}
9845
a010bdbe 9846static int gdb_get_spr_reg(CPUPPCState *env, GByteArray *buf, int n)
707c7c2e
FR
9847{
9848 int reg;
9849 int len;
9850
9851 reg = gdb_find_spr_idx(env, n);
9852 if (reg < 0) {
9853 return 0;
9854 }
9855
9856 len = TARGET_LONG_SIZE;
a010bdbe
AB
9857 gdb_get_regl(buf, env->spr[reg]);
9858 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, len), len);
707c7c2e
FR
9859 return len;
9860}
9861
9862static int gdb_set_spr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
9863{
9864 int reg;
9865 int len;
9866
9867 reg = gdb_find_spr_idx(env, n);
9868 if (reg < 0) {
9869 return 0;
9870 }
9871
9872 len = TARGET_LONG_SIZE;
9873 ppc_maybe_bswap_register(env, mem_buf, len);
9874 env->spr[reg] = ldn_p(mem_buf, len);
9875
9876 return len;
9877}
9878#endif
9879
a010bdbe 9880static int gdb_get_float_reg(CPUPPCState *env, GByteArray *buf, int n)
24951522 9881{
a010bdbe 9882 uint8_t *mem_buf;
24951522 9883 if (n < 32) {
a010bdbe
AB
9884 gdb_get_reg64(buf, *cpu_fpr_ptr(env, n));
9885 mem_buf = gdb_get_reg_ptr(buf, 8);
385abeb3 9886 ppc_maybe_bswap_register(env, mem_buf, 8);
24951522
AJ
9887 return 8;
9888 }
9889 if (n == 32) {
a010bdbe
AB
9890 gdb_get_reg32(buf, env->fpscr);
9891 mem_buf = gdb_get_reg_ptr(buf, 4);
385abeb3 9892 ppc_maybe_bswap_register(env, mem_buf, 4);
24951522
AJ
9893 return 4;
9894 }
9895 return 0;
9896}
9897
1328c2bf 9898static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
24951522
AJ
9899{
9900 if (n < 32) {
385abeb3 9901 ppc_maybe_bswap_register(env, mem_buf, 8);
ef96e3ae 9902 *cpu_fpr_ptr(env, n) = ldfq_p(mem_buf);
24951522
AJ
9903 return 8;
9904 }
9905 if (n == 32) {
385abeb3 9906 ppc_maybe_bswap_register(env, mem_buf, 4);
d6478bc7 9907 helper_store_fpscr(env, ldl_p(mem_buf), 0xffffffff);
24951522
AJ
9908 return 4;
9909 }
9910 return 0;
9911}
9912
a010bdbe 9913static int gdb_get_avr_reg(CPUPPCState *env, GByteArray *buf, int n)
b4f8d821 9914{
a010bdbe
AB
9915 uint8_t *mem_buf;
9916
b4f8d821 9917 if (n < 32) {
ef96e3ae 9918 ppc_avr_t *avr = cpu_avr_ptr(env, n);
87601e2d 9919 if (!avr_need_swap(env)) {
a010bdbe 9920 gdb_get_reg128(buf, avr->u64[0] , avr->u64[1]);
87601e2d 9921 } else {
a010bdbe 9922 gdb_get_reg128(buf, avr->u64[1] , avr->u64[0]);
87601e2d 9923 }
a010bdbe 9924 mem_buf = gdb_get_reg_ptr(buf, 16);
ea499e71
GK
9925 ppc_maybe_bswap_register(env, mem_buf, 8);
9926 ppc_maybe_bswap_register(env, mem_buf + 8, 8);
b4f8d821
AJ
9927 return 16;
9928 }
70976a79 9929 if (n == 32) {
a010bdbe
AB
9930 gdb_get_reg32(buf, helper_mfvscr(env));
9931 mem_buf = gdb_get_reg_ptr(buf, 4);
ea499e71 9932 ppc_maybe_bswap_register(env, mem_buf, 4);
b4f8d821
AJ
9933 return 4;
9934 }
70976a79 9935 if (n == 33) {
a010bdbe
AB
9936 gdb_get_reg32(buf, (uint32_t)env->spr[SPR_VRSAVE]);
9937 mem_buf = gdb_get_reg_ptr(buf, 4);
ea499e71 9938 ppc_maybe_bswap_register(env, mem_buf, 4);
b4f8d821
AJ
9939 return 4;
9940 }
9941 return 0;
9942}
9943
1328c2bf 9944static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
b4f8d821
AJ
9945{
9946 if (n < 32) {
ef96e3ae 9947 ppc_avr_t *avr = cpu_avr_ptr(env, n);
ea499e71
GK
9948 ppc_maybe_bswap_register(env, mem_buf, 8);
9949 ppc_maybe_bswap_register(env, mem_buf + 8, 8);
87601e2d 9950 if (!avr_need_swap(env)) {
ef96e3ae
MCA
9951 avr->u64[0] = ldq_p(mem_buf);
9952 avr->u64[1] = ldq_p(mem_buf + 8);
87601e2d 9953 } else {
ef96e3ae
MCA
9954 avr->u64[1] = ldq_p(mem_buf);
9955 avr->u64[0] = ldq_p(mem_buf + 8);
87601e2d 9956 }
b4f8d821
AJ
9957 return 16;
9958 }
70976a79 9959 if (n == 32) {
ea499e71 9960 ppc_maybe_bswap_register(env, mem_buf, 4);
c5ba06a3 9961 helper_mtvscr(env, ldl_p(mem_buf));
b4f8d821
AJ
9962 return 4;
9963 }
70976a79 9964 if (n == 33) {
ea499e71 9965 ppc_maybe_bswap_register(env, mem_buf, 4);
b4f8d821
AJ
9966 env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf);
9967 return 4;
9968 }
9969 return 0;
9970}
9971
a010bdbe 9972static int gdb_get_spe_reg(CPUPPCState *env, GByteArray *buf, int n)
688890f7
AJ
9973{
9974 if (n < 32) {
9975#if defined(TARGET_PPC64)
a010bdbe
AB
9976 gdb_get_reg32(buf, env->gpr[n] >> 32);
9977 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
688890f7 9978#else
a010bdbe 9979 gdb_get_reg32(buf, env->gprh[n]);
688890f7
AJ
9980#endif
9981 return 4;
9982 }
70976a79 9983 if (n == 32) {
a010bdbe
AB
9984 gdb_get_reg64(buf, env->spe_acc);
9985 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
688890f7
AJ
9986 return 8;
9987 }
70976a79 9988 if (n == 33) {
a010bdbe
AB
9989 gdb_get_reg32(buf, env->spe_fscr);
9990 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
688890f7
AJ
9991 return 4;
9992 }
9993 return 0;
9994}
9995
1328c2bf 9996static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
688890f7
AJ
9997{
9998 if (n < 32) {
9999#if defined(TARGET_PPC64)
10000 target_ulong lo = (uint32_t)env->gpr[n];
95f5b540
GK
10001 target_ulong hi;
10002
10003 ppc_maybe_bswap_register(env, mem_buf, 4);
10004
10005 hi = (target_ulong)ldl_p(mem_buf) << 32;
688890f7
AJ
10006 env->gpr[n] = lo | hi;
10007#else
10008 env->gprh[n] = ldl_p(mem_buf);
10009#endif
10010 return 4;
10011 }
70976a79 10012 if (n == 32) {
95f5b540 10013 ppc_maybe_bswap_register(env, mem_buf, 8);
688890f7
AJ
10014 env->spe_acc = ldq_p(mem_buf);
10015 return 8;
10016 }
70976a79 10017 if (n == 33) {
95f5b540 10018 ppc_maybe_bswap_register(env, mem_buf, 4);
d34defbc 10019 env->spe_fscr = ldl_p(mem_buf);
688890f7
AJ
10020 return 4;
10021 }
10022 return 0;
10023}
10024
a010bdbe 10025static int gdb_get_vsx_reg(CPUPPCState *env, GByteArray *buf, int n)
1438eff3
AB
10026{
10027 if (n < 32) {
a010bdbe
AB
10028 gdb_get_reg64(buf, *cpu_vsrl_ptr(env, n));
10029 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
1438eff3
AB
10030 return 8;
10031 }
10032 return 0;
10033}
10034
10035static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
10036{
10037 if (n < 32) {
10038 ppc_maybe_bswap_register(env, mem_buf, 8);
ef96e3ae 10039 *cpu_vsrl_ptr(env, n) = ldq_p(mem_buf);
1438eff3
AB
10040 return 8;
10041 }
10042 return 0;
10043}
10044
55e5c285 10045static int ppc_fixup_cpu(PowerPCCPU *cpu)
12b1143b 10046{
55e5c285
AF
10047 CPUPPCState *env = &cpu->env;
10048
1d28b5f6
DG
10049 /*
10050 * TCG doesn't (yet) emulate some groups of instructions that are
10051 * implemented on some otherwise supported CPUs (e.g. VSX and
10052 * decimal floating point instructions on POWER7). We remove
10053 * unsupported instruction groups from the cpu state's instruction
10054 * masks and hope the guest can cope. For at least the pseries
10055 * machine, the unavailability of these instructions can be
10056 * advertised to the guest via the device tree.
10057 */
12b1143b
DG
10058 if ((env->insns_flags & ~PPC_TCG_INSNS)
10059 || (env->insns_flags2 & ~PPC_TCG_INSNS2)) {
8297be80
AF
10060 warn_report("Disabling some instructions which are not "
10061 "emulated by TCG (0x%" PRIx64 ", 0x%" PRIx64 ")",
10062 env->insns_flags & ~PPC_TCG_INSNS,
10063 env->insns_flags2 & ~PPC_TCG_INSNS2);
12b1143b
DG
10064 }
10065 env->insns_flags &= PPC_TCG_INSNS;
10066 env->insns_flags2 &= PPC_TCG_INSNS2;
10067 return 0;
10068}
10069
e850da55 10070static void ppc_cpu_realize(DeviceState *dev, Error **errp)
a750fc0b 10071{
22169d41 10072 CPUState *cs = CPU(dev);
4776ce60 10073 PowerPCCPU *cpu = POWERPC_CPU(dev);
2985b86b 10074 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
2985b86b 10075 Error *local_err = NULL;
fe828a4d 10076
ce5b1bbf 10077 cpu_exec_realizefn(cs, &local_err);
6dd0f834
BR
10078 if (local_err != NULL) {
10079 error_propagate(errp, local_err);
10080 return;
10081 }
7cca3e46
SB
10082 if (cpu->vcpu_id == UNASSIGNED_CPU_INDEX) {
10083 cpu->vcpu_id = cs->cpu_index;
41264b38 10084 }
4656e1f0 10085
0ce470cd 10086 if (tcg_enabled()) {
55e5c285 10087 if (ppc_fixup_cpu(cpu) != 0) {
2985b86b 10088 error_setg(errp, "Unable to emulate selected CPU with TCG");
fd356563 10089 goto unrealize;
12b1143b
DG
10090 }
10091 }
10092
2985b86b
AF
10093 create_ppc_opcodes(cpu, &local_err);
10094 if (local_err != NULL) {
10095 error_propagate(errp, local_err);
fd356563 10096 goto unrealize;
2985b86b 10097 }
cfe34f44 10098 init_ppc_proc(cpu);
24951522 10099
cfe34f44 10100 if (pcc->insns_flags & PPC_FLOAT) {
22169d41 10101 gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
24951522
AJ
10102 33, "power-fpu.xml", 0);
10103 }
cfe34f44 10104 if (pcc->insns_flags & PPC_ALTIVEC) {
22169d41 10105 gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg,
b4f8d821
AJ
10106 34, "power-altivec.xml", 0);
10107 }
cfe34f44 10108 if (pcc->insns_flags & PPC_SPE) {
22169d41 10109 gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
688890f7
AJ
10110 34, "power-spe.xml", 0);
10111 }
1438eff3
AB
10112 if (pcc->insns_flags2 & PPC2_VSX) {
10113 gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg,
10114 32, "power-vsx.xml", 0);
10115 }
707c7c2e
FR
10116#ifndef CONFIG_USER_ONLY
10117 gdb_register_coprocessor(cs, gdb_get_spr_reg, gdb_set_spr_reg,
10118 pcc->gdb_num_sprs, "power-spr.xml", 0);
10119#endif
14a10fc3
AF
10120 qemu_init_vcpu(cs);
10121
4776ce60
AF
10122 pcc->parent_realize(dev, errp);
10123
a750fc0b 10124#if defined(PPC_DUMP_CPU)
3a607854 10125 {
22169d41 10126 CPUPPCState *env = &cpu->env;
b55266b5 10127 const char *mmu_model, *excp_model, *bus_model;
a750fc0b
JM
10128 switch (env->mmu_model) {
10129 case POWERPC_MMU_32B:
10130 mmu_model = "PowerPC 32";
10131 break;
a750fc0b
JM
10132 case POWERPC_MMU_SOFT_6xx:
10133 mmu_model = "PowerPC 6xx/7xx with software driven TLBs";
10134 break;
10135 case POWERPC_MMU_SOFT_74xx:
10136 mmu_model = "PowerPC 74xx with software driven TLBs";
10137 break;
10138 case POWERPC_MMU_SOFT_4xx:
10139 mmu_model = "PowerPC 4xx with software driven TLBs";
10140 break;
10141 case POWERPC_MMU_SOFT_4xx_Z:
10142 mmu_model = "PowerPC 4xx with software driven TLBs "
10143 "and zones protections";
10144 break;
b4095fed
JM
10145 case POWERPC_MMU_REAL:
10146 mmu_model = "PowerPC real mode only";
10147 break;
10148 case POWERPC_MMU_MPC8xx:
10149 mmu_model = "PowerPC MPC8xx";
a750fc0b
JM
10150 break;
10151 case POWERPC_MMU_BOOKE:
10152 mmu_model = "PowerPC BookE";
10153 break;
01662f3e
AG
10154 case POWERPC_MMU_BOOKE206:
10155 mmu_model = "PowerPC BookE 2.06";
a750fc0b 10156 break;
b4095fed
JM
10157 case POWERPC_MMU_601:
10158 mmu_model = "PowerPC 601";
10159 break;
c364946d 10160#if defined(TARGET_PPC64)
00af685f
JM
10161 case POWERPC_MMU_64B:
10162 mmu_model = "PowerPC 64";
10163 break;
00af685f 10164#endif
a750fc0b
JM
10165 default:
10166 mmu_model = "Unknown or invalid";
10167 break;
10168 }
10169 switch (env->excp_model) {
10170 case POWERPC_EXCP_STD:
10171 excp_model = "PowerPC";
10172 break;
10173 case POWERPC_EXCP_40x:
10174 excp_model = "PowerPC 40x";
10175 break;
10176 case POWERPC_EXCP_601:
10177 excp_model = "PowerPC 601";
10178 break;
10179 case POWERPC_EXCP_602:
10180 excp_model = "PowerPC 602";
10181 break;
10182 case POWERPC_EXCP_603:
10183 excp_model = "PowerPC 603";
10184 break;
10185 case POWERPC_EXCP_603E:
10186 excp_model = "PowerPC 603e";
10187 break;
10188 case POWERPC_EXCP_604:
10189 excp_model = "PowerPC 604";
10190 break;
10191 case POWERPC_EXCP_7x0:
10192 excp_model = "PowerPC 740/750";
10193 break;
10194 case POWERPC_EXCP_7x5:
10195 excp_model = "PowerPC 745/755";
10196 break;
10197 case POWERPC_EXCP_74xx:
10198 excp_model = "PowerPC 74xx";
10199 break;
a750fc0b
JM
10200 case POWERPC_EXCP_BOOKE:
10201 excp_model = "PowerPC BookE";
10202 break;
c364946d 10203#if defined(TARGET_PPC64)
00af685f
JM
10204 case POWERPC_EXCP_970:
10205 excp_model = "PowerPC 970";
10206 break;
10207#endif
a750fc0b
JM
10208 default:
10209 excp_model = "Unknown or invalid";
10210 break;
10211 }
10212 switch (env->bus_model) {
10213 case PPC_FLAGS_INPUT_6xx:
10214 bus_model = "PowerPC 6xx";
10215 break;
10216 case PPC_FLAGS_INPUT_BookE:
10217 bus_model = "PowerPC BookE";
10218 break;
10219 case PPC_FLAGS_INPUT_405:
10220 bus_model = "PowerPC 405";
10221 break;
a750fc0b
JM
10222 case PPC_FLAGS_INPUT_401:
10223 bus_model = "PowerPC 401/403";
10224 break;
b4095fed
JM
10225 case PPC_FLAGS_INPUT_RCPU:
10226 bus_model = "RCPU / MPC8xx";
10227 break;
c364946d 10228#if defined(TARGET_PPC64)
00af685f
JM
10229 case PPC_FLAGS_INPUT_970:
10230 bus_model = "PowerPC 970";
10231 break;
10232#endif
a750fc0b
JM
10233 default:
10234 bus_model = "Unknown or invalid";
10235 break;
10236 }
10237 printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64 "\n"
10238 " MMU model : %s\n",
a5100e75
AK
10239 object_class_get_name(OBJECT_CLASS(pcc)),
10240 pcc->pvr, pcc->msr_mask, mmu_model);
f2e63a42 10241#if !defined(CONFIG_USER_ONLY)
a5100e75 10242 if (env->tlb.tlb6) {
a750fc0b
JM
10243 printf(" %d %s TLB in %d ways\n",
10244 env->nb_tlb, env->id_tlbs ? "splitted" : "merged",
10245 env->nb_ways);
10246 }
f2e63a42 10247#endif
a750fc0b
JM
10248 printf(" Exceptions model : %s\n"
10249 " Bus model : %s\n",
10250 excp_model, bus_model);
25ba3a68 10251 printf(" MSR features :\n");
1d28b5f6 10252 if (env->flags & POWERPC_FLAG_SPE) {
25ba3a68
JM
10253 printf(" signal processing engine enable"
10254 "\n");
1d28b5f6 10255 } else if (env->flags & POWERPC_FLAG_VRE) {
25ba3a68 10256 printf(" vector processor enable\n");
1d28b5f6
DG
10257 }
10258 if (env->flags & POWERPC_FLAG_TGPR) {
25ba3a68 10259 printf(" temporary GPRs\n");
1d28b5f6 10260 } else if (env->flags & POWERPC_FLAG_CE) {
25ba3a68 10261 printf(" critical input enable\n");
1d28b5f6
DG
10262 }
10263 if (env->flags & POWERPC_FLAG_SE) {
25ba3a68 10264 printf(" single-step trace mode\n");
1d28b5f6 10265 } else if (env->flags & POWERPC_FLAG_DWE) {
25ba3a68 10266 printf(" debug wait enable\n");
1d28b5f6 10267 } else if (env->flags & POWERPC_FLAG_UBLE) {
25ba3a68 10268 printf(" user BTB lock enable\n");
1d28b5f6
DG
10269 }
10270 if (env->flags & POWERPC_FLAG_BE) {
25ba3a68 10271 printf(" branch-step trace mode\n");
1d28b5f6 10272 } else if (env->flags & POWERPC_FLAG_DE) {
25ba3a68 10273 printf(" debug interrupt enable\n");
1d28b5f6
DG
10274 }
10275 if (env->flags & POWERPC_FLAG_PX) {
25ba3a68 10276 printf(" inclusive protection\n");
1d28b5f6 10277 } else if (env->flags & POWERPC_FLAG_PMM) {
25ba3a68 10278 printf(" performance monitor mark\n");
1d28b5f6
DG
10279 }
10280 if (env->flags == POWERPC_FLAG_NONE) {
25ba3a68 10281 printf(" none\n");
1d28b5f6 10282 }
4018bae9
JM
10283 printf(" Time-base/decrementer clock source: %s\n",
10284 env->flags & POWERPC_FLAG_RTC_CLK ? "RTC clock" : "bus clock");
22169d41
AF
10285 dump_ppc_insns(env);
10286 dump_ppc_sprs(env);
10287 fflush(stdout);
a750fc0b 10288 }
3a607854 10289#endif
fd356563
BR
10290 return;
10291
10292unrealize:
10293 cpu_exec_unrealizefn(cs);
a750fc0b 10294}
3fc6c082 10295
e850da55 10296static void ppc_cpu_unrealize(DeviceState *dev, Error **errp)
b048960f
AF
10297{
10298 PowerPCCPU *cpu = POWERPC_CPU(dev);
7bbc124e 10299 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
7bbc124e 10300 Error *local_err = NULL;
323ad19b
ND
10301 opc_handler_t **table, **table_2;
10302 int i, j, k;
b048960f 10303
7bbc124e
LV
10304 pcc->parent_unrealize(dev, &local_err);
10305 if (local_err != NULL) {
10306 error_propagate(errp, local_err);
10307 return;
10308 }
6dd0f834 10309
b048960f 10310 for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) {
28876bf2 10311 if (cpu->opcodes[i] == &invalid_handler) {
81f194dd
BR
10312 continue;
10313 }
28876bf2
AB
10314 if (is_indirect_opcode(cpu->opcodes[i])) {
10315 table = ind_table(cpu->opcodes[i]);
81f194dd 10316 for (j = 0; j < PPC_CPU_INDIRECT_OPCODES_LEN; j++) {
323ad19b
ND
10317 if (table[j] == &invalid_handler) {
10318 continue;
10319 }
10320 if (is_indirect_opcode(table[j])) {
10321 table_2 = ind_table(table[j]);
10322 for (k = 0; k < PPC_CPU_INDIRECT_OPCODES_LEN; k++) {
10323 if (table_2[k] != &invalid_handler &&
10324 is_indirect_opcode(table_2[k])) {
10325 g_free((opc_handler_t *)((uintptr_t)table_2[k] &
10326 ~PPC_INDIRECT));
10327 }
10328 }
81f194dd 10329 g_free((opc_handler_t *)((uintptr_t)table[j] &
323ad19b 10330 ~PPC_INDIRECT));
81f194dd
BR
10331 }
10332 }
28876bf2 10333 g_free((opc_handler_t *)((uintptr_t)cpu->opcodes[i] &
81f194dd 10334 ~PPC_INDIRECT));
b048960f
AF
10335 }
10336 }
10337}
10338
2985b86b 10339static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b)
f0ad8c34 10340{
2985b86b
AF
10341 ObjectClass *oc = (ObjectClass *)a;
10342 uint32_t pvr = *(uint32_t *)b;
10343 PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
10344
10345 /* -cpu host does a PVR lookup during construction */
10346 if (unlikely(strcmp(object_class_get_name(oc),
10347 TYPE_HOST_POWERPC_CPU) == 0)) {
10348 return -1;
f0ad8c34 10349 }
f0ad8c34 10350
cfe34f44 10351 return pcc->pvr == pvr ? 0 : -1;
f0ad8c34
AG
10352}
10353
2985b86b 10354PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr)
3fc6c082 10355{
2985b86b
AF
10356 GSList *list, *item;
10357 PowerPCCPUClass *pcc = NULL;
be40edcd 10358
2985b86b
AF
10359 list = object_class_get_list(TYPE_POWERPC_CPU, false);
10360 item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr);
10361 if (item != NULL) {
10362 pcc = POWERPC_CPU_CLASS(item->data);
3fc6c082 10363 }
2985b86b
AF
10364 g_slist_free(list);
10365
10366 return pcc;
10367}
10368
3bc9ccc0
AK
10369static gint ppc_cpu_compare_class_pvr_mask(gconstpointer a, gconstpointer b)
10370{
10371 ObjectClass *oc = (ObjectClass *)a;
10372 uint32_t pvr = *(uint32_t *)b;
10373 PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
3bc9ccc0
AK
10374
10375 /* -cpu host does a PVR lookup during construction */
10376 if (unlikely(strcmp(object_class_get_name(oc),
10377 TYPE_HOST_POWERPC_CPU) == 0)) {
10378 return -1;
10379 }
10380
03ae4133
AK
10381 if (pcc->pvr_match(pcc, pvr)) {
10382 return 0;
10383 }
3bc9ccc0 10384
03ae4133 10385 return -1;
3bc9ccc0
AK
10386}
10387
10388PowerPCCPUClass *ppc_cpu_class_by_pvr_mask(uint32_t pvr)
10389{
10390 GSList *list, *item;
10391 PowerPCCPUClass *pcc = NULL;
10392
10393 list = object_class_get_list(TYPE_POWERPC_CPU, true);
10394 item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr_mask);
10395 if (item != NULL) {
10396 pcc = POWERPC_CPU_CLASS(item->data);
10397 }
10398 g_slist_free(list);
10399
10400 return pcc;
10401}
10402
2e9c10eb 10403static const char *ppc_cpu_lookup_alias(const char *alias)
b918f885
IM
10404{
10405 int ai;
10406
10407 for (ai = 0; ppc_cpu_aliases[ai].alias != NULL; ai++) {
10408 if (strcmp(ppc_cpu_aliases[ai].alias, alias) == 0) {
10409 return ppc_cpu_aliases[ai].model;
10410 }
10411 }
10412
10413 return NULL;
10414}
10415
2985b86b 10416static ObjectClass *ppc_cpu_class_by_name(const char *name)
ee4e83ed 10417{
03c9141d
IM
10418 char *cpu_model, *typename;
10419 ObjectClass *oc;
b55266b5 10420 const char *p;
b376db77
IM
10421 unsigned long pvr;
10422
1d28b5f6
DG
10423 /*
10424 * Lookup by PVR if cpu_model is valid 8 digit hex number (excl:
10425 * 0x prefix if present)
b376db77
IM
10426 */
10427 if (!qemu_strtoul(name, &p, 16, &pvr)) {
10428 int len = p - name;
10429 len = (len == 10) && (name[1] == 'x') ? len - 2 : len;
10430 if ((len == 8) && (*p == '\0')) {
10431 return OBJECT_CLASS(ppc_cpu_class_by_pvr(pvr));
f0ad8c34 10432 }
2985b86b 10433 }
f0ad8c34 10434
03c9141d
IM
10435 cpu_model = g_ascii_strdown(name, -1);
10436 p = ppc_cpu_lookup_alias(cpu_model);
10437 if (p) {
10438 g_free(cpu_model);
10439 cpu_model = g_strdup(p);
3fc6c082 10440 }
ee4e83ed 10441
03c9141d
IM
10442 typename = g_strdup_printf("%s" POWERPC_CPU_TYPE_SUFFIX, cpu_model);
10443 oc = object_class_by_name(typename);
10444 g_free(typename);
10445 g_free(cpu_model);
fdf8a960 10446
a69dc537 10447 return oc;
3fc6c082
FB
10448}
10449
b8e99967
IM
10450static void ppc_cpu_parse_featurestr(const char *type, char *features,
10451 Error **errp)
10452{
10453 Object *machine = qdev_get_machine();
10454 const PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(object_class_by_name(type));
10455
10456 if (!features) {
10457 return;
10458 }
10459
10460 if (object_property_find(machine, "max-cpu-compat", NULL)) {
10461 int i;
10462 char **inpieces;
10463 char *s = features;
10464 Error *local_err = NULL;
10465 char *compat_str = NULL;
10466
10467 /*
10468 * Backwards compatibility hack:
10469 *
10470 * CPUs had a "compat=" property which didn't make sense for
10471 * anything except pseries. It was replaced by "max-cpu-compat"
10472 * machine option. This supports old command lines like
10473 * -cpu POWER8,compat=power7
10474 * By stripping the compat option and applying it to the machine
10475 * before passing it on to the cpu level parser.
10476 */
10477 inpieces = g_strsplit(features, ",", 0);
10478 *s = '\0';
10479 for (i = 0; inpieces[i]; i++) {
10480 if (g_str_has_prefix(inpieces[i], "compat=")) {
22062e54
GK
10481 warn_report_once("CPU 'compat' property is deprecated; "
10482 "use max-cpu-compat machine property instead");
b8e99967
IM
10483 compat_str = inpieces[i];
10484 continue;
10485 }
10486 if ((i != 0) && (s != features)) {
10487 s = g_stpcpy(s, ",");
10488 }
10489 s = g_stpcpy(s, inpieces[i]);
10490 }
10491
10492 if (compat_str) {
10493 char *v = compat_str + strlen("compat=");
10494 object_property_set_str(machine, v, "max-cpu-compat", &local_err);
10495 }
10496 g_strfreev(inpieces);
10497 if (local_err) {
10498 error_propagate(errp, local_err);
10499 return;
10500 }
10501 }
10502
10503 /* do property processing with generic handler */
10504 pcc->parent_parse_features(type, features, errp);
10505}
10506
e9edd931
TH
10507PowerPCCPUClass *ppc_cpu_get_family_class(PowerPCCPUClass *pcc)
10508{
10509 ObjectClass *oc = OBJECT_CLASS(pcc);
10510
10511 while (oc && !object_class_is_abstract(oc)) {
10512 oc = object_class_get_parent(oc);
10513 }
10514 assert(oc);
10515
10516 return POWERPC_CPU_CLASS(oc);
10517}
10518
2985b86b
AF
10519/* Sort by PVR, ordering special case "host" last. */
10520static gint ppc_cpu_list_compare(gconstpointer a, gconstpointer b)
10521{
10522 ObjectClass *oc_a = (ObjectClass *)a;
10523 ObjectClass *oc_b = (ObjectClass *)b;
10524 PowerPCCPUClass *pcc_a = POWERPC_CPU_CLASS(oc_a);
10525 PowerPCCPUClass *pcc_b = POWERPC_CPU_CLASS(oc_b);
10526 const char *name_a = object_class_get_name(oc_a);
10527 const char *name_b = object_class_get_name(oc_b);
10528
10529 if (strcmp(name_a, TYPE_HOST_POWERPC_CPU) == 0) {
10530 return 1;
10531 } else if (strcmp(name_b, TYPE_HOST_POWERPC_CPU) == 0) {
10532 return -1;
10533 } else {
10534 /* Avoid an integer overflow during subtraction */
cfe34f44 10535 if (pcc_a->pvr < pcc_b->pvr) {
2985b86b 10536 return -1;
cfe34f44 10537 } else if (pcc_a->pvr > pcc_b->pvr) {
2985b86b
AF
10538 return 1;
10539 } else {
10540 return 0;
10541 }
10542 }
10543}
10544
10545static void ppc_cpu_list_entry(gpointer data, gpointer user_data)
10546{
10547 ObjectClass *oc = data;
2985b86b 10548 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
e9edd931 10549 DeviceClass *family = DEVICE_CLASS(ppc_cpu_get_family_class(pcc));
de400129
AF
10550 const char *typename = object_class_get_name(oc);
10551 char *name;
55d3d1a4 10552 int i;
2985b86b 10553
5ba4576b
AF
10554 if (unlikely(strcmp(typename, TYPE_HOST_POWERPC_CPU) == 0)) {
10555 return;
10556 }
4d7fb187 10557
de400129 10558 name = g_strndup(typename,
c9137065 10559 strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX));
0442428a 10560 qemu_printf("PowerPC %-16s PVR %08x\n", name, pcc->pvr);
e9a96075 10561 for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
9761ad75 10562 PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
2527cb91 10563 ObjectClass *alias_oc = ppc_cpu_class_by_name(alias->model);
55d3d1a4
AF
10564
10565 if (alias_oc != oc) {
10566 continue;
10567 }
e9edd931
TH
10568 /*
10569 * If running with KVM, we might update the family alias later, so
10570 * avoid printing the wrong alias here and use "preferred" instead
10571 */
10572 if (strcmp(alias->alias, family->desc) == 0) {
0442428a
MA
10573 qemu_printf("PowerPC %-16s (alias for preferred %s CPU)\n",
10574 alias->alias, family->desc);
e9edd931 10575 } else {
0442428a
MA
10576 qemu_printf("PowerPC %-16s (alias for %s)\n",
10577 alias->alias, name);
e9edd931 10578 }
55d3d1a4 10579 }
de400129 10580 g_free(name);
2985b86b
AF
10581}
10582
0442428a 10583void ppc_cpu_list(void)
2985b86b 10584{
2985b86b
AF
10585 GSList *list;
10586
10587 list = object_class_get_list(TYPE_POWERPC_CPU, false);
10588 list = g_slist_sort(list, ppc_cpu_list_compare);
0442428a 10589 g_slist_foreach(list, ppc_cpu_list_entry, NULL);
2985b86b 10590 g_slist_free(list);
fd5ed418 10591
5ba4576b 10592#ifdef CONFIG_KVM
0442428a
MA
10593 qemu_printf("\n");
10594 qemu_printf("PowerPC %-16s\n", "host");
5ba4576b 10595#endif
2985b86b
AF
10596}
10597
10598static void ppc_cpu_defs_entry(gpointer data, gpointer user_data)
10599{
10600 ObjectClass *oc = data;
10601 CpuDefinitionInfoList **first = user_data;
de400129 10602 const char *typename;
2985b86b
AF
10603 CpuDefinitionInfoList *entry;
10604 CpuDefinitionInfo *info;
10605
de400129 10606 typename = object_class_get_name(oc);
2985b86b 10607 info = g_malloc0(sizeof(*info));
de400129 10608 info->name = g_strndup(typename,
c9137065 10609 strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX));
2985b86b
AF
10610
10611 entry = g_malloc0(sizeof(*entry));
10612 entry->value = info;
10613 entry->next = *first;
10614 *first = entry;
3fc6c082 10615}
1d0cb67d 10616
25a9d6ca 10617CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
70b7660a
AL
10618{
10619 CpuDefinitionInfoList *cpu_list = NULL;
2985b86b 10620 GSList *list;
35e21d3f 10621 int i;
70b7660a 10622
2985b86b
AF
10623 list = object_class_get_list(TYPE_POWERPC_CPU, false);
10624 g_slist_foreach(list, ppc_cpu_defs_entry, &cpu_list);
10625 g_slist_free(list);
70b7660a 10626
e9a96075 10627 for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
9761ad75 10628 PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
35e21d3f
AF
10629 ObjectClass *oc;
10630 CpuDefinitionInfoList *entry;
10631 CpuDefinitionInfo *info;
10632
2527cb91 10633 oc = ppc_cpu_class_by_name(alias->model);
35e21d3f
AF
10634 if (oc == NULL) {
10635 continue;
10636 }
10637
10638 info = g_malloc0(sizeof(*info));
10639 info->name = g_strdup(alias->alias);
8ed877b7 10640 info->q_typename = g_strdup(object_class_get_name(oc));
35e21d3f
AF
10641
10642 entry = g_malloc0(sizeof(*entry));
10643 entry->value = info;
10644 entry->next = cpu_list;
10645 cpu_list = entry;
10646 }
10647
2985b86b
AF
10648 return cpu_list;
10649}
70b7660a 10650
f45748f1
AF
10651static void ppc_cpu_set_pc(CPUState *cs, vaddr value)
10652{
10653 PowerPCCPU *cpu = POWERPC_CPU(cs);
10654
10655 cpu->env.nip = value;
10656}
10657
8c2e1b00
AF
10658static bool ppc_cpu_has_work(CPUState *cs)
10659{
10660 PowerPCCPU *cpu = POWERPC_CPU(cs);
10661 CPUPPCState *env = &cpu->env;
10662
10663 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
10664}
10665
781c67ca 10666static void ppc_cpu_reset(DeviceState *dev)
1d0cb67d 10667{
781c67ca 10668 CPUState *s = CPU(dev);
1d0cb67d
AF
10669 PowerPCCPU *cpu = POWERPC_CPU(s);
10670 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
10671 CPUPPCState *env = &cpu->env;
a1389542 10672 target_ulong msr;
d197fdbc 10673 int i;
a1389542 10674
781c67ca 10675 pcc->parent_reset(dev);
1d0cb67d 10676
a1389542 10677 msr = (target_ulong)0;
932ccbdd 10678 msr |= (target_ulong)MSR_HVB;
a1389542
AF
10679 msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */
10680 msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */
10681 msr |= (target_ulong)1 << MSR_EP;
10682#if defined(DO_SINGLE_STEP) && 0
10683 /* Single step trace mode */
10684 msr |= (target_ulong)1 << MSR_SE;
10685 msr |= (target_ulong)1 << MSR_BE;
10686#endif
10687#if defined(CONFIG_USER_ONLY)
10688 msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
e82c42b7
RH
10689 msr |= (target_ulong)1 << MSR_FE0; /* Allow floating point exceptions */
10690 msr |= (target_ulong)1 << MSR_FE1;
a1389542 10691 msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
5b274ed7 10692 msr |= (target_ulong)1 << MSR_VSX; /* Allow VSX usage */
a1389542
AF
10693 msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
10694 msr |= (target_ulong)1 << MSR_PR;
cdcdda27
AK
10695#if defined(TARGET_PPC64)
10696 msr |= (target_ulong)1 << MSR_TM; /* Transactional memory */
10697#endif
e22c357b
DK
10698#if !defined(TARGET_WORDS_BIGENDIAN)
10699 msr |= (target_ulong)1 << MSR_LE; /* Little-endian user mode */
a74029f6
RH
10700 if (!((env->msr_mask >> MSR_LE) & 1)) {
10701 fprintf(stderr, "Selected CPU does not support little-endian.\n");
10702 exit(1);
10703 }
e22c357b 10704#endif
a1389542 10705#endif
2cf3eb6d 10706
a1389542
AF
10707#if defined(TARGET_PPC64)
10708 if (env->mmu_model & POWERPC_MMU_64) {
8b9f2118 10709 msr |= (1ULL << MSR_SF);
a1389542
AF
10710 }
10711#endif
2cf3eb6d
FC
10712
10713 hreg_store_msr(env, msr, 1);
10714
10715#if !defined(CONFIG_USER_ONLY)
10716 env->nip = env->hreset_vector | env->excp_prefix;
10717 if (env->mmu_model != POWERPC_MMU_REAL) {
10718 ppc_tlb_invalidate_all(env);
10719 }
10720#endif
10721
a1389542
AF
10722 hreg_compute_hflags(env);
10723 env->reserve_addr = (target_ulong)-1ULL;
10724 /* Be sure no exception or interrupt is pending */
10725 env->pending_interrupts = 0;
27103424 10726 s->exception_index = POWERPC_EXCP_NONE;
a1389542 10727 env->error_code = 0;
40177438 10728 ppc_irq_reset(cpu);
2b15811c 10729
cbc65a8f
RH
10730 /* tininess for underflow is detected before rounding */
10731 set_float_detect_tininess(float_tininess_before_rounding,
10732 &env->fp_status);
10733
d197fdbc
AK
10734 for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
10735 ppc_spr_t *spr = &env->spr_cb[i];
10736
10737 if (!spr->name) {
10738 continue;
10739 }
10740 env->spr[i] = spr->default_value;
10741 }
1d0cb67d
AF
10742}
10743
7826c2b2
GK
10744#ifndef CONFIG_USER_ONLY
10745static bool ppc_cpu_is_big_endian(CPUState *cs)
10746{
10747 PowerPCCPU *cpu = POWERPC_CPU(cs);
10748 CPUPPCState *env = &cpu->env;
10749
10750 cpu_synchronize_state(cs);
10751
10752 return !msr_le;
10753}
03ef074c
NP
10754
10755static void ppc_cpu_exec_enter(CPUState *cs)
10756{
10757 PowerPCCPU *cpu = POWERPC_CPU(cs);
10758
10759 if (cpu->vhyp) {
10760 PPCVirtualHypervisorClass *vhc =
10761 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
10762 vhc->cpu_exec_enter(cpu->vhyp, cpu);
10763 }
10764}
10765
10766static void ppc_cpu_exec_exit(CPUState *cs)
10767{
10768 PowerPCCPU *cpu = POWERPC_CPU(cs);
10769
10770 if (cpu->vhyp) {
10771 PPCVirtualHypervisorClass *vhc =
10772 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
10773 vhc->cpu_exec_exit(cpu->vhyp, cpu);
10774 }
10775}
7826c2b2
GK
10776#endif
10777
e850da55 10778static void ppc_cpu_instance_init(Object *obj)
6cca7ad6
AF
10779{
10780 PowerPCCPU *cpu = POWERPC_CPU(obj);
2985b86b 10781 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
6cca7ad6
AF
10782 CPUPPCState *env = &cpu->env;
10783
7506ed90 10784 cpu_set_cpustate_pointers(cpu);
7cca3e46 10785 cpu->vcpu_id = UNASSIGNED_CPU_INDEX;
2985b86b 10786
cfe34f44
AF
10787 env->msr_mask = pcc->msr_mask;
10788 env->mmu_model = pcc->mmu_model;
10789 env->excp_model = pcc->excp_model;
10790 env->bus_model = pcc->bus_model;
10791 env->insns_flags = pcc->insns_flags;
10792 env->insns_flags2 = pcc->insns_flags2;
10793 env->flags = pcc->flags;
10794 env->bfd_mach = pcc->bfd_mach;
10795 env->check_pow = pcc->check_pow;
2985b86b 10796
1d28b5f6
DG
10797 /*
10798 * Mark HV mode as supported if the CPU has an MSR_HV bit in the
10799 * msr_mask. The mask can later be cleared by PAPR mode but the hv
10800 * mode support will remain, thus enforcing that we cannot use
10801 * priv. instructions in guest in PAPR mode. For 970 we currently
10802 * simply don't set HV in msr_mask thus simulating an "Apple mode"
10803 * 970. If we ever want to support 970 HV mode, we'll have to add
10804 * a processor attribute of some sort.
932ccbdd
BH
10805 */
10806#if !defined(CONFIG_USER_ONLY)
10807 env->has_hv_mode = !!(env->msr_mask & MSR_HVB);
10808#endif
10809
a059471d
DG
10810 ppc_hash64_init(cpu);
10811}
10812
10813static void ppc_cpu_instance_finalize(Object *obj)
10814{
10815 PowerPCCPU *cpu = POWERPC_CPU(obj);
10816
10817 ppc_hash64_finalize(cpu);
6cca7ad6
AF
10818}
10819
03ae4133
AK
10820static bool ppc_pvr_match_default(PowerPCCPUClass *pcc, uint32_t pvr)
10821{
10822 return pcc->pvr == pvr;
10823}
10824
b3820e6c
DH
10825static gchar *ppc_gdb_arch_name(CPUState *cs)
10826{
10827#if defined(TARGET_PPC64)
10828 return g_strdup("powerpc:common64");
10829#else
10830 return g_strdup("powerpc:common");
10831#endif
10832}
10833
0eea8cdd
RH
10834static void ppc_disas_set_info(CPUState *cs, disassemble_info *info)
10835{
10836 PowerPCCPU *cpu = POWERPC_CPU(cs);
10837 CPUPPCState *env = &cpu->env;
10838
10839 if ((env->hflags >> MSR_LE) & 1) {
10840 info->endian = BFD_ENDIAN_LITTLE;
10841 }
10842 info->mach = env->bfd_mach;
10843 if (!env->bfd_mach) {
10844#ifdef TARGET_PPC64
10845 info->mach = bfd_mach_ppc64;
10846#else
10847 info->mach = bfd_mach_ppc;
10848#endif
10849 }
10850 info->disassembler_options = (char *)"any";
10851 info->print_insn = print_insn_ppc;
ac226899
RH
10852
10853 info->cap_arch = CS_ARCH_PPC;
10854#ifdef TARGET_PPC64
10855 info->cap_mode = CS_MODE_64;
10856#endif
0eea8cdd
RH
10857}
10858
146c11f1
DG
10859static Property ppc_cpu_properties[] = {
10860 DEFINE_PROP_BOOL("pre-2.8-migration", PowerPCCPU, pre_2_8_migration, false),
d5fc133e
DG
10861 DEFINE_PROP_BOOL("pre-2.10-migration", PowerPCCPU, pre_2_10_migration,
10862 false),
d8c0c7af 10863 DEFINE_PROP_BOOL("pre-3.0-migration", PowerPCCPU, pre_3_0_migration,
67d7d66f 10864 false),
146c11f1
DG
10865 DEFINE_PROP_END_OF_LIST(),
10866};
10867
1d0cb67d
AF
10868static void ppc_cpu_class_init(ObjectClass *oc, void *data)
10869{
10870 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
10871 CPUClass *cc = CPU_CLASS(oc);
4776ce60
AF
10872 DeviceClass *dc = DEVICE_CLASS(oc);
10873
e850da55 10874 device_class_set_parent_realize(dc, ppc_cpu_realize,
bf853881 10875 &pcc->parent_realize);
e850da55 10876 device_class_set_parent_unrealize(dc, ppc_cpu_unrealize,
bf853881 10877 &pcc->parent_unrealize);
03ae4133 10878 pcc->pvr_match = ppc_pvr_match_default;
382d2db6 10879 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_always;
4f67d30b 10880 device_class_set_props(dc, ppc_cpu_properties);
1d0cb67d 10881
781c67ca 10882 device_class_set_parent_reset(dc, ppc_cpu_reset, &pcc->parent_reset);
2b8c2754
AF
10883
10884 cc->class_by_name = ppc_cpu_class_by_name;
b8e99967
IM
10885 pcc->parent_parse_features = cc->parse_features;
10886 cc->parse_features = ppc_cpu_parse_featurestr;
8c2e1b00 10887 cc->has_work = ppc_cpu_has_work;
97a8ea5a 10888 cc->do_interrupt = ppc_cpu_do_interrupt;
458dd766 10889 cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt;
878096ee
AF
10890 cc->dump_state = ppc_cpu_dump_state;
10891 cc->dump_statistics = ppc_cpu_dump_statistics;
f45748f1 10892 cc->set_pc = ppc_cpu_set_pc;
5b50e790
AF
10893 cc->gdb_read_register = ppc_cpu_gdb_read_register;
10894 cc->gdb_write_register = ppc_cpu_gdb_write_register;
0f3110fa 10895 cc->do_unaligned_access = ppc_cpu_do_unaligned_access;
351bc97e 10896#ifndef CONFIG_USER_ONLY
00b941e5 10897 cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
a90db158 10898 cc->vmsd = &vmstate_ppc_cpu;
00b941e5 10899#endif
356bb70e
MN
10900#if defined(CONFIG_SOFTMMU)
10901 cc->write_elf64_note = ppc64_cpu_write_elf64_note;
10902 cc->write_elf32_note = ppc32_cpu_write_elf32_note;
10903#endif
a0e372f0
AF
10904
10905 cc->gdb_num_core_regs = 71;
707c7c2e
FR
10906#ifndef CONFIG_USER_ONLY
10907 cc->gdb_get_dynamic_xml = ppc_gdb_get_dynamic_xml;
10908#endif
b3cad3ab
AG
10909#ifdef USE_APPLE_GDB
10910 cc->gdb_read_register = ppc_cpu_gdb_read_register_apple;
10911 cc->gdb_write_register = ppc_cpu_gdb_write_register_apple;
10912 cc->gdb_num_core_regs = 71 + 32;
10913#endif
10914
b3820e6c 10915 cc->gdb_arch_name = ppc_gdb_arch_name;
5b24c641
AF
10916#if defined(TARGET_PPC64)
10917 cc->gdb_core_xml_file = "power64-core.xml";
10918#else
10919 cc->gdb_core_xml_file = "power-core.xml";
10920#endif
7826c2b2
GK
10921#ifndef CONFIG_USER_ONLY
10922 cc->virtio_is_big_endian = ppc_cpu_is_big_endian;
10923#endif
74d7fc7f 10924#ifdef CONFIG_TCG
55c3ceef 10925 cc->tcg_initialize = ppc_translate_init;
351bc97e 10926 cc->tlb_fill = ppc_cpu_tlb_fill;
74d7fc7f 10927#endif
03ef074c
NP
10928#ifndef CONFIG_USER_ONLY
10929 cc->cpu_exec_enter = ppc_cpu_exec_enter;
10930 cc->cpu_exec_exit = ppc_cpu_exec_exit;
10931#endif
10932
0eea8cdd 10933 cc->disas_set_info = ppc_disas_set_info;
1d28b5f6 10934
3bbf37f2 10935 dc->fw_name = "PowerPC,UNKNOWN";
1d0cb67d
AF
10936}
10937
10938static const TypeInfo ppc_cpu_type_info = {
10939 .name = TYPE_POWERPC_CPU,
10940 .parent = TYPE_CPU,
10941 .instance_size = sizeof(PowerPCCPU),
e850da55 10942 .instance_init = ppc_cpu_instance_init,
a059471d 10943 .instance_finalize = ppc_cpu_instance_finalize,
2985b86b 10944 .abstract = true,
1d0cb67d
AF
10945 .class_size = sizeof(PowerPCCPUClass),
10946 .class_init = ppc_cpu_class_init,
10947};
10948
1d1be34d
DG
10949static const TypeInfo ppc_vhyp_type_info = {
10950 .name = TYPE_PPC_VIRTUAL_HYPERVISOR,
10951 .parent = TYPE_INTERFACE,
10952 .class_size = sizeof(PPCVirtualHypervisorClass),
10953};
10954
1d0cb67d
AF
10955static void ppc_cpu_register_types(void)
10956{
10957 type_register_static(&ppc_cpu_type_info);
1d1be34d 10958 type_register_static(&ppc_vhyp_type_info);
1d0cb67d
AF
10959}
10960
10961type_init(ppc_cpu_register_types)