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