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