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