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