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