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