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