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