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