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