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