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