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