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