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