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