]> git.proxmox.com Git - mirror_qemu.git/blame - target/ppc/translate_init.inc.c
spapr/xive: Simplify kvmppc_xive_disconnect()
[mirror_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;
3c89b8d6 3385 env->excp_vectors[POWERPC_EXCP_SYSCALL_VECTORED] = 0x00000000;
d8ce5fd6
BH
3386#endif
3387}
3388
7d37b274
CLG
3389static void init_excp_POWER10(CPUPPCState *env)
3390{
3391 init_excp_POWER9(env);
3392}
3393
e1833e1f
JM
3394#endif
3395
2f462816
JM
3396/*****************************************************************************/
3397/* Power management enable checks */
c364946d 3398static int check_pow_none(CPUPPCState *env)
2f462816
JM
3399{
3400 return 0;
3401}
3402
c364946d 3403static int check_pow_nocheck(CPUPPCState *env)
2f462816
JM
3404{
3405 return 1;
3406}
3407
c364946d 3408static int check_pow_hid0(CPUPPCState *env)
2f462816 3409{
1d28b5f6 3410 if (env->spr[SPR_HID0] & 0x00E00000) {
2f462816 3411 return 1;
1d28b5f6 3412 }
2f462816
JM
3413
3414 return 0;
3415}
3416
c364946d 3417static int check_pow_hid0_74xx(CPUPPCState *env)
4e777442 3418{
1d28b5f6 3419 if (env->spr[SPR_HID0] & 0x00600000) {
4e777442 3420 return 1;
1d28b5f6 3421 }
4e777442
JM
3422
3423 return 0;
3424}
3425
382d2db6
GK
3426static bool ppc_cpu_interrupts_big_endian_always(PowerPCCPU *cpu)
3427{
3428 return true;
3429}
3430
3431#ifdef TARGET_PPC64
3432static bool ppc_cpu_interrupts_big_endian_lpcr(PowerPCCPU *cpu)
3433{
3434 return !(cpu->env.spr[SPR_LPCR] & LPCR_ILE);
3435}
3436#endif
3437
a750fc0b
JM
3438/*****************************************************************************/
3439/* PowerPC implementations definitions */
76a66253 3440
7856e3a4
AF
3441#define POWERPC_FAMILY(_name) \
3442 static void \
3443 glue(glue(ppc_, _name), _cpu_family_class_init)(ObjectClass *, void *); \
3444 \
3445 static const TypeInfo \
3446 glue(glue(ppc_, _name), _cpu_family_type_info) = { \
3447 .name = stringify(_name) "-family-" TYPE_POWERPC_CPU, \
3448 .parent = TYPE_POWERPC_CPU, \
3449 .abstract = true, \
3450 .class_init = glue(glue(ppc_, _name), _cpu_family_class_init), \
3451 }; \
3452 \
3453 static void glue(glue(ppc_, _name), _cpu_family_register_types)(void) \
3454 { \
3455 type_register_static( \
3456 &glue(glue(ppc_, _name), _cpu_family_type_info)); \
3457 } \
3458 \
3459 type_init(glue(glue(ppc_, _name), _cpu_family_register_types)) \
3460 \
3461 static void glue(glue(ppc_, _name), _cpu_family_class_init)
3462
c364946d 3463static void init_proc_401(CPUPPCState *env)
a750fc0b
JM
3464{
3465 gen_spr_40x(env);
3466 gen_spr_401_403(env);
3467 gen_spr_401(env);
e1833e1f 3468 init_excp_4xx_real(env);
d63001d1
JM
3469 env->dcache_line_size = 32;
3470 env->icache_line_size = 32;
4e290a0b 3471 /* Allocate hardware IRQ controller */
db70b311 3472 ppc40x_irq_init(env_archcpu(env));
ddd1055b
FC
3473
3474 SET_FIT_PERIOD(12, 16, 20, 24);
3475 SET_WDT_PERIOD(16, 20, 24, 28);
a750fc0b 3476}
76a66253 3477
7856e3a4
AF
3478POWERPC_FAMILY(401)(ObjectClass *oc, void *data)
3479{
ca5dff0a 3480 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3481 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3482
ca5dff0a 3483 dc->desc = "PowerPC 401";
7856e3a4
AF
3484 pcc->init_proc = init_proc_401;
3485 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
3486 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3487 PPC_WRTEE | PPC_DCR |
3488 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3489 PPC_CACHE_DCBZ |
3490 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3491 PPC_4xx_COMMON | PPC_40x_EXCP;
9df5a466
TM
3492 pcc->msr_mask = (1ull << MSR_KEY) |
3493 (1ull << MSR_POW) |
3494 (1ull << MSR_CE) |
3495 (1ull << MSR_ILE) |
3496 (1ull << MSR_EE) |
3497 (1ull << MSR_PR) |
3498 (1ull << MSR_ME) |
3499 (1ull << MSR_DE) |
3500 (1ull << MSR_LE);
ba9fd9f1
AF
3501 pcc->mmu_model = POWERPC_MMU_REAL;
3502 pcc->excp_model = POWERPC_EXCP_40x;
3503 pcc->bus_model = PPC_FLAGS_INPUT_401;
3504 pcc->bfd_mach = bfd_mach_ppc_403;
3505 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3506 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
3507}
3508
c364946d 3509static void init_proc_401x2(CPUPPCState *env)
a750fc0b
JM
3510{
3511 gen_spr_40x(env);
3512 gen_spr_401_403(env);
3513 gen_spr_401x2(env);
3514 gen_spr_compress(env);
a750fc0b 3515 /* Memory management */
f2e63a42 3516#if !defined(CONFIG_USER_ONLY)
a750fc0b
JM
3517 env->nb_tlb = 64;
3518 env->nb_ways = 1;
3519 env->id_tlbs = 0;
1c53accc 3520 env->tlb_type = TLB_EMB;
f2e63a42 3521#endif
e1833e1f 3522 init_excp_4xx_softmmu(env);
d63001d1
JM
3523 env->dcache_line_size = 32;
3524 env->icache_line_size = 32;
4e290a0b 3525 /* Allocate hardware IRQ controller */
db70b311 3526 ppc40x_irq_init(env_archcpu(env));
ddd1055b
FC
3527
3528 SET_FIT_PERIOD(12, 16, 20, 24);
3529 SET_WDT_PERIOD(16, 20, 24, 28);
76a66253
JM
3530}
3531
7856e3a4
AF
3532POWERPC_FAMILY(401x2)(ObjectClass *oc, void *data)
3533{
ca5dff0a 3534 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3535 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3536
ca5dff0a 3537 dc->desc = "PowerPC 401x2";
7856e3a4
AF
3538 pcc->init_proc = init_proc_401x2;
3539 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
3540 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
3541 PPC_DCR | PPC_WRTEE |
3542 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3543 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3544 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3545 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3546 PPC_4xx_COMMON | PPC_40x_EXCP;
9df5a466
TM
3547 pcc->msr_mask = (1ull << 20) |
3548 (1ull << MSR_KEY) |
3549 (1ull << MSR_POW) |
3550 (1ull << MSR_CE) |
3551 (1ull << MSR_ILE) |
3552 (1ull << MSR_EE) |
3553 (1ull << MSR_PR) |
3554 (1ull << MSR_ME) |
3555 (1ull << MSR_DE) |
3556 (1ull << MSR_IR) |
3557 (1ull << MSR_DR) |
3558 (1ull << MSR_LE);
ba9fd9f1
AF
3559 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3560 pcc->excp_model = POWERPC_EXCP_40x;
3561 pcc->bus_model = PPC_FLAGS_INPUT_401;
3562 pcc->bfd_mach = bfd_mach_ppc_403;
3563 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3564 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
3565}
3566
c364946d 3567static void init_proc_401x3(CPUPPCState *env)
76a66253 3568{
4e290a0b
JM
3569 gen_spr_40x(env);
3570 gen_spr_401_403(env);
3571 gen_spr_401(env);
3572 gen_spr_401x2(env);
3573 gen_spr_compress(env);
e1833e1f 3574 init_excp_4xx_softmmu(env);
d63001d1
JM
3575 env->dcache_line_size = 32;
3576 env->icache_line_size = 32;
4e290a0b 3577 /* Allocate hardware IRQ controller */
db70b311 3578 ppc40x_irq_init(env_archcpu(env));
ddd1055b
FC
3579
3580 SET_FIT_PERIOD(12, 16, 20, 24);
3581 SET_WDT_PERIOD(16, 20, 24, 28);
3fc6c082 3582}
a750fc0b 3583
7856e3a4
AF
3584POWERPC_FAMILY(401x3)(ObjectClass *oc, void *data)
3585{
ca5dff0a 3586 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3587 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3588
ca5dff0a 3589 dc->desc = "PowerPC 401x3";
7856e3a4
AF
3590 pcc->init_proc = init_proc_401x3;
3591 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
3592 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
3593 PPC_DCR | PPC_WRTEE |
3594 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3595 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3596 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3597 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3598 PPC_4xx_COMMON | PPC_40x_EXCP;
9df5a466
TM
3599 pcc->msr_mask = (1ull << 20) |
3600 (1ull << MSR_KEY) |
3601 (1ull << MSR_POW) |
3602 (1ull << MSR_CE) |
3603 (1ull << MSR_ILE) |
3604 (1ull << MSR_EE) |
3605 (1ull << MSR_PR) |
3606 (1ull << MSR_ME) |
3607 (1ull << MSR_DWE) |
3608 (1ull << MSR_DE) |
3609 (1ull << MSR_IR) |
3610 (1ull << MSR_DR) |
3611 (1ull << MSR_LE);
ba9fd9f1
AF
3612 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3613 pcc->excp_model = POWERPC_EXCP_40x;
3614 pcc->bus_model = PPC_FLAGS_INPUT_401;
3615 pcc->bfd_mach = bfd_mach_ppc_403;
3616 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3617 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
3618}
3619
c364946d 3620static void init_proc_IOP480(CPUPPCState *env)
3fc6c082 3621{
a750fc0b
JM
3622 gen_spr_40x(env);
3623 gen_spr_401_403(env);
3624 gen_spr_401x2(env);
3625 gen_spr_compress(env);
a750fc0b 3626 /* Memory management */
f2e63a42 3627#if !defined(CONFIG_USER_ONLY)
a750fc0b
JM
3628 env->nb_tlb = 64;
3629 env->nb_ways = 1;
3630 env->id_tlbs = 0;
1c53accc 3631 env->tlb_type = TLB_EMB;
f2e63a42 3632#endif
e1833e1f 3633 init_excp_4xx_softmmu(env);
d63001d1
JM
3634 env->dcache_line_size = 32;
3635 env->icache_line_size = 32;
4e290a0b 3636 /* Allocate hardware IRQ controller */
db70b311 3637 ppc40x_irq_init(env_archcpu(env));
ddd1055b
FC
3638
3639 SET_FIT_PERIOD(8, 12, 16, 20);
3640 SET_WDT_PERIOD(16, 20, 24, 28);
3fc6c082
FB
3641}
3642
7856e3a4
AF
3643POWERPC_FAMILY(IOP480)(ObjectClass *oc, void *data)
3644{
ca5dff0a 3645 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3646 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3647
ca5dff0a 3648 dc->desc = "IOP480";
7856e3a4
AF
3649 pcc->init_proc = init_proc_IOP480;
3650 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
3651 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3652 PPC_DCR | PPC_WRTEE |
3653 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3654 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3655 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3656 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3657 PPC_4xx_COMMON | PPC_40x_EXCP;
9df5a466
TM
3658 pcc->msr_mask = (1ull << 20) |
3659 (1ull << MSR_KEY) |
3660 (1ull << MSR_POW) |
3661 (1ull << MSR_CE) |
3662 (1ull << MSR_ILE) |
3663 (1ull << MSR_EE) |
3664 (1ull << MSR_PR) |
3665 (1ull << MSR_ME) |
3666 (1ull << MSR_DE) |
3667 (1ull << MSR_IR) |
3668 (1ull << MSR_DR) |
3669 (1ull << MSR_LE);
ba9fd9f1
AF
3670 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3671 pcc->excp_model = POWERPC_EXCP_40x;
3672 pcc->bus_model = PPC_FLAGS_INPUT_401;
3673 pcc->bfd_mach = bfd_mach_ppc_403;
3674 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3675 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
3676}
3677
c364946d 3678static void init_proc_403(CPUPPCState *env)
3fc6c082 3679{
a750fc0b
JM
3680 gen_spr_40x(env);
3681 gen_spr_401_403(env);
3682 gen_spr_403(env);
3683 gen_spr_403_real(env);
e1833e1f 3684 init_excp_4xx_real(env);
d63001d1
JM
3685 env->dcache_line_size = 32;
3686 env->icache_line_size = 32;
4e290a0b 3687 /* Allocate hardware IRQ controller */
db70b311 3688 ppc40x_irq_init(env_archcpu(env));
ddd1055b
FC
3689
3690 SET_FIT_PERIOD(8, 12, 16, 20);
3691 SET_WDT_PERIOD(16, 20, 24, 28);
3fc6c082
FB
3692}
3693
7856e3a4
AF
3694POWERPC_FAMILY(403)(ObjectClass *oc, void *data)
3695{
ca5dff0a 3696 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3697 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3698
ca5dff0a 3699 dc->desc = "PowerPC 403";
7856e3a4
AF
3700 pcc->init_proc = init_proc_403;
3701 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
3702 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3703 PPC_DCR | PPC_WRTEE |
3704 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3705 PPC_CACHE_DCBZ |
3706 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3707 PPC_4xx_COMMON | PPC_40x_EXCP;
9df5a466
TM
3708 pcc->msr_mask = (1ull << MSR_POW) |
3709 (1ull << MSR_CE) |
3710 (1ull << MSR_ILE) |
3711 (1ull << MSR_EE) |
3712 (1ull << MSR_PR) |
3713 (1ull << MSR_ME) |
3714 (1ull << MSR_PE) |
3715 (1ull << MSR_PX) |
3716 (1ull << MSR_LE);
ba9fd9f1
AF
3717 pcc->mmu_model = POWERPC_MMU_REAL;
3718 pcc->excp_model = POWERPC_EXCP_40x;
3719 pcc->bus_model = PPC_FLAGS_INPUT_401;
3720 pcc->bfd_mach = bfd_mach_ppc_403;
3721 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_PX |
3722 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
3723}
3724
c364946d 3725static void init_proc_403GCX(CPUPPCState *env)
3fc6c082 3726{
a750fc0b
JM
3727 gen_spr_40x(env);
3728 gen_spr_401_403(env);
3729 gen_spr_403(env);
3730 gen_spr_403_real(env);
3731 gen_spr_403_mmu(env);
3732 /* Bus access control */
5cbdb3a3 3733 /* not emulated, as QEMU never does speculative access */
a750fc0b
JM
3734 spr_register(env, SPR_40x_SGR, "SGR",
3735 SPR_NOACCESS, SPR_NOACCESS,
3736 &spr_read_generic, &spr_write_generic,
3737 0xFFFFFFFF);
5cbdb3a3 3738 /* not emulated, as QEMU do not emulate caches */
a750fc0b
JM
3739 spr_register(env, SPR_40x_DCWR, "DCWR",
3740 SPR_NOACCESS, SPR_NOACCESS,
3741 &spr_read_generic, &spr_write_generic,
3742 0x00000000);
3743 /* Memory management */
f2e63a42 3744#if !defined(CONFIG_USER_ONLY)
a750fc0b
JM
3745 env->nb_tlb = 64;
3746 env->nb_ways = 1;
3747 env->id_tlbs = 0;
1c53accc 3748 env->tlb_type = TLB_EMB;
f2e63a42 3749#endif
80d11f44
JM
3750 init_excp_4xx_softmmu(env);
3751 env->dcache_line_size = 32;
3752 env->icache_line_size = 32;
3753 /* Allocate hardware IRQ controller */
db70b311 3754 ppc40x_irq_init(env_archcpu(env));
ddd1055b
FC
3755
3756 SET_FIT_PERIOD(8, 12, 16, 20);
3757 SET_WDT_PERIOD(16, 20, 24, 28);
80d11f44
JM
3758}
3759
7856e3a4
AF
3760POWERPC_FAMILY(403GCX)(ObjectClass *oc, void *data)
3761{
ca5dff0a 3762 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3763 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3764
ca5dff0a 3765 dc->desc = "PowerPC 403 GCX";
7856e3a4
AF
3766 pcc->init_proc = init_proc_403GCX;
3767 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
3768 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3769 PPC_DCR | PPC_WRTEE |
3770 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3771 PPC_CACHE_DCBZ |
3772 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3773 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3774 PPC_4xx_COMMON | PPC_40x_EXCP;
9df5a466
TM
3775 pcc->msr_mask = (1ull << MSR_POW) |
3776 (1ull << MSR_CE) |
3777 (1ull << MSR_ILE) |
3778 (1ull << MSR_EE) |
3779 (1ull << MSR_PR) |
3780 (1ull << MSR_ME) |
3781 (1ull << MSR_PE) |
3782 (1ull << MSR_PX) |
3783 (1ull << MSR_LE);
ba9fd9f1
AF
3784 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3785 pcc->excp_model = POWERPC_EXCP_40x;
3786 pcc->bus_model = PPC_FLAGS_INPUT_401;
3787 pcc->bfd_mach = bfd_mach_ppc_403;
3788 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_PX |
3789 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
3790}
3791
c364946d 3792static void init_proc_405(CPUPPCState *env)
80d11f44
JM
3793{
3794 /* Time base */
3795 gen_tbl(env);
3796 gen_spr_40x(env);
3797 gen_spr_405(env);
3798 /* Bus access control */
5cbdb3a3 3799 /* not emulated, as QEMU never does speculative access */
80d11f44
JM
3800 spr_register(env, SPR_40x_SGR, "SGR",
3801 SPR_NOACCESS, SPR_NOACCESS,
3802 &spr_read_generic, &spr_write_generic,
3803 0xFFFFFFFF);
5cbdb3a3 3804 /* not emulated, as QEMU do not emulate caches */
80d11f44
JM
3805 spr_register(env, SPR_40x_DCWR, "DCWR",
3806 SPR_NOACCESS, SPR_NOACCESS,
3807 &spr_read_generic, &spr_write_generic,
3808 0x00000000);
3809 /* Memory management */
3810#if !defined(CONFIG_USER_ONLY)
3811 env->nb_tlb = 64;
3812 env->nb_ways = 1;
3813 env->id_tlbs = 0;
1c53accc 3814 env->tlb_type = TLB_EMB;
80d11f44
JM
3815#endif
3816 init_excp_4xx_softmmu(env);
3817 env->dcache_line_size = 32;
3818 env->icache_line_size = 32;
3819 /* Allocate hardware IRQ controller */
db70b311 3820 ppc40x_irq_init(env_archcpu(env));
ddd1055b
FC
3821
3822 SET_FIT_PERIOD(8, 12, 16, 20);
3823 SET_WDT_PERIOD(16, 20, 24, 28);
80d11f44
JM
3824}
3825
7856e3a4
AF
3826POWERPC_FAMILY(405)(ObjectClass *oc, void *data)
3827{
ca5dff0a 3828 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3829 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3830
ca5dff0a 3831 dc->desc = "PowerPC 405";
7856e3a4
AF
3832 pcc->init_proc = init_proc_405;
3833 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
3834 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
3835 PPC_DCR | PPC_WRTEE |
3836 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3837 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3838 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3839 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3840 PPC_4xx_COMMON | PPC_405_MAC | PPC_40x_EXCP;
9df5a466
TM
3841 pcc->msr_mask = (1ull << MSR_POW) |
3842 (1ull << MSR_CE) |
3843 (1ull << MSR_EE) |
3844 (1ull << MSR_PR) |
3845 (1ull << MSR_FP) |
3846 (1ull << MSR_DWE) |
3847 (1ull << MSR_DE) |
3848 (1ull << MSR_IR) |
3849 (1ull << MSR_DR);
ba9fd9f1
AF
3850 pcc->mmu_model = POWERPC_MMU_SOFT_4xx;
3851 pcc->excp_model = POWERPC_EXCP_40x;
3852 pcc->bus_model = PPC_FLAGS_INPUT_405;
3853 pcc->bfd_mach = bfd_mach_ppc_403;
3854 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
3855 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
3856}
3857
c364946d 3858static void init_proc_440EP(CPUPPCState *env)
80d11f44
JM
3859{
3860 /* Time base */
3861 gen_tbl(env);
3862 gen_spr_BookE(env, 0x000000000000FFFFULL);
3863 gen_spr_440(env);
3864 gen_spr_usprgh(env);
3865 /* Processor identification */
3866 spr_register(env, SPR_BOOKE_PIR, "PIR",
3867 SPR_NOACCESS, SPR_NOACCESS,
3868 &spr_read_generic, &spr_write_pir,
3869 0x00000000);
3870 /* XXX : not implemented */
3871 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
3872 SPR_NOACCESS, SPR_NOACCESS,
3873 &spr_read_generic, &spr_write_generic,
3874 0x00000000);
3875 /* XXX : not implemented */
3876 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
3877 SPR_NOACCESS, SPR_NOACCESS,
3878 &spr_read_generic, &spr_write_generic,
3879 0x00000000);
3880 /* XXX : not implemented */
3881 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
3882 SPR_NOACCESS, SPR_NOACCESS,
3883 &spr_read_generic, &spr_write_generic,
3884 0x00000000);
3885 /* XXX : not implemented */
3886 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
3887 SPR_NOACCESS, SPR_NOACCESS,
3888 &spr_read_generic, &spr_write_generic,
3889 0x00000000);
3890 /* XXX : not implemented */
3891 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
3892 SPR_NOACCESS, SPR_NOACCESS,
3893 &spr_read_generic, &spr_write_generic,
3894 0x00000000);
3895 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
3896 SPR_NOACCESS, SPR_NOACCESS,
3897 &spr_read_generic, &spr_write_generic,
3898 0x00000000);
3899 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
3900 SPR_NOACCESS, SPR_NOACCESS,
3901 &spr_read_generic, &spr_write_generic,
3902 0x00000000);
3903 /* XXX : not implemented */
3904 spr_register(env, SPR_440_CCR1, "CCR1",
3905 SPR_NOACCESS, SPR_NOACCESS,
3906 &spr_read_generic, &spr_write_generic,
3907 0x00000000);
3908 /* Memory management */
3909#if !defined(CONFIG_USER_ONLY)
3910 env->nb_tlb = 64;
3911 env->nb_ways = 1;
3912 env->id_tlbs = 0;
1c53accc 3913 env->tlb_type = TLB_EMB;
80d11f44
JM
3914#endif
3915 init_excp_BookE(env);
3916 env->dcache_line_size = 32;
3917 env->icache_line_size = 32;
db70b311 3918 ppc40x_irq_init(env_archcpu(env));
ddd1055b
FC
3919
3920 SET_FIT_PERIOD(12, 16, 20, 24);
3921 SET_WDT_PERIOD(20, 24, 28, 32);
80d11f44
JM
3922}
3923
7856e3a4
AF
3924POWERPC_FAMILY(440EP)(ObjectClass *oc, void *data)
3925{
ca5dff0a 3926 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3927 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3928
ca5dff0a 3929 dc->desc = "PowerPC 440 EP";
7856e3a4
AF
3930 pcc->init_proc = init_proc_440EP;
3931 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
3932 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3933 PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL |
3934 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
3935 PPC_FLOAT_STFIWX |
3936 PPC_DCR | PPC_WRTEE | PPC_RFMCI |
3937 PPC_CACHE | PPC_CACHE_ICBI |
3938 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3939 PPC_MEM_TLBSYNC | PPC_MFTB |
3940 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
3941 PPC_440_SPEC;
81bb29ac
BZ
3942 pcc->msr_mask = (1ull << MSR_POW) |
3943 (1ull << MSR_CE) |
3944 (1ull << MSR_EE) |
3945 (1ull << MSR_PR) |
3946 (1ull << MSR_FP) |
3947 (1ull << MSR_ME) |
3948 (1ull << MSR_FE0) |
3949 (1ull << MSR_DWE) |
3950 (1ull << MSR_DE) |
3951 (1ull << MSR_FE1) |
3952 (1ull << MSR_IR) |
3953 (1ull << MSR_DR);
3954 pcc->mmu_model = POWERPC_MMU_BOOKE;
3955 pcc->excp_model = POWERPC_EXCP_BOOKE;
3956 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
3957 pcc->bfd_mach = bfd_mach_ppc_403;
3958 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
3959 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
3960}
3961
3962POWERPC_FAMILY(460EX)(ObjectClass *oc, void *data)
3963{
3964 DeviceClass *dc = DEVICE_CLASS(oc);
3965 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3966
3967 dc->desc = "PowerPC 460 EX";
3968 pcc->init_proc = init_proc_440EP;
3969 pcc->check_pow = check_pow_nocheck;
3970 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3971 PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL |
3972 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
3973 PPC_FLOAT_STFIWX |
3974 PPC_DCR | PPC_DCRX | PPC_WRTEE | PPC_RFMCI |
3975 PPC_CACHE | PPC_CACHE_ICBI |
3976 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3977 PPC_MEM_TLBSYNC | PPC_MFTB |
3978 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
3979 PPC_440_SPEC;
9df5a466
TM
3980 pcc->msr_mask = (1ull << MSR_POW) |
3981 (1ull << MSR_CE) |
3982 (1ull << MSR_EE) |
3983 (1ull << MSR_PR) |
3984 (1ull << MSR_FP) |
3985 (1ull << MSR_ME) |
3986 (1ull << MSR_FE0) |
3987 (1ull << MSR_DWE) |
3988 (1ull << MSR_DE) |
3989 (1ull << MSR_FE1) |
3990 (1ull << MSR_IR) |
3991 (1ull << MSR_DR);
ba9fd9f1
AF
3992 pcc->mmu_model = POWERPC_MMU_BOOKE;
3993 pcc->excp_model = POWERPC_EXCP_BOOKE;
3994 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
3995 pcc->bfd_mach = bfd_mach_ppc_403;
3996 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
3997 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
3998}
3999
c364946d 4000static void init_proc_440GP(CPUPPCState *env)
80d11f44
JM
4001{
4002 /* Time base */
4003 gen_tbl(env);
4004 gen_spr_BookE(env, 0x000000000000FFFFULL);
4005 gen_spr_440(env);
4006 gen_spr_usprgh(env);
4007 /* Processor identification */
4008 spr_register(env, SPR_BOOKE_PIR, "PIR",
4009 SPR_NOACCESS, SPR_NOACCESS,
4010 &spr_read_generic, &spr_write_pir,
4011 0x00000000);
4012 /* XXX : not implemented */
4013 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4014 SPR_NOACCESS, SPR_NOACCESS,
4015 &spr_read_generic, &spr_write_generic,
4016 0x00000000);
4017 /* XXX : not implemented */
4018 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4019 SPR_NOACCESS, SPR_NOACCESS,
4020 &spr_read_generic, &spr_write_generic,
4021 0x00000000);
4022 /* XXX : not implemented */
4023 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
4024 SPR_NOACCESS, SPR_NOACCESS,
4025 &spr_read_generic, &spr_write_generic,
4026 0x00000000);
4027 /* XXX : not implemented */
4028 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
4029 SPR_NOACCESS, SPR_NOACCESS,
4030 &spr_read_generic, &spr_write_generic,
4031 0x00000000);
4032 /* Memory management */
4033#if !defined(CONFIG_USER_ONLY)
4034 env->nb_tlb = 64;
4035 env->nb_ways = 1;
4036 env->id_tlbs = 0;
1c53accc 4037 env->tlb_type = TLB_EMB;
80d11f44
JM
4038#endif
4039 init_excp_BookE(env);
4040 env->dcache_line_size = 32;
4041 env->icache_line_size = 32;
4042 /* XXX: TODO: allocate internal IRQ controller */
ddd1055b
FC
4043
4044 SET_FIT_PERIOD(12, 16, 20, 24);
4045 SET_WDT_PERIOD(20, 24, 28, 32);
80d11f44
JM
4046}
4047
7856e3a4
AF
4048POWERPC_FAMILY(440GP)(ObjectClass *oc, void *data)
4049{
ca5dff0a 4050 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4051 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4052
ca5dff0a 4053 dc->desc = "PowerPC 440 GP";
7856e3a4
AF
4054 pcc->init_proc = init_proc_440GP;
4055 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
4056 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4057 PPC_DCR | PPC_DCRX | PPC_WRTEE | PPC_MFAPIDI |
4058 PPC_CACHE | PPC_CACHE_ICBI |
4059 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4060 PPC_MEM_TLBSYNC | PPC_TLBIVA | PPC_MFTB |
4061 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4062 PPC_440_SPEC;
9df5a466
TM
4063 pcc->msr_mask = (1ull << MSR_POW) |
4064 (1ull << MSR_CE) |
4065 (1ull << MSR_EE) |
4066 (1ull << MSR_PR) |
4067 (1ull << MSR_FP) |
4068 (1ull << MSR_ME) |
4069 (1ull << MSR_FE0) |
4070 (1ull << MSR_DWE) |
4071 (1ull << MSR_DE) |
4072 (1ull << MSR_FE1) |
4073 (1ull << MSR_IR) |
4074 (1ull << MSR_DR);
ba9fd9f1
AF
4075 pcc->mmu_model = POWERPC_MMU_BOOKE;
4076 pcc->excp_model = POWERPC_EXCP_BOOKE;
4077 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4078 pcc->bfd_mach = bfd_mach_ppc_403;
4079 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4080 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4081}
4082
c364946d 4083static void init_proc_440x4(CPUPPCState *env)
80d11f44
JM
4084{
4085 /* Time base */
4086 gen_tbl(env);
4087 gen_spr_BookE(env, 0x000000000000FFFFULL);
4088 gen_spr_440(env);
4089 gen_spr_usprgh(env);
4090 /* Processor identification */
4091 spr_register(env, SPR_BOOKE_PIR, "PIR",
4092 SPR_NOACCESS, SPR_NOACCESS,
4093 &spr_read_generic, &spr_write_pir,
4094 0x00000000);
4095 /* XXX : not implemented */
4096 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4097 SPR_NOACCESS, SPR_NOACCESS,
4098 &spr_read_generic, &spr_write_generic,
4099 0x00000000);
4100 /* XXX : not implemented */
4101 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4102 SPR_NOACCESS, SPR_NOACCESS,
4103 &spr_read_generic, &spr_write_generic,
4104 0x00000000);
4105 /* XXX : not implemented */
4106 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
4107 SPR_NOACCESS, SPR_NOACCESS,
4108 &spr_read_generic, &spr_write_generic,
4109 0x00000000);
4110 /* XXX : not implemented */
4111 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
4112 SPR_NOACCESS, SPR_NOACCESS,
4113 &spr_read_generic, &spr_write_generic,
4114 0x00000000);
4115 /* Memory management */
4116#if !defined(CONFIG_USER_ONLY)
4117 env->nb_tlb = 64;
4118 env->nb_ways = 1;
4119 env->id_tlbs = 0;
1c53accc 4120 env->tlb_type = TLB_EMB;
80d11f44
JM
4121#endif
4122 init_excp_BookE(env);
d63001d1
JM
4123 env->dcache_line_size = 32;
4124 env->icache_line_size = 32;
80d11f44 4125 /* XXX: TODO: allocate internal IRQ controller */
ddd1055b
FC
4126
4127 SET_FIT_PERIOD(12, 16, 20, 24);
4128 SET_WDT_PERIOD(20, 24, 28, 32);
3fc6c082
FB
4129}
4130
7856e3a4
AF
4131POWERPC_FAMILY(440x4)(ObjectClass *oc, void *data)
4132{
ca5dff0a 4133 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4134 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4135
ca5dff0a 4136 dc->desc = "PowerPC 440x4";
7856e3a4
AF
4137 pcc->init_proc = init_proc_440x4;
4138 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
4139 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4140 PPC_DCR | PPC_WRTEE |
4141 PPC_CACHE | PPC_CACHE_ICBI |
4142 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4143 PPC_MEM_TLBSYNC | PPC_MFTB |
4144 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4145 PPC_440_SPEC;
9df5a466
TM
4146 pcc->msr_mask = (1ull << MSR_POW) |
4147 (1ull << MSR_CE) |
4148 (1ull << MSR_EE) |
4149 (1ull << MSR_PR) |
4150 (1ull << MSR_FP) |
4151 (1ull << MSR_ME) |
4152 (1ull << MSR_FE0) |
4153 (1ull << MSR_DWE) |
4154 (1ull << MSR_DE) |
4155 (1ull << MSR_FE1) |
4156 (1ull << MSR_IR) |
4157 (1ull << MSR_DR);
ba9fd9f1
AF
4158 pcc->mmu_model = POWERPC_MMU_BOOKE;
4159 pcc->excp_model = POWERPC_EXCP_BOOKE;
4160 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4161 pcc->bfd_mach = bfd_mach_ppc_403;
4162 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4163 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4164}
4165
c364946d 4166static void init_proc_440x5(CPUPPCState *env)
3fc6c082 4167{
a750fc0b
JM
4168 /* Time base */
4169 gen_tbl(env);
80d11f44
JM
4170 gen_spr_BookE(env, 0x000000000000FFFFULL);
4171 gen_spr_440(env);
4172 gen_spr_usprgh(env);
4173 /* Processor identification */
4174 spr_register(env, SPR_BOOKE_PIR, "PIR",
4175 SPR_NOACCESS, SPR_NOACCESS,
4176 &spr_read_generic, &spr_write_pir,
4177 0x00000000);
4178 /* XXX : not implemented */
4179 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
a750fc0b
JM
4180 SPR_NOACCESS, SPR_NOACCESS,
4181 &spr_read_generic, &spr_write_generic,
80d11f44
JM
4182 0x00000000);
4183 /* XXX : not implemented */
4184 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4185 SPR_NOACCESS, SPR_NOACCESS,
4186 &spr_read_generic, &spr_write_generic,
4187 0x00000000);
4188 /* XXX : not implemented */
4189 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
4190 SPR_NOACCESS, SPR_NOACCESS,
4191 &spr_read_generic, &spr_write_generic,
4192 0x00000000);
4193 /* XXX : not implemented */
4194 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
4195 SPR_NOACCESS, SPR_NOACCESS,
4196 &spr_read_generic, &spr_write_generic,
4197 0x00000000);
4198 /* XXX : not implemented */
4199 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
4200 SPR_NOACCESS, SPR_NOACCESS,
4201 &spr_read_generic, &spr_write_generic,
4202 0x00000000);
4203 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
4204 SPR_NOACCESS, SPR_NOACCESS,
4205 &spr_read_generic, &spr_write_generic,
4206 0x00000000);
4207 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
4208 SPR_NOACCESS, SPR_NOACCESS,
4209 &spr_read_generic, &spr_write_generic,
4210 0x00000000);
4211 /* XXX : not implemented */
4212 spr_register(env, SPR_440_CCR1, "CCR1",
a750fc0b
JM
4213 SPR_NOACCESS, SPR_NOACCESS,
4214 &spr_read_generic, &spr_write_generic,
4215 0x00000000);
4216 /* Memory management */
f2e63a42 4217#if !defined(CONFIG_USER_ONLY)
a750fc0b
JM
4218 env->nb_tlb = 64;
4219 env->nb_ways = 1;
4220 env->id_tlbs = 0;
1c53accc 4221 env->tlb_type = TLB_EMB;
f2e63a42 4222#endif
80d11f44 4223 init_excp_BookE(env);
d63001d1
JM
4224 env->dcache_line_size = 32;
4225 env->icache_line_size = 32;
db70b311 4226 ppc40x_irq_init(env_archcpu(env));
ddd1055b
FC
4227
4228 SET_FIT_PERIOD(12, 16, 20, 24);
4229 SET_WDT_PERIOD(20, 24, 28, 32);
3fc6c082
FB
4230}
4231
7856e3a4
AF
4232POWERPC_FAMILY(440x5)(ObjectClass *oc, void *data)
4233{
ca5dff0a 4234 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4235 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4236
ca5dff0a 4237 dc->desc = "PowerPC 440x5";
7856e3a4
AF
4238 pcc->init_proc = init_proc_440x5;
4239 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
4240 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4241 PPC_DCR | PPC_WRTEE | PPC_RFMCI |
4242 PPC_CACHE | PPC_CACHE_ICBI |
4243 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4244 PPC_MEM_TLBSYNC | PPC_MFTB |
4245 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4246 PPC_440_SPEC;
9df5a466
TM
4247 pcc->msr_mask = (1ull << MSR_POW) |
4248 (1ull << MSR_CE) |
4249 (1ull << MSR_EE) |
4250 (1ull << MSR_PR) |
4251 (1ull << MSR_FP) |
4252 (1ull << MSR_ME) |
4253 (1ull << MSR_FE0) |
4254 (1ull << MSR_DWE) |
4255 (1ull << MSR_DE) |
4256 (1ull << MSR_FE1) |
4257 (1ull << MSR_IR) |
4258 (1ull << MSR_DR);
ba9fd9f1
AF
4259 pcc->mmu_model = POWERPC_MMU_BOOKE;
4260 pcc->excp_model = POWERPC_EXCP_BOOKE;
4261 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4262 pcc->bfd_mach = bfd_mach_ppc_403;
4263 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4264 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4265}
4266
b8c867ed
PM
4267POWERPC_FAMILY(440x5wDFPU)(ObjectClass *oc, void *data)
4268{
4269 DeviceClass *dc = DEVICE_CLASS(oc);
4270 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4271
4272 dc->desc = "PowerPC 440x5 with double precision FPU";
4273 pcc->init_proc = init_proc_440x5;
4274 pcc->check_pow = check_pow_nocheck;
4275 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4276 PPC_FLOAT | PPC_FLOAT_FSQRT |
4277 PPC_FLOAT_STFIWX |
4278 PPC_DCR | PPC_WRTEE | PPC_RFMCI |
4279 PPC_CACHE | PPC_CACHE_ICBI |
4280 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4281 PPC_MEM_TLBSYNC | PPC_MFTB |
4282 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4283 PPC_440_SPEC;
4284 pcc->insns_flags2 = PPC2_FP_CVT_S64;
9df5a466
TM
4285 pcc->msr_mask = (1ull << MSR_POW) |
4286 (1ull << MSR_CE) |
4287 (1ull << MSR_EE) |
4288 (1ull << MSR_PR) |
4289 (1ull << MSR_FP) |
4290 (1ull << MSR_ME) |
4291 (1ull << MSR_FE0) |
4292 (1ull << MSR_DWE) |
4293 (1ull << MSR_DE) |
4294 (1ull << MSR_FE1) |
4295 (1ull << MSR_IR) |
4296 (1ull << MSR_DR);
ba9fd9f1
AF
4297 pcc->mmu_model = POWERPC_MMU_BOOKE;
4298 pcc->excp_model = POWERPC_EXCP_BOOKE;
4299 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4300 pcc->bfd_mach = bfd_mach_ppc_403;
4301 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4302 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4303}
4304
c364946d 4305static void init_proc_MPC5xx(CPUPPCState *env)
80d11f44
JM
4306{
4307 /* Time base */
4308 gen_tbl(env);
4309 gen_spr_5xx_8xx(env);
4310 gen_spr_5xx(env);
4311 init_excp_MPC5xx(env);
4312 env->dcache_line_size = 32;
4313 env->icache_line_size = 32;
4314 /* XXX: TODO: allocate internal IRQ controller */
4315}
4316
7856e3a4
AF
4317POWERPC_FAMILY(MPC5xx)(ObjectClass *oc, void *data)
4318{
ca5dff0a 4319 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4320 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4321
ca5dff0a 4322 dc->desc = "Freescale 5xx cores (aka RCPU)";
7856e3a4
AF
4323 pcc->init_proc = init_proc_MPC5xx;
4324 pcc->check_pow = check_pow_none;
53116ebf
AF
4325 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4326 PPC_MEM_EIEIO | PPC_MEM_SYNC |
4327 PPC_CACHE_ICBI | PPC_FLOAT | PPC_FLOAT_STFIWX |
4328 PPC_MFTB;
9df5a466
TM
4329 pcc->msr_mask = (1ull << MSR_ILE) |
4330 (1ull << MSR_EE) |
4331 (1ull << MSR_PR) |
4332 (1ull << MSR_FP) |
4333 (1ull << MSR_ME) |
4334 (1ull << MSR_FE0) |
4335 (1ull << MSR_SE) |
4336 (1ull << MSR_DE) |
4337 (1ull << MSR_FE1) |
4338 (1ull << MSR_EP) |
4339 (1ull << MSR_RI) |
4340 (1ull << MSR_LE);
ba9fd9f1
AF
4341 pcc->mmu_model = POWERPC_MMU_REAL;
4342 pcc->excp_model = POWERPC_EXCP_603;
4343 pcc->bus_model = PPC_FLAGS_INPUT_RCPU;
4344 pcc->bfd_mach = bfd_mach_ppc_505;
4345 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
4346 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4347}
4348
c364946d 4349static void init_proc_MPC8xx(CPUPPCState *env)
80d11f44
JM
4350{
4351 /* Time base */
4352 gen_tbl(env);
4353 gen_spr_5xx_8xx(env);
4354 gen_spr_8xx(env);
4355 init_excp_MPC8xx(env);
4356 env->dcache_line_size = 32;
4357 env->icache_line_size = 32;
4358 /* XXX: TODO: allocate internal IRQ controller */
4359}
4360
7856e3a4
AF
4361POWERPC_FAMILY(MPC8xx)(ObjectClass *oc, void *data)
4362{
ca5dff0a 4363 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4364 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4365
ca5dff0a 4366 dc->desc = "Freescale 8xx cores (aka PowerQUICC)";
7856e3a4
AF
4367 pcc->init_proc = init_proc_MPC8xx;
4368 pcc->check_pow = check_pow_none;
53116ebf
AF
4369 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4370 PPC_MEM_EIEIO | PPC_MEM_SYNC |
4371 PPC_CACHE_ICBI | PPC_MFTB;
9df5a466
TM
4372 pcc->msr_mask = (1ull << MSR_ILE) |
4373 (1ull << MSR_EE) |
4374 (1ull << MSR_PR) |
4375 (1ull << MSR_FP) |
4376 (1ull << MSR_ME) |
4377 (1ull << MSR_SE) |
4378 (1ull << MSR_DE) |
4379 (1ull << MSR_EP) |
4380 (1ull << MSR_IR) |
4381 (1ull << MSR_DR) |
4382 (1ull << MSR_RI) |
4383 (1ull << MSR_LE);
ba9fd9f1
AF
4384 pcc->mmu_model = POWERPC_MMU_MPC8xx;
4385 pcc->excp_model = POWERPC_EXCP_603;
4386 pcc->bus_model = PPC_FLAGS_INPUT_RCPU;
4387 pcc->bfd_mach = bfd_mach_ppc_860;
4388 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
4389 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4390}
4391
80d11f44 4392/* Freescale 82xx cores (aka PowerQUICC-II) */
ca5dff0a 4393
c364946d 4394static void init_proc_G2(CPUPPCState *env)
3fc6c082 4395{
80d11f44 4396 gen_spr_ne_601(env);
4f4f28ff 4397 gen_spr_sdr1(env);
80d11f44
JM
4398 gen_spr_G2_755(env);
4399 gen_spr_G2(env);
a750fc0b
JM
4400 /* Time base */
4401 gen_tbl(env);
bd928eba
JM
4402 /* External access control */
4403 /* XXX : not implemented */
4404 spr_register(env, SPR_EAR, "EAR",
4405 SPR_NOACCESS, SPR_NOACCESS,
4406 &spr_read_generic, &spr_write_generic,
4407 0x00000000);
80d11f44
JM
4408 /* Hardware implementation register */
4409 /* XXX : not implemented */
4410 spr_register(env, SPR_HID0, "HID0",
4411 SPR_NOACCESS, SPR_NOACCESS,
4412 &spr_read_generic, &spr_write_generic,
4413 0x00000000);
4414 /* XXX : not implemented */
4415 spr_register(env, SPR_HID1, "HID1",
4416 SPR_NOACCESS, SPR_NOACCESS,
4417 &spr_read_generic, &spr_write_generic,
4418 0x00000000);
4419 /* XXX : not implemented */
4420 spr_register(env, SPR_HID2, "HID2",
4421 SPR_NOACCESS, SPR_NOACCESS,
4422 &spr_read_generic, &spr_write_generic,
4423 0x00000000);
a750fc0b 4424 /* Memory management */
80d11f44
JM
4425 gen_low_BATs(env);
4426 gen_high_BATs(env);
4427 gen_6xx_7xx_soft_tlb(env, 64, 2);
4428 init_excp_G2(env);
d63001d1
JM
4429 env->dcache_line_size = 32;
4430 env->icache_line_size = 32;
80d11f44 4431 /* Allocate hardware IRQ controller */
db70b311 4432 ppc6xx_irq_init(env_archcpu(env));
3fc6c082 4433}
a750fc0b 4434
7856e3a4
AF
4435POWERPC_FAMILY(G2)(ObjectClass *oc, void *data)
4436{
ca5dff0a 4437 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4438 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4439
ca5dff0a 4440 dc->desc = "PowerPC G2";
7856e3a4
AF
4441 pcc->init_proc = init_proc_G2;
4442 pcc->check_pow = check_pow_hid0;
53116ebf
AF
4443 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4444 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4445 PPC_FLOAT_STFIWX |
4446 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4447 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4448 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4449 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
4450 pcc->msr_mask = (1ull << MSR_POW) |
4451 (1ull << MSR_TGPR) |
4452 (1ull << MSR_EE) |
4453 (1ull << MSR_PR) |
4454 (1ull << MSR_FP) |
4455 (1ull << MSR_ME) |
4456 (1ull << MSR_FE0) |
4457 (1ull << MSR_SE) |
4458 (1ull << MSR_DE) |
4459 (1ull << MSR_FE1) |
4460 (1ull << MSR_AL) |
4461 (1ull << MSR_EP) |
4462 (1ull << MSR_IR) |
4463 (1ull << MSR_DR) |
4464 (1ull << MSR_RI);
ba9fd9f1
AF
4465 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4466 pcc->excp_model = POWERPC_EXCP_G2;
4467 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4468 pcc->bfd_mach = bfd_mach_ppc_ec603e;
4469 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4470 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4471}
4472
c364946d 4473static void init_proc_G2LE(CPUPPCState *env)
3fc6c082 4474{
80d11f44 4475 gen_spr_ne_601(env);
4f4f28ff 4476 gen_spr_sdr1(env);
80d11f44
JM
4477 gen_spr_G2_755(env);
4478 gen_spr_G2(env);
a750fc0b
JM
4479 /* Time base */
4480 gen_tbl(env);
bd928eba
JM
4481 /* External access control */
4482 /* XXX : not implemented */
4483 spr_register(env, SPR_EAR, "EAR",
4484 SPR_NOACCESS, SPR_NOACCESS,
4485 &spr_read_generic, &spr_write_generic,
4486 0x00000000);
80d11f44 4487 /* Hardware implementation register */
578bb252 4488 /* XXX : not implemented */
80d11f44 4489 spr_register(env, SPR_HID0, "HID0",
a750fc0b
JM
4490 SPR_NOACCESS, SPR_NOACCESS,
4491 &spr_read_generic, &spr_write_generic,
4492 0x00000000);
80d11f44
JM
4493 /* XXX : not implemented */
4494 spr_register(env, SPR_HID1, "HID1",
a750fc0b
JM
4495 SPR_NOACCESS, SPR_NOACCESS,
4496 &spr_read_generic, &spr_write_generic,
4497 0x00000000);
578bb252 4498 /* XXX : not implemented */
80d11f44 4499 spr_register(env, SPR_HID2, "HID2",
a750fc0b
JM
4500 SPR_NOACCESS, SPR_NOACCESS,
4501 &spr_read_generic, &spr_write_generic,
4502 0x00000000);
2bc17322 4503
a750fc0b 4504 /* Memory management */
80d11f44
JM
4505 gen_low_BATs(env);
4506 gen_high_BATs(env);
4507 gen_6xx_7xx_soft_tlb(env, 64, 2);
4508 init_excp_G2(env);
d63001d1
JM
4509 env->dcache_line_size = 32;
4510 env->icache_line_size = 32;
80d11f44 4511 /* Allocate hardware IRQ controller */
db70b311 4512 ppc6xx_irq_init(env_archcpu(env));
3fc6c082
FB
4513}
4514
7856e3a4
AF
4515POWERPC_FAMILY(G2LE)(ObjectClass *oc, void *data)
4516{
ca5dff0a 4517 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4518 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4519
ca5dff0a 4520 dc->desc = "PowerPC G2LE";
7856e3a4
AF
4521 pcc->init_proc = init_proc_G2LE;
4522 pcc->check_pow = check_pow_hid0;
53116ebf
AF
4523 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4524 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4525 PPC_FLOAT_STFIWX |
4526 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4527 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4528 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4529 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
4530 pcc->msr_mask = (1ull << MSR_POW) |
4531 (1ull << MSR_TGPR) |
4532 (1ull << MSR_ILE) |
4533 (1ull << MSR_EE) |
4534 (1ull << MSR_PR) |
4535 (1ull << MSR_FP) |
4536 (1ull << MSR_ME) |
4537 (1ull << MSR_FE0) |
4538 (1ull << MSR_SE) |
4539 (1ull << MSR_DE) |
4540 (1ull << MSR_FE1) |
4541 (1ull << MSR_AL) |
4542 (1ull << MSR_EP) |
4543 (1ull << MSR_IR) |
4544 (1ull << MSR_DR) |
4545 (1ull << MSR_RI) |
4546 (1ull << MSR_LE);
ba9fd9f1
AF
4547 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4548 pcc->excp_model = POWERPC_EXCP_G2;
4549 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4550 pcc->bfd_mach = bfd_mach_ppc_ec603e;
4551 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4552 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4553}
4554
c364946d 4555static void init_proc_e200(CPUPPCState *env)
3fc6c082 4556{
e1833e1f
JM
4557 /* Time base */
4558 gen_tbl(env);
80d11f44 4559 gen_spr_BookE(env, 0x000000070000FFFFULL);
578bb252 4560 /* XXX : not implemented */
80d11f44 4561 spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
d34defbc
AJ
4562 &spr_read_spefscr, &spr_write_spefscr,
4563 &spr_read_spefscr, &spr_write_spefscr,
e1833e1f 4564 0x00000000);
80d11f44 4565 /* Memory management */
d21ee633 4566 gen_spr_BookE206(env, 0x0000005D, NULL, 0);
80d11f44
JM
4567 /* XXX : not implemented */
4568 spr_register(env, SPR_HID0, "HID0",
e1833e1f
JM
4569 SPR_NOACCESS, SPR_NOACCESS,
4570 &spr_read_generic, &spr_write_generic,
4571 0x00000000);
80d11f44
JM
4572 /* XXX : not implemented */
4573 spr_register(env, SPR_HID1, "HID1",
e1833e1f
JM
4574 SPR_NOACCESS, SPR_NOACCESS,
4575 &spr_read_generic, &spr_write_generic,
4576 0x00000000);
578bb252 4577 /* XXX : not implemented */
80d11f44 4578 spr_register(env, SPR_Exxx_ALTCTXCR, "ALTCTXCR",
e1833e1f
JM
4579 SPR_NOACCESS, SPR_NOACCESS,
4580 &spr_read_generic, &spr_write_generic,
4581 0x00000000);
578bb252 4582 /* XXX : not implemented */
80d11f44
JM
4583 spr_register(env, SPR_Exxx_BUCSR, "BUCSR",
4584 SPR_NOACCESS, SPR_NOACCESS,
e1833e1f 4585 &spr_read_generic, &spr_write_generic,
80d11f44
JM
4586 0x00000000);
4587 /* XXX : not implemented */
4588 spr_register(env, SPR_Exxx_CTXCR, "CTXCR",
4589 SPR_NOACCESS, SPR_NOACCESS,
4590 &spr_read_generic, &spr_write_generic,
4591 0x00000000);
4592 /* XXX : not implemented */
4593 spr_register(env, SPR_Exxx_DBCNT, "DBCNT",
4594 SPR_NOACCESS, SPR_NOACCESS,
4595 &spr_read_generic, &spr_write_generic,
4596 0x00000000);
4597 /* XXX : not implemented */
4598 spr_register(env, SPR_Exxx_DBCR3, "DBCR3",
4599 SPR_NOACCESS, SPR_NOACCESS,
4600 &spr_read_generic, &spr_write_generic,
4601 0x00000000);
4602 /* XXX : not implemented */
4603 spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0",
deb05c4c
AG
4604 &spr_read_generic, SPR_NOACCESS,
4605 &spr_read_generic, SPR_NOACCESS,
80d11f44
JM
4606 0x00000000);
4607 /* XXX : not implemented */
4608 spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0",
4609 SPR_NOACCESS, SPR_NOACCESS,
4610 &spr_read_generic, &spr_write_generic,
4611 0x00000000);
4612 /* XXX : not implemented */
4613 spr_register(env, SPR_Exxx_L1FINV0, "L1FINV0",
4614 SPR_NOACCESS, SPR_NOACCESS,
4615 &spr_read_generic, &spr_write_generic,
4616 0x00000000);
4617 /* XXX : not implemented */
4618 spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG",
4619 SPR_NOACCESS, SPR_NOACCESS,
4620 &spr_read_generic, &spr_write_generic,
4621 0x00000000);
4622 /* XXX : not implemented */
4623 spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG",
4624 SPR_NOACCESS, SPR_NOACCESS,
4625 &spr_read_generic, &spr_write_generic,
4626 0x00000000);
4627 /* XXX : not implemented */
4628 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4629 SPR_NOACCESS, SPR_NOACCESS,
4630 &spr_read_generic, &spr_write_generic,
4631 0x00000000);
4632 /* XXX : not implemented */
4633 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4634 SPR_NOACCESS, SPR_NOACCESS,
4635 &spr_read_generic, &spr_write_generic,
4636 0x00000000);
01662f3e
AG
4637 /* XXX : not implemented */
4638 spr_register(env, SPR_MMUCSR0, "MMUCSR0",
4639 SPR_NOACCESS, SPR_NOACCESS,
4640 &spr_read_generic, &spr_write_generic,
4641 0x00000000); /* TOFIX */
80d11f44
JM
4642 spr_register(env, SPR_BOOKE_DSRR0, "DSRR0",
4643 SPR_NOACCESS, SPR_NOACCESS,
4644 &spr_read_generic, &spr_write_generic,
4645 0x00000000);
4646 spr_register(env, SPR_BOOKE_DSRR1, "DSRR1",
4647 SPR_NOACCESS, SPR_NOACCESS,
e1833e1f
JM
4648 &spr_read_generic, &spr_write_generic,
4649 0x00000000);
f2e63a42 4650#if !defined(CONFIG_USER_ONLY)
e1833e1f
JM
4651 env->nb_tlb = 64;
4652 env->nb_ways = 1;
4653 env->id_tlbs = 0;
1c53accc 4654 env->tlb_type = TLB_EMB;
f2e63a42 4655#endif
e9cd84b9 4656 init_excp_e200(env, 0xFFFF0000UL);
d63001d1
JM
4657 env->dcache_line_size = 32;
4658 env->icache_line_size = 32;
e1833e1f 4659 /* XXX: TODO: allocate internal IRQ controller */
3fc6c082 4660}
a750fc0b 4661
7856e3a4
AF
4662POWERPC_FAMILY(e200)(ObjectClass *oc, void *data)
4663{
ca5dff0a 4664 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4665 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4666
ca5dff0a 4667 dc->desc = "e200 core";
7856e3a4
AF
4668 pcc->init_proc = init_proc_e200;
4669 pcc->check_pow = check_pow_hid0;
1d28b5f6
DG
4670 /*
4671 * XXX: unimplemented instructions:
53116ebf
AF
4672 * dcblc
4673 * dcbtlst
4674 * dcbtstls
4675 * icblc
4676 * icbtls
4677 * tlbivax
4678 * all SPE multiply-accumulate instructions
4679 */
4680 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
4681 PPC_SPE | PPC_SPE_SINGLE |
4682 PPC_WRTEE | PPC_RFDI |
4683 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
4684 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4685 PPC_MEM_TLBSYNC | PPC_TLBIVAX |
4686 PPC_BOOKE;
9df5a466
TM
4687 pcc->msr_mask = (1ull << MSR_UCLE) |
4688 (1ull << MSR_SPE) |
4689 (1ull << MSR_POW) |
4690 (1ull << MSR_CE) |
4691 (1ull << MSR_EE) |
4692 (1ull << MSR_PR) |
4693 (1ull << MSR_FP) |
4694 (1ull << MSR_ME) |
4695 (1ull << MSR_FE0) |
4696 (1ull << MSR_DWE) |
4697 (1ull << MSR_DE) |
4698 (1ull << MSR_FE1) |
4699 (1ull << MSR_IR) |
4700 (1ull << MSR_DR);
ba9fd9f1
AF
4701 pcc->mmu_model = POWERPC_MMU_BOOKE206;
4702 pcc->excp_model = POWERPC_EXCP_BOOKE;
4703 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4704 pcc->bfd_mach = bfd_mach_ppc_860;
4705 pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
4706 POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
4707 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4708}
4709
c364946d 4710static void init_proc_e300(CPUPPCState *env)
3fc6c082 4711{
80d11f44 4712 gen_spr_ne_601(env);
4f4f28ff 4713 gen_spr_sdr1(env);
80d11f44 4714 gen_spr_603(env);
a750fc0b
JM
4715 /* Time base */
4716 gen_tbl(env);
80d11f44
JM
4717 /* hardware implementation registers */
4718 /* XXX : not implemented */
4719 spr_register(env, SPR_HID0, "HID0",
4720 SPR_NOACCESS, SPR_NOACCESS,
4721 &spr_read_generic, &spr_write_generic,
4722 0x00000000);
4723 /* XXX : not implemented */
4724 spr_register(env, SPR_HID1, "HID1",
4725 SPR_NOACCESS, SPR_NOACCESS,
4726 &spr_read_generic, &spr_write_generic,
4727 0x00000000);
8daf1781
TM
4728 /* XXX : not implemented */
4729 spr_register(env, SPR_HID2, "HID2",
4730 SPR_NOACCESS, SPR_NOACCESS,
4731 &spr_read_generic, &spr_write_generic,
4732 0x00000000);
3ade1a05
FC
4733 /* Breakpoints */
4734 /* XXX : not implemented */
4735 spr_register(env, SPR_DABR, "DABR",
4736 SPR_NOACCESS, SPR_NOACCESS,
4737 &spr_read_generic, &spr_write_generic,
4738 0x00000000);
4739 /* XXX : not implemented */
4740 spr_register(env, SPR_DABR2, "DABR2",
4741 SPR_NOACCESS, SPR_NOACCESS,
4742 &spr_read_generic, &spr_write_generic,
4743 0x00000000);
4744 /* XXX : not implemented */
4745 spr_register(env, SPR_IABR2, "IABR2",
4746 SPR_NOACCESS, SPR_NOACCESS,
4747 &spr_read_generic, &spr_write_generic,
4748 0x00000000);
4749 /* XXX : not implemented */
4750 spr_register(env, SPR_IBCR, "IBCR",
4751 SPR_NOACCESS, SPR_NOACCESS,
4752 &spr_read_generic, &spr_write_generic,
4753 0x00000000);
4754 /* XXX : not implemented */
4755 spr_register(env, SPR_DBCR, "DBCR",
4756 SPR_NOACCESS, SPR_NOACCESS,
4757 &spr_read_generic, &spr_write_generic,
4758 0x00000000);
80d11f44
JM
4759 /* Memory management */
4760 gen_low_BATs(env);
8daf1781 4761 gen_high_BATs(env);
80d11f44
JM
4762 gen_6xx_7xx_soft_tlb(env, 64, 2);
4763 init_excp_603(env);
4764 env->dcache_line_size = 32;
4765 env->icache_line_size = 32;
4766 /* Allocate hardware IRQ controller */
db70b311 4767 ppc6xx_irq_init(env_archcpu(env));
80d11f44
JM
4768}
4769
7856e3a4
AF
4770POWERPC_FAMILY(e300)(ObjectClass *oc, void *data)
4771{
ca5dff0a 4772 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4773 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4774
ca5dff0a 4775 dc->desc = "e300 core";
7856e3a4
AF
4776 pcc->init_proc = init_proc_e300;
4777 pcc->check_pow = check_pow_hid0;
53116ebf
AF
4778 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4779 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4780 PPC_FLOAT_STFIWX |
4781 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4782 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4783 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4784 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
4785 pcc->msr_mask = (1ull << MSR_POW) |
4786 (1ull << MSR_TGPR) |
4787 (1ull << MSR_ILE) |
4788 (1ull << MSR_EE) |
4789 (1ull << MSR_PR) |
4790 (1ull << MSR_FP) |
4791 (1ull << MSR_ME) |
4792 (1ull << MSR_FE0) |
4793 (1ull << MSR_SE) |
4794 (1ull << MSR_DE) |
4795 (1ull << MSR_FE1) |
4796 (1ull << MSR_AL) |
4797 (1ull << MSR_EP) |
4798 (1ull << MSR_IR) |
4799 (1ull << MSR_DR) |
4800 (1ull << MSR_RI) |
4801 (1ull << MSR_LE);
ba9fd9f1
AF
4802 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4803 pcc->excp_model = POWERPC_EXCP_603;
4804 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4805 pcc->bfd_mach = bfd_mach_ppc_603;
4806 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4807 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4808}
4809
b81ccf8a 4810#if !defined(CONFIG_USER_ONLY)
69b058c8 4811static void spr_write_mas73(DisasContext *ctx, int sprn, int gprn)
b81ccf8a
AG
4812{
4813 TCGv val = tcg_temp_new();
4814 tcg_gen_ext32u_tl(val, cpu_gpr[gprn]);
4815 gen_store_spr(SPR_BOOKE_MAS3, val);
cfee0218 4816 tcg_gen_shri_tl(val, cpu_gpr[gprn], 32);
b81ccf8a
AG
4817 gen_store_spr(SPR_BOOKE_MAS7, val);
4818 tcg_temp_free(val);
4819}
4820
69b058c8 4821static void spr_read_mas73(DisasContext *ctx, int gprn, int sprn)
b81ccf8a
AG
4822{
4823 TCGv mas7 = tcg_temp_new();
4824 TCGv mas3 = tcg_temp_new();
4825 gen_load_spr(mas7, SPR_BOOKE_MAS7);
4826 tcg_gen_shli_tl(mas7, mas7, 32);
4827 gen_load_spr(mas3, SPR_BOOKE_MAS3);
4828 tcg_gen_or_tl(cpu_gpr[gprn], mas3, mas7);
4829 tcg_temp_free(mas3);
4830 tcg_temp_free(mas7);
4831}
4832
b81ccf8a
AG
4833#endif
4834
f7aa5583
VS
4835enum fsl_e500_version {
4836 fsl_e500v1,
4837 fsl_e500v2,
4838 fsl_e500mc,
b81ccf8a 4839 fsl_e5500,
54a50dae 4840 fsl_e6500,
f7aa5583
VS
4841};
4842
c364946d 4843static void init_proc_e500(CPUPPCState *env, int version)
80d11f44 4844{
01662f3e 4845 uint32_t tlbncfg[2];
b81ccf8a 4846 uint64_t ivor_mask;
e9cd84b9 4847 uint64_t ivpr_mask = 0xFFFF0000ULL;
a496e8ee
AG
4848 uint32_t l1cfg0 = 0x3800 /* 8 ways */
4849 | 0x0020; /* 32 kb */
d2ea2bf7
AG
4850 uint32_t l1cfg1 = 0x3800 /* 8 ways */
4851 | 0x0020; /* 32 kb */
d21ee633 4852 uint32_t mmucfg = 0;
01662f3e
AG
4853#if !defined(CONFIG_USER_ONLY)
4854 int i;
4855#endif
4856
80d11f44
JM
4857 /* Time base */
4858 gen_tbl(env);
01662f3e
AG
4859 /*
4860 * XXX The e500 doesn't implement IVOR7 and IVOR9, but doesn't
4861 * complain when accessing them.
4862 * gen_spr_BookE(env, 0x0000000F0000FD7FULL);
4863 */
b81ccf8a 4864 switch (version) {
1d28b5f6
DG
4865 case fsl_e500v1:
4866 case fsl_e500v2:
4867 default:
4868 ivor_mask = 0x0000000F0000FFFFULL;
4869 break;
4870 case fsl_e500mc:
4871 case fsl_e5500:
4872 ivor_mask = 0x000003FE0000FFFFULL;
4873 break;
4874 case fsl_e6500:
4875 ivor_mask = 0x000003FF0000FFFFULL;
4876 break;
2c9732db
AG
4877 }
4878 gen_spr_BookE(env, ivor_mask);
b1c897d5 4879 gen_spr_usprg3(env);
80d11f44
JM
4880 /* Processor identification */
4881 spr_register(env, SPR_BOOKE_PIR, "PIR",
4882 SPR_NOACCESS, SPR_NOACCESS,
4883 &spr_read_generic, &spr_write_pir,
4884 0x00000000);
4885 /* XXX : not implemented */
4886 spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
d34defbc
AJ
4887 &spr_read_spefscr, &spr_write_spefscr,
4888 &spr_read_spefscr, &spr_write_spefscr,
80d11f44 4889 0x00000000);
892c587f 4890#if !defined(CONFIG_USER_ONLY)
80d11f44 4891 /* Memory management */
80d11f44 4892 env->nb_pids = 3;
01662f3e
AG
4893 env->nb_ways = 2;
4894 env->id_tlbs = 0;
4895 switch (version) {
f7aa5583 4896 case fsl_e500v1:
01662f3e
AG
4897 tlbncfg[0] = gen_tlbncfg(2, 1, 1, 0, 256);
4898 tlbncfg[1] = gen_tlbncfg(16, 1, 9, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16);
4899 break;
f7aa5583 4900 case fsl_e500v2:
01662f3e
AG
4901 tlbncfg[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4902 tlbncfg[1] = gen_tlbncfg(16, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16);
f7aa5583
VS
4903 break;
4904 case fsl_e500mc:
b81ccf8a 4905 case fsl_e5500:
f7aa5583
VS
4906 tlbncfg[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4907 tlbncfg[1] = gen_tlbncfg(64, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 64);
892c587f 4908 break;
54a50dae
KF
4909 case fsl_e6500:
4910 mmucfg = 0x6510B45;
4911 env->nb_pids = 1;
4912 tlbncfg[0] = 0x08052400;
4913 tlbncfg[1] = 0x40028040;
4914 break;
892c587f 4915 default:
db70b311 4916 cpu_abort(env_cpu(env), "Unknown CPU: " TARGET_FMT_lx "\n",
1d28b5f6 4917 env->spr[SPR_PVR]);
892c587f
AG
4918 }
4919#endif
4920 /* Cache sizes */
4921 switch (version) {
4922 case fsl_e500v1:
4923 case fsl_e500v2:
4924 env->dcache_line_size = 32;
4925 env->icache_line_size = 32;
4926 break;
4927 case fsl_e500mc:
b81ccf8a 4928 case fsl_e5500:
f7aa5583
VS
4929 env->dcache_line_size = 64;
4930 env->icache_line_size = 64;
a496e8ee 4931 l1cfg0 |= 0x1000000; /* 64 byte cache block size */
d2ea2bf7 4932 l1cfg1 |= 0x1000000; /* 64 byte cache block size */
01662f3e 4933 break;
54a50dae
KF
4934 case fsl_e6500:
4935 env->dcache_line_size = 32;
4936 env->icache_line_size = 32;
4937 l1cfg0 |= 0x0F83820;
4938 l1cfg1 |= 0x0B83820;
4939 break;
01662f3e 4940 default:
db70b311 4941 cpu_abort(env_cpu(env), "Unknown CPU: " TARGET_FMT_lx "\n",
1d28b5f6 4942 env->spr[SPR_PVR]);
01662f3e 4943 }
d21ee633 4944 gen_spr_BookE206(env, 0x000000DF, tlbncfg, mmucfg);
80d11f44
JM
4945 /* XXX : not implemented */
4946 spr_register(env, SPR_HID0, "HID0",
4947 SPR_NOACCESS, SPR_NOACCESS,
4948 &spr_read_generic, &spr_write_generic,
4949 0x00000000);
4950 /* XXX : not implemented */
4951 spr_register(env, SPR_HID1, "HID1",
4952 SPR_NOACCESS, SPR_NOACCESS,
4953 &spr_read_generic, &spr_write_generic,
4954 0x00000000);
4955 /* XXX : not implemented */
4956 spr_register(env, SPR_Exxx_BBEAR, "BBEAR",
4957 SPR_NOACCESS, SPR_NOACCESS,
4958 &spr_read_generic, &spr_write_generic,
4959 0x00000000);
4960 /* XXX : not implemented */
4961 spr_register(env, SPR_Exxx_BBTAR, "BBTAR",
4962 SPR_NOACCESS, SPR_NOACCESS,
4963 &spr_read_generic, &spr_write_generic,
4964 0x00000000);
4965 /* XXX : not implemented */
4966 spr_register(env, SPR_Exxx_MCAR, "MCAR",
4967 SPR_NOACCESS, SPR_NOACCESS,
4968 &spr_read_generic, &spr_write_generic,
4969 0x00000000);
578bb252 4970 /* XXX : not implemented */
a750fc0b
JM
4971 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
4972 SPR_NOACCESS, SPR_NOACCESS,
4973 &spr_read_generic, &spr_write_generic,
4974 0x00000000);
80d11f44
JM
4975 /* XXX : not implemented */
4976 spr_register(env, SPR_Exxx_NPIDR, "NPIDR",
a750fc0b
JM
4977 SPR_NOACCESS, SPR_NOACCESS,
4978 &spr_read_generic, &spr_write_generic,
4979 0x00000000);
80d11f44
JM
4980 /* XXX : not implemented */
4981 spr_register(env, SPR_Exxx_BUCSR, "BUCSR",
a750fc0b
JM
4982 SPR_NOACCESS, SPR_NOACCESS,
4983 &spr_read_generic, &spr_write_generic,
4984 0x00000000);
578bb252 4985 /* XXX : not implemented */
80d11f44 4986 spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0",
deb05c4c
AG
4987 &spr_read_generic, SPR_NOACCESS,
4988 &spr_read_generic, SPR_NOACCESS,
a496e8ee 4989 l1cfg0);
d2ea2bf7
AG
4990 spr_register(env, SPR_Exxx_L1CFG1, "L1CFG1",
4991 &spr_read_generic, SPR_NOACCESS,
4992 &spr_read_generic, SPR_NOACCESS,
4993 l1cfg1);
80d11f44
JM
4994 spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0",
4995 SPR_NOACCESS, SPR_NOACCESS,
01662f3e 4996 &spr_read_generic, &spr_write_e500_l1csr0,
80d11f44 4997 0x00000000);
80d11f44
JM
4998 spr_register(env, SPR_Exxx_L1CSR1, "L1CSR1",
4999 SPR_NOACCESS, SPR_NOACCESS,
ea71258d 5000 &spr_read_generic, &spr_write_e500_l1csr1,
80d11f44 5001 0x00000000);
80d11f44
JM
5002 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
5003 SPR_NOACCESS, SPR_NOACCESS,
5004 &spr_read_generic, &spr_write_generic,
5005 0x00000000);
5006 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
5007 SPR_NOACCESS, SPR_NOACCESS,
a750fc0b
JM
5008 &spr_read_generic, &spr_write_generic,
5009 0x00000000);
01662f3e
AG
5010 spr_register(env, SPR_MMUCSR0, "MMUCSR0",
5011 SPR_NOACCESS, SPR_NOACCESS,
5012 &spr_read_generic, &spr_write_booke206_mmucsr0,
5013 0x00000000);
b81ccf8a
AG
5014 spr_register(env, SPR_BOOKE_EPR, "EPR",
5015 SPR_NOACCESS, SPR_NOACCESS,
68c2dd70 5016 &spr_read_generic, SPR_NOACCESS,
b81ccf8a
AG
5017 0x00000000);
5018 /* XXX better abstract into Emb.xxx features */
54a50dae 5019 if ((version == fsl_e5500) || (version == fsl_e6500)) {
b81ccf8a
AG
5020 spr_register(env, SPR_BOOKE_EPCR, "EPCR",
5021 SPR_NOACCESS, SPR_NOACCESS,
5022 &spr_read_generic, &spr_write_generic,
5023 0x00000000);
5024 spr_register(env, SPR_BOOKE_MAS7_MAS3, "MAS7_MAS3",
5025 SPR_NOACCESS, SPR_NOACCESS,
5026 &spr_read_mas73, &spr_write_mas73,
5027 0x00000000);
5028 ivpr_mask = (target_ulong)~0xFFFFULL;
5029 }
01662f3e 5030
54a50dae 5031 if (version == fsl_e6500) {
54a50dae
KF
5032 /* Thread identification */
5033 spr_register(env, SPR_TIR, "TIR",
5034 SPR_NOACCESS, SPR_NOACCESS,
5035 &spr_read_generic, SPR_NOACCESS,
5036 0x00000000);
5037 spr_register(env, SPR_BOOKE_TLB0PS, "TLB0PS",
5038 SPR_NOACCESS, SPR_NOACCESS,
5039 &spr_read_generic, SPR_NOACCESS,
5040 0x00000004);
5041 spr_register(env, SPR_BOOKE_TLB1PS, "TLB1PS",
5042 SPR_NOACCESS, SPR_NOACCESS,
5043 &spr_read_generic, SPR_NOACCESS,
5044 0x7FFFFFFC);
5045 }
5046
f2e63a42 5047#if !defined(CONFIG_USER_ONLY)
01662f3e 5048 env->nb_tlb = 0;
1c53accc 5049 env->tlb_type = TLB_MAS;
01662f3e
AG
5050 for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
5051 env->nb_tlb += booke206_tlb_size(env, i);
5052 }
f2e63a42 5053#endif
01662f3e 5054
e9cd84b9 5055 init_excp_e200(env, ivpr_mask);
9fdc60bf 5056 /* Allocate hardware IRQ controller */
db70b311 5057 ppce500_irq_init(env_archcpu(env));
3fc6c082 5058}
a750fc0b 5059
01662f3e
AG
5060static void init_proc_e500v1(CPUPPCState *env)
5061{
f7aa5583 5062 init_proc_e500(env, fsl_e500v1);
01662f3e
AG
5063}
5064
7856e3a4
AF
5065POWERPC_FAMILY(e500v1)(ObjectClass *oc, void *data)
5066{
ca5dff0a 5067 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5068 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5069
ca5dff0a 5070 dc->desc = "e500v1 core";
7856e3a4
AF
5071 pcc->init_proc = init_proc_e500v1;
5072 pcc->check_pow = check_pow_hid0;
53116ebf
AF
5073 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
5074 PPC_SPE | PPC_SPE_SINGLE |
5075 PPC_WRTEE | PPC_RFDI |
5076 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5077 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5078 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
5079 pcc->insns_flags2 = PPC2_BOOKE206;
9df5a466
TM
5080 pcc->msr_mask = (1ull << MSR_UCLE) |
5081 (1ull << MSR_SPE) |
5082 (1ull << MSR_POW) |
5083 (1ull << MSR_CE) |
5084 (1ull << MSR_EE) |
5085 (1ull << MSR_PR) |
5086 (1ull << MSR_FP) |
5087 (1ull << MSR_ME) |
5088 (1ull << MSR_FE0) |
5089 (1ull << MSR_DWE) |
5090 (1ull << MSR_DE) |
5091 (1ull << MSR_FE1) |
5092 (1ull << MSR_IR) |
5093 (1ull << MSR_DR);
ba9fd9f1
AF
5094 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5095 pcc->excp_model = POWERPC_EXCP_BOOKE;
5096 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5097 pcc->bfd_mach = bfd_mach_ppc_860;
5098 pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
5099 POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
5100 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5101}
5102
01662f3e
AG
5103static void init_proc_e500v2(CPUPPCState *env)
5104{
f7aa5583
VS
5105 init_proc_e500(env, fsl_e500v2);
5106}
5107
7856e3a4
AF
5108POWERPC_FAMILY(e500v2)(ObjectClass *oc, void *data)
5109{
ca5dff0a 5110 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5111 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5112
ca5dff0a 5113 dc->desc = "e500v2 core";
7856e3a4
AF
5114 pcc->init_proc = init_proc_e500v2;
5115 pcc->check_pow = check_pow_hid0;
53116ebf
AF
5116 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
5117 PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE |
5118 PPC_WRTEE | PPC_RFDI |
5119 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5120 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5121 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
5122 pcc->insns_flags2 = PPC2_BOOKE206;
9df5a466
TM
5123 pcc->msr_mask = (1ull << MSR_UCLE) |
5124 (1ull << MSR_SPE) |
5125 (1ull << MSR_POW) |
5126 (1ull << MSR_CE) |
5127 (1ull << MSR_EE) |
5128 (1ull << MSR_PR) |
5129 (1ull << MSR_FP) |
5130 (1ull << MSR_ME) |
5131 (1ull << MSR_FE0) |
5132 (1ull << MSR_DWE) |
5133 (1ull << MSR_DE) |
5134 (1ull << MSR_FE1) |
5135 (1ull << MSR_IR) |
5136 (1ull << MSR_DR);
ba9fd9f1
AF
5137 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5138 pcc->excp_model = POWERPC_EXCP_BOOKE;
5139 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5140 pcc->bfd_mach = bfd_mach_ppc_860;
5141 pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
5142 POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
5143 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5144}
5145
f7aa5583
VS
5146static void init_proc_e500mc(CPUPPCState *env)
5147{
5148 init_proc_e500(env, fsl_e500mc);
01662f3e
AG
5149}
5150
7856e3a4
AF
5151POWERPC_FAMILY(e500mc)(ObjectClass *oc, void *data)
5152{
ca5dff0a 5153 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5154 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5155
ca5dff0a 5156 dc->desc = "e500mc core";
7856e3a4
AF
5157 pcc->init_proc = init_proc_e500mc;
5158 pcc->check_pow = check_pow_none;
2fff4bad 5159 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
53116ebf
AF
5160 PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
5161 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5162 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5163 PPC_FLOAT | PPC_FLOAT_FRES |
5164 PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
5165 PPC_FLOAT_STFIWX | PPC_WAIT |
5166 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
5167 pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL;
9df5a466
TM
5168 pcc->msr_mask = (1ull << MSR_GS) |
5169 (1ull << MSR_UCLE) |
5170 (1ull << MSR_CE) |
5171 (1ull << MSR_EE) |
5172 (1ull << MSR_PR) |
5173 (1ull << MSR_FP) |
5174 (1ull << MSR_ME) |
5175 (1ull << MSR_FE0) |
5176 (1ull << MSR_DE) |
5177 (1ull << MSR_FE1) |
5178 (1ull << MSR_IR) |
5179 (1ull << MSR_DR) |
5180 (1ull << MSR_PX) |
5181 (1ull << MSR_RI);
ba9fd9f1
AF
5182 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5183 pcc->excp_model = POWERPC_EXCP_BOOKE;
5184 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5185 /* FIXME: figure out the correct flag for e500mc */
5186 pcc->bfd_mach = bfd_mach_ppc_e500;
5187 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
5188 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5189}
5190
b81ccf8a
AG
5191#ifdef TARGET_PPC64
5192static void init_proc_e5500(CPUPPCState *env)
5193{
5194 init_proc_e500(env, fsl_e5500);
5195}
7856e3a4
AF
5196
5197POWERPC_FAMILY(e5500)(ObjectClass *oc, void *data)
5198{
ca5dff0a 5199 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5200 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5201
ca5dff0a 5202 dc->desc = "e5500 core";
7856e3a4
AF
5203 pcc->init_proc = init_proc_e5500;
5204 pcc->check_pow = check_pow_none;
2fff4bad 5205 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
53116ebf
AF
5206 PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
5207 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5208 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5209 PPC_FLOAT | PPC_FLOAT_FRES |
5210 PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
5211 PPC_FLOAT_STFIWX | PPC_WAIT |
5212 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC |
5213 PPC_64B | PPC_POPCNTB | PPC_POPCNTWD;
78ee6bd0 5214 pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL | PPC2_PERM_ISA206 |
4171853c 5215 PPC2_FP_CVT_S64;
9df5a466
TM
5216 pcc->msr_mask = (1ull << MSR_CM) |
5217 (1ull << MSR_GS) |
5218 (1ull << MSR_UCLE) |
5219 (1ull << MSR_CE) |
5220 (1ull << MSR_EE) |
5221 (1ull << MSR_PR) |
5222 (1ull << MSR_FP) |
5223 (1ull << MSR_ME) |
5224 (1ull << MSR_FE0) |
5225 (1ull << MSR_DE) |
5226 (1ull << MSR_FE1) |
5227 (1ull << MSR_IR) |
5228 (1ull << MSR_DR) |
5229 (1ull << MSR_PX) |
5230 (1ull << MSR_RI);
ba9fd9f1
AF
5231 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5232 pcc->excp_model = POWERPC_EXCP_BOOKE;
5233 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5234 /* FIXME: figure out the correct flag for e5500 */
5235 pcc->bfd_mach = bfd_mach_ppc_e500;
5236 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
5237 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4 5238}
54a50dae
KF
5239
5240static void init_proc_e6500(CPUPPCState *env)
5241{
5242 init_proc_e500(env, fsl_e6500);
5243}
5244
5245POWERPC_FAMILY(e6500)(ObjectClass *oc, void *data)
5246{
5247 DeviceClass *dc = DEVICE_CLASS(oc);
5248 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5249
5250 dc->desc = "e6500 core";
5251 pcc->init_proc = init_proc_e6500;
5252 pcc->check_pow = check_pow_none;
5253 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
5254 PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
5255 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5256 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5257 PPC_FLOAT | PPC_FLOAT_FRES |
5258 PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
5259 PPC_FLOAT_STFIWX | PPC_WAIT |
5260 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC |
5261 PPC_64B | PPC_POPCNTB | PPC_POPCNTWD | PPC_ALTIVEC;
78ee6bd0 5262 pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL | PPC2_PERM_ISA206 |
54a50dae
KF
5263 PPC2_FP_CVT_S64 | PPC2_ATOMIC_ISA206;
5264 pcc->msr_mask = (1ull << MSR_CM) |
5265 (1ull << MSR_GS) |
5266 (1ull << MSR_UCLE) |
5267 (1ull << MSR_CE) |
5268 (1ull << MSR_EE) |
5269 (1ull << MSR_PR) |
5270 (1ull << MSR_FP) |
5271 (1ull << MSR_ME) |
5272 (1ull << MSR_FE0) |
5273 (1ull << MSR_DE) |
5274 (1ull << MSR_FE1) |
5275 (1ull << MSR_IS) |
5276 (1ull << MSR_DS) |
5277 (1ull << MSR_PX) |
5278 (1ull << MSR_RI) |
5279 (1ull << MSR_VR);
5280 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5281 pcc->excp_model = POWERPC_EXCP_BOOKE;
5282 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5283 pcc->bfd_mach = bfd_mach_ppc_e500;
5284 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
5285 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_VRE;
5286}
5287
b81ccf8a
AG
5288#endif
5289
a750fc0b 5290/* Non-embedded PowerPC */
a750fc0b 5291
082c6681 5292#define POWERPC_MSRR_601 (0x0000000000001040ULL)
a750fc0b 5293
c364946d 5294static void init_proc_601(CPUPPCState *env)
3fc6c082 5295{
a750fc0b 5296 gen_spr_ne_601(env);
4f4f28ff 5297 gen_spr_sdr1(env);
a750fc0b
JM
5298 gen_spr_601(env);
5299 /* Hardware implementation registers */
5300 /* XXX : not implemented */
5301 spr_register(env, SPR_HID0, "HID0",
5302 SPR_NOACCESS, SPR_NOACCESS,
056401ea 5303 &spr_read_generic, &spr_write_hid0_601,
faadf50e 5304 0x80010080);
a750fc0b
JM
5305 /* XXX : not implemented */
5306 spr_register(env, SPR_HID1, "HID1",
5307 SPR_NOACCESS, SPR_NOACCESS,
5308 &spr_read_generic, &spr_write_generic,
5309 0x00000000);
5310 /* XXX : not implemented */
5311 spr_register(env, SPR_601_HID2, "HID2",
5312 SPR_NOACCESS, SPR_NOACCESS,
5313 &spr_read_generic, &spr_write_generic,
5314 0x00000000);
5315 /* XXX : not implemented */
5316 spr_register(env, SPR_601_HID5, "HID5",
5317 SPR_NOACCESS, SPR_NOACCESS,
5318 &spr_read_generic, &spr_write_generic,
5319 0x00000000);
a750fc0b 5320 /* Memory management */
e1833e1f 5321 init_excp_601(env);
1d28b5f6
DG
5322 /*
5323 * XXX: beware that dcache line size is 64
082c6681
JM
5324 * but dcbz uses 32 bytes "sectors"
5325 * XXX: this breaks clcs instruction !
5326 */
5327 env->dcache_line_size = 32;
d63001d1 5328 env->icache_line_size = 64;
faadf50e 5329 /* Allocate hardware IRQ controller */
db70b311 5330 ppc6xx_irq_init(env_archcpu(env));
3fc6c082
FB
5331}
5332
7856e3a4
AF
5333POWERPC_FAMILY(601)(ObjectClass *oc, void *data)
5334{
ca5dff0a 5335 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5336 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5337
ca5dff0a 5338 dc->desc = "PowerPC 601";
7856e3a4
AF
5339 pcc->init_proc = init_proc_601;
5340 pcc->check_pow = check_pow_none;
53116ebf
AF
5341 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
5342 PPC_FLOAT |
5343 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5344 PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
5345 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
5346 pcc->msr_mask = (1ull << MSR_EE) |
5347 (1ull << MSR_PR) |
5348 (1ull << MSR_FP) |
5349 (1ull << MSR_ME) |
5350 (1ull << MSR_FE0) |
5351 (1ull << MSR_SE) |
5352 (1ull << MSR_FE1) |
5353 (1ull << MSR_EP) |
5354 (1ull << MSR_IR) |
5355 (1ull << MSR_DR);
ba9fd9f1 5356 pcc->mmu_model = POWERPC_MMU_601;
b632a148
DG
5357#if defined(CONFIG_SOFTMMU)
5358 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5359#endif
ba9fd9f1
AF
5360 pcc->excp_model = POWERPC_EXCP_601;
5361 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5362 pcc->bfd_mach = bfd_mach_ppc_601;
5363 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK;
7856e3a4
AF
5364}
5365
082c6681 5366#define POWERPC_MSRR_601v (0x0000000000001040ULL)
082c6681 5367
c364946d 5368static void init_proc_601v(CPUPPCState *env)
082c6681
JM
5369{
5370 init_proc_601(env);
5371 /* XXX : not implemented */
5372 spr_register(env, SPR_601_HID15, "HID15",
5373 SPR_NOACCESS, SPR_NOACCESS,
5374 &spr_read_generic, &spr_write_generic,
5375 0x00000000);
5376}
5377
7856e3a4
AF
5378POWERPC_FAMILY(601v)(ObjectClass *oc, void *data)
5379{
ca5dff0a 5380 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5381 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5382
ca5dff0a 5383 dc->desc = "PowerPC 601v";
7856e3a4
AF
5384 pcc->init_proc = init_proc_601v;
5385 pcc->check_pow = check_pow_none;
53116ebf
AF
5386 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
5387 PPC_FLOAT |
5388 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5389 PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
5390 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
5391 pcc->msr_mask = (1ull << MSR_EE) |
5392 (1ull << MSR_PR) |
5393 (1ull << MSR_FP) |
5394 (1ull << MSR_ME) |
5395 (1ull << MSR_FE0) |
5396 (1ull << MSR_SE) |
5397 (1ull << MSR_FE1) |
5398 (1ull << MSR_EP) |
5399 (1ull << MSR_IR) |
5400 (1ull << MSR_DR);
ba9fd9f1 5401 pcc->mmu_model = POWERPC_MMU_601;
b632a148
DG
5402#if defined(CONFIG_SOFTMMU)
5403 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5404#endif
ba9fd9f1
AF
5405 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5406 pcc->bfd_mach = bfd_mach_ppc_601;
5407 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK;
7856e3a4
AF
5408}
5409
c364946d 5410static void init_proc_602(CPUPPCState *env)
3fc6c082 5411{
a750fc0b 5412 gen_spr_ne_601(env);
4f4f28ff 5413 gen_spr_sdr1(env);
a750fc0b
JM
5414 gen_spr_602(env);
5415 /* Time base */
5416 gen_tbl(env);
5417 /* hardware implementation registers */
5418 /* XXX : not implemented */
5419 spr_register(env, SPR_HID0, "HID0",
5420 SPR_NOACCESS, SPR_NOACCESS,
5421 &spr_read_generic, &spr_write_generic,
5422 0x00000000);
5423 /* XXX : not implemented */
5424 spr_register(env, SPR_HID1, "HID1",
5425 SPR_NOACCESS, SPR_NOACCESS,
5426 &spr_read_generic, &spr_write_generic,
5427 0x00000000);
5428 /* Memory management */
5429 gen_low_BATs(env);
5430 gen_6xx_7xx_soft_tlb(env, 64, 2);
e1833e1f 5431 init_excp_602(env);
d63001d1
JM
5432 env->dcache_line_size = 32;
5433 env->icache_line_size = 32;
a750fc0b 5434 /* Allocate hardware IRQ controller */
db70b311 5435 ppc6xx_irq_init(env_archcpu(env));
a750fc0b 5436}
3fc6c082 5437
7856e3a4
AF
5438POWERPC_FAMILY(602)(ObjectClass *oc, void *data)
5439{
ca5dff0a 5440 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5441 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5442
ca5dff0a 5443 dc->desc = "PowerPC 602";
7856e3a4
AF
5444 pcc->init_proc = init_proc_602;
5445 pcc->check_pow = check_pow_hid0;
53116ebf
AF
5446 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5447 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5448 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5449 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5450 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5451 PPC_MEM_TLBIE | PPC_6xx_TLB | PPC_MEM_TLBSYNC |
5452 PPC_SEGMENT | PPC_602_SPEC;
9df5a466
TM
5453 pcc->msr_mask = (1ull << MSR_VSX) |
5454 (1ull << MSR_SA) |
5455 (1ull << MSR_POW) |
5456 (1ull << MSR_TGPR) |
5457 (1ull << MSR_ILE) |
5458 (1ull << MSR_EE) |
5459 (1ull << MSR_PR) |
5460 (1ull << MSR_FP) |
5461 (1ull << MSR_ME) |
5462 (1ull << MSR_FE0) |
5463 (1ull << MSR_SE) |
5464 (1ull << MSR_DE) |
5465 (1ull << MSR_FE1) |
5466 (1ull << MSR_EP) |
5467 (1ull << MSR_IR) |
5468 (1ull << MSR_DR) |
5469 (1ull << MSR_RI) |
5470 (1ull << MSR_LE);
ba9fd9f1
AF
5471 /* XXX: 602 MMU is quite specific. Should add a special case */
5472 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
5473 pcc->excp_model = POWERPC_EXCP_602;
5474 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5475 pcc->bfd_mach = bfd_mach_ppc_602;
5476 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
5477 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5478}
5479
c364946d 5480static void init_proc_603(CPUPPCState *env)
a750fc0b
JM
5481{
5482 gen_spr_ne_601(env);
4f4f28ff 5483 gen_spr_sdr1(env);
a750fc0b
JM
5484 gen_spr_603(env);
5485 /* Time base */
5486 gen_tbl(env);
5487 /* hardware implementation registers */
5488 /* XXX : not implemented */
5489 spr_register(env, SPR_HID0, "HID0",
5490 SPR_NOACCESS, SPR_NOACCESS,
5491 &spr_read_generic, &spr_write_generic,
5492 0x00000000);
5493 /* XXX : not implemented */
5494 spr_register(env, SPR_HID1, "HID1",
5495 SPR_NOACCESS, SPR_NOACCESS,
5496 &spr_read_generic, &spr_write_generic,
5497 0x00000000);
5498 /* Memory management */
5499 gen_low_BATs(env);
5500 gen_6xx_7xx_soft_tlb(env, 64, 2);
e1833e1f 5501 init_excp_603(env);
d63001d1
JM
5502 env->dcache_line_size = 32;
5503 env->icache_line_size = 32;
a750fc0b 5504 /* Allocate hardware IRQ controller */
db70b311 5505 ppc6xx_irq_init(env_archcpu(env));
3fc6c082
FB
5506}
5507
7856e3a4
AF
5508POWERPC_FAMILY(603)(ObjectClass *oc, void *data)
5509{
ca5dff0a 5510 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5511 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5512
ca5dff0a 5513 dc->desc = "PowerPC 603";
7856e3a4
AF
5514 pcc->init_proc = init_proc_603;
5515 pcc->check_pow = check_pow_hid0;
53116ebf
AF
5516 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5517 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5518 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5519 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5520 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5521 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
5522 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
5523 pcc->msr_mask = (1ull << MSR_POW) |
5524 (1ull << MSR_TGPR) |
5525 (1ull << MSR_ILE) |
5526 (1ull << MSR_EE) |
5527 (1ull << MSR_PR) |
5528 (1ull << MSR_FP) |
5529 (1ull << MSR_ME) |
5530 (1ull << MSR_FE0) |
5531 (1ull << MSR_SE) |
5532 (1ull << MSR_DE) |
5533 (1ull << MSR_FE1) |
5534 (1ull << MSR_EP) |
5535 (1ull << MSR_IR) |
5536 (1ull << MSR_DR) |
5537 (1ull << MSR_RI) |
5538 (1ull << MSR_LE);
ba9fd9f1
AF
5539 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
5540 pcc->excp_model = POWERPC_EXCP_603;
5541 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5542 pcc->bfd_mach = bfd_mach_ppc_603;
5543 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
5544 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5545}
5546
c364946d 5547static void init_proc_603E(CPUPPCState *env)
a750fc0b
JM
5548{
5549 gen_spr_ne_601(env);
4f4f28ff 5550 gen_spr_sdr1(env);
a750fc0b
JM
5551 gen_spr_603(env);
5552 /* Time base */
5553 gen_tbl(env);
5554 /* hardware implementation registers */
5555 /* XXX : not implemented */
5556 spr_register(env, SPR_HID0, "HID0",
5557 SPR_NOACCESS, SPR_NOACCESS,
5558 &spr_read_generic, &spr_write_generic,
5559 0x00000000);
5560 /* XXX : not implemented */
5561 spr_register(env, SPR_HID1, "HID1",
5562 SPR_NOACCESS, SPR_NOACCESS,
5563 &spr_read_generic, &spr_write_generic,
5564 0x00000000);
a750fc0b
JM
5565 /* Memory management */
5566 gen_low_BATs(env);
5567 gen_6xx_7xx_soft_tlb(env, 64, 2);
e1833e1f 5568 init_excp_603(env);
d63001d1
JM
5569 env->dcache_line_size = 32;
5570 env->icache_line_size = 32;
a750fc0b 5571 /* Allocate hardware IRQ controller */
db70b311 5572 ppc6xx_irq_init(env_archcpu(env));
a750fc0b
JM
5573}
5574
7856e3a4
AF
5575POWERPC_FAMILY(603E)(ObjectClass *oc, void *data)
5576{
ca5dff0a 5577 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5578 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5579
ca5dff0a 5580 dc->desc = "PowerPC 603e";
7856e3a4
AF
5581 pcc->init_proc = init_proc_603E;
5582 pcc->check_pow = check_pow_hid0;
53116ebf
AF
5583 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5584 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5585 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5586 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5587 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5588 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
5589 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
5590 pcc->msr_mask = (1ull << MSR_POW) |
5591 (1ull << MSR_TGPR) |
5592 (1ull << MSR_ILE) |
5593 (1ull << MSR_EE) |
5594 (1ull << MSR_PR) |
5595 (1ull << MSR_FP) |
5596 (1ull << MSR_ME) |
5597 (1ull << MSR_FE0) |
5598 (1ull << MSR_SE) |
5599 (1ull << MSR_DE) |
5600 (1ull << MSR_FE1) |
5601 (1ull << MSR_EP) |
5602 (1ull << MSR_IR) |
5603 (1ull << MSR_DR) |
5604 (1ull << MSR_RI) |
5605 (1ull << MSR_LE);
ba9fd9f1
AF
5606 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
5607 pcc->excp_model = POWERPC_EXCP_603E;
5608 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5609 pcc->bfd_mach = bfd_mach_ppc_ec603e;
5610 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
5611 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5612}
5613
c364946d 5614static void init_proc_604(CPUPPCState *env)
a750fc0b
JM
5615{
5616 gen_spr_ne_601(env);
4f4f28ff 5617 gen_spr_sdr1(env);
a750fc0b
JM
5618 gen_spr_604(env);
5619 /* Time base */
5620 gen_tbl(env);
5621 /* Hardware implementation registers */
5622 /* XXX : not implemented */
082c6681
JM
5623 spr_register(env, SPR_HID0, "HID0",
5624 SPR_NOACCESS, SPR_NOACCESS,
5625 &spr_read_generic, &spr_write_generic,
5626 0x00000000);
5627 /* Memory management */
5628 gen_low_BATs(env);
5629 init_excp_604(env);
5630 env->dcache_line_size = 32;
5631 env->icache_line_size = 32;
5632 /* Allocate hardware IRQ controller */
db70b311 5633 ppc6xx_irq_init(env_archcpu(env));
082c6681
JM
5634}
5635
7856e3a4
AF
5636POWERPC_FAMILY(604)(ObjectClass *oc, void *data)
5637{
ca5dff0a 5638 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5639 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5640
ca5dff0a 5641 dc->desc = "PowerPC 604";
7856e3a4
AF
5642 pcc->init_proc = init_proc_604;
5643 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
5644 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5645 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5646 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5647 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5648 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5649 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5650 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
5651 pcc->msr_mask = (1ull << MSR_POW) |
5652 (1ull << MSR_ILE) |
5653 (1ull << MSR_EE) |
5654 (1ull << MSR_PR) |
5655 (1ull << MSR_FP) |
5656 (1ull << MSR_ME) |
5657 (1ull << MSR_FE0) |
5658 (1ull << MSR_SE) |
5659 (1ull << MSR_DE) |
5660 (1ull << MSR_FE1) |
5661 (1ull << MSR_EP) |
5662 (1ull << MSR_IR) |
5663 (1ull << MSR_DR) |
5664 (1ull << MSR_PMM) |
5665 (1ull << MSR_RI) |
5666 (1ull << MSR_LE);
ba9fd9f1 5667 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
5668#if defined(CONFIG_SOFTMMU)
5669 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5670#endif
ba9fd9f1
AF
5671 pcc->excp_model = POWERPC_EXCP_604;
5672 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5673 pcc->bfd_mach = bfd_mach_ppc_604;
5674 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5675 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5676}
5677
c364946d 5678static void init_proc_604E(CPUPPCState *env)
082c6681
JM
5679{
5680 gen_spr_ne_601(env);
4f4f28ff 5681 gen_spr_sdr1(env);
082c6681
JM
5682 gen_spr_604(env);
5683 /* XXX : not implemented */
cb8b8bf8 5684 spr_register(env, SPR_7XX_MMCR1, "MMCR1",
082c6681
JM
5685 SPR_NOACCESS, SPR_NOACCESS,
5686 &spr_read_generic, &spr_write_generic,
5687 0x00000000);
5688 /* XXX : not implemented */
cb8b8bf8 5689 spr_register(env, SPR_7XX_PMC3, "PMC3",
082c6681
JM
5690 SPR_NOACCESS, SPR_NOACCESS,
5691 &spr_read_generic, &spr_write_generic,
5692 0x00000000);
5693 /* XXX : not implemented */
cb8b8bf8 5694 spr_register(env, SPR_7XX_PMC4, "PMC4",
082c6681
JM
5695 SPR_NOACCESS, SPR_NOACCESS,
5696 &spr_read_generic, &spr_write_generic,
5697 0x00000000);
5698 /* Time base */
5699 gen_tbl(env);
5700 /* Hardware implementation registers */
5701 /* XXX : not implemented */
a750fc0b
JM
5702 spr_register(env, SPR_HID0, "HID0",
5703 SPR_NOACCESS, SPR_NOACCESS,
5704 &spr_read_generic, &spr_write_generic,
5705 0x00000000);
5706 /* XXX : not implemented */
5707 spr_register(env, SPR_HID1, "HID1",
5708 SPR_NOACCESS, SPR_NOACCESS,
5709 &spr_read_generic, &spr_write_generic,
5710 0x00000000);
5711 /* Memory management */
5712 gen_low_BATs(env);
e1833e1f 5713 init_excp_604(env);
d63001d1
JM
5714 env->dcache_line_size = 32;
5715 env->icache_line_size = 32;
a750fc0b 5716 /* Allocate hardware IRQ controller */
db70b311 5717 ppc6xx_irq_init(env_archcpu(env));
a750fc0b
JM
5718}
5719
7856e3a4
AF
5720POWERPC_FAMILY(604E)(ObjectClass *oc, void *data)
5721{
ca5dff0a 5722 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5723 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5724
ca5dff0a 5725 dc->desc = "PowerPC 604E";
7856e3a4
AF
5726 pcc->init_proc = init_proc_604E;
5727 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
5728 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5729 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5730 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5731 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5732 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5733 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5734 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
5735 pcc->msr_mask = (1ull << MSR_POW) |
5736 (1ull << MSR_ILE) |
5737 (1ull << MSR_EE) |
5738 (1ull << MSR_PR) |
5739 (1ull << MSR_FP) |
5740 (1ull << MSR_ME) |
5741 (1ull << MSR_FE0) |
5742 (1ull << MSR_SE) |
5743 (1ull << MSR_DE) |
5744 (1ull << MSR_FE1) |
5745 (1ull << MSR_EP) |
5746 (1ull << MSR_IR) |
5747 (1ull << MSR_DR) |
5748 (1ull << MSR_PMM) |
5749 (1ull << MSR_RI) |
5750 (1ull << MSR_LE);
ba9fd9f1 5751 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
5752#if defined(CONFIG_SOFTMMU)
5753 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5754#endif
ba9fd9f1
AF
5755 pcc->excp_model = POWERPC_EXCP_604;
5756 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5757 pcc->bfd_mach = bfd_mach_ppc_604;
5758 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5759 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5760}
5761
c364946d 5762static void init_proc_740(CPUPPCState *env)
a750fc0b
JM
5763{
5764 gen_spr_ne_601(env);
4f4f28ff 5765 gen_spr_sdr1(env);
a750fc0b
JM
5766 gen_spr_7xx(env);
5767 /* Time base */
5768 gen_tbl(env);
5769 /* Thermal management */
5770 gen_spr_thrm(env);
5771 /* Hardware implementation registers */
5772 /* XXX : not implemented */
5773 spr_register(env, SPR_HID0, "HID0",
5774 SPR_NOACCESS, SPR_NOACCESS,
5775 &spr_read_generic, &spr_write_generic,
5776 0x00000000);
5777 /* XXX : not implemented */
5778 spr_register(env, SPR_HID1, "HID1",
5779 SPR_NOACCESS, SPR_NOACCESS,
5780 &spr_read_generic, &spr_write_generic,
5781 0x00000000);
5782 /* Memory management */
5783 gen_low_BATs(env);
e1833e1f 5784 init_excp_7x0(env);
d63001d1
JM
5785 env->dcache_line_size = 32;
5786 env->icache_line_size = 32;
a750fc0b 5787 /* Allocate hardware IRQ controller */
db70b311 5788 ppc6xx_irq_init(env_archcpu(env));
a750fc0b
JM
5789}
5790
7856e3a4
AF
5791POWERPC_FAMILY(740)(ObjectClass *oc, void *data)
5792{
ca5dff0a 5793 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5794 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5795
ca5dff0a 5796 dc->desc = "PowerPC 740";
7856e3a4
AF
5797 pcc->init_proc = init_proc_740;
5798 pcc->check_pow = check_pow_hid0;
53116ebf
AF
5799 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5800 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5801 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5802 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5803 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5804 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5805 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
5806 pcc->msr_mask = (1ull << MSR_POW) |
5807 (1ull << MSR_ILE) |
5808 (1ull << MSR_EE) |
5809 (1ull << MSR_PR) |
5810 (1ull << MSR_FP) |
5811 (1ull << MSR_ME) |
5812 (1ull << MSR_FE0) |
5813 (1ull << MSR_SE) |
5814 (1ull << MSR_DE) |
5815 (1ull << MSR_FE1) |
5816 (1ull << MSR_EP) |
5817 (1ull << MSR_IR) |
5818 (1ull << MSR_DR) |
5819 (1ull << MSR_PMM) |
5820 (1ull << MSR_RI) |
5821 (1ull << MSR_LE);
ba9fd9f1 5822 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
5823#if defined(CONFIG_SOFTMMU)
5824 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5825#endif
ba9fd9f1
AF
5826 pcc->excp_model = POWERPC_EXCP_7x0;
5827 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5828 pcc->bfd_mach = bfd_mach_ppc_750;
5829 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5830 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5831}
5832
c364946d 5833static void init_proc_750(CPUPPCState *env)
bd928eba
JM
5834{
5835 gen_spr_ne_601(env);
4f4f28ff 5836 gen_spr_sdr1(env);
bd928eba
JM
5837 gen_spr_7xx(env);
5838 /* XXX : not implemented */
5839 spr_register(env, SPR_L2CR, "L2CR",
5840 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 5841 &spr_read_generic, spr_access_nop,
bd928eba
JM
5842 0x00000000);
5843 /* Time base */
5844 gen_tbl(env);
5845 /* Thermal management */
5846 gen_spr_thrm(env);
5847 /* Hardware implementation registers */
5848 /* XXX : not implemented */
5849 spr_register(env, SPR_HID0, "HID0",
5850 SPR_NOACCESS, SPR_NOACCESS,
5851 &spr_read_generic, &spr_write_generic,
5852 0x00000000);
5853 /* XXX : not implemented */
5854 spr_register(env, SPR_HID1, "HID1",
5855 SPR_NOACCESS, SPR_NOACCESS,
5856 &spr_read_generic, &spr_write_generic,
5857 0x00000000);
5858 /* Memory management */
5859 gen_low_BATs(env);
1d28b5f6
DG
5860 /*
5861 * XXX: high BATs are also present but are known to be bugged on
bd928eba
JM
5862 * die version 1.x
5863 */
5864 init_excp_7x0(env);
5865 env->dcache_line_size = 32;
5866 env->icache_line_size = 32;
5867 /* Allocate hardware IRQ controller */
db70b311 5868 ppc6xx_irq_init(env_archcpu(env));
bd928eba
JM
5869}
5870
7856e3a4
AF
5871POWERPC_FAMILY(750)(ObjectClass *oc, void *data)
5872{
ca5dff0a 5873 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5874 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5875
ca5dff0a 5876 dc->desc = "PowerPC 750";
7856e3a4
AF
5877 pcc->init_proc = init_proc_750;
5878 pcc->check_pow = check_pow_hid0;
53116ebf
AF
5879 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5880 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5881 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5882 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5883 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5884 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5885 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
5886 pcc->msr_mask = (1ull << MSR_POW) |
5887 (1ull << MSR_ILE) |
5888 (1ull << MSR_EE) |
5889 (1ull << MSR_PR) |
5890 (1ull << MSR_FP) |
5891 (1ull << MSR_ME) |
5892 (1ull << MSR_FE0) |
5893 (1ull << MSR_SE) |
5894 (1ull << MSR_DE) |
5895 (1ull << MSR_FE1) |
5896 (1ull << MSR_EP) |
5897 (1ull << MSR_IR) |
5898 (1ull << MSR_DR) |
5899 (1ull << MSR_PMM) |
5900 (1ull << MSR_RI) |
5901 (1ull << MSR_LE);
ba9fd9f1 5902 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
5903#if defined(CONFIG_SOFTMMU)
5904 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5905#endif
ba9fd9f1
AF
5906 pcc->excp_model = POWERPC_EXCP_7x0;
5907 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5908 pcc->bfd_mach = bfd_mach_ppc_750;
5909 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5910 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5911}
5912
c364946d 5913static void init_proc_750cl(CPUPPCState *env)
bd928eba
JM
5914{
5915 gen_spr_ne_601(env);
4f4f28ff 5916 gen_spr_sdr1(env);
bd928eba
JM
5917 gen_spr_7xx(env);
5918 /* XXX : not implemented */
5919 spr_register(env, SPR_L2CR, "L2CR",
5920 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 5921 &spr_read_generic, spr_access_nop,
bd928eba
JM
5922 0x00000000);
5923 /* Time base */
5924 gen_tbl(env);
5925 /* Thermal management */
5926 /* Those registers are fake on 750CL */
5927 spr_register(env, SPR_THRM1, "THRM1",
5928 SPR_NOACCESS, SPR_NOACCESS,
5929 &spr_read_generic, &spr_write_generic,
5930 0x00000000);
5931 spr_register(env, SPR_THRM2, "THRM2",
5932 SPR_NOACCESS, SPR_NOACCESS,
5933 &spr_read_generic, &spr_write_generic,
5934 0x00000000);
5935 spr_register(env, SPR_THRM3, "THRM3",
5936 SPR_NOACCESS, SPR_NOACCESS,
5937 &spr_read_generic, &spr_write_generic,
5938 0x00000000);
5939 /* XXX: not implemented */
5940 spr_register(env, SPR_750_TDCL, "TDCL",
5941 SPR_NOACCESS, SPR_NOACCESS,
5942 &spr_read_generic, &spr_write_generic,
5943 0x00000000);
5944 spr_register(env, SPR_750_TDCH, "TDCH",
5945 SPR_NOACCESS, SPR_NOACCESS,
5946 &spr_read_generic, &spr_write_generic,
5947 0x00000000);
5948 /* DMA */
5949 /* XXX : not implemented */
5950 spr_register(env, SPR_750_WPAR, "WPAR",
5951 SPR_NOACCESS, SPR_NOACCESS,
5952 &spr_read_generic, &spr_write_generic,
5953 0x00000000);
5954 spr_register(env, SPR_750_DMAL, "DMAL",
5955 SPR_NOACCESS, SPR_NOACCESS,
5956 &spr_read_generic, &spr_write_generic,
5957 0x00000000);
5958 spr_register(env, SPR_750_DMAU, "DMAU",
5959 SPR_NOACCESS, SPR_NOACCESS,
5960 &spr_read_generic, &spr_write_generic,
5961 0x00000000);
5962 /* Hardware implementation registers */
5963 /* XXX : not implemented */
5964 spr_register(env, SPR_HID0, "HID0",
5965 SPR_NOACCESS, SPR_NOACCESS,
5966 &spr_read_generic, &spr_write_generic,
5967 0x00000000);
5968 /* XXX : not implemented */
5969 spr_register(env, SPR_HID1, "HID1",
5970 SPR_NOACCESS, SPR_NOACCESS,
5971 &spr_read_generic, &spr_write_generic,
5972 0x00000000);
5973 /* XXX : not implemented */
5974 spr_register(env, SPR_750CL_HID2, "HID2",
5975 SPR_NOACCESS, SPR_NOACCESS,
5976 &spr_read_generic, &spr_write_generic,
5977 0x00000000);
5978 /* XXX : not implemented */
5979 spr_register(env, SPR_750CL_HID4, "HID4",
5980 SPR_NOACCESS, SPR_NOACCESS,
5981 &spr_read_generic, &spr_write_generic,
5982 0x00000000);
5983 /* Quantization registers */
5984 /* XXX : not implemented */
5985 spr_register(env, SPR_750_GQR0, "GQR0",
5986 SPR_NOACCESS, SPR_NOACCESS,
5987 &spr_read_generic, &spr_write_generic,
5988 0x00000000);
5989 /* XXX : not implemented */
5990 spr_register(env, SPR_750_GQR1, "GQR1",
5991 SPR_NOACCESS, SPR_NOACCESS,
5992 &spr_read_generic, &spr_write_generic,
5993 0x00000000);
5994 /* XXX : not implemented */
5995 spr_register(env, SPR_750_GQR2, "GQR2",
5996 SPR_NOACCESS, SPR_NOACCESS,
5997 &spr_read_generic, &spr_write_generic,
5998 0x00000000);
5999 /* XXX : not implemented */
6000 spr_register(env, SPR_750_GQR3, "GQR3",
6001 SPR_NOACCESS, SPR_NOACCESS,
6002 &spr_read_generic, &spr_write_generic,
6003 0x00000000);
6004 /* XXX : not implemented */
6005 spr_register(env, SPR_750_GQR4, "GQR4",
6006 SPR_NOACCESS, SPR_NOACCESS,
6007 &spr_read_generic, &spr_write_generic,
6008 0x00000000);
6009 /* XXX : not implemented */
6010 spr_register(env, SPR_750_GQR5, "GQR5",
6011 SPR_NOACCESS, SPR_NOACCESS,
6012 &spr_read_generic, &spr_write_generic,
6013 0x00000000);
6014 /* XXX : not implemented */
6015 spr_register(env, SPR_750_GQR6, "GQR6",
6016 SPR_NOACCESS, SPR_NOACCESS,
6017 &spr_read_generic, &spr_write_generic,
6018 0x00000000);
6019 /* XXX : not implemented */
6020 spr_register(env, SPR_750_GQR7, "GQR7",
6021 SPR_NOACCESS, SPR_NOACCESS,
6022 &spr_read_generic, &spr_write_generic,
6023 0x00000000);
6024 /* Memory management */
6025 gen_low_BATs(env);
6026 /* PowerPC 750cl has 8 DBATs and 8 IBATs */
6027 gen_high_BATs(env);
6028 init_excp_750cl(env);
6029 env->dcache_line_size = 32;
6030 env->icache_line_size = 32;
6031 /* Allocate hardware IRQ controller */
db70b311 6032 ppc6xx_irq_init(env_archcpu(env));
bd928eba
JM
6033}
6034
7856e3a4
AF
6035POWERPC_FAMILY(750cl)(ObjectClass *oc, void *data)
6036{
ca5dff0a 6037 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6038 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6039
ca5dff0a 6040 dc->desc = "PowerPC 750 CL";
7856e3a4
AF
6041 pcc->init_proc = init_proc_750cl;
6042 pcc->check_pow = check_pow_hid0;
1d28b5f6
DG
6043 /*
6044 * XXX: not implemented:
53116ebf
AF
6045 * cache lock instructions:
6046 * dcbz_l
6047 * floating point paired instructions
6048 * psq_lux
6049 * psq_lx
6050 * psq_stux
6051 * psq_stx
6052 * ps_abs
6053 * ps_add
6054 * ps_cmpo0
6055 * ps_cmpo1
6056 * ps_cmpu0
6057 * ps_cmpu1
6058 * ps_div
6059 * ps_madd
6060 * ps_madds0
6061 * ps_madds1
6062 * ps_merge00
6063 * ps_merge01
6064 * ps_merge10
6065 * ps_merge11
6066 * ps_mr
6067 * ps_msub
6068 * ps_mul
6069 * ps_muls0
6070 * ps_muls1
6071 * ps_nabs
6072 * ps_neg
6073 * ps_nmadd
6074 * ps_nmsub
6075 * ps_res
6076 * ps_rsqrte
6077 * ps_sel
6078 * ps_sub
6079 * ps_sum0
6080 * ps_sum1
6081 */
6082 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6083 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6084 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6085 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6086 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6087 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6088 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
6089 pcc->msr_mask = (1ull << MSR_POW) |
6090 (1ull << MSR_ILE) |
6091 (1ull << MSR_EE) |
6092 (1ull << MSR_PR) |
6093 (1ull << MSR_FP) |
6094 (1ull << MSR_ME) |
6095 (1ull << MSR_FE0) |
6096 (1ull << MSR_SE) |
6097 (1ull << MSR_DE) |
6098 (1ull << MSR_FE1) |
6099 (1ull << MSR_EP) |
6100 (1ull << MSR_IR) |
6101 (1ull << MSR_DR) |
6102 (1ull << MSR_PMM) |
6103 (1ull << MSR_RI) |
6104 (1ull << MSR_LE);
ba9fd9f1 6105 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
6106#if defined(CONFIG_SOFTMMU)
6107 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6108#endif
ba9fd9f1
AF
6109 pcc->excp_model = POWERPC_EXCP_7x0;
6110 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6111 pcc->bfd_mach = bfd_mach_ppc_750;
6112 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6113 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6114}
6115
c364946d 6116static void init_proc_750cx(CPUPPCState *env)
bd928eba
JM
6117{
6118 gen_spr_ne_601(env);
4f4f28ff 6119 gen_spr_sdr1(env);
bd928eba
JM
6120 gen_spr_7xx(env);
6121 /* XXX : not implemented */
6122 spr_register(env, SPR_L2CR, "L2CR",
6123 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 6124 &spr_read_generic, spr_access_nop,
bd928eba
JM
6125 0x00000000);
6126 /* Time base */
6127 gen_tbl(env);
6128 /* Thermal management */
6129 gen_spr_thrm(env);
6130 /* This register is not implemented but is present for compatibility */
6131 spr_register(env, SPR_SDA, "SDA",
6132 SPR_NOACCESS, SPR_NOACCESS,
6133 &spr_read_generic, &spr_write_generic,
6134 0x00000000);
6135 /* Hardware implementation registers */
6136 /* XXX : not implemented */
6137 spr_register(env, SPR_HID0, "HID0",
6138 SPR_NOACCESS, SPR_NOACCESS,
6139 &spr_read_generic, &spr_write_generic,
6140 0x00000000);
6141 /* XXX : not implemented */
6142 spr_register(env, SPR_HID1, "HID1",
6143 SPR_NOACCESS, SPR_NOACCESS,
6144 &spr_read_generic, &spr_write_generic,
6145 0x00000000);
6146 /* Memory management */
6147 gen_low_BATs(env);
4e777442
JM
6148 /* PowerPC 750cx has 8 DBATs and 8 IBATs */
6149 gen_high_BATs(env);
bd928eba
JM
6150 init_excp_750cx(env);
6151 env->dcache_line_size = 32;
6152 env->icache_line_size = 32;
6153 /* Allocate hardware IRQ controller */
db70b311 6154 ppc6xx_irq_init(env_archcpu(env));
bd928eba
JM
6155}
6156
7856e3a4
AF
6157POWERPC_FAMILY(750cx)(ObjectClass *oc, void *data)
6158{
ca5dff0a 6159 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6160 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6161
ca5dff0a 6162 dc->desc = "PowerPC 750CX";
7856e3a4
AF
6163 pcc->init_proc = init_proc_750cx;
6164 pcc->check_pow = check_pow_hid0;
53116ebf
AF
6165 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6166 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6167 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6168 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6169 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6170 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6171 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
6172 pcc->msr_mask = (1ull << MSR_POW) |
6173 (1ull << MSR_ILE) |
6174 (1ull << MSR_EE) |
6175 (1ull << MSR_PR) |
6176 (1ull << MSR_FP) |
6177 (1ull << MSR_ME) |
6178 (1ull << MSR_FE0) |
6179 (1ull << MSR_SE) |
6180 (1ull << MSR_DE) |
6181 (1ull << MSR_FE1) |
6182 (1ull << MSR_EP) |
6183 (1ull << MSR_IR) |
6184 (1ull << MSR_DR) |
6185 (1ull << MSR_PMM) |
6186 (1ull << MSR_RI) |
6187 (1ull << MSR_LE);
ba9fd9f1 6188 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
6189#if defined(CONFIG_SOFTMMU)
6190 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6191#endif
ba9fd9f1
AF
6192 pcc->excp_model = POWERPC_EXCP_7x0;
6193 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6194 pcc->bfd_mach = bfd_mach_ppc_750;
6195 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6196 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6197}
6198
c364946d 6199static void init_proc_750fx(CPUPPCState *env)
a750fc0b
JM
6200{
6201 gen_spr_ne_601(env);
4f4f28ff 6202 gen_spr_sdr1(env);
a750fc0b 6203 gen_spr_7xx(env);
bd928eba
JM
6204 /* XXX : not implemented */
6205 spr_register(env, SPR_L2CR, "L2CR",
6206 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 6207 &spr_read_generic, spr_access_nop,
bd928eba 6208 0x00000000);
a750fc0b
JM
6209 /* Time base */
6210 gen_tbl(env);
6211 /* Thermal management */
6212 gen_spr_thrm(env);
bd928eba
JM
6213 /* XXX : not implemented */
6214 spr_register(env, SPR_750_THRM4, "THRM4",
6215 SPR_NOACCESS, SPR_NOACCESS,
6216 &spr_read_generic, &spr_write_generic,
6217 0x00000000);
a750fc0b
JM
6218 /* Hardware implementation registers */
6219 /* XXX : not implemented */
6220 spr_register(env, SPR_HID0, "HID0",
6221 SPR_NOACCESS, SPR_NOACCESS,
6222 &spr_read_generic, &spr_write_generic,
6223 0x00000000);
6224 /* XXX : not implemented */
6225 spr_register(env, SPR_HID1, "HID1",
6226 SPR_NOACCESS, SPR_NOACCESS,
6227 &spr_read_generic, &spr_write_generic,
6228 0x00000000);
6229 /* XXX : not implemented */
bd928eba 6230 spr_register(env, SPR_750FX_HID2, "HID2",
a750fc0b
JM
6231 SPR_NOACCESS, SPR_NOACCESS,
6232 &spr_read_generic, &spr_write_generic,
6233 0x00000000);
6234 /* Memory management */
6235 gen_low_BATs(env);
6236 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6237 gen_high_BATs(env);
bd928eba 6238 init_excp_7x0(env);
d63001d1
JM
6239 env->dcache_line_size = 32;
6240 env->icache_line_size = 32;
a750fc0b 6241 /* Allocate hardware IRQ controller */
db70b311 6242 ppc6xx_irq_init(env_archcpu(env));
a750fc0b
JM
6243}
6244
7856e3a4
AF
6245POWERPC_FAMILY(750fx)(ObjectClass *oc, void *data)
6246{
ca5dff0a 6247 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6248 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6249
ca5dff0a 6250 dc->desc = "PowerPC 750FX";
7856e3a4
AF
6251 pcc->init_proc = init_proc_750fx;
6252 pcc->check_pow = check_pow_hid0;
53116ebf
AF
6253 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6254 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6255 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6256 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6257 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6258 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6259 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
6260 pcc->msr_mask = (1ull << MSR_POW) |
6261 (1ull << MSR_ILE) |
6262 (1ull << MSR_EE) |
6263 (1ull << MSR_PR) |
6264 (1ull << MSR_FP) |
6265 (1ull << MSR_ME) |
6266 (1ull << MSR_FE0) |
6267 (1ull << MSR_SE) |
6268 (1ull << MSR_DE) |
6269 (1ull << MSR_FE1) |
6270 (1ull << MSR_EP) |
6271 (1ull << MSR_IR) |
6272 (1ull << MSR_DR) |
6273 (1ull << MSR_PMM) |
6274 (1ull << MSR_RI) |
6275 (1ull << MSR_LE);
ba9fd9f1 6276 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
6277#if defined(CONFIG_SOFTMMU)
6278 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6279#endif
ba9fd9f1
AF
6280 pcc->excp_model = POWERPC_EXCP_7x0;
6281 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6282 pcc->bfd_mach = bfd_mach_ppc_750;
6283 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6284 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6285}
6286
c364946d 6287static void init_proc_750gx(CPUPPCState *env)
bd928eba
JM
6288{
6289 gen_spr_ne_601(env);
4f4f28ff 6290 gen_spr_sdr1(env);
bd928eba
JM
6291 gen_spr_7xx(env);
6292 /* XXX : not implemented (XXX: different from 750fx) */
6293 spr_register(env, SPR_L2CR, "L2CR",
6294 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 6295 &spr_read_generic, spr_access_nop,
bd928eba
JM
6296 0x00000000);
6297 /* Time base */
6298 gen_tbl(env);
6299 /* Thermal management */
6300 gen_spr_thrm(env);
6301 /* XXX : not implemented */
6302 spr_register(env, SPR_750_THRM4, "THRM4",
6303 SPR_NOACCESS, SPR_NOACCESS,
6304 &spr_read_generic, &spr_write_generic,
6305 0x00000000);
6306 /* Hardware implementation registers */
6307 /* XXX : not implemented (XXX: different from 750fx) */
6308 spr_register(env, SPR_HID0, "HID0",
6309 SPR_NOACCESS, SPR_NOACCESS,
6310 &spr_read_generic, &spr_write_generic,
6311 0x00000000);
6312 /* XXX : not implemented */
6313 spr_register(env, SPR_HID1, "HID1",
6314 SPR_NOACCESS, SPR_NOACCESS,
6315 &spr_read_generic, &spr_write_generic,
6316 0x00000000);
6317 /* XXX : not implemented (XXX: different from 750fx) */
6318 spr_register(env, SPR_750FX_HID2, "HID2",
6319 SPR_NOACCESS, SPR_NOACCESS,
6320 &spr_read_generic, &spr_write_generic,
6321 0x00000000);
6322 /* Memory management */
6323 gen_low_BATs(env);
6324 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6325 gen_high_BATs(env);
6326 init_excp_7x0(env);
6327 env->dcache_line_size = 32;
6328 env->icache_line_size = 32;
6329 /* Allocate hardware IRQ controller */
db70b311 6330 ppc6xx_irq_init(env_archcpu(env));
bd928eba
JM
6331}
6332
7856e3a4
AF
6333POWERPC_FAMILY(750gx)(ObjectClass *oc, void *data)
6334{
ca5dff0a 6335 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6336 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6337
ca5dff0a 6338 dc->desc = "PowerPC 750GX";
7856e3a4
AF
6339 pcc->init_proc = init_proc_750gx;
6340 pcc->check_pow = check_pow_hid0;
53116ebf
AF
6341 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6342 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6343 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6344 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6345 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6346 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6347 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
6348 pcc->msr_mask = (1ull << MSR_POW) |
6349 (1ull << MSR_ILE) |
6350 (1ull << MSR_EE) |
6351 (1ull << MSR_PR) |
6352 (1ull << MSR_FP) |
6353 (1ull << MSR_ME) |
6354 (1ull << MSR_FE0) |
6355 (1ull << MSR_SE) |
6356 (1ull << MSR_DE) |
6357 (1ull << MSR_FE1) |
6358 (1ull << MSR_EP) |
6359 (1ull << MSR_IR) |
6360 (1ull << MSR_DR) |
6361 (1ull << MSR_PMM) |
6362 (1ull << MSR_RI) |
6363 (1ull << MSR_LE);
ba9fd9f1 6364 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
6365#if defined(CONFIG_SOFTMMU)
6366 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6367#endif
ba9fd9f1
AF
6368 pcc->excp_model = POWERPC_EXCP_7x0;
6369 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6370 pcc->bfd_mach = bfd_mach_ppc_750;
6371 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6372 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6373}
6374
c364946d 6375static void init_proc_745(CPUPPCState *env)
bd928eba
JM
6376{
6377 gen_spr_ne_601(env);
4f4f28ff 6378 gen_spr_sdr1(env);
bd928eba
JM
6379 gen_spr_7xx(env);
6380 gen_spr_G2_755(env);
6381 /* Time base */
6382 gen_tbl(env);
6383 /* Thermal management */
6384 gen_spr_thrm(env);
6385 /* Hardware implementation registers */
6386 /* XXX : not implemented */
6387 spr_register(env, SPR_HID0, "HID0",
6388 SPR_NOACCESS, SPR_NOACCESS,
6389 &spr_read_generic, &spr_write_generic,
6390 0x00000000);
6391 /* XXX : not implemented */
6392 spr_register(env, SPR_HID1, "HID1",
6393 SPR_NOACCESS, SPR_NOACCESS,
6394 &spr_read_generic, &spr_write_generic,
6395 0x00000000);
6396 /* XXX : not implemented */
6397 spr_register(env, SPR_HID2, "HID2",
6398 SPR_NOACCESS, SPR_NOACCESS,
6399 &spr_read_generic, &spr_write_generic,
6400 0x00000000);
6401 /* Memory management */
6402 gen_low_BATs(env);
6403 gen_high_BATs(env);
6404 gen_6xx_7xx_soft_tlb(env, 64, 2);
6405 init_excp_7x5(env);
6406 env->dcache_line_size = 32;
6407 env->icache_line_size = 32;
6408 /* Allocate hardware IRQ controller */
db70b311 6409 ppc6xx_irq_init(env_archcpu(env));
bd928eba
JM
6410}
6411
7856e3a4
AF
6412POWERPC_FAMILY(745)(ObjectClass *oc, void *data)
6413{
ca5dff0a 6414 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6415 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6416
ca5dff0a 6417 dc->desc = "PowerPC 745";
7856e3a4
AF
6418 pcc->init_proc = init_proc_745;
6419 pcc->check_pow = check_pow_hid0;
53116ebf
AF
6420 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6421 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6422 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6423 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6424 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6425 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
6426 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
6427 pcc->msr_mask = (1ull << MSR_POW) |
6428 (1ull << MSR_ILE) |
6429 (1ull << MSR_EE) |
6430 (1ull << MSR_PR) |
6431 (1ull << MSR_FP) |
6432 (1ull << MSR_ME) |
6433 (1ull << MSR_FE0) |
6434 (1ull << MSR_SE) |
6435 (1ull << MSR_DE) |
6436 (1ull << MSR_FE1) |
6437 (1ull << MSR_EP) |
6438 (1ull << MSR_IR) |
6439 (1ull << MSR_DR) |
6440 (1ull << MSR_PMM) |
6441 (1ull << MSR_RI) |
6442 (1ull << MSR_LE);
ba9fd9f1
AF
6443 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
6444 pcc->excp_model = POWERPC_EXCP_7x5;
6445 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6446 pcc->bfd_mach = bfd_mach_ppc_750;
6447 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6448 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6449}
6450
c364946d 6451static void init_proc_755(CPUPPCState *env)
a750fc0b
JM
6452{
6453 gen_spr_ne_601(env);
4f4f28ff 6454 gen_spr_sdr1(env);
bd928eba 6455 gen_spr_7xx(env);
a750fc0b
JM
6456 gen_spr_G2_755(env);
6457 /* Time base */
6458 gen_tbl(env);
6459 /* L2 cache control */
6460 /* XXX : not implemented */
bd928eba 6461 spr_register(env, SPR_L2CR, "L2CR",
a750fc0b 6462 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 6463 &spr_read_generic, spr_access_nop,
a750fc0b
JM
6464 0x00000000);
6465 /* XXX : not implemented */
6466 spr_register(env, SPR_L2PMCR, "L2PMCR",
6467 SPR_NOACCESS, SPR_NOACCESS,
6468 &spr_read_generic, &spr_write_generic,
6469 0x00000000);
bd928eba
JM
6470 /* Thermal management */
6471 gen_spr_thrm(env);
a750fc0b
JM
6472 /* Hardware implementation registers */
6473 /* XXX : not implemented */
6474 spr_register(env, SPR_HID0, "HID0",
6475 SPR_NOACCESS, SPR_NOACCESS,
6476 &spr_read_generic, &spr_write_generic,
6477 0x00000000);
6478 /* XXX : not implemented */
6479 spr_register(env, SPR_HID1, "HID1",
6480 SPR_NOACCESS, SPR_NOACCESS,
6481 &spr_read_generic, &spr_write_generic,
6482 0x00000000);
6483 /* XXX : not implemented */
6484 spr_register(env, SPR_HID2, "HID2",
6485 SPR_NOACCESS, SPR_NOACCESS,
6486 &spr_read_generic, &spr_write_generic,
6487 0x00000000);
6488 /* Memory management */
6489 gen_low_BATs(env);
6490 gen_high_BATs(env);
6491 gen_6xx_7xx_soft_tlb(env, 64, 2);
7a3a6927 6492 init_excp_7x5(env);
d63001d1
JM
6493 env->dcache_line_size = 32;
6494 env->icache_line_size = 32;
a750fc0b 6495 /* Allocate hardware IRQ controller */
db70b311 6496 ppc6xx_irq_init(env_archcpu(env));
a750fc0b
JM
6497}
6498
7856e3a4
AF
6499POWERPC_FAMILY(755)(ObjectClass *oc, void *data)
6500{
ca5dff0a 6501 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6502 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6503
ca5dff0a 6504 dc->desc = "PowerPC 755";
7856e3a4
AF
6505 pcc->init_proc = init_proc_755;
6506 pcc->check_pow = check_pow_hid0;
53116ebf
AF
6507 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6508 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6509 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6510 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6511 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6512 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
6513 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
6514 pcc->msr_mask = (1ull << MSR_POW) |
6515 (1ull << MSR_ILE) |
6516 (1ull << MSR_EE) |
6517 (1ull << MSR_PR) |
6518 (1ull << MSR_FP) |
6519 (1ull << MSR_ME) |
6520 (1ull << MSR_FE0) |
6521 (1ull << MSR_SE) |
6522 (1ull << MSR_DE) |
6523 (1ull << MSR_FE1) |
6524 (1ull << MSR_EP) |
6525 (1ull << MSR_IR) |
6526 (1ull << MSR_DR) |
6527 (1ull << MSR_PMM) |
6528 (1ull << MSR_RI) |
6529 (1ull << MSR_LE);
ba9fd9f1
AF
6530 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
6531 pcc->excp_model = POWERPC_EXCP_7x5;
6532 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6533 pcc->bfd_mach = bfd_mach_ppc_750;
6534 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6535 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6536}
6537
c364946d 6538static void init_proc_7400(CPUPPCState *env)
a750fc0b
JM
6539{
6540 gen_spr_ne_601(env);
4f4f28ff 6541 gen_spr_sdr1(env);
a750fc0b
JM
6542 gen_spr_7xx(env);
6543 /* Time base */
6544 gen_tbl(env);
6545 /* 74xx specific SPR */
6546 gen_spr_74xx(env);
4e777442
JM
6547 /* XXX : not implemented */
6548 spr_register(env, SPR_UBAMR, "UBAMR",
6549 &spr_read_ureg, SPR_NOACCESS,
6550 &spr_read_ureg, SPR_NOACCESS,
6551 0x00000000);
6552 /* XXX: this seems not implemented on all revisions. */
6553 /* XXX : not implemented */
6554 spr_register(env, SPR_MSSCR1, "MSSCR1",
6555 SPR_NOACCESS, SPR_NOACCESS,
6556 &spr_read_generic, &spr_write_generic,
6557 0x00000000);
a750fc0b
JM
6558 /* Thermal management */
6559 gen_spr_thrm(env);
6560 /* Memory management */
6561 gen_low_BATs(env);
e1833e1f 6562 init_excp_7400(env);
d63001d1
JM
6563 env->dcache_line_size = 32;
6564 env->icache_line_size = 32;
a750fc0b 6565 /* Allocate hardware IRQ controller */
db70b311 6566 ppc6xx_irq_init(env_archcpu(env));
a750fc0b
JM
6567}
6568
7856e3a4
AF
6569POWERPC_FAMILY(7400)(ObjectClass *oc, void *data)
6570{
ca5dff0a 6571 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6572 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6573
ca5dff0a 6574 dc->desc = "PowerPC 7400 (aka G4)";
7856e3a4
AF
6575 pcc->init_proc = init_proc_7400;
6576 pcc->check_pow = check_pow_hid0;
53116ebf
AF
6577 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6578 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6579 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6580 PPC_FLOAT_STFIWX |
6581 PPC_CACHE | PPC_CACHE_ICBI |
6582 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6583 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6584 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6585 PPC_MEM_TLBIA |
6586 PPC_SEGMENT | PPC_EXTERN |
6587 PPC_ALTIVEC;
9df5a466
TM
6588 pcc->msr_mask = (1ull << MSR_VR) |
6589 (1ull << MSR_POW) |
6590 (1ull << MSR_ILE) |
6591 (1ull << MSR_EE) |
6592 (1ull << MSR_PR) |
6593 (1ull << MSR_FP) |
6594 (1ull << MSR_ME) |
6595 (1ull << MSR_FE0) |
6596 (1ull << MSR_SE) |
6597 (1ull << MSR_DE) |
6598 (1ull << MSR_FE1) |
6599 (1ull << MSR_EP) |
6600 (1ull << MSR_IR) |
6601 (1ull << MSR_DR) |
6602 (1ull << MSR_PMM) |
6603 (1ull << MSR_RI) |
6604 (1ull << MSR_LE);
ba9fd9f1 6605 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
6606#if defined(CONFIG_SOFTMMU)
6607 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6608#endif
ba9fd9f1
AF
6609 pcc->excp_model = POWERPC_EXCP_74xx;
6610 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6611 pcc->bfd_mach = bfd_mach_ppc_7400;
6612 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6613 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6614 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6615}
6616
c364946d 6617static void init_proc_7410(CPUPPCState *env)
a750fc0b
JM
6618{
6619 gen_spr_ne_601(env);
4f4f28ff 6620 gen_spr_sdr1(env);
a750fc0b
JM
6621 gen_spr_7xx(env);
6622 /* Time base */
6623 gen_tbl(env);
6624 /* 74xx specific SPR */
6625 gen_spr_74xx(env);
4e777442
JM
6626 /* XXX : not implemented */
6627 spr_register(env, SPR_UBAMR, "UBAMR",
6628 &spr_read_ureg, SPR_NOACCESS,
6629 &spr_read_ureg, SPR_NOACCESS,
6630 0x00000000);
a750fc0b
JM
6631 /* Thermal management */
6632 gen_spr_thrm(env);
6633 /* L2PMCR */
6634 /* XXX : not implemented */
6635 spr_register(env, SPR_L2PMCR, "L2PMCR",
6636 SPR_NOACCESS, SPR_NOACCESS,
6637 &spr_read_generic, &spr_write_generic,
6638 0x00000000);
6639 /* LDSTDB */
6640 /* XXX : not implemented */
6641 spr_register(env, SPR_LDSTDB, "LDSTDB",
6642 SPR_NOACCESS, SPR_NOACCESS,
6643 &spr_read_generic, &spr_write_generic,
6644 0x00000000);
6645 /* Memory management */
6646 gen_low_BATs(env);
e1833e1f 6647 init_excp_7400(env);
d63001d1
JM
6648 env->dcache_line_size = 32;
6649 env->icache_line_size = 32;
a750fc0b 6650 /* Allocate hardware IRQ controller */
db70b311 6651 ppc6xx_irq_init(env_archcpu(env));
a750fc0b
JM
6652}
6653
7856e3a4
AF
6654POWERPC_FAMILY(7410)(ObjectClass *oc, void *data)
6655{
ca5dff0a 6656 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6657 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6658
ca5dff0a 6659 dc->desc = "PowerPC 7410 (aka G4)";
7856e3a4
AF
6660 pcc->init_proc = init_proc_7410;
6661 pcc->check_pow = check_pow_hid0;
53116ebf
AF
6662 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6663 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6664 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6665 PPC_FLOAT_STFIWX |
6666 PPC_CACHE | PPC_CACHE_ICBI |
6667 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6668 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6669 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6670 PPC_MEM_TLBIA |
6671 PPC_SEGMENT | PPC_EXTERN |
6672 PPC_ALTIVEC;
9df5a466
TM
6673 pcc->msr_mask = (1ull << MSR_VR) |
6674 (1ull << MSR_POW) |
6675 (1ull << MSR_ILE) |
6676 (1ull << MSR_EE) |
6677 (1ull << MSR_PR) |
6678 (1ull << MSR_FP) |
6679 (1ull << MSR_ME) |
6680 (1ull << MSR_FE0) |
6681 (1ull << MSR_SE) |
6682 (1ull << MSR_DE) |
6683 (1ull << MSR_FE1) |
6684 (1ull << MSR_EP) |
6685 (1ull << MSR_IR) |
6686 (1ull << MSR_DR) |
6687 (1ull << MSR_PMM) |
6688 (1ull << MSR_RI) |
6689 (1ull << MSR_LE);
ba9fd9f1 6690 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
6691#if defined(CONFIG_SOFTMMU)
6692 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6693#endif
ba9fd9f1
AF
6694 pcc->excp_model = POWERPC_EXCP_74xx;
6695 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6696 pcc->bfd_mach = bfd_mach_ppc_7400;
6697 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6698 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6699 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6700}
6701
c364946d 6702static void init_proc_7440(CPUPPCState *env)
a750fc0b
JM
6703{
6704 gen_spr_ne_601(env);
4f4f28ff 6705 gen_spr_sdr1(env);
a750fc0b
JM
6706 gen_spr_7xx(env);
6707 /* Time base */
6708 gen_tbl(env);
6709 /* 74xx specific SPR */
6710 gen_spr_74xx(env);
4e777442
JM
6711 /* XXX : not implemented */
6712 spr_register(env, SPR_UBAMR, "UBAMR",
6713 &spr_read_ureg, SPR_NOACCESS,
6714 &spr_read_ureg, SPR_NOACCESS,
6715 0x00000000);
a750fc0b
JM
6716 /* LDSTCR */
6717 /* XXX : not implemented */
6718 spr_register(env, SPR_LDSTCR, "LDSTCR",
6719 SPR_NOACCESS, SPR_NOACCESS,
6720 &spr_read_generic, &spr_write_generic,
6721 0x00000000);
6722 /* ICTRL */
6723 /* XXX : not implemented */
6724 spr_register(env, SPR_ICTRL, "ICTRL",
6725 SPR_NOACCESS, SPR_NOACCESS,
6726 &spr_read_generic, &spr_write_generic,
6727 0x00000000);
6728 /* MSSSR0 */
578bb252 6729 /* XXX : not implemented */
a750fc0b
JM
6730 spr_register(env, SPR_MSSSR0, "MSSSR0",
6731 SPR_NOACCESS, SPR_NOACCESS,
6732 &spr_read_generic, &spr_write_generic,
6733 0x00000000);
6734 /* PMC */
6735 /* XXX : not implemented */
cb8b8bf8 6736 spr_register(env, SPR_7XX_PMC5, "PMC5",
a750fc0b
JM
6737 SPR_NOACCESS, SPR_NOACCESS,
6738 &spr_read_generic, &spr_write_generic,
6739 0x00000000);
578bb252 6740 /* XXX : not implemented */
cb8b8bf8 6741 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
a750fc0b
JM
6742 &spr_read_ureg, SPR_NOACCESS,
6743 &spr_read_ureg, SPR_NOACCESS,
6744 0x00000000);
578bb252 6745 /* XXX : not implemented */
cb8b8bf8 6746 spr_register(env, SPR_7XX_PMC6, "PMC6",
a750fc0b
JM
6747 SPR_NOACCESS, SPR_NOACCESS,
6748 &spr_read_generic, &spr_write_generic,
6749 0x00000000);
578bb252 6750 /* XXX : not implemented */
cb8b8bf8 6751 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
a750fc0b
JM
6752 &spr_read_ureg, SPR_NOACCESS,
6753 &spr_read_ureg, SPR_NOACCESS,
6754 0x00000000);
6755 /* Memory management */
6756 gen_low_BATs(env);
578bb252 6757 gen_74xx_soft_tlb(env, 128, 2);
1c27f8fb 6758 init_excp_7450(env);
d63001d1
JM
6759 env->dcache_line_size = 32;
6760 env->icache_line_size = 32;
a750fc0b 6761 /* Allocate hardware IRQ controller */
db70b311 6762 ppc6xx_irq_init(env_archcpu(env));
a750fc0b 6763}
a750fc0b 6764
7856e3a4
AF
6765POWERPC_FAMILY(7440)(ObjectClass *oc, void *data)
6766{
ca5dff0a 6767 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6768 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6769
ca5dff0a 6770 dc->desc = "PowerPC 7440 (aka G4)";
7856e3a4
AF
6771 pcc->init_proc = init_proc_7440;
6772 pcc->check_pow = check_pow_hid0_74xx;
53116ebf
AF
6773 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6774 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6775 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6776 PPC_FLOAT_STFIWX |
6777 PPC_CACHE | PPC_CACHE_ICBI |
6778 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6779 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6780 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6781 PPC_MEM_TLBIA | PPC_74xx_TLB |
6782 PPC_SEGMENT | PPC_EXTERN |
6783 PPC_ALTIVEC;
9df5a466
TM
6784 pcc->msr_mask = (1ull << MSR_VR) |
6785 (1ull << MSR_POW) |
6786 (1ull << MSR_ILE) |
6787 (1ull << MSR_EE) |
6788 (1ull << MSR_PR) |
6789 (1ull << MSR_FP) |
6790 (1ull << MSR_ME) |
6791 (1ull << MSR_FE0) |
6792 (1ull << MSR_SE) |
6793 (1ull << MSR_DE) |
6794 (1ull << MSR_FE1) |
6795 (1ull << MSR_EP) |
6796 (1ull << MSR_IR) |
6797 (1ull << MSR_DR) |
6798 (1ull << MSR_PMM) |
6799 (1ull << MSR_RI) |
6800 (1ull << MSR_LE);
ba9fd9f1
AF
6801 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
6802 pcc->excp_model = POWERPC_EXCP_74xx;
6803 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6804 pcc->bfd_mach = bfd_mach_ppc_7400;
6805 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6806 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6807 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6808}
6809
c364946d 6810static void init_proc_7450(CPUPPCState *env)
a750fc0b
JM
6811{
6812 gen_spr_ne_601(env);
4f4f28ff 6813 gen_spr_sdr1(env);
a750fc0b
JM
6814 gen_spr_7xx(env);
6815 /* Time base */
6816 gen_tbl(env);
6817 /* 74xx specific SPR */
6818 gen_spr_74xx(env);
6819 /* Level 3 cache control */
6820 gen_l3_ctrl(env);
4e777442
JM
6821 /* L3ITCR1 */
6822 /* XXX : not implemented */
6823 spr_register(env, SPR_L3ITCR1, "L3ITCR1",
6824 SPR_NOACCESS, SPR_NOACCESS,
6825 &spr_read_generic, &spr_write_generic,
6826 0x00000000);
6827 /* L3ITCR2 */
6828 /* XXX : not implemented */
6829 spr_register(env, SPR_L3ITCR2, "L3ITCR2",
6830 SPR_NOACCESS, SPR_NOACCESS,
6831 &spr_read_generic, &spr_write_generic,
6832 0x00000000);
6833 /* L3ITCR3 */
6834 /* XXX : not implemented */
6835 spr_register(env, SPR_L3ITCR3, "L3ITCR3",
6836 SPR_NOACCESS, SPR_NOACCESS,
6837 &spr_read_generic, &spr_write_generic,
6838 0x00000000);
6839 /* L3OHCR */
6840 /* XXX : not implemented */
6841 spr_register(env, SPR_L3OHCR, "L3OHCR",
6842 SPR_NOACCESS, SPR_NOACCESS,
6843 &spr_read_generic, &spr_write_generic,
6844 0x00000000);
6845 /* XXX : not implemented */
6846 spr_register(env, SPR_UBAMR, "UBAMR",
6847 &spr_read_ureg, SPR_NOACCESS,
6848 &spr_read_ureg, SPR_NOACCESS,
6849 0x00000000);
a750fc0b
JM
6850 /* LDSTCR */
6851 /* XXX : not implemented */
6852 spr_register(env, SPR_LDSTCR, "LDSTCR",
6853 SPR_NOACCESS, SPR_NOACCESS,
6854 &spr_read_generic, &spr_write_generic,
6855 0x00000000);
6856 /* ICTRL */
6857 /* XXX : not implemented */
6858 spr_register(env, SPR_ICTRL, "ICTRL",
6859 SPR_NOACCESS, SPR_NOACCESS,
6860 &spr_read_generic, &spr_write_generic,
6861 0x00000000);
6862 /* MSSSR0 */
578bb252 6863 /* XXX : not implemented */
a750fc0b
JM
6864 spr_register(env, SPR_MSSSR0, "MSSSR0",
6865 SPR_NOACCESS, SPR_NOACCESS,
6866 &spr_read_generic, &spr_write_generic,
6867 0x00000000);
6868 /* PMC */
6869 /* XXX : not implemented */
cb8b8bf8 6870 spr_register(env, SPR_7XX_PMC5, "PMC5",
a750fc0b
JM
6871 SPR_NOACCESS, SPR_NOACCESS,
6872 &spr_read_generic, &spr_write_generic,
6873 0x00000000);
578bb252 6874 /* XXX : not implemented */
cb8b8bf8 6875 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
a750fc0b
JM
6876 &spr_read_ureg, SPR_NOACCESS,
6877 &spr_read_ureg, SPR_NOACCESS,
6878 0x00000000);
578bb252 6879 /* XXX : not implemented */
cb8b8bf8 6880 spr_register(env, SPR_7XX_PMC6, "PMC6",
a750fc0b
JM
6881 SPR_NOACCESS, SPR_NOACCESS,
6882 &spr_read_generic, &spr_write_generic,
6883 0x00000000);
578bb252 6884 /* XXX : not implemented */
cb8b8bf8 6885 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
a750fc0b
JM
6886 &spr_read_ureg, SPR_NOACCESS,
6887 &spr_read_ureg, SPR_NOACCESS,
6888 0x00000000);
6889 /* Memory management */
6890 gen_low_BATs(env);
578bb252 6891 gen_74xx_soft_tlb(env, 128, 2);
e1833e1f 6892 init_excp_7450(env);
d63001d1
JM
6893 env->dcache_line_size = 32;
6894 env->icache_line_size = 32;
a750fc0b 6895 /* Allocate hardware IRQ controller */
db70b311 6896 ppc6xx_irq_init(env_archcpu(env));
a750fc0b 6897}
a750fc0b 6898
7856e3a4
AF
6899POWERPC_FAMILY(7450)(ObjectClass *oc, void *data)
6900{
ca5dff0a 6901 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6902 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6903
ca5dff0a 6904 dc->desc = "PowerPC 7450 (aka G4)";
7856e3a4
AF
6905 pcc->init_proc = init_proc_7450;
6906 pcc->check_pow = check_pow_hid0_74xx;
53116ebf
AF
6907 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6908 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6909 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6910 PPC_FLOAT_STFIWX |
6911 PPC_CACHE | PPC_CACHE_ICBI |
6912 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6913 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6914 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6915 PPC_MEM_TLBIA | PPC_74xx_TLB |
6916 PPC_SEGMENT | PPC_EXTERN |
6917 PPC_ALTIVEC;
9df5a466
TM
6918 pcc->msr_mask = (1ull << MSR_VR) |
6919 (1ull << MSR_POW) |
6920 (1ull << MSR_ILE) |
6921 (1ull << MSR_EE) |
6922 (1ull << MSR_PR) |
6923 (1ull << MSR_FP) |
6924 (1ull << MSR_ME) |
6925 (1ull << MSR_FE0) |
6926 (1ull << MSR_SE) |
6927 (1ull << MSR_DE) |
6928 (1ull << MSR_FE1) |
6929 (1ull << MSR_EP) |
6930 (1ull << MSR_IR) |
6931 (1ull << MSR_DR) |
6932 (1ull << MSR_PMM) |
6933 (1ull << MSR_RI) |
6934 (1ull << MSR_LE);
ba9fd9f1
AF
6935 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
6936 pcc->excp_model = POWERPC_EXCP_74xx;
6937 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6938 pcc->bfd_mach = bfd_mach_ppc_7400;
6939 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6940 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6941 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6942}
6943
c364946d 6944static void init_proc_7445(CPUPPCState *env)
a750fc0b
JM
6945{
6946 gen_spr_ne_601(env);
4f4f28ff 6947 gen_spr_sdr1(env);
a750fc0b
JM
6948 gen_spr_7xx(env);
6949 /* Time base */
6950 gen_tbl(env);
6951 /* 74xx specific SPR */
6952 gen_spr_74xx(env);
6953 /* LDSTCR */
6954 /* XXX : not implemented */
6955 spr_register(env, SPR_LDSTCR, "LDSTCR",
6956 SPR_NOACCESS, SPR_NOACCESS,
6957 &spr_read_generic, &spr_write_generic,
6958 0x00000000);
6959 /* ICTRL */
6960 /* XXX : not implemented */
6961 spr_register(env, SPR_ICTRL, "ICTRL",
6962 SPR_NOACCESS, SPR_NOACCESS,
6963 &spr_read_generic, &spr_write_generic,
6964 0x00000000);
6965 /* MSSSR0 */
578bb252 6966 /* XXX : not implemented */
a750fc0b
JM
6967 spr_register(env, SPR_MSSSR0, "MSSSR0",
6968 SPR_NOACCESS, SPR_NOACCESS,
6969 &spr_read_generic, &spr_write_generic,
6970 0x00000000);
6971 /* PMC */
6972 /* XXX : not implemented */
cb8b8bf8 6973 spr_register(env, SPR_7XX_PMC5, "PMC5",
a750fc0b
JM
6974 SPR_NOACCESS, SPR_NOACCESS,
6975 &spr_read_generic, &spr_write_generic,
6976 0x00000000);
578bb252 6977 /* XXX : not implemented */
cb8b8bf8 6978 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
a750fc0b
JM
6979 &spr_read_ureg, SPR_NOACCESS,
6980 &spr_read_ureg, SPR_NOACCESS,
6981 0x00000000);
578bb252 6982 /* XXX : not implemented */
cb8b8bf8 6983 spr_register(env, SPR_7XX_PMC6, "PMC6",
a750fc0b
JM
6984 SPR_NOACCESS, SPR_NOACCESS,
6985 &spr_read_generic, &spr_write_generic,
6986 0x00000000);
578bb252 6987 /* XXX : not implemented */
cb8b8bf8 6988 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
a750fc0b
JM
6989 &spr_read_ureg, SPR_NOACCESS,
6990 &spr_read_ureg, SPR_NOACCESS,
6991 0x00000000);
6992 /* SPRGs */
6993 spr_register(env, SPR_SPRG4, "SPRG4",
6994 SPR_NOACCESS, SPR_NOACCESS,
6995 &spr_read_generic, &spr_write_generic,
6996 0x00000000);
6997 spr_register(env, SPR_USPRG4, "USPRG4",
6998 &spr_read_ureg, SPR_NOACCESS,
6999 &spr_read_ureg, SPR_NOACCESS,
7000 0x00000000);
7001 spr_register(env, SPR_SPRG5, "SPRG5",
7002 SPR_NOACCESS, SPR_NOACCESS,
7003 &spr_read_generic, &spr_write_generic,
7004 0x00000000);
7005 spr_register(env, SPR_USPRG5, "USPRG5",
7006 &spr_read_ureg, SPR_NOACCESS,
7007 &spr_read_ureg, SPR_NOACCESS,
7008 0x00000000);
7009 spr_register(env, SPR_SPRG6, "SPRG6",
7010 SPR_NOACCESS, SPR_NOACCESS,
7011 &spr_read_generic, &spr_write_generic,
7012 0x00000000);
7013 spr_register(env, SPR_USPRG6, "USPRG6",
7014 &spr_read_ureg, SPR_NOACCESS,
7015 &spr_read_ureg, SPR_NOACCESS,
7016 0x00000000);
7017 spr_register(env, SPR_SPRG7, "SPRG7",
7018 SPR_NOACCESS, SPR_NOACCESS,
7019 &spr_read_generic, &spr_write_generic,
7020 0x00000000);
7021 spr_register(env, SPR_USPRG7, "USPRG7",
7022 &spr_read_ureg, SPR_NOACCESS,
7023 &spr_read_ureg, SPR_NOACCESS,
7024 0x00000000);
7025 /* Memory management */
7026 gen_low_BATs(env);
7027 gen_high_BATs(env);
578bb252 7028 gen_74xx_soft_tlb(env, 128, 2);
e1833e1f 7029 init_excp_7450(env);
d63001d1
JM
7030 env->dcache_line_size = 32;
7031 env->icache_line_size = 32;
a750fc0b 7032 /* Allocate hardware IRQ controller */
db70b311 7033 ppc6xx_irq_init(env_archcpu(env));
a750fc0b 7034}
a750fc0b 7035
7856e3a4
AF
7036POWERPC_FAMILY(7445)(ObjectClass *oc, void *data)
7037{
ca5dff0a 7038 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
7039 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7040
ca5dff0a 7041 dc->desc = "PowerPC 7445 (aka G4)";
7856e3a4
AF
7042 pcc->init_proc = init_proc_7445;
7043 pcc->check_pow = check_pow_hid0_74xx;
53116ebf
AF
7044 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7045 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7046 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7047 PPC_FLOAT_STFIWX |
7048 PPC_CACHE | PPC_CACHE_ICBI |
7049 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
7050 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7051 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7052 PPC_MEM_TLBIA | PPC_74xx_TLB |
7053 PPC_SEGMENT | PPC_EXTERN |
7054 PPC_ALTIVEC;
9df5a466
TM
7055 pcc->msr_mask = (1ull << MSR_VR) |
7056 (1ull << MSR_POW) |
7057 (1ull << MSR_ILE) |
7058 (1ull << MSR_EE) |
7059 (1ull << MSR_PR) |
7060 (1ull << MSR_FP) |
7061 (1ull << MSR_ME) |
7062 (1ull << MSR_FE0) |
7063 (1ull << MSR_SE) |
7064 (1ull << MSR_DE) |
7065 (1ull << MSR_FE1) |
7066 (1ull << MSR_EP) |
7067 (1ull << MSR_IR) |
7068 (1ull << MSR_DR) |
7069 (1ull << MSR_PMM) |
7070 (1ull << MSR_RI) |
7071 (1ull << MSR_LE);
ba9fd9f1
AF
7072 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
7073 pcc->excp_model = POWERPC_EXCP_74xx;
7074 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7075 pcc->bfd_mach = bfd_mach_ppc_7400;
7076 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7077 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7078 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
7079}
7080
c364946d 7081static void init_proc_7455(CPUPPCState *env)
a750fc0b
JM
7082{
7083 gen_spr_ne_601(env);
4f4f28ff 7084 gen_spr_sdr1(env);
a750fc0b
JM
7085 gen_spr_7xx(env);
7086 /* Time base */
7087 gen_tbl(env);
7088 /* 74xx specific SPR */
7089 gen_spr_74xx(env);
7090 /* Level 3 cache control */
7091 gen_l3_ctrl(env);
7092 /* LDSTCR */
7093 /* XXX : not implemented */
7094 spr_register(env, SPR_LDSTCR, "LDSTCR",
7095 SPR_NOACCESS, SPR_NOACCESS,
7096 &spr_read_generic, &spr_write_generic,
7097 0x00000000);
7098 /* ICTRL */
7099 /* XXX : not implemented */
7100 spr_register(env, SPR_ICTRL, "ICTRL",
7101 SPR_NOACCESS, SPR_NOACCESS,
7102 &spr_read_generic, &spr_write_generic,
7103 0x00000000);
7104 /* MSSSR0 */
578bb252 7105 /* XXX : not implemented */
a750fc0b
JM
7106 spr_register(env, SPR_MSSSR0, "MSSSR0",
7107 SPR_NOACCESS, SPR_NOACCESS,
7108 &spr_read_generic, &spr_write_generic,
7109 0x00000000);
7110 /* PMC */
7111 /* XXX : not implemented */
cb8b8bf8 7112 spr_register(env, SPR_7XX_PMC5, "PMC5",
a750fc0b
JM
7113 SPR_NOACCESS, SPR_NOACCESS,
7114 &spr_read_generic, &spr_write_generic,
7115 0x00000000);
578bb252 7116 /* XXX : not implemented */
cb8b8bf8 7117 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
a750fc0b
JM
7118 &spr_read_ureg, SPR_NOACCESS,
7119 &spr_read_ureg, SPR_NOACCESS,
7120 0x00000000);
578bb252 7121 /* XXX : not implemented */
cb8b8bf8 7122 spr_register(env, SPR_7XX_PMC6, "PMC6",
a750fc0b
JM
7123 SPR_NOACCESS, SPR_NOACCESS,
7124 &spr_read_generic, &spr_write_generic,
7125 0x00000000);
578bb252 7126 /* XXX : not implemented */
cb8b8bf8 7127 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
a750fc0b
JM
7128 &spr_read_ureg, SPR_NOACCESS,
7129 &spr_read_ureg, SPR_NOACCESS,
7130 0x00000000);
7131 /* SPRGs */
7132 spr_register(env, SPR_SPRG4, "SPRG4",
7133 SPR_NOACCESS, SPR_NOACCESS,
7134 &spr_read_generic, &spr_write_generic,
7135 0x00000000);
7136 spr_register(env, SPR_USPRG4, "USPRG4",
7137 &spr_read_ureg, SPR_NOACCESS,
7138 &spr_read_ureg, SPR_NOACCESS,
7139 0x00000000);
7140 spr_register(env, SPR_SPRG5, "SPRG5",
7141 SPR_NOACCESS, SPR_NOACCESS,
7142 &spr_read_generic, &spr_write_generic,
7143 0x00000000);
7144 spr_register(env, SPR_USPRG5, "USPRG5",
7145 &spr_read_ureg, SPR_NOACCESS,
7146 &spr_read_ureg, SPR_NOACCESS,
7147 0x00000000);
7148 spr_register(env, SPR_SPRG6, "SPRG6",
7149 SPR_NOACCESS, SPR_NOACCESS,
7150 &spr_read_generic, &spr_write_generic,
7151 0x00000000);
7152 spr_register(env, SPR_USPRG6, "USPRG6",
7153 &spr_read_ureg, SPR_NOACCESS,
7154 &spr_read_ureg, SPR_NOACCESS,
7155 0x00000000);
7156 spr_register(env, SPR_SPRG7, "SPRG7",
7157 SPR_NOACCESS, SPR_NOACCESS,
7158 &spr_read_generic, &spr_write_generic,
7159 0x00000000);
7160 spr_register(env, SPR_USPRG7, "USPRG7",
7161 &spr_read_ureg, SPR_NOACCESS,
7162 &spr_read_ureg, SPR_NOACCESS,
7163 0x00000000);
7164 /* Memory management */
7165 gen_low_BATs(env);
7166 gen_high_BATs(env);
578bb252 7167 gen_74xx_soft_tlb(env, 128, 2);
e1833e1f 7168 init_excp_7450(env);
d63001d1
JM
7169 env->dcache_line_size = 32;
7170 env->icache_line_size = 32;
a750fc0b 7171 /* Allocate hardware IRQ controller */
db70b311 7172 ppc6xx_irq_init(env_archcpu(env));
a750fc0b 7173}
a750fc0b 7174
7856e3a4
AF
7175POWERPC_FAMILY(7455)(ObjectClass *oc, void *data)
7176{
ca5dff0a 7177 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
7178 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7179
ca5dff0a 7180 dc->desc = "PowerPC 7455 (aka G4)";
7856e3a4
AF
7181 pcc->init_proc = init_proc_7455;
7182 pcc->check_pow = check_pow_hid0_74xx;
53116ebf
AF
7183 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7184 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7185 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7186 PPC_FLOAT_STFIWX |
7187 PPC_CACHE | PPC_CACHE_ICBI |
7188 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
7189 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7190 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7191 PPC_MEM_TLBIA | PPC_74xx_TLB |
7192 PPC_SEGMENT | PPC_EXTERN |
7193 PPC_ALTIVEC;
9df5a466
TM
7194 pcc->msr_mask = (1ull << MSR_VR) |
7195 (1ull << MSR_POW) |
7196 (1ull << MSR_ILE) |
7197 (1ull << MSR_EE) |
7198 (1ull << MSR_PR) |
7199 (1ull << MSR_FP) |
7200 (1ull << MSR_ME) |
7201 (1ull << MSR_FE0) |
7202 (1ull << MSR_SE) |
7203 (1ull << MSR_DE) |
7204 (1ull << MSR_FE1) |
7205 (1ull << MSR_EP) |
7206 (1ull << MSR_IR) |
7207 (1ull << MSR_DR) |
7208 (1ull << MSR_PMM) |
7209 (1ull << MSR_RI) |
7210 (1ull << MSR_LE);
ba9fd9f1
AF
7211 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
7212 pcc->excp_model = POWERPC_EXCP_74xx;
7213 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7214 pcc->bfd_mach = bfd_mach_ppc_7400;
7215 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7216 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7217 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
7218}
7219
c364946d 7220static void init_proc_7457(CPUPPCState *env)
4e777442
JM
7221{
7222 gen_spr_ne_601(env);
4f4f28ff 7223 gen_spr_sdr1(env);
4e777442
JM
7224 gen_spr_7xx(env);
7225 /* Time base */
7226 gen_tbl(env);
7227 /* 74xx specific SPR */
7228 gen_spr_74xx(env);
7229 /* Level 3 cache control */
7230 gen_l3_ctrl(env);
7231 /* L3ITCR1 */
7232 /* XXX : not implemented */
7233 spr_register(env, SPR_L3ITCR1, "L3ITCR1",
7234 SPR_NOACCESS, SPR_NOACCESS,
7235 &spr_read_generic, &spr_write_generic,
7236 0x00000000);
7237 /* L3ITCR2 */
7238 /* XXX : not implemented */
7239 spr_register(env, SPR_L3ITCR2, "L3ITCR2",
7240 SPR_NOACCESS, SPR_NOACCESS,
7241 &spr_read_generic, &spr_write_generic,
7242 0x00000000);
7243 /* L3ITCR3 */
7244 /* XXX : not implemented */
7245 spr_register(env, SPR_L3ITCR3, "L3ITCR3",
7246 SPR_NOACCESS, SPR_NOACCESS,
7247 &spr_read_generic, &spr_write_generic,
7248 0x00000000);
7249 /* L3OHCR */
7250 /* XXX : not implemented */
7251 spr_register(env, SPR_L3OHCR, "L3OHCR",
7252 SPR_NOACCESS, SPR_NOACCESS,
7253 &spr_read_generic, &spr_write_generic,
7254 0x00000000);
7255 /* LDSTCR */
7256 /* XXX : not implemented */
7257 spr_register(env, SPR_LDSTCR, "LDSTCR",
7258 SPR_NOACCESS, SPR_NOACCESS,
7259 &spr_read_generic, &spr_write_generic,
7260 0x00000000);
7261 /* ICTRL */
7262 /* XXX : not implemented */
7263 spr_register(env, SPR_ICTRL, "ICTRL",
7264 SPR_NOACCESS, SPR_NOACCESS,
7265 &spr_read_generic, &spr_write_generic,
7266 0x00000000);
7267 /* MSSSR0 */
7268 /* XXX : not implemented */
7269 spr_register(env, SPR_MSSSR0, "MSSSR0",
7270 SPR_NOACCESS, SPR_NOACCESS,
7271 &spr_read_generic, &spr_write_generic,
7272 0x00000000);
7273 /* PMC */
7274 /* XXX : not implemented */
cb8b8bf8 7275 spr_register(env, SPR_7XX_PMC5, "PMC5",
4e777442
JM
7276 SPR_NOACCESS, SPR_NOACCESS,
7277 &spr_read_generic, &spr_write_generic,
7278 0x00000000);
7279 /* XXX : not implemented */
cb8b8bf8 7280 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
4e777442
JM
7281 &spr_read_ureg, SPR_NOACCESS,
7282 &spr_read_ureg, SPR_NOACCESS,
7283 0x00000000);
7284 /* XXX : not implemented */
cb8b8bf8 7285 spr_register(env, SPR_7XX_PMC6, "PMC6",
4e777442
JM
7286 SPR_NOACCESS, SPR_NOACCESS,
7287 &spr_read_generic, &spr_write_generic,
7288 0x00000000);
7289 /* XXX : not implemented */
cb8b8bf8 7290 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
4e777442
JM
7291 &spr_read_ureg, SPR_NOACCESS,
7292 &spr_read_ureg, SPR_NOACCESS,
7293 0x00000000);
7294 /* SPRGs */
7295 spr_register(env, SPR_SPRG4, "SPRG4",
7296 SPR_NOACCESS, SPR_NOACCESS,
7297 &spr_read_generic, &spr_write_generic,
7298 0x00000000);
7299 spr_register(env, SPR_USPRG4, "USPRG4",
7300 &spr_read_ureg, SPR_NOACCESS,
7301 &spr_read_ureg, SPR_NOACCESS,
7302 0x00000000);
7303 spr_register(env, SPR_SPRG5, "SPRG5",
7304 SPR_NOACCESS, SPR_NOACCESS,
7305 &spr_read_generic, &spr_write_generic,
7306 0x00000000);
7307 spr_register(env, SPR_USPRG5, "USPRG5",
7308 &spr_read_ureg, SPR_NOACCESS,
7309 &spr_read_ureg, SPR_NOACCESS,
7310 0x00000000);
7311 spr_register(env, SPR_SPRG6, "SPRG6",
7312 SPR_NOACCESS, SPR_NOACCESS,
7313 &spr_read_generic, &spr_write_generic,
7314 0x00000000);
7315 spr_register(env, SPR_USPRG6, "USPRG6",
7316 &spr_read_ureg, SPR_NOACCESS,
7317 &spr_read_ureg, SPR_NOACCESS,
7318 0x00000000);
7319 spr_register(env, SPR_SPRG7, "SPRG7",
7320 SPR_NOACCESS, SPR_NOACCESS,
7321 &spr_read_generic, &spr_write_generic,
7322 0x00000000);
7323 spr_register(env, SPR_USPRG7, "USPRG7",
7324 &spr_read_ureg, SPR_NOACCESS,
7325 &spr_read_ureg, SPR_NOACCESS,
7326 0x00000000);
7327 /* Memory management */
7328 gen_low_BATs(env);
7329 gen_high_BATs(env);
7330 gen_74xx_soft_tlb(env, 128, 2);
7331 init_excp_7450(env);
7332 env->dcache_line_size = 32;
7333 env->icache_line_size = 32;
7334 /* Allocate hardware IRQ controller */
db70b311 7335 ppc6xx_irq_init(env_archcpu(env));
4e777442
JM
7336}
7337
7856e3a4
AF
7338POWERPC_FAMILY(7457)(ObjectClass *oc, void *data)
7339{
ca5dff0a 7340 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
7341 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7342
ca5dff0a 7343 dc->desc = "PowerPC 7457 (aka G4)";
7856e3a4
AF
7344 pcc->init_proc = init_proc_7457;
7345 pcc->check_pow = check_pow_hid0_74xx;
53116ebf
AF
7346 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7347 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7348 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7349 PPC_FLOAT_STFIWX |
7350 PPC_CACHE | PPC_CACHE_ICBI |
7351 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
7352 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7353 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7354 PPC_MEM_TLBIA | PPC_74xx_TLB |
7355 PPC_SEGMENT | PPC_EXTERN |
7356 PPC_ALTIVEC;
9df5a466
TM
7357 pcc->msr_mask = (1ull << MSR_VR) |
7358 (1ull << MSR_POW) |
7359 (1ull << MSR_ILE) |
7360 (1ull << MSR_EE) |
7361 (1ull << MSR_PR) |
7362 (1ull << MSR_FP) |
7363 (1ull << MSR_ME) |
7364 (1ull << MSR_FE0) |
7365 (1ull << MSR_SE) |
7366 (1ull << MSR_DE) |
7367 (1ull << MSR_FE1) |
7368 (1ull << MSR_EP) |
7369 (1ull << MSR_IR) |
7370 (1ull << MSR_DR) |
7371 (1ull << MSR_PMM) |
7372 (1ull << MSR_RI) |
7373 (1ull << MSR_LE);
ba9fd9f1
AF
7374 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
7375 pcc->excp_model = POWERPC_EXCP_74xx;
7376 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7377 pcc->bfd_mach = bfd_mach_ppc_7400;
7378 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7379 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7380 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
7381}
7382
c364946d 7383static void init_proc_e600(CPUPPCState *env)
7162bdea
JG
7384{
7385 gen_spr_ne_601(env);
4f4f28ff 7386 gen_spr_sdr1(env);
7162bdea
JG
7387 gen_spr_7xx(env);
7388 /* Time base */
7389 gen_tbl(env);
7390 /* 74xx specific SPR */
7391 gen_spr_74xx(env);
7392 /* XXX : not implemented */
7393 spr_register(env, SPR_UBAMR, "UBAMR",
7394 &spr_read_ureg, SPR_NOACCESS,
7395 &spr_read_ureg, SPR_NOACCESS,
7396 0x00000000);
7397 /* XXX : not implemented */
7398 spr_register(env, SPR_LDSTCR, "LDSTCR",
7399 SPR_NOACCESS, SPR_NOACCESS,
7400 &spr_read_generic, &spr_write_generic,
7401 0x00000000);
7402 /* XXX : not implemented */
7403 spr_register(env, SPR_ICTRL, "ICTRL",
7404 SPR_NOACCESS, SPR_NOACCESS,
7405 &spr_read_generic, &spr_write_generic,
7406 0x00000000);
7407 /* XXX : not implemented */
7408 spr_register(env, SPR_MSSSR0, "MSSSR0",
7409 SPR_NOACCESS, SPR_NOACCESS,
7410 &spr_read_generic, &spr_write_generic,
7411 0x00000000);
7412 /* XXX : not implemented */
cb8b8bf8 7413 spr_register(env, SPR_7XX_PMC5, "PMC5",
7162bdea
JG
7414 SPR_NOACCESS, SPR_NOACCESS,
7415 &spr_read_generic, &spr_write_generic,
7416 0x00000000);
7417 /* XXX : not implemented */
cb8b8bf8 7418 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
7162bdea
JG
7419 &spr_read_ureg, SPR_NOACCESS,
7420 &spr_read_ureg, SPR_NOACCESS,
7421 0x00000000);
7422 /* XXX : not implemented */
cb8b8bf8 7423 spr_register(env, SPR_7XX_PMC6, "PMC6",
7162bdea
JG
7424 SPR_NOACCESS, SPR_NOACCESS,
7425 &spr_read_generic, &spr_write_generic,
7426 0x00000000);
7427 /* XXX : not implemented */
cb8b8bf8 7428 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
7162bdea
JG
7429 &spr_read_ureg, SPR_NOACCESS,
7430 &spr_read_ureg, SPR_NOACCESS,
7431 0x00000000);
7432 /* SPRGs */
7433 spr_register(env, SPR_SPRG4, "SPRG4",
7434 SPR_NOACCESS, SPR_NOACCESS,
7435 &spr_read_generic, &spr_write_generic,
7436 0x00000000);
7437 spr_register(env, SPR_USPRG4, "USPRG4",
7438 &spr_read_ureg, SPR_NOACCESS,
7439 &spr_read_ureg, SPR_NOACCESS,
7440 0x00000000);
7441 spr_register(env, SPR_SPRG5, "SPRG5",
7442 SPR_NOACCESS, SPR_NOACCESS,
7443 &spr_read_generic, &spr_write_generic,
7444 0x00000000);
7445 spr_register(env, SPR_USPRG5, "USPRG5",
7446 &spr_read_ureg, SPR_NOACCESS,
7447 &spr_read_ureg, SPR_NOACCESS,
7448 0x00000000);
7449 spr_register(env, SPR_SPRG6, "SPRG6",
7450 SPR_NOACCESS, SPR_NOACCESS,
7451 &spr_read_generic, &spr_write_generic,
7452 0x00000000);
7453 spr_register(env, SPR_USPRG6, "USPRG6",
7454 &spr_read_ureg, SPR_NOACCESS,
7455 &spr_read_ureg, SPR_NOACCESS,
7456 0x00000000);
7457 spr_register(env, SPR_SPRG7, "SPRG7",
7458 SPR_NOACCESS, SPR_NOACCESS,
7459 &spr_read_generic, &spr_write_generic,
7460 0x00000000);
7461 spr_register(env, SPR_USPRG7, "USPRG7",
7462 &spr_read_ureg, SPR_NOACCESS,
7463 &spr_read_ureg, SPR_NOACCESS,
7464 0x00000000);
7465 /* Memory management */
7466 gen_low_BATs(env);
7467 gen_high_BATs(env);
7468 gen_74xx_soft_tlb(env, 128, 2);
7469 init_excp_7450(env);
7470 env->dcache_line_size = 32;
7471 env->icache_line_size = 32;
7472 /* Allocate hardware IRQ controller */
db70b311 7473 ppc6xx_irq_init(env_archcpu(env));
7162bdea
JG
7474}
7475
7476POWERPC_FAMILY(e600)(ObjectClass *oc, void *data)
7477{
7478 DeviceClass *dc = DEVICE_CLASS(oc);
7479 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7480
7481 dc->desc = "PowerPC e600";
7482 pcc->init_proc = init_proc_e600;
7483 pcc->check_pow = check_pow_hid0_74xx;
7484 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7485 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7486 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7487 PPC_FLOAT_STFIWX |
7488 PPC_CACHE | PPC_CACHE_ICBI |
7489 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
7490 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7491 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7492 PPC_MEM_TLBIA | PPC_74xx_TLB |
7493 PPC_SEGMENT | PPC_EXTERN |
7494 PPC_ALTIVEC;
7495 pcc->insns_flags2 = PPC_NONE;
9df5a466
TM
7496 pcc->msr_mask = (1ull << MSR_VR) |
7497 (1ull << MSR_POW) |
7498 (1ull << MSR_ILE) |
7499 (1ull << MSR_EE) |
7500 (1ull << MSR_PR) |
7501 (1ull << MSR_FP) |
7502 (1ull << MSR_ME) |
7503 (1ull << MSR_FE0) |
7504 (1ull << MSR_SE) |
7505 (1ull << MSR_DE) |
7506 (1ull << MSR_FE1) |
7507 (1ull << MSR_EP) |
7508 (1ull << MSR_IR) |
7509 (1ull << MSR_DR) |
7510 (1ull << MSR_PMM) |
7511 (1ull << MSR_RI) |
7512 (1ull << MSR_LE);
7162bdea
JG
7513 pcc->mmu_model = POWERPC_MMU_32B;
7514#if defined(CONFIG_SOFTMMU)
7515 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
7516#endif
7517 pcc->excp_model = POWERPC_EXCP_74xx;
7518 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7519 pcc->bfd_mach = bfd_mach_ppc_7400;
7520 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7521 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7522 POWERPC_FLAG_BUS_CLK;
7523}
7524
c364946d 7525#if defined(TARGET_PPC64)
417bf010
JM
7526#if defined(CONFIG_USER_ONLY)
7527#define POWERPC970_HID5_INIT 0x00000080
7528#else
7529#define POWERPC970_HID5_INIT 0x00000000
7530#endif
7531
69b058c8
PB
7532static void gen_fscr_facility_check(DisasContext *ctx, int facility_sprn,
7533 int bit, int sprn, int cause)
45ed0be1
AK
7534{
7535 TCGv_i32 t1 = tcg_const_i32(bit);
7536 TCGv_i32 t2 = tcg_const_i32(sprn);
7537 TCGv_i32 t3 = tcg_const_i32(cause);
7538
45ed0be1
AK
7539 gen_helper_fscr_facility_check(cpu_env, t1, t2, t3);
7540
7541 tcg_temp_free_i32(t3);
7542 tcg_temp_free_i32(t2);
7543 tcg_temp_free_i32(t1);
7544}
7545
69b058c8
PB
7546static void gen_msr_facility_check(DisasContext *ctx, int facility_sprn,
7547 int bit, int sprn, int cause)
cdcdda27
AK
7548{
7549 TCGv_i32 t1 = tcg_const_i32(bit);
7550 TCGv_i32 t2 = tcg_const_i32(sprn);
7551 TCGv_i32 t3 = tcg_const_i32(cause);
7552
cdcdda27
AK
7553 gen_helper_msr_facility_check(cpu_env, t1, t2, t3);
7554
7555 tcg_temp_free_i32(t3);
7556 tcg_temp_free_i32(t2);
7557 tcg_temp_free_i32(t1);
7558}
7559
69b058c8 7560static void spr_read_prev_upper32(DisasContext *ctx, int gprn, int sprn)
cdcdda27
AK
7561{
7562 TCGv spr_up = tcg_temp_new();
7563 TCGv spr = tcg_temp_new();
7564
7565 gen_load_spr(spr, sprn - 1);
7566 tcg_gen_shri_tl(spr_up, spr, 32);
7567 tcg_gen_ext32u_tl(cpu_gpr[gprn], spr_up);
7568
7569 tcg_temp_free(spr);
7570 tcg_temp_free(spr_up);
7571}
7572
69b058c8 7573static void spr_write_prev_upper32(DisasContext *ctx, int sprn, int gprn)
cdcdda27
AK
7574{
7575 TCGv spr = tcg_temp_new();
7576
7577 gen_load_spr(spr, sprn - 1);
7578 tcg_gen_deposit_tl(spr, spr, cpu_gpr[gprn], 32, 32);
7579 gen_store_spr(sprn - 1, spr);
7580
7581 tcg_temp_free(spr);
7582}
7583
c364946d 7584static int check_pow_970(CPUPPCState *env)
2f462816 7585{
bbc01ca7 7586 if (env->spr[SPR_HID0] & (HID0_DEEPNAP | HID0_DOZE | HID0_NAP)) {
2f462816 7587 return 1;
bbc01ca7 7588 }
2f462816
JM
7589
7590 return 0;
7591}
7592
42382f62 7593static void gen_spr_970_hid(CPUPPCState *env)
a750fc0b 7594{
a750fc0b
JM
7595 /* Hardware implementation registers */
7596 /* XXX : not implemented */
7597 spr_register(env, SPR_HID0, "HID0",
7598 SPR_NOACCESS, SPR_NOACCESS,
06403421 7599 &spr_read_generic, &spr_write_clear,
d63001d1 7600 0x60000000);
a750fc0b
JM
7601 spr_register(env, SPR_HID1, "HID1",
7602 SPR_NOACCESS, SPR_NOACCESS,
7603 &spr_read_generic, &spr_write_generic,
7604 0x00000000);
e57448f1
JM
7605 spr_register(env, SPR_970_HID5, "HID5",
7606 SPR_NOACCESS, SPR_NOACCESS,
7607 &spr_read_generic, &spr_write_generic,
417bf010 7608 POWERPC970_HID5_INIT);
42382f62
AK
7609}
7610
7611static void gen_spr_970_hior(CPUPPCState *env)
7612{
12de9a39
JM
7613 spr_register(env, SPR_HIOR, "SPR_HIOR",
7614 SPR_NOACCESS, SPR_NOACCESS,
2adab7d6
BS
7615 &spr_read_hior, &spr_write_hior,
7616 0x00000000);
42382f62 7617}
7856e3a4 7618
4f4f28ff 7619static void gen_spr_book3s_ctrl(CPUPPCState *env)
42382f62 7620{
4e98d8cf
BS
7621 spr_register(env, SPR_CTRL, "SPR_CTRL",
7622 SPR_NOACCESS, SPR_NOACCESS,
4e381819 7623 SPR_NOACCESS, &spr_write_generic,
4e98d8cf
BS
7624 0x00000000);
7625 spr_register(env, SPR_UCTRL, "SPR_UCTRL",
eb16dd9c
AK
7626 &spr_read_ureg, SPR_NOACCESS,
7627 &spr_read_ureg, SPR_NOACCESS,
4e98d8cf 7628 0x00000000);
42382f62
AK
7629}
7630
7631static void gen_spr_book3s_altivec(CPUPPCState *env)
7632{
7633 if (!(env->insns_flags & PPC_ALTIVEC)) {
7634 return;
7635 }
7636
7303f83d
AK
7637 spr_register_kvm(env, SPR_VRSAVE, "VRSAVE",
7638 &spr_read_generic, &spr_write_generic,
7639 &spr_read_generic, &spr_write_generic,
7640 KVM_REG_PPC_VRSAVE, 0x00000000);
42382f62 7641
1d28b5f6
DG
7642 /*
7643 * Can't find information on what this should be on reset. This
7644 * value is the one used by 74xx processors.
7645 */
42382f62
AK
7646 vscr_init(env, 0x00010000);
7647}
7648
fd51ff63
AK
7649static void gen_spr_book3s_dbg(CPUPPCState *env)
7650{
cd9adfdd
AK
7651 /*
7652 * TODO: different specs define different scopes for these,
7653 * will have to address this:
7654 * 970: super/write and super/read
7655 * powerisa 2.03..2.04: hypv/write and super/read.
7656 * powerisa 2.05 and newer: hypv/write and hypv/read.
7657 */
fd51ff63
AK
7658 spr_register_kvm(env, SPR_DABR, "DABR",
7659 SPR_NOACCESS, SPR_NOACCESS,
7660 &spr_read_generic, &spr_write_generic,
7661 KVM_REG_PPC_DABR, 0x00000000);
cd9adfdd
AK
7662 spr_register_kvm(env, SPR_DABRX, "DABRX",
7663 SPR_NOACCESS, SPR_NOACCESS,
7664 &spr_read_generic, &spr_write_generic,
7665 KVM_REG_PPC_DABRX, 0x00000000);
fd51ff63
AK
7666}
7667
f401dd32
BH
7668static void gen_spr_book3s_207_dbg(CPUPPCState *env)
7669{
7670 spr_register_kvm_hv(env, SPR_DAWR, "DAWR",
7671 SPR_NOACCESS, SPR_NOACCESS,
7672 SPR_NOACCESS, SPR_NOACCESS,
7673 &spr_read_generic, &spr_write_generic,
7674 KVM_REG_PPC_DAWR, 0x00000000);
7675 spr_register_kvm_hv(env, SPR_DAWRX, "DAWRX",
7676 SPR_NOACCESS, SPR_NOACCESS,
7677 SPR_NOACCESS, SPR_NOACCESS,
7678 &spr_read_generic, &spr_write_generic,
7679 KVM_REG_PPC_DAWRX, 0x00000000);
eb5ceb4d
BH
7680 spr_register_kvm_hv(env, SPR_CIABR, "CIABR",
7681 SPR_NOACCESS, SPR_NOACCESS,
7682 SPR_NOACCESS, SPR_NOACCESS,
7683 &spr_read_generic, &spr_write_generic,
7684 KVM_REG_PPC_CIABR, 0x00000000);
f401dd32
BH
7685}
7686
fd51ff63
AK
7687static void gen_spr_970_dbg(CPUPPCState *env)
7688{
7689 /* Breakpoints */
7690 spr_register(env, SPR_IABR, "IABR",
7691 SPR_NOACCESS, SPR_NOACCESS,
7692 &spr_read_generic, &spr_write_generic,
7693 0x00000000);
7694}
7695
7696static void gen_spr_book3s_pmu_sup(CPUPPCState *env)
7697{
83cc6f8c
AK
7698 spr_register_kvm(env, SPR_POWER_MMCR0, "MMCR0",
7699 SPR_NOACCESS, SPR_NOACCESS,
7700 &spr_read_generic, &spr_write_generic,
7701 KVM_REG_PPC_MMCR0, 0x00000000);
7702 spr_register_kvm(env, SPR_POWER_MMCR1, "MMCR1",
7703 SPR_NOACCESS, SPR_NOACCESS,
7704 &spr_read_generic, &spr_write_generic,
7705 KVM_REG_PPC_MMCR1, 0x00000000);
7706 spr_register_kvm(env, SPR_POWER_MMCRA, "MMCRA",
7707 SPR_NOACCESS, SPR_NOACCESS,
7708 &spr_read_generic, &spr_write_generic,
7709 KVM_REG_PPC_MMCRA, 0x00000000);
7710 spr_register_kvm(env, SPR_POWER_PMC1, "PMC1",
7711 SPR_NOACCESS, SPR_NOACCESS,
7712 &spr_read_generic, &spr_write_generic,
7713 KVM_REG_PPC_PMC1, 0x00000000);
7714 spr_register_kvm(env, SPR_POWER_PMC2, "PMC2",
7715 SPR_NOACCESS, SPR_NOACCESS,
7716 &spr_read_generic, &spr_write_generic,
7717 KVM_REG_PPC_PMC2, 0x00000000);
7718 spr_register_kvm(env, SPR_POWER_PMC3, "PMC3",
7719 SPR_NOACCESS, SPR_NOACCESS,
7720 &spr_read_generic, &spr_write_generic,
7721 KVM_REG_PPC_PMC3, 0x00000000);
7722 spr_register_kvm(env, SPR_POWER_PMC4, "PMC4",
7723 SPR_NOACCESS, SPR_NOACCESS,
7724 &spr_read_generic, &spr_write_generic,
7725 KVM_REG_PPC_PMC4, 0x00000000);
7726 spr_register_kvm(env, SPR_POWER_PMC5, "PMC5",
7727 SPR_NOACCESS, SPR_NOACCESS,
7728 &spr_read_generic, &spr_write_generic,
7729 KVM_REG_PPC_PMC5, 0x00000000);
7730 spr_register_kvm(env, SPR_POWER_PMC6, "PMC6",
7731 SPR_NOACCESS, SPR_NOACCESS,
7732 &spr_read_generic, &spr_write_generic,
7733 KVM_REG_PPC_PMC6, 0x00000000);
7734 spr_register_kvm(env, SPR_POWER_SIAR, "SIAR",
7735 SPR_NOACCESS, SPR_NOACCESS,
7736 &spr_read_generic, &spr_write_generic,
7737 KVM_REG_PPC_SIAR, 0x00000000);
7738 spr_register_kvm(env, SPR_POWER_SDAR, "SDAR",
7739 SPR_NOACCESS, SPR_NOACCESS,
7740 &spr_read_generic, &spr_write_generic,
7741 KVM_REG_PPC_SDAR, 0x00000000);
fd51ff63
AK
7742}
7743
7744static void gen_spr_book3s_pmu_user(CPUPPCState *env)
7745{
7746 spr_register(env, SPR_POWER_UMMCR0, "UMMCR0",
7747 &spr_read_ureg, SPR_NOACCESS,
7748 &spr_read_ureg, &spr_write_ureg,
7749 0x00000000);
7750 spr_register(env, SPR_POWER_UMMCR1, "UMMCR1",
7751 &spr_read_ureg, SPR_NOACCESS,
7752 &spr_read_ureg, &spr_write_ureg,
7753 0x00000000);
077850b0
AK
7754 spr_register(env, SPR_POWER_UMMCRA, "UMMCRA",
7755 &spr_read_ureg, SPR_NOACCESS,
7756 &spr_read_ureg, &spr_write_ureg,
7757 0x00000000);
fd51ff63
AK
7758 spr_register(env, SPR_POWER_UPMC1, "UPMC1",
7759 &spr_read_ureg, SPR_NOACCESS,
7760 &spr_read_ureg, &spr_write_ureg,
7761 0x00000000);
7762 spr_register(env, SPR_POWER_UPMC2, "UPMC2",
7763 &spr_read_ureg, SPR_NOACCESS,
7764 &spr_read_ureg, &spr_write_ureg,
7765 0x00000000);
7766 spr_register(env, SPR_POWER_UPMC3, "UPMC3",
7767 &spr_read_ureg, SPR_NOACCESS,
7768 &spr_read_ureg, &spr_write_ureg,
7769 0x00000000);
7770 spr_register(env, SPR_POWER_UPMC4, "UPMC4",
7771 &spr_read_ureg, SPR_NOACCESS,
7772 &spr_read_ureg, &spr_write_ureg,
7773 0x00000000);
077850b0
AK
7774 spr_register(env, SPR_POWER_UPMC5, "UPMC5",
7775 &spr_read_ureg, SPR_NOACCESS,
7776 &spr_read_ureg, &spr_write_ureg,
7777 0x00000000);
7778 spr_register(env, SPR_POWER_UPMC6, "UPMC6",
7779 &spr_read_ureg, SPR_NOACCESS,
7780 &spr_read_ureg, &spr_write_ureg,
7781 0x00000000);
fd51ff63
AK
7782 spr_register(env, SPR_POWER_USIAR, "USIAR",
7783 &spr_read_ureg, SPR_NOACCESS,
7784 &spr_read_ureg, &spr_write_ureg,
7785 0x00000000);
077850b0
AK
7786 spr_register(env, SPR_POWER_USDAR, "USDAR",
7787 &spr_read_ureg, SPR_NOACCESS,
7788 &spr_read_ureg, &spr_write_ureg,
7789 0x00000000);
fd51ff63
AK
7790}
7791
c36c97f8
AK
7792static void gen_spr_970_pmu_sup(CPUPPCState *env)
7793{
83cc6f8c
AK
7794 spr_register_kvm(env, SPR_970_PMC7, "PMC7",
7795 SPR_NOACCESS, SPR_NOACCESS,
7796 &spr_read_generic, &spr_write_generic,
7797 KVM_REG_PPC_PMC7, 0x00000000);
7798 spr_register_kvm(env, SPR_970_PMC8, "PMC8",
7799 SPR_NOACCESS, SPR_NOACCESS,
7800 &spr_read_generic, &spr_write_generic,
7801 KVM_REG_PPC_PMC8, 0x00000000);
c36c97f8
AK
7802}
7803
7804static void gen_spr_970_pmu_user(CPUPPCState *env)
7805{
7806 spr_register(env, SPR_970_UPMC7, "UPMC7",
7807 &spr_read_ureg, SPR_NOACCESS,
7808 &spr_read_ureg, &spr_write_ureg,
7809 0x00000000);
7810 spr_register(env, SPR_970_UPMC8, "UPMC8",
7811 &spr_read_ureg, SPR_NOACCESS,
7812 &spr_read_ureg, &spr_write_ureg,
7813 0x00000000);
7814}
7815
70c53407
AK
7816static void gen_spr_power8_pmu_sup(CPUPPCState *env)
7817{
7818 spr_register_kvm(env, SPR_POWER_MMCR2, "MMCR2",
7819 SPR_NOACCESS, SPR_NOACCESS,
7820 &spr_read_generic, &spr_write_generic,
7821 KVM_REG_PPC_MMCR2, 0x00000000);
7822 spr_register_kvm(env, SPR_POWER_MMCRS, "MMCRS",
7823 SPR_NOACCESS, SPR_NOACCESS,
7824 &spr_read_generic, &spr_write_generic,
7825 KVM_REG_PPC_MMCRS, 0x00000000);
14646457
BH
7826 spr_register_kvm(env, SPR_POWER_SIER, "SIER",
7827 SPR_NOACCESS, SPR_NOACCESS,
7828 &spr_read_generic, &spr_write_generic,
7829 KVM_REG_PPC_SIER, 0x00000000);
7830 spr_register_kvm(env, SPR_POWER_SPMC1, "SPMC1",
7831 SPR_NOACCESS, SPR_NOACCESS,
7832 &spr_read_generic, &spr_write_generic,
7833 KVM_REG_PPC_SPMC1, 0x00000000);
7834 spr_register_kvm(env, SPR_POWER_SPMC2, "SPMC2",
7835 SPR_NOACCESS, SPR_NOACCESS,
7836 &spr_read_generic, &spr_write_generic,
7837 KVM_REG_PPC_SPMC2, 0x00000000);
7838 spr_register_kvm(env, SPR_TACR, "TACR",
7839 SPR_NOACCESS, SPR_NOACCESS,
7840 &spr_read_generic, &spr_write_generic,
7841 KVM_REG_PPC_TACR, 0x00000000);
7842 spr_register_kvm(env, SPR_TCSCR, "TCSCR",
7843 SPR_NOACCESS, SPR_NOACCESS,
7844 &spr_read_generic, &spr_write_generic,
7845 KVM_REG_PPC_TCSCR, 0x00000000);
7846 spr_register_kvm(env, SPR_CSIGR, "CSIGR",
7847 SPR_NOACCESS, SPR_NOACCESS,
7848 &spr_read_generic, &spr_write_generic,
7849 KVM_REG_PPC_CSIGR, 0x00000000);
70c53407
AK
7850}
7851
7852static void gen_spr_power8_pmu_user(CPUPPCState *env)
7853{
7854 spr_register(env, SPR_POWER_UMMCR2, "UMMCR2",
7855 &spr_read_ureg, SPR_NOACCESS,
7856 &spr_read_ureg, &spr_write_ureg,
7857 0x00000000);
14646457
BH
7858 spr_register(env, SPR_POWER_USIER, "USIER",
7859 &spr_read_generic, SPR_NOACCESS,
7860 &spr_read_generic, &spr_write_generic,
7861 0x00000000);
70c53407
AK
7862}
7863
fd51ff63
AK
7864static void gen_spr_power5p_ear(CPUPPCState *env)
7865{
7866 /* External access control */
7867 spr_register(env, SPR_EAR, "EAR",
7868 SPR_NOACCESS, SPR_NOACCESS,
7869 &spr_read_generic, &spr_write_generic,
7870 0x00000000);
7871}
7872
f0ec31b1
SJS
7873static void gen_spr_power5p_tb(CPUPPCState *env)
7874{
7875 /* TBU40 (High 40 bits of the Timebase register */
7876 spr_register_hv(env, SPR_TBU40, "TBU40",
7877 SPR_NOACCESS, SPR_NOACCESS,
7878 SPR_NOACCESS, SPR_NOACCESS,
7879 SPR_NOACCESS, &spr_write_tbu40,
7880 0x00000000);
7881}
7882
8eeb330c
BH
7883#if !defined(CONFIG_USER_ONLY)
7884static void spr_write_hmer(DisasContext *ctx, int sprn, int gprn)
7885{
7886 TCGv hmer = tcg_temp_new();
7887
7888 gen_load_spr(hmer, sprn);
7889 tcg_gen_and_tl(hmer, cpu_gpr[gprn], hmer);
7890 gen_store_spr(sprn, hmer);
7891 spr_store_dump_spr(sprn);
7892 tcg_temp_free(hmer);
7893}
4b3fc377
BH
7894
7895static void spr_write_lpcr(DisasContext *ctx, int sprn, int gprn)
7896{
7897 gen_helper_store_lpcr(cpu_env, cpu_gpr[gprn]);
7898}
4b3fc377
BH
7899#endif /* !defined(CONFIG_USER_ONLY) */
7900
7901static void gen_spr_970_lpar(CPUPPCState *env)
7902{
7903#if !defined(CONFIG_USER_ONLY)
19acd4b6
DG
7904 /*
7905 * PPC970: HID4 covers things later controlled by the LPCR and
7906 * RMOR in later CPUs, but with a different encoding. We only
7907 * support the 970 in "Apple mode" which has all hypervisor
7908 * facilities disabled by strapping, so we can basically just
7909 * ignore it
7910 */
4b3fc377
BH
7911 spr_register(env, SPR_970_HID4, "HID4",
7912 SPR_NOACCESS, SPR_NOACCESS,
19acd4b6 7913 &spr_read_generic, &spr_write_generic,
4b3fc377
BH
7914 0x00000000);
7915#endif
7916}
7917
7918static void gen_spr_power5p_lpar(CPUPPCState *env)
7919{
7920#if !defined(CONFIG_USER_ONLY)
7921 /* Logical partitionning */
635dff20
BH
7922 spr_register_kvm_hv(env, SPR_LPCR, "LPCR",
7923 SPR_NOACCESS, SPR_NOACCESS,
7924 SPR_NOACCESS, SPR_NOACCESS,
7925 &spr_read_generic, &spr_write_lpcr,
7926 KVM_REG_PPC_LPCR, LPCR_LPES0 | LPCR_LPES1);
4b236b62
BH
7927 spr_register_hv(env, SPR_HDEC, "HDEC",
7928 SPR_NOACCESS, SPR_NOACCESS,
7929 SPR_NOACCESS, SPR_NOACCESS,
7930 &spr_read_hdecr, &spr_write_hdecr, 0);
8eeb330c 7931#endif
4b3fc377 7932}
8eeb330c 7933
e61716aa
AK
7934static void gen_spr_book3s_ids(CPUPPCState *env)
7935{
8eeb330c
BH
7936 /* FIXME: Will need to deal with thread vs core only SPRs */
7937
e61716aa 7938 /* Processor identification */
8eeb330c 7939 spr_register_hv(env, SPR_PIR, "PIR",
e61716aa 7940 SPR_NOACCESS, SPR_NOACCESS,
bfda32a8 7941 &spr_read_generic, SPR_NOACCESS,
8eeb330c
BH
7942 &spr_read_generic, NULL,
7943 0x00000000);
7944 spr_register_hv(env, SPR_HID0, "HID0",
7945 SPR_NOACCESS, SPR_NOACCESS,
7946 SPR_NOACCESS, SPR_NOACCESS,
7947 &spr_read_generic, &spr_write_generic,
7948 0x00000000);
7949 spr_register_hv(env, SPR_TSCR, "TSCR",
7950 SPR_NOACCESS, SPR_NOACCESS,
7951 SPR_NOACCESS, SPR_NOACCESS,
7952 &spr_read_generic, &spr_write_generic,
7953 0x00000000);
7954 spr_register_hv(env, SPR_HMER, "HMER",
7955 SPR_NOACCESS, SPR_NOACCESS,
7956 SPR_NOACCESS, SPR_NOACCESS,
7957 &spr_read_generic, &spr_write_hmer,
7958 0x00000000);
7959 spr_register_hv(env, SPR_HMEER, "HMEER",
7960 SPR_NOACCESS, SPR_NOACCESS,
7961 SPR_NOACCESS, SPR_NOACCESS,
7962 &spr_read_generic, &spr_write_generic,
7963 0x00000000);
7964 spr_register_hv(env, SPR_TFMR, "TFMR",
7965 SPR_NOACCESS, SPR_NOACCESS,
7966 SPR_NOACCESS, SPR_NOACCESS,
7967 &spr_read_generic, &spr_write_generic,
7968 0x00000000);
7969 spr_register_hv(env, SPR_LPIDR, "LPIDR",
7970 SPR_NOACCESS, SPR_NOACCESS,
7971 SPR_NOACCESS, SPR_NOACCESS,
c4dae9cd 7972 &spr_read_generic, &spr_write_lpidr,
8eeb330c
BH
7973 0x00000000);
7974 spr_register_hv(env, SPR_HFSCR, "HFSCR",
7975 SPR_NOACCESS, SPR_NOACCESS,
7976 SPR_NOACCESS, SPR_NOACCESS,
7977 &spr_read_generic, &spr_write_generic,
7978 0x00000000);
7979 spr_register_hv(env, SPR_MMCRC, "MMCRC",
7980 SPR_NOACCESS, SPR_NOACCESS,
7981 SPR_NOACCESS, SPR_NOACCESS,
7982 &spr_read_generic, &spr_write_generic,
7983 0x00000000);
7984 spr_register_hv(env, SPR_MMCRH, "MMCRH",
7985 SPR_NOACCESS, SPR_NOACCESS,
7986 SPR_NOACCESS, SPR_NOACCESS,
7987 &spr_read_generic, &spr_write_generic,
7988 0x00000000);
7989 spr_register_hv(env, SPR_HSPRG0, "HSPRG0",
7990 SPR_NOACCESS, SPR_NOACCESS,
7991 SPR_NOACCESS, SPR_NOACCESS,
7992 &spr_read_generic, &spr_write_generic,
7993 0x00000000);
7994 spr_register_hv(env, SPR_HSPRG1, "HSPRG1",
7995 SPR_NOACCESS, SPR_NOACCESS,
7996 SPR_NOACCESS, SPR_NOACCESS,
7997 &spr_read_generic, &spr_write_generic,
7998 0x00000000);
7999 spr_register_hv(env, SPR_HSRR0, "HSRR0",
8000 SPR_NOACCESS, SPR_NOACCESS,
8001 SPR_NOACCESS, SPR_NOACCESS,
8002 &spr_read_generic, &spr_write_generic,
8003 0x00000000);
8004 spr_register_hv(env, SPR_HSRR1, "HSRR1",
8005 SPR_NOACCESS, SPR_NOACCESS,
8006 SPR_NOACCESS, SPR_NOACCESS,
8007 &spr_read_generic, &spr_write_generic,
8008 0x00000000);
8009 spr_register_hv(env, SPR_HDAR, "HDAR",
8010 SPR_NOACCESS, SPR_NOACCESS,
8011 SPR_NOACCESS, SPR_NOACCESS,
8012 &spr_read_generic, &spr_write_generic,
8013 0x00000000);
8014 spr_register_hv(env, SPR_HDSISR, "HDSISR",
8015 SPR_NOACCESS, SPR_NOACCESS,
8016 SPR_NOACCESS, SPR_NOACCESS,
8017 &spr_read_generic, &spr_write_generic,
8018 0x00000000);
51671009 8019 spr_register_hv(env, SPR_HRMOR, "HRMOR",
8eeb330c
BH
8020 SPR_NOACCESS, SPR_NOACCESS,
8021 SPR_NOACCESS, SPR_NOACCESS,
8022 &spr_read_generic, &spr_write_generic,
8023 0x00000000);
51671009
DG
8024}
8025
8026static void gen_spr_rmor(CPUPPCState *env)
8027{
8028 spr_register_hv(env, SPR_RMOR, "RMOR",
8eeb330c
BH
8029 SPR_NOACCESS, SPR_NOACCESS,
8030 SPR_NOACCESS, SPR_NOACCESS,
8031 &spr_read_generic, &spr_write_generic,
e61716aa
AK
8032 0x00000000);
8033}
8034
d1a721ab
AK
8035static void gen_spr_power8_ids(CPUPPCState *env)
8036{
8037 /* Thread identification */
8038 spr_register(env, SPR_TIR, "TIR",
8039 SPR_NOACCESS, SPR_NOACCESS,
8040 &spr_read_generic, SPR_NOACCESS,
8041 0x00000000);
8042}
8043
e61716aa
AK
8044static void gen_spr_book3s_purr(CPUPPCState *env)
8045{
8046#if !defined(CONFIG_USER_ONLY)
8047 /* PURR & SPURR: Hack - treat these as aliases for the TB for now */
5cc7e69f
SJS
8048 spr_register_kvm_hv(env, SPR_PURR, "PURR",
8049 &spr_read_purr, SPR_NOACCESS,
8050 &spr_read_purr, SPR_NOACCESS,
8051 &spr_read_purr, &spr_write_purr,
8052 KVM_REG_PPC_PURR, 0x00000000);
8053 spr_register_kvm_hv(env, SPR_SPURR, "SPURR",
8054 &spr_read_purr, SPR_NOACCESS,
8055 &spr_read_purr, SPR_NOACCESS,
8056 &spr_read_purr, &spr_write_purr,
8057 KVM_REG_PPC_SPURR, 0x00000000);
e61716aa
AK
8058#endif
8059}
8060
5db7d4fa
AK
8061static void gen_spr_power6_dbg(CPUPPCState *env)
8062{
8063#if !defined(CONFIG_USER_ONLY)
8064 spr_register(env, SPR_CFAR, "SPR_CFAR",
8065 SPR_NOACCESS, SPR_NOACCESS,
8066 &spr_read_cfar, &spr_write_cfar,
8067 0x00000000);
8068#endif
8069}
8070
8071static void gen_spr_power5p_common(CPUPPCState *env)
8072{
7303f83d
AK
8073 spr_register_kvm(env, SPR_PPR, "PPR",
8074 &spr_read_generic, &spr_write_generic,
8075 &spr_read_generic, &spr_write_generic,
8076 KVM_REG_PPC_PPR, 0x00000000);
5db7d4fa
AK
8077}
8078
8079static void gen_spr_power6_common(CPUPPCState *env)
8080{
8081#if !defined(CONFIG_USER_ONLY)
8082 spr_register_kvm(env, SPR_DSCR, "SPR_DSCR",
8083 SPR_NOACCESS, SPR_NOACCESS,
8084 &spr_read_generic, &spr_write_generic,
8085 KVM_REG_PPC_DSCR, 0x00000000);
8086#endif
8087 /*
8088 * Register PCR to report POWERPC_EXCP_PRIV_REG instead of
6b375544 8089 * POWERPC_EXCP_INVAL_SPR in userspace. Permit hypervisor access.
5db7d4fa 8090 */
6b375544 8091 spr_register_hv(env, SPR_PCR, "PCR",
5db7d4fa
AK
8092 SPR_NOACCESS, SPR_NOACCESS,
8093 SPR_NOACCESS, SPR_NOACCESS,
6b375544 8094 &spr_read_generic, &spr_write_pcr,
5db7d4fa
AK
8095 0x00000000);
8096}
8097
69b058c8 8098static void spr_read_tar(DisasContext *ctx, int gprn, int sprn)
45ed0be1 8099{
69b058c8
PB
8100 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_TAR, sprn, FSCR_IC_TAR);
8101 spr_read_generic(ctx, gprn, sprn);
45ed0be1
AK
8102}
8103
69b058c8 8104static void spr_write_tar(DisasContext *ctx, int sprn, int gprn)
45ed0be1 8105{
69b058c8
PB
8106 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_TAR, sprn, FSCR_IC_TAR);
8107 spr_write_generic(ctx, sprn, gprn);
45ed0be1
AK
8108}
8109
768167ab
AK
8110static void gen_spr_power8_tce_address_control(CPUPPCState *env)
8111{
1e440cbc
TH
8112 spr_register_kvm(env, SPR_TAR, "TAR",
8113 &spr_read_tar, &spr_write_tar,
8114 &spr_read_generic, &spr_write_generic,
8115 KVM_REG_PPC_TAR, 0x00000000);
768167ab
AK
8116}
8117
69b058c8 8118static void spr_read_tm(DisasContext *ctx, int gprn, int sprn)
cdcdda27 8119{
69b058c8
PB
8120 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8121 spr_read_generic(ctx, gprn, sprn);
cdcdda27
AK
8122}
8123
69b058c8 8124static void spr_write_tm(DisasContext *ctx, int sprn, int gprn)
cdcdda27 8125{
69b058c8
PB
8126 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8127 spr_write_generic(ctx, sprn, gprn);
cdcdda27
AK
8128}
8129
69b058c8 8130static void spr_read_tm_upper32(DisasContext *ctx, int gprn, int sprn)
cdcdda27 8131{
69b058c8
PB
8132 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8133 spr_read_prev_upper32(ctx, gprn, sprn);
cdcdda27
AK
8134}
8135
69b058c8 8136static void spr_write_tm_upper32(DisasContext *ctx, int sprn, int gprn)
cdcdda27 8137{
69b058c8
PB
8138 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8139 spr_write_prev_upper32(ctx, sprn, gprn);
cdcdda27
AK
8140}
8141
8142static void gen_spr_power8_tm(CPUPPCState *env)
8143{
8144 spr_register_kvm(env, SPR_TFHAR, "TFHAR",
8145 &spr_read_tm, &spr_write_tm,
8146 &spr_read_tm, &spr_write_tm,
8147 KVM_REG_PPC_TFHAR, 0x00000000);
8148 spr_register_kvm(env, SPR_TFIAR, "TFIAR",
8149 &spr_read_tm, &spr_write_tm,
8150 &spr_read_tm, &spr_write_tm,
8151 KVM_REG_PPC_TFIAR, 0x00000000);
8152 spr_register_kvm(env, SPR_TEXASR, "TEXASR",
8153 &spr_read_tm, &spr_write_tm,
8154 &spr_read_tm, &spr_write_tm,
8155 KVM_REG_PPC_TEXASR, 0x00000000);
8156 spr_register(env, SPR_TEXASRU, "TEXASRU",
8157 &spr_read_tm_upper32, &spr_write_tm_upper32,
8158 &spr_read_tm_upper32, &spr_write_tm_upper32,
8159 0x00000000);
8160}
8161
69b058c8 8162static void spr_read_ebb(DisasContext *ctx, int gprn, int sprn)
4ee4a03b 8163{
69b058c8
PB
8164 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8165 spr_read_generic(ctx, gprn, sprn);
4ee4a03b
AK
8166}
8167
69b058c8 8168static void spr_write_ebb(DisasContext *ctx, int sprn, int gprn)
4ee4a03b 8169{
69b058c8
PB
8170 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8171 spr_write_generic(ctx, sprn, gprn);
4ee4a03b
AK
8172}
8173
69b058c8 8174static void spr_read_ebb_upper32(DisasContext *ctx, int gprn, int sprn)
4ee4a03b 8175{
69b058c8
PB
8176 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8177 spr_read_prev_upper32(ctx, gprn, sprn);
4ee4a03b
AK
8178}
8179
69b058c8 8180static void spr_write_ebb_upper32(DisasContext *ctx, int sprn, int gprn)
4ee4a03b 8181{
69b058c8
PB
8182 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8183 spr_write_prev_upper32(ctx, sprn, gprn);
4ee4a03b
AK
8184}
8185
8186static void gen_spr_power8_ebb(CPUPPCState *env)
8187{
8188 spr_register(env, SPR_BESCRS, "BESCRS",
8189 &spr_read_ebb, &spr_write_ebb,
8190 &spr_read_generic, &spr_write_generic,
8191 0x00000000);
8192 spr_register(env, SPR_BESCRSU, "BESCRSU",
8193 &spr_read_ebb_upper32, &spr_write_ebb_upper32,
8194 &spr_read_prev_upper32, &spr_write_prev_upper32,
8195 0x00000000);
8196 spr_register(env, SPR_BESCRR, "BESCRR",
8197 &spr_read_ebb, &spr_write_ebb,
8198 &spr_read_generic, &spr_write_generic,
8199 0x00000000);
8200 spr_register(env, SPR_BESCRRU, "BESCRRU",
8201 &spr_read_ebb_upper32, &spr_write_ebb_upper32,
8202 &spr_read_prev_upper32, &spr_write_prev_upper32,
8203 0x00000000);
8204 spr_register_kvm(env, SPR_EBBHR, "EBBHR",
8205 &spr_read_ebb, &spr_write_ebb,
8206 &spr_read_generic, &spr_write_generic,
8207 KVM_REG_PPC_EBBHR, 0x00000000);
8208 spr_register_kvm(env, SPR_EBBRR, "EBBRR",
8209 &spr_read_ebb, &spr_write_ebb,
8210 &spr_read_generic, &spr_write_generic,
8211 KVM_REG_PPC_EBBRR, 0x00000000);
8212 spr_register_kvm(env, SPR_BESCR, "BESCR",
8213 &spr_read_ebb, &spr_write_ebb,
8214 &spr_read_generic, &spr_write_generic,
8215 KVM_REG_PPC_BESCR, 0x00000000);
8216}
8217
3ba55e39
CB
8218/* Virtual Time Base */
8219static void gen_spr_vtb(CPUPPCState *env)
8220{
5d62725b
SJS
8221 spr_register_kvm_hv(env, SPR_VTB, "VTB",
8222 SPR_NOACCESS, SPR_NOACCESS,
8223 &spr_read_vtb, SPR_NOACCESS,
8224 &spr_read_vtb, &spr_write_vtb,
8225 KVM_REG_PPC_VTB, 0x00000000);
3ba55e39
CB
8226}
8227
7019cb3d
AK
8228static void gen_spr_power8_fscr(CPUPPCState *env)
8229{
45ed0be1
AK
8230#if defined(CONFIG_USER_ONLY)
8231 target_ulong initval = 1ULL << FSCR_TAR;
8232#else
8233 target_ulong initval = 0;
8234#endif
7019cb3d
AK
8235 spr_register_kvm(env, SPR_FSCR, "FSCR",
8236 SPR_NOACCESS, SPR_NOACCESS,
8237 &spr_read_generic, &spr_write_generic,
45ed0be1 8238 KVM_REG_PPC_FSCR, initval);
7019cb3d
AK
8239}
8240
d6f1445f
TH
8241static void gen_spr_power8_pspb(CPUPPCState *env)
8242{
8243 spr_register_kvm(env, SPR_PSPB, "PSPB",
8244 SPR_NOACCESS, SPR_NOACCESS,
8245 &spr_read_generic, &spr_write_generic32,
8246 KVM_REG_PPC_PSPB, 0);
8247}
8248
cfc61ba6
AK
8249static void gen_spr_power8_dpdes(CPUPPCState *env)
8250{
8251#if !defined(CONFIG_USER_ONLY)
8252 /* Directed Privileged Door-bell Exception State, used for IPI */
5ba7ba1d
CLG
8253 spr_register_kvm_hv(env, SPR_DPDES, "DPDES",
8254 SPR_NOACCESS, SPR_NOACCESS,
8255 &spr_read_dpdes, SPR_NOACCESS,
8256 &spr_read_dpdes, &spr_write_dpdes,
8257 KVM_REG_PPC_DPDES, 0x00000000);
cfc61ba6
AK
8258#endif
8259}
8260
21a558be
BH
8261static void gen_spr_power8_ic(CPUPPCState *env)
8262{
8263#if !defined(CONFIG_USER_ONLY)
8264 spr_register_hv(env, SPR_IC, "IC",
8265 SPR_NOACCESS, SPR_NOACCESS,
8266 &spr_read_generic, SPR_NOACCESS,
8267 &spr_read_generic, &spr_write_generic,
8268 0);
9d0e5c8c
CLG
8269#endif
8270}
8271
8272static void gen_spr_power8_book4(CPUPPCState *env)
8273{
8274 /* Add a number of P8 book4 registers */
8275#if !defined(CONFIG_USER_ONLY)
9c1cf38d
BH
8276 spr_register_kvm(env, SPR_ACOP, "ACOP",
8277 SPR_NOACCESS, SPR_NOACCESS,
8278 &spr_read_generic, &spr_write_generic,
8279 KVM_REG_PPC_ACOP, 0);
8280 spr_register_kvm(env, SPR_BOOKS_PID, "PID",
8281 SPR_NOACCESS, SPR_NOACCESS,
31b2b0f8 8282 &spr_read_generic, &spr_write_pidr,
9c1cf38d
BH
8283 KVM_REG_PPC_PID, 0);
8284 spr_register_kvm(env, SPR_WORT, "WORT",
8285 SPR_NOACCESS, SPR_NOACCESS,
8286 &spr_read_generic, &spr_write_generic,
8287 KVM_REG_PPC_WORT, 0);
21a558be
BH
8288#endif
8289}
8290
8eb0f563
BH
8291static void gen_spr_power7_book4(CPUPPCState *env)
8292{
8293 /* Add a number of P7 book4 registers */
8294#if !defined(CONFIG_USER_ONLY)
8295 spr_register_kvm(env, SPR_ACOP, "ACOP",
8296 SPR_NOACCESS, SPR_NOACCESS,
8297 &spr_read_generic, &spr_write_generic,
8298 KVM_REG_PPC_ACOP, 0);
8299 spr_register_kvm(env, SPR_BOOKS_PID, "PID",
8300 SPR_NOACCESS, SPR_NOACCESS,
8301 &spr_read_generic, &spr_write_generic,
8302 KVM_REG_PPC_PID, 0);
8303#endif
8304}
8305
8eeb330c
BH
8306static void gen_spr_power8_rpr(CPUPPCState *env)
8307{
8308#if !defined(CONFIG_USER_ONLY)
8309 spr_register_hv(env, SPR_RPR, "RPR",
8310 SPR_NOACCESS, SPR_NOACCESS,
8311 SPR_NOACCESS, SPR_NOACCESS,
8312 &spr_read_generic, &spr_write_generic,
8313 0x00000103070F1F3F);
8314#endif
8315}
8316
4a7518e0
CLG
8317static void gen_spr_power9_mmu(CPUPPCState *env)
8318{
8319#if !defined(CONFIG_USER_ONLY)
8320 /* Partition Table Control */
56de52ca
SJS
8321 spr_register_kvm_hv(env, SPR_PTCR, "PTCR",
8322 SPR_NOACCESS, SPR_NOACCESS,
8323 SPR_NOACCESS, SPR_NOACCESS,
8324 &spr_read_generic, &spr_write_ptcr,
8325 KVM_REG_PPC_PTCR, 0x00000000);
32d0f0d8
SJS
8326 /* Address Segment Descriptor Register */
8327 spr_register_hv(env, SPR_ASDR, "ASDR",
8328 SPR_NOACCESS, SPR_NOACCESS,
8329 SPR_NOACCESS, SPR_NOACCESS,
8330 &spr_read_generic, &spr_write_generic,
8331 0x0000000000000000);
4a7518e0
CLG
8332#endif
8333}
8334
4f4f28ff 8335static void init_proc_book3s_common(CPUPPCState *env)
42382f62
AK
8336{
8337 gen_spr_ne_601(env);
42382f62 8338 gen_tbl(env);
b1c897d5 8339 gen_spr_usprg3(env);
42382f62 8340 gen_spr_book3s_altivec(env);
fd51ff63
AK
8341 gen_spr_book3s_pmu_sup(env);
8342 gen_spr_book3s_pmu_user(env);
4f4f28ff
SJS
8343 gen_spr_book3s_ctrl(env);
8344}
fd51ff63 8345
4f4f28ff
SJS
8346static void init_proc_970(CPUPPCState *env)
8347{
8348 /* Common Registers */
8349 init_proc_book3s_common(env);
8350 gen_spr_sdr1(env);
8351 gen_spr_book3s_dbg(env);
8352
8353 /* 970 Specific Registers */
8354 gen_spr_970_hid(env);
8355 gen_spr_970_hior(env);
8356 gen_low_BATs(env);
8357 gen_spr_970_pmu_sup(env);
8358 gen_spr_970_pmu_user(env);
8359 gen_spr_970_lpar(env);
8360 gen_spr_970_dbg(env);
8361
8362 /* env variables */
d63001d1
JM
8363 env->dcache_line_size = 128;
8364 env->icache_line_size = 128;
a750fc0b 8365
4f4f28ff
SJS
8366 /* Allocate hardware IRQ controller */
8367 init_excp_970(env);
db70b311 8368 ppc970_irq_init(env_archcpu(env));
7488d481
AK
8369}
8370
bbc01ca7 8371POWERPC_FAMILY(970)(ObjectClass *oc, void *data)
7856e3a4 8372{
ca5dff0a 8373 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
8374 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8375
bbc01ca7
AK
8376 dc->desc = "PowerPC 970";
8377 pcc->init_proc = init_proc_970;
8378 pcc->check_pow = check_pow_970;
53116ebf
AF
8379 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
8380 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8381 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
8382 PPC_FLOAT_STFIWX |
8383 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8384 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8385 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
8386 PPC_64B | PPC_ALTIVEC |
8387 PPC_SEGMENT_64B | PPC_SLBI;
4171853c 8388 pcc->insns_flags2 = PPC2_FP_CVT_S64;
9df5a466
TM
8389 pcc->msr_mask = (1ull << MSR_SF) |
8390 (1ull << MSR_VR) |
8391 (1ull << MSR_POW) |
8392 (1ull << MSR_EE) |
8393 (1ull << MSR_PR) |
8394 (1ull << MSR_FP) |
8395 (1ull << MSR_ME) |
8396 (1ull << MSR_FE0) |
8397 (1ull << MSR_SE) |
8398 (1ull << MSR_DE) |
8399 (1ull << MSR_FE1) |
8400 (1ull << MSR_IR) |
8401 (1ull << MSR_DR) |
8402 (1ull << MSR_PMM) |
8403 (1ull << MSR_RI);
ba9fd9f1 8404 pcc->mmu_model = POWERPC_MMU_64B;
b632a148
DG
8405#if defined(CONFIG_SOFTMMU)
8406 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
21e405f1 8407 pcc->hash64_opts = &ppc_hash64_opts_basic;
b632a148 8408#endif
ba9fd9f1
AF
8409 pcc->excp_model = POWERPC_EXCP_970;
8410 pcc->bus_model = PPC_FLAGS_INPUT_970;
8411 pcc->bfd_mach = bfd_mach_ppc64;
8412 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8413 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8414 POWERPC_FLAG_BUS_CLK;
06f6e124
AG
8415 pcc->l1_dcache_size = 0x8000;
8416 pcc->l1_icache_size = 0x10000;
7856e3a4
AF
8417}
8418
35ebcb2b
AF
8419static void init_proc_power5plus(CPUPPCState *env)
8420{
4f4f28ff
SJS
8421 /* Common Registers */
8422 init_proc_book3s_common(env);
8423 gen_spr_sdr1(env);
8424 gen_spr_book3s_dbg(env);
8425
8426 /* POWER5+ Specific Registers */
8427 gen_spr_970_hid(env);
8428 gen_spr_970_hior(env);
8429 gen_low_BATs(env);
8430 gen_spr_970_pmu_sup(env);
8431 gen_spr_970_pmu_user(env);
8432 gen_spr_power5p_common(env);
8433 gen_spr_power5p_lpar(env);
8434 gen_spr_power5p_ear(env);
f0ec31b1 8435 gen_spr_power5p_tb(env);
4f4f28ff
SJS
8436
8437 /* env variables */
4f4f28ff
SJS
8438 env->dcache_line_size = 128;
8439 env->icache_line_size = 128;
8440
8441 /* Allocate hardware IRQ controller */
8442 init_excp_970(env);
db70b311 8443 ppc970_irq_init(env_archcpu(env));
35ebcb2b
AF
8444}
8445
8446POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data)
8447{
8448 DeviceClass *dc = DEVICE_CLASS(oc);
8449 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8450
793826cd 8451 dc->fw_name = "PowerPC,POWER5";
35ebcb2b
AF
8452 dc->desc = "POWER5+";
8453 pcc->init_proc = init_proc_power5plus;
90618f4f 8454 pcc->check_pow = check_pow_970;
35ebcb2b
AF
8455 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
8456 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8457 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
8458 PPC_FLOAT_STFIWX |
8459 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8460 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8461 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
8462 PPC_64B |
8463 PPC_SEGMENT_64B | PPC_SLBI;
4171853c 8464 pcc->insns_flags2 = PPC2_FP_CVT_S64;
9df5a466
TM
8465 pcc->msr_mask = (1ull << MSR_SF) |
8466 (1ull << MSR_VR) |
8467 (1ull << MSR_POW) |
8468 (1ull << MSR_EE) |
8469 (1ull << MSR_PR) |
8470 (1ull << MSR_FP) |
8471 (1ull << MSR_ME) |
8472 (1ull << MSR_FE0) |
8473 (1ull << MSR_SE) |
8474 (1ull << MSR_DE) |
8475 (1ull << MSR_FE1) |
8476 (1ull << MSR_IR) |
8477 (1ull << MSR_DR) |
8478 (1ull << MSR_PMM) |
8479 (1ull << MSR_RI);
e232eccc
DG
8480 pcc->lpcr_mask = LPCR_RMLS | LPCR_ILE | LPCR_LPES0 | LPCR_LPES1 |
8481 LPCR_RMI | LPCR_HDICE;
aa4bb587 8482 pcc->mmu_model = POWERPC_MMU_2_03;
35ebcb2b
AF
8483#if defined(CONFIG_SOFTMMU)
8484 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
21e405f1 8485 pcc->hash64_opts = &ppc_hash64_opts_basic;
a8dafa52 8486 pcc->lrg_decr_bits = 32;
35ebcb2b
AF
8487#endif
8488 pcc->excp_model = POWERPC_EXCP_970;
8489 pcc->bus_model = PPC_FLAGS_INPUT_970;
8490 pcc->bfd_mach = bfd_mach_ppc64;
8491 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8492 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8493 POWERPC_FLAG_BUS_CLK;
06f6e124
AG
8494 pcc->l1_dcache_size = 0x8000;
8495 pcc->l1_icache_size = 0x10000;
35ebcb2b
AF
8496}
8497
c364946d 8498static void init_proc_POWER7(CPUPPCState *env)
9d52e907 8499{
4f4f28ff
SJS
8500 /* Common Registers */
8501 init_proc_book3s_common(env);
8502 gen_spr_sdr1(env);
8503 gen_spr_book3s_dbg(env);
8504
8505 /* POWER7 Specific Registers */
8506 gen_spr_book3s_ids(env);
51671009 8507 gen_spr_rmor(env);
4f4f28ff
SJS
8508 gen_spr_amr(env);
8509 gen_spr_book3s_purr(env);
8510 gen_spr_power5p_common(env);
8511 gen_spr_power5p_lpar(env);
8512 gen_spr_power5p_ear(env);
f0ec31b1 8513 gen_spr_power5p_tb(env);
4f4f28ff
SJS
8514 gen_spr_power6_common(env);
8515 gen_spr_power6_dbg(env);
8516 gen_spr_power7_book4(env);
8517
8518 /* env variables */
4f4f28ff
SJS
8519 env->dcache_line_size = 128;
8520 env->icache_line_size = 128;
8521
8522 /* Allocate hardware IRQ controller */
8523 init_excp_POWER7(env);
db70b311 8524 ppcPOWER7_irq_init(env_archcpu(env));
9d52e907 8525}
9d52e907 8526
03ae4133
AK
8527static bool ppc_pvr_match_power7(PowerPCCPUClass *pcc, uint32_t pvr)
8528{
8529 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7P_BASE) {
8530 return true;
8531 }
8532 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7_BASE) {
8533 return true;
8534 }
8535 return false;
8536}
8537
7778a575
BH
8538static bool cpu_has_work_POWER7(CPUState *cs)
8539{
8540 PowerPCCPU *cpu = POWERPC_CPU(cs);
8541 CPUPPCState *env = &cpu->env;
8542
8543 if (cs->halted) {
8544 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
8545 return false;
8546 }
8547 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
8548 (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) {
8549 return true;
8550 }
8551 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
8552 (env->spr[SPR_LPCR] & LPCR_P7_PECE1)) {
8553 return true;
8554 }
8555 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
8556 (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
8557 return true;
8558 }
8559 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
8560 (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
8561 return true;
8562 }
8563 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
8564 return true;
8565 }
8566 return false;
8567 } else {
8568 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
8569 }
8570}
8571
7856e3a4
AF
8572POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
8573{
ca5dff0a 8574 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4 8575 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7778a575 8576 CPUClass *cc = CPU_CLASS(oc);
7856e3a4 8577
793826cd 8578 dc->fw_name = "PowerPC,POWER7";
ca5dff0a 8579 dc->desc = "POWER7";
03ae4133 8580 pcc->pvr_match = ppc_pvr_match_power7;
8cd2ce7a
TH
8581 pcc->pcr_mask = PCR_VEC_DIS | PCR_VSX_DIS | PCR_COMPAT_2_05;
8582 pcc->pcr_supported = PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
7856e3a4
AF
8583 pcc->init_proc = init_proc_POWER7;
8584 pcc->check_pow = check_pow_nocheck;
7778a575 8585 cc->has_work = cpu_has_work_POWER7;
e71ec2e9 8586 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
53116ebf
AF
8587 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8588 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
ce8ca30b 8589 PPC_FLOAT_FRSQRTES |
53116ebf 8590 PPC_FLOAT_STFIWX |
c7386080 8591 PPC_FLOAT_EXT |
53116ebf
AF
8592 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8593 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8594 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
dfdd3e43 8595 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
53116ebf 8596 PPC_SEGMENT_64B | PPC_SLBI |
b7815375
BH
8597 PPC_POPCNTB | PPC_POPCNTWD |
8598 PPC_CILDST;
86ba37ed 8599 pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
1fa6c533 8600 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
29a0e4e9 8601 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
7778a575
BH
8602 PPC2_FP_TST_ISA206 | PPC2_FP_CVT_S64 |
8603 PPC2_PM_ISA206;
9df5a466
TM
8604 pcc->msr_mask = (1ull << MSR_SF) |
8605 (1ull << MSR_VR) |
8606 (1ull << MSR_VSX) |
8607 (1ull << MSR_EE) |
8608 (1ull << MSR_PR) |
8609 (1ull << MSR_FP) |
8610 (1ull << MSR_ME) |
8611 (1ull << MSR_FE0) |
8612 (1ull << MSR_SE) |
8613 (1ull << MSR_DE) |
8614 (1ull << MSR_FE1) |
8615 (1ull << MSR_IR) |
8616 (1ull << MSR_DR) |
8617 (1ull << MSR_PMM) |
8618 (1ull << MSR_RI) |
8619 (1ull << MSR_LE);
e232eccc
DG
8620 pcc->lpcr_mask = LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_DPFD |
8621 LPCR_VRMASD | LPCR_RMLS | LPCR_ILE |
8622 LPCR_P7_PECE0 | LPCR_P7_PECE1 | LPCR_P7_PECE2 |
8623 LPCR_MER | LPCR_TC |
8624 LPCR_LPES0 | LPCR_LPES1 | LPCR_HDICE;
8625 pcc->lpcr_pm = LPCR_P7_PECE0 | LPCR_P7_PECE1 | LPCR_P7_PECE2;
ba9fd9f1 8626 pcc->mmu_model = POWERPC_MMU_2_06;
b632a148
DG
8627#if defined(CONFIG_SOFTMMU)
8628 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
b07c59f7 8629 pcc->hash64_opts = &ppc_hash64_opts_POWER7;
a8dafa52 8630 pcc->lrg_decr_bits = 32;
b650d6a2
AK
8631#endif
8632 pcc->excp_model = POWERPC_EXCP_POWER7;
8633 pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
8634 pcc->bfd_mach = bfd_mach_ppc64;
8635 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8636 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8637 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
8638 POWERPC_FLAG_VSX;
8639 pcc->l1_dcache_size = 0x8000;
8640 pcc->l1_icache_size = 0x8000;
382d2db6 8641 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
b650d6a2
AK
8642}
8643
60511041
TM
8644static void init_proc_POWER8(CPUPPCState *env)
8645{
4f4f28ff
SJS
8646 /* Common Registers */
8647 init_proc_book3s_common(env);
8648 gen_spr_sdr1(env);
8649 gen_spr_book3s_207_dbg(env);
8650
8651 /* POWER8 Specific Registers */
8652 gen_spr_book3s_ids(env);
51671009 8653 gen_spr_rmor(env);
4f4f28ff
SJS
8654 gen_spr_amr(env);
8655 gen_spr_iamr(env);
8656 gen_spr_book3s_purr(env);
8657 gen_spr_power5p_common(env);
8658 gen_spr_power5p_lpar(env);
8659 gen_spr_power5p_ear(env);
f0ec31b1 8660 gen_spr_power5p_tb(env);
4f4f28ff
SJS
8661 gen_spr_power6_common(env);
8662 gen_spr_power6_dbg(env);
8663 gen_spr_power8_tce_address_control(env);
8664 gen_spr_power8_ids(env);
8665 gen_spr_power8_ebb(env);
8666 gen_spr_power8_fscr(env);
8667 gen_spr_power8_pmu_sup(env);
8668 gen_spr_power8_pmu_user(env);
8669 gen_spr_power8_tm(env);
8670 gen_spr_power8_pspb(env);
cfc61ba6 8671 gen_spr_power8_dpdes(env);
4f4f28ff
SJS
8672 gen_spr_vtb(env);
8673 gen_spr_power8_ic(env);
8674 gen_spr_power8_book4(env);
8675 gen_spr_power8_rpr(env);
8676
8677 /* env variables */
4f4f28ff
SJS
8678 env->dcache_line_size = 128;
8679 env->icache_line_size = 128;
8680
8681 /* Allocate hardware IRQ controller */
8682 init_excp_POWER8(env);
db70b311 8683 ppcPOWER7_irq_init(env_archcpu(env));
60511041
TM
8684}
8685
03ae4133
AK
8686static bool ppc_pvr_match_power8(PowerPCCPUClass *pcc, uint32_t pvr)
8687{
a88dced8
AK
8688 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8NVL_BASE) {
8689 return true;
8690 }
03ae4133
AK
8691 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8E_BASE) {
8692 return true;
8693 }
8694 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8_BASE) {
8695 return true;
8696 }
8697 return false;
8698}
8699
7778a575
BH
8700static bool cpu_has_work_POWER8(CPUState *cs)
8701{
8702 PowerPCCPU *cpu = POWERPC_CPU(cs);
8703 CPUPPCState *env = &cpu->env;
8704
8705 if (cs->halted) {
8706 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
8707 return false;
8708 }
8709 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
8710 (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) {
8711 return true;
8712 }
8713 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
8714 (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) {
8715 return true;
8716 }
8717 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
8718 (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
8719 return true;
8720 }
8721 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
8722 (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
8723 return true;
8724 }
8725 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
8726 (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) {
8727 return true;
8728 }
8729 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
8730 (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) {
8731 return true;
8732 }
8733 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
8734 return true;
8735 }
8736 return false;
8737 } else {
8738 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
8739 }
8740}
8741
b60c6007 8742POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
8d43ea1c
PS
8743{
8744 DeviceClass *dc = DEVICE_CLASS(oc);
8745 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7778a575 8746 CPUClass *cc = CPU_CLASS(oc);
8d43ea1c 8747
793826cd 8748 dc->fw_name = "PowerPC,POWER8";
b60c6007 8749 dc->desc = "POWER8";
03ae4133 8750 pcc->pvr_match = ppc_pvr_match_power8;
8cd2ce7a
TH
8751 pcc->pcr_mask = PCR_TM_DIS | PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
8752 pcc->pcr_supported = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
60511041 8753 pcc->init_proc = init_proc_POWER8;
8d43ea1c 8754 pcc->check_pow = check_pow_nocheck;
7778a575 8755 cc->has_work = cpu_has_work_POWER8;
536492eb 8756 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
8d43ea1c
PS
8757 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8758 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
ce8ca30b 8759 PPC_FLOAT_FRSQRTES |
8d43ea1c 8760 PPC_FLOAT_STFIWX |
c7386080 8761 PPC_FLOAT_EXT |
8d43ea1c
PS
8762 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8763 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8764 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
4e080611 8765 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
8d43ea1c 8766 PPC_SEGMENT_64B | PPC_SLBI |
b7815375
BH
8767 PPC_POPCNTB | PPC_POPCNTWD |
8768 PPC_CILDST;
86ba37ed 8769 pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
1fa6c533 8770 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
29a0e4e9 8771 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
38a85337 8772 PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
df99d30d 8773 PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
3e28c5e3 8774 PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
7778a575 8775 PPC2_TM | PPC2_PM_ISA206;
9df5a466 8776 pcc->msr_mask = (1ull << MSR_SF) |
23513f81 8777 (1ull << MSR_HV) |
cdcdda27 8778 (1ull << MSR_TM) |
9df5a466
TM
8779 (1ull << MSR_VR) |
8780 (1ull << MSR_VSX) |
8781 (1ull << MSR_EE) |
8782 (1ull << MSR_PR) |
8783 (1ull << MSR_FP) |
8784 (1ull << MSR_ME) |
8785 (1ull << MSR_FE0) |
8786 (1ull << MSR_SE) |
8787 (1ull << MSR_DE) |
8788 (1ull << MSR_FE1) |
8789 (1ull << MSR_IR) |
8790 (1ull << MSR_DR) |
8791 (1ull << MSR_PMM) |
8792 (1ull << MSR_RI) |
21b786f6
SG
8793 (1ull << MSR_TS0) |
8794 (1ull << MSR_TS1) |
9df5a466 8795 (1ull << MSR_LE);
e232eccc
DG
8796 pcc->lpcr_mask = LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV |
8797 LPCR_DPFD | LPCR_VRMASD | LPCR_RMLS | LPCR_ILE |
8798 LPCR_AIL | LPCR_ONL | LPCR_P8_PECE0 | LPCR_P8_PECE1 |
8799 LPCR_P8_PECE2 | LPCR_P8_PECE3 | LPCR_P8_PECE4 |
8800 LPCR_MER | LPCR_TC | LPCR_LPES0 | LPCR_HDICE;
8801 pcc->lpcr_pm = LPCR_P8_PECE0 | LPCR_P8_PECE1 | LPCR_P8_PECE2 |
8802 LPCR_P8_PECE3 | LPCR_P8_PECE4;
aa4bb587 8803 pcc->mmu_model = POWERPC_MMU_2_07;
8d43ea1c
PS
8804#if defined(CONFIG_SOFTMMU)
8805 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
b07c59f7 8806 pcc->hash64_opts = &ppc_hash64_opts_POWER7;
a8dafa52 8807 pcc->lrg_decr_bits = 32;
289af4ac 8808 pcc->n_host_threads = 8;
706d6467
AK
8809#endif
8810 pcc->excp_model = POWERPC_EXCP_POWER8;
8811 pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
8812 pcc->bfd_mach = bfd_mach_ppc64;
8813 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8814 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8815 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
8816 POWERPC_FLAG_VSX | POWERPC_FLAG_TM;
8817 pcc->l1_dcache_size = 0x8000;
8818 pcc->l1_icache_size = 0x8000;
8819 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
8820}
4f4f28ff 8821
ccd531b9
SJS
8822#ifdef CONFIG_SOFTMMU
8823/*
8824 * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings
8825 * Encoded as array of int_32s in the form:
8826 * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
8827 * x -> AP encoding
8828 * y -> radix mode supported page size (encoded as a shift)
8829 */
8830static struct ppc_radix_page_info POWER9_radix_page_info = {
8831 .count = 4,
8832 .entries = {
8833 0x0000000c, /* 4K - enc: 0x0 */
8834 0xa0000010, /* 64K - enc: 0x5 */
8835 0x20000015, /* 2M - enc: 0x1 */
8836 0x4000001e /* 1G - enc: 0x2 */
8837 }
8838};
8839#endif /* CONFIG_SOFTMMU */
8840
706d6467
AK
8841static void init_proc_POWER9(CPUPPCState *env)
8842{
4f4f28ff
SJS
8843 /* Common Registers */
8844 init_proc_book3s_common(env);
8845 gen_spr_book3s_207_dbg(env);
8846
8847 /* POWER8 Specific Registers */
8848 gen_spr_book3s_ids(env);
8849 gen_spr_amr(env);
8850 gen_spr_iamr(env);
8851 gen_spr_book3s_purr(env);
8852 gen_spr_power5p_common(env);
8853 gen_spr_power5p_lpar(env);
8854 gen_spr_power5p_ear(env);
f0ec31b1 8855 gen_spr_power5p_tb(env);
4f4f28ff
SJS
8856 gen_spr_power6_common(env);
8857 gen_spr_power6_dbg(env);
8858 gen_spr_power8_tce_address_control(env);
8859 gen_spr_power8_ids(env);
8860 gen_spr_power8_ebb(env);
8861 gen_spr_power8_fscr(env);
8862 gen_spr_power8_pmu_sup(env);
8863 gen_spr_power8_pmu_user(env);
8864 gen_spr_power8_tm(env);
8865 gen_spr_power8_pspb(env);
cfc61ba6 8866 gen_spr_power8_dpdes(env);
4f4f28ff
SJS
8867 gen_spr_vtb(env);
8868 gen_spr_power8_ic(env);
8869 gen_spr_power8_book4(env);
8870 gen_spr_power8_rpr(env);
4a7518e0 8871 gen_spr_power9_mmu(env);
4f4f28ff 8872
650f3287
DG
8873 /* POWER9 Specific registers */
8874 spr_register_kvm(env, SPR_TIDR, "TIDR", NULL, NULL,
8875 spr_read_generic, spr_write_generic,
8876 KVM_REG_PPC_TIDR, 0);
8877
b8af5b2d
DG
8878 /* FIXME: Filter fields properly based on privilege level */
8879 spr_register_kvm_hv(env, SPR_PSSCR, "PSSCR", NULL, NULL, NULL, NULL,
8880 spr_read_generic, spr_write_generic,
8881 KVM_REG_PPC_PSSCR, 0);
8882
4f4f28ff 8883 /* env variables */
4f4f28ff
SJS
8884 env->dcache_line_size = 128;
8885 env->icache_line_size = 128;
8886
8887 /* Allocate hardware IRQ controller */
d8ce5fd6 8888 init_excp_POWER9(env);
db70b311 8889 ppcPOWER9_irq_init(env_archcpu(env));
706d6467
AK
8890}
8891
8892static bool ppc_pvr_match_power9(PowerPCCPUClass *pcc, uint32_t pvr)
8893{
8894 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER9_BASE) {
8895 return true;
8896 }
8897 return false;
8898}
8899
6f46dcb3
SJS
8900static bool cpu_has_work_POWER9(CPUState *cs)
8901{
8902 PowerPCCPU *cpu = POWERPC_CPU(cs);
8903 CPUPPCState *env = &cpu->env;
8904
8905 if (cs->halted) {
21c0d66a
BH
8906 uint64_t psscr = env->spr[SPR_PSSCR];
8907
6f46dcb3
SJS
8908 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
8909 return false;
8910 }
21c0d66a
BH
8911
8912 /* If EC is clear, just return true on any pending interrupt */
8913 if (!(psscr & PSSCR_EC)) {
8914 return true;
8915 }
6f46dcb3
SJS
8916 /* External Exception */
8917 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
8918 (env->spr[SPR_LPCR] & LPCR_EEE)) {
6eebe6dc
BH
8919 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
8920 if (heic == 0 || !msr_hv || msr_pr) {
8921 return true;
8922 }
6f46dcb3
SJS
8923 }
8924 /* Decrementer Exception */
8925 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
8926 (env->spr[SPR_LPCR] & LPCR_DEE)) {
8927 return true;
8928 }
8929 /* Machine Check or Hypervisor Maintenance Exception */
8930 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK |
8931 1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) {
8932 return true;
8933 }
8934 /* Privileged Doorbell Exception */
8935 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
8936 (env->spr[SPR_LPCR] & LPCR_PDEE)) {
8937 return true;
8938 }
8939 /* Hypervisor Doorbell Exception */
8940 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
8941 (env->spr[SPR_LPCR] & LPCR_HDEE)) {
8942 return true;
8943 }
d8ce5fd6
BH
8944 /* Hypervisor virtualization exception */
8945 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HVIRT)) &&
8946 (env->spr[SPR_LPCR] & LPCR_HVEE)) {
8947 return true;
8948 }
6f46dcb3
SJS
8949 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
8950 return true;
8951 }
8952 return false;
8953 } else {
8954 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
8955 }
8956}
8957
706d6467
AK
8958POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
8959{
8960 DeviceClass *dc = DEVICE_CLASS(oc);
8961 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6f46dcb3 8962 CPUClass *cc = CPU_CLASS(oc);
706d6467
AK
8963
8964 dc->fw_name = "PowerPC,POWER9";
8965 dc->desc = "POWER9";
706d6467
AK
8966 pcc->pvr_match = ppc_pvr_match_power9;
8967 pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07;
216c944e
SJS
8968 pcc->pcr_supported = PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 |
8969 PCR_COMPAT_2_05;
706d6467
AK
8970 pcc->init_proc = init_proc_POWER9;
8971 pcc->check_pow = check_pow_nocheck;
6f46dcb3 8972 cc->has_work = cpu_has_work_POWER9;
706d6467
AK
8973 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
8974 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8975 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
8976 PPC_FLOAT_FRSQRTES |
8977 PPC_FLOAT_STFIWX |
8978 PPC_FLOAT_EXT |
8979 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8980 PPC_MEM_SYNC | PPC_MEM_EIEIO |
c8830502 8981 PPC_MEM_TLBSYNC |
da874d90 8982 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
706d6467
AK
8983 PPC_SEGMENT_64B | PPC_SLBI |
8984 PPC_POPCNTB | PPC_POPCNTWD |
8985 PPC_CILDST;
8986 pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
8987 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
8988 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
8989 PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
8990 PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
8991 PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
316aed64 8992 PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL;
706d6467 8993 pcc->msr_mask = (1ull << MSR_SF) |
23513f81 8994 (1ull << MSR_HV) |
706d6467
AK
8995 (1ull << MSR_TM) |
8996 (1ull << MSR_VR) |
8997 (1ull << MSR_VSX) |
8998 (1ull << MSR_EE) |
8999 (1ull << MSR_PR) |
9000 (1ull << MSR_FP) |
9001 (1ull << MSR_ME) |
9002 (1ull << MSR_FE0) |
9003 (1ull << MSR_SE) |
9004 (1ull << MSR_DE) |
9005 (1ull << MSR_FE1) |
9006 (1ull << MSR_IR) |
9007 (1ull << MSR_DR) |
9008 (1ull << MSR_PMM) |
9009 (1ull << MSR_RI) |
9010 (1ull << MSR_LE);
e232eccc
DG
9011 pcc->lpcr_mask = LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD |
9012 (LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL |
9013 LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR | LPCR_LD |
9014 (LPCR_PECE_L_MASK & (LPCR_PDEE | LPCR_HDEE | LPCR_EEE |
9015 LPCR_DEE | LPCR_OEE))
9016 | LPCR_MER | LPCR_GTSE | LPCR_TC |
9017 LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE | LPCR_HDICE;
9018 pcc->lpcr_pm = LPCR_PDEE | LPCR_HDEE | LPCR_EEE | LPCR_DEE | LPCR_OEE;
86cf1e9f 9019 pcc->mmu_model = POWERPC_MMU_3_00;
706d6467 9020#if defined(CONFIG_SOFTMMU)
b2899495 9021 pcc->handle_mmu_fault = ppc64_v3_handle_mmu_fault;
706d6467 9022 /* segment page size remain the same */
b07c59f7 9023 pcc->hash64_opts = &ppc_hash64_opts_POWER7;
ccd531b9 9024 pcc->radix_page_info = &POWER9_radix_page_info;
a8dafa52 9025 pcc->lrg_decr_bits = 56;
289af4ac 9026 pcc->n_host_threads = 4;
8d43ea1c 9027#endif
a790e82b 9028 pcc->excp_model = POWERPC_EXCP_POWER9;
67afe775 9029 pcc->bus_model = PPC_FLAGS_INPUT_POWER9;
8d43ea1c
PS
9030 pcc->bfd_mach = bfd_mach_ppc64;
9031 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
9032 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
74f23997 9033 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
3c89b8d6 9034 POWERPC_FLAG_VSX | POWERPC_FLAG_TM | POWERPC_FLAG_SCV;
8d43ea1c
PS
9035 pcc->l1_dcache_size = 0x8000;
9036 pcc->l1_icache_size = 0x8000;
382d2db6 9037 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
8d43ea1c 9038}
a750fc0b 9039
7d37b274
CLG
9040#ifdef CONFIG_SOFTMMU
9041/*
9042 * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings
9043 * Encoded as array of int_32s in the form:
9044 * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
9045 * x -> AP encoding
9046 * y -> radix mode supported page size (encoded as a shift)
9047 */
9048static struct ppc_radix_page_info POWER10_radix_page_info = {
9049 .count = 4,
9050 .entries = {
9051 0x0000000c, /* 4K - enc: 0x0 */
9052 0xa0000010, /* 64K - enc: 0x5 */
9053 0x20000015, /* 2M - enc: 0x1 */
9054 0x4000001e /* 1G - enc: 0x2 */
9055 }
9056};
9057#endif /* CONFIG_SOFTMMU */
9058
9059static void init_proc_POWER10(CPUPPCState *env)
9060{
9061 /* Common Registers */
9062 init_proc_book3s_common(env);
9063 gen_spr_book3s_207_dbg(env);
9064
9065 /* POWER8 Specific Registers */
9066 gen_spr_book3s_ids(env);
9067 gen_spr_amr(env);
9068 gen_spr_iamr(env);
9069 gen_spr_book3s_purr(env);
9070 gen_spr_power5p_common(env);
9071 gen_spr_power5p_lpar(env);
9072 gen_spr_power5p_ear(env);
9073 gen_spr_power6_common(env);
9074 gen_spr_power6_dbg(env);
9075 gen_spr_power8_tce_address_control(env);
9076 gen_spr_power8_ids(env);
9077 gen_spr_power8_ebb(env);
9078 gen_spr_power8_fscr(env);
9079 gen_spr_power8_pmu_sup(env);
9080 gen_spr_power8_pmu_user(env);
9081 gen_spr_power8_tm(env);
9082 gen_spr_power8_pspb(env);
9083 gen_spr_vtb(env);
9084 gen_spr_power8_ic(env);
9085 gen_spr_power8_book4(env);
9086 gen_spr_power8_rpr(env);
9087 gen_spr_power9_mmu(env);
9088
7d37b274
CLG
9089 /* FIXME: Filter fields properly based on privilege level */
9090 spr_register_kvm_hv(env, SPR_PSSCR, "PSSCR", NULL, NULL, NULL, NULL,
9091 spr_read_generic, spr_write_generic,
9092 KVM_REG_PPC_PSSCR, 0);
9093
9094 /* env variables */
9095 env->dcache_line_size = 128;
9096 env->icache_line_size = 128;
9097
9098 /* Allocate hardware IRQ controller */
9099 init_excp_POWER10(env);
9100 ppcPOWER9_irq_init(env_archcpu(env));
9101}
9102
9103static bool ppc_pvr_match_power10(PowerPCCPUClass *pcc, uint32_t pvr)
9104{
9105 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER10_BASE) {
9106 return true;
9107 }
9108 return false;
9109}
9110
9111static bool cpu_has_work_POWER10(CPUState *cs)
9112{
9113 PowerPCCPU *cpu = POWERPC_CPU(cs);
9114 CPUPPCState *env = &cpu->env;
9115
9116 if (cs->halted) {
9117 uint64_t psscr = env->spr[SPR_PSSCR];
9118
9119 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
9120 return false;
9121 }
9122
9123 /* If EC is clear, just return true on any pending interrupt */
9124 if (!(psscr & PSSCR_EC)) {
9125 return true;
9126 }
9127 /* External Exception */
9128 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
9129 (env->spr[SPR_LPCR] & LPCR_EEE)) {
9130 bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
9131 if (heic == 0 || !msr_hv || msr_pr) {
9132 return true;
9133 }
9134 }
9135 /* Decrementer Exception */
9136 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
9137 (env->spr[SPR_LPCR] & LPCR_DEE)) {
9138 return true;
9139 }
9140 /* Machine Check or Hypervisor Maintenance Exception */
9141 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK |
9142 1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) {
9143 return true;
9144 }
9145 /* Privileged Doorbell Exception */
9146 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
9147 (env->spr[SPR_LPCR] & LPCR_PDEE)) {
9148 return true;
9149 }
9150 /* Hypervisor Doorbell Exception */
9151 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
9152 (env->spr[SPR_LPCR] & LPCR_HDEE)) {
9153 return true;
9154 }
9155 /* Hypervisor virtualization exception */
9156 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HVIRT)) &&
9157 (env->spr[SPR_LPCR] & LPCR_HVEE)) {
9158 return true;
9159 }
9160 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
9161 return true;
9162 }
9163 return false;
9164 } else {
9165 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
9166 }
9167}
9168
9169POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data)
9170{
9171 DeviceClass *dc = DEVICE_CLASS(oc);
9172 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
9173 CPUClass *cc = CPU_CLASS(oc);
9174
9175 dc->fw_name = "PowerPC,POWER10";
9176 dc->desc = "POWER10";
7d37b274
CLG
9177 pcc->pvr_match = ppc_pvr_match_power10;
9178 pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07 |
9179 PCR_COMPAT_3_00;
9180 pcc->pcr_supported = PCR_COMPAT_3_10 | PCR_COMPAT_3_00 | PCR_COMPAT_2_07 |
9181 PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
9182 pcc->init_proc = init_proc_POWER10;
9183 pcc->check_pow = check_pow_nocheck;
9184 cc->has_work = cpu_has_work_POWER10;
9185 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
9186 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
9187 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
9188 PPC_FLOAT_FRSQRTES |
9189 PPC_FLOAT_STFIWX |
9190 PPC_FLOAT_EXT |
9191 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
9192 PPC_MEM_SYNC | PPC_MEM_EIEIO |
9193 PPC_MEM_TLBSYNC |
9194 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
9195 PPC_SEGMENT_64B | PPC_SLBI |
9196 PPC_POPCNTB | PPC_POPCNTWD |
9197 PPC_CILDST;
9198 pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
9199 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
9200 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
9201 PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
9202 PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
9203 PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
9495edb0 9204 PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL | PPC2_ISA310;
7d37b274 9205 pcc->msr_mask = (1ull << MSR_SF) |
23513f81 9206 (1ull << MSR_HV) |
7d37b274
CLG
9207 (1ull << MSR_TM) |
9208 (1ull << MSR_VR) |
9209 (1ull << MSR_VSX) |
9210 (1ull << MSR_EE) |
9211 (1ull << MSR_PR) |
9212 (1ull << MSR_FP) |
9213 (1ull << MSR_ME) |
9214 (1ull << MSR_FE0) |
9215 (1ull << MSR_SE) |
9216 (1ull << MSR_DE) |
9217 (1ull << MSR_FE1) |
9218 (1ull << MSR_IR) |
9219 (1ull << MSR_DR) |
9220 (1ull << MSR_PMM) |
9221 (1ull << MSR_RI) |
9222 (1ull << MSR_LE);
e232eccc
DG
9223 pcc->lpcr_mask = LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD |
9224 (LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL |
9225 LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR | LPCR_LD |
9226 (LPCR_PECE_L_MASK & (LPCR_PDEE | LPCR_HDEE | LPCR_EEE |
9227 LPCR_DEE | LPCR_OEE))
9228 | LPCR_MER | LPCR_GTSE | LPCR_TC |
9229 LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE | LPCR_HDICE;
9230 pcc->lpcr_pm = LPCR_PDEE | LPCR_HDEE | LPCR_EEE | LPCR_DEE | LPCR_OEE;
7d37b274
CLG
9231 pcc->mmu_model = POWERPC_MMU_3_00;
9232#if defined(CONFIG_SOFTMMU)
9233 pcc->handle_mmu_fault = ppc64_v3_handle_mmu_fault;
9234 /* segment page size remain the same */
9235 pcc->hash64_opts = &ppc_hash64_opts_POWER7;
9236 pcc->radix_page_info = &POWER10_radix_page_info;
9237 pcc->lrg_decr_bits = 56;
9238#endif
9239 pcc->excp_model = POWERPC_EXCP_POWER9;
9240 pcc->bus_model = PPC_FLAGS_INPUT_POWER9;
9241 pcc->bfd_mach = bfd_mach_ppc64;
9242 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
9243 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
9244 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
9245 POWERPC_FLAG_VSX | POWERPC_FLAG_TM;
9246 pcc->l1_dcache_size = 0x8000;
9247 pcc->l1_icache_size = 0x8000;
9248 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
7d37b274
CLG
9249}
9250
26a7f129 9251#if !defined(CONFIG_USER_ONLY)
da20aed1 9252void cpu_ppc_set_vhyp(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp)
26a7f129
BH
9253{
9254 CPUPPCState *env = &cpu->env;
9255
b7b0b1f1
DG
9256 cpu->vhyp = vhyp;
9257
4550f6a5
DG
9258 /*
9259 * With a virtual hypervisor mode we never allow the CPU to go
9260 * hypervisor mode itself
26a7f129 9261 */
4550f6a5 9262 env->msr_mask &= ~MSR_HVB;
26a7f129
BH
9263}
9264
9265#endif /* !defined(CONFIG_USER_ONLY) */
9266
c364946d 9267#endif /* defined(TARGET_PPC64) */
fd5ed418 9268
a750fc0b 9269/*****************************************************************************/
60b14d95 9270/* Generic CPU instantiation routine */
cfe34f44 9271static void init_ppc_proc(PowerPCCPU *cpu)
a750fc0b 9272{
cfe34f44
AF
9273 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
9274 CPUPPCState *env = &cpu->env;
a750fc0b 9275#if !defined(CONFIG_USER_ONLY)
e1833e1f
JM
9276 int i;
9277
a750fc0b 9278 env->irq_inputs = NULL;
e1833e1f 9279 /* Set all exception vectors to an invalid address */
1d28b5f6 9280 for (i = 0; i < POWERPC_EXCP_NB; i++) {
e1833e1f 9281 env->excp_vectors[i] = (target_ulong)(-1ULL);
1d28b5f6 9282 }
e1833e1f
JM
9283 env->ivor_mask = 0x00000000;
9284 env->ivpr_mask = 0x00000000;
a750fc0b
JM
9285 /* Default MMU definitions */
9286 env->nb_BATs = 0;
9287 env->nb_tlb = 0;
9288 env->nb_ways = 0;
1c53accc 9289 env->tlb_type = TLB_NONE;
f2e63a42 9290#endif
a750fc0b
JM
9291 /* Register SPR common to all PowerPC implementations */
9292 gen_spr_generic(env);
9293 spr_register(env, SPR_PVR, "PVR",
a139aa17
NF
9294 /* Linux permits userspace to read PVR */
9295#if defined(CONFIG_LINUX_USER)
9296 &spr_read_generic,
9297#else
9298 SPR_NOACCESS,
9299#endif
9300 SPR_NOACCESS,
a750fc0b 9301 &spr_read_generic, SPR_NOACCESS,
cfe34f44 9302 pcc->pvr);
80d11f44 9303 /* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
cfe34f44
AF
9304 if (pcc->svr != POWERPC_SVR_NONE) {
9305 if (pcc->svr & POWERPC_SVR_E500) {
80d11f44
JM
9306 spr_register(env, SPR_E500_SVR, "SVR",
9307 SPR_NOACCESS, SPR_NOACCESS,
9308 &spr_read_generic, SPR_NOACCESS,
cfe34f44 9309 pcc->svr & ~POWERPC_SVR_E500);
80d11f44
JM
9310 } else {
9311 spr_register(env, SPR_SVR, "SVR",
9312 SPR_NOACCESS, SPR_NOACCESS,
9313 &spr_read_generic, SPR_NOACCESS,
cfe34f44 9314 pcc->svr);
80d11f44
JM
9315 }
9316 }
a750fc0b 9317 /* PowerPC implementation specific initialisations (SPRs, timers, ...) */
cfe34f44 9318 (*pcc->init_proc)(env);
2cf3eb6d 9319
707c7c2e
FR
9320#if !defined(CONFIG_USER_ONLY)
9321 ppc_gdb_gen_spr_xml(cpu);
9322#endif
9323
25ba3a68
JM
9324 /* MSR bits & flags consistency checks */
9325 if (env->msr_mask & (1 << 25)) {
9326 switch (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
9327 case POWERPC_FLAG_SPE:
9328 case POWERPC_FLAG_VRE:
9329 break;
9330 default:
9331 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9332 "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n");
9333 exit(1);
9334 }
9335 } else if (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
9336 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9337 "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n");
9338 exit(1);
9339 }
9340 if (env->msr_mask & (1 << 17)) {
9341 switch (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
9342 case POWERPC_FLAG_TGPR:
9343 case POWERPC_FLAG_CE:
9344 break;
9345 default:
9346 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9347 "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n");
9348 exit(1);
9349 }
9350 } else if (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
9351 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9352 "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n");
9353 exit(1);
9354 }
9355 if (env->msr_mask & (1 << 10)) {
9356 switch (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
9357 POWERPC_FLAG_UBLE)) {
9358 case POWERPC_FLAG_SE:
9359 case POWERPC_FLAG_DWE:
9360 case POWERPC_FLAG_UBLE:
9361 break;
9362 default:
9363 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9364 "Should define POWERPC_FLAG_SE or POWERPC_FLAG_DWE or "
9365 "POWERPC_FLAG_UBLE\n");
9366 exit(1);
9367 }
9368 } else if (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
9369 POWERPC_FLAG_UBLE)) {
9370 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9371 "Should not define POWERPC_FLAG_SE nor POWERPC_FLAG_DWE nor "
9372 "POWERPC_FLAG_UBLE\n");
9373 exit(1);
9374 }
9375 if (env->msr_mask & (1 << 9)) {
9376 switch (env->flags & (POWERPC_FLAG_BE | POWERPC_FLAG_DE)) {
9377 case POWERPC_FLAG_BE:
9378 case POWERPC_FLAG_DE:
9379 break;
9380 default:
9381 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9382 "Should define POWERPC_FLAG_BE or POWERPC_FLAG_DE\n");
9383 exit(1);
9384 }
9385 } else if (env->flags & (POWERPC_FLAG_BE | POWERPC_FLAG_DE)) {
9386 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9387 "Should not define POWERPC_FLAG_BE nor POWERPC_FLAG_DE\n");
9388 exit(1);
9389 }
9390 if (env->msr_mask & (1 << 2)) {
9391 switch (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
9392 case POWERPC_FLAG_PX:
9393 case POWERPC_FLAG_PMM:
9394 break;
9395 default:
9396 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9397 "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n");
9398 exit(1);
9399 }
9400 } else if (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
9401 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9402 "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n");
9403 exit(1);
9404 }
4018bae9
JM
9405 if ((env->flags & (POWERPC_FLAG_RTC_CLK | POWERPC_FLAG_BUS_CLK)) == 0) {
9406 fprintf(stderr, "PowerPC flags inconsistency\n"
9407 "Should define the time-base and decrementer clock source\n");
9408 exit(1);
9409 }
a750fc0b 9410 /* Allocate TLBs buffer when needed */
f2e63a42 9411#if !defined(CONFIG_USER_ONLY)
a750fc0b
JM
9412 if (env->nb_tlb != 0) {
9413 int nb_tlb = env->nb_tlb;
1d28b5f6 9414 if (env->id_tlbs != 0) {
a750fc0b 9415 nb_tlb *= 2;
1d28b5f6 9416 }
1c53accc
AG
9417 switch (env->tlb_type) {
9418 case TLB_6XX:
cc226c06 9419 env->tlb.tlb6 = g_new0(ppc6xx_tlb_t, nb_tlb);
1c53accc
AG
9420 break;
9421 case TLB_EMB:
cc226c06 9422 env->tlb.tlbe = g_new0(ppcemb_tlb_t, nb_tlb);
1c53accc
AG
9423 break;
9424 case TLB_MAS:
cc226c06 9425 env->tlb.tlbm = g_new0(ppcmas_tlb_t, nb_tlb);
1c53accc
AG
9426 break;
9427 }
a750fc0b
JM
9428 /* Pre-compute some useful values */
9429 env->tlb_per_way = env->nb_tlb / env->nb_ways;
9430 }
a750fc0b 9431 if (env->irq_inputs == NULL) {
8297be80
AF
9432 warn_report("no internal IRQ controller registered."
9433 " Attempt QEMU to crash very soon !");
a750fc0b
JM
9434 }
9435#endif
2f462816 9436 if (env->check_pow == NULL) {
b62e39b4 9437 warn_report("no power management check handler registered."
8297be80 9438 " Attempt QEMU to crash very soon !");
2f462816 9439 }
a750fc0b
JM
9440}
9441
9442#if defined(PPC_DUMP_CPU)
c364946d 9443static void dump_ppc_sprs(CPUPPCState *env)
a750fc0b
JM
9444{
9445 ppc_spr_t *spr;
9446#if !defined(CONFIG_USER_ONLY)
9447 uint32_t sr, sw;
9448#endif
9449 uint32_t ur, uw;
9450 int i, j, n;
9451
9452 printf("Special purpose registers:\n");
9453 for (i = 0; i < 32; i++) {
9454 for (j = 0; j < 32; j++) {
9455 n = (i << 5) | j;
9456 spr = &env->spr_cb[n];
9457 uw = spr->uea_write != NULL && spr->uea_write != SPR_NOACCESS;
9458 ur = spr->uea_read != NULL && spr->uea_read != SPR_NOACCESS;
9459#if !defined(CONFIG_USER_ONLY)
9460 sw = spr->oea_write != NULL && spr->oea_write != SPR_NOACCESS;
9461 sr = spr->oea_read != NULL && spr->oea_read != SPR_NOACCESS;
9462 if (sw || sr || uw || ur) {
9463 printf("SPR: %4d (%03x) %-8s s%c%c u%c%c\n",
9464 (i << 5) | j, (i << 5) | j, spr->name,
9465 sw ? 'w' : '-', sr ? 'r' : '-',
9466 uw ? 'w' : '-', ur ? 'r' : '-');
9467 }
9468#else
9469 if (uw || ur) {
9470 printf("SPR: %4d (%03x) %-8s u%c%c\n",
9471 (i << 5) | j, (i << 5) | j, spr->name,
9472 uw ? 'w' : '-', ur ? 'r' : '-');
9473 }
9474#endif
9475 }
9476 }
9477 fflush(stdout);
9478 fflush(stderr);
9479}
9480#endif
9481
9482/*****************************************************************************/
a750fc0b 9483
a750fc0b
JM
9484/* Opcode types */
9485enum {
9486 PPC_DIRECT = 0, /* Opcode routine */
9487 PPC_INDIRECT = 1, /* Indirect opcode table */
9488};
9489
54ff58bb
BR
9490#define PPC_OPCODE_MASK 0x3
9491
c364946d 9492static inline int is_indirect_opcode(void *handler)
a750fc0b 9493{
54ff58bb 9494 return ((uintptr_t)handler & PPC_OPCODE_MASK) == PPC_INDIRECT;
a750fc0b
JM
9495}
9496
c227f099 9497static inline opc_handler_t **ind_table(void *handler)
a750fc0b 9498{
54ff58bb 9499 return (opc_handler_t **)((uintptr_t)handler & ~PPC_OPCODE_MASK);
a750fc0b
JM
9500}
9501
9502/* Instruction table creation */
9503/* Opcodes tables creation */
c364946d 9504static void fill_new_table(opc_handler_t **table, int len)
a750fc0b
JM
9505{
9506 int i;
9507
1d28b5f6 9508 for (i = 0; i < len; i++) {
a750fc0b 9509 table[i] = &invalid_handler;
1d28b5f6 9510 }
a750fc0b
JM
9511}
9512
c364946d 9513static int create_new_table(opc_handler_t **table, unsigned char idx)
a750fc0b 9514{
c227f099 9515 opc_handler_t **tmp;
a750fc0b 9516
54ff58bb
BR
9517 tmp = g_new(opc_handler_t *, PPC_CPU_INDIRECT_OPCODES_LEN);
9518 fill_new_table(tmp, PPC_CPU_INDIRECT_OPCODES_LEN);
5724753e 9519 table[idx] = (opc_handler_t *)((uintptr_t)tmp | PPC_INDIRECT);
a750fc0b
JM
9520
9521 return 0;
9522}
9523
c364946d 9524static int insert_in_table(opc_handler_t **table, unsigned char idx,
c227f099 9525 opc_handler_t *handler)
a750fc0b 9526{
1d28b5f6 9527 if (table[idx] != &invalid_handler) {
a750fc0b 9528 return -1;
1d28b5f6 9529 }
a750fc0b
JM
9530 table[idx] = handler;
9531
9532 return 0;
9533}
9534
c364946d
DG
9535static int register_direct_insn(opc_handler_t **ppc_opcodes,
9536 unsigned char idx, opc_handler_t *handler)
a750fc0b
JM
9537{
9538 if (insert_in_table(ppc_opcodes, idx, handler) < 0) {
9539 printf("*** ERROR: opcode %02x already assigned in main "
9540 "opcode table\n", idx);
4c1b1bfe
JM
9541#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9542 printf(" Registered handler '%s' - new handler '%s'\n",
9543 ppc_opcodes[idx]->oname, handler->oname);
9544#endif
a750fc0b
JM
9545 return -1;
9546 }
9547
9548 return 0;
9549}
9550
c364946d
DG
9551static int register_ind_in_table(opc_handler_t **table,
9552 unsigned char idx1, unsigned char idx2,
9553 opc_handler_t *handler)
a750fc0b
JM
9554{
9555 if (table[idx1] == &invalid_handler) {
9556 if (create_new_table(table, idx1) < 0) {
9557 printf("*** ERROR: unable to create indirect table "
9558 "idx=%02x\n", idx1);
9559 return -1;
9560 }
9561 } else {
9562 if (!is_indirect_opcode(table[idx1])) {
9563 printf("*** ERROR: idx %02x already assigned to a direct "
9564 "opcode\n", idx1);
4c1b1bfe
JM
9565#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9566 printf(" Registered handler '%s' - new handler '%s'\n",
9567 ind_table(table[idx1])[idx2]->oname, handler->oname);
9568#endif
a750fc0b
JM
9569 return -1;
9570 }
3a607854 9571 }
a750fc0b
JM
9572 if (handler != NULL &&
9573 insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) {
9574 printf("*** ERROR: opcode %02x already assigned in "
9575 "opcode table %02x\n", idx2, idx1);
4c1b1bfe
JM
9576#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9577 printf(" Registered handler '%s' - new handler '%s'\n",
9578 ind_table(table[idx1])[idx2]->oname, handler->oname);
9579#endif
a750fc0b 9580 return -1;
3a607854 9581 }
a750fc0b
JM
9582
9583 return 0;
9584}
9585
c364946d
DG
9586static int register_ind_insn(opc_handler_t **ppc_opcodes,
9587 unsigned char idx1, unsigned char idx2,
9588 opc_handler_t *handler)
a750fc0b 9589{
74c373e4 9590 return register_ind_in_table(ppc_opcodes, idx1, idx2, handler);
a750fc0b
JM
9591}
9592
c364946d
DG
9593static int register_dblind_insn(opc_handler_t **ppc_opcodes,
9594 unsigned char idx1, unsigned char idx2,
9595 unsigned char idx3, opc_handler_t *handler)
a750fc0b
JM
9596{
9597 if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
9598 printf("*** ERROR: unable to join indirect table idx "
9599 "[%02x-%02x]\n", idx1, idx2);
9600 return -1;
9601 }
9602 if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3,
9603 handler) < 0) {
9604 printf("*** ERROR: unable to insert opcode "
9605 "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
9606 return -1;
9607 }
9608
9609 return 0;
9610}
9611
323ad19b
ND
9612static int register_trplind_insn(opc_handler_t **ppc_opcodes,
9613 unsigned char idx1, unsigned char idx2,
9614 unsigned char idx3, unsigned char idx4,
9615 opc_handler_t *handler)
9616{
9617 opc_handler_t **table;
9618
9619 if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
9620 printf("*** ERROR: unable to join indirect table idx "
9621 "[%02x-%02x]\n", idx1, idx2);
9622 return -1;
9623 }
9624 table = ind_table(ppc_opcodes[idx1]);
9625 if (register_ind_in_table(table, idx2, idx3, NULL) < 0) {
9626 printf("*** ERROR: unable to join 2nd-level indirect table idx "
9627 "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
9628 return -1;
9629 }
9630 table = ind_table(table[idx2]);
9631 if (register_ind_in_table(table, idx3, idx4, handler) < 0) {
9632 printf("*** ERROR: unable to insert opcode "
9633 "[%02x-%02x-%02x-%02x]\n", idx1, idx2, idx3, idx4);
9634 return -1;
9635 }
9636 return 0;
9637}
c364946d 9638static int register_insn(opc_handler_t **ppc_opcodes, opcode_t *insn)
a750fc0b
JM
9639{
9640 if (insn->opc2 != 0xFF) {
9641 if (insn->opc3 != 0xFF) {
323ad19b
ND
9642 if (insn->opc4 != 0xFF) {
9643 if (register_trplind_insn(ppc_opcodes, insn->opc1, insn->opc2,
9644 insn->opc3, insn->opc4,
9645 &insn->handler) < 0) {
9646 return -1;
9647 }
9648 } else {
9649 if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2,
1d28b5f6 9650 insn->opc3, &insn->handler) < 0) {
323ad19b 9651 return -1;
1d28b5f6 9652 }
323ad19b 9653 }
a750fc0b
JM
9654 } else {
9655 if (register_ind_insn(ppc_opcodes, insn->opc1,
1d28b5f6 9656 insn->opc2, &insn->handler) < 0) {
a750fc0b 9657 return -1;
1d28b5f6 9658 }
a750fc0b
JM
9659 }
9660 } else {
1d28b5f6 9661 if (register_direct_insn(ppc_opcodes, insn->opc1, &insn->handler) < 0) {
a750fc0b 9662 return -1;
1d28b5f6 9663 }
a750fc0b
JM
9664 }
9665
9666 return 0;
9667}
9668
c364946d 9669static int test_opcode_table(opc_handler_t **table, int len)
a750fc0b
JM
9670{
9671 int i, count, tmp;
9672
9673 for (i = 0, count = 0; i < len; i++) {
9674 /* Consistency fixup */
1d28b5f6 9675 if (table[i] == NULL) {
a750fc0b 9676 table[i] = &invalid_handler;
1d28b5f6 9677 }
a750fc0b
JM
9678 if (table[i] != &invalid_handler) {
9679 if (is_indirect_opcode(table[i])) {
54ff58bb
BR
9680 tmp = test_opcode_table(ind_table(table[i]),
9681 PPC_CPU_INDIRECT_OPCODES_LEN);
a750fc0b
JM
9682 if (tmp == 0) {
9683 free(table[i]);
9684 table[i] = &invalid_handler;
9685 } else {
9686 count++;
9687 }
9688 } else {
9689 count++;
9690 }
9691 }
9692 }
9693
9694 return count;
9695}
9696
c364946d 9697static void fix_opcode_tables(opc_handler_t **ppc_opcodes)
a750fc0b 9698{
1d28b5f6 9699 if (test_opcode_table(ppc_opcodes, PPC_CPU_OPCODES_LEN) == 0) {
a750fc0b 9700 printf("*** WARNING: no opcode defined !\n");
1d28b5f6 9701 }
a750fc0b
JM
9702}
9703
9704/*****************************************************************************/
2985b86b 9705static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp)
a750fc0b 9706{
2985b86b 9707 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
c227f099 9708 opcode_t *opc;
a750fc0b 9709
28876bf2 9710 fill_new_table(cpu->opcodes, PPC_CPU_OPCODES_LEN);
5c55ff99 9711 for (opc = opcodes; opc < &opcodes[ARRAY_SIZE(opcodes)]; opc++) {
cfe34f44
AF
9712 if (((opc->handler.type & pcc->insns_flags) != 0) ||
9713 ((opc->handler.type2 & pcc->insns_flags2) != 0)) {
28876bf2 9714 if (register_insn(cpu->opcodes, opc) < 0) {
2985b86b 9715 error_setg(errp, "ERROR initializing PowerPC instruction "
312fd5f2 9716 "0x%02x 0x%02x 0x%02x", opc->opc1, opc->opc2,
2985b86b
AF
9717 opc->opc3);
9718 return;
a750fc0b
JM
9719 }
9720 }
9721 }
28876bf2 9722 fix_opcode_tables(cpu->opcodes);
a750fc0b
JM
9723 fflush(stdout);
9724 fflush(stderr);
a750fc0b
JM
9725}
9726
9727#if defined(PPC_DUMP_CPU)
c364946d 9728static void dump_ppc_insns(CPUPPCState *env)
a750fc0b 9729{
c227f099 9730 opc_handler_t **table, *handler;
b55266b5 9731 const char *p, *q;
323ad19b 9732 uint8_t opc1, opc2, opc3, opc4;
a750fc0b
JM
9733
9734 printf("Instructions set:\n");
9735 /* opc1 is 6 bits long */
54ff58bb 9736 for (opc1 = 0x00; opc1 < PPC_CPU_OPCODES_LEN; opc1++) {
a750fc0b
JM
9737 table = env->opcodes;
9738 handler = table[opc1];
9739 if (is_indirect_opcode(handler)) {
9740 /* opc2 is 5 bits long */
54ff58bb 9741 for (opc2 = 0; opc2 < PPC_CPU_INDIRECT_OPCODES_LEN; opc2++) {
a750fc0b
JM
9742 table = env->opcodes;
9743 handler = env->opcodes[opc1];
9744 table = ind_table(handler);
9745 handler = table[opc2];
9746 if (is_indirect_opcode(handler)) {
9747 table = ind_table(handler);
9748 /* opc3 is 5 bits long */
54ff58bb
BR
9749 for (opc3 = 0; opc3 < PPC_CPU_INDIRECT_OPCODES_LEN;
9750 opc3++) {
a750fc0b 9751 handler = table[opc3];
323ad19b
ND
9752 if (is_indirect_opcode(handler)) {
9753 table = ind_table(handler);
9754 /* opc4 is 5 bits long */
9755 for (opc4 = 0; opc4 < PPC_CPU_INDIRECT_OPCODES_LEN;
9756 opc4++) {
9757 handler = table[opc4];
9758 if (handler->handler != &gen_invalid) {
9759 printf("INSN: %02x %02x %02x %02x -- "
9760 "(%02d %04d %02d) : %s\n",
9761 opc1, opc2, opc3, opc4,
9762 opc1, (opc3 << 5) | opc2, opc4,
4c1b1bfe
JM
9763 handler->oname);
9764 }
323ad19b
ND
9765 }
9766 } else {
9767 if (handler->handler != &gen_invalid) {
9768 /* Special hack to properly dump SPE insns */
9769 p = strchr(handler->oname, '_');
9770 if (p == NULL) {
4c1b1bfe
JM
9771 printf("INSN: %02x %02x %02x (%02d %04d) : "
9772 "%s\n",
323ad19b
ND
9773 opc1, opc2, opc3, opc1,
9774 (opc3 << 5) | opc2,
9775 handler->oname);
9776 } else {
9777 q = "speundef";
9778 if ((p - handler->oname) != strlen(q)
9779 || (memcmp(handler->oname, q, strlen(q))
9780 != 0)) {
9781 /* First instruction */
9782 printf("INSN: %02x %02x %02x"
9783 "(%02d %04d) : %.*s\n",
9784 opc1, opc2 << 1, opc3, opc1,
9785 (opc3 << 6) | (opc2 << 1),
9786 (int)(p - handler->oname),
9787 handler->oname);
9788 }
9789 if (strcmp(p + 1, q) != 0) {
9790 /* Second instruction */
9791 printf("INSN: %02x %02x %02x "
9792 "(%02d %04d) : %s\n", opc1,
9793 (opc2 << 1) | 1, opc3, opc1,
9794 (opc3 << 6) | (opc2 << 1) | 1,
9795 p + 1);
9796 }
4c1b1bfe
JM
9797 }
9798 }
a750fc0b
JM
9799 }
9800 }
9801 } else {
9802 if (handler->handler != &gen_invalid) {
9803 printf("INSN: %02x %02x -- (%02d %04d) : %s\n",
9804 opc1, opc2, opc1, opc2, handler->oname);
9805 }
9806 }
9807 }
9808 } else {
9809 if (handler->handler != &gen_invalid) {
9810 printf("INSN: %02x -- -- (%02d ----) : %s\n",
9811 opc1, opc1, handler->oname);
9812 }
9813 }
9814 }
9815}
3a607854 9816#endif
a750fc0b 9817
87601e2d
GK
9818static bool avr_need_swap(CPUPPCState *env)
9819{
9820#ifdef HOST_WORDS_BIGENDIAN
ea499e71 9821 return msr_le;
87601e2d 9822#else
ea499e71 9823 return !msr_le;
87601e2d
GK
9824#endif
9825}
9826
707c7c2e
FR
9827#if !defined(CONFIG_USER_ONLY)
9828static int gdb_find_spr_idx(CPUPPCState *env, int n)
9829{
9830 int i;
9831
9832 for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
9833 ppc_spr_t *spr = &env->spr_cb[i];
9834
9835 if (spr->name && spr->gdb_id == n) {
9836 return i;
9837 }
9838 }
9839 return -1;
9840}
9841
a010bdbe 9842static int gdb_get_spr_reg(CPUPPCState *env, GByteArray *buf, int n)
707c7c2e
FR
9843{
9844 int reg;
9845 int len;
9846
9847 reg = gdb_find_spr_idx(env, n);
9848 if (reg < 0) {
9849 return 0;
9850 }
9851
9852 len = TARGET_LONG_SIZE;
a010bdbe
AB
9853 gdb_get_regl(buf, env->spr[reg]);
9854 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, len), len);
707c7c2e
FR
9855 return len;
9856}
9857
9858static int gdb_set_spr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
9859{
9860 int reg;
9861 int len;
9862
9863 reg = gdb_find_spr_idx(env, n);
9864 if (reg < 0) {
9865 return 0;
9866 }
9867
9868 len = TARGET_LONG_SIZE;
9869 ppc_maybe_bswap_register(env, mem_buf, len);
9870 env->spr[reg] = ldn_p(mem_buf, len);
9871
9872 return len;
9873}
9874#endif
9875
a010bdbe 9876static int gdb_get_float_reg(CPUPPCState *env, GByteArray *buf, int n)
24951522 9877{
a010bdbe 9878 uint8_t *mem_buf;
24951522 9879 if (n < 32) {
38c1c098 9880 gdb_get_float64(buf, *cpu_fpr_ptr(env, n));
a010bdbe 9881 mem_buf = gdb_get_reg_ptr(buf, 8);
385abeb3 9882 ppc_maybe_bswap_register(env, mem_buf, 8);
24951522
AJ
9883 return 8;
9884 }
9885 if (n == 32) {
a010bdbe
AB
9886 gdb_get_reg32(buf, env->fpscr);
9887 mem_buf = gdb_get_reg_ptr(buf, 4);
385abeb3 9888 ppc_maybe_bswap_register(env, mem_buf, 4);
24951522
AJ
9889 return 4;
9890 }
9891 return 0;
9892}
9893
1328c2bf 9894static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
24951522
AJ
9895{
9896 if (n < 32) {
385abeb3 9897 ppc_maybe_bswap_register(env, mem_buf, 8);
ef96e3ae 9898 *cpu_fpr_ptr(env, n) = ldfq_p(mem_buf);
24951522
AJ
9899 return 8;
9900 }
9901 if (n == 32) {
385abeb3 9902 ppc_maybe_bswap_register(env, mem_buf, 4);
d6478bc7 9903 helper_store_fpscr(env, ldl_p(mem_buf), 0xffffffff);
24951522
AJ
9904 return 4;
9905 }
9906 return 0;
9907}
9908
a010bdbe 9909static int gdb_get_avr_reg(CPUPPCState *env, GByteArray *buf, int n)
b4f8d821 9910{
a010bdbe
AB
9911 uint8_t *mem_buf;
9912
b4f8d821 9913 if (n < 32) {
ef96e3ae 9914 ppc_avr_t *avr = cpu_avr_ptr(env, n);
87601e2d 9915 if (!avr_need_swap(env)) {
a010bdbe 9916 gdb_get_reg128(buf, avr->u64[0] , avr->u64[1]);
87601e2d 9917 } else {
a010bdbe 9918 gdb_get_reg128(buf, avr->u64[1] , avr->u64[0]);
87601e2d 9919 }
a010bdbe 9920 mem_buf = gdb_get_reg_ptr(buf, 16);
ea499e71
GK
9921 ppc_maybe_bswap_register(env, mem_buf, 8);
9922 ppc_maybe_bswap_register(env, mem_buf + 8, 8);
b4f8d821
AJ
9923 return 16;
9924 }
70976a79 9925 if (n == 32) {
a010bdbe
AB
9926 gdb_get_reg32(buf, helper_mfvscr(env));
9927 mem_buf = gdb_get_reg_ptr(buf, 4);
ea499e71 9928 ppc_maybe_bswap_register(env, mem_buf, 4);
b4f8d821
AJ
9929 return 4;
9930 }
70976a79 9931 if (n == 33) {
a010bdbe
AB
9932 gdb_get_reg32(buf, (uint32_t)env->spr[SPR_VRSAVE]);
9933 mem_buf = gdb_get_reg_ptr(buf, 4);
ea499e71 9934 ppc_maybe_bswap_register(env, mem_buf, 4);
b4f8d821
AJ
9935 return 4;
9936 }
9937 return 0;
9938}
9939
1328c2bf 9940static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
b4f8d821
AJ
9941{
9942 if (n < 32) {
ef96e3ae 9943 ppc_avr_t *avr = cpu_avr_ptr(env, n);
ea499e71
GK
9944 ppc_maybe_bswap_register(env, mem_buf, 8);
9945 ppc_maybe_bswap_register(env, mem_buf + 8, 8);
87601e2d 9946 if (!avr_need_swap(env)) {
ef96e3ae
MCA
9947 avr->u64[0] = ldq_p(mem_buf);
9948 avr->u64[1] = ldq_p(mem_buf + 8);
87601e2d 9949 } else {
ef96e3ae
MCA
9950 avr->u64[1] = ldq_p(mem_buf);
9951 avr->u64[0] = ldq_p(mem_buf + 8);
87601e2d 9952 }
b4f8d821
AJ
9953 return 16;
9954 }
70976a79 9955 if (n == 32) {
ea499e71 9956 ppc_maybe_bswap_register(env, mem_buf, 4);
c5ba06a3 9957 helper_mtvscr(env, ldl_p(mem_buf));
b4f8d821
AJ
9958 return 4;
9959 }
70976a79 9960 if (n == 33) {
ea499e71 9961 ppc_maybe_bswap_register(env, mem_buf, 4);
b4f8d821
AJ
9962 env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf);
9963 return 4;
9964 }
9965 return 0;
9966}
9967
a010bdbe 9968static int gdb_get_spe_reg(CPUPPCState *env, GByteArray *buf, int n)
688890f7
AJ
9969{
9970 if (n < 32) {
9971#if defined(TARGET_PPC64)
a010bdbe
AB
9972 gdb_get_reg32(buf, env->gpr[n] >> 32);
9973 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
688890f7 9974#else
a010bdbe 9975 gdb_get_reg32(buf, env->gprh[n]);
688890f7
AJ
9976#endif
9977 return 4;
9978 }
70976a79 9979 if (n == 32) {
a010bdbe
AB
9980 gdb_get_reg64(buf, env->spe_acc);
9981 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
688890f7
AJ
9982 return 8;
9983 }
70976a79 9984 if (n == 33) {
a010bdbe
AB
9985 gdb_get_reg32(buf, env->spe_fscr);
9986 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
688890f7
AJ
9987 return 4;
9988 }
9989 return 0;
9990}
9991
1328c2bf 9992static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
688890f7
AJ
9993{
9994 if (n < 32) {
9995#if defined(TARGET_PPC64)
9996 target_ulong lo = (uint32_t)env->gpr[n];
95f5b540
GK
9997 target_ulong hi;
9998
9999 ppc_maybe_bswap_register(env, mem_buf, 4);
10000
10001 hi = (target_ulong)ldl_p(mem_buf) << 32;
688890f7
AJ
10002 env->gpr[n] = lo | hi;
10003#else
10004 env->gprh[n] = ldl_p(mem_buf);
10005#endif
10006 return 4;
10007 }
70976a79 10008 if (n == 32) {
95f5b540 10009 ppc_maybe_bswap_register(env, mem_buf, 8);
688890f7
AJ
10010 env->spe_acc = ldq_p(mem_buf);
10011 return 8;
10012 }
70976a79 10013 if (n == 33) {
95f5b540 10014 ppc_maybe_bswap_register(env, mem_buf, 4);
d34defbc 10015 env->spe_fscr = ldl_p(mem_buf);
688890f7
AJ
10016 return 4;
10017 }
10018 return 0;
10019}
10020
a010bdbe 10021static int gdb_get_vsx_reg(CPUPPCState *env, GByteArray *buf, int n)
1438eff3
AB
10022{
10023 if (n < 32) {
a010bdbe
AB
10024 gdb_get_reg64(buf, *cpu_vsrl_ptr(env, n));
10025 ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
1438eff3
AB
10026 return 8;
10027 }
10028 return 0;
10029}
10030
10031static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
10032{
10033 if (n < 32) {
10034 ppc_maybe_bswap_register(env, mem_buf, 8);
ef96e3ae 10035 *cpu_vsrl_ptr(env, n) = ldq_p(mem_buf);
1438eff3
AB
10036 return 8;
10037 }
10038 return 0;
10039}
10040
55e5c285 10041static int ppc_fixup_cpu(PowerPCCPU *cpu)
12b1143b 10042{
55e5c285
AF
10043 CPUPPCState *env = &cpu->env;
10044
1d28b5f6
DG
10045 /*
10046 * TCG doesn't (yet) emulate some groups of instructions that are
10047 * implemented on some otherwise supported CPUs (e.g. VSX and
10048 * decimal floating point instructions on POWER7). We remove
10049 * unsupported instruction groups from the cpu state's instruction
10050 * masks and hope the guest can cope. For at least the pseries
10051 * machine, the unavailability of these instructions can be
10052 * advertised to the guest via the device tree.
10053 */
12b1143b
DG
10054 if ((env->insns_flags & ~PPC_TCG_INSNS)
10055 || (env->insns_flags2 & ~PPC_TCG_INSNS2)) {
8297be80
AF
10056 warn_report("Disabling some instructions which are not "
10057 "emulated by TCG (0x%" PRIx64 ", 0x%" PRIx64 ")",
10058 env->insns_flags & ~PPC_TCG_INSNS,
10059 env->insns_flags2 & ~PPC_TCG_INSNS2);
12b1143b
DG
10060 }
10061 env->insns_flags &= PPC_TCG_INSNS;
10062 env->insns_flags2 &= PPC_TCG_INSNS2;
10063 return 0;
10064}
10065
e850da55 10066static void ppc_cpu_realize(DeviceState *dev, Error **errp)
a750fc0b 10067{
22169d41 10068 CPUState *cs = CPU(dev);
4776ce60 10069 PowerPCCPU *cpu = POWERPC_CPU(dev);
2985b86b 10070 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
2985b86b 10071 Error *local_err = NULL;
fe828a4d 10072
ce5b1bbf 10073 cpu_exec_realizefn(cs, &local_err);
6dd0f834
BR
10074 if (local_err != NULL) {
10075 error_propagate(errp, local_err);
10076 return;
10077 }
7cca3e46
SB
10078 if (cpu->vcpu_id == UNASSIGNED_CPU_INDEX) {
10079 cpu->vcpu_id = cs->cpu_index;
41264b38 10080 }
4656e1f0 10081
0ce470cd 10082 if (tcg_enabled()) {
55e5c285 10083 if (ppc_fixup_cpu(cpu) != 0) {
2985b86b 10084 error_setg(errp, "Unable to emulate selected CPU with TCG");
fd356563 10085 goto unrealize;
12b1143b
DG
10086 }
10087 }
10088
2985b86b
AF
10089 create_ppc_opcodes(cpu, &local_err);
10090 if (local_err != NULL) {
10091 error_propagate(errp, local_err);
fd356563 10092 goto unrealize;
2985b86b 10093 }
cfe34f44 10094 init_ppc_proc(cpu);
24951522 10095
cfe34f44 10096 if (pcc->insns_flags & PPC_FLOAT) {
22169d41 10097 gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
24951522
AJ
10098 33, "power-fpu.xml", 0);
10099 }
cfe34f44 10100 if (pcc->insns_flags & PPC_ALTIVEC) {
22169d41 10101 gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg,
b4f8d821
AJ
10102 34, "power-altivec.xml", 0);
10103 }
cfe34f44 10104 if (pcc->insns_flags & PPC_SPE) {
22169d41 10105 gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
688890f7
AJ
10106 34, "power-spe.xml", 0);
10107 }
1438eff3
AB
10108 if (pcc->insns_flags2 & PPC2_VSX) {
10109 gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg,
10110 32, "power-vsx.xml", 0);
10111 }
707c7c2e
FR
10112#ifndef CONFIG_USER_ONLY
10113 gdb_register_coprocessor(cs, gdb_get_spr_reg, gdb_set_spr_reg,
10114 pcc->gdb_num_sprs, "power-spr.xml", 0);
10115#endif
14a10fc3
AF
10116 qemu_init_vcpu(cs);
10117
4776ce60
AF
10118 pcc->parent_realize(dev, errp);
10119
a750fc0b 10120#if defined(PPC_DUMP_CPU)
3a607854 10121 {
22169d41 10122 CPUPPCState *env = &cpu->env;
b55266b5 10123 const char *mmu_model, *excp_model, *bus_model;
a750fc0b
JM
10124 switch (env->mmu_model) {
10125 case POWERPC_MMU_32B:
10126 mmu_model = "PowerPC 32";
10127 break;
a750fc0b
JM
10128 case POWERPC_MMU_SOFT_6xx:
10129 mmu_model = "PowerPC 6xx/7xx with software driven TLBs";
10130 break;
10131 case POWERPC_MMU_SOFT_74xx:
10132 mmu_model = "PowerPC 74xx with software driven TLBs";
10133 break;
10134 case POWERPC_MMU_SOFT_4xx:
10135 mmu_model = "PowerPC 4xx with software driven TLBs";
10136 break;
10137 case POWERPC_MMU_SOFT_4xx_Z:
10138 mmu_model = "PowerPC 4xx with software driven TLBs "
10139 "and zones protections";
10140 break;
b4095fed
JM
10141 case POWERPC_MMU_REAL:
10142 mmu_model = "PowerPC real mode only";
10143 break;
10144 case POWERPC_MMU_MPC8xx:
10145 mmu_model = "PowerPC MPC8xx";
a750fc0b
JM
10146 break;
10147 case POWERPC_MMU_BOOKE:
10148 mmu_model = "PowerPC BookE";
10149 break;
01662f3e
AG
10150 case POWERPC_MMU_BOOKE206:
10151 mmu_model = "PowerPC BookE 2.06";
a750fc0b 10152 break;
b4095fed
JM
10153 case POWERPC_MMU_601:
10154 mmu_model = "PowerPC 601";
10155 break;
c364946d 10156#if defined(TARGET_PPC64)
00af685f
JM
10157 case POWERPC_MMU_64B:
10158 mmu_model = "PowerPC 64";
10159 break;
00af685f 10160#endif
a750fc0b
JM
10161 default:
10162 mmu_model = "Unknown or invalid";
10163 break;
10164 }
10165 switch (env->excp_model) {
10166 case POWERPC_EXCP_STD:
10167 excp_model = "PowerPC";
10168 break;
10169 case POWERPC_EXCP_40x:
10170 excp_model = "PowerPC 40x";
10171 break;
10172 case POWERPC_EXCP_601:
10173 excp_model = "PowerPC 601";
10174 break;
10175 case POWERPC_EXCP_602:
10176 excp_model = "PowerPC 602";
10177 break;
10178 case POWERPC_EXCP_603:
10179 excp_model = "PowerPC 603";
10180 break;
10181 case POWERPC_EXCP_603E:
10182 excp_model = "PowerPC 603e";
10183 break;
10184 case POWERPC_EXCP_604:
10185 excp_model = "PowerPC 604";
10186 break;
10187 case POWERPC_EXCP_7x0:
10188 excp_model = "PowerPC 740/750";
10189 break;
10190 case POWERPC_EXCP_7x5:
10191 excp_model = "PowerPC 745/755";
10192 break;
10193 case POWERPC_EXCP_74xx:
10194 excp_model = "PowerPC 74xx";
10195 break;
a750fc0b
JM
10196 case POWERPC_EXCP_BOOKE:
10197 excp_model = "PowerPC BookE";
10198 break;
c364946d 10199#if defined(TARGET_PPC64)
00af685f
JM
10200 case POWERPC_EXCP_970:
10201 excp_model = "PowerPC 970";
10202 break;
10203#endif
a750fc0b
JM
10204 default:
10205 excp_model = "Unknown or invalid";
10206 break;
10207 }
10208 switch (env->bus_model) {
10209 case PPC_FLAGS_INPUT_6xx:
10210 bus_model = "PowerPC 6xx";
10211 break;
10212 case PPC_FLAGS_INPUT_BookE:
10213 bus_model = "PowerPC BookE";
10214 break;
10215 case PPC_FLAGS_INPUT_405:
10216 bus_model = "PowerPC 405";
10217 break;
a750fc0b
JM
10218 case PPC_FLAGS_INPUT_401:
10219 bus_model = "PowerPC 401/403";
10220 break;
b4095fed
JM
10221 case PPC_FLAGS_INPUT_RCPU:
10222 bus_model = "RCPU / MPC8xx";
10223 break;
c364946d 10224#if defined(TARGET_PPC64)
00af685f
JM
10225 case PPC_FLAGS_INPUT_970:
10226 bus_model = "PowerPC 970";
10227 break;
10228#endif
a750fc0b
JM
10229 default:
10230 bus_model = "Unknown or invalid";
10231 break;
10232 }
10233 printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64 "\n"
10234 " MMU model : %s\n",
a5100e75
AK
10235 object_class_get_name(OBJECT_CLASS(pcc)),
10236 pcc->pvr, pcc->msr_mask, mmu_model);
f2e63a42 10237#if !defined(CONFIG_USER_ONLY)
a5100e75 10238 if (env->tlb.tlb6) {
a750fc0b
JM
10239 printf(" %d %s TLB in %d ways\n",
10240 env->nb_tlb, env->id_tlbs ? "splitted" : "merged",
10241 env->nb_ways);
10242 }
f2e63a42 10243#endif
a750fc0b
JM
10244 printf(" Exceptions model : %s\n"
10245 " Bus model : %s\n",
10246 excp_model, bus_model);
25ba3a68 10247 printf(" MSR features :\n");
1d28b5f6 10248 if (env->flags & POWERPC_FLAG_SPE) {
25ba3a68
JM
10249 printf(" signal processing engine enable"
10250 "\n");
1d28b5f6 10251 } else if (env->flags & POWERPC_FLAG_VRE) {
25ba3a68 10252 printf(" vector processor enable\n");
1d28b5f6
DG
10253 }
10254 if (env->flags & POWERPC_FLAG_TGPR) {
25ba3a68 10255 printf(" temporary GPRs\n");
1d28b5f6 10256 } else if (env->flags & POWERPC_FLAG_CE) {
25ba3a68 10257 printf(" critical input enable\n");
1d28b5f6
DG
10258 }
10259 if (env->flags & POWERPC_FLAG_SE) {
25ba3a68 10260 printf(" single-step trace mode\n");
1d28b5f6 10261 } else if (env->flags & POWERPC_FLAG_DWE) {
25ba3a68 10262 printf(" debug wait enable\n");
1d28b5f6 10263 } else if (env->flags & POWERPC_FLAG_UBLE) {
25ba3a68 10264 printf(" user BTB lock enable\n");
1d28b5f6
DG
10265 }
10266 if (env->flags & POWERPC_FLAG_BE) {
25ba3a68 10267 printf(" branch-step trace mode\n");
1d28b5f6 10268 } else if (env->flags & POWERPC_FLAG_DE) {
25ba3a68 10269 printf(" debug interrupt enable\n");
1d28b5f6
DG
10270 }
10271 if (env->flags & POWERPC_FLAG_PX) {
25ba3a68 10272 printf(" inclusive protection\n");
1d28b5f6 10273 } else if (env->flags & POWERPC_FLAG_PMM) {
25ba3a68 10274 printf(" performance monitor mark\n");
1d28b5f6
DG
10275 }
10276 if (env->flags == POWERPC_FLAG_NONE) {
25ba3a68 10277 printf(" none\n");
1d28b5f6 10278 }
4018bae9
JM
10279 printf(" Time-base/decrementer clock source: %s\n",
10280 env->flags & POWERPC_FLAG_RTC_CLK ? "RTC clock" : "bus clock");
22169d41
AF
10281 dump_ppc_insns(env);
10282 dump_ppc_sprs(env);
10283 fflush(stdout);
a750fc0b 10284 }
3a607854 10285#endif
fd356563
BR
10286 return;
10287
10288unrealize:
10289 cpu_exec_unrealizefn(cs);
a750fc0b 10290}
3fc6c082 10291
b69c3c21 10292static void ppc_cpu_unrealize(DeviceState *dev)
b048960f
AF
10293{
10294 PowerPCCPU *cpu = POWERPC_CPU(dev);
7bbc124e 10295 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
323ad19b
ND
10296 opc_handler_t **table, **table_2;
10297 int i, j, k;
b048960f 10298
b69c3c21 10299 pcc->parent_unrealize(dev);
6dd0f834 10300
b048960f 10301 for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) {
28876bf2 10302 if (cpu->opcodes[i] == &invalid_handler) {
81f194dd
BR
10303 continue;
10304 }
28876bf2
AB
10305 if (is_indirect_opcode(cpu->opcodes[i])) {
10306 table = ind_table(cpu->opcodes[i]);
81f194dd 10307 for (j = 0; j < PPC_CPU_INDIRECT_OPCODES_LEN; j++) {
323ad19b
ND
10308 if (table[j] == &invalid_handler) {
10309 continue;
10310 }
10311 if (is_indirect_opcode(table[j])) {
10312 table_2 = ind_table(table[j]);
10313 for (k = 0; k < PPC_CPU_INDIRECT_OPCODES_LEN; k++) {
10314 if (table_2[k] != &invalid_handler &&
10315 is_indirect_opcode(table_2[k])) {
10316 g_free((opc_handler_t *)((uintptr_t)table_2[k] &
10317 ~PPC_INDIRECT));
10318 }
10319 }
81f194dd 10320 g_free((opc_handler_t *)((uintptr_t)table[j] &
323ad19b 10321 ~PPC_INDIRECT));
81f194dd
BR
10322 }
10323 }
28876bf2 10324 g_free((opc_handler_t *)((uintptr_t)cpu->opcodes[i] &
81f194dd 10325 ~PPC_INDIRECT));
b048960f
AF
10326 }
10327 }
10328}
10329
2985b86b 10330static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b)
f0ad8c34 10331{
2985b86b
AF
10332 ObjectClass *oc = (ObjectClass *)a;
10333 uint32_t pvr = *(uint32_t *)b;
10334 PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
10335
10336 /* -cpu host does a PVR lookup during construction */
10337 if (unlikely(strcmp(object_class_get_name(oc),
10338 TYPE_HOST_POWERPC_CPU) == 0)) {
10339 return -1;
f0ad8c34 10340 }
f0ad8c34 10341
cfe34f44 10342 return pcc->pvr == pvr ? 0 : -1;
f0ad8c34
AG
10343}
10344
2985b86b 10345PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr)
3fc6c082 10346{
2985b86b
AF
10347 GSList *list, *item;
10348 PowerPCCPUClass *pcc = NULL;
be40edcd 10349
2985b86b
AF
10350 list = object_class_get_list(TYPE_POWERPC_CPU, false);
10351 item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr);
10352 if (item != NULL) {
10353 pcc = POWERPC_CPU_CLASS(item->data);
3fc6c082 10354 }
2985b86b
AF
10355 g_slist_free(list);
10356
10357 return pcc;
10358}
10359
3bc9ccc0
AK
10360static gint ppc_cpu_compare_class_pvr_mask(gconstpointer a, gconstpointer b)
10361{
10362 ObjectClass *oc = (ObjectClass *)a;
10363 uint32_t pvr = *(uint32_t *)b;
10364 PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
3bc9ccc0
AK
10365
10366 /* -cpu host does a PVR lookup during construction */
10367 if (unlikely(strcmp(object_class_get_name(oc),
10368 TYPE_HOST_POWERPC_CPU) == 0)) {
10369 return -1;
10370 }
10371
03ae4133
AK
10372 if (pcc->pvr_match(pcc, pvr)) {
10373 return 0;
10374 }
3bc9ccc0 10375
03ae4133 10376 return -1;
3bc9ccc0
AK
10377}
10378
10379PowerPCCPUClass *ppc_cpu_class_by_pvr_mask(uint32_t pvr)
10380{
10381 GSList *list, *item;
10382 PowerPCCPUClass *pcc = NULL;
10383
10384 list = object_class_get_list(TYPE_POWERPC_CPU, true);
10385 item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr_mask);
10386 if (item != NULL) {
10387 pcc = POWERPC_CPU_CLASS(item->data);
10388 }
10389 g_slist_free(list);
10390
10391 return pcc;
10392}
10393
2e9c10eb 10394static const char *ppc_cpu_lookup_alias(const char *alias)
b918f885
IM
10395{
10396 int ai;
10397
10398 for (ai = 0; ppc_cpu_aliases[ai].alias != NULL; ai++) {
10399 if (strcmp(ppc_cpu_aliases[ai].alias, alias) == 0) {
10400 return ppc_cpu_aliases[ai].model;
10401 }
10402 }
10403
10404 return NULL;
10405}
10406
2985b86b 10407static ObjectClass *ppc_cpu_class_by_name(const char *name)
ee4e83ed 10408{
03c9141d
IM
10409 char *cpu_model, *typename;
10410 ObjectClass *oc;
b55266b5 10411 const char *p;
b376db77
IM
10412 unsigned long pvr;
10413
1d28b5f6
DG
10414 /*
10415 * Lookup by PVR if cpu_model is valid 8 digit hex number (excl:
10416 * 0x prefix if present)
b376db77
IM
10417 */
10418 if (!qemu_strtoul(name, &p, 16, &pvr)) {
10419 int len = p - name;
10420 len = (len == 10) && (name[1] == 'x') ? len - 2 : len;
10421 if ((len == 8) && (*p == '\0')) {
10422 return OBJECT_CLASS(ppc_cpu_class_by_pvr(pvr));
f0ad8c34 10423 }
2985b86b 10424 }
f0ad8c34 10425
03c9141d
IM
10426 cpu_model = g_ascii_strdown(name, -1);
10427 p = ppc_cpu_lookup_alias(cpu_model);
10428 if (p) {
10429 g_free(cpu_model);
10430 cpu_model = g_strdup(p);
3fc6c082 10431 }
ee4e83ed 10432
03c9141d
IM
10433 typename = g_strdup_printf("%s" POWERPC_CPU_TYPE_SUFFIX, cpu_model);
10434 oc = object_class_by_name(typename);
10435 g_free(typename);
10436 g_free(cpu_model);
fdf8a960 10437
a69dc537 10438 return oc;
3fc6c082
FB
10439}
10440
b8e99967
IM
10441static void ppc_cpu_parse_featurestr(const char *type, char *features,
10442 Error **errp)
10443{
10444 Object *machine = qdev_get_machine();
10445 const PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(object_class_by_name(type));
10446
10447 if (!features) {
10448 return;
10449 }
10450
10451 if (object_property_find(machine, "max-cpu-compat", NULL)) {
10452 int i;
10453 char **inpieces;
10454 char *s = features;
10455 Error *local_err = NULL;
10456 char *compat_str = NULL;
10457
10458 /*
10459 * Backwards compatibility hack:
10460 *
10461 * CPUs had a "compat=" property which didn't make sense for
10462 * anything except pseries. It was replaced by "max-cpu-compat"
10463 * machine option. This supports old command lines like
10464 * -cpu POWER8,compat=power7
10465 * By stripping the compat option and applying it to the machine
10466 * before passing it on to the cpu level parser.
10467 */
10468 inpieces = g_strsplit(features, ",", 0);
10469 *s = '\0';
10470 for (i = 0; inpieces[i]; i++) {
10471 if (g_str_has_prefix(inpieces[i], "compat=")) {
22062e54
GK
10472 warn_report_once("CPU 'compat' property is deprecated; "
10473 "use max-cpu-compat machine property instead");
b8e99967
IM
10474 compat_str = inpieces[i];
10475 continue;
10476 }
10477 if ((i != 0) && (s != features)) {
10478 s = g_stpcpy(s, ",");
10479 }
10480 s = g_stpcpy(s, inpieces[i]);
10481 }
10482
10483 if (compat_str) {
10484 char *v = compat_str + strlen("compat=");
5325cc34 10485 object_property_set_str(machine, "max-cpu-compat", v, &local_err);
b8e99967
IM
10486 }
10487 g_strfreev(inpieces);
10488 if (local_err) {
10489 error_propagate(errp, local_err);
10490 return;
10491 }
10492 }
10493
10494 /* do property processing with generic handler */
10495 pcc->parent_parse_features(type, features, errp);
10496}
10497
e9edd931
TH
10498PowerPCCPUClass *ppc_cpu_get_family_class(PowerPCCPUClass *pcc)
10499{
10500 ObjectClass *oc = OBJECT_CLASS(pcc);
10501
10502 while (oc && !object_class_is_abstract(oc)) {
10503 oc = object_class_get_parent(oc);
10504 }
10505 assert(oc);
10506
10507 return POWERPC_CPU_CLASS(oc);
10508}
10509
2985b86b
AF
10510/* Sort by PVR, ordering special case "host" last. */
10511static gint ppc_cpu_list_compare(gconstpointer a, gconstpointer b)
10512{
10513 ObjectClass *oc_a = (ObjectClass *)a;
10514 ObjectClass *oc_b = (ObjectClass *)b;
10515 PowerPCCPUClass *pcc_a = POWERPC_CPU_CLASS(oc_a);
10516 PowerPCCPUClass *pcc_b = POWERPC_CPU_CLASS(oc_b);
10517 const char *name_a = object_class_get_name(oc_a);
10518 const char *name_b = object_class_get_name(oc_b);
10519
10520 if (strcmp(name_a, TYPE_HOST_POWERPC_CPU) == 0) {
10521 return 1;
10522 } else if (strcmp(name_b, TYPE_HOST_POWERPC_CPU) == 0) {
10523 return -1;
10524 } else {
10525 /* Avoid an integer overflow during subtraction */
cfe34f44 10526 if (pcc_a->pvr < pcc_b->pvr) {
2985b86b 10527 return -1;
cfe34f44 10528 } else if (pcc_a->pvr > pcc_b->pvr) {
2985b86b
AF
10529 return 1;
10530 } else {
10531 return 0;
10532 }
10533 }
10534}
10535
10536static void ppc_cpu_list_entry(gpointer data, gpointer user_data)
10537{
10538 ObjectClass *oc = data;
2985b86b 10539 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
e9edd931 10540 DeviceClass *family = DEVICE_CLASS(ppc_cpu_get_family_class(pcc));
de400129
AF
10541 const char *typename = object_class_get_name(oc);
10542 char *name;
55d3d1a4 10543 int i;
2985b86b 10544
5ba4576b
AF
10545 if (unlikely(strcmp(typename, TYPE_HOST_POWERPC_CPU) == 0)) {
10546 return;
10547 }
4d7fb187 10548
de400129 10549 name = g_strndup(typename,
c9137065 10550 strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX));
0442428a 10551 qemu_printf("PowerPC %-16s PVR %08x\n", name, pcc->pvr);
e9a96075 10552 for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
9761ad75 10553 PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
2527cb91 10554 ObjectClass *alias_oc = ppc_cpu_class_by_name(alias->model);
55d3d1a4
AF
10555
10556 if (alias_oc != oc) {
10557 continue;
10558 }
e9edd931
TH
10559 /*
10560 * If running with KVM, we might update the family alias later, so
10561 * avoid printing the wrong alias here and use "preferred" instead
10562 */
10563 if (strcmp(alias->alias, family->desc) == 0) {
0442428a
MA
10564 qemu_printf("PowerPC %-16s (alias for preferred %s CPU)\n",
10565 alias->alias, family->desc);
e9edd931 10566 } else {
0442428a
MA
10567 qemu_printf("PowerPC %-16s (alias for %s)\n",
10568 alias->alias, name);
e9edd931 10569 }
55d3d1a4 10570 }
de400129 10571 g_free(name);
2985b86b
AF
10572}
10573
0442428a 10574void ppc_cpu_list(void)
2985b86b 10575{
2985b86b
AF
10576 GSList *list;
10577
10578 list = object_class_get_list(TYPE_POWERPC_CPU, false);
10579 list = g_slist_sort(list, ppc_cpu_list_compare);
0442428a 10580 g_slist_foreach(list, ppc_cpu_list_entry, NULL);
2985b86b 10581 g_slist_free(list);
fd5ed418 10582
5ba4576b 10583#ifdef CONFIG_KVM
0442428a
MA
10584 qemu_printf("\n");
10585 qemu_printf("PowerPC %-16s\n", "host");
5ba4576b 10586#endif
2985b86b
AF
10587}
10588
10589static void ppc_cpu_defs_entry(gpointer data, gpointer user_data)
10590{
10591 ObjectClass *oc = data;
10592 CpuDefinitionInfoList **first = user_data;
de400129 10593 const char *typename;
2985b86b
AF
10594 CpuDefinitionInfoList *entry;
10595 CpuDefinitionInfo *info;
10596
de400129 10597 typename = object_class_get_name(oc);
2985b86b 10598 info = g_malloc0(sizeof(*info));
de400129 10599 info->name = g_strndup(typename,
c9137065 10600 strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX));
2985b86b
AF
10601
10602 entry = g_malloc0(sizeof(*entry));
10603 entry->value = info;
10604 entry->next = *first;
10605 *first = entry;
3fc6c082 10606}
1d0cb67d 10607
25a9d6ca 10608CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
70b7660a
AL
10609{
10610 CpuDefinitionInfoList *cpu_list = NULL;
2985b86b 10611 GSList *list;
35e21d3f 10612 int i;
70b7660a 10613
2985b86b
AF
10614 list = object_class_get_list(TYPE_POWERPC_CPU, false);
10615 g_slist_foreach(list, ppc_cpu_defs_entry, &cpu_list);
10616 g_slist_free(list);
70b7660a 10617
e9a96075 10618 for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
9761ad75 10619 PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
35e21d3f
AF
10620 ObjectClass *oc;
10621 CpuDefinitionInfoList *entry;
10622 CpuDefinitionInfo *info;
10623
2527cb91 10624 oc = ppc_cpu_class_by_name(alias->model);
35e21d3f
AF
10625 if (oc == NULL) {
10626 continue;
10627 }
10628
10629 info = g_malloc0(sizeof(*info));
10630 info->name = g_strdup(alias->alias);
8ed877b7 10631 info->q_typename = g_strdup(object_class_get_name(oc));
35e21d3f
AF
10632
10633 entry = g_malloc0(sizeof(*entry));
10634 entry->value = info;
10635 entry->next = cpu_list;
10636 cpu_list = entry;
10637 }
10638
2985b86b
AF
10639 return cpu_list;
10640}
70b7660a 10641
f45748f1
AF
10642static void ppc_cpu_set_pc(CPUState *cs, vaddr value)
10643{
10644 PowerPCCPU *cpu = POWERPC_CPU(cs);
10645
10646 cpu->env.nip = value;
10647}
10648
8c2e1b00
AF
10649static bool ppc_cpu_has_work(CPUState *cs)
10650{
10651 PowerPCCPU *cpu = POWERPC_CPU(cs);
10652 CPUPPCState *env = &cpu->env;
10653
10654 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
10655}
10656
781c67ca 10657static void ppc_cpu_reset(DeviceState *dev)
1d0cb67d 10658{
781c67ca 10659 CPUState *s = CPU(dev);
1d0cb67d
AF
10660 PowerPCCPU *cpu = POWERPC_CPU(s);
10661 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
10662 CPUPPCState *env = &cpu->env;
a1389542 10663 target_ulong msr;
d197fdbc 10664 int i;
a1389542 10665
781c67ca 10666 pcc->parent_reset(dev);
1d0cb67d 10667
a1389542 10668 msr = (target_ulong)0;
932ccbdd 10669 msr |= (target_ulong)MSR_HVB;
a1389542
AF
10670 msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */
10671 msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */
10672 msr |= (target_ulong)1 << MSR_EP;
10673#if defined(DO_SINGLE_STEP) && 0
10674 /* Single step trace mode */
10675 msr |= (target_ulong)1 << MSR_SE;
10676 msr |= (target_ulong)1 << MSR_BE;
10677#endif
10678#if defined(CONFIG_USER_ONLY)
10679 msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
e82c42b7
RH
10680 msr |= (target_ulong)1 << MSR_FE0; /* Allow floating point exceptions */
10681 msr |= (target_ulong)1 << MSR_FE1;
a1389542 10682 msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
5b274ed7 10683 msr |= (target_ulong)1 << MSR_VSX; /* Allow VSX usage */
a1389542
AF
10684 msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
10685 msr |= (target_ulong)1 << MSR_PR;
cdcdda27
AK
10686#if defined(TARGET_PPC64)
10687 msr |= (target_ulong)1 << MSR_TM; /* Transactional memory */
10688#endif
e22c357b
DK
10689#if !defined(TARGET_WORDS_BIGENDIAN)
10690 msr |= (target_ulong)1 << MSR_LE; /* Little-endian user mode */
a74029f6
RH
10691 if (!((env->msr_mask >> MSR_LE) & 1)) {
10692 fprintf(stderr, "Selected CPU does not support little-endian.\n");
10693 exit(1);
10694 }
e22c357b 10695#endif
a1389542 10696#endif
2cf3eb6d 10697
a1389542
AF
10698#if defined(TARGET_PPC64)
10699 if (env->mmu_model & POWERPC_MMU_64) {
8b9f2118 10700 msr |= (1ULL << MSR_SF);
a1389542
AF
10701 }
10702#endif
2cf3eb6d
FC
10703
10704 hreg_store_msr(env, msr, 1);
10705
10706#if !defined(CONFIG_USER_ONLY)
10707 env->nip = env->hreset_vector | env->excp_prefix;
10708 if (env->mmu_model != POWERPC_MMU_REAL) {
10709 ppc_tlb_invalidate_all(env);
10710 }
10711#endif
10712
a1389542
AF
10713 hreg_compute_hflags(env);
10714 env->reserve_addr = (target_ulong)-1ULL;
10715 /* Be sure no exception or interrupt is pending */
10716 env->pending_interrupts = 0;
27103424 10717 s->exception_index = POWERPC_EXCP_NONE;
a1389542 10718 env->error_code = 0;
40177438 10719 ppc_irq_reset(cpu);
2b15811c 10720
cbc65a8f
RH
10721 /* tininess for underflow is detected before rounding */
10722 set_float_detect_tininess(float_tininess_before_rounding,
10723 &env->fp_status);
10724
d197fdbc
AK
10725 for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
10726 ppc_spr_t *spr = &env->spr_cb[i];
10727
10728 if (!spr->name) {
10729 continue;
10730 }
10731 env->spr[i] = spr->default_value;
10732 }
1d0cb67d
AF
10733}
10734
7826c2b2
GK
10735#ifndef CONFIG_USER_ONLY
10736static bool ppc_cpu_is_big_endian(CPUState *cs)
10737{
10738 PowerPCCPU *cpu = POWERPC_CPU(cs);
10739 CPUPPCState *env = &cpu->env;
10740
10741 cpu_synchronize_state(cs);
10742
10743 return !msr_le;
10744}
03ef074c
NP
10745
10746static void ppc_cpu_exec_enter(CPUState *cs)
10747{
10748 PowerPCCPU *cpu = POWERPC_CPU(cs);
10749
10750 if (cpu->vhyp) {
10751 PPCVirtualHypervisorClass *vhc =
10752 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
10753 vhc->cpu_exec_enter(cpu->vhyp, cpu);
10754 }
10755}
10756
10757static void ppc_cpu_exec_exit(CPUState *cs)
10758{
10759 PowerPCCPU *cpu = POWERPC_CPU(cs);
10760
10761 if (cpu->vhyp) {
10762 PPCVirtualHypervisorClass *vhc =
10763 PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp);
10764 vhc->cpu_exec_exit(cpu->vhyp, cpu);
10765 }
10766}
7826c2b2
GK
10767#endif
10768
e850da55 10769static void ppc_cpu_instance_init(Object *obj)
6cca7ad6
AF
10770{
10771 PowerPCCPU *cpu = POWERPC_CPU(obj);
2985b86b 10772 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
6cca7ad6
AF
10773 CPUPPCState *env = &cpu->env;
10774
7506ed90 10775 cpu_set_cpustate_pointers(cpu);
7cca3e46 10776 cpu->vcpu_id = UNASSIGNED_CPU_INDEX;
2985b86b 10777
cfe34f44
AF
10778 env->msr_mask = pcc->msr_mask;
10779 env->mmu_model = pcc->mmu_model;
10780 env->excp_model = pcc->excp_model;
10781 env->bus_model = pcc->bus_model;
10782 env->insns_flags = pcc->insns_flags;
10783 env->insns_flags2 = pcc->insns_flags2;
10784 env->flags = pcc->flags;
10785 env->bfd_mach = pcc->bfd_mach;
10786 env->check_pow = pcc->check_pow;
2985b86b 10787
1d28b5f6
DG
10788 /*
10789 * Mark HV mode as supported if the CPU has an MSR_HV bit in the
10790 * msr_mask. The mask can later be cleared by PAPR mode but the hv
10791 * mode support will remain, thus enforcing that we cannot use
10792 * priv. instructions in guest in PAPR mode. For 970 we currently
10793 * simply don't set HV in msr_mask thus simulating an "Apple mode"
10794 * 970. If we ever want to support 970 HV mode, we'll have to add
10795 * a processor attribute of some sort.
932ccbdd
BH
10796 */
10797#if !defined(CONFIG_USER_ONLY)
10798 env->has_hv_mode = !!(env->msr_mask & MSR_HVB);
10799#endif
10800
a059471d
DG
10801 ppc_hash64_init(cpu);
10802}
10803
10804static void ppc_cpu_instance_finalize(Object *obj)
10805{
10806 PowerPCCPU *cpu = POWERPC_CPU(obj);
10807
10808 ppc_hash64_finalize(cpu);
6cca7ad6
AF
10809}
10810
03ae4133
AK
10811static bool ppc_pvr_match_default(PowerPCCPUClass *pcc, uint32_t pvr)
10812{
10813 return pcc->pvr == pvr;
10814}
10815
b3820e6c
DH
10816static gchar *ppc_gdb_arch_name(CPUState *cs)
10817{
10818#if defined(TARGET_PPC64)
10819 return g_strdup("powerpc:common64");
10820#else
10821 return g_strdup("powerpc:common");
10822#endif
10823}
10824
0eea8cdd
RH
10825static void ppc_disas_set_info(CPUState *cs, disassemble_info *info)
10826{
10827 PowerPCCPU *cpu = POWERPC_CPU(cs);
10828 CPUPPCState *env = &cpu->env;
10829
10830 if ((env->hflags >> MSR_LE) & 1) {
10831 info->endian = BFD_ENDIAN_LITTLE;
10832 }
10833 info->mach = env->bfd_mach;
10834 if (!env->bfd_mach) {
10835#ifdef TARGET_PPC64
10836 info->mach = bfd_mach_ppc64;
10837#else
10838 info->mach = bfd_mach_ppc;
10839#endif
10840 }
10841 info->disassembler_options = (char *)"any";
10842 info->print_insn = print_insn_ppc;
ac226899
RH
10843
10844 info->cap_arch = CS_ARCH_PPC;
10845#ifdef TARGET_PPC64
10846 info->cap_mode = CS_MODE_64;
10847#endif
0eea8cdd
RH
10848}
10849
146c11f1
DG
10850static Property ppc_cpu_properties[] = {
10851 DEFINE_PROP_BOOL("pre-2.8-migration", PowerPCCPU, pre_2_8_migration, false),
d5fc133e
DG
10852 DEFINE_PROP_BOOL("pre-2.10-migration", PowerPCCPU, pre_2_10_migration,
10853 false),
d8c0c7af 10854 DEFINE_PROP_BOOL("pre-3.0-migration", PowerPCCPU, pre_3_0_migration,
67d7d66f 10855 false),
146c11f1
DG
10856 DEFINE_PROP_END_OF_LIST(),
10857};
10858
1d0cb67d
AF
10859static void ppc_cpu_class_init(ObjectClass *oc, void *data)
10860{
10861 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
10862 CPUClass *cc = CPU_CLASS(oc);
4776ce60
AF
10863 DeviceClass *dc = DEVICE_CLASS(oc);
10864
e850da55 10865 device_class_set_parent_realize(dc, ppc_cpu_realize,
bf853881 10866 &pcc->parent_realize);
e850da55 10867 device_class_set_parent_unrealize(dc, ppc_cpu_unrealize,
bf853881 10868 &pcc->parent_unrealize);
03ae4133 10869 pcc->pvr_match = ppc_pvr_match_default;
382d2db6 10870 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_always;
4f67d30b 10871 device_class_set_props(dc, ppc_cpu_properties);
1d0cb67d 10872
781c67ca 10873 device_class_set_parent_reset(dc, ppc_cpu_reset, &pcc->parent_reset);
2b8c2754
AF
10874
10875 cc->class_by_name = ppc_cpu_class_by_name;
b8e99967
IM
10876 pcc->parent_parse_features = cc->parse_features;
10877 cc->parse_features = ppc_cpu_parse_featurestr;
8c2e1b00 10878 cc->has_work = ppc_cpu_has_work;
97a8ea5a 10879 cc->do_interrupt = ppc_cpu_do_interrupt;
458dd766 10880 cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt;
878096ee
AF
10881 cc->dump_state = ppc_cpu_dump_state;
10882 cc->dump_statistics = ppc_cpu_dump_statistics;
f45748f1 10883 cc->set_pc = ppc_cpu_set_pc;
5b50e790
AF
10884 cc->gdb_read_register = ppc_cpu_gdb_read_register;
10885 cc->gdb_write_register = ppc_cpu_gdb_write_register;
0f3110fa 10886 cc->do_unaligned_access = ppc_cpu_do_unaligned_access;
351bc97e 10887#ifndef CONFIG_USER_ONLY
00b941e5 10888 cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
a90db158 10889 cc->vmsd = &vmstate_ppc_cpu;
00b941e5 10890#endif
356bb70e
MN
10891#if defined(CONFIG_SOFTMMU)
10892 cc->write_elf64_note = ppc64_cpu_write_elf64_note;
10893 cc->write_elf32_note = ppc32_cpu_write_elf32_note;
10894#endif
a0e372f0
AF
10895
10896 cc->gdb_num_core_regs = 71;
707c7c2e
FR
10897#ifndef CONFIG_USER_ONLY
10898 cc->gdb_get_dynamic_xml = ppc_gdb_get_dynamic_xml;
10899#endif
b3cad3ab
AG
10900#ifdef USE_APPLE_GDB
10901 cc->gdb_read_register = ppc_cpu_gdb_read_register_apple;
10902 cc->gdb_write_register = ppc_cpu_gdb_write_register_apple;
10903 cc->gdb_num_core_regs = 71 + 32;
10904#endif
10905
b3820e6c 10906 cc->gdb_arch_name = ppc_gdb_arch_name;
5b24c641
AF
10907#if defined(TARGET_PPC64)
10908 cc->gdb_core_xml_file = "power64-core.xml";
10909#else
10910 cc->gdb_core_xml_file = "power-core.xml";
10911#endif
7826c2b2
GK
10912#ifndef CONFIG_USER_ONLY
10913 cc->virtio_is_big_endian = ppc_cpu_is_big_endian;
10914#endif
74d7fc7f 10915#ifdef CONFIG_TCG
55c3ceef 10916 cc->tcg_initialize = ppc_translate_init;
351bc97e 10917 cc->tlb_fill = ppc_cpu_tlb_fill;
74d7fc7f 10918#endif
03ef074c
NP
10919#ifndef CONFIG_USER_ONLY
10920 cc->cpu_exec_enter = ppc_cpu_exec_enter;
10921 cc->cpu_exec_exit = ppc_cpu_exec_exit;
10922#endif
10923
0eea8cdd 10924 cc->disas_set_info = ppc_disas_set_info;
1d28b5f6 10925
3bbf37f2 10926 dc->fw_name = "PowerPC,UNKNOWN";
1d0cb67d
AF
10927}
10928
10929static const TypeInfo ppc_cpu_type_info = {
10930 .name = TYPE_POWERPC_CPU,
10931 .parent = TYPE_CPU,
10932 .instance_size = sizeof(PowerPCCPU),
e850da55 10933 .instance_init = ppc_cpu_instance_init,
a059471d 10934 .instance_finalize = ppc_cpu_instance_finalize,
2985b86b 10935 .abstract = true,
1d0cb67d
AF
10936 .class_size = sizeof(PowerPCCPUClass),
10937 .class_init = ppc_cpu_class_init,
10938};
10939
e89aac1a 10940#ifndef CONFIG_USER_ONLY
1d1be34d
DG
10941static const TypeInfo ppc_vhyp_type_info = {
10942 .name = TYPE_PPC_VIRTUAL_HYPERVISOR,
10943 .parent = TYPE_INTERFACE,
10944 .class_size = sizeof(PPCVirtualHypervisorClass),
10945};
e89aac1a 10946#endif
1d1be34d 10947
1d0cb67d
AF
10948static void ppc_cpu_register_types(void)
10949{
10950 type_register_static(&ppc_cpu_type_info);
e89aac1a 10951#ifndef CONFIG_USER_ONLY
1d1be34d 10952 type_register_static(&ppc_vhyp_type_info);
e89aac1a 10953#endif
1d0cb67d
AF
10954}
10955
10956type_init(ppc_cpu_register_types)