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