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