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