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