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