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