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