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