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