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