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