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