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