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