]> git.proxmox.com Git - mirror_qemu.git/blame - target/ppc/translate_init.c
ppc: simplify cpu model lookup by PVR
[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
JM
9318 if (env->irq_inputs == NULL) {
9319 fprintf(stderr, "WARNING: no internal IRQ controller registered.\n"
5cbdb3a3 9320 " Attempt QEMU to crash very soon !\n");
a750fc0b
JM
9321 }
9322#endif
2f462816
JM
9323 if (env->check_pow == NULL) {
9324 fprintf(stderr, "WARNING: no power management check handler "
9325 "registered.\n"
5cbdb3a3 9326 " Attempt QEMU to crash very soon !\n");
2f462816 9327 }
a750fc0b
JM
9328}
9329
9330#if defined(PPC_DUMP_CPU)
c364946d 9331static void dump_ppc_sprs(CPUPPCState *env)
a750fc0b
JM
9332{
9333 ppc_spr_t *spr;
9334#if !defined(CONFIG_USER_ONLY)
9335 uint32_t sr, sw;
9336#endif
9337 uint32_t ur, uw;
9338 int i, j, n;
9339
9340 printf("Special purpose registers:\n");
9341 for (i = 0; i < 32; i++) {
9342 for (j = 0; j < 32; j++) {
9343 n = (i << 5) | j;
9344 spr = &env->spr_cb[n];
9345 uw = spr->uea_write != NULL && spr->uea_write != SPR_NOACCESS;
9346 ur = spr->uea_read != NULL && spr->uea_read != SPR_NOACCESS;
9347#if !defined(CONFIG_USER_ONLY)
9348 sw = spr->oea_write != NULL && spr->oea_write != SPR_NOACCESS;
9349 sr = spr->oea_read != NULL && spr->oea_read != SPR_NOACCESS;
9350 if (sw || sr || uw || ur) {
9351 printf("SPR: %4d (%03x) %-8s s%c%c u%c%c\n",
9352 (i << 5) | j, (i << 5) | j, spr->name,
9353 sw ? 'w' : '-', sr ? 'r' : '-',
9354 uw ? 'w' : '-', ur ? 'r' : '-');
9355 }
9356#else
9357 if (uw || ur) {
9358 printf("SPR: %4d (%03x) %-8s u%c%c\n",
9359 (i << 5) | j, (i << 5) | j, spr->name,
9360 uw ? 'w' : '-', ur ? 'r' : '-');
9361 }
9362#endif
9363 }
9364 }
9365 fflush(stdout);
9366 fflush(stderr);
9367}
9368#endif
9369
9370/*****************************************************************************/
a750fc0b 9371
a750fc0b
JM
9372/* Opcode types */
9373enum {
9374 PPC_DIRECT = 0, /* Opcode routine */
9375 PPC_INDIRECT = 1, /* Indirect opcode table */
9376};
9377
54ff58bb
BR
9378#define PPC_OPCODE_MASK 0x3
9379
c364946d 9380static inline int is_indirect_opcode(void *handler)
a750fc0b 9381{
54ff58bb 9382 return ((uintptr_t)handler & PPC_OPCODE_MASK) == PPC_INDIRECT;
a750fc0b
JM
9383}
9384
c227f099 9385static inline opc_handler_t **ind_table(void *handler)
a750fc0b 9386{
54ff58bb 9387 return (opc_handler_t **)((uintptr_t)handler & ~PPC_OPCODE_MASK);
a750fc0b
JM
9388}
9389
9390/* Instruction table creation */
9391/* Opcodes tables creation */
c364946d 9392static void fill_new_table(opc_handler_t **table, int len)
a750fc0b
JM
9393{
9394 int i;
9395
9396 for (i = 0; i < len; i++)
9397 table[i] = &invalid_handler;
9398}
9399
c364946d 9400static int create_new_table(opc_handler_t **table, unsigned char idx)
a750fc0b 9401{
c227f099 9402 opc_handler_t **tmp;
a750fc0b 9403
54ff58bb
BR
9404 tmp = g_new(opc_handler_t *, PPC_CPU_INDIRECT_OPCODES_LEN);
9405 fill_new_table(tmp, PPC_CPU_INDIRECT_OPCODES_LEN);
5724753e 9406 table[idx] = (opc_handler_t *)((uintptr_t)tmp | PPC_INDIRECT);
a750fc0b
JM
9407
9408 return 0;
9409}
9410
c364946d 9411static int insert_in_table(opc_handler_t **table, unsigned char idx,
c227f099 9412 opc_handler_t *handler)
a750fc0b
JM
9413{
9414 if (table[idx] != &invalid_handler)
9415 return -1;
9416 table[idx] = handler;
9417
9418 return 0;
9419}
9420
c364946d
DG
9421static int register_direct_insn(opc_handler_t **ppc_opcodes,
9422 unsigned char idx, opc_handler_t *handler)
a750fc0b
JM
9423{
9424 if (insert_in_table(ppc_opcodes, idx, handler) < 0) {
9425 printf("*** ERROR: opcode %02x already assigned in main "
9426 "opcode table\n", idx);
4c1b1bfe
JM
9427#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9428 printf(" Registered handler '%s' - new handler '%s'\n",
9429 ppc_opcodes[idx]->oname, handler->oname);
9430#endif
a750fc0b
JM
9431 return -1;
9432 }
9433
9434 return 0;
9435}
9436
c364946d
DG
9437static int register_ind_in_table(opc_handler_t **table,
9438 unsigned char idx1, unsigned char idx2,
9439 opc_handler_t *handler)
a750fc0b
JM
9440{
9441 if (table[idx1] == &invalid_handler) {
9442 if (create_new_table(table, idx1) < 0) {
9443 printf("*** ERROR: unable to create indirect table "
9444 "idx=%02x\n", idx1);
9445 return -1;
9446 }
9447 } else {
9448 if (!is_indirect_opcode(table[idx1])) {
9449 printf("*** ERROR: idx %02x already assigned to a direct "
9450 "opcode\n", idx1);
4c1b1bfe
JM
9451#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9452 printf(" Registered handler '%s' - new handler '%s'\n",
9453 ind_table(table[idx1])[idx2]->oname, handler->oname);
9454#endif
a750fc0b
JM
9455 return -1;
9456 }
3a607854 9457 }
a750fc0b
JM
9458 if (handler != NULL &&
9459 insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) {
9460 printf("*** ERROR: opcode %02x already assigned in "
9461 "opcode table %02x\n", idx2, idx1);
4c1b1bfe
JM
9462#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9463 printf(" Registered handler '%s' - new handler '%s'\n",
9464 ind_table(table[idx1])[idx2]->oname, handler->oname);
9465#endif
a750fc0b 9466 return -1;
3a607854 9467 }
a750fc0b
JM
9468
9469 return 0;
9470}
9471
c364946d
DG
9472static int register_ind_insn(opc_handler_t **ppc_opcodes,
9473 unsigned char idx1, unsigned char idx2,
9474 opc_handler_t *handler)
a750fc0b 9475{
74c373e4 9476 return register_ind_in_table(ppc_opcodes, idx1, idx2, handler);
a750fc0b
JM
9477}
9478
c364946d
DG
9479static int register_dblind_insn(opc_handler_t **ppc_opcodes,
9480 unsigned char idx1, unsigned char idx2,
9481 unsigned char idx3, opc_handler_t *handler)
a750fc0b
JM
9482{
9483 if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
9484 printf("*** ERROR: unable to join indirect table idx "
9485 "[%02x-%02x]\n", idx1, idx2);
9486 return -1;
9487 }
9488 if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3,
9489 handler) < 0) {
9490 printf("*** ERROR: unable to insert opcode "
9491 "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
9492 return -1;
9493 }
9494
9495 return 0;
9496}
9497
323ad19b
ND
9498static int register_trplind_insn(opc_handler_t **ppc_opcodes,
9499 unsigned char idx1, unsigned char idx2,
9500 unsigned char idx3, unsigned char idx4,
9501 opc_handler_t *handler)
9502{
9503 opc_handler_t **table;
9504
9505 if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
9506 printf("*** ERROR: unable to join indirect table idx "
9507 "[%02x-%02x]\n", idx1, idx2);
9508 return -1;
9509 }
9510 table = ind_table(ppc_opcodes[idx1]);
9511 if (register_ind_in_table(table, idx2, idx3, NULL) < 0) {
9512 printf("*** ERROR: unable to join 2nd-level indirect table idx "
9513 "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
9514 return -1;
9515 }
9516 table = ind_table(table[idx2]);
9517 if (register_ind_in_table(table, idx3, idx4, handler) < 0) {
9518 printf("*** ERROR: unable to insert opcode "
9519 "[%02x-%02x-%02x-%02x]\n", idx1, idx2, idx3, idx4);
9520 return -1;
9521 }
9522 return 0;
9523}
c364946d 9524static int register_insn(opc_handler_t **ppc_opcodes, opcode_t *insn)
a750fc0b
JM
9525{
9526 if (insn->opc2 != 0xFF) {
9527 if (insn->opc3 != 0xFF) {
323ad19b
ND
9528 if (insn->opc4 != 0xFF) {
9529 if (register_trplind_insn(ppc_opcodes, insn->opc1, insn->opc2,
9530 insn->opc3, insn->opc4,
9531 &insn->handler) < 0) {
9532 return -1;
9533 }
9534 } else {
9535 if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2,
9536 insn->opc3, &insn->handler) < 0)
9537 return -1;
9538 }
a750fc0b
JM
9539 } else {
9540 if (register_ind_insn(ppc_opcodes, insn->opc1,
9541 insn->opc2, &insn->handler) < 0)
9542 return -1;
9543 }
9544 } else {
9545 if (register_direct_insn(ppc_opcodes, insn->opc1, &insn->handler) < 0)
9546 return -1;
9547 }
9548
9549 return 0;
9550}
9551
c364946d 9552static int test_opcode_table(opc_handler_t **table, int len)
a750fc0b
JM
9553{
9554 int i, count, tmp;
9555
9556 for (i = 0, count = 0; i < len; i++) {
9557 /* Consistency fixup */
9558 if (table[i] == NULL)
9559 table[i] = &invalid_handler;
9560 if (table[i] != &invalid_handler) {
9561 if (is_indirect_opcode(table[i])) {
54ff58bb
BR
9562 tmp = test_opcode_table(ind_table(table[i]),
9563 PPC_CPU_INDIRECT_OPCODES_LEN);
a750fc0b
JM
9564 if (tmp == 0) {
9565 free(table[i]);
9566 table[i] = &invalid_handler;
9567 } else {
9568 count++;
9569 }
9570 } else {
9571 count++;
9572 }
9573 }
9574 }
9575
9576 return count;
9577}
9578
c364946d 9579static void fix_opcode_tables(opc_handler_t **ppc_opcodes)
a750fc0b 9580{
54ff58bb 9581 if (test_opcode_table(ppc_opcodes, PPC_CPU_OPCODES_LEN) == 0)
a750fc0b
JM
9582 printf("*** WARNING: no opcode defined !\n");
9583}
9584
9585/*****************************************************************************/
2985b86b 9586static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp)
a750fc0b 9587{
2985b86b
AF
9588 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
9589 CPUPPCState *env = &cpu->env;
c227f099 9590 opcode_t *opc;
a750fc0b 9591
54ff58bb 9592 fill_new_table(env->opcodes, PPC_CPU_OPCODES_LEN);
5c55ff99 9593 for (opc = opcodes; opc < &opcodes[ARRAY_SIZE(opcodes)]; opc++) {
cfe34f44
AF
9594 if (((opc->handler.type & pcc->insns_flags) != 0) ||
9595 ((opc->handler.type2 & pcc->insns_flags2) != 0)) {
a750fc0b 9596 if (register_insn(env->opcodes, opc) < 0) {
2985b86b 9597 error_setg(errp, "ERROR initializing PowerPC instruction "
312fd5f2 9598 "0x%02x 0x%02x 0x%02x", opc->opc1, opc->opc2,
2985b86b
AF
9599 opc->opc3);
9600 return;
a750fc0b
JM
9601 }
9602 }
9603 }
c227f099 9604 fix_opcode_tables(env->opcodes);
a750fc0b
JM
9605 fflush(stdout);
9606 fflush(stderr);
a750fc0b
JM
9607}
9608
9609#if defined(PPC_DUMP_CPU)
c364946d 9610static void dump_ppc_insns(CPUPPCState *env)
a750fc0b 9611{
c227f099 9612 opc_handler_t **table, *handler;
b55266b5 9613 const char *p, *q;
323ad19b 9614 uint8_t opc1, opc2, opc3, opc4;
a750fc0b
JM
9615
9616 printf("Instructions set:\n");
9617 /* opc1 is 6 bits long */
54ff58bb 9618 for (opc1 = 0x00; opc1 < PPC_CPU_OPCODES_LEN; opc1++) {
a750fc0b
JM
9619 table = env->opcodes;
9620 handler = table[opc1];
9621 if (is_indirect_opcode(handler)) {
9622 /* opc2 is 5 bits long */
54ff58bb 9623 for (opc2 = 0; opc2 < PPC_CPU_INDIRECT_OPCODES_LEN; opc2++) {
a750fc0b
JM
9624 table = env->opcodes;
9625 handler = env->opcodes[opc1];
9626 table = ind_table(handler);
9627 handler = table[opc2];
9628 if (is_indirect_opcode(handler)) {
9629 table = ind_table(handler);
9630 /* opc3 is 5 bits long */
54ff58bb
BR
9631 for (opc3 = 0; opc3 < PPC_CPU_INDIRECT_OPCODES_LEN;
9632 opc3++) {
a750fc0b 9633 handler = table[opc3];
323ad19b
ND
9634 if (is_indirect_opcode(handler)) {
9635 table = ind_table(handler);
9636 /* opc4 is 5 bits long */
9637 for (opc4 = 0; opc4 < PPC_CPU_INDIRECT_OPCODES_LEN;
9638 opc4++) {
9639 handler = table[opc4];
9640 if (handler->handler != &gen_invalid) {
9641 printf("INSN: %02x %02x %02x %02x -- "
9642 "(%02d %04d %02d) : %s\n",
9643 opc1, opc2, opc3, opc4,
9644 opc1, (opc3 << 5) | opc2, opc4,
4c1b1bfe
JM
9645 handler->oname);
9646 }
323ad19b
ND
9647 }
9648 } else {
9649 if (handler->handler != &gen_invalid) {
9650 /* Special hack to properly dump SPE insns */
9651 p = strchr(handler->oname, '_');
9652 if (p == NULL) {
4c1b1bfe
JM
9653 printf("INSN: %02x %02x %02x (%02d %04d) : "
9654 "%s\n",
323ad19b
ND
9655 opc1, opc2, opc3, opc1,
9656 (opc3 << 5) | opc2,
9657 handler->oname);
9658 } else {
9659 q = "speundef";
9660 if ((p - handler->oname) != strlen(q)
9661 || (memcmp(handler->oname, q, strlen(q))
9662 != 0)) {
9663 /* First instruction */
9664 printf("INSN: %02x %02x %02x"
9665 "(%02d %04d) : %.*s\n",
9666 opc1, opc2 << 1, opc3, opc1,
9667 (opc3 << 6) | (opc2 << 1),
9668 (int)(p - handler->oname),
9669 handler->oname);
9670 }
9671 if (strcmp(p + 1, q) != 0) {
9672 /* Second instruction */
9673 printf("INSN: %02x %02x %02x "
9674 "(%02d %04d) : %s\n", opc1,
9675 (opc2 << 1) | 1, opc3, opc1,
9676 (opc3 << 6) | (opc2 << 1) | 1,
9677 p + 1);
9678 }
4c1b1bfe
JM
9679 }
9680 }
a750fc0b
JM
9681 }
9682 }
9683 } else {
9684 if (handler->handler != &gen_invalid) {
9685 printf("INSN: %02x %02x -- (%02d %04d) : %s\n",
9686 opc1, opc2, opc1, opc2, handler->oname);
9687 }
9688 }
9689 }
9690 } else {
9691 if (handler->handler != &gen_invalid) {
9692 printf("INSN: %02x -- -- (%02d ----) : %s\n",
9693 opc1, opc1, handler->oname);
9694 }
9695 }
9696 }
9697}
3a607854 9698#endif
a750fc0b 9699
87601e2d
GK
9700static bool avr_need_swap(CPUPPCState *env)
9701{
9702#ifdef HOST_WORDS_BIGENDIAN
ea499e71 9703 return msr_le;
87601e2d 9704#else
ea499e71 9705 return !msr_le;
87601e2d
GK
9706#endif
9707}
9708
1328c2bf 9709static int gdb_get_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
24951522
AJ
9710{
9711 if (n < 32) {
9712 stfq_p(mem_buf, env->fpr[n]);
385abeb3 9713 ppc_maybe_bswap_register(env, mem_buf, 8);
24951522
AJ
9714 return 8;
9715 }
9716 if (n == 32) {
5a576fb3 9717 stl_p(mem_buf, env->fpscr);
385abeb3 9718 ppc_maybe_bswap_register(env, mem_buf, 4);
24951522
AJ
9719 return 4;
9720 }
9721 return 0;
9722}
9723
1328c2bf 9724static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
24951522
AJ
9725{
9726 if (n < 32) {
385abeb3 9727 ppc_maybe_bswap_register(env, mem_buf, 8);
24951522
AJ
9728 env->fpr[n] = ldfq_p(mem_buf);
9729 return 8;
9730 }
9731 if (n == 32) {
385abeb3 9732 ppc_maybe_bswap_register(env, mem_buf, 4);
d6478bc7 9733 helper_store_fpscr(env, ldl_p(mem_buf), 0xffffffff);
24951522
AJ
9734 return 4;
9735 }
9736 return 0;
9737}
9738
1328c2bf 9739static int gdb_get_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
b4f8d821
AJ
9740{
9741 if (n < 32) {
87601e2d
GK
9742 if (!avr_need_swap(env)) {
9743 stq_p(mem_buf, env->avr[n].u64[0]);
9744 stq_p(mem_buf+8, env->avr[n].u64[1]);
9745 } else {
9746 stq_p(mem_buf, env->avr[n].u64[1]);
9747 stq_p(mem_buf+8, env->avr[n].u64[0]);
9748 }
ea499e71
GK
9749 ppc_maybe_bswap_register(env, mem_buf, 8);
9750 ppc_maybe_bswap_register(env, mem_buf + 8, 8);
b4f8d821
AJ
9751 return 16;
9752 }
70976a79 9753 if (n == 32) {
b4f8d821 9754 stl_p(mem_buf, env->vscr);
ea499e71 9755 ppc_maybe_bswap_register(env, mem_buf, 4);
b4f8d821
AJ
9756 return 4;
9757 }
70976a79 9758 if (n == 33) {
b4f8d821 9759 stl_p(mem_buf, (uint32_t)env->spr[SPR_VRSAVE]);
ea499e71 9760 ppc_maybe_bswap_register(env, mem_buf, 4);
b4f8d821
AJ
9761 return 4;
9762 }
9763 return 0;
9764}
9765
1328c2bf 9766static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
b4f8d821
AJ
9767{
9768 if (n < 32) {
ea499e71
GK
9769 ppc_maybe_bswap_register(env, mem_buf, 8);
9770 ppc_maybe_bswap_register(env, mem_buf + 8, 8);
87601e2d
GK
9771 if (!avr_need_swap(env)) {
9772 env->avr[n].u64[0] = ldq_p(mem_buf);
9773 env->avr[n].u64[1] = ldq_p(mem_buf+8);
9774 } else {
9775 env->avr[n].u64[1] = ldq_p(mem_buf);
9776 env->avr[n].u64[0] = ldq_p(mem_buf+8);
9777 }
b4f8d821
AJ
9778 return 16;
9779 }
70976a79 9780 if (n == 32) {
ea499e71 9781 ppc_maybe_bswap_register(env, mem_buf, 4);
b4f8d821
AJ
9782 env->vscr = ldl_p(mem_buf);
9783 return 4;
9784 }
70976a79 9785 if (n == 33) {
ea499e71 9786 ppc_maybe_bswap_register(env, mem_buf, 4);
b4f8d821
AJ
9787 env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf);
9788 return 4;
9789 }
9790 return 0;
9791}
9792
1328c2bf 9793static int gdb_get_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
688890f7
AJ
9794{
9795 if (n < 32) {
9796#if defined(TARGET_PPC64)
9797 stl_p(mem_buf, env->gpr[n] >> 32);
95f5b540 9798 ppc_maybe_bswap_register(env, mem_buf, 4);
688890f7
AJ
9799#else
9800 stl_p(mem_buf, env->gprh[n]);
9801#endif
9802 return 4;
9803 }
70976a79 9804 if (n == 32) {
688890f7 9805 stq_p(mem_buf, env->spe_acc);
95f5b540 9806 ppc_maybe_bswap_register(env, mem_buf, 8);
688890f7
AJ
9807 return 8;
9808 }
70976a79 9809 if (n == 33) {
d34defbc 9810 stl_p(mem_buf, env->spe_fscr);
95f5b540 9811 ppc_maybe_bswap_register(env, mem_buf, 4);
688890f7
AJ
9812 return 4;
9813 }
9814 return 0;
9815}
9816
1328c2bf 9817static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
688890f7
AJ
9818{
9819 if (n < 32) {
9820#if defined(TARGET_PPC64)
9821 target_ulong lo = (uint32_t)env->gpr[n];
95f5b540
GK
9822 target_ulong hi;
9823
9824 ppc_maybe_bswap_register(env, mem_buf, 4);
9825
9826 hi = (target_ulong)ldl_p(mem_buf) << 32;
688890f7
AJ
9827 env->gpr[n] = lo | hi;
9828#else
9829 env->gprh[n] = ldl_p(mem_buf);
9830#endif
9831 return 4;
9832 }
70976a79 9833 if (n == 32) {
95f5b540 9834 ppc_maybe_bswap_register(env, mem_buf, 8);
688890f7
AJ
9835 env->spe_acc = ldq_p(mem_buf);
9836 return 8;
9837 }
70976a79 9838 if (n == 33) {
95f5b540 9839 ppc_maybe_bswap_register(env, mem_buf, 4);
d34defbc 9840 env->spe_fscr = ldl_p(mem_buf);
688890f7
AJ
9841 return 4;
9842 }
9843 return 0;
9844}
9845
1438eff3
AB
9846static int gdb_get_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
9847{
9848 if (n < 32) {
9849 stq_p(mem_buf, env->vsr[n]);
9850 ppc_maybe_bswap_register(env, mem_buf, 8);
9851 return 8;
9852 }
9853 return 0;
9854}
9855
9856static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
9857{
9858 if (n < 32) {
9859 ppc_maybe_bswap_register(env, mem_buf, 8);
9860 env->vsr[n] = ldq_p(mem_buf);
9861 return 8;
9862 }
9863 return 0;
9864}
9865
55e5c285 9866static int ppc_fixup_cpu(PowerPCCPU *cpu)
12b1143b 9867{
55e5c285
AF
9868 CPUPPCState *env = &cpu->env;
9869
12b1143b
DG
9870 /* TCG doesn't (yet) emulate some groups of instructions that
9871 * are implemented on some otherwise supported CPUs (e.g. VSX
9872 * and decimal floating point instructions on POWER7). We
9873 * remove unsupported instruction groups from the cpu state's
9874 * instruction masks and hope the guest can cope. For at
9875 * least the pseries machine, the unavailability of these
9876 * instructions can be advertised to the guest via the device
9877 * tree. */
9878 if ((env->insns_flags & ~PPC_TCG_INSNS)
9879 || (env->insns_flags2 & ~PPC_TCG_INSNS2)) {
9880 fprintf(stderr, "Warning: Disabling some instructions which are not "
9881 "emulated by TCG (0x%" PRIx64 ", 0x%" PRIx64 ")\n",
9882 env->insns_flags & ~PPC_TCG_INSNS,
9883 env->insns_flags2 & ~PPC_TCG_INSNS2);
9884 }
9885 env->insns_flags &= PPC_TCG_INSNS;
9886 env->insns_flags2 &= PPC_TCG_INSNS2;
9887 return 0;
9888}
9889
292363e1
AF
9890static inline bool ppc_cpu_is_valid(PowerPCCPUClass *pcc)
9891{
9892#ifdef TARGET_PPCEMB
9893 return pcc->mmu_model == POWERPC_MMU_BOOKE ||
9894 pcc->mmu_model == POWERPC_MMU_SOFT_4xx ||
9895 pcc->mmu_model == POWERPC_MMU_SOFT_4xx_Z;
9896#else
9897 return true;
9898#endif
9899}
9900
4776ce60 9901static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
a750fc0b 9902{
22169d41 9903 CPUState *cs = CPU(dev);
4776ce60 9904 PowerPCCPU *cpu = POWERPC_CPU(dev);
2985b86b 9905 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
2985b86b 9906 Error *local_err = NULL;
fe828a4d 9907#if !defined(CONFIG_USER_ONLY)
c4e6c423 9908 int max_smt = kvmppc_smt_threads();
fe828a4d
MQ
9909#endif
9910
ce5b1bbf 9911 cpu_exec_realizefn(cs, &local_err);
6dd0f834
BR
9912 if (local_err != NULL) {
9913 error_propagate(errp, local_err);
9914 return;
9915 }
0ce470cd 9916
6dd0f834 9917#if !defined(CONFIG_USER_ONLY)
81210c20 9918 cpu->vcpu_id = (cs->cpu_index / smp_threads) * max_smt
0ce470cd 9919 + (cs->cpu_index % smp_threads);
41264b38 9920
81210c20
SB
9921 if (kvm_enabled() && !kvm_vcpu_id_is_valid(cpu->vcpu_id)) {
9922 error_setg(errp, "Can't create CPU with id %d in KVM", cpu->vcpu_id);
41264b38
GK
9923 error_append_hint(errp, "Adjust the number of cpus to %d "
9924 "or try to raise the number of threads per core\n",
81210c20 9925 cpu->vcpu_id * smp_threads / max_smt);
fd356563 9926 goto unrealize;
41264b38 9927 }
fe828a4d 9928#endif
4656e1f0 9929
0ce470cd 9930 if (tcg_enabled()) {
55e5c285 9931 if (ppc_fixup_cpu(cpu) != 0) {
2985b86b 9932 error_setg(errp, "Unable to emulate selected CPU with TCG");
fd356563 9933 goto unrealize;
12b1143b
DG
9934 }
9935 }
9936
4d7fb187 9937#if defined(TARGET_PPCEMB)
292363e1
AF
9938 if (!ppc_cpu_is_valid(pcc)) {
9939 error_setg(errp, "CPU does not possess a BookE or 4xx MMU. "
4d7fb187
AF
9940 "Please use qemu-system-ppc or qemu-system-ppc64 instead "
9941 "or choose another CPU model.");
fd356563 9942 goto unrealize;
4d7fb187
AF
9943 }
9944#endif
9945
2985b86b
AF
9946 create_ppc_opcodes(cpu, &local_err);
9947 if (local_err != NULL) {
9948 error_propagate(errp, local_err);
fd356563 9949 goto unrealize;
2985b86b 9950 }
cfe34f44 9951 init_ppc_proc(cpu);
24951522 9952
cfe34f44 9953 if (pcc->insns_flags & PPC_FLOAT) {
22169d41 9954 gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
24951522
AJ
9955 33, "power-fpu.xml", 0);
9956 }
cfe34f44 9957 if (pcc->insns_flags & PPC_ALTIVEC) {
22169d41 9958 gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg,
b4f8d821
AJ
9959 34, "power-altivec.xml", 0);
9960 }
cfe34f44 9961 if (pcc->insns_flags & PPC_SPE) {
22169d41 9962 gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
688890f7
AJ
9963 34, "power-spe.xml", 0);
9964 }
1438eff3
AB
9965 if (pcc->insns_flags2 & PPC2_VSX) {
9966 gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg,
9967 32, "power-vsx.xml", 0);
9968 }
688890f7 9969
14a10fc3
AF
9970 qemu_init_vcpu(cs);
9971
4776ce60
AF
9972 pcc->parent_realize(dev, errp);
9973
a750fc0b 9974#if defined(PPC_DUMP_CPU)
3a607854 9975 {
22169d41 9976 CPUPPCState *env = &cpu->env;
b55266b5 9977 const char *mmu_model, *excp_model, *bus_model;
a750fc0b
JM
9978 switch (env->mmu_model) {
9979 case POWERPC_MMU_32B:
9980 mmu_model = "PowerPC 32";
9981 break;
a750fc0b
JM
9982 case POWERPC_MMU_SOFT_6xx:
9983 mmu_model = "PowerPC 6xx/7xx with software driven TLBs";
9984 break;
9985 case POWERPC_MMU_SOFT_74xx:
9986 mmu_model = "PowerPC 74xx with software driven TLBs";
9987 break;
9988 case POWERPC_MMU_SOFT_4xx:
9989 mmu_model = "PowerPC 4xx with software driven TLBs";
9990 break;
9991 case POWERPC_MMU_SOFT_4xx_Z:
9992 mmu_model = "PowerPC 4xx with software driven TLBs "
9993 "and zones protections";
9994 break;
b4095fed
JM
9995 case POWERPC_MMU_REAL:
9996 mmu_model = "PowerPC real mode only";
9997 break;
9998 case POWERPC_MMU_MPC8xx:
9999 mmu_model = "PowerPC MPC8xx";
a750fc0b
JM
10000 break;
10001 case POWERPC_MMU_BOOKE:
10002 mmu_model = "PowerPC BookE";
10003 break;
01662f3e
AG
10004 case POWERPC_MMU_BOOKE206:
10005 mmu_model = "PowerPC BookE 2.06";
a750fc0b 10006 break;
b4095fed
JM
10007 case POWERPC_MMU_601:
10008 mmu_model = "PowerPC 601";
10009 break;
c364946d 10010#if defined(TARGET_PPC64)
00af685f
JM
10011 case POWERPC_MMU_64B:
10012 mmu_model = "PowerPC 64";
10013 break;
00af685f 10014#endif
a750fc0b
JM
10015 default:
10016 mmu_model = "Unknown or invalid";
10017 break;
10018 }
10019 switch (env->excp_model) {
10020 case POWERPC_EXCP_STD:
10021 excp_model = "PowerPC";
10022 break;
10023 case POWERPC_EXCP_40x:
10024 excp_model = "PowerPC 40x";
10025 break;
10026 case POWERPC_EXCP_601:
10027 excp_model = "PowerPC 601";
10028 break;
10029 case POWERPC_EXCP_602:
10030 excp_model = "PowerPC 602";
10031 break;
10032 case POWERPC_EXCP_603:
10033 excp_model = "PowerPC 603";
10034 break;
10035 case POWERPC_EXCP_603E:
10036 excp_model = "PowerPC 603e";
10037 break;
10038 case POWERPC_EXCP_604:
10039 excp_model = "PowerPC 604";
10040 break;
10041 case POWERPC_EXCP_7x0:
10042 excp_model = "PowerPC 740/750";
10043 break;
10044 case POWERPC_EXCP_7x5:
10045 excp_model = "PowerPC 745/755";
10046 break;
10047 case POWERPC_EXCP_74xx:
10048 excp_model = "PowerPC 74xx";
10049 break;
a750fc0b
JM
10050 case POWERPC_EXCP_BOOKE:
10051 excp_model = "PowerPC BookE";
10052 break;
c364946d 10053#if defined(TARGET_PPC64)
00af685f
JM
10054 case POWERPC_EXCP_970:
10055 excp_model = "PowerPC 970";
10056 break;
10057#endif
a750fc0b
JM
10058 default:
10059 excp_model = "Unknown or invalid";
10060 break;
10061 }
10062 switch (env->bus_model) {
10063 case PPC_FLAGS_INPUT_6xx:
10064 bus_model = "PowerPC 6xx";
10065 break;
10066 case PPC_FLAGS_INPUT_BookE:
10067 bus_model = "PowerPC BookE";
10068 break;
10069 case PPC_FLAGS_INPUT_405:
10070 bus_model = "PowerPC 405";
10071 break;
a750fc0b
JM
10072 case PPC_FLAGS_INPUT_401:
10073 bus_model = "PowerPC 401/403";
10074 break;
b4095fed
JM
10075 case PPC_FLAGS_INPUT_RCPU:
10076 bus_model = "RCPU / MPC8xx";
10077 break;
c364946d 10078#if defined(TARGET_PPC64)
00af685f
JM
10079 case PPC_FLAGS_INPUT_970:
10080 bus_model = "PowerPC 970";
10081 break;
10082#endif
a750fc0b
JM
10083 default:
10084 bus_model = "Unknown or invalid";
10085 break;
10086 }
10087 printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64 "\n"
10088 " MMU model : %s\n",
a5100e75
AK
10089 object_class_get_name(OBJECT_CLASS(pcc)),
10090 pcc->pvr, pcc->msr_mask, mmu_model);
f2e63a42 10091#if !defined(CONFIG_USER_ONLY)
a5100e75 10092 if (env->tlb.tlb6) {
a750fc0b
JM
10093 printf(" %d %s TLB in %d ways\n",
10094 env->nb_tlb, env->id_tlbs ? "splitted" : "merged",
10095 env->nb_ways);
10096 }
f2e63a42 10097#endif
a750fc0b
JM
10098 printf(" Exceptions model : %s\n"
10099 " Bus model : %s\n",
10100 excp_model, bus_model);
25ba3a68
JM
10101 printf(" MSR features :\n");
10102 if (env->flags & POWERPC_FLAG_SPE)
10103 printf(" signal processing engine enable"
10104 "\n");
10105 else if (env->flags & POWERPC_FLAG_VRE)
10106 printf(" vector processor enable\n");
10107 if (env->flags & POWERPC_FLAG_TGPR)
10108 printf(" temporary GPRs\n");
10109 else if (env->flags & POWERPC_FLAG_CE)
10110 printf(" critical input enable\n");
10111 if (env->flags & POWERPC_FLAG_SE)
10112 printf(" single-step trace mode\n");
10113 else if (env->flags & POWERPC_FLAG_DWE)
10114 printf(" debug wait enable\n");
10115 else if (env->flags & POWERPC_FLAG_UBLE)
10116 printf(" user BTB lock enable\n");
10117 if (env->flags & POWERPC_FLAG_BE)
10118 printf(" branch-step trace mode\n");
10119 else if (env->flags & POWERPC_FLAG_DE)
10120 printf(" debug interrupt enable\n");
10121 if (env->flags & POWERPC_FLAG_PX)
10122 printf(" inclusive protection\n");
10123 else if (env->flags & POWERPC_FLAG_PMM)
10124 printf(" performance monitor mark\n");
10125 if (env->flags == POWERPC_FLAG_NONE)
10126 printf(" none\n");
4018bae9
JM
10127 printf(" Time-base/decrementer clock source: %s\n",
10128 env->flags & POWERPC_FLAG_RTC_CLK ? "RTC clock" : "bus clock");
22169d41
AF
10129 dump_ppc_insns(env);
10130 dump_ppc_sprs(env);
10131 fflush(stdout);
a750fc0b 10132 }
3a607854 10133#endif
fd356563
BR
10134 return;
10135
10136unrealize:
10137 cpu_exec_unrealizefn(cs);
a750fc0b 10138}
3fc6c082 10139
b048960f
AF
10140static void ppc_cpu_unrealizefn(DeviceState *dev, Error **errp)
10141{
10142 PowerPCCPU *cpu = POWERPC_CPU(dev);
7bbc124e 10143 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
b048960f 10144 CPUPPCState *env = &cpu->env;
7bbc124e 10145 Error *local_err = NULL;
323ad19b
ND
10146 opc_handler_t **table, **table_2;
10147 int i, j, k;
b048960f 10148
7bbc124e
LV
10149 pcc->parent_unrealize(dev, &local_err);
10150 if (local_err != NULL) {
10151 error_propagate(errp, local_err);
10152 return;
10153 }
6dd0f834 10154
b048960f 10155 for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) {
81f194dd
BR
10156 if (env->opcodes[i] == &invalid_handler) {
10157 continue;
10158 }
10159 if (is_indirect_opcode(env->opcodes[i])) {
10160 table = ind_table(env->opcodes[i]);
10161 for (j = 0; j < PPC_CPU_INDIRECT_OPCODES_LEN; j++) {
323ad19b
ND
10162 if (table[j] == &invalid_handler) {
10163 continue;
10164 }
10165 if (is_indirect_opcode(table[j])) {
10166 table_2 = ind_table(table[j]);
10167 for (k = 0; k < PPC_CPU_INDIRECT_OPCODES_LEN; k++) {
10168 if (table_2[k] != &invalid_handler &&
10169 is_indirect_opcode(table_2[k])) {
10170 g_free((opc_handler_t *)((uintptr_t)table_2[k] &
10171 ~PPC_INDIRECT));
10172 }
10173 }
81f194dd 10174 g_free((opc_handler_t *)((uintptr_t)table[j] &
323ad19b 10175 ~PPC_INDIRECT));
81f194dd
BR
10176 }
10177 }
10178 g_free((opc_handler_t *)((uintptr_t)env->opcodes[i] &
10179 ~PPC_INDIRECT));
b048960f
AF
10180 }
10181 }
10182}
10183
2985b86b 10184static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b)
f0ad8c34 10185{
2985b86b
AF
10186 ObjectClass *oc = (ObjectClass *)a;
10187 uint32_t pvr = *(uint32_t *)b;
10188 PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
10189
10190 /* -cpu host does a PVR lookup during construction */
10191 if (unlikely(strcmp(object_class_get_name(oc),
10192 TYPE_HOST_POWERPC_CPU) == 0)) {
10193 return -1;
f0ad8c34 10194 }
f0ad8c34 10195
292363e1 10196 if (!ppc_cpu_is_valid(pcc)) {
4d7fb187
AF
10197 return -1;
10198 }
4d7fb187 10199
cfe34f44 10200 return pcc->pvr == pvr ? 0 : -1;
f0ad8c34
AG
10201}
10202
2985b86b 10203PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr)
3fc6c082 10204{
2985b86b
AF
10205 GSList *list, *item;
10206 PowerPCCPUClass *pcc = NULL;
be40edcd 10207
2985b86b
AF
10208 list = object_class_get_list(TYPE_POWERPC_CPU, false);
10209 item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr);
10210 if (item != NULL) {
10211 pcc = POWERPC_CPU_CLASS(item->data);
3fc6c082 10212 }
2985b86b
AF
10213 g_slist_free(list);
10214
10215 return pcc;
10216}
10217
3bc9ccc0
AK
10218static gint ppc_cpu_compare_class_pvr_mask(gconstpointer a, gconstpointer b)
10219{
10220 ObjectClass *oc = (ObjectClass *)a;
10221 uint32_t pvr = *(uint32_t *)b;
10222 PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
3bc9ccc0
AK
10223
10224 /* -cpu host does a PVR lookup during construction */
10225 if (unlikely(strcmp(object_class_get_name(oc),
10226 TYPE_HOST_POWERPC_CPU) == 0)) {
10227 return -1;
10228 }
10229
292363e1 10230 if (!ppc_cpu_is_valid(pcc)) {
3bc9ccc0
AK
10231 return -1;
10232 }
292363e1 10233
03ae4133
AK
10234 if (pcc->pvr_match(pcc, pvr)) {
10235 return 0;
10236 }
3bc9ccc0 10237
03ae4133 10238 return -1;
3bc9ccc0
AK
10239}
10240
10241PowerPCCPUClass *ppc_cpu_class_by_pvr_mask(uint32_t pvr)
10242{
10243 GSList *list, *item;
10244 PowerPCCPUClass *pcc = NULL;
10245
10246 list = object_class_get_list(TYPE_POWERPC_CPU, true);
10247 item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr_mask);
10248 if (item != NULL) {
10249 pcc = POWERPC_CPU_CLASS(item->data);
10250 }
10251 g_slist_free(list);
10252
10253 return pcc;
10254}
10255
9761ad75
AG
10256static ObjectClass *ppc_cpu_class_by_name(const char *name);
10257
10258static ObjectClass *ppc_cpu_class_by_alias(PowerPCCPUAlias *alias)
10259{
10260 ObjectClass *invalid_class = (void*)ppc_cpu_class_by_alias;
10261
10262 /* Cache target class lookups in the alias table */
10263 if (!alias->oc) {
10264 alias->oc = ppc_cpu_class_by_name(alias->model);
10265 if (!alias->oc) {
10266 /* Fast check for non-existing aliases */
10267 alias->oc = invalid_class;
10268 }
10269 }
10270
10271 if (alias->oc == invalid_class) {
10272 return NULL;
10273 } else {
10274 return alias->oc;
10275 }
10276}
10277
2985b86b 10278static ObjectClass *ppc_cpu_class_by_name(const char *name)
ee4e83ed 10279{
03c9141d
IM
10280 char *cpu_model, *typename;
10281 ObjectClass *oc;
b55266b5 10282 const char *p;
b376db77
IM
10283 unsigned long pvr;
10284
10285 /* Lookup by PVR if cpu_model is valid 8 digit hex number
10286 * (excl: 0x prefix if present)
10287 */
10288 if (!qemu_strtoul(name, &p, 16, &pvr)) {
10289 int len = p - name;
10290 len = (len == 10) && (name[1] == 'x') ? len - 2 : len;
10291 if ((len == 8) && (*p == '\0')) {
10292 return OBJECT_CLASS(ppc_cpu_class_by_pvr(pvr));
f0ad8c34 10293 }
2985b86b 10294 }
f0ad8c34 10295
03c9141d
IM
10296 cpu_model = g_ascii_strdown(name, -1);
10297 p = ppc_cpu_lookup_alias(cpu_model);
10298 if (p) {
10299 g_free(cpu_model);
10300 cpu_model = g_strdup(p);
3fc6c082 10301 }
ee4e83ed 10302
03c9141d
IM
10303 typename = g_strdup_printf("%s" POWERPC_CPU_TYPE_SUFFIX, cpu_model);
10304 oc = object_class_by_name(typename);
10305 g_free(typename);
10306 g_free(cpu_model);
fdf8a960 10307
03c9141d
IM
10308 if (oc && ppc_cpu_is_valid(POWERPC_CPU_CLASS(oc))) {
10309 return oc;
fdf8a960
AK
10310 }
10311
10312 return NULL;
3fc6c082
FB
10313}
10314
caf6316d
TH
10315const char *ppc_cpu_lookup_alias(const char *alias)
10316{
10317 int ai;
10318
10319 for (ai = 0; ppc_cpu_aliases[ai].alias != NULL; ai++) {
10320 if (strcmp(ppc_cpu_aliases[ai].alias, alias) == 0) {
10321 return ppc_cpu_aliases[ai].model;
10322 }
10323 }
10324
10325 return NULL;
10326}
10327
e9edd931
TH
10328PowerPCCPUClass *ppc_cpu_get_family_class(PowerPCCPUClass *pcc)
10329{
10330 ObjectClass *oc = OBJECT_CLASS(pcc);
10331
10332 while (oc && !object_class_is_abstract(oc)) {
10333 oc = object_class_get_parent(oc);
10334 }
10335 assert(oc);
10336
10337 return POWERPC_CPU_CLASS(oc);
10338}
10339
2985b86b
AF
10340/* Sort by PVR, ordering special case "host" last. */
10341static gint ppc_cpu_list_compare(gconstpointer a, gconstpointer b)
10342{
10343 ObjectClass *oc_a = (ObjectClass *)a;
10344 ObjectClass *oc_b = (ObjectClass *)b;
10345 PowerPCCPUClass *pcc_a = POWERPC_CPU_CLASS(oc_a);
10346 PowerPCCPUClass *pcc_b = POWERPC_CPU_CLASS(oc_b);
10347 const char *name_a = object_class_get_name(oc_a);
10348 const char *name_b = object_class_get_name(oc_b);
10349
10350 if (strcmp(name_a, TYPE_HOST_POWERPC_CPU) == 0) {
10351 return 1;
10352 } else if (strcmp(name_b, TYPE_HOST_POWERPC_CPU) == 0) {
10353 return -1;
10354 } else {
10355 /* Avoid an integer overflow during subtraction */
cfe34f44 10356 if (pcc_a->pvr < pcc_b->pvr) {
2985b86b 10357 return -1;
cfe34f44 10358 } else if (pcc_a->pvr > pcc_b->pvr) {
2985b86b
AF
10359 return 1;
10360 } else {
10361 return 0;
10362 }
10363 }
10364}
10365
10366static void ppc_cpu_list_entry(gpointer data, gpointer user_data)
10367{
10368 ObjectClass *oc = data;
10369 CPUListState *s = user_data;
10370 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
e9edd931 10371 DeviceClass *family = DEVICE_CLASS(ppc_cpu_get_family_class(pcc));
de400129
AF
10372 const char *typename = object_class_get_name(oc);
10373 char *name;
55d3d1a4 10374 int i;
2985b86b 10375
292363e1 10376 if (!ppc_cpu_is_valid(pcc)) {
4d7fb187
AF
10377 return;
10378 }
5ba4576b
AF
10379 if (unlikely(strcmp(typename, TYPE_HOST_POWERPC_CPU) == 0)) {
10380 return;
10381 }
4d7fb187 10382
de400129 10383 name = g_strndup(typename,
c9137065 10384 strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX));
2985b86b 10385 (*s->cpu_fprintf)(s->file, "PowerPC %-16s PVR %08x\n",
cfe34f44 10386 name, pcc->pvr);
e9a96075 10387 for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
9761ad75
AG
10388 PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
10389 ObjectClass *alias_oc = ppc_cpu_class_by_alias(alias);
55d3d1a4
AF
10390
10391 if (alias_oc != oc) {
10392 continue;
10393 }
e9edd931
TH
10394 /*
10395 * If running with KVM, we might update the family alias later, so
10396 * avoid printing the wrong alias here and use "preferred" instead
10397 */
10398 if (strcmp(alias->alias, family->desc) == 0) {
10399 (*s->cpu_fprintf)(s->file,
10400 "PowerPC %-16s (alias for preferred %s CPU)\n",
10401 alias->alias, family->desc);
10402 } else {
10403 (*s->cpu_fprintf)(s->file, "PowerPC %-16s (alias for %s)\n",
10404 alias->alias, name);
10405 }
55d3d1a4 10406 }
de400129 10407 g_free(name);
2985b86b
AF
10408}
10409
10410void ppc_cpu_list(FILE *f, fprintf_function cpu_fprintf)
10411{
10412 CPUListState s = {
10413 .file = f,
10414 .cpu_fprintf = cpu_fprintf,
10415 };
10416 GSList *list;
10417
10418 list = object_class_get_list(TYPE_POWERPC_CPU, false);
10419 list = g_slist_sort(list, ppc_cpu_list_compare);
10420 g_slist_foreach(list, ppc_cpu_list_entry, &s);
10421 g_slist_free(list);
fd5ed418 10422
5ba4576b
AF
10423#ifdef CONFIG_KVM
10424 cpu_fprintf(f, "\n");
10425 cpu_fprintf(f, "PowerPC %-16s\n", "host");
10426#endif
2985b86b
AF
10427}
10428
10429static void ppc_cpu_defs_entry(gpointer data, gpointer user_data)
10430{
10431 ObjectClass *oc = data;
10432 CpuDefinitionInfoList **first = user_data;
de400129 10433 const char *typename;
2985b86b
AF
10434 CpuDefinitionInfoList *entry;
10435 CpuDefinitionInfo *info;
4d7fb187
AF
10436 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
10437
292363e1 10438 if (!ppc_cpu_is_valid(pcc)) {
4d7fb187
AF
10439 return;
10440 }
2985b86b 10441
de400129 10442 typename = object_class_get_name(oc);
2985b86b 10443 info = g_malloc0(sizeof(*info));
de400129 10444 info->name = g_strndup(typename,
c9137065 10445 strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX));
2985b86b
AF
10446
10447 entry = g_malloc0(sizeof(*entry));
10448 entry->value = info;
10449 entry->next = *first;
10450 *first = entry;
3fc6c082 10451}
1d0cb67d 10452
76b64a7a 10453CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
70b7660a
AL
10454{
10455 CpuDefinitionInfoList *cpu_list = NULL;
2985b86b 10456 GSList *list;
35e21d3f 10457 int i;
70b7660a 10458
2985b86b
AF
10459 list = object_class_get_list(TYPE_POWERPC_CPU, false);
10460 g_slist_foreach(list, ppc_cpu_defs_entry, &cpu_list);
10461 g_slist_free(list);
70b7660a 10462
e9a96075 10463 for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
9761ad75 10464 PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
35e21d3f
AF
10465 ObjectClass *oc;
10466 CpuDefinitionInfoList *entry;
10467 CpuDefinitionInfo *info;
10468
9761ad75 10469 oc = ppc_cpu_class_by_alias(alias);
35e21d3f
AF
10470 if (oc == NULL) {
10471 continue;
10472 }
10473
10474 info = g_malloc0(sizeof(*info));
10475 info->name = g_strdup(alias->alias);
8ed877b7 10476 info->q_typename = g_strdup(object_class_get_name(oc));
35e21d3f
AF
10477
10478 entry = g_malloc0(sizeof(*entry));
10479 entry->value = info;
10480 entry->next = cpu_list;
10481 cpu_list = entry;
10482 }
10483
2985b86b
AF
10484 return cpu_list;
10485}
70b7660a 10486
f45748f1
AF
10487static void ppc_cpu_set_pc(CPUState *cs, vaddr value)
10488{
10489 PowerPCCPU *cpu = POWERPC_CPU(cs);
10490
10491 cpu->env.nip = value;
10492}
10493
8c2e1b00
AF
10494static bool ppc_cpu_has_work(CPUState *cs)
10495{
10496 PowerPCCPU *cpu = POWERPC_CPU(cs);
10497 CPUPPCState *env = &cpu->env;
10498
10499 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
10500}
10501
1d0cb67d
AF
10502/* CPUClass::reset() */
10503static void ppc_cpu_reset(CPUState *s)
10504{
10505 PowerPCCPU *cpu = POWERPC_CPU(s);
10506 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
10507 CPUPPCState *env = &cpu->env;
a1389542 10508 target_ulong msr;
d197fdbc 10509 int i;
a1389542 10510
1d0cb67d
AF
10511 pcc->parent_reset(s);
10512
a1389542 10513 msr = (target_ulong)0;
932ccbdd 10514 msr |= (target_ulong)MSR_HVB;
a1389542
AF
10515 msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */
10516 msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */
10517 msr |= (target_ulong)1 << MSR_EP;
10518#if defined(DO_SINGLE_STEP) && 0
10519 /* Single step trace mode */
10520 msr |= (target_ulong)1 << MSR_SE;
10521 msr |= (target_ulong)1 << MSR_BE;
10522#endif
10523#if defined(CONFIG_USER_ONLY)
10524 msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
10525 msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
5b274ed7 10526 msr |= (target_ulong)1 << MSR_VSX; /* Allow VSX usage */
a1389542
AF
10527 msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
10528 msr |= (target_ulong)1 << MSR_PR;
cdcdda27
AK
10529#if defined(TARGET_PPC64)
10530 msr |= (target_ulong)1 << MSR_TM; /* Transactional memory */
10531#endif
e22c357b
DK
10532#if !defined(TARGET_WORDS_BIGENDIAN)
10533 msr |= (target_ulong)1 << MSR_LE; /* Little-endian user mode */
a74029f6
RH
10534 if (!((env->msr_mask >> MSR_LE) & 1)) {
10535 fprintf(stderr, "Selected CPU does not support little-endian.\n");
10536 exit(1);
10537 }
e22c357b 10538#endif
a1389542 10539#endif
2cf3eb6d 10540
a1389542
AF
10541#if defined(TARGET_PPC64)
10542 if (env->mmu_model & POWERPC_MMU_64) {
8b9f2118 10543 msr |= (1ULL << MSR_SF);
a1389542
AF
10544 }
10545#endif
2cf3eb6d
FC
10546
10547 hreg_store_msr(env, msr, 1);
10548
10549#if !defined(CONFIG_USER_ONLY)
10550 env->nip = env->hreset_vector | env->excp_prefix;
10551 if (env->mmu_model != POWERPC_MMU_REAL) {
10552 ppc_tlb_invalidate_all(env);
10553 }
10554#endif
10555
a1389542
AF
10556 hreg_compute_hflags(env);
10557 env->reserve_addr = (target_ulong)-1ULL;
10558 /* Be sure no exception or interrupt is pending */
10559 env->pending_interrupts = 0;
27103424 10560 s->exception_index = POWERPC_EXCP_NONE;
a1389542 10561 env->error_code = 0;
2b15811c
DG
10562
10563#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
1bfb37d1
DG
10564 env->vpa_addr = 0;
10565 env->slb_shadow_addr = 0;
10566 env->slb_shadow_size = 0;
10567 env->dtl_addr = 0;
2b15811c
DG
10568 env->dtl_size = 0;
10569#endif /* TARGET_PPC64 */
10570
d197fdbc
AK
10571 for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
10572 ppc_spr_t *spr = &env->spr_cb[i];
10573
10574 if (!spr->name) {
10575 continue;
10576 }
10577 env->spr[i] = spr->default_value;
10578 }
1d0cb67d
AF
10579}
10580
7826c2b2
GK
10581#ifndef CONFIG_USER_ONLY
10582static bool ppc_cpu_is_big_endian(CPUState *cs)
10583{
10584 PowerPCCPU *cpu = POWERPC_CPU(cs);
10585 CPUPPCState *env = &cpu->env;
10586
10587 cpu_synchronize_state(cs);
10588
10589 return !msr_le;
10590}
10591#endif
10592
6cca7ad6
AF
10593static void ppc_cpu_initfn(Object *obj)
10594{
c05efcb1 10595 CPUState *cs = CPU(obj);
6cca7ad6 10596 PowerPCCPU *cpu = POWERPC_CPU(obj);
2985b86b 10597 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
6cca7ad6
AF
10598 CPUPPCState *env = &cpu->env;
10599
c05efcb1 10600 cs->env_ptr = env;
2985b86b 10601
cfe34f44
AF
10602 env->msr_mask = pcc->msr_mask;
10603 env->mmu_model = pcc->mmu_model;
10604 env->excp_model = pcc->excp_model;
10605 env->bus_model = pcc->bus_model;
10606 env->insns_flags = pcc->insns_flags;
10607 env->insns_flags2 = pcc->insns_flags2;
10608 env->flags = pcc->flags;
10609 env->bfd_mach = pcc->bfd_mach;
10610 env->check_pow = pcc->check_pow;
2985b86b 10611
932ccbdd
BH
10612 /* Mark HV mode as supported if the CPU has an MSR_HV bit
10613 * in the msr_mask. The mask can later be cleared by PAPR
10614 * mode but the hv mode support will remain, thus enforcing
10615 * that we cannot use priv. instructions in guest in PAPR
10616 * mode. For 970 we currently simply don't set HV in msr_mask
10617 * thus simulating an "Apple mode" 970. If we ever want to
10618 * support 970 HV mode, we'll have to add a processor attribute
10619 * of some sort.
10620 */
10621#if !defined(CONFIG_USER_ONLY)
10622 env->has_hv_mode = !!(env->msr_mask & MSR_HVB);
10623#endif
10624
2985b86b 10625#if defined(TARGET_PPC64)
cfe34f44
AF
10626 if (pcc->sps) {
10627 env->sps = *pcc->sps;
2985b86b 10628 } else if (env->mmu_model & POWERPC_MMU_64) {
4322e8ce
BH
10629 /* Use default sets of page sizes. We don't support MPSS */
10630 static const struct ppc_segment_page_sizes defsps_4k = {
2985b86b
AF
10631 .sps = {
10632 { .page_shift = 12, /* 4K */
10633 .slb_enc = 0,
10634 .enc = { { .page_shift = 12, .pte_enc = 0 } }
10635 },
10636 { .page_shift = 24, /* 16M */
10637 .slb_enc = 0x100,
10638 .enc = { { .page_shift = 24, .pte_enc = 0 } }
10639 },
10640 },
10641 };
4322e8ce
BH
10642 static const struct ppc_segment_page_sizes defsps_64k = {
10643 .sps = {
10644 { .page_shift = 12, /* 4K */
10645 .slb_enc = 0,
10646 .enc = { { .page_shift = 12, .pte_enc = 0 } }
10647 },
10648 { .page_shift = 16, /* 64K */
10649 .slb_enc = 0x110,
10650 .enc = { { .page_shift = 16, .pte_enc = 1 } }
10651 },
10652 { .page_shift = 24, /* 16M */
10653 .slb_enc = 0x100,
10654 .enc = { { .page_shift = 24, .pte_enc = 0 } }
10655 },
10656 },
10657 };
10658 env->sps = (env->mmu_model & POWERPC_MMU_64K) ? defsps_64k : defsps_4k;
2985b86b
AF
10659 }
10660#endif /* defined(TARGET_PPC64) */
60925d26
AF
10661
10662 if (tcg_enabled()) {
10663 ppc_translate_init();
10664 }
6cca7ad6
AF
10665}
10666
03ae4133
AK
10667static bool ppc_pvr_match_default(PowerPCCPUClass *pcc, uint32_t pvr)
10668{
10669 return pcc->pvr == pvr;
10670}
10671
b3820e6c
DH
10672static gchar *ppc_gdb_arch_name(CPUState *cs)
10673{
10674#if defined(TARGET_PPC64)
10675 return g_strdup("powerpc:common64");
10676#else
10677 return g_strdup("powerpc:common");
10678#endif
10679}
10680
146c11f1
DG
10681static Property ppc_cpu_properties[] = {
10682 DEFINE_PROP_BOOL("pre-2.8-migration", PowerPCCPU, pre_2_8_migration, false),
d5fc133e
DG
10683 DEFINE_PROP_BOOL("pre-2.10-migration", PowerPCCPU, pre_2_10_migration,
10684 false),
146c11f1
DG
10685 DEFINE_PROP_END_OF_LIST(),
10686};
10687
1d0cb67d
AF
10688static void ppc_cpu_class_init(ObjectClass *oc, void *data)
10689{
10690 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
10691 CPUClass *cc = CPU_CLASS(oc);
4776ce60
AF
10692 DeviceClass *dc = DEVICE_CLASS(oc);
10693
10694 pcc->parent_realize = dc->realize;
7bbc124e 10695 pcc->parent_unrealize = dc->unrealize;
03ae4133 10696 pcc->pvr_match = ppc_pvr_match_default;
382d2db6 10697 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_always;
4776ce60 10698 dc->realize = ppc_cpu_realizefn;
b048960f 10699 dc->unrealize = ppc_cpu_unrealizefn;
146c11f1 10700 dc->props = ppc_cpu_properties;
1d0cb67d
AF
10701
10702 pcc->parent_reset = cc->reset;
10703 cc->reset = ppc_cpu_reset;
2b8c2754
AF
10704
10705 cc->class_by_name = ppc_cpu_class_by_name;
8c2e1b00 10706 cc->has_work = ppc_cpu_has_work;
97a8ea5a 10707 cc->do_interrupt = ppc_cpu_do_interrupt;
458dd766 10708 cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt;
878096ee
AF
10709 cc->dump_state = ppc_cpu_dump_state;
10710 cc->dump_statistics = ppc_cpu_dump_statistics;
f45748f1 10711 cc->set_pc = ppc_cpu_set_pc;
5b50e790
AF
10712 cc->gdb_read_register = ppc_cpu_gdb_read_register;
10713 cc->gdb_write_register = ppc_cpu_gdb_write_register;
7510454e
AF
10714#ifdef CONFIG_USER_ONLY
10715 cc->handle_mmu_fault = ppc_cpu_handle_mmu_fault;
10716#else
00b941e5 10717 cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
a90db158 10718 cc->vmsd = &vmstate_ppc_cpu;
00b941e5 10719#endif
356bb70e
MN
10720#if defined(CONFIG_SOFTMMU)
10721 cc->write_elf64_note = ppc64_cpu_write_elf64_note;
10722 cc->write_elf32_note = ppc32_cpu_write_elf32_note;
10723#endif
a0e372f0
AF
10724
10725 cc->gdb_num_core_regs = 71;
b3cad3ab
AG
10726
10727#ifdef USE_APPLE_GDB
10728 cc->gdb_read_register = ppc_cpu_gdb_read_register_apple;
10729 cc->gdb_write_register = ppc_cpu_gdb_write_register_apple;
10730 cc->gdb_num_core_regs = 71 + 32;
10731#endif
10732
b3820e6c 10733 cc->gdb_arch_name = ppc_gdb_arch_name;
5b24c641
AF
10734#if defined(TARGET_PPC64)
10735 cc->gdb_core_xml_file = "power64-core.xml";
10736#else
10737 cc->gdb_core_xml_file = "power-core.xml";
10738#endif
7826c2b2
GK
10739#ifndef CONFIG_USER_ONLY
10740 cc->virtio_is_big_endian = ppc_cpu_is_big_endian;
10741#endif
3bbf37f2
AF
10742
10743 dc->fw_name = "PowerPC,UNKNOWN";
1d0cb67d
AF
10744}
10745
10746static const TypeInfo ppc_cpu_type_info = {
10747 .name = TYPE_POWERPC_CPU,
10748 .parent = TYPE_CPU,
10749 .instance_size = sizeof(PowerPCCPU),
6cca7ad6 10750 .instance_init = ppc_cpu_initfn,
2985b86b 10751 .abstract = true,
1d0cb67d
AF
10752 .class_size = sizeof(PowerPCCPUClass),
10753 .class_init = ppc_cpu_class_init,
10754};
10755
1d1be34d
DG
10756static const TypeInfo ppc_vhyp_type_info = {
10757 .name = TYPE_PPC_VIRTUAL_HYPERVISOR,
10758 .parent = TYPE_INTERFACE,
10759 .class_size = sizeof(PPCVirtualHypervisorClass),
10760};
10761
1d0cb67d
AF
10762static void ppc_cpu_register_types(void)
10763{
10764 type_register_static(&ppc_cpu_type_info);
1d1be34d 10765 type_register_static(&ppc_vhyp_type_info);
1d0cb67d
AF
10766}
10767
10768type_init(ppc_cpu_register_types)