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