]> git.proxmox.com Git - mirror_qemu.git/blame - target-ppc/translate_init.c
Declare and Enable VSX
[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;
3064 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3065 env->excp_vectors[POWERPC_EXCP_MAINT] = 0x00001600;
3066 env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001700;
3067 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001800;
9d52e907
DG
3068 /* Hardware reset vector */
3069 env->hreset_vector = 0x0000000000000100ULL;
3070#endif
3071}
e1833e1f
JM
3072#endif
3073
2f462816
JM
3074/*****************************************************************************/
3075/* Power management enable checks */
3076static int check_pow_none (CPUPPCState *env)
3077{
3078 return 0;
3079}
3080
3081static int check_pow_nocheck (CPUPPCState *env)
3082{
3083 return 1;
3084}
3085
3086static int check_pow_hid0 (CPUPPCState *env)
3087{
3088 if (env->spr[SPR_HID0] & 0x00E00000)
3089 return 1;
3090
3091 return 0;
3092}
3093
4e777442
JM
3094static int check_pow_hid0_74xx (CPUPPCState *env)
3095{
3096 if (env->spr[SPR_HID0] & 0x00600000)
3097 return 1;
3098
3099 return 0;
3100}
3101
a750fc0b
JM
3102/*****************************************************************************/
3103/* PowerPC implementations definitions */
76a66253 3104
7856e3a4
AF
3105#define POWERPC_FAMILY(_name) \
3106 static void \
3107 glue(glue(ppc_, _name), _cpu_family_class_init)(ObjectClass *, void *); \
3108 \
3109 static const TypeInfo \
3110 glue(glue(ppc_, _name), _cpu_family_type_info) = { \
3111 .name = stringify(_name) "-family-" TYPE_POWERPC_CPU, \
3112 .parent = TYPE_POWERPC_CPU, \
3113 .abstract = true, \
3114 .class_init = glue(glue(ppc_, _name), _cpu_family_class_init), \
3115 }; \
3116 \
3117 static void glue(glue(ppc_, _name), _cpu_family_register_types)(void) \
3118 { \
3119 type_register_static( \
3120 &glue(glue(ppc_, _name), _cpu_family_type_info)); \
3121 } \
3122 \
3123 type_init(glue(glue(ppc_, _name), _cpu_family_register_types)) \
3124 \
3125 static void glue(glue(ppc_, _name), _cpu_family_class_init)
3126
a750fc0b
JM
3127static void init_proc_401 (CPUPPCState *env)
3128{
3129 gen_spr_40x(env);
3130 gen_spr_401_403(env);
3131 gen_spr_401(env);
e1833e1f 3132 init_excp_4xx_real(env);
d63001d1
JM
3133 env->dcache_line_size = 32;
3134 env->icache_line_size = 32;
4e290a0b
JM
3135 /* Allocate hardware IRQ controller */
3136 ppc40x_irq_init(env);
ddd1055b
FC
3137
3138 SET_FIT_PERIOD(12, 16, 20, 24);
3139 SET_WDT_PERIOD(16, 20, 24, 28);
a750fc0b 3140}
76a66253 3141
7856e3a4
AF
3142POWERPC_FAMILY(401)(ObjectClass *oc, void *data)
3143{
ca5dff0a 3144 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3145 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3146
ca5dff0a 3147 dc->desc = "PowerPC 401";
7856e3a4
AF
3148 pcc->init_proc = init_proc_401;
3149 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
3150 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3151 PPC_WRTEE | PPC_DCR |
3152 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3153 PPC_CACHE_DCBZ |
3154 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3155 PPC_4xx_COMMON | PPC_40x_EXCP;
ba9fd9f1
AF
3156 pcc->msr_mask = 0x00000000000FD201ULL;
3157 pcc->mmu_model = POWERPC_MMU_REAL;
3158 pcc->excp_model = POWERPC_EXCP_40x;
3159 pcc->bus_model = PPC_FLAGS_INPUT_401;
3160 pcc->bfd_mach = bfd_mach_ppc_403;
3161 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3162 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
3163}
3164
a750fc0b
JM
3165static void init_proc_401x2 (CPUPPCState *env)
3166{
3167 gen_spr_40x(env);
3168 gen_spr_401_403(env);
3169 gen_spr_401x2(env);
3170 gen_spr_compress(env);
a750fc0b 3171 /* Memory management */
f2e63a42 3172#if !defined(CONFIG_USER_ONLY)
a750fc0b
JM
3173 env->nb_tlb = 64;
3174 env->nb_ways = 1;
3175 env->id_tlbs = 0;
1c53accc 3176 env->tlb_type = TLB_EMB;
f2e63a42 3177#endif
e1833e1f 3178 init_excp_4xx_softmmu(env);
d63001d1
JM
3179 env->dcache_line_size = 32;
3180 env->icache_line_size = 32;
4e290a0b
JM
3181 /* Allocate hardware IRQ controller */
3182 ppc40x_irq_init(env);
ddd1055b
FC
3183
3184 SET_FIT_PERIOD(12, 16, 20, 24);
3185 SET_WDT_PERIOD(16, 20, 24, 28);
76a66253
JM
3186}
3187
7856e3a4
AF
3188POWERPC_FAMILY(401x2)(ObjectClass *oc, void *data)
3189{
ca5dff0a 3190 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3191 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3192
ca5dff0a 3193 dc->desc = "PowerPC 401x2";
7856e3a4
AF
3194 pcc->init_proc = init_proc_401x2;
3195 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
3196 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
3197 PPC_DCR | PPC_WRTEE |
3198 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3199 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3200 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3201 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3202 PPC_4xx_COMMON | PPC_40x_EXCP;
ba9fd9f1
AF
3203 pcc->msr_mask = 0x00000000001FD231ULL;
3204 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3205 pcc->excp_model = POWERPC_EXCP_40x;
3206 pcc->bus_model = PPC_FLAGS_INPUT_401;
3207 pcc->bfd_mach = bfd_mach_ppc_403;
3208 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3209 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
3210}
3211
e1833e1f 3212static void init_proc_401x3 (CPUPPCState *env)
76a66253 3213{
4e290a0b
JM
3214 gen_spr_40x(env);
3215 gen_spr_401_403(env);
3216 gen_spr_401(env);
3217 gen_spr_401x2(env);
3218 gen_spr_compress(env);
e1833e1f 3219 init_excp_4xx_softmmu(env);
d63001d1
JM
3220 env->dcache_line_size = 32;
3221 env->icache_line_size = 32;
4e290a0b
JM
3222 /* Allocate hardware IRQ controller */
3223 ppc40x_irq_init(env);
ddd1055b
FC
3224
3225 SET_FIT_PERIOD(12, 16, 20, 24);
3226 SET_WDT_PERIOD(16, 20, 24, 28);
3fc6c082 3227}
a750fc0b 3228
7856e3a4
AF
3229POWERPC_FAMILY(401x3)(ObjectClass *oc, void *data)
3230{
ca5dff0a 3231 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3232 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3233
ca5dff0a 3234 dc->desc = "PowerPC 401x3";
7856e3a4
AF
3235 pcc->init_proc = init_proc_401x3;
3236 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
3237 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
3238 PPC_DCR | PPC_WRTEE |
3239 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3240 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3241 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3242 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3243 PPC_4xx_COMMON | PPC_40x_EXCP;
ba9fd9f1
AF
3244 pcc->msr_mask = 0x00000000001FD631ULL;
3245 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3246 pcc->excp_model = POWERPC_EXCP_40x;
3247 pcc->bus_model = PPC_FLAGS_INPUT_401;
3248 pcc->bfd_mach = bfd_mach_ppc_403;
3249 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3250 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
3251}
3252
a750fc0b 3253static void init_proc_IOP480 (CPUPPCState *env)
3fc6c082 3254{
a750fc0b
JM
3255 gen_spr_40x(env);
3256 gen_spr_401_403(env);
3257 gen_spr_401x2(env);
3258 gen_spr_compress(env);
a750fc0b 3259 /* Memory management */
f2e63a42 3260#if !defined(CONFIG_USER_ONLY)
a750fc0b
JM
3261 env->nb_tlb = 64;
3262 env->nb_ways = 1;
3263 env->id_tlbs = 0;
1c53accc 3264 env->tlb_type = TLB_EMB;
f2e63a42 3265#endif
e1833e1f 3266 init_excp_4xx_softmmu(env);
d63001d1
JM
3267 env->dcache_line_size = 32;
3268 env->icache_line_size = 32;
4e290a0b
JM
3269 /* Allocate hardware IRQ controller */
3270 ppc40x_irq_init(env);
ddd1055b
FC
3271
3272 SET_FIT_PERIOD(8, 12, 16, 20);
3273 SET_WDT_PERIOD(16, 20, 24, 28);
3fc6c082
FB
3274}
3275
7856e3a4
AF
3276POWERPC_FAMILY(IOP480)(ObjectClass *oc, void *data)
3277{
ca5dff0a 3278 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3279 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3280
ca5dff0a 3281 dc->desc = "IOP480";
7856e3a4
AF
3282 pcc->init_proc = init_proc_IOP480;
3283 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
3284 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3285 PPC_DCR | PPC_WRTEE |
3286 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3287 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3288 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3289 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3290 PPC_4xx_COMMON | PPC_40x_EXCP;
ba9fd9f1
AF
3291 pcc->msr_mask = 0x00000000001FD231ULL;
3292 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3293 pcc->excp_model = POWERPC_EXCP_40x;
3294 pcc->bus_model = PPC_FLAGS_INPUT_401;
3295 pcc->bfd_mach = bfd_mach_ppc_403;
3296 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3297 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
3298}
3299
a750fc0b 3300static void init_proc_403 (CPUPPCState *env)
3fc6c082 3301{
a750fc0b
JM
3302 gen_spr_40x(env);
3303 gen_spr_401_403(env);
3304 gen_spr_403(env);
3305 gen_spr_403_real(env);
e1833e1f 3306 init_excp_4xx_real(env);
d63001d1
JM
3307 env->dcache_line_size = 32;
3308 env->icache_line_size = 32;
4e290a0b
JM
3309 /* Allocate hardware IRQ controller */
3310 ppc40x_irq_init(env);
ddd1055b
FC
3311
3312 SET_FIT_PERIOD(8, 12, 16, 20);
3313 SET_WDT_PERIOD(16, 20, 24, 28);
3fc6c082
FB
3314}
3315
7856e3a4
AF
3316POWERPC_FAMILY(403)(ObjectClass *oc, void *data)
3317{
ca5dff0a 3318 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3319 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3320
ca5dff0a 3321 dc->desc = "PowerPC 403";
7856e3a4
AF
3322 pcc->init_proc = init_proc_403;
3323 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
3324 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3325 PPC_DCR | PPC_WRTEE |
3326 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3327 PPC_CACHE_DCBZ |
3328 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3329 PPC_4xx_COMMON | PPC_40x_EXCP;
ba9fd9f1
AF
3330 pcc->msr_mask = 0x000000000007D00DULL;
3331 pcc->mmu_model = POWERPC_MMU_REAL;
3332 pcc->excp_model = POWERPC_EXCP_40x;
3333 pcc->bus_model = PPC_FLAGS_INPUT_401;
3334 pcc->bfd_mach = bfd_mach_ppc_403;
3335 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_PX |
3336 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
3337}
3338
a750fc0b 3339static void init_proc_403GCX (CPUPPCState *env)
3fc6c082 3340{
a750fc0b
JM
3341 gen_spr_40x(env);
3342 gen_spr_401_403(env);
3343 gen_spr_403(env);
3344 gen_spr_403_real(env);
3345 gen_spr_403_mmu(env);
3346 /* Bus access control */
5cbdb3a3 3347 /* not emulated, as QEMU never does speculative access */
a750fc0b
JM
3348 spr_register(env, SPR_40x_SGR, "SGR",
3349 SPR_NOACCESS, SPR_NOACCESS,
3350 &spr_read_generic, &spr_write_generic,
3351 0xFFFFFFFF);
5cbdb3a3 3352 /* not emulated, as QEMU do not emulate caches */
a750fc0b
JM
3353 spr_register(env, SPR_40x_DCWR, "DCWR",
3354 SPR_NOACCESS, SPR_NOACCESS,
3355 &spr_read_generic, &spr_write_generic,
3356 0x00000000);
3357 /* Memory management */
f2e63a42 3358#if !defined(CONFIG_USER_ONLY)
a750fc0b
JM
3359 env->nb_tlb = 64;
3360 env->nb_ways = 1;
3361 env->id_tlbs = 0;
1c53accc 3362 env->tlb_type = TLB_EMB;
f2e63a42 3363#endif
80d11f44
JM
3364 init_excp_4xx_softmmu(env);
3365 env->dcache_line_size = 32;
3366 env->icache_line_size = 32;
3367 /* Allocate hardware IRQ controller */
3368 ppc40x_irq_init(env);
ddd1055b
FC
3369
3370 SET_FIT_PERIOD(8, 12, 16, 20);
3371 SET_WDT_PERIOD(16, 20, 24, 28);
80d11f44
JM
3372}
3373
7856e3a4
AF
3374POWERPC_FAMILY(403GCX)(ObjectClass *oc, void *data)
3375{
ca5dff0a 3376 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3377 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3378
ca5dff0a 3379 dc->desc = "PowerPC 403 GCX";
7856e3a4
AF
3380 pcc->init_proc = init_proc_403GCX;
3381 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
3382 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3383 PPC_DCR | PPC_WRTEE |
3384 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3385 PPC_CACHE_DCBZ |
3386 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3387 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3388 PPC_4xx_COMMON | PPC_40x_EXCP;
ba9fd9f1
AF
3389 pcc->msr_mask = 0x000000000007D00DULL;
3390 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3391 pcc->excp_model = POWERPC_EXCP_40x;
3392 pcc->bus_model = PPC_FLAGS_INPUT_401;
3393 pcc->bfd_mach = bfd_mach_ppc_403;
3394 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_PX |
3395 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
3396}
3397
80d11f44
JM
3398static void init_proc_405 (CPUPPCState *env)
3399{
3400 /* Time base */
3401 gen_tbl(env);
3402 gen_spr_40x(env);
3403 gen_spr_405(env);
3404 /* Bus access control */
5cbdb3a3 3405 /* not emulated, as QEMU never does speculative access */
80d11f44
JM
3406 spr_register(env, SPR_40x_SGR, "SGR",
3407 SPR_NOACCESS, SPR_NOACCESS,
3408 &spr_read_generic, &spr_write_generic,
3409 0xFFFFFFFF);
5cbdb3a3 3410 /* not emulated, as QEMU do not emulate caches */
80d11f44
JM
3411 spr_register(env, SPR_40x_DCWR, "DCWR",
3412 SPR_NOACCESS, SPR_NOACCESS,
3413 &spr_read_generic, &spr_write_generic,
3414 0x00000000);
3415 /* Memory management */
3416#if !defined(CONFIG_USER_ONLY)
3417 env->nb_tlb = 64;
3418 env->nb_ways = 1;
3419 env->id_tlbs = 0;
1c53accc 3420 env->tlb_type = TLB_EMB;
80d11f44
JM
3421#endif
3422 init_excp_4xx_softmmu(env);
3423 env->dcache_line_size = 32;
3424 env->icache_line_size = 32;
3425 /* Allocate hardware IRQ controller */
3426 ppc40x_irq_init(env);
ddd1055b
FC
3427
3428 SET_FIT_PERIOD(8, 12, 16, 20);
3429 SET_WDT_PERIOD(16, 20, 24, 28);
80d11f44
JM
3430}
3431
7856e3a4
AF
3432POWERPC_FAMILY(405)(ObjectClass *oc, void *data)
3433{
ca5dff0a 3434 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3435 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3436
ca5dff0a 3437 dc->desc = "PowerPC 405";
7856e3a4
AF
3438 pcc->init_proc = init_proc_405;
3439 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
3440 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
3441 PPC_DCR | PPC_WRTEE |
3442 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3443 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3444 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3445 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3446 PPC_4xx_COMMON | PPC_405_MAC | PPC_40x_EXCP;
ba9fd9f1
AF
3447 pcc->msr_mask = 0x000000000006E630ULL;
3448 pcc->mmu_model = POWERPC_MMU_SOFT_4xx;
3449 pcc->excp_model = POWERPC_EXCP_40x;
3450 pcc->bus_model = PPC_FLAGS_INPUT_405;
3451 pcc->bfd_mach = bfd_mach_ppc_403;
3452 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
3453 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
3454}
3455
80d11f44
JM
3456static void init_proc_440EP (CPUPPCState *env)
3457{
3458 /* Time base */
3459 gen_tbl(env);
3460 gen_spr_BookE(env, 0x000000000000FFFFULL);
3461 gen_spr_440(env);
3462 gen_spr_usprgh(env);
3463 /* Processor identification */
3464 spr_register(env, SPR_BOOKE_PIR, "PIR",
3465 SPR_NOACCESS, SPR_NOACCESS,
3466 &spr_read_generic, &spr_write_pir,
3467 0x00000000);
3468 /* XXX : not implemented */
3469 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
3470 SPR_NOACCESS, SPR_NOACCESS,
3471 &spr_read_generic, &spr_write_generic,
3472 0x00000000);
3473 /* XXX : not implemented */
3474 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
3475 SPR_NOACCESS, SPR_NOACCESS,
3476 &spr_read_generic, &spr_write_generic,
3477 0x00000000);
3478 /* XXX : not implemented */
3479 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
3480 SPR_NOACCESS, SPR_NOACCESS,
3481 &spr_read_generic, &spr_write_generic,
3482 0x00000000);
3483 /* XXX : not implemented */
3484 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
3485 SPR_NOACCESS, SPR_NOACCESS,
3486 &spr_read_generic, &spr_write_generic,
3487 0x00000000);
3488 /* XXX : not implemented */
3489 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
3490 SPR_NOACCESS, SPR_NOACCESS,
3491 &spr_read_generic, &spr_write_generic,
3492 0x00000000);
3493 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
3494 SPR_NOACCESS, SPR_NOACCESS,
3495 &spr_read_generic, &spr_write_generic,
3496 0x00000000);
3497 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
3498 SPR_NOACCESS, SPR_NOACCESS,
3499 &spr_read_generic, &spr_write_generic,
3500 0x00000000);
3501 /* XXX : not implemented */
3502 spr_register(env, SPR_440_CCR1, "CCR1",
3503 SPR_NOACCESS, SPR_NOACCESS,
3504 &spr_read_generic, &spr_write_generic,
3505 0x00000000);
3506 /* Memory management */
3507#if !defined(CONFIG_USER_ONLY)
3508 env->nb_tlb = 64;
3509 env->nb_ways = 1;
3510 env->id_tlbs = 0;
1c53accc 3511 env->tlb_type = TLB_EMB;
80d11f44
JM
3512#endif
3513 init_excp_BookE(env);
3514 env->dcache_line_size = 32;
3515 env->icache_line_size = 32;
c0a7e81a 3516 ppc40x_irq_init(env);
ddd1055b
FC
3517
3518 SET_FIT_PERIOD(12, 16, 20, 24);
3519 SET_WDT_PERIOD(20, 24, 28, 32);
80d11f44
JM
3520}
3521
7856e3a4
AF
3522POWERPC_FAMILY(440EP)(ObjectClass *oc, void *data)
3523{
ca5dff0a 3524 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3525 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3526
ca5dff0a 3527 dc->desc = "PowerPC 440 EP";
7856e3a4
AF
3528 pcc->init_proc = init_proc_440EP;
3529 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
3530 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3531 PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL |
3532 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
3533 PPC_FLOAT_STFIWX |
3534 PPC_DCR | PPC_WRTEE | PPC_RFMCI |
3535 PPC_CACHE | PPC_CACHE_ICBI |
3536 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3537 PPC_MEM_TLBSYNC | PPC_MFTB |
3538 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
3539 PPC_440_SPEC;
ba9fd9f1
AF
3540 pcc->msr_mask = 0x000000000006FF30ULL;
3541 pcc->mmu_model = POWERPC_MMU_BOOKE;
3542 pcc->excp_model = POWERPC_EXCP_BOOKE;
3543 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
3544 pcc->bfd_mach = bfd_mach_ppc_403;
3545 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
3546 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
3547}
3548
80d11f44
JM
3549static void init_proc_440GP (CPUPPCState *env)
3550{
3551 /* Time base */
3552 gen_tbl(env);
3553 gen_spr_BookE(env, 0x000000000000FFFFULL);
3554 gen_spr_440(env);
3555 gen_spr_usprgh(env);
3556 /* Processor identification */
3557 spr_register(env, SPR_BOOKE_PIR, "PIR",
3558 SPR_NOACCESS, SPR_NOACCESS,
3559 &spr_read_generic, &spr_write_pir,
3560 0x00000000);
3561 /* XXX : not implemented */
3562 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
3563 SPR_NOACCESS, SPR_NOACCESS,
3564 &spr_read_generic, &spr_write_generic,
3565 0x00000000);
3566 /* XXX : not implemented */
3567 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
3568 SPR_NOACCESS, SPR_NOACCESS,
3569 &spr_read_generic, &spr_write_generic,
3570 0x00000000);
3571 /* XXX : not implemented */
3572 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
3573 SPR_NOACCESS, SPR_NOACCESS,
3574 &spr_read_generic, &spr_write_generic,
3575 0x00000000);
3576 /* XXX : not implemented */
3577 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
3578 SPR_NOACCESS, SPR_NOACCESS,
3579 &spr_read_generic, &spr_write_generic,
3580 0x00000000);
3581 /* Memory management */
3582#if !defined(CONFIG_USER_ONLY)
3583 env->nb_tlb = 64;
3584 env->nb_ways = 1;
3585 env->id_tlbs = 0;
1c53accc 3586 env->tlb_type = TLB_EMB;
80d11f44
JM
3587#endif
3588 init_excp_BookE(env);
3589 env->dcache_line_size = 32;
3590 env->icache_line_size = 32;
3591 /* XXX: TODO: allocate internal IRQ controller */
ddd1055b
FC
3592
3593 SET_FIT_PERIOD(12, 16, 20, 24);
3594 SET_WDT_PERIOD(20, 24, 28, 32);
80d11f44
JM
3595}
3596
7856e3a4
AF
3597POWERPC_FAMILY(440GP)(ObjectClass *oc, void *data)
3598{
ca5dff0a 3599 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3600 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3601
ca5dff0a 3602 dc->desc = "PowerPC 440 GP";
7856e3a4
AF
3603 pcc->init_proc = init_proc_440GP;
3604 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
3605 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3606 PPC_DCR | PPC_DCRX | PPC_WRTEE | PPC_MFAPIDI |
3607 PPC_CACHE | PPC_CACHE_ICBI |
3608 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3609 PPC_MEM_TLBSYNC | PPC_TLBIVA | PPC_MFTB |
3610 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
3611 PPC_440_SPEC;
ba9fd9f1
AF
3612 pcc->msr_mask = 0x000000000006FF30ULL;
3613 pcc->mmu_model = POWERPC_MMU_BOOKE;
3614 pcc->excp_model = POWERPC_EXCP_BOOKE;
3615 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
3616 pcc->bfd_mach = bfd_mach_ppc_403;
3617 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
3618 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
3619}
3620
80d11f44
JM
3621static void init_proc_440x4 (CPUPPCState *env)
3622{
3623 /* Time base */
3624 gen_tbl(env);
3625 gen_spr_BookE(env, 0x000000000000FFFFULL);
3626 gen_spr_440(env);
3627 gen_spr_usprgh(env);
3628 /* Processor identification */
3629 spr_register(env, SPR_BOOKE_PIR, "PIR",
3630 SPR_NOACCESS, SPR_NOACCESS,
3631 &spr_read_generic, &spr_write_pir,
3632 0x00000000);
3633 /* XXX : not implemented */
3634 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
3635 SPR_NOACCESS, SPR_NOACCESS,
3636 &spr_read_generic, &spr_write_generic,
3637 0x00000000);
3638 /* XXX : not implemented */
3639 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
3640 SPR_NOACCESS, SPR_NOACCESS,
3641 &spr_read_generic, &spr_write_generic,
3642 0x00000000);
3643 /* XXX : not implemented */
3644 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
3645 SPR_NOACCESS, SPR_NOACCESS,
3646 &spr_read_generic, &spr_write_generic,
3647 0x00000000);
3648 /* XXX : not implemented */
3649 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
3650 SPR_NOACCESS, SPR_NOACCESS,
3651 &spr_read_generic, &spr_write_generic,
3652 0x00000000);
3653 /* Memory management */
3654#if !defined(CONFIG_USER_ONLY)
3655 env->nb_tlb = 64;
3656 env->nb_ways = 1;
3657 env->id_tlbs = 0;
1c53accc 3658 env->tlb_type = TLB_EMB;
80d11f44
JM
3659#endif
3660 init_excp_BookE(env);
d63001d1
JM
3661 env->dcache_line_size = 32;
3662 env->icache_line_size = 32;
80d11f44 3663 /* XXX: TODO: allocate internal IRQ controller */
ddd1055b
FC
3664
3665 SET_FIT_PERIOD(12, 16, 20, 24);
3666 SET_WDT_PERIOD(20, 24, 28, 32);
3fc6c082
FB
3667}
3668
7856e3a4
AF
3669POWERPC_FAMILY(440x4)(ObjectClass *oc, void *data)
3670{
ca5dff0a 3671 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3672 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3673
ca5dff0a 3674 dc->desc = "PowerPC 440x4";
7856e3a4
AF
3675 pcc->init_proc = init_proc_440x4;
3676 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
3677 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3678 PPC_DCR | PPC_WRTEE |
3679 PPC_CACHE | PPC_CACHE_ICBI |
3680 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3681 PPC_MEM_TLBSYNC | PPC_MFTB |
3682 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
3683 PPC_440_SPEC;
ba9fd9f1
AF
3684 pcc->msr_mask = 0x000000000006FF30ULL;
3685 pcc->mmu_model = POWERPC_MMU_BOOKE;
3686 pcc->excp_model = POWERPC_EXCP_BOOKE;
3687 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
3688 pcc->bfd_mach = bfd_mach_ppc_403;
3689 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
3690 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
3691}
3692
80d11f44 3693static void init_proc_440x5 (CPUPPCState *env)
3fc6c082 3694{
a750fc0b
JM
3695 /* Time base */
3696 gen_tbl(env);
80d11f44
JM
3697 gen_spr_BookE(env, 0x000000000000FFFFULL);
3698 gen_spr_440(env);
3699 gen_spr_usprgh(env);
3700 /* Processor identification */
3701 spr_register(env, SPR_BOOKE_PIR, "PIR",
3702 SPR_NOACCESS, SPR_NOACCESS,
3703 &spr_read_generic, &spr_write_pir,
3704 0x00000000);
3705 /* XXX : not implemented */
3706 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
a750fc0b
JM
3707 SPR_NOACCESS, SPR_NOACCESS,
3708 &spr_read_generic, &spr_write_generic,
80d11f44
JM
3709 0x00000000);
3710 /* XXX : not implemented */
3711 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
3712 SPR_NOACCESS, SPR_NOACCESS,
3713 &spr_read_generic, &spr_write_generic,
3714 0x00000000);
3715 /* XXX : not implemented */
3716 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
3717 SPR_NOACCESS, SPR_NOACCESS,
3718 &spr_read_generic, &spr_write_generic,
3719 0x00000000);
3720 /* XXX : not implemented */
3721 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
3722 SPR_NOACCESS, SPR_NOACCESS,
3723 &spr_read_generic, &spr_write_generic,
3724 0x00000000);
3725 /* XXX : not implemented */
3726 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
3727 SPR_NOACCESS, SPR_NOACCESS,
3728 &spr_read_generic, &spr_write_generic,
3729 0x00000000);
3730 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
3731 SPR_NOACCESS, SPR_NOACCESS,
3732 &spr_read_generic, &spr_write_generic,
3733 0x00000000);
3734 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
3735 SPR_NOACCESS, SPR_NOACCESS,
3736 &spr_read_generic, &spr_write_generic,
3737 0x00000000);
3738 /* XXX : not implemented */
3739 spr_register(env, SPR_440_CCR1, "CCR1",
a750fc0b
JM
3740 SPR_NOACCESS, SPR_NOACCESS,
3741 &spr_read_generic, &spr_write_generic,
3742 0x00000000);
3743 /* Memory management */
f2e63a42 3744#if !defined(CONFIG_USER_ONLY)
a750fc0b
JM
3745 env->nb_tlb = 64;
3746 env->nb_ways = 1;
3747 env->id_tlbs = 0;
1c53accc 3748 env->tlb_type = TLB_EMB;
f2e63a42 3749#endif
80d11f44 3750 init_excp_BookE(env);
d63001d1
JM
3751 env->dcache_line_size = 32;
3752 env->icache_line_size = 32;
95070372 3753 ppc40x_irq_init(env);
ddd1055b
FC
3754
3755 SET_FIT_PERIOD(12, 16, 20, 24);
3756 SET_WDT_PERIOD(20, 24, 28, 32);
3fc6c082
FB
3757}
3758
7856e3a4
AF
3759POWERPC_FAMILY(440x5)(ObjectClass *oc, void *data)
3760{
ca5dff0a 3761 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3762 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3763
ca5dff0a 3764 dc->desc = "PowerPC 440x5";
7856e3a4
AF
3765 pcc->init_proc = init_proc_440x5;
3766 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
3767 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3768 PPC_DCR | PPC_WRTEE | PPC_RFMCI |
3769 PPC_CACHE | PPC_CACHE_ICBI |
3770 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3771 PPC_MEM_TLBSYNC | PPC_MFTB |
3772 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
3773 PPC_440_SPEC;
ba9fd9f1
AF
3774 pcc->msr_mask = 0x000000000006FF30ULL;
3775 pcc->mmu_model = POWERPC_MMU_BOOKE;
3776 pcc->excp_model = POWERPC_EXCP_BOOKE;
3777 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
3778 pcc->bfd_mach = bfd_mach_ppc_403;
3779 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
3780 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
3781}
3782
80d11f44 3783static void init_proc_460 (CPUPPCState *env)
3fc6c082 3784{
a750fc0b
JM
3785 /* Time base */
3786 gen_tbl(env);
80d11f44 3787 gen_spr_BookE(env, 0x000000000000FFFFULL);
a750fc0b 3788 gen_spr_440(env);
80d11f44
JM
3789 gen_spr_usprgh(env);
3790 /* Processor identification */
3791 spr_register(env, SPR_BOOKE_PIR, "PIR",
3792 SPR_NOACCESS, SPR_NOACCESS,
3793 &spr_read_generic, &spr_write_pir,
3794 0x00000000);
3795 /* XXX : not implemented */
3796 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
3797 SPR_NOACCESS, SPR_NOACCESS,
3798 &spr_read_generic, &spr_write_generic,
3799 0x00000000);
3800 /* XXX : not implemented */
3801 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
3802 SPR_NOACCESS, SPR_NOACCESS,
3803 &spr_read_generic, &spr_write_generic,
3804 0x00000000);
3805 /* XXX : not implemented */
3806 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
3807 SPR_NOACCESS, SPR_NOACCESS,
3808 &spr_read_generic, &spr_write_generic,
3809 0x00000000);
3810 /* XXX : not implemented */
3811 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
3812 SPR_NOACCESS, SPR_NOACCESS,
3813 &spr_read_generic, &spr_write_generic,
3814 0x00000000);
578bb252 3815 /* XXX : not implemented */
a750fc0b
JM
3816 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
3817 SPR_NOACCESS, SPR_NOACCESS,
3818 &spr_read_generic, &spr_write_generic,
3819 0x00000000);
3820 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
3821 SPR_NOACCESS, SPR_NOACCESS,
3822 &spr_read_generic, &spr_write_generic,
3823 0x00000000);
3824 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
3825 SPR_NOACCESS, SPR_NOACCESS,
3826 &spr_read_generic, &spr_write_generic,
3827 0x00000000);
578bb252 3828 /* XXX : not implemented */
a750fc0b
JM
3829 spr_register(env, SPR_440_CCR1, "CCR1",
3830 SPR_NOACCESS, SPR_NOACCESS,
3831 &spr_read_generic, &spr_write_generic,
3832 0x00000000);
80d11f44
JM
3833 /* XXX : not implemented */
3834 spr_register(env, SPR_DCRIPR, "SPR_DCRIPR",
3835 &spr_read_generic, &spr_write_generic,
3836 &spr_read_generic, &spr_write_generic,
3837 0x00000000);
a750fc0b 3838 /* Memory management */
f2e63a42 3839#if !defined(CONFIG_USER_ONLY)
a750fc0b
JM
3840 env->nb_tlb = 64;
3841 env->nb_ways = 1;
3842 env->id_tlbs = 0;
1c53accc 3843 env->tlb_type = TLB_EMB;
f2e63a42 3844#endif
e1833e1f 3845 init_excp_BookE(env);
d63001d1
JM
3846 env->dcache_line_size = 32;
3847 env->icache_line_size = 32;
a750fc0b 3848 /* XXX: TODO: allocate internal IRQ controller */
ddd1055b
FC
3849
3850 SET_FIT_PERIOD(12, 16, 20, 24);
3851 SET_WDT_PERIOD(20, 24, 28, 32);
3fc6c082
FB
3852}
3853
7856e3a4
AF
3854POWERPC_FAMILY(460)(ObjectClass *oc, void *data)
3855{
ca5dff0a 3856 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3857 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3858
ca5dff0a 3859 dc->desc = "PowerPC 460 (guessed)";
7856e3a4
AF
3860 pcc->init_proc = init_proc_460;
3861 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
3862 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3863 PPC_DCR | PPC_DCRX | PPC_DCRUX |
3864 PPC_WRTEE | PPC_MFAPIDI | PPC_MFTB |
3865 PPC_CACHE | PPC_CACHE_ICBI |
3866 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3867 PPC_MEM_TLBSYNC | PPC_TLBIVA |
3868 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
3869 PPC_440_SPEC;
ba9fd9f1
AF
3870 pcc->msr_mask = 0x000000000006FF30ULL;
3871 pcc->mmu_model = POWERPC_MMU_BOOKE;
3872 pcc->excp_model = POWERPC_EXCP_BOOKE;
3873 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
3874 pcc->bfd_mach = bfd_mach_ppc_403;
3875 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
3876 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
3877}
3878
80d11f44 3879static void init_proc_460F (CPUPPCState *env)
3fc6c082 3880{
a750fc0b
JM
3881 /* Time base */
3882 gen_tbl(env);
80d11f44 3883 gen_spr_BookE(env, 0x000000000000FFFFULL);
a750fc0b 3884 gen_spr_440(env);
80d11f44
JM
3885 gen_spr_usprgh(env);
3886 /* Processor identification */
3887 spr_register(env, SPR_BOOKE_PIR, "PIR",
3888 SPR_NOACCESS, SPR_NOACCESS,
3889 &spr_read_generic, &spr_write_pir,
3890 0x00000000);
3891 /* XXX : not implemented */
3892 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
3893 SPR_NOACCESS, SPR_NOACCESS,
3894 &spr_read_generic, &spr_write_generic,
3895 0x00000000);
3896 /* XXX : not implemented */
3897 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
3898 SPR_NOACCESS, SPR_NOACCESS,
3899 &spr_read_generic, &spr_write_generic,
3900 0x00000000);
3901 /* XXX : not implemented */
3902 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
3903 SPR_NOACCESS, SPR_NOACCESS,
3904 &spr_read_generic, &spr_write_generic,
3905 0x00000000);
3906 /* XXX : not implemented */
3907 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
3908 SPR_NOACCESS, SPR_NOACCESS,
3909 &spr_read_generic, &spr_write_generic,
3910 0x00000000);
3911 /* XXX : not implemented */
3912 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
3913 SPR_NOACCESS, SPR_NOACCESS,
3914 &spr_read_generic, &spr_write_generic,
3915 0x00000000);
3916 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
3917 SPR_NOACCESS, SPR_NOACCESS,
3918 &spr_read_generic, &spr_write_generic,
3919 0x00000000);
3920 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
3921 SPR_NOACCESS, SPR_NOACCESS,
3922 &spr_read_generic, &spr_write_generic,
3923 0x00000000);
3924 /* XXX : not implemented */
3925 spr_register(env, SPR_440_CCR1, "CCR1",
3926 SPR_NOACCESS, SPR_NOACCESS,
3927 &spr_read_generic, &spr_write_generic,
3928 0x00000000);
3929 /* XXX : not implemented */
3930 spr_register(env, SPR_DCRIPR, "SPR_DCRIPR",
3931 &spr_read_generic, &spr_write_generic,
3932 &spr_read_generic, &spr_write_generic,
3933 0x00000000);
a750fc0b 3934 /* Memory management */
f2e63a42 3935#if !defined(CONFIG_USER_ONLY)
a750fc0b
JM
3936 env->nb_tlb = 64;
3937 env->nb_ways = 1;
3938 env->id_tlbs = 0;
1c53accc 3939 env->tlb_type = TLB_EMB;
f2e63a42 3940#endif
e1833e1f 3941 init_excp_BookE(env);
d63001d1
JM
3942 env->dcache_line_size = 32;
3943 env->icache_line_size = 32;
a750fc0b 3944 /* XXX: TODO: allocate internal IRQ controller */
ddd1055b
FC
3945
3946 SET_FIT_PERIOD(12, 16, 20, 24);
3947 SET_WDT_PERIOD(20, 24, 28, 32);
3fc6c082
FB
3948}
3949
7856e3a4
AF
3950POWERPC_FAMILY(460F)(ObjectClass *oc, void *data)
3951{
ca5dff0a 3952 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3953 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3954
ca5dff0a 3955 dc->desc = "PowerPC 460F (guessed)";
7856e3a4
AF
3956 pcc->init_proc = init_proc_460F;
3957 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
3958 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3959 PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL |
3960 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
3961 PPC_FLOAT_STFIWX | PPC_MFTB |
3962 PPC_DCR | PPC_DCRX | PPC_DCRUX |
3963 PPC_WRTEE | PPC_MFAPIDI |
3964 PPC_CACHE | PPC_CACHE_ICBI |
3965 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3966 PPC_MEM_TLBSYNC | PPC_TLBIVA |
3967 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
3968 PPC_440_SPEC;
ba9fd9f1
AF
3969 pcc->msr_mask = 0x000000000006FF30ULL;
3970 pcc->mmu_model = POWERPC_MMU_BOOKE;
3971 pcc->excp_model = POWERPC_EXCP_BOOKE;
3972 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
3973 pcc->bfd_mach = bfd_mach_ppc_403;
3974 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
3975 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
3976}
3977
80d11f44
JM
3978static void init_proc_MPC5xx (CPUPPCState *env)
3979{
3980 /* Time base */
3981 gen_tbl(env);
3982 gen_spr_5xx_8xx(env);
3983 gen_spr_5xx(env);
3984 init_excp_MPC5xx(env);
3985 env->dcache_line_size = 32;
3986 env->icache_line_size = 32;
3987 /* XXX: TODO: allocate internal IRQ controller */
3988}
3989
7856e3a4
AF
3990POWERPC_FAMILY(MPC5xx)(ObjectClass *oc, void *data)
3991{
ca5dff0a 3992 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
3993 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3994
ca5dff0a 3995 dc->desc = "Freescale 5xx cores (aka RCPU)";
7856e3a4
AF
3996 pcc->init_proc = init_proc_MPC5xx;
3997 pcc->check_pow = check_pow_none;
53116ebf
AF
3998 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3999 PPC_MEM_EIEIO | PPC_MEM_SYNC |
4000 PPC_CACHE_ICBI | PPC_FLOAT | PPC_FLOAT_STFIWX |
4001 PPC_MFTB;
ba9fd9f1
AF
4002 pcc->msr_mask = 0x000000000001FF43ULL;
4003 pcc->mmu_model = POWERPC_MMU_REAL;
4004 pcc->excp_model = POWERPC_EXCP_603;
4005 pcc->bus_model = PPC_FLAGS_INPUT_RCPU;
4006 pcc->bfd_mach = bfd_mach_ppc_505;
4007 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
4008 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4009}
4010
80d11f44
JM
4011static void init_proc_MPC8xx (CPUPPCState *env)
4012{
4013 /* Time base */
4014 gen_tbl(env);
4015 gen_spr_5xx_8xx(env);
4016 gen_spr_8xx(env);
4017 init_excp_MPC8xx(env);
4018 env->dcache_line_size = 32;
4019 env->icache_line_size = 32;
4020 /* XXX: TODO: allocate internal IRQ controller */
4021}
4022
7856e3a4
AF
4023POWERPC_FAMILY(MPC8xx)(ObjectClass *oc, void *data)
4024{
ca5dff0a 4025 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4026 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4027
ca5dff0a 4028 dc->desc = "Freescale 8xx cores (aka PowerQUICC)";
7856e3a4
AF
4029 pcc->init_proc = init_proc_MPC8xx;
4030 pcc->check_pow = check_pow_none;
53116ebf
AF
4031 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4032 PPC_MEM_EIEIO | PPC_MEM_SYNC |
4033 PPC_CACHE_ICBI | PPC_MFTB;
ba9fd9f1
AF
4034 pcc->msr_mask = 0x000000000001F673ULL;
4035 pcc->mmu_model = POWERPC_MMU_MPC8xx;
4036 pcc->excp_model = POWERPC_EXCP_603;
4037 pcc->bus_model = PPC_FLAGS_INPUT_RCPU;
4038 pcc->bfd_mach = bfd_mach_ppc_860;
4039 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
4040 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4041}
4042
80d11f44 4043/* Freescale 82xx cores (aka PowerQUICC-II) */
ca5dff0a 4044
80d11f44 4045static void init_proc_G2 (CPUPPCState *env)
3fc6c082 4046{
80d11f44
JM
4047 gen_spr_ne_601(env);
4048 gen_spr_G2_755(env);
4049 gen_spr_G2(env);
a750fc0b
JM
4050 /* Time base */
4051 gen_tbl(env);
bd928eba
JM
4052 /* External access control */
4053 /* XXX : not implemented */
4054 spr_register(env, SPR_EAR, "EAR",
4055 SPR_NOACCESS, SPR_NOACCESS,
4056 &spr_read_generic, &spr_write_generic,
4057 0x00000000);
80d11f44
JM
4058 /* Hardware implementation register */
4059 /* XXX : not implemented */
4060 spr_register(env, SPR_HID0, "HID0",
4061 SPR_NOACCESS, SPR_NOACCESS,
4062 &spr_read_generic, &spr_write_generic,
4063 0x00000000);
4064 /* XXX : not implemented */
4065 spr_register(env, SPR_HID1, "HID1",
4066 SPR_NOACCESS, SPR_NOACCESS,
4067 &spr_read_generic, &spr_write_generic,
4068 0x00000000);
4069 /* XXX : not implemented */
4070 spr_register(env, SPR_HID2, "HID2",
4071 SPR_NOACCESS, SPR_NOACCESS,
4072 &spr_read_generic, &spr_write_generic,
4073 0x00000000);
a750fc0b 4074 /* Memory management */
80d11f44
JM
4075 gen_low_BATs(env);
4076 gen_high_BATs(env);
4077 gen_6xx_7xx_soft_tlb(env, 64, 2);
4078 init_excp_G2(env);
d63001d1
JM
4079 env->dcache_line_size = 32;
4080 env->icache_line_size = 32;
80d11f44
JM
4081 /* Allocate hardware IRQ controller */
4082 ppc6xx_irq_init(env);
3fc6c082 4083}
a750fc0b 4084
7856e3a4
AF
4085POWERPC_FAMILY(G2)(ObjectClass *oc, void *data)
4086{
ca5dff0a 4087 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4088 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4089
ca5dff0a 4090 dc->desc = "PowerPC G2";
7856e3a4
AF
4091 pcc->init_proc = init_proc_G2;
4092 pcc->check_pow = check_pow_hid0;
53116ebf
AF
4093 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4094 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4095 PPC_FLOAT_STFIWX |
4096 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4097 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4098 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4099 PPC_SEGMENT | PPC_EXTERN;
ba9fd9f1
AF
4100 pcc->msr_mask = 0x000000000006FFF2ULL;
4101 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4102 pcc->excp_model = POWERPC_EXCP_G2;
4103 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4104 pcc->bfd_mach = bfd_mach_ppc_ec603e;
4105 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4106 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4107}
4108
80d11f44 4109static void init_proc_G2LE (CPUPPCState *env)
3fc6c082 4110{
80d11f44
JM
4111 gen_spr_ne_601(env);
4112 gen_spr_G2_755(env);
4113 gen_spr_G2(env);
a750fc0b
JM
4114 /* Time base */
4115 gen_tbl(env);
bd928eba
JM
4116 /* External access control */
4117 /* XXX : not implemented */
4118 spr_register(env, SPR_EAR, "EAR",
4119 SPR_NOACCESS, SPR_NOACCESS,
4120 &spr_read_generic, &spr_write_generic,
4121 0x00000000);
80d11f44 4122 /* Hardware implementation register */
578bb252 4123 /* XXX : not implemented */
80d11f44 4124 spr_register(env, SPR_HID0, "HID0",
a750fc0b
JM
4125 SPR_NOACCESS, SPR_NOACCESS,
4126 &spr_read_generic, &spr_write_generic,
4127 0x00000000);
80d11f44
JM
4128 /* XXX : not implemented */
4129 spr_register(env, SPR_HID1, "HID1",
a750fc0b
JM
4130 SPR_NOACCESS, SPR_NOACCESS,
4131 &spr_read_generic, &spr_write_generic,
4132 0x00000000);
578bb252 4133 /* XXX : not implemented */
80d11f44 4134 spr_register(env, SPR_HID2, "HID2",
a750fc0b
JM
4135 SPR_NOACCESS, SPR_NOACCESS,
4136 &spr_read_generic, &spr_write_generic,
4137 0x00000000);
2bc17322
FC
4138 /* Breakpoints */
4139 /* XXX : not implemented */
4140 spr_register(env, SPR_DABR, "DABR",
4141 SPR_NOACCESS, SPR_NOACCESS,
4142 &spr_read_generic, &spr_write_generic,
4143 0x00000000);
4144 /* XXX : not implemented */
4145 spr_register(env, SPR_DABR2, "DABR2",
4146 SPR_NOACCESS, SPR_NOACCESS,
4147 &spr_read_generic, &spr_write_generic,
4148 0x00000000);
4149 /* XXX : not implemented */
4150 spr_register(env, SPR_IABR2, "IABR2",
4151 SPR_NOACCESS, SPR_NOACCESS,
4152 &spr_read_generic, &spr_write_generic,
4153 0x00000000);
4154 /* XXX : not implemented */
4155 spr_register(env, SPR_IBCR, "IBCR",
4156 SPR_NOACCESS, SPR_NOACCESS,
4157 &spr_read_generic, &spr_write_generic,
4158 0x00000000);
4159 /* XXX : not implemented */
4160 spr_register(env, SPR_DBCR, "DBCR",
4161 SPR_NOACCESS, SPR_NOACCESS,
4162 &spr_read_generic, &spr_write_generic,
4163 0x00000000);
4164
a750fc0b 4165 /* Memory management */
80d11f44
JM
4166 gen_low_BATs(env);
4167 gen_high_BATs(env);
4168 gen_6xx_7xx_soft_tlb(env, 64, 2);
4169 init_excp_G2(env);
d63001d1
JM
4170 env->dcache_line_size = 32;
4171 env->icache_line_size = 32;
80d11f44
JM
4172 /* Allocate hardware IRQ controller */
4173 ppc6xx_irq_init(env);
3fc6c082
FB
4174}
4175
7856e3a4
AF
4176POWERPC_FAMILY(G2LE)(ObjectClass *oc, void *data)
4177{
ca5dff0a 4178 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4179 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4180
ca5dff0a 4181 dc->desc = "PowerPC G2LE";
7856e3a4
AF
4182 pcc->init_proc = init_proc_G2LE;
4183 pcc->check_pow = check_pow_hid0;
53116ebf
AF
4184 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4185 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4186 PPC_FLOAT_STFIWX |
4187 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4188 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4189 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4190 PPC_SEGMENT | PPC_EXTERN;
ba9fd9f1
AF
4191 pcc->msr_mask = 0x000000000007FFF3ULL;
4192 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4193 pcc->excp_model = POWERPC_EXCP_G2;
4194 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4195 pcc->bfd_mach = bfd_mach_ppc_ec603e;
4196 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4197 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4198}
4199
80d11f44 4200static void init_proc_e200 (CPUPPCState *env)
3fc6c082 4201{
e1833e1f
JM
4202 /* Time base */
4203 gen_tbl(env);
80d11f44 4204 gen_spr_BookE(env, 0x000000070000FFFFULL);
578bb252 4205 /* XXX : not implemented */
80d11f44 4206 spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
d34defbc
AJ
4207 &spr_read_spefscr, &spr_write_spefscr,
4208 &spr_read_spefscr, &spr_write_spefscr,
e1833e1f 4209 0x00000000);
80d11f44 4210 /* Memory management */
01662f3e 4211 gen_spr_BookE206(env, 0x0000005D, NULL);
80d11f44
JM
4212 /* XXX : not implemented */
4213 spr_register(env, SPR_HID0, "HID0",
e1833e1f
JM
4214 SPR_NOACCESS, SPR_NOACCESS,
4215 &spr_read_generic, &spr_write_generic,
4216 0x00000000);
80d11f44
JM
4217 /* XXX : not implemented */
4218 spr_register(env, SPR_HID1, "HID1",
e1833e1f
JM
4219 SPR_NOACCESS, SPR_NOACCESS,
4220 &spr_read_generic, &spr_write_generic,
4221 0x00000000);
578bb252 4222 /* XXX : not implemented */
80d11f44 4223 spr_register(env, SPR_Exxx_ALTCTXCR, "ALTCTXCR",
e1833e1f
JM
4224 SPR_NOACCESS, SPR_NOACCESS,
4225 &spr_read_generic, &spr_write_generic,
4226 0x00000000);
578bb252 4227 /* XXX : not implemented */
80d11f44
JM
4228 spr_register(env, SPR_Exxx_BUCSR, "BUCSR",
4229 SPR_NOACCESS, SPR_NOACCESS,
e1833e1f 4230 &spr_read_generic, &spr_write_generic,
80d11f44
JM
4231 0x00000000);
4232 /* XXX : not implemented */
4233 spr_register(env, SPR_Exxx_CTXCR, "CTXCR",
4234 SPR_NOACCESS, SPR_NOACCESS,
4235 &spr_read_generic, &spr_write_generic,
4236 0x00000000);
4237 /* XXX : not implemented */
4238 spr_register(env, SPR_Exxx_DBCNT, "DBCNT",
4239 SPR_NOACCESS, SPR_NOACCESS,
4240 &spr_read_generic, &spr_write_generic,
4241 0x00000000);
4242 /* XXX : not implemented */
4243 spr_register(env, SPR_Exxx_DBCR3, "DBCR3",
4244 SPR_NOACCESS, SPR_NOACCESS,
4245 &spr_read_generic, &spr_write_generic,
4246 0x00000000);
4247 /* XXX : not implemented */
4248 spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0",
4249 SPR_NOACCESS, SPR_NOACCESS,
4250 &spr_read_generic, &spr_write_generic,
4251 0x00000000);
4252 /* XXX : not implemented */
4253 spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0",
4254 SPR_NOACCESS, SPR_NOACCESS,
4255 &spr_read_generic, &spr_write_generic,
4256 0x00000000);
4257 /* XXX : not implemented */
4258 spr_register(env, SPR_Exxx_L1FINV0, "L1FINV0",
4259 SPR_NOACCESS, SPR_NOACCESS,
4260 &spr_read_generic, &spr_write_generic,
4261 0x00000000);
4262 /* XXX : not implemented */
4263 spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG",
4264 SPR_NOACCESS, SPR_NOACCESS,
4265 &spr_read_generic, &spr_write_generic,
4266 0x00000000);
4267 /* XXX : not implemented */
4268 spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG",
4269 SPR_NOACCESS, SPR_NOACCESS,
4270 &spr_read_generic, &spr_write_generic,
4271 0x00000000);
4272 /* XXX : not implemented */
4273 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4274 SPR_NOACCESS, SPR_NOACCESS,
4275 &spr_read_generic, &spr_write_generic,
4276 0x00000000);
4277 /* XXX : not implemented */
4278 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4279 SPR_NOACCESS, SPR_NOACCESS,
4280 &spr_read_generic, &spr_write_generic,
4281 0x00000000);
01662f3e
AG
4282 /* XXX : not implemented */
4283 spr_register(env, SPR_MMUCSR0, "MMUCSR0",
4284 SPR_NOACCESS, SPR_NOACCESS,
4285 &spr_read_generic, &spr_write_generic,
4286 0x00000000); /* TOFIX */
80d11f44
JM
4287 spr_register(env, SPR_BOOKE_DSRR0, "DSRR0",
4288 SPR_NOACCESS, SPR_NOACCESS,
4289 &spr_read_generic, &spr_write_generic,
4290 0x00000000);
4291 spr_register(env, SPR_BOOKE_DSRR1, "DSRR1",
4292 SPR_NOACCESS, SPR_NOACCESS,
e1833e1f
JM
4293 &spr_read_generic, &spr_write_generic,
4294 0x00000000);
f2e63a42 4295#if !defined(CONFIG_USER_ONLY)
e1833e1f
JM
4296 env->nb_tlb = 64;
4297 env->nb_ways = 1;
4298 env->id_tlbs = 0;
1c53accc 4299 env->tlb_type = TLB_EMB;
f2e63a42 4300#endif
e9cd84b9 4301 init_excp_e200(env, 0xFFFF0000UL);
d63001d1
JM
4302 env->dcache_line_size = 32;
4303 env->icache_line_size = 32;
e1833e1f 4304 /* XXX: TODO: allocate internal IRQ controller */
3fc6c082 4305}
a750fc0b 4306
7856e3a4
AF
4307POWERPC_FAMILY(e200)(ObjectClass *oc, void *data)
4308{
ca5dff0a 4309 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4310 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4311
ca5dff0a 4312 dc->desc = "e200 core";
7856e3a4
AF
4313 pcc->init_proc = init_proc_e200;
4314 pcc->check_pow = check_pow_hid0;
53116ebf
AF
4315 /* XXX: unimplemented instructions:
4316 * dcblc
4317 * dcbtlst
4318 * dcbtstls
4319 * icblc
4320 * icbtls
4321 * tlbivax
4322 * all SPE multiply-accumulate instructions
4323 */
4324 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
4325 PPC_SPE | PPC_SPE_SINGLE |
4326 PPC_WRTEE | PPC_RFDI |
4327 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
4328 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4329 PPC_MEM_TLBSYNC | PPC_TLBIVAX |
4330 PPC_BOOKE;
ba9fd9f1
AF
4331 pcc->msr_mask = 0x000000000606FF30ULL;
4332 pcc->mmu_model = POWERPC_MMU_BOOKE206;
4333 pcc->excp_model = POWERPC_EXCP_BOOKE;
4334 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4335 pcc->bfd_mach = bfd_mach_ppc_860;
4336 pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
4337 POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
4338 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4339}
4340
80d11f44 4341static void init_proc_e300 (CPUPPCState *env)
3fc6c082 4342{
80d11f44
JM
4343 gen_spr_ne_601(env);
4344 gen_spr_603(env);
a750fc0b
JM
4345 /* Time base */
4346 gen_tbl(env);
80d11f44
JM
4347 /* hardware implementation registers */
4348 /* XXX : not implemented */
4349 spr_register(env, SPR_HID0, "HID0",
4350 SPR_NOACCESS, SPR_NOACCESS,
4351 &spr_read_generic, &spr_write_generic,
4352 0x00000000);
4353 /* XXX : not implemented */
4354 spr_register(env, SPR_HID1, "HID1",
4355 SPR_NOACCESS, SPR_NOACCESS,
4356 &spr_read_generic, &spr_write_generic,
4357 0x00000000);
8daf1781
TM
4358 /* XXX : not implemented */
4359 spr_register(env, SPR_HID2, "HID2",
4360 SPR_NOACCESS, SPR_NOACCESS,
4361 &spr_read_generic, &spr_write_generic,
4362 0x00000000);
80d11f44
JM
4363 /* Memory management */
4364 gen_low_BATs(env);
8daf1781 4365 gen_high_BATs(env);
80d11f44
JM
4366 gen_6xx_7xx_soft_tlb(env, 64, 2);
4367 init_excp_603(env);
4368 env->dcache_line_size = 32;
4369 env->icache_line_size = 32;
4370 /* Allocate hardware IRQ controller */
4371 ppc6xx_irq_init(env);
4372}
4373
7856e3a4
AF
4374POWERPC_FAMILY(e300)(ObjectClass *oc, void *data)
4375{
ca5dff0a 4376 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4377 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4378
ca5dff0a 4379 dc->desc = "e300 core";
7856e3a4
AF
4380 pcc->init_proc = init_proc_e300;
4381 pcc->check_pow = check_pow_hid0;
53116ebf
AF
4382 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4383 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4384 PPC_FLOAT_STFIWX |
4385 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4386 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4387 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4388 PPC_SEGMENT | PPC_EXTERN;
ba9fd9f1
AF
4389 pcc->msr_mask = 0x000000000007FFF3ULL;
4390 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4391 pcc->excp_model = POWERPC_EXCP_603;
4392 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4393 pcc->bfd_mach = bfd_mach_ppc_603;
4394 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4395 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4396}
4397
b81ccf8a
AG
4398#if !defined(CONFIG_USER_ONLY)
4399static void spr_write_mas73(void *opaque, int sprn, int gprn)
4400{
4401 TCGv val = tcg_temp_new();
4402 tcg_gen_ext32u_tl(val, cpu_gpr[gprn]);
4403 gen_store_spr(SPR_BOOKE_MAS3, val);
cfee0218 4404 tcg_gen_shri_tl(val, cpu_gpr[gprn], 32);
b81ccf8a
AG
4405 gen_store_spr(SPR_BOOKE_MAS7, val);
4406 tcg_temp_free(val);
4407}
4408
4409static void spr_read_mas73(void *opaque, int gprn, int sprn)
4410{
4411 TCGv mas7 = tcg_temp_new();
4412 TCGv mas3 = tcg_temp_new();
4413 gen_load_spr(mas7, SPR_BOOKE_MAS7);
4414 tcg_gen_shli_tl(mas7, mas7, 32);
4415 gen_load_spr(mas3, SPR_BOOKE_MAS3);
4416 tcg_gen_or_tl(cpu_gpr[gprn], mas3, mas7);
4417 tcg_temp_free(mas3);
4418 tcg_temp_free(mas7);
4419}
4420
b81ccf8a
AG
4421#endif
4422
f7aa5583
VS
4423enum fsl_e500_version {
4424 fsl_e500v1,
4425 fsl_e500v2,
4426 fsl_e500mc,
b81ccf8a 4427 fsl_e5500,
f7aa5583
VS
4428};
4429
01662f3e 4430static void init_proc_e500 (CPUPPCState *env, int version)
80d11f44 4431{
01662f3e 4432 uint32_t tlbncfg[2];
b81ccf8a 4433 uint64_t ivor_mask;
e9cd84b9 4434 uint64_t ivpr_mask = 0xFFFF0000ULL;
a496e8ee
AG
4435 uint32_t l1cfg0 = 0x3800 /* 8 ways */
4436 | 0x0020; /* 32 kb */
01662f3e
AG
4437#if !defined(CONFIG_USER_ONLY)
4438 int i;
4439#endif
4440
80d11f44
JM
4441 /* Time base */
4442 gen_tbl(env);
01662f3e
AG
4443 /*
4444 * XXX The e500 doesn't implement IVOR7 and IVOR9, but doesn't
4445 * complain when accessing them.
4446 * gen_spr_BookE(env, 0x0000000F0000FD7FULL);
4447 */
b81ccf8a
AG
4448 switch (version) {
4449 case fsl_e500v1:
4450 case fsl_e500v2:
4451 default:
4452 ivor_mask = 0x0000000F0000FFFFULL;
4453 break;
4454 case fsl_e500mc:
4455 case fsl_e5500:
4456 ivor_mask = 0x000003FE0000FFFFULL;
4457 break;
2c9732db
AG
4458 }
4459 gen_spr_BookE(env, ivor_mask);
80d11f44
JM
4460 /* Processor identification */
4461 spr_register(env, SPR_BOOKE_PIR, "PIR",
4462 SPR_NOACCESS, SPR_NOACCESS,
4463 &spr_read_generic, &spr_write_pir,
4464 0x00000000);
4465 /* XXX : not implemented */
4466 spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
d34defbc
AJ
4467 &spr_read_spefscr, &spr_write_spefscr,
4468 &spr_read_spefscr, &spr_write_spefscr,
80d11f44 4469 0x00000000);
892c587f 4470#if !defined(CONFIG_USER_ONLY)
80d11f44 4471 /* Memory management */
80d11f44 4472 env->nb_pids = 3;
01662f3e
AG
4473 env->nb_ways = 2;
4474 env->id_tlbs = 0;
4475 switch (version) {
f7aa5583 4476 case fsl_e500v1:
01662f3e
AG
4477 tlbncfg[0] = gen_tlbncfg(2, 1, 1, 0, 256);
4478 tlbncfg[1] = gen_tlbncfg(16, 1, 9, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16);
4479 break;
f7aa5583 4480 case fsl_e500v2:
01662f3e
AG
4481 tlbncfg[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4482 tlbncfg[1] = gen_tlbncfg(16, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16);
f7aa5583
VS
4483 break;
4484 case fsl_e500mc:
b81ccf8a 4485 case fsl_e5500:
f7aa5583
VS
4486 tlbncfg[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4487 tlbncfg[1] = gen_tlbncfg(64, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 64);
892c587f
AG
4488 break;
4489 default:
4490 cpu_abort(env, "Unknown CPU: " TARGET_FMT_lx "\n", env->spr[SPR_PVR]);
4491 }
4492#endif
4493 /* Cache sizes */
4494 switch (version) {
4495 case fsl_e500v1:
4496 case fsl_e500v2:
4497 env->dcache_line_size = 32;
4498 env->icache_line_size = 32;
4499 break;
4500 case fsl_e500mc:
b81ccf8a 4501 case fsl_e5500:
f7aa5583
VS
4502 env->dcache_line_size = 64;
4503 env->icache_line_size = 64;
a496e8ee 4504 l1cfg0 |= 0x1000000; /* 64 byte cache block size */
01662f3e
AG
4505 break;
4506 default:
4507 cpu_abort(env, "Unknown CPU: " TARGET_FMT_lx "\n", env->spr[SPR_PVR]);
4508 }
01662f3e 4509 gen_spr_BookE206(env, 0x000000DF, tlbncfg);
80d11f44
JM
4510 /* XXX : not implemented */
4511 spr_register(env, SPR_HID0, "HID0",
4512 SPR_NOACCESS, SPR_NOACCESS,
4513 &spr_read_generic, &spr_write_generic,
4514 0x00000000);
4515 /* XXX : not implemented */
4516 spr_register(env, SPR_HID1, "HID1",
4517 SPR_NOACCESS, SPR_NOACCESS,
4518 &spr_read_generic, &spr_write_generic,
4519 0x00000000);
4520 /* XXX : not implemented */
4521 spr_register(env, SPR_Exxx_BBEAR, "BBEAR",
4522 SPR_NOACCESS, SPR_NOACCESS,
4523 &spr_read_generic, &spr_write_generic,
4524 0x00000000);
4525 /* XXX : not implemented */
4526 spr_register(env, SPR_Exxx_BBTAR, "BBTAR",
4527 SPR_NOACCESS, SPR_NOACCESS,
4528 &spr_read_generic, &spr_write_generic,
4529 0x00000000);
4530 /* XXX : not implemented */
4531 spr_register(env, SPR_Exxx_MCAR, "MCAR",
4532 SPR_NOACCESS, SPR_NOACCESS,
4533 &spr_read_generic, &spr_write_generic,
4534 0x00000000);
578bb252 4535 /* XXX : not implemented */
a750fc0b
JM
4536 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
4537 SPR_NOACCESS, SPR_NOACCESS,
4538 &spr_read_generic, &spr_write_generic,
4539 0x00000000);
80d11f44
JM
4540 /* XXX : not implemented */
4541 spr_register(env, SPR_Exxx_NPIDR, "NPIDR",
a750fc0b
JM
4542 SPR_NOACCESS, SPR_NOACCESS,
4543 &spr_read_generic, &spr_write_generic,
4544 0x00000000);
80d11f44
JM
4545 /* XXX : not implemented */
4546 spr_register(env, SPR_Exxx_BUCSR, "BUCSR",
a750fc0b
JM
4547 SPR_NOACCESS, SPR_NOACCESS,
4548 &spr_read_generic, &spr_write_generic,
4549 0x00000000);
578bb252 4550 /* XXX : not implemented */
80d11f44 4551 spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0",
a750fc0b
JM
4552 SPR_NOACCESS, SPR_NOACCESS,
4553 &spr_read_generic, &spr_write_generic,
a496e8ee 4554 l1cfg0);
578bb252 4555 /* XXX : not implemented */
80d11f44
JM
4556 spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0",
4557 SPR_NOACCESS, SPR_NOACCESS,
01662f3e 4558 &spr_read_generic, &spr_write_e500_l1csr0,
80d11f44
JM
4559 0x00000000);
4560 /* XXX : not implemented */
4561 spr_register(env, SPR_Exxx_L1CSR1, "L1CSR1",
4562 SPR_NOACCESS, SPR_NOACCESS,
4563 &spr_read_generic, &spr_write_generic,
4564 0x00000000);
80d11f44
JM
4565 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
4566 SPR_NOACCESS, SPR_NOACCESS,
4567 &spr_read_generic, &spr_write_generic,
4568 0x00000000);
4569 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
4570 SPR_NOACCESS, SPR_NOACCESS,
a750fc0b
JM
4571 &spr_read_generic, &spr_write_generic,
4572 0x00000000);
01662f3e
AG
4573 spr_register(env, SPR_MMUCSR0, "MMUCSR0",
4574 SPR_NOACCESS, SPR_NOACCESS,
4575 &spr_read_generic, &spr_write_booke206_mmucsr0,
4576 0x00000000);
b81ccf8a
AG
4577 spr_register(env, SPR_BOOKE_EPR, "EPR",
4578 SPR_NOACCESS, SPR_NOACCESS,
68c2dd70 4579 &spr_read_generic, SPR_NOACCESS,
b81ccf8a
AG
4580 0x00000000);
4581 /* XXX better abstract into Emb.xxx features */
4582 if (version == fsl_e5500) {
4583 spr_register(env, SPR_BOOKE_EPCR, "EPCR",
4584 SPR_NOACCESS, SPR_NOACCESS,
4585 &spr_read_generic, &spr_write_generic,
4586 0x00000000);
4587 spr_register(env, SPR_BOOKE_MAS7_MAS3, "MAS7_MAS3",
4588 SPR_NOACCESS, SPR_NOACCESS,
4589 &spr_read_mas73, &spr_write_mas73,
4590 0x00000000);
4591 ivpr_mask = (target_ulong)~0xFFFFULL;
4592 }
01662f3e 4593
f2e63a42 4594#if !defined(CONFIG_USER_ONLY)
01662f3e 4595 env->nb_tlb = 0;
1c53accc 4596 env->tlb_type = TLB_MAS;
01662f3e
AG
4597 for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
4598 env->nb_tlb += booke206_tlb_size(env, i);
4599 }
f2e63a42 4600#endif
01662f3e 4601
e9cd84b9 4602 init_excp_e200(env, ivpr_mask);
9fdc60bf
AJ
4603 /* Allocate hardware IRQ controller */
4604 ppce500_irq_init(env);
3fc6c082 4605}
a750fc0b 4606
01662f3e
AG
4607static void init_proc_e500v1(CPUPPCState *env)
4608{
f7aa5583 4609 init_proc_e500(env, fsl_e500v1);
01662f3e
AG
4610}
4611
7856e3a4
AF
4612POWERPC_FAMILY(e500v1)(ObjectClass *oc, void *data)
4613{
ca5dff0a 4614 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4615 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4616
ca5dff0a 4617 dc->desc = "e500v1 core";
7856e3a4
AF
4618 pcc->init_proc = init_proc_e500v1;
4619 pcc->check_pow = check_pow_hid0;
53116ebf
AF
4620 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
4621 PPC_SPE | PPC_SPE_SINGLE |
4622 PPC_WRTEE | PPC_RFDI |
4623 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
4624 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4625 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
4626 pcc->insns_flags2 = PPC2_BOOKE206;
ba9fd9f1
AF
4627 pcc->msr_mask = 0x000000000606FF30ULL;
4628 pcc->mmu_model = POWERPC_MMU_BOOKE206;
4629 pcc->excp_model = POWERPC_EXCP_BOOKE;
4630 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4631 pcc->bfd_mach = bfd_mach_ppc_860;
4632 pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
4633 POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
4634 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4635}
4636
01662f3e
AG
4637static void init_proc_e500v2(CPUPPCState *env)
4638{
f7aa5583
VS
4639 init_proc_e500(env, fsl_e500v2);
4640}
4641
7856e3a4
AF
4642POWERPC_FAMILY(e500v2)(ObjectClass *oc, void *data)
4643{
ca5dff0a 4644 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4645 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4646
ca5dff0a 4647 dc->desc = "e500v2 core";
7856e3a4
AF
4648 pcc->init_proc = init_proc_e500v2;
4649 pcc->check_pow = check_pow_hid0;
53116ebf
AF
4650 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
4651 PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE |
4652 PPC_WRTEE | PPC_RFDI |
4653 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
4654 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4655 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
4656 pcc->insns_flags2 = PPC2_BOOKE206;
ba9fd9f1
AF
4657 pcc->msr_mask = 0x000000000606FF30ULL;
4658 pcc->mmu_model = POWERPC_MMU_BOOKE206;
4659 pcc->excp_model = POWERPC_EXCP_BOOKE;
4660 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4661 pcc->bfd_mach = bfd_mach_ppc_860;
4662 pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
4663 POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
4664 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4665}
4666
f7aa5583
VS
4667static void init_proc_e500mc(CPUPPCState *env)
4668{
4669 init_proc_e500(env, fsl_e500mc);
01662f3e
AG
4670}
4671
7856e3a4
AF
4672POWERPC_FAMILY(e500mc)(ObjectClass *oc, void *data)
4673{
ca5dff0a 4674 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4675 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4676
ca5dff0a 4677 dc->desc = "e500mc core";
7856e3a4
AF
4678 pcc->init_proc = init_proc_e500mc;
4679 pcc->check_pow = check_pow_none;
53116ebf
AF
4680 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
4681 PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
4682 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
4683 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4684 PPC_FLOAT | PPC_FLOAT_FRES |
4685 PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
4686 PPC_FLOAT_STFIWX | PPC_WAIT |
4687 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
4688 pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL;
ba9fd9f1
AF
4689 pcc->msr_mask = 0x000000001402FB36ULL;
4690 pcc->mmu_model = POWERPC_MMU_BOOKE206;
4691 pcc->excp_model = POWERPC_EXCP_BOOKE;
4692 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4693 /* FIXME: figure out the correct flag for e500mc */
4694 pcc->bfd_mach = bfd_mach_ppc_e500;
4695 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
4696 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4697}
4698
b81ccf8a
AG
4699#ifdef TARGET_PPC64
4700static void init_proc_e5500(CPUPPCState *env)
4701{
4702 init_proc_e500(env, fsl_e5500);
4703}
7856e3a4
AF
4704
4705POWERPC_FAMILY(e5500)(ObjectClass *oc, void *data)
4706{
ca5dff0a 4707 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4708 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4709
ca5dff0a 4710 dc->desc = "e5500 core";
7856e3a4
AF
4711 pcc->init_proc = init_proc_e5500;
4712 pcc->check_pow = check_pow_none;
53116ebf
AF
4713 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
4714 PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
4715 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
4716 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4717 PPC_FLOAT | PPC_FLOAT_FRES |
4718 PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
4719 PPC_FLOAT_STFIWX | PPC_WAIT |
4720 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC |
4721 PPC_64B | PPC_POPCNTB | PPC_POPCNTWD;
4722 pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL;
ba9fd9f1
AF
4723 pcc->msr_mask = 0x000000009402FB36ULL;
4724 pcc->mmu_model = POWERPC_MMU_BOOKE206;
4725 pcc->excp_model = POWERPC_EXCP_BOOKE;
4726 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4727 /* FIXME: figure out the correct flag for e5500 */
4728 pcc->bfd_mach = bfd_mach_ppc_e500;
4729 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
4730 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4 4731}
b81ccf8a
AG
4732#endif
4733
a750fc0b 4734/* Non-embedded PowerPC */
a750fc0b
JM
4735
4736/* POWER : same as 601, without mfmsr, mfsr */
53116ebf
AF
4737POWERPC_FAMILY(POWER)(ObjectClass *oc, void *data)
4738{
ca5dff0a 4739 DeviceClass *dc = DEVICE_CLASS(oc);
53116ebf
AF
4740 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4741
ca5dff0a 4742 dc->desc = "POWER";
953af181 4743 /* pcc->insns_flags = XXX_TODO; */
ba9fd9f1
AF
4744 /* POWER RSC (from RAD6000) */
4745 pcc->msr_mask = 0x00000000FEF0ULL;
53116ebf 4746}
a750fc0b 4747
082c6681 4748#define POWERPC_MSRR_601 (0x0000000000001040ULL)
a750fc0b
JM
4749
4750static void init_proc_601 (CPUPPCState *env)
3fc6c082 4751{
a750fc0b
JM
4752 gen_spr_ne_601(env);
4753 gen_spr_601(env);
4754 /* Hardware implementation registers */
4755 /* XXX : not implemented */
4756 spr_register(env, SPR_HID0, "HID0",
4757 SPR_NOACCESS, SPR_NOACCESS,
056401ea 4758 &spr_read_generic, &spr_write_hid0_601,
faadf50e 4759 0x80010080);
a750fc0b
JM
4760 /* XXX : not implemented */
4761 spr_register(env, SPR_HID1, "HID1",
4762 SPR_NOACCESS, SPR_NOACCESS,
4763 &spr_read_generic, &spr_write_generic,
4764 0x00000000);
4765 /* XXX : not implemented */
4766 spr_register(env, SPR_601_HID2, "HID2",
4767 SPR_NOACCESS, SPR_NOACCESS,
4768 &spr_read_generic, &spr_write_generic,
4769 0x00000000);
4770 /* XXX : not implemented */
4771 spr_register(env, SPR_601_HID5, "HID5",
4772 SPR_NOACCESS, SPR_NOACCESS,
4773 &spr_read_generic, &spr_write_generic,
4774 0x00000000);
a750fc0b 4775 /* Memory management */
e1833e1f 4776 init_excp_601(env);
082c6681
JM
4777 /* XXX: beware that dcache line size is 64
4778 * but dcbz uses 32 bytes "sectors"
4779 * XXX: this breaks clcs instruction !
4780 */
4781 env->dcache_line_size = 32;
d63001d1 4782 env->icache_line_size = 64;
faadf50e
JM
4783 /* Allocate hardware IRQ controller */
4784 ppc6xx_irq_init(env);
3fc6c082
FB
4785}
4786
7856e3a4
AF
4787POWERPC_FAMILY(601)(ObjectClass *oc, void *data)
4788{
ca5dff0a 4789 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4790 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4791
ca5dff0a 4792 dc->desc = "PowerPC 601";
7856e3a4
AF
4793 pcc->init_proc = init_proc_601;
4794 pcc->check_pow = check_pow_none;
53116ebf
AF
4795 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
4796 PPC_FLOAT |
4797 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4798 PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
4799 PPC_SEGMENT | PPC_EXTERN;
ba9fd9f1
AF
4800 pcc->msr_mask = 0x000000000000FD70ULL;
4801 pcc->mmu_model = POWERPC_MMU_601;
b632a148
DG
4802#if defined(CONFIG_SOFTMMU)
4803 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
4804#endif
ba9fd9f1
AF
4805 pcc->excp_model = POWERPC_EXCP_601;
4806 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4807 pcc->bfd_mach = bfd_mach_ppc_601;
4808 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK;
7856e3a4
AF
4809}
4810
082c6681 4811#define POWERPC_MSRR_601v (0x0000000000001040ULL)
082c6681
JM
4812
4813static void init_proc_601v (CPUPPCState *env)
4814{
4815 init_proc_601(env);
4816 /* XXX : not implemented */
4817 spr_register(env, SPR_601_HID15, "HID15",
4818 SPR_NOACCESS, SPR_NOACCESS,
4819 &spr_read_generic, &spr_write_generic,
4820 0x00000000);
4821}
4822
7856e3a4
AF
4823POWERPC_FAMILY(601v)(ObjectClass *oc, void *data)
4824{
ca5dff0a 4825 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4826 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4827
ca5dff0a 4828 dc->desc = "PowerPC 601v";
7856e3a4
AF
4829 pcc->init_proc = init_proc_601v;
4830 pcc->check_pow = check_pow_none;
53116ebf
AF
4831 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
4832 PPC_FLOAT |
4833 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4834 PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
4835 PPC_SEGMENT | PPC_EXTERN;
ba9fd9f1
AF
4836 pcc->msr_mask = 0x000000000000FD70ULL;
4837 pcc->mmu_model = POWERPC_MMU_601;
b632a148
DG
4838#if defined(CONFIG_SOFTMMU)
4839 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
4840#endif
ba9fd9f1
AF
4841 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4842 pcc->bfd_mach = bfd_mach_ppc_601;
4843 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK;
7856e3a4
AF
4844}
4845
a750fc0b 4846static void init_proc_602 (CPUPPCState *env)
3fc6c082 4847{
a750fc0b
JM
4848 gen_spr_ne_601(env);
4849 gen_spr_602(env);
4850 /* Time base */
4851 gen_tbl(env);
4852 /* hardware implementation registers */
4853 /* XXX : not implemented */
4854 spr_register(env, SPR_HID0, "HID0",
4855 SPR_NOACCESS, SPR_NOACCESS,
4856 &spr_read_generic, &spr_write_generic,
4857 0x00000000);
4858 /* XXX : not implemented */
4859 spr_register(env, SPR_HID1, "HID1",
4860 SPR_NOACCESS, SPR_NOACCESS,
4861 &spr_read_generic, &spr_write_generic,
4862 0x00000000);
4863 /* Memory management */
4864 gen_low_BATs(env);
4865 gen_6xx_7xx_soft_tlb(env, 64, 2);
e1833e1f 4866 init_excp_602(env);
d63001d1
JM
4867 env->dcache_line_size = 32;
4868 env->icache_line_size = 32;
a750fc0b
JM
4869 /* Allocate hardware IRQ controller */
4870 ppc6xx_irq_init(env);
4871}
3fc6c082 4872
7856e3a4
AF
4873POWERPC_FAMILY(602)(ObjectClass *oc, void *data)
4874{
ca5dff0a 4875 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4876 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4877
ca5dff0a 4878 dc->desc = "PowerPC 602";
7856e3a4
AF
4879 pcc->init_proc = init_proc_602;
4880 pcc->check_pow = check_pow_hid0;
53116ebf
AF
4881 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4882 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4883 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
4884 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4885 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4886 PPC_MEM_TLBIE | PPC_6xx_TLB | PPC_MEM_TLBSYNC |
4887 PPC_SEGMENT | PPC_602_SPEC;
ba9fd9f1
AF
4888 pcc->msr_mask = 0x0000000000C7FF73ULL;
4889 /* XXX: 602 MMU is quite specific. Should add a special case */
4890 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4891 pcc->excp_model = POWERPC_EXCP_602;
4892 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4893 pcc->bfd_mach = bfd_mach_ppc_602;
4894 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4895 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4896}
4897
a750fc0b
JM
4898static void init_proc_603 (CPUPPCState *env)
4899{
4900 gen_spr_ne_601(env);
4901 gen_spr_603(env);
4902 /* Time base */
4903 gen_tbl(env);
4904 /* hardware implementation registers */
4905 /* XXX : not implemented */
4906 spr_register(env, SPR_HID0, "HID0",
4907 SPR_NOACCESS, SPR_NOACCESS,
4908 &spr_read_generic, &spr_write_generic,
4909 0x00000000);
4910 /* XXX : not implemented */
4911 spr_register(env, SPR_HID1, "HID1",
4912 SPR_NOACCESS, SPR_NOACCESS,
4913 &spr_read_generic, &spr_write_generic,
4914 0x00000000);
4915 /* Memory management */
4916 gen_low_BATs(env);
4917 gen_6xx_7xx_soft_tlb(env, 64, 2);
e1833e1f 4918 init_excp_603(env);
d63001d1
JM
4919 env->dcache_line_size = 32;
4920 env->icache_line_size = 32;
a750fc0b
JM
4921 /* Allocate hardware IRQ controller */
4922 ppc6xx_irq_init(env);
3fc6c082
FB
4923}
4924
7856e3a4
AF
4925POWERPC_FAMILY(603)(ObjectClass *oc, void *data)
4926{
ca5dff0a 4927 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4928 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4929
ca5dff0a 4930 dc->desc = "PowerPC 603";
7856e3a4
AF
4931 pcc->init_proc = init_proc_603;
4932 pcc->check_pow = check_pow_hid0;
53116ebf
AF
4933 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4934 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4935 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
4936 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4937 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4938 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4939 PPC_SEGMENT | PPC_EXTERN;
ba9fd9f1
AF
4940 pcc->msr_mask = 0x000000000007FF73ULL;
4941 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4942 pcc->excp_model = POWERPC_EXCP_603;
4943 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4944 pcc->bfd_mach = bfd_mach_ppc_603;
4945 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4946 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4947}
4948
a750fc0b
JM
4949static void init_proc_603E (CPUPPCState *env)
4950{
4951 gen_spr_ne_601(env);
4952 gen_spr_603(env);
4953 /* Time base */
4954 gen_tbl(env);
4955 /* hardware implementation registers */
4956 /* XXX : not implemented */
4957 spr_register(env, SPR_HID0, "HID0",
4958 SPR_NOACCESS, SPR_NOACCESS,
4959 &spr_read_generic, &spr_write_generic,
4960 0x00000000);
4961 /* XXX : not implemented */
4962 spr_register(env, SPR_HID1, "HID1",
4963 SPR_NOACCESS, SPR_NOACCESS,
4964 &spr_read_generic, &spr_write_generic,
4965 0x00000000);
a750fc0b
JM
4966 /* Memory management */
4967 gen_low_BATs(env);
4968 gen_6xx_7xx_soft_tlb(env, 64, 2);
e1833e1f 4969 init_excp_603(env);
d63001d1
JM
4970 env->dcache_line_size = 32;
4971 env->icache_line_size = 32;
a750fc0b
JM
4972 /* Allocate hardware IRQ controller */
4973 ppc6xx_irq_init(env);
4974}
4975
7856e3a4
AF
4976POWERPC_FAMILY(603E)(ObjectClass *oc, void *data)
4977{
ca5dff0a 4978 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4979 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4980
ca5dff0a 4981 dc->desc = "PowerPC 603e";
7856e3a4
AF
4982 pcc->init_proc = init_proc_603E;
4983 pcc->check_pow = check_pow_hid0;
53116ebf
AF
4984 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4985 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4986 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
4987 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4988 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4989 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4990 PPC_SEGMENT | PPC_EXTERN;
ba9fd9f1
AF
4991 pcc->msr_mask = 0x000000000007FF73ULL;
4992 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4993 pcc->excp_model = POWERPC_EXCP_603E;
4994 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4995 pcc->bfd_mach = bfd_mach_ppc_ec603e;
4996 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4997 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4998}
4999
a750fc0b
JM
5000static void init_proc_604 (CPUPPCState *env)
5001{
5002 gen_spr_ne_601(env);
5003 gen_spr_604(env);
5004 /* Time base */
5005 gen_tbl(env);
5006 /* Hardware implementation registers */
5007 /* XXX : not implemented */
082c6681
JM
5008 spr_register(env, SPR_HID0, "HID0",
5009 SPR_NOACCESS, SPR_NOACCESS,
5010 &spr_read_generic, &spr_write_generic,
5011 0x00000000);
5012 /* Memory management */
5013 gen_low_BATs(env);
5014 init_excp_604(env);
5015 env->dcache_line_size = 32;
5016 env->icache_line_size = 32;
5017 /* Allocate hardware IRQ controller */
5018 ppc6xx_irq_init(env);
5019}
5020
7856e3a4
AF
5021POWERPC_FAMILY(604)(ObjectClass *oc, void *data)
5022{
ca5dff0a 5023 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5024 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5025
ca5dff0a 5026 dc->desc = "PowerPC 604";
7856e3a4
AF
5027 pcc->init_proc = init_proc_604;
5028 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
5029 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5030 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5031 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5032 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5033 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5034 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5035 PPC_SEGMENT | PPC_EXTERN;
ba9fd9f1
AF
5036 pcc->msr_mask = 0x000000000005FF77ULL;
5037 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
5038#if defined(CONFIG_SOFTMMU)
5039 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5040#endif
ba9fd9f1
AF
5041 pcc->excp_model = POWERPC_EXCP_604;
5042 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5043 pcc->bfd_mach = bfd_mach_ppc_604;
5044 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5045 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5046}
5047
082c6681
JM
5048static void init_proc_604E (CPUPPCState *env)
5049{
5050 gen_spr_ne_601(env);
5051 gen_spr_604(env);
5052 /* XXX : not implemented */
5053 spr_register(env, SPR_MMCR1, "MMCR1",
5054 SPR_NOACCESS, SPR_NOACCESS,
5055 &spr_read_generic, &spr_write_generic,
5056 0x00000000);
5057 /* XXX : not implemented */
5058 spr_register(env, SPR_PMC3, "PMC3",
5059 SPR_NOACCESS, SPR_NOACCESS,
5060 &spr_read_generic, &spr_write_generic,
5061 0x00000000);
5062 /* XXX : not implemented */
5063 spr_register(env, SPR_PMC4, "PMC4",
5064 SPR_NOACCESS, SPR_NOACCESS,
5065 &spr_read_generic, &spr_write_generic,
5066 0x00000000);
5067 /* Time base */
5068 gen_tbl(env);
5069 /* Hardware implementation registers */
5070 /* XXX : not implemented */
a750fc0b
JM
5071 spr_register(env, SPR_HID0, "HID0",
5072 SPR_NOACCESS, SPR_NOACCESS,
5073 &spr_read_generic, &spr_write_generic,
5074 0x00000000);
5075 /* XXX : not implemented */
5076 spr_register(env, SPR_HID1, "HID1",
5077 SPR_NOACCESS, SPR_NOACCESS,
5078 &spr_read_generic, &spr_write_generic,
5079 0x00000000);
5080 /* Memory management */
5081 gen_low_BATs(env);
e1833e1f 5082 init_excp_604(env);
d63001d1
JM
5083 env->dcache_line_size = 32;
5084 env->icache_line_size = 32;
a750fc0b
JM
5085 /* Allocate hardware IRQ controller */
5086 ppc6xx_irq_init(env);
5087}
5088
7856e3a4
AF
5089POWERPC_FAMILY(604E)(ObjectClass *oc, void *data)
5090{
ca5dff0a 5091 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5092 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5093
ca5dff0a 5094 dc->desc = "PowerPC 604E";
7856e3a4
AF
5095 pcc->init_proc = init_proc_604E;
5096 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
5097 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5098 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5099 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5100 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5101 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5102 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5103 PPC_SEGMENT | PPC_EXTERN;
ba9fd9f1
AF
5104 pcc->msr_mask = 0x000000000005FF77ULL;
5105 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
5106#if defined(CONFIG_SOFTMMU)
5107 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5108#endif
ba9fd9f1
AF
5109 pcc->excp_model = POWERPC_EXCP_604;
5110 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5111 pcc->bfd_mach = bfd_mach_ppc_604;
5112 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5113 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5114}
5115
bd928eba 5116static void init_proc_740 (CPUPPCState *env)
a750fc0b
JM
5117{
5118 gen_spr_ne_601(env);
5119 gen_spr_7xx(env);
5120 /* Time base */
5121 gen_tbl(env);
5122 /* Thermal management */
5123 gen_spr_thrm(env);
5124 /* Hardware implementation registers */
5125 /* XXX : not implemented */
5126 spr_register(env, SPR_HID0, "HID0",
5127 SPR_NOACCESS, SPR_NOACCESS,
5128 &spr_read_generic, &spr_write_generic,
5129 0x00000000);
5130 /* XXX : not implemented */
5131 spr_register(env, SPR_HID1, "HID1",
5132 SPR_NOACCESS, SPR_NOACCESS,
5133 &spr_read_generic, &spr_write_generic,
5134 0x00000000);
5135 /* Memory management */
5136 gen_low_BATs(env);
e1833e1f 5137 init_excp_7x0(env);
d63001d1
JM
5138 env->dcache_line_size = 32;
5139 env->icache_line_size = 32;
a750fc0b
JM
5140 /* Allocate hardware IRQ controller */
5141 ppc6xx_irq_init(env);
5142}
5143
7856e3a4
AF
5144POWERPC_FAMILY(740)(ObjectClass *oc, void *data)
5145{
ca5dff0a 5146 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5147 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5148
ca5dff0a 5149 dc->desc = "PowerPC 740";
7856e3a4
AF
5150 pcc->init_proc = init_proc_740;
5151 pcc->check_pow = check_pow_hid0;
53116ebf
AF
5152 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5153 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5154 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5155 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5156 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5157 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5158 PPC_SEGMENT | PPC_EXTERN;
ba9fd9f1
AF
5159 pcc->msr_mask = 0x000000000005FF77ULL;
5160 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
5161#if defined(CONFIG_SOFTMMU)
5162 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5163#endif
ba9fd9f1
AF
5164 pcc->excp_model = POWERPC_EXCP_7x0;
5165 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5166 pcc->bfd_mach = bfd_mach_ppc_750;
5167 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5168 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5169}
5170
bd928eba
JM
5171static void init_proc_750 (CPUPPCState *env)
5172{
5173 gen_spr_ne_601(env);
5174 gen_spr_7xx(env);
5175 /* XXX : not implemented */
5176 spr_register(env, SPR_L2CR, "L2CR",
5177 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 5178 &spr_read_generic, spr_access_nop,
bd928eba
JM
5179 0x00000000);
5180 /* Time base */
5181 gen_tbl(env);
5182 /* Thermal management */
5183 gen_spr_thrm(env);
5184 /* Hardware implementation registers */
5185 /* XXX : not implemented */
5186 spr_register(env, SPR_HID0, "HID0",
5187 SPR_NOACCESS, SPR_NOACCESS,
5188 &spr_read_generic, &spr_write_generic,
5189 0x00000000);
5190 /* XXX : not implemented */
5191 spr_register(env, SPR_HID1, "HID1",
5192 SPR_NOACCESS, SPR_NOACCESS,
5193 &spr_read_generic, &spr_write_generic,
5194 0x00000000);
5195 /* Memory management */
5196 gen_low_BATs(env);
5197 /* XXX: high BATs are also present but are known to be bugged on
5198 * die version 1.x
5199 */
5200 init_excp_7x0(env);
5201 env->dcache_line_size = 32;
5202 env->icache_line_size = 32;
5203 /* Allocate hardware IRQ controller */
5204 ppc6xx_irq_init(env);
5205}
5206
7856e3a4
AF
5207POWERPC_FAMILY(750)(ObjectClass *oc, void *data)
5208{
ca5dff0a 5209 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5210 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5211
ca5dff0a 5212 dc->desc = "PowerPC 750";
7856e3a4
AF
5213 pcc->init_proc = init_proc_750;
5214 pcc->check_pow = check_pow_hid0;
53116ebf
AF
5215 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5216 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5217 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5218 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5219 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5220 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5221 PPC_SEGMENT | PPC_EXTERN;
ba9fd9f1
AF
5222 pcc->msr_mask = 0x000000000005FF77ULL;
5223 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
5224#if defined(CONFIG_SOFTMMU)
5225 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5226#endif
ba9fd9f1
AF
5227 pcc->excp_model = POWERPC_EXCP_7x0;
5228 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5229 pcc->bfd_mach = bfd_mach_ppc_750;
5230 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5231 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5232}
5233
bd928eba
JM
5234static void init_proc_750cl (CPUPPCState *env)
5235{
5236 gen_spr_ne_601(env);
5237 gen_spr_7xx(env);
5238 /* XXX : not implemented */
5239 spr_register(env, SPR_L2CR, "L2CR",
5240 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 5241 &spr_read_generic, spr_access_nop,
bd928eba
JM
5242 0x00000000);
5243 /* Time base */
5244 gen_tbl(env);
5245 /* Thermal management */
5246 /* Those registers are fake on 750CL */
5247 spr_register(env, SPR_THRM1, "THRM1",
5248 SPR_NOACCESS, SPR_NOACCESS,
5249 &spr_read_generic, &spr_write_generic,
5250 0x00000000);
5251 spr_register(env, SPR_THRM2, "THRM2",
5252 SPR_NOACCESS, SPR_NOACCESS,
5253 &spr_read_generic, &spr_write_generic,
5254 0x00000000);
5255 spr_register(env, SPR_THRM3, "THRM3",
5256 SPR_NOACCESS, SPR_NOACCESS,
5257 &spr_read_generic, &spr_write_generic,
5258 0x00000000);
5259 /* XXX: not implemented */
5260 spr_register(env, SPR_750_TDCL, "TDCL",
5261 SPR_NOACCESS, SPR_NOACCESS,
5262 &spr_read_generic, &spr_write_generic,
5263 0x00000000);
5264 spr_register(env, SPR_750_TDCH, "TDCH",
5265 SPR_NOACCESS, SPR_NOACCESS,
5266 &spr_read_generic, &spr_write_generic,
5267 0x00000000);
5268 /* DMA */
5269 /* XXX : not implemented */
5270 spr_register(env, SPR_750_WPAR, "WPAR",
5271 SPR_NOACCESS, SPR_NOACCESS,
5272 &spr_read_generic, &spr_write_generic,
5273 0x00000000);
5274 spr_register(env, SPR_750_DMAL, "DMAL",
5275 SPR_NOACCESS, SPR_NOACCESS,
5276 &spr_read_generic, &spr_write_generic,
5277 0x00000000);
5278 spr_register(env, SPR_750_DMAU, "DMAU",
5279 SPR_NOACCESS, SPR_NOACCESS,
5280 &spr_read_generic, &spr_write_generic,
5281 0x00000000);
5282 /* Hardware implementation registers */
5283 /* XXX : not implemented */
5284 spr_register(env, SPR_HID0, "HID0",
5285 SPR_NOACCESS, SPR_NOACCESS,
5286 &spr_read_generic, &spr_write_generic,
5287 0x00000000);
5288 /* XXX : not implemented */
5289 spr_register(env, SPR_HID1, "HID1",
5290 SPR_NOACCESS, SPR_NOACCESS,
5291 &spr_read_generic, &spr_write_generic,
5292 0x00000000);
5293 /* XXX : not implemented */
5294 spr_register(env, SPR_750CL_HID2, "HID2",
5295 SPR_NOACCESS, SPR_NOACCESS,
5296 &spr_read_generic, &spr_write_generic,
5297 0x00000000);
5298 /* XXX : not implemented */
5299 spr_register(env, SPR_750CL_HID4, "HID4",
5300 SPR_NOACCESS, SPR_NOACCESS,
5301 &spr_read_generic, &spr_write_generic,
5302 0x00000000);
5303 /* Quantization registers */
5304 /* XXX : not implemented */
5305 spr_register(env, SPR_750_GQR0, "GQR0",
5306 SPR_NOACCESS, SPR_NOACCESS,
5307 &spr_read_generic, &spr_write_generic,
5308 0x00000000);
5309 /* XXX : not implemented */
5310 spr_register(env, SPR_750_GQR1, "GQR1",
5311 SPR_NOACCESS, SPR_NOACCESS,
5312 &spr_read_generic, &spr_write_generic,
5313 0x00000000);
5314 /* XXX : not implemented */
5315 spr_register(env, SPR_750_GQR2, "GQR2",
5316 SPR_NOACCESS, SPR_NOACCESS,
5317 &spr_read_generic, &spr_write_generic,
5318 0x00000000);
5319 /* XXX : not implemented */
5320 spr_register(env, SPR_750_GQR3, "GQR3",
5321 SPR_NOACCESS, SPR_NOACCESS,
5322 &spr_read_generic, &spr_write_generic,
5323 0x00000000);
5324 /* XXX : not implemented */
5325 spr_register(env, SPR_750_GQR4, "GQR4",
5326 SPR_NOACCESS, SPR_NOACCESS,
5327 &spr_read_generic, &spr_write_generic,
5328 0x00000000);
5329 /* XXX : not implemented */
5330 spr_register(env, SPR_750_GQR5, "GQR5",
5331 SPR_NOACCESS, SPR_NOACCESS,
5332 &spr_read_generic, &spr_write_generic,
5333 0x00000000);
5334 /* XXX : not implemented */
5335 spr_register(env, SPR_750_GQR6, "GQR6",
5336 SPR_NOACCESS, SPR_NOACCESS,
5337 &spr_read_generic, &spr_write_generic,
5338 0x00000000);
5339 /* XXX : not implemented */
5340 spr_register(env, SPR_750_GQR7, "GQR7",
5341 SPR_NOACCESS, SPR_NOACCESS,
5342 &spr_read_generic, &spr_write_generic,
5343 0x00000000);
5344 /* Memory management */
5345 gen_low_BATs(env);
5346 /* PowerPC 750cl has 8 DBATs and 8 IBATs */
5347 gen_high_BATs(env);
5348 init_excp_750cl(env);
5349 env->dcache_line_size = 32;
5350 env->icache_line_size = 32;
5351 /* Allocate hardware IRQ controller */
5352 ppc6xx_irq_init(env);
5353}
5354
7856e3a4
AF
5355POWERPC_FAMILY(750cl)(ObjectClass *oc, void *data)
5356{
ca5dff0a 5357 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5358 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5359
ca5dff0a 5360 dc->desc = "PowerPC 750 CL";
7856e3a4
AF
5361 pcc->init_proc = init_proc_750cl;
5362 pcc->check_pow = check_pow_hid0;
53116ebf
AF
5363 /* XXX: not implemented:
5364 * cache lock instructions:
5365 * dcbz_l
5366 * floating point paired instructions
5367 * psq_lux
5368 * psq_lx
5369 * psq_stux
5370 * psq_stx
5371 * ps_abs
5372 * ps_add
5373 * ps_cmpo0
5374 * ps_cmpo1
5375 * ps_cmpu0
5376 * ps_cmpu1
5377 * ps_div
5378 * ps_madd
5379 * ps_madds0
5380 * ps_madds1
5381 * ps_merge00
5382 * ps_merge01
5383 * ps_merge10
5384 * ps_merge11
5385 * ps_mr
5386 * ps_msub
5387 * ps_mul
5388 * ps_muls0
5389 * ps_muls1
5390 * ps_nabs
5391 * ps_neg
5392 * ps_nmadd
5393 * ps_nmsub
5394 * ps_res
5395 * ps_rsqrte
5396 * ps_sel
5397 * ps_sub
5398 * ps_sum0
5399 * ps_sum1
5400 */
5401 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5402 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5403 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5404 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5405 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5406 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5407 PPC_SEGMENT | PPC_EXTERN;
ba9fd9f1
AF
5408 pcc->msr_mask = 0x000000000005FF77ULL;
5409 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
5410#if defined(CONFIG_SOFTMMU)
5411 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5412#endif
ba9fd9f1
AF
5413 pcc->excp_model = POWERPC_EXCP_7x0;
5414 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5415 pcc->bfd_mach = bfd_mach_ppc_750;
5416 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5417 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5418}
5419
bd928eba
JM
5420static void init_proc_750cx (CPUPPCState *env)
5421{
5422 gen_spr_ne_601(env);
5423 gen_spr_7xx(env);
5424 /* XXX : not implemented */
5425 spr_register(env, SPR_L2CR, "L2CR",
5426 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 5427 &spr_read_generic, spr_access_nop,
bd928eba
JM
5428 0x00000000);
5429 /* Time base */
5430 gen_tbl(env);
5431 /* Thermal management */
5432 gen_spr_thrm(env);
5433 /* This register is not implemented but is present for compatibility */
5434 spr_register(env, SPR_SDA, "SDA",
5435 SPR_NOACCESS, SPR_NOACCESS,
5436 &spr_read_generic, &spr_write_generic,
5437 0x00000000);
5438 /* Hardware implementation registers */
5439 /* XXX : not implemented */
5440 spr_register(env, SPR_HID0, "HID0",
5441 SPR_NOACCESS, SPR_NOACCESS,
5442 &spr_read_generic, &spr_write_generic,
5443 0x00000000);
5444 /* XXX : not implemented */
5445 spr_register(env, SPR_HID1, "HID1",
5446 SPR_NOACCESS, SPR_NOACCESS,
5447 &spr_read_generic, &spr_write_generic,
5448 0x00000000);
5449 /* Memory management */
5450 gen_low_BATs(env);
4e777442
JM
5451 /* PowerPC 750cx has 8 DBATs and 8 IBATs */
5452 gen_high_BATs(env);
bd928eba
JM
5453 init_excp_750cx(env);
5454 env->dcache_line_size = 32;
5455 env->icache_line_size = 32;
5456 /* Allocate hardware IRQ controller */
5457 ppc6xx_irq_init(env);
5458}
5459
7856e3a4
AF
5460POWERPC_FAMILY(750cx)(ObjectClass *oc, void *data)
5461{
ca5dff0a 5462 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5463 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5464
ca5dff0a 5465 dc->desc = "PowerPC 750CX";
7856e3a4
AF
5466 pcc->init_proc = init_proc_750cx;
5467 pcc->check_pow = check_pow_hid0;
53116ebf
AF
5468 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5469 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5470 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5471 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5472 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5473 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5474 PPC_SEGMENT | PPC_EXTERN;
ba9fd9f1
AF
5475 pcc->msr_mask = 0x000000000005FF77ULL;
5476 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
5477#if defined(CONFIG_SOFTMMU)
5478 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5479#endif
ba9fd9f1
AF
5480 pcc->excp_model = POWERPC_EXCP_7x0;
5481 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5482 pcc->bfd_mach = bfd_mach_ppc_750;
5483 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5484 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5485}
5486
a750fc0b
JM
5487static void init_proc_750fx (CPUPPCState *env)
5488{
5489 gen_spr_ne_601(env);
5490 gen_spr_7xx(env);
bd928eba
JM
5491 /* XXX : not implemented */
5492 spr_register(env, SPR_L2CR, "L2CR",
5493 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 5494 &spr_read_generic, spr_access_nop,
bd928eba 5495 0x00000000);
a750fc0b
JM
5496 /* Time base */
5497 gen_tbl(env);
5498 /* Thermal management */
5499 gen_spr_thrm(env);
bd928eba
JM
5500 /* XXX : not implemented */
5501 spr_register(env, SPR_750_THRM4, "THRM4",
5502 SPR_NOACCESS, SPR_NOACCESS,
5503 &spr_read_generic, &spr_write_generic,
5504 0x00000000);
a750fc0b
JM
5505 /* Hardware implementation registers */
5506 /* XXX : not implemented */
5507 spr_register(env, SPR_HID0, "HID0",
5508 SPR_NOACCESS, SPR_NOACCESS,
5509 &spr_read_generic, &spr_write_generic,
5510 0x00000000);
5511 /* XXX : not implemented */
5512 spr_register(env, SPR_HID1, "HID1",
5513 SPR_NOACCESS, SPR_NOACCESS,
5514 &spr_read_generic, &spr_write_generic,
5515 0x00000000);
5516 /* XXX : not implemented */
bd928eba 5517 spr_register(env, SPR_750FX_HID2, "HID2",
a750fc0b
JM
5518 SPR_NOACCESS, SPR_NOACCESS,
5519 &spr_read_generic, &spr_write_generic,
5520 0x00000000);
5521 /* Memory management */
5522 gen_low_BATs(env);
5523 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
5524 gen_high_BATs(env);
bd928eba 5525 init_excp_7x0(env);
d63001d1
JM
5526 env->dcache_line_size = 32;
5527 env->icache_line_size = 32;
a750fc0b
JM
5528 /* Allocate hardware IRQ controller */
5529 ppc6xx_irq_init(env);
5530}
5531
7856e3a4
AF
5532POWERPC_FAMILY(750fx)(ObjectClass *oc, void *data)
5533{
ca5dff0a 5534 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5535 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5536
ca5dff0a 5537 dc->desc = "PowerPC 750FX";
7856e3a4
AF
5538 pcc->init_proc = init_proc_750fx;
5539 pcc->check_pow = check_pow_hid0;
53116ebf
AF
5540 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5541 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5542 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5543 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5544 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5545 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5546 PPC_SEGMENT | PPC_EXTERN;
ba9fd9f1
AF
5547 pcc->msr_mask = 0x000000000005FF77ULL;
5548 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
5549#if defined(CONFIG_SOFTMMU)
5550 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5551#endif
ba9fd9f1
AF
5552 pcc->excp_model = POWERPC_EXCP_7x0;
5553 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5554 pcc->bfd_mach = bfd_mach_ppc_750;
5555 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5556 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5557}
5558
bd928eba
JM
5559static void init_proc_750gx (CPUPPCState *env)
5560{
5561 gen_spr_ne_601(env);
5562 gen_spr_7xx(env);
5563 /* XXX : not implemented (XXX: different from 750fx) */
5564 spr_register(env, SPR_L2CR, "L2CR",
5565 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 5566 &spr_read_generic, spr_access_nop,
bd928eba
JM
5567 0x00000000);
5568 /* Time base */
5569 gen_tbl(env);
5570 /* Thermal management */
5571 gen_spr_thrm(env);
5572 /* XXX : not implemented */
5573 spr_register(env, SPR_750_THRM4, "THRM4",
5574 SPR_NOACCESS, SPR_NOACCESS,
5575 &spr_read_generic, &spr_write_generic,
5576 0x00000000);
5577 /* Hardware implementation registers */
5578 /* XXX : not implemented (XXX: different from 750fx) */
5579 spr_register(env, SPR_HID0, "HID0",
5580 SPR_NOACCESS, SPR_NOACCESS,
5581 &spr_read_generic, &spr_write_generic,
5582 0x00000000);
5583 /* XXX : not implemented */
5584 spr_register(env, SPR_HID1, "HID1",
5585 SPR_NOACCESS, SPR_NOACCESS,
5586 &spr_read_generic, &spr_write_generic,
5587 0x00000000);
5588 /* XXX : not implemented (XXX: different from 750fx) */
5589 spr_register(env, SPR_750FX_HID2, "HID2",
5590 SPR_NOACCESS, SPR_NOACCESS,
5591 &spr_read_generic, &spr_write_generic,
5592 0x00000000);
5593 /* Memory management */
5594 gen_low_BATs(env);
5595 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
5596 gen_high_BATs(env);
5597 init_excp_7x0(env);
5598 env->dcache_line_size = 32;
5599 env->icache_line_size = 32;
5600 /* Allocate hardware IRQ controller */
5601 ppc6xx_irq_init(env);
5602}
5603
7856e3a4
AF
5604POWERPC_FAMILY(750gx)(ObjectClass *oc, void *data)
5605{
ca5dff0a 5606 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5607 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5608
ca5dff0a 5609 dc->desc = "PowerPC 750GX";
7856e3a4
AF
5610 pcc->init_proc = init_proc_750gx;
5611 pcc->check_pow = check_pow_hid0;
53116ebf
AF
5612 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5613 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5614 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5615 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5616 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5617 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5618 PPC_SEGMENT | PPC_EXTERN;
ba9fd9f1
AF
5619 pcc->msr_mask = 0x000000000005FF77ULL;
5620 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
5621#if defined(CONFIG_SOFTMMU)
5622 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5623#endif
ba9fd9f1
AF
5624 pcc->excp_model = POWERPC_EXCP_7x0;
5625 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5626 pcc->bfd_mach = bfd_mach_ppc_750;
5627 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5628 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5629}
5630
bd928eba
JM
5631static void init_proc_745 (CPUPPCState *env)
5632{
5633 gen_spr_ne_601(env);
5634 gen_spr_7xx(env);
5635 gen_spr_G2_755(env);
5636 /* Time base */
5637 gen_tbl(env);
5638 /* Thermal management */
5639 gen_spr_thrm(env);
5640 /* Hardware implementation registers */
5641 /* XXX : not implemented */
5642 spr_register(env, SPR_HID0, "HID0",
5643 SPR_NOACCESS, SPR_NOACCESS,
5644 &spr_read_generic, &spr_write_generic,
5645 0x00000000);
5646 /* XXX : not implemented */
5647 spr_register(env, SPR_HID1, "HID1",
5648 SPR_NOACCESS, SPR_NOACCESS,
5649 &spr_read_generic, &spr_write_generic,
5650 0x00000000);
5651 /* XXX : not implemented */
5652 spr_register(env, SPR_HID2, "HID2",
5653 SPR_NOACCESS, SPR_NOACCESS,
5654 &spr_read_generic, &spr_write_generic,
5655 0x00000000);
5656 /* Memory management */
5657 gen_low_BATs(env);
5658 gen_high_BATs(env);
5659 gen_6xx_7xx_soft_tlb(env, 64, 2);
5660 init_excp_7x5(env);
5661 env->dcache_line_size = 32;
5662 env->icache_line_size = 32;
5663 /* Allocate hardware IRQ controller */
5664 ppc6xx_irq_init(env);
5665}
5666
7856e3a4
AF
5667POWERPC_FAMILY(745)(ObjectClass *oc, void *data)
5668{
ca5dff0a 5669 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5670 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5671
ca5dff0a 5672 dc->desc = "PowerPC 745";
7856e3a4
AF
5673 pcc->init_proc = init_proc_745;
5674 pcc->check_pow = check_pow_hid0;
53116ebf
AF
5675 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5676 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5677 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5678 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5679 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5680 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
5681 PPC_SEGMENT | PPC_EXTERN;
ba9fd9f1
AF
5682 pcc->msr_mask = 0x000000000005FF77ULL;
5683 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
5684 pcc->excp_model = POWERPC_EXCP_7x5;
5685 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5686 pcc->bfd_mach = bfd_mach_ppc_750;
5687 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5688 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5689}
5690
bd928eba 5691static void init_proc_755 (CPUPPCState *env)
a750fc0b
JM
5692{
5693 gen_spr_ne_601(env);
bd928eba 5694 gen_spr_7xx(env);
a750fc0b
JM
5695 gen_spr_G2_755(env);
5696 /* Time base */
5697 gen_tbl(env);
5698 /* L2 cache control */
5699 /* XXX : not implemented */
bd928eba 5700 spr_register(env, SPR_L2CR, "L2CR",
a750fc0b 5701 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 5702 &spr_read_generic, spr_access_nop,
a750fc0b
JM
5703 0x00000000);
5704 /* XXX : not implemented */
5705 spr_register(env, SPR_L2PMCR, "L2PMCR",
5706 SPR_NOACCESS, SPR_NOACCESS,
5707 &spr_read_generic, &spr_write_generic,
5708 0x00000000);
bd928eba
JM
5709 /* Thermal management */
5710 gen_spr_thrm(env);
a750fc0b
JM
5711 /* Hardware implementation registers */
5712 /* XXX : not implemented */
5713 spr_register(env, SPR_HID0, "HID0",
5714 SPR_NOACCESS, SPR_NOACCESS,
5715 &spr_read_generic, &spr_write_generic,
5716 0x00000000);
5717 /* XXX : not implemented */
5718 spr_register(env, SPR_HID1, "HID1",
5719 SPR_NOACCESS, SPR_NOACCESS,
5720 &spr_read_generic, &spr_write_generic,
5721 0x00000000);
5722 /* XXX : not implemented */
5723 spr_register(env, SPR_HID2, "HID2",
5724 SPR_NOACCESS, SPR_NOACCESS,
5725 &spr_read_generic, &spr_write_generic,
5726 0x00000000);
5727 /* Memory management */
5728 gen_low_BATs(env);
5729 gen_high_BATs(env);
5730 gen_6xx_7xx_soft_tlb(env, 64, 2);
7a3a6927 5731 init_excp_7x5(env);
d63001d1
JM
5732 env->dcache_line_size = 32;
5733 env->icache_line_size = 32;
a750fc0b
JM
5734 /* Allocate hardware IRQ controller */
5735 ppc6xx_irq_init(env);
5736}
5737
7856e3a4
AF
5738POWERPC_FAMILY(755)(ObjectClass *oc, void *data)
5739{
ca5dff0a 5740 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5741 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5742
ca5dff0a 5743 dc->desc = "PowerPC 755";
7856e3a4
AF
5744 pcc->init_proc = init_proc_755;
5745 pcc->check_pow = check_pow_hid0;
53116ebf
AF
5746 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5747 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5748 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5749 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5750 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5751 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
5752 PPC_SEGMENT | PPC_EXTERN;
ba9fd9f1
AF
5753 pcc->msr_mask = 0x000000000005FF77ULL;
5754 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
5755 pcc->excp_model = POWERPC_EXCP_7x5;
5756 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5757 pcc->bfd_mach = bfd_mach_ppc_750;
5758 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5759 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5760}
5761
a750fc0b
JM
5762static void init_proc_7400 (CPUPPCState *env)
5763{
5764 gen_spr_ne_601(env);
5765 gen_spr_7xx(env);
5766 /* Time base */
5767 gen_tbl(env);
5768 /* 74xx specific SPR */
5769 gen_spr_74xx(env);
4e777442
JM
5770 /* XXX : not implemented */
5771 spr_register(env, SPR_UBAMR, "UBAMR",
5772 &spr_read_ureg, SPR_NOACCESS,
5773 &spr_read_ureg, SPR_NOACCESS,
5774 0x00000000);
5775 /* XXX: this seems not implemented on all revisions. */
5776 /* XXX : not implemented */
5777 spr_register(env, SPR_MSSCR1, "MSSCR1",
5778 SPR_NOACCESS, SPR_NOACCESS,
5779 &spr_read_generic, &spr_write_generic,
5780 0x00000000);
a750fc0b
JM
5781 /* Thermal management */
5782 gen_spr_thrm(env);
5783 /* Memory management */
5784 gen_low_BATs(env);
e1833e1f 5785 init_excp_7400(env);
d63001d1
JM
5786 env->dcache_line_size = 32;
5787 env->icache_line_size = 32;
a750fc0b
JM
5788 /* Allocate hardware IRQ controller */
5789 ppc6xx_irq_init(env);
5790}
5791
7856e3a4
AF
5792POWERPC_FAMILY(7400)(ObjectClass *oc, void *data)
5793{
ca5dff0a 5794 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5795 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5796
ca5dff0a 5797 dc->desc = "PowerPC 7400 (aka G4)";
7856e3a4
AF
5798 pcc->init_proc = init_proc_7400;
5799 pcc->check_pow = check_pow_hid0;
53116ebf
AF
5800 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5801 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5802 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
5803 PPC_FLOAT_STFIWX |
5804 PPC_CACHE | PPC_CACHE_ICBI |
5805 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
5806 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5807 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5808 PPC_MEM_TLBIA |
5809 PPC_SEGMENT | PPC_EXTERN |
5810 PPC_ALTIVEC;
ba9fd9f1
AF
5811 pcc->msr_mask = 0x000000000205FF77ULL;
5812 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
5813#if defined(CONFIG_SOFTMMU)
5814 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5815#endif
ba9fd9f1
AF
5816 pcc->excp_model = POWERPC_EXCP_74xx;
5817 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5818 pcc->bfd_mach = bfd_mach_ppc_7400;
5819 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
5820 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
5821 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5822}
5823
a750fc0b
JM
5824static void init_proc_7410 (CPUPPCState *env)
5825{
5826 gen_spr_ne_601(env);
5827 gen_spr_7xx(env);
5828 /* Time base */
5829 gen_tbl(env);
5830 /* 74xx specific SPR */
5831 gen_spr_74xx(env);
4e777442
JM
5832 /* XXX : not implemented */
5833 spr_register(env, SPR_UBAMR, "UBAMR",
5834 &spr_read_ureg, SPR_NOACCESS,
5835 &spr_read_ureg, SPR_NOACCESS,
5836 0x00000000);
a750fc0b
JM
5837 /* Thermal management */
5838 gen_spr_thrm(env);
5839 /* L2PMCR */
5840 /* XXX : not implemented */
5841 spr_register(env, SPR_L2PMCR, "L2PMCR",
5842 SPR_NOACCESS, SPR_NOACCESS,
5843 &spr_read_generic, &spr_write_generic,
5844 0x00000000);
5845 /* LDSTDB */
5846 /* XXX : not implemented */
5847 spr_register(env, SPR_LDSTDB, "LDSTDB",
5848 SPR_NOACCESS, SPR_NOACCESS,
5849 &spr_read_generic, &spr_write_generic,
5850 0x00000000);
5851 /* Memory management */
5852 gen_low_BATs(env);
e1833e1f 5853 init_excp_7400(env);
d63001d1
JM
5854 env->dcache_line_size = 32;
5855 env->icache_line_size = 32;
a750fc0b
JM
5856 /* Allocate hardware IRQ controller */
5857 ppc6xx_irq_init(env);
5858}
5859
7856e3a4
AF
5860POWERPC_FAMILY(7410)(ObjectClass *oc, void *data)
5861{
ca5dff0a 5862 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5863 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5864
ca5dff0a 5865 dc->desc = "PowerPC 7410 (aka G4)";
7856e3a4
AF
5866 pcc->init_proc = init_proc_7410;
5867 pcc->check_pow = check_pow_hid0;
53116ebf
AF
5868 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5869 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5870 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
5871 PPC_FLOAT_STFIWX |
5872 PPC_CACHE | PPC_CACHE_ICBI |
5873 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
5874 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5875 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5876 PPC_MEM_TLBIA |
5877 PPC_SEGMENT | PPC_EXTERN |
5878 PPC_ALTIVEC;
ba9fd9f1
AF
5879 pcc->msr_mask = 0x000000000205FF77ULL;
5880 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
5881#if defined(CONFIG_SOFTMMU)
5882 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5883#endif
ba9fd9f1
AF
5884 pcc->excp_model = POWERPC_EXCP_74xx;
5885 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5886 pcc->bfd_mach = bfd_mach_ppc_7400;
5887 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
5888 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
5889 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5890}
5891
a750fc0b
JM
5892static void init_proc_7440 (CPUPPCState *env)
5893{
5894 gen_spr_ne_601(env);
5895 gen_spr_7xx(env);
5896 /* Time base */
5897 gen_tbl(env);
5898 /* 74xx specific SPR */
5899 gen_spr_74xx(env);
4e777442
JM
5900 /* XXX : not implemented */
5901 spr_register(env, SPR_UBAMR, "UBAMR",
5902 &spr_read_ureg, SPR_NOACCESS,
5903 &spr_read_ureg, SPR_NOACCESS,
5904 0x00000000);
a750fc0b
JM
5905 /* LDSTCR */
5906 /* XXX : not implemented */
5907 spr_register(env, SPR_LDSTCR, "LDSTCR",
5908 SPR_NOACCESS, SPR_NOACCESS,
5909 &spr_read_generic, &spr_write_generic,
5910 0x00000000);
5911 /* ICTRL */
5912 /* XXX : not implemented */
5913 spr_register(env, SPR_ICTRL, "ICTRL",
5914 SPR_NOACCESS, SPR_NOACCESS,
5915 &spr_read_generic, &spr_write_generic,
5916 0x00000000);
5917 /* MSSSR0 */
578bb252 5918 /* XXX : not implemented */
a750fc0b
JM
5919 spr_register(env, SPR_MSSSR0, "MSSSR0",
5920 SPR_NOACCESS, SPR_NOACCESS,
5921 &spr_read_generic, &spr_write_generic,
5922 0x00000000);
5923 /* PMC */
5924 /* XXX : not implemented */
5925 spr_register(env, SPR_PMC5, "PMC5",
5926 SPR_NOACCESS, SPR_NOACCESS,
5927 &spr_read_generic, &spr_write_generic,
5928 0x00000000);
578bb252 5929 /* XXX : not implemented */
a750fc0b
JM
5930 spr_register(env, SPR_UPMC5, "UPMC5",
5931 &spr_read_ureg, SPR_NOACCESS,
5932 &spr_read_ureg, SPR_NOACCESS,
5933 0x00000000);
578bb252 5934 /* XXX : not implemented */
a750fc0b
JM
5935 spr_register(env, SPR_PMC6, "PMC6",
5936 SPR_NOACCESS, SPR_NOACCESS,
5937 &spr_read_generic, &spr_write_generic,
5938 0x00000000);
578bb252 5939 /* XXX : not implemented */
a750fc0b
JM
5940 spr_register(env, SPR_UPMC6, "UPMC6",
5941 &spr_read_ureg, SPR_NOACCESS,
5942 &spr_read_ureg, SPR_NOACCESS,
5943 0x00000000);
5944 /* Memory management */
5945 gen_low_BATs(env);
578bb252 5946 gen_74xx_soft_tlb(env, 128, 2);
1c27f8fb 5947 init_excp_7450(env);
d63001d1
JM
5948 env->dcache_line_size = 32;
5949 env->icache_line_size = 32;
a750fc0b
JM
5950 /* Allocate hardware IRQ controller */
5951 ppc6xx_irq_init(env);
5952}
a750fc0b 5953
7856e3a4
AF
5954POWERPC_FAMILY(7440)(ObjectClass *oc, void *data)
5955{
ca5dff0a 5956 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5957 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5958
ca5dff0a 5959 dc->desc = "PowerPC 7440 (aka G4)";
7856e3a4
AF
5960 pcc->init_proc = init_proc_7440;
5961 pcc->check_pow = check_pow_hid0_74xx;
53116ebf
AF
5962 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5963 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5964 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
5965 PPC_FLOAT_STFIWX |
5966 PPC_CACHE | PPC_CACHE_ICBI |
5967 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
5968 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5969 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5970 PPC_MEM_TLBIA | PPC_74xx_TLB |
5971 PPC_SEGMENT | PPC_EXTERN |
5972 PPC_ALTIVEC;
ba9fd9f1
AF
5973 pcc->msr_mask = 0x000000000205FF77ULL;
5974 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
5975 pcc->excp_model = POWERPC_EXCP_74xx;
5976 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5977 pcc->bfd_mach = bfd_mach_ppc_7400;
5978 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
5979 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
5980 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5981}
5982
a750fc0b
JM
5983static void init_proc_7450 (CPUPPCState *env)
5984{
5985 gen_spr_ne_601(env);
5986 gen_spr_7xx(env);
5987 /* Time base */
5988 gen_tbl(env);
5989 /* 74xx specific SPR */
5990 gen_spr_74xx(env);
5991 /* Level 3 cache control */
5992 gen_l3_ctrl(env);
4e777442
JM
5993 /* L3ITCR1 */
5994 /* XXX : not implemented */
5995 spr_register(env, SPR_L3ITCR1, "L3ITCR1",
5996 SPR_NOACCESS, SPR_NOACCESS,
5997 &spr_read_generic, &spr_write_generic,
5998 0x00000000);
5999 /* L3ITCR2 */
6000 /* XXX : not implemented */
6001 spr_register(env, SPR_L3ITCR2, "L3ITCR2",
6002 SPR_NOACCESS, SPR_NOACCESS,
6003 &spr_read_generic, &spr_write_generic,
6004 0x00000000);
6005 /* L3ITCR3 */
6006 /* XXX : not implemented */
6007 spr_register(env, SPR_L3ITCR3, "L3ITCR3",
6008 SPR_NOACCESS, SPR_NOACCESS,
6009 &spr_read_generic, &spr_write_generic,
6010 0x00000000);
6011 /* L3OHCR */
6012 /* XXX : not implemented */
6013 spr_register(env, SPR_L3OHCR, "L3OHCR",
6014 SPR_NOACCESS, SPR_NOACCESS,
6015 &spr_read_generic, &spr_write_generic,
6016 0x00000000);
6017 /* XXX : not implemented */
6018 spr_register(env, SPR_UBAMR, "UBAMR",
6019 &spr_read_ureg, SPR_NOACCESS,
6020 &spr_read_ureg, SPR_NOACCESS,
6021 0x00000000);
a750fc0b
JM
6022 /* LDSTCR */
6023 /* XXX : not implemented */
6024 spr_register(env, SPR_LDSTCR, "LDSTCR",
6025 SPR_NOACCESS, SPR_NOACCESS,
6026 &spr_read_generic, &spr_write_generic,
6027 0x00000000);
6028 /* ICTRL */
6029 /* XXX : not implemented */
6030 spr_register(env, SPR_ICTRL, "ICTRL",
6031 SPR_NOACCESS, SPR_NOACCESS,
6032 &spr_read_generic, &spr_write_generic,
6033 0x00000000);
6034 /* MSSSR0 */
578bb252 6035 /* XXX : not implemented */
a750fc0b
JM
6036 spr_register(env, SPR_MSSSR0, "MSSSR0",
6037 SPR_NOACCESS, SPR_NOACCESS,
6038 &spr_read_generic, &spr_write_generic,
6039 0x00000000);
6040 /* PMC */
6041 /* XXX : not implemented */
6042 spr_register(env, SPR_PMC5, "PMC5",
6043 SPR_NOACCESS, SPR_NOACCESS,
6044 &spr_read_generic, &spr_write_generic,
6045 0x00000000);
578bb252 6046 /* XXX : not implemented */
a750fc0b
JM
6047 spr_register(env, SPR_UPMC5, "UPMC5",
6048 &spr_read_ureg, SPR_NOACCESS,
6049 &spr_read_ureg, SPR_NOACCESS,
6050 0x00000000);
578bb252 6051 /* XXX : not implemented */
a750fc0b
JM
6052 spr_register(env, SPR_PMC6, "PMC6",
6053 SPR_NOACCESS, SPR_NOACCESS,
6054 &spr_read_generic, &spr_write_generic,
6055 0x00000000);
578bb252 6056 /* XXX : not implemented */
a750fc0b
JM
6057 spr_register(env, SPR_UPMC6, "UPMC6",
6058 &spr_read_ureg, SPR_NOACCESS,
6059 &spr_read_ureg, SPR_NOACCESS,
6060 0x00000000);
6061 /* Memory management */
6062 gen_low_BATs(env);
578bb252 6063 gen_74xx_soft_tlb(env, 128, 2);
e1833e1f 6064 init_excp_7450(env);
d63001d1
JM
6065 env->dcache_line_size = 32;
6066 env->icache_line_size = 32;
a750fc0b
JM
6067 /* Allocate hardware IRQ controller */
6068 ppc6xx_irq_init(env);
6069}
a750fc0b 6070
7856e3a4
AF
6071POWERPC_FAMILY(7450)(ObjectClass *oc, void *data)
6072{
ca5dff0a 6073 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6074 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6075
ca5dff0a 6076 dc->desc = "PowerPC 7450 (aka G4)";
7856e3a4
AF
6077 pcc->init_proc = init_proc_7450;
6078 pcc->check_pow = check_pow_hid0_74xx;
53116ebf
AF
6079 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6080 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6081 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6082 PPC_FLOAT_STFIWX |
6083 PPC_CACHE | PPC_CACHE_ICBI |
6084 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6085 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6086 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6087 PPC_MEM_TLBIA | PPC_74xx_TLB |
6088 PPC_SEGMENT | PPC_EXTERN |
6089 PPC_ALTIVEC;
ba9fd9f1
AF
6090 pcc->msr_mask = 0x000000000205FF77ULL;
6091 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
6092 pcc->excp_model = POWERPC_EXCP_74xx;
6093 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6094 pcc->bfd_mach = bfd_mach_ppc_7400;
6095 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6096 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6097 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6098}
6099
a750fc0b
JM
6100static void init_proc_7445 (CPUPPCState *env)
6101{
6102 gen_spr_ne_601(env);
6103 gen_spr_7xx(env);
6104 /* Time base */
6105 gen_tbl(env);
6106 /* 74xx specific SPR */
6107 gen_spr_74xx(env);
6108 /* LDSTCR */
6109 /* XXX : not implemented */
6110 spr_register(env, SPR_LDSTCR, "LDSTCR",
6111 SPR_NOACCESS, SPR_NOACCESS,
6112 &spr_read_generic, &spr_write_generic,
6113 0x00000000);
6114 /* ICTRL */
6115 /* XXX : not implemented */
6116 spr_register(env, SPR_ICTRL, "ICTRL",
6117 SPR_NOACCESS, SPR_NOACCESS,
6118 &spr_read_generic, &spr_write_generic,
6119 0x00000000);
6120 /* MSSSR0 */
578bb252 6121 /* XXX : not implemented */
a750fc0b
JM
6122 spr_register(env, SPR_MSSSR0, "MSSSR0",
6123 SPR_NOACCESS, SPR_NOACCESS,
6124 &spr_read_generic, &spr_write_generic,
6125 0x00000000);
6126 /* PMC */
6127 /* XXX : not implemented */
6128 spr_register(env, SPR_PMC5, "PMC5",
6129 SPR_NOACCESS, SPR_NOACCESS,
6130 &spr_read_generic, &spr_write_generic,
6131 0x00000000);
578bb252 6132 /* XXX : not implemented */
a750fc0b
JM
6133 spr_register(env, SPR_UPMC5, "UPMC5",
6134 &spr_read_ureg, SPR_NOACCESS,
6135 &spr_read_ureg, SPR_NOACCESS,
6136 0x00000000);
578bb252 6137 /* XXX : not implemented */
a750fc0b
JM
6138 spr_register(env, SPR_PMC6, "PMC6",
6139 SPR_NOACCESS, SPR_NOACCESS,
6140 &spr_read_generic, &spr_write_generic,
6141 0x00000000);
578bb252 6142 /* XXX : not implemented */
a750fc0b
JM
6143 spr_register(env, SPR_UPMC6, "UPMC6",
6144 &spr_read_ureg, SPR_NOACCESS,
6145 &spr_read_ureg, SPR_NOACCESS,
6146 0x00000000);
6147 /* SPRGs */
6148 spr_register(env, SPR_SPRG4, "SPRG4",
6149 SPR_NOACCESS, SPR_NOACCESS,
6150 &spr_read_generic, &spr_write_generic,
6151 0x00000000);
6152 spr_register(env, SPR_USPRG4, "USPRG4",
6153 &spr_read_ureg, SPR_NOACCESS,
6154 &spr_read_ureg, SPR_NOACCESS,
6155 0x00000000);
6156 spr_register(env, SPR_SPRG5, "SPRG5",
6157 SPR_NOACCESS, SPR_NOACCESS,
6158 &spr_read_generic, &spr_write_generic,
6159 0x00000000);
6160 spr_register(env, SPR_USPRG5, "USPRG5",
6161 &spr_read_ureg, SPR_NOACCESS,
6162 &spr_read_ureg, SPR_NOACCESS,
6163 0x00000000);
6164 spr_register(env, SPR_SPRG6, "SPRG6",
6165 SPR_NOACCESS, SPR_NOACCESS,
6166 &spr_read_generic, &spr_write_generic,
6167 0x00000000);
6168 spr_register(env, SPR_USPRG6, "USPRG6",
6169 &spr_read_ureg, SPR_NOACCESS,
6170 &spr_read_ureg, SPR_NOACCESS,
6171 0x00000000);
6172 spr_register(env, SPR_SPRG7, "SPRG7",
6173 SPR_NOACCESS, SPR_NOACCESS,
6174 &spr_read_generic, &spr_write_generic,
6175 0x00000000);
6176 spr_register(env, SPR_USPRG7, "USPRG7",
6177 &spr_read_ureg, SPR_NOACCESS,
6178 &spr_read_ureg, SPR_NOACCESS,
6179 0x00000000);
6180 /* Memory management */
6181 gen_low_BATs(env);
6182 gen_high_BATs(env);
578bb252 6183 gen_74xx_soft_tlb(env, 128, 2);
e1833e1f 6184 init_excp_7450(env);
d63001d1
JM
6185 env->dcache_line_size = 32;
6186 env->icache_line_size = 32;
a750fc0b
JM
6187 /* Allocate hardware IRQ controller */
6188 ppc6xx_irq_init(env);
6189}
a750fc0b 6190
7856e3a4
AF
6191POWERPC_FAMILY(7445)(ObjectClass *oc, void *data)
6192{
ca5dff0a 6193 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6194 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6195
ca5dff0a 6196 dc->desc = "PowerPC 7445 (aka G4)";
7856e3a4
AF
6197 pcc->init_proc = init_proc_7445;
6198 pcc->check_pow = check_pow_hid0_74xx;
53116ebf
AF
6199 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6200 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6201 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6202 PPC_FLOAT_STFIWX |
6203 PPC_CACHE | PPC_CACHE_ICBI |
6204 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6205 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6206 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6207 PPC_MEM_TLBIA | PPC_74xx_TLB |
6208 PPC_SEGMENT | PPC_EXTERN |
6209 PPC_ALTIVEC;
ba9fd9f1
AF
6210 pcc->msr_mask = 0x000000000205FF77ULL;
6211 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
6212 pcc->excp_model = POWERPC_EXCP_74xx;
6213 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6214 pcc->bfd_mach = bfd_mach_ppc_7400;
6215 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6216 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6217 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6218}
6219
a750fc0b
JM
6220static void init_proc_7455 (CPUPPCState *env)
6221{
6222 gen_spr_ne_601(env);
6223 gen_spr_7xx(env);
6224 /* Time base */
6225 gen_tbl(env);
6226 /* 74xx specific SPR */
6227 gen_spr_74xx(env);
6228 /* Level 3 cache control */
6229 gen_l3_ctrl(env);
6230 /* LDSTCR */
6231 /* XXX : not implemented */
6232 spr_register(env, SPR_LDSTCR, "LDSTCR",
6233 SPR_NOACCESS, SPR_NOACCESS,
6234 &spr_read_generic, &spr_write_generic,
6235 0x00000000);
6236 /* ICTRL */
6237 /* XXX : not implemented */
6238 spr_register(env, SPR_ICTRL, "ICTRL",
6239 SPR_NOACCESS, SPR_NOACCESS,
6240 &spr_read_generic, &spr_write_generic,
6241 0x00000000);
6242 /* MSSSR0 */
578bb252 6243 /* XXX : not implemented */
a750fc0b
JM
6244 spr_register(env, SPR_MSSSR0, "MSSSR0",
6245 SPR_NOACCESS, SPR_NOACCESS,
6246 &spr_read_generic, &spr_write_generic,
6247 0x00000000);
6248 /* PMC */
6249 /* XXX : not implemented */
6250 spr_register(env, SPR_PMC5, "PMC5",
6251 SPR_NOACCESS, SPR_NOACCESS,
6252 &spr_read_generic, &spr_write_generic,
6253 0x00000000);
578bb252 6254 /* XXX : not implemented */
a750fc0b
JM
6255 spr_register(env, SPR_UPMC5, "UPMC5",
6256 &spr_read_ureg, SPR_NOACCESS,
6257 &spr_read_ureg, SPR_NOACCESS,
6258 0x00000000);
578bb252 6259 /* XXX : not implemented */
a750fc0b
JM
6260 spr_register(env, SPR_PMC6, "PMC6",
6261 SPR_NOACCESS, SPR_NOACCESS,
6262 &spr_read_generic, &spr_write_generic,
6263 0x00000000);
578bb252 6264 /* XXX : not implemented */
a750fc0b
JM
6265 spr_register(env, SPR_UPMC6, "UPMC6",
6266 &spr_read_ureg, SPR_NOACCESS,
6267 &spr_read_ureg, SPR_NOACCESS,
6268 0x00000000);
6269 /* SPRGs */
6270 spr_register(env, SPR_SPRG4, "SPRG4",
6271 SPR_NOACCESS, SPR_NOACCESS,
6272 &spr_read_generic, &spr_write_generic,
6273 0x00000000);
6274 spr_register(env, SPR_USPRG4, "USPRG4",
6275 &spr_read_ureg, SPR_NOACCESS,
6276 &spr_read_ureg, SPR_NOACCESS,
6277 0x00000000);
6278 spr_register(env, SPR_SPRG5, "SPRG5",
6279 SPR_NOACCESS, SPR_NOACCESS,
6280 &spr_read_generic, &spr_write_generic,
6281 0x00000000);
6282 spr_register(env, SPR_USPRG5, "USPRG5",
6283 &spr_read_ureg, SPR_NOACCESS,
6284 &spr_read_ureg, SPR_NOACCESS,
6285 0x00000000);
6286 spr_register(env, SPR_SPRG6, "SPRG6",
6287 SPR_NOACCESS, SPR_NOACCESS,
6288 &spr_read_generic, &spr_write_generic,
6289 0x00000000);
6290 spr_register(env, SPR_USPRG6, "USPRG6",
6291 &spr_read_ureg, SPR_NOACCESS,
6292 &spr_read_ureg, SPR_NOACCESS,
6293 0x00000000);
6294 spr_register(env, SPR_SPRG7, "SPRG7",
6295 SPR_NOACCESS, SPR_NOACCESS,
6296 &spr_read_generic, &spr_write_generic,
6297 0x00000000);
6298 spr_register(env, SPR_USPRG7, "USPRG7",
6299 &spr_read_ureg, SPR_NOACCESS,
6300 &spr_read_ureg, SPR_NOACCESS,
6301 0x00000000);
6302 /* Memory management */
6303 gen_low_BATs(env);
6304 gen_high_BATs(env);
578bb252 6305 gen_74xx_soft_tlb(env, 128, 2);
e1833e1f 6306 init_excp_7450(env);
d63001d1
JM
6307 env->dcache_line_size = 32;
6308 env->icache_line_size = 32;
a750fc0b
JM
6309 /* Allocate hardware IRQ controller */
6310 ppc6xx_irq_init(env);
6311}
a750fc0b 6312
7856e3a4
AF
6313POWERPC_FAMILY(7455)(ObjectClass *oc, void *data)
6314{
ca5dff0a 6315 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6316 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6317
ca5dff0a 6318 dc->desc = "PowerPC 7455 (aka G4)";
7856e3a4
AF
6319 pcc->init_proc = init_proc_7455;
6320 pcc->check_pow = check_pow_hid0_74xx;
53116ebf
AF
6321 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6322 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6323 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6324 PPC_FLOAT_STFIWX |
6325 PPC_CACHE | PPC_CACHE_ICBI |
6326 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6327 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6328 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6329 PPC_MEM_TLBIA | PPC_74xx_TLB |
6330 PPC_SEGMENT | PPC_EXTERN |
6331 PPC_ALTIVEC;
ba9fd9f1
AF
6332 pcc->msr_mask = 0x000000000205FF77ULL;
6333 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
6334 pcc->excp_model = POWERPC_EXCP_74xx;
6335 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6336 pcc->bfd_mach = bfd_mach_ppc_7400;
6337 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6338 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6339 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6340}
6341
4e777442
JM
6342static void init_proc_7457 (CPUPPCState *env)
6343{
6344 gen_spr_ne_601(env);
6345 gen_spr_7xx(env);
6346 /* Time base */
6347 gen_tbl(env);
6348 /* 74xx specific SPR */
6349 gen_spr_74xx(env);
6350 /* Level 3 cache control */
6351 gen_l3_ctrl(env);
6352 /* L3ITCR1 */
6353 /* XXX : not implemented */
6354 spr_register(env, SPR_L3ITCR1, "L3ITCR1",
6355 SPR_NOACCESS, SPR_NOACCESS,
6356 &spr_read_generic, &spr_write_generic,
6357 0x00000000);
6358 /* L3ITCR2 */
6359 /* XXX : not implemented */
6360 spr_register(env, SPR_L3ITCR2, "L3ITCR2",
6361 SPR_NOACCESS, SPR_NOACCESS,
6362 &spr_read_generic, &spr_write_generic,
6363 0x00000000);
6364 /* L3ITCR3 */
6365 /* XXX : not implemented */
6366 spr_register(env, SPR_L3ITCR3, "L3ITCR3",
6367 SPR_NOACCESS, SPR_NOACCESS,
6368 &spr_read_generic, &spr_write_generic,
6369 0x00000000);
6370 /* L3OHCR */
6371 /* XXX : not implemented */
6372 spr_register(env, SPR_L3OHCR, "L3OHCR",
6373 SPR_NOACCESS, SPR_NOACCESS,
6374 &spr_read_generic, &spr_write_generic,
6375 0x00000000);
6376 /* LDSTCR */
6377 /* XXX : not implemented */
6378 spr_register(env, SPR_LDSTCR, "LDSTCR",
6379 SPR_NOACCESS, SPR_NOACCESS,
6380 &spr_read_generic, &spr_write_generic,
6381 0x00000000);
6382 /* ICTRL */
6383 /* XXX : not implemented */
6384 spr_register(env, SPR_ICTRL, "ICTRL",
6385 SPR_NOACCESS, SPR_NOACCESS,
6386 &spr_read_generic, &spr_write_generic,
6387 0x00000000);
6388 /* MSSSR0 */
6389 /* XXX : not implemented */
6390 spr_register(env, SPR_MSSSR0, "MSSSR0",
6391 SPR_NOACCESS, SPR_NOACCESS,
6392 &spr_read_generic, &spr_write_generic,
6393 0x00000000);
6394 /* PMC */
6395 /* XXX : not implemented */
6396 spr_register(env, SPR_PMC5, "PMC5",
6397 SPR_NOACCESS, SPR_NOACCESS,
6398 &spr_read_generic, &spr_write_generic,
6399 0x00000000);
6400 /* XXX : not implemented */
6401 spr_register(env, SPR_UPMC5, "UPMC5",
6402 &spr_read_ureg, SPR_NOACCESS,
6403 &spr_read_ureg, SPR_NOACCESS,
6404 0x00000000);
6405 /* XXX : not implemented */
6406 spr_register(env, SPR_PMC6, "PMC6",
6407 SPR_NOACCESS, SPR_NOACCESS,
6408 &spr_read_generic, &spr_write_generic,
6409 0x00000000);
6410 /* XXX : not implemented */
6411 spr_register(env, SPR_UPMC6, "UPMC6",
6412 &spr_read_ureg, SPR_NOACCESS,
6413 &spr_read_ureg, SPR_NOACCESS,
6414 0x00000000);
6415 /* SPRGs */
6416 spr_register(env, SPR_SPRG4, "SPRG4",
6417 SPR_NOACCESS, SPR_NOACCESS,
6418 &spr_read_generic, &spr_write_generic,
6419 0x00000000);
6420 spr_register(env, SPR_USPRG4, "USPRG4",
6421 &spr_read_ureg, SPR_NOACCESS,
6422 &spr_read_ureg, SPR_NOACCESS,
6423 0x00000000);
6424 spr_register(env, SPR_SPRG5, "SPRG5",
6425 SPR_NOACCESS, SPR_NOACCESS,
6426 &spr_read_generic, &spr_write_generic,
6427 0x00000000);
6428 spr_register(env, SPR_USPRG5, "USPRG5",
6429 &spr_read_ureg, SPR_NOACCESS,
6430 &spr_read_ureg, SPR_NOACCESS,
6431 0x00000000);
6432 spr_register(env, SPR_SPRG6, "SPRG6",
6433 SPR_NOACCESS, SPR_NOACCESS,
6434 &spr_read_generic, &spr_write_generic,
6435 0x00000000);
6436 spr_register(env, SPR_USPRG6, "USPRG6",
6437 &spr_read_ureg, SPR_NOACCESS,
6438 &spr_read_ureg, SPR_NOACCESS,
6439 0x00000000);
6440 spr_register(env, SPR_SPRG7, "SPRG7",
6441 SPR_NOACCESS, SPR_NOACCESS,
6442 &spr_read_generic, &spr_write_generic,
6443 0x00000000);
6444 spr_register(env, SPR_USPRG7, "USPRG7",
6445 &spr_read_ureg, SPR_NOACCESS,
6446 &spr_read_ureg, SPR_NOACCESS,
6447 0x00000000);
6448 /* Memory management */
6449 gen_low_BATs(env);
6450 gen_high_BATs(env);
6451 gen_74xx_soft_tlb(env, 128, 2);
6452 init_excp_7450(env);
6453 env->dcache_line_size = 32;
6454 env->icache_line_size = 32;
6455 /* Allocate hardware IRQ controller */
6456 ppc6xx_irq_init(env);
6457}
6458
7856e3a4
AF
6459POWERPC_FAMILY(7457)(ObjectClass *oc, void *data)
6460{
ca5dff0a 6461 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6462 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6463
ca5dff0a 6464 dc->desc = "PowerPC 7457 (aka G4)";
7856e3a4
AF
6465 pcc->init_proc = init_proc_7457;
6466 pcc->check_pow = check_pow_hid0_74xx;
53116ebf
AF
6467 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6468 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6469 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6470 PPC_FLOAT_STFIWX |
6471 PPC_CACHE | PPC_CACHE_ICBI |
6472 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6473 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6474 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6475 PPC_MEM_TLBIA | PPC_74xx_TLB |
6476 PPC_SEGMENT | PPC_EXTERN |
6477 PPC_ALTIVEC;
ba9fd9f1
AF
6478 pcc->msr_mask = 0x000000000205FF77ULL;
6479 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
6480 pcc->excp_model = POWERPC_EXCP_74xx;
6481 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6482 pcc->bfd_mach = bfd_mach_ppc_7400;
6483 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6484 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6485 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6486}
6487
7162bdea
JG
6488static void init_proc_e600 (CPUPPCState *env)
6489{
6490 gen_spr_ne_601(env);
6491 gen_spr_7xx(env);
6492 /* Time base */
6493 gen_tbl(env);
6494 /* 74xx specific SPR */
6495 gen_spr_74xx(env);
6496 /* XXX : not implemented */
6497 spr_register(env, SPR_UBAMR, "UBAMR",
6498 &spr_read_ureg, SPR_NOACCESS,
6499 &spr_read_ureg, SPR_NOACCESS,
6500 0x00000000);
6501 /* XXX : not implemented */
6502 spr_register(env, SPR_LDSTCR, "LDSTCR",
6503 SPR_NOACCESS, SPR_NOACCESS,
6504 &spr_read_generic, &spr_write_generic,
6505 0x00000000);
6506 /* XXX : not implemented */
6507 spr_register(env, SPR_ICTRL, "ICTRL",
6508 SPR_NOACCESS, SPR_NOACCESS,
6509 &spr_read_generic, &spr_write_generic,
6510 0x00000000);
6511 /* XXX : not implemented */
6512 spr_register(env, SPR_MSSSR0, "MSSSR0",
6513 SPR_NOACCESS, SPR_NOACCESS,
6514 &spr_read_generic, &spr_write_generic,
6515 0x00000000);
6516 /* XXX : not implemented */
6517 spr_register(env, SPR_PMC5, "PMC5",
6518 SPR_NOACCESS, SPR_NOACCESS,
6519 &spr_read_generic, &spr_write_generic,
6520 0x00000000);
6521 /* XXX : not implemented */
6522 spr_register(env, SPR_UPMC5, "UPMC5",
6523 &spr_read_ureg, SPR_NOACCESS,
6524 &spr_read_ureg, SPR_NOACCESS,
6525 0x00000000);
6526 /* XXX : not implemented */
6527 spr_register(env, SPR_PMC6, "PMC6",
6528 SPR_NOACCESS, SPR_NOACCESS,
6529 &spr_read_generic, &spr_write_generic,
6530 0x00000000);
6531 /* XXX : not implemented */
6532 spr_register(env, SPR_UPMC6, "UPMC6",
6533 &spr_read_ureg, SPR_NOACCESS,
6534 &spr_read_ureg, SPR_NOACCESS,
6535 0x00000000);
6536 /* SPRGs */
6537 spr_register(env, SPR_SPRG4, "SPRG4",
6538 SPR_NOACCESS, SPR_NOACCESS,
6539 &spr_read_generic, &spr_write_generic,
6540 0x00000000);
6541 spr_register(env, SPR_USPRG4, "USPRG4",
6542 &spr_read_ureg, SPR_NOACCESS,
6543 &spr_read_ureg, SPR_NOACCESS,
6544 0x00000000);
6545 spr_register(env, SPR_SPRG5, "SPRG5",
6546 SPR_NOACCESS, SPR_NOACCESS,
6547 &spr_read_generic, &spr_write_generic,
6548 0x00000000);
6549 spr_register(env, SPR_USPRG5, "USPRG5",
6550 &spr_read_ureg, SPR_NOACCESS,
6551 &spr_read_ureg, SPR_NOACCESS,
6552 0x00000000);
6553 spr_register(env, SPR_SPRG6, "SPRG6",
6554 SPR_NOACCESS, SPR_NOACCESS,
6555 &spr_read_generic, &spr_write_generic,
6556 0x00000000);
6557 spr_register(env, SPR_USPRG6, "USPRG6",
6558 &spr_read_ureg, SPR_NOACCESS,
6559 &spr_read_ureg, SPR_NOACCESS,
6560 0x00000000);
6561 spr_register(env, SPR_SPRG7, "SPRG7",
6562 SPR_NOACCESS, SPR_NOACCESS,
6563 &spr_read_generic, &spr_write_generic,
6564 0x00000000);
6565 spr_register(env, SPR_USPRG7, "USPRG7",
6566 &spr_read_ureg, SPR_NOACCESS,
6567 &spr_read_ureg, SPR_NOACCESS,
6568 0x00000000);
6569 /* Memory management */
6570 gen_low_BATs(env);
6571 gen_high_BATs(env);
6572 gen_74xx_soft_tlb(env, 128, 2);
6573 init_excp_7450(env);
6574 env->dcache_line_size = 32;
6575 env->icache_line_size = 32;
6576 /* Allocate hardware IRQ controller */
6577 ppc6xx_irq_init(env);
6578}
6579
6580POWERPC_FAMILY(e600)(ObjectClass *oc, void *data)
6581{
6582 DeviceClass *dc = DEVICE_CLASS(oc);
6583 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6584
6585 dc->desc = "PowerPC e600";
6586 pcc->init_proc = init_proc_e600;
6587 pcc->check_pow = check_pow_hid0_74xx;
6588 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6589 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6590 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6591 PPC_FLOAT_STFIWX |
6592 PPC_CACHE | PPC_CACHE_ICBI |
6593 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6594 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6595 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6596 PPC_MEM_TLBIA | PPC_74xx_TLB |
6597 PPC_SEGMENT | PPC_EXTERN |
6598 PPC_ALTIVEC;
6599 pcc->insns_flags2 = PPC_NONE;
6600 pcc->msr_mask = 0x000000000205FF77ULL;
6601 pcc->mmu_model = POWERPC_MMU_32B;
6602#if defined(CONFIG_SOFTMMU)
6603 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6604#endif
6605 pcc->excp_model = POWERPC_EXCP_74xx;
6606 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6607 pcc->bfd_mach = bfd_mach_ppc_7400;
6608 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6609 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6610 POWERPC_FLAG_BUS_CLK;
6611}
6612
a750fc0b 6613#if defined (TARGET_PPC64)
417bf010
JM
6614#if defined(CONFIG_USER_ONLY)
6615#define POWERPC970_HID5_INIT 0x00000080
6616#else
6617#define POWERPC970_HID5_INIT 0x00000000
6618#endif
6619
2f462816
JM
6620static int check_pow_970 (CPUPPCState *env)
6621{
6622 if (env->spr[SPR_HID0] & 0x00600000)
6623 return 1;
6624
6625 return 0;
6626}
6627
a750fc0b
JM
6628static void init_proc_970 (CPUPPCState *env)
6629{
6630 gen_spr_ne_601(env);
6631 gen_spr_7xx(env);
6632 /* Time base */
6633 gen_tbl(env);
6634 /* Hardware implementation registers */
6635 /* XXX : not implemented */
6636 spr_register(env, SPR_HID0, "HID0",
6637 SPR_NOACCESS, SPR_NOACCESS,
06403421 6638 &spr_read_generic, &spr_write_clear,
d63001d1 6639 0x60000000);
a750fc0b
JM
6640 /* XXX : not implemented */
6641 spr_register(env, SPR_HID1, "HID1",
6642 SPR_NOACCESS, SPR_NOACCESS,
6643 &spr_read_generic, &spr_write_generic,
6644 0x00000000);
6645 /* XXX : not implemented */
bd928eba 6646 spr_register(env, SPR_750FX_HID2, "HID2",
a750fc0b
JM
6647 SPR_NOACCESS, SPR_NOACCESS,
6648 &spr_read_generic, &spr_write_generic,
6649 0x00000000);
e57448f1
JM
6650 /* XXX : not implemented */
6651 spr_register(env, SPR_970_HID5, "HID5",
6652 SPR_NOACCESS, SPR_NOACCESS,
6653 &spr_read_generic, &spr_write_generic,
417bf010 6654 POWERPC970_HID5_INIT);
bd928eba
JM
6655 /* XXX : not implemented */
6656 spr_register(env, SPR_L2CR, "L2CR",
6657 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 6658 &spr_read_generic, spr_access_nop,
bd928eba 6659 0x00000000);
a750fc0b
JM
6660 /* Memory management */
6661 /* XXX: not correct */
6662 gen_low_BATs(env);
12de9a39
JM
6663 /* XXX : not implemented */
6664 spr_register(env, SPR_MMUCFG, "MMUCFG",
6665 SPR_NOACCESS, SPR_NOACCESS,
6666 &spr_read_generic, SPR_NOACCESS,
6667 0x00000000); /* TOFIX */
6668 /* XXX : not implemented */
6669 spr_register(env, SPR_MMUCSR0, "MMUCSR0",
6670 SPR_NOACCESS, SPR_NOACCESS,
6671 &spr_read_generic, &spr_write_generic,
6672 0x00000000); /* TOFIX */
6673 spr_register(env, SPR_HIOR, "SPR_HIOR",
6674 SPR_NOACCESS, SPR_NOACCESS,
2adab7d6
BS
6675 &spr_read_hior, &spr_write_hior,
6676 0x00000000);
f2e63a42 6677#if !defined(CONFIG_USER_ONLY)
12de9a39 6678 env->slb_nr = 32;
f2e63a42 6679#endif
e1833e1f 6680 init_excp_970(env);
d63001d1
JM
6681 env->dcache_line_size = 128;
6682 env->icache_line_size = 128;
a750fc0b
JM
6683 /* Allocate hardware IRQ controller */
6684 ppc970_irq_init(env);
cf8358c8
AJ
6685 /* Can't find information on what this should be on reset. This
6686 * value is the one used by 74xx processors. */
6687 vscr_init(env, 0x00010000);
a750fc0b 6688}
a750fc0b 6689
7856e3a4
AF
6690POWERPC_FAMILY(970)(ObjectClass *oc, void *data)
6691{
ca5dff0a 6692 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6693 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6694
ca5dff0a 6695 dc->desc = "PowerPC 970";
7856e3a4
AF
6696 pcc->init_proc = init_proc_970;
6697 pcc->check_pow = check_pow_970;
53116ebf
AF
6698 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6699 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6700 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6701 PPC_FLOAT_STFIWX |
6702 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6703 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6704 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6705 PPC_64B | PPC_ALTIVEC |
6706 PPC_SEGMENT_64B | PPC_SLBI;
ba9fd9f1
AF
6707 pcc->msr_mask = 0x900000000204FF36ULL;
6708 pcc->mmu_model = POWERPC_MMU_64B;
b632a148
DG
6709#if defined(CONFIG_SOFTMMU)
6710 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
6711#endif
ba9fd9f1
AF
6712 pcc->excp_model = POWERPC_EXCP_970;
6713 pcc->bus_model = PPC_FLAGS_INPUT_970;
6714 pcc->bfd_mach = bfd_mach_ppc64;
6715 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6716 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6717 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6718}
6719
2f462816
JM
6720static int check_pow_970FX (CPUPPCState *env)
6721{
6722 if (env->spr[SPR_HID0] & 0x00600000)
6723 return 1;
6724
6725 return 0;
6726}
6727
a750fc0b
JM
6728static void init_proc_970FX (CPUPPCState *env)
6729{
6730 gen_spr_ne_601(env);
6731 gen_spr_7xx(env);
6732 /* Time base */
6733 gen_tbl(env);
6734 /* Hardware implementation registers */
6735 /* XXX : not implemented */
6736 spr_register(env, SPR_HID0, "HID0",
6737 SPR_NOACCESS, SPR_NOACCESS,
06403421 6738 &spr_read_generic, &spr_write_clear,
d63001d1 6739 0x60000000);
a750fc0b
JM
6740 /* XXX : not implemented */
6741 spr_register(env, SPR_HID1, "HID1",
6742 SPR_NOACCESS, SPR_NOACCESS,
6743 &spr_read_generic, &spr_write_generic,
6744 0x00000000);
6745 /* XXX : not implemented */
bd928eba 6746 spr_register(env, SPR_750FX_HID2, "HID2",
a750fc0b
JM
6747 SPR_NOACCESS, SPR_NOACCESS,
6748 &spr_read_generic, &spr_write_generic,
6749 0x00000000);
d63001d1
JM
6750 /* XXX : not implemented */
6751 spr_register(env, SPR_970_HID5, "HID5",
6752 SPR_NOACCESS, SPR_NOACCESS,
6753 &spr_read_generic, &spr_write_generic,
417bf010 6754 POWERPC970_HID5_INIT);
bd928eba
JM
6755 /* XXX : not implemented */
6756 spr_register(env, SPR_L2CR, "L2CR",
6757 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 6758 &spr_read_generic, spr_access_nop,
bd928eba 6759 0x00000000);
a750fc0b
JM
6760 /* Memory management */
6761 /* XXX: not correct */
6762 gen_low_BATs(env);
12de9a39
JM
6763 /* XXX : not implemented */
6764 spr_register(env, SPR_MMUCFG, "MMUCFG",
6765 SPR_NOACCESS, SPR_NOACCESS,
6766 &spr_read_generic, SPR_NOACCESS,
6767 0x00000000); /* TOFIX */
6768 /* XXX : not implemented */
6769 spr_register(env, SPR_MMUCSR0, "MMUCSR0",
6770 SPR_NOACCESS, SPR_NOACCESS,
6771 &spr_read_generic, &spr_write_generic,
6772 0x00000000); /* TOFIX */
6773 spr_register(env, SPR_HIOR, "SPR_HIOR",
6774 SPR_NOACCESS, SPR_NOACCESS,
2adab7d6
BS
6775 &spr_read_hior, &spr_write_hior,
6776 0x00000000);
4e98d8cf
BS
6777 spr_register(env, SPR_CTRL, "SPR_CTRL",
6778 SPR_NOACCESS, SPR_NOACCESS,
6779 &spr_read_generic, &spr_write_generic,
6780 0x00000000);
6781 spr_register(env, SPR_UCTRL, "SPR_UCTRL",
6782 SPR_NOACCESS, SPR_NOACCESS,
6783 &spr_read_generic, &spr_write_generic,
6784 0x00000000);
6785 spr_register(env, SPR_VRSAVE, "SPR_VRSAVE",
6786 &spr_read_generic, &spr_write_generic,
6787 &spr_read_generic, &spr_write_generic,
6788 0x00000000);
f2e63a42 6789#if !defined(CONFIG_USER_ONLY)
8eee0af9 6790 env->slb_nr = 64;
f2e63a42 6791#endif
e1833e1f 6792 init_excp_970(env);
d63001d1
JM
6793 env->dcache_line_size = 128;
6794 env->icache_line_size = 128;
a750fc0b
JM
6795 /* Allocate hardware IRQ controller */
6796 ppc970_irq_init(env);
cf8358c8
AJ
6797 /* Can't find information on what this should be on reset. This
6798 * value is the one used by 74xx processors. */
6799 vscr_init(env, 0x00010000);
a750fc0b 6800}
a750fc0b 6801
7856e3a4
AF
6802POWERPC_FAMILY(970FX)(ObjectClass *oc, void *data)
6803{
ca5dff0a 6804 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6805 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6806
ca5dff0a 6807 dc->desc = "PowerPC 970FX (aka G5)";
7856e3a4
AF
6808 pcc->init_proc = init_proc_970FX;
6809 pcc->check_pow = check_pow_970FX;
53116ebf
AF
6810 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6811 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6812 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6813 PPC_FLOAT_STFIWX |
6814 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6815 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6816 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6817 PPC_64B | PPC_ALTIVEC |
6818 PPC_SEGMENT_64B | PPC_SLBI;
ba9fd9f1
AF
6819 pcc->msr_mask = 0x800000000204FF36ULL;
6820 pcc->mmu_model = POWERPC_MMU_64B;
b632a148
DG
6821#if defined(CONFIG_SOFTMMU)
6822 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
6823#endif
ba9fd9f1
AF
6824 pcc->excp_model = POWERPC_EXCP_970;
6825 pcc->bus_model = PPC_FLAGS_INPUT_970;
6826 pcc->bfd_mach = bfd_mach_ppc64;
6827 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6828 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6829 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6830}
6831
2f462816
JM
6832static int check_pow_970GX (CPUPPCState *env)
6833{
6834 if (env->spr[SPR_HID0] & 0x00600000)
6835 return 1;
6836
6837 return 0;
6838}
6839
a750fc0b
JM
6840static void init_proc_970GX (CPUPPCState *env)
6841{
6842 gen_spr_ne_601(env);
6843 gen_spr_7xx(env);
6844 /* Time base */
6845 gen_tbl(env);
6846 /* Hardware implementation registers */
6847 /* XXX : not implemented */
6848 spr_register(env, SPR_HID0, "HID0",
6849 SPR_NOACCESS, SPR_NOACCESS,
06403421 6850 &spr_read_generic, &spr_write_clear,
d63001d1 6851 0x60000000);
a750fc0b
JM
6852 /* XXX : not implemented */
6853 spr_register(env, SPR_HID1, "HID1",
6854 SPR_NOACCESS, SPR_NOACCESS,
6855 &spr_read_generic, &spr_write_generic,
6856 0x00000000);
6857 /* XXX : not implemented */
bd928eba 6858 spr_register(env, SPR_750FX_HID2, "HID2",
a750fc0b
JM
6859 SPR_NOACCESS, SPR_NOACCESS,
6860 &spr_read_generic, &spr_write_generic,
6861 0x00000000);
d63001d1
JM
6862 /* XXX : not implemented */
6863 spr_register(env, SPR_970_HID5, "HID5",
6864 SPR_NOACCESS, SPR_NOACCESS,
6865 &spr_read_generic, &spr_write_generic,
417bf010 6866 POWERPC970_HID5_INIT);
bd928eba
JM
6867 /* XXX : not implemented */
6868 spr_register(env, SPR_L2CR, "L2CR",
6869 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 6870 &spr_read_generic, spr_access_nop,
bd928eba 6871 0x00000000);
a750fc0b
JM
6872 /* Memory management */
6873 /* XXX: not correct */
6874 gen_low_BATs(env);
12de9a39
JM
6875 /* XXX : not implemented */
6876 spr_register(env, SPR_MMUCFG, "MMUCFG",
6877 SPR_NOACCESS, SPR_NOACCESS,
6878 &spr_read_generic, SPR_NOACCESS,
6879 0x00000000); /* TOFIX */
6880 /* XXX : not implemented */
6881 spr_register(env, SPR_MMUCSR0, "MMUCSR0",
6882 SPR_NOACCESS, SPR_NOACCESS,
6883 &spr_read_generic, &spr_write_generic,
6884 0x00000000); /* TOFIX */
6885 spr_register(env, SPR_HIOR, "SPR_HIOR",
6886 SPR_NOACCESS, SPR_NOACCESS,
2adab7d6
BS
6887 &spr_read_hior, &spr_write_hior,
6888 0x00000000);
f2e63a42 6889#if !defined(CONFIG_USER_ONLY)
12de9a39 6890 env->slb_nr = 32;
f2e63a42 6891#endif
e1833e1f 6892 init_excp_970(env);
d63001d1
JM
6893 env->dcache_line_size = 128;
6894 env->icache_line_size = 128;
a750fc0b
JM
6895 /* Allocate hardware IRQ controller */
6896 ppc970_irq_init(env);
cf8358c8
AJ
6897 /* Can't find information on what this should be on reset. This
6898 * value is the one used by 74xx processors. */
6899 vscr_init(env, 0x00010000);
a750fc0b 6900}
a750fc0b 6901
7856e3a4
AF
6902POWERPC_FAMILY(970GX)(ObjectClass *oc, void *data)
6903{
ca5dff0a 6904 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6905 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6906
ca5dff0a 6907 dc->desc = "PowerPC 970 GX";
7856e3a4
AF
6908 pcc->init_proc = init_proc_970GX;
6909 pcc->check_pow = check_pow_970GX;
53116ebf
AF
6910 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6911 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6912 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6913 PPC_FLOAT_STFIWX |
6914 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6915 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6916 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6917 PPC_64B | PPC_ALTIVEC |
6918 PPC_SEGMENT_64B | PPC_SLBI;
ba9fd9f1
AF
6919 pcc->msr_mask = 0x800000000204FF36ULL;
6920 pcc->mmu_model = POWERPC_MMU_64B;
b632a148
DG
6921#if defined(CONFIG_SOFTMMU)
6922 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
6923#endif
ba9fd9f1
AF
6924 pcc->excp_model = POWERPC_EXCP_970;
6925 pcc->bus_model = PPC_FLAGS_INPUT_970;
6926 pcc->bfd_mach = bfd_mach_ppc64;
6927 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6928 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6929 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6930}
6931
2f462816
JM
6932static int check_pow_970MP (CPUPPCState *env)
6933{
6934 if (env->spr[SPR_HID0] & 0x01C00000)
6935 return 1;
6936
6937 return 0;
6938}
6939
6940static void init_proc_970MP (CPUPPCState *env)
6941{
6942 gen_spr_ne_601(env);
6943 gen_spr_7xx(env);
6944 /* Time base */
6945 gen_tbl(env);
6946 /* Hardware implementation registers */
6947 /* XXX : not implemented */
6948 spr_register(env, SPR_HID0, "HID0",
6949 SPR_NOACCESS, SPR_NOACCESS,
6950 &spr_read_generic, &spr_write_clear,
6951 0x60000000);
6952 /* XXX : not implemented */
6953 spr_register(env, SPR_HID1, "HID1",
6954 SPR_NOACCESS, SPR_NOACCESS,
6955 &spr_read_generic, &spr_write_generic,
6956 0x00000000);
6957 /* XXX : not implemented */
bd928eba 6958 spr_register(env, SPR_750FX_HID2, "HID2",
2f462816
JM
6959 SPR_NOACCESS, SPR_NOACCESS,
6960 &spr_read_generic, &spr_write_generic,
6961 0x00000000);
6962 /* XXX : not implemented */
6963 spr_register(env, SPR_970_HID5, "HID5",
6964 SPR_NOACCESS, SPR_NOACCESS,
6965 &spr_read_generic, &spr_write_generic,
6966 POWERPC970_HID5_INIT);
bd928eba
JM
6967 /* XXX : not implemented */
6968 spr_register(env, SPR_L2CR, "L2CR",
6969 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 6970 &spr_read_generic, spr_access_nop,
bd928eba 6971 0x00000000);
2f462816
JM
6972 /* Memory management */
6973 /* XXX: not correct */
6974 gen_low_BATs(env);
6975 /* XXX : not implemented */
6976 spr_register(env, SPR_MMUCFG, "MMUCFG",
6977 SPR_NOACCESS, SPR_NOACCESS,
6978 &spr_read_generic, SPR_NOACCESS,
6979 0x00000000); /* TOFIX */
6980 /* XXX : not implemented */
6981 spr_register(env, SPR_MMUCSR0, "MMUCSR0",
6982 SPR_NOACCESS, SPR_NOACCESS,
6983 &spr_read_generic, &spr_write_generic,
6984 0x00000000); /* TOFIX */
6985 spr_register(env, SPR_HIOR, "SPR_HIOR",
6986 SPR_NOACCESS, SPR_NOACCESS,
2adab7d6
BS
6987 &spr_read_hior, &spr_write_hior,
6988 0x00000000);
2f462816
JM
6989#if !defined(CONFIG_USER_ONLY)
6990 env->slb_nr = 32;
6991#endif
6992 init_excp_970(env);
6993 env->dcache_line_size = 128;
6994 env->icache_line_size = 128;
6995 /* Allocate hardware IRQ controller */
6996 ppc970_irq_init(env);
cf8358c8
AJ
6997 /* Can't find information on what this should be on reset. This
6998 * value is the one used by 74xx processors. */
6999 vscr_init(env, 0x00010000);
2f462816
JM
7000}
7001
7856e3a4
AF
7002POWERPC_FAMILY(970MP)(ObjectClass *oc, void *data)
7003{
ca5dff0a 7004 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
7005 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7006
ca5dff0a 7007 dc->desc = "PowerPC 970 MP";
7856e3a4
AF
7008 pcc->init_proc = init_proc_970MP;
7009 pcc->check_pow = check_pow_970MP;
53116ebf
AF
7010 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7011 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7012 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7013 PPC_FLOAT_STFIWX |
7014 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
7015 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7016 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7017 PPC_64B | PPC_ALTIVEC |
7018 PPC_SEGMENT_64B | PPC_SLBI;
ba9fd9f1
AF
7019 pcc->msr_mask = 0x900000000204FF36ULL;
7020 pcc->mmu_model = POWERPC_MMU_64B;
b632a148
DG
7021#if defined(CONFIG_SOFTMMU)
7022 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
7023#endif
ba9fd9f1
AF
7024 pcc->excp_model = POWERPC_EXCP_970;
7025 pcc->bus_model = PPC_FLAGS_INPUT_970;
7026 pcc->bfd_mach = bfd_mach_ppc64;
7027 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7028 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7029 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
7030}
7031
35ebcb2b
AF
7032static void init_proc_power5plus(CPUPPCState *env)
7033{
7034 gen_spr_ne_601(env);
7035 gen_spr_7xx(env);
7036 /* Time base */
7037 gen_tbl(env);
7038 /* Hardware implementation registers */
7039 /* XXX : not implemented */
7040 spr_register(env, SPR_HID0, "HID0",
7041 SPR_NOACCESS, SPR_NOACCESS,
7042 &spr_read_generic, &spr_write_clear,
7043 0x60000000);
7044 /* XXX : not implemented */
7045 spr_register(env, SPR_HID1, "HID1",
7046 SPR_NOACCESS, SPR_NOACCESS,
7047 &spr_read_generic, &spr_write_generic,
7048 0x00000000);
7049 /* XXX : not implemented */
7050 spr_register(env, SPR_750FX_HID2, "HID2",
7051 SPR_NOACCESS, SPR_NOACCESS,
7052 &spr_read_generic, &spr_write_generic,
7053 0x00000000);
7054 /* XXX : not implemented */
7055 spr_register(env, SPR_970_HID5, "HID5",
7056 SPR_NOACCESS, SPR_NOACCESS,
7057 &spr_read_generic, &spr_write_generic,
7058 POWERPC970_HID5_INIT);
7059 /* XXX : not implemented */
7060 spr_register(env, SPR_L2CR, "L2CR",
7061 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 7062 &spr_read_generic, spr_access_nop,
35ebcb2b
AF
7063 0x00000000);
7064 /* Memory management */
7065 /* XXX: not correct */
7066 gen_low_BATs(env);
7067 /* XXX : not implemented */
7068 spr_register(env, SPR_MMUCFG, "MMUCFG",
7069 SPR_NOACCESS, SPR_NOACCESS,
7070 &spr_read_generic, SPR_NOACCESS,
7071 0x00000000); /* TOFIX */
7072 /* XXX : not implemented */
7073 spr_register(env, SPR_MMUCSR0, "MMUCSR0",
7074 SPR_NOACCESS, SPR_NOACCESS,
7075 &spr_read_generic, &spr_write_generic,
7076 0x00000000); /* TOFIX */
7077 spr_register(env, SPR_HIOR, "SPR_HIOR",
7078 SPR_NOACCESS, SPR_NOACCESS,
7079 &spr_read_hior, &spr_write_hior,
7080 0x00000000);
7081 spr_register(env, SPR_CTRL, "SPR_CTRL",
7082 SPR_NOACCESS, SPR_NOACCESS,
7083 &spr_read_generic, &spr_write_generic,
7084 0x00000000);
7085 spr_register(env, SPR_UCTRL, "SPR_UCTRL",
7086 SPR_NOACCESS, SPR_NOACCESS,
7087 &spr_read_generic, &spr_write_generic,
7088 0x00000000);
7089 spr_register(env, SPR_VRSAVE, "SPR_VRSAVE",
7090 &spr_read_generic, &spr_write_generic,
7091 &spr_read_generic, &spr_write_generic,
7092 0x00000000);
7093#if !defined(CONFIG_USER_ONLY)
7094 env->slb_nr = 64;
7095#endif
7096 init_excp_970(env);
7097 env->dcache_line_size = 128;
7098 env->icache_line_size = 128;
7099 /* Allocate hardware IRQ controller */
7100 ppc970_irq_init(env);
7101 /* Can't find information on what this should be on reset. This
7102 * value is the one used by 74xx processors. */
7103 vscr_init(env, 0x00010000);
7104}
7105
7106POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data)
7107{
7108 DeviceClass *dc = DEVICE_CLASS(oc);
7109 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7110
793826cd 7111 dc->fw_name = "PowerPC,POWER5";
35ebcb2b
AF
7112 dc->desc = "POWER5+";
7113 pcc->init_proc = init_proc_power5plus;
7114 pcc->check_pow = check_pow_970FX;
7115 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7116 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7117 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7118 PPC_FLOAT_STFIWX |
7119 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
7120 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7121 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7122 PPC_64B |
7123 PPC_SEGMENT_64B | PPC_SLBI;
7124 pcc->msr_mask = 0x800000000204FF36ULL;
7125 pcc->mmu_model = POWERPC_MMU_64B;
7126#if defined(CONFIG_SOFTMMU)
7127 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
7128#endif
7129 pcc->excp_model = POWERPC_EXCP_970;
7130 pcc->bus_model = PPC_FLAGS_INPUT_970;
7131 pcc->bfd_mach = bfd_mach_ppc64;
7132 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7133 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7134 POWERPC_FLAG_BUS_CLK;
7135}
7136
9d52e907
DG
7137static void init_proc_POWER7 (CPUPPCState *env)
7138{
7139 gen_spr_ne_601(env);
7140 gen_spr_7xx(env);
7141 /* Time base */
7142 gen_tbl(env);
2e06214f
NW
7143 /* Processor identification */
7144 spr_register(env, SPR_PIR, "PIR",
7145 SPR_NOACCESS, SPR_NOACCESS,
7146 &spr_read_generic, &spr_write_pir,
7147 0x00000000);
9d52e907
DG
7148#if !defined(CONFIG_USER_ONLY)
7149 /* PURR & SPURR: Hack - treat these as aliases for the TB for now */
d67d40ea
DG
7150 spr_register_kvm(env, SPR_PURR, "PURR",
7151 &spr_read_purr, SPR_NOACCESS,
7152 &spr_read_purr, SPR_NOACCESS,
7153 KVM_REG_PPC_PURR, 0x00000000);
7154 spr_register_kvm(env, SPR_SPURR, "SPURR",
7155 &spr_read_purr, SPR_NOACCESS,
7156 &spr_read_purr, SPR_NOACCESS,
7157 KVM_REG_PPC_SPURR, 0x00000000);
697ab892
DG
7158 spr_register(env, SPR_CFAR, "SPR_CFAR",
7159 SPR_NOACCESS, SPR_NOACCESS,
7160 &spr_read_cfar, &spr_write_cfar,
7161 0x00000000);
d67d40ea
DG
7162 spr_register_kvm(env, SPR_DSCR, "SPR_DSCR",
7163 SPR_NOACCESS, SPR_NOACCESS,
7164 &spr_read_generic, &spr_write_generic,
7165 KVM_REG_PPC_DSCR, 0x00000000);
702763fa
DG
7166 spr_register_kvm(env, SPR_MMCRA, "SPR_MMCRA",
7167 SPR_NOACCESS, SPR_NOACCESS,
7168 &spr_read_generic, &spr_write_generic,
7169 KVM_REG_PPC_MMCRA, 0x00000000);
7170 spr_register_kvm(env, SPR_PMC5, "SPR_PMC5",
7171 SPR_NOACCESS, SPR_NOACCESS,
7172 &spr_read_generic, &spr_write_generic,
7173 KVM_REG_PPC_PMC5, 0x00000000);
7174 spr_register_kvm(env, SPR_PMC6, "SPR_PMC6",
7175 SPR_NOACCESS, SPR_NOACCESS,
7176 &spr_read_generic, &spr_write_generic,
7177 KVM_REG_PPC_PMC6, 0x00000000);
9d52e907
DG
7178#endif /* !CONFIG_USER_ONLY */
7179 /* Memory management */
7180 /* XXX : not implemented */
7181 spr_register(env, SPR_MMUCFG, "MMUCFG",
7182 SPR_NOACCESS, SPR_NOACCESS,
7183 &spr_read_generic, SPR_NOACCESS,
7184 0x00000000); /* TOFIX */
f80872e2 7185 gen_spr_amr(env);
9d52e907
DG
7186 /* XXX : not implemented */
7187 spr_register(env, SPR_CTRL, "SPR_CTRLT",
7188 SPR_NOACCESS, SPR_NOACCESS,
7189 &spr_read_generic, &spr_write_generic,
7190 0x80800000);
7191 spr_register(env, SPR_UCTRL, "SPR_CTRLF",
7192 SPR_NOACCESS, SPR_NOACCESS,
7193 &spr_read_generic, &spr_write_generic,
7194 0x80800000);
7195 spr_register(env, SPR_VRSAVE, "SPR_VRSAVE",
7196 &spr_read_generic, &spr_write_generic,
7197 &spr_read_generic, &spr_write_generic,
7198 0x00000000);
04559d52
AB
7199 spr_register(env, SPR_PPR, "PPR",
7200 &spr_read_generic, &spr_write_generic,
7201 &spr_read_generic, &spr_write_generic,
7202 0x00000000);
9d52e907
DG
7203#if !defined(CONFIG_USER_ONLY)
7204 env->slb_nr = 32;
7205#endif
7206 init_excp_POWER7(env);
7207 env->dcache_line_size = 128;
7208 env->icache_line_size = 128;
0cbad81f 7209
9d52e907
DG
7210 /* Allocate hardware IRQ controller */
7211 ppcPOWER7_irq_init(env);
7212 /* Can't find information on what this should be on reset. This
7213 * value is the one used by 74xx processors. */
7214 vscr_init(env, 0x00010000);
7215}
9d52e907 7216
7856e3a4
AF
7217POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
7218{
ca5dff0a 7219 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
7220 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7221
793826cd 7222 dc->fw_name = "PowerPC,POWER7";
ca5dff0a 7223 dc->desc = "POWER7";
3bc9ccc0
AK
7224 pcc->pvr = CPU_POWERPC_POWER7_BASE;
7225 pcc->pvr_mask = CPU_POWERPC_POWER7_MASK;
7856e3a4
AF
7226 pcc->init_proc = init_proc_POWER7;
7227 pcc->check_pow = check_pow_nocheck;
e71ec2e9 7228 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
53116ebf
AF
7229 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7230 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7231 PPC_FLOAT_STFIWX |
7232 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
7233 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7234 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7235 PPC_64B | PPC_ALTIVEC |
7236 PPC_SEGMENT_64B | PPC_SLBI |
7237 PPC_POPCNTB | PPC_POPCNTWD;
9c2627b0 7238 pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205;
bb429d22 7239 pcc->msr_mask = 0x800000000204FF37ULL;
ba9fd9f1 7240 pcc->mmu_model = POWERPC_MMU_2_06;
b632a148
DG
7241#if defined(CONFIG_SOFTMMU)
7242 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
7243#endif
ba9fd9f1
AF
7244 pcc->excp_model = POWERPC_EXCP_POWER7;
7245 pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
7246 pcc->bfd_mach = bfd_mach_ppc64;
7247 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7248 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
74f23997
TM
7249 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
7250 POWERPC_FLAG_VSX;
0cbad81f
DG
7251 pcc->l1_dcache_size = 0x8000;
7252 pcc->l1_icache_size = 0x8000;
7856e3a4 7253}
8d43ea1c
PS
7254
7255POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
7256{
7257 DeviceClass *dc = DEVICE_CLASS(oc);
7258 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7259
793826cd 7260 dc->fw_name = "PowerPC,POWER8";
8d43ea1c 7261 dc->desc = "POWER8";
3bc9ccc0
AK
7262 pcc->pvr = CPU_POWERPC_POWER8_BASE;
7263 pcc->pvr_mask = CPU_POWERPC_POWER8_MASK;
8d43ea1c
PS
7264 pcc->init_proc = init_proc_POWER7;
7265 pcc->check_pow = check_pow_nocheck;
7266 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7267 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7268 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7269 PPC_FLOAT_STFIWX |
7270 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
7271 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7272 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7273 PPC_64B | PPC_ALTIVEC |
7274 PPC_SEGMENT_64B | PPC_SLBI |
7275 PPC_POPCNTB | PPC_POPCNTWD;
7276 pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX;
7277 pcc->msr_mask = 0x800000000204FF36ULL;
7278 pcc->mmu_model = POWERPC_MMU_2_06;
7279#if defined(CONFIG_SOFTMMU)
7280 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
7281#endif
7282 pcc->excp_model = POWERPC_EXCP_POWER7;
7283 pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
7284 pcc->bfd_mach = bfd_mach_ppc64;
7285 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7286 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
74f23997
TM
7287 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
7288 POWERPC_FLAG_VSX;
8d43ea1c
PS
7289 pcc->l1_dcache_size = 0x8000;
7290 pcc->l1_icache_size = 0x8000;
7291}
a750fc0b
JM
7292#endif /* defined (TARGET_PPC64) */
7293
fd5ed418 7294
a750fc0b 7295/*****************************************************************************/
60b14d95 7296/* Generic CPU instantiation routine */
cfe34f44 7297static void init_ppc_proc(PowerPCCPU *cpu)
a750fc0b 7298{
cfe34f44
AF
7299 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
7300 CPUPPCState *env = &cpu->env;
a750fc0b 7301#if !defined(CONFIG_USER_ONLY)
e1833e1f
JM
7302 int i;
7303
a750fc0b 7304 env->irq_inputs = NULL;
e1833e1f
JM
7305 /* Set all exception vectors to an invalid address */
7306 for (i = 0; i < POWERPC_EXCP_NB; i++)
7307 env->excp_vectors[i] = (target_ulong)(-1ULL);
e1833e1f
JM
7308 env->ivor_mask = 0x00000000;
7309 env->ivpr_mask = 0x00000000;
a750fc0b
JM
7310 /* Default MMU definitions */
7311 env->nb_BATs = 0;
7312 env->nb_tlb = 0;
7313 env->nb_ways = 0;
1c53accc 7314 env->tlb_type = TLB_NONE;
f2e63a42 7315#endif
a750fc0b
JM
7316 /* Register SPR common to all PowerPC implementations */
7317 gen_spr_generic(env);
7318 spr_register(env, SPR_PVR, "PVR",
a139aa17
NF
7319 /* Linux permits userspace to read PVR */
7320#if defined(CONFIG_LINUX_USER)
7321 &spr_read_generic,
7322#else
7323 SPR_NOACCESS,
7324#endif
7325 SPR_NOACCESS,
a750fc0b 7326 &spr_read_generic, SPR_NOACCESS,
cfe34f44 7327 pcc->pvr);
80d11f44 7328 /* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
cfe34f44
AF
7329 if (pcc->svr != POWERPC_SVR_NONE) {
7330 if (pcc->svr & POWERPC_SVR_E500) {
80d11f44
JM
7331 spr_register(env, SPR_E500_SVR, "SVR",
7332 SPR_NOACCESS, SPR_NOACCESS,
7333 &spr_read_generic, SPR_NOACCESS,
cfe34f44 7334 pcc->svr & ~POWERPC_SVR_E500);
80d11f44
JM
7335 } else {
7336 spr_register(env, SPR_SVR, "SVR",
7337 SPR_NOACCESS, SPR_NOACCESS,
7338 &spr_read_generic, SPR_NOACCESS,
cfe34f44 7339 pcc->svr);
80d11f44
JM
7340 }
7341 }
a750fc0b 7342 /* PowerPC implementation specific initialisations (SPRs, timers, ...) */
cfe34f44 7343 (*pcc->init_proc)(env);
2cf3eb6d 7344
25ba3a68
JM
7345 /* MSR bits & flags consistency checks */
7346 if (env->msr_mask & (1 << 25)) {
7347 switch (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
7348 case POWERPC_FLAG_SPE:
7349 case POWERPC_FLAG_VRE:
7350 break;
7351 default:
7352 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
7353 "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n");
7354 exit(1);
7355 }
7356 } else if (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
7357 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
7358 "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n");
7359 exit(1);
7360 }
7361 if (env->msr_mask & (1 << 17)) {
7362 switch (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
7363 case POWERPC_FLAG_TGPR:
7364 case POWERPC_FLAG_CE:
7365 break;
7366 default:
7367 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
7368 "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n");
7369 exit(1);
7370 }
7371 } else if (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
7372 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
7373 "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n");
7374 exit(1);
7375 }
7376 if (env->msr_mask & (1 << 10)) {
7377 switch (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
7378 POWERPC_FLAG_UBLE)) {
7379 case POWERPC_FLAG_SE:
7380 case POWERPC_FLAG_DWE:
7381 case POWERPC_FLAG_UBLE:
7382 break;
7383 default:
7384 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
7385 "Should define POWERPC_FLAG_SE or POWERPC_FLAG_DWE or "
7386 "POWERPC_FLAG_UBLE\n");
7387 exit(1);
7388 }
7389 } else if (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
7390 POWERPC_FLAG_UBLE)) {
7391 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
7392 "Should not define POWERPC_FLAG_SE nor POWERPC_FLAG_DWE nor "
7393 "POWERPC_FLAG_UBLE\n");
7394 exit(1);
7395 }
7396 if (env->msr_mask & (1 << 9)) {
7397 switch (env->flags & (POWERPC_FLAG_BE | POWERPC_FLAG_DE)) {
7398 case POWERPC_FLAG_BE:
7399 case POWERPC_FLAG_DE:
7400 break;
7401 default:
7402 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
7403 "Should define POWERPC_FLAG_BE or POWERPC_FLAG_DE\n");
7404 exit(1);
7405 }
7406 } else if (env->flags & (POWERPC_FLAG_BE | POWERPC_FLAG_DE)) {
7407 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
7408 "Should not define POWERPC_FLAG_BE nor POWERPC_FLAG_DE\n");
7409 exit(1);
7410 }
7411 if (env->msr_mask & (1 << 2)) {
7412 switch (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
7413 case POWERPC_FLAG_PX:
7414 case POWERPC_FLAG_PMM:
7415 break;
7416 default:
7417 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
7418 "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n");
7419 exit(1);
7420 }
7421 } else if (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
7422 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
7423 "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n");
7424 exit(1);
7425 }
4018bae9
JM
7426 if ((env->flags & (POWERPC_FLAG_RTC_CLK | POWERPC_FLAG_BUS_CLK)) == 0) {
7427 fprintf(stderr, "PowerPC flags inconsistency\n"
7428 "Should define the time-base and decrementer clock source\n");
7429 exit(1);
7430 }
a750fc0b 7431 /* Allocate TLBs buffer when needed */
f2e63a42 7432#if !defined(CONFIG_USER_ONLY)
a750fc0b
JM
7433 if (env->nb_tlb != 0) {
7434 int nb_tlb = env->nb_tlb;
7435 if (env->id_tlbs != 0)
7436 nb_tlb *= 2;
1c53accc
AG
7437 switch (env->tlb_type) {
7438 case TLB_6XX:
7267c094 7439 env->tlb.tlb6 = g_malloc0(nb_tlb * sizeof(ppc6xx_tlb_t));
1c53accc
AG
7440 break;
7441 case TLB_EMB:
7267c094 7442 env->tlb.tlbe = g_malloc0(nb_tlb * sizeof(ppcemb_tlb_t));
1c53accc
AG
7443 break;
7444 case TLB_MAS:
7267c094 7445 env->tlb.tlbm = g_malloc0(nb_tlb * sizeof(ppcmas_tlb_t));
1c53accc
AG
7446 break;
7447 }
a750fc0b
JM
7448 /* Pre-compute some useful values */
7449 env->tlb_per_way = env->nb_tlb / env->nb_ways;
7450 }
a750fc0b
JM
7451 if (env->irq_inputs == NULL) {
7452 fprintf(stderr, "WARNING: no internal IRQ controller registered.\n"
5cbdb3a3 7453 " Attempt QEMU to crash very soon !\n");
a750fc0b
JM
7454 }
7455#endif
2f462816
JM
7456 if (env->check_pow == NULL) {
7457 fprintf(stderr, "WARNING: no power management check handler "
7458 "registered.\n"
5cbdb3a3 7459 " Attempt QEMU to crash very soon !\n");
2f462816 7460 }
a750fc0b
JM
7461}
7462
7463#if defined(PPC_DUMP_CPU)
7464static void dump_ppc_sprs (CPUPPCState *env)
7465{
7466 ppc_spr_t *spr;
7467#if !defined(CONFIG_USER_ONLY)
7468 uint32_t sr, sw;
7469#endif
7470 uint32_t ur, uw;
7471 int i, j, n;
7472
7473 printf("Special purpose registers:\n");
7474 for (i = 0; i < 32; i++) {
7475 for (j = 0; j < 32; j++) {
7476 n = (i << 5) | j;
7477 spr = &env->spr_cb[n];
7478 uw = spr->uea_write != NULL && spr->uea_write != SPR_NOACCESS;
7479 ur = spr->uea_read != NULL && spr->uea_read != SPR_NOACCESS;
7480#if !defined(CONFIG_USER_ONLY)
7481 sw = spr->oea_write != NULL && spr->oea_write != SPR_NOACCESS;
7482 sr = spr->oea_read != NULL && spr->oea_read != SPR_NOACCESS;
7483 if (sw || sr || uw || ur) {
7484 printf("SPR: %4d (%03x) %-8s s%c%c u%c%c\n",
7485 (i << 5) | j, (i << 5) | j, spr->name,
7486 sw ? 'w' : '-', sr ? 'r' : '-',
7487 uw ? 'w' : '-', ur ? 'r' : '-');
7488 }
7489#else
7490 if (uw || ur) {
7491 printf("SPR: %4d (%03x) %-8s u%c%c\n",
7492 (i << 5) | j, (i << 5) | j, spr->name,
7493 uw ? 'w' : '-', ur ? 'r' : '-');
7494 }
7495#endif
7496 }
7497 }
7498 fflush(stdout);
7499 fflush(stderr);
7500}
7501#endif
7502
7503/*****************************************************************************/
7504#include <stdlib.h>
7505#include <string.h>
7506
a750fc0b
JM
7507/* Opcode types */
7508enum {
7509 PPC_DIRECT = 0, /* Opcode routine */
7510 PPC_INDIRECT = 1, /* Indirect opcode table */
7511};
7512
7513static inline int is_indirect_opcode (void *handler)
7514{
5724753e 7515 return ((uintptr_t)handler & 0x03) == PPC_INDIRECT;
a750fc0b
JM
7516}
7517
c227f099 7518static inline opc_handler_t **ind_table(void *handler)
a750fc0b 7519{
5724753e 7520 return (opc_handler_t **)((uintptr_t)handler & ~3);
a750fc0b
JM
7521}
7522
7523/* Instruction table creation */
7524/* Opcodes tables creation */
c227f099 7525static void fill_new_table (opc_handler_t **table, int len)
a750fc0b
JM
7526{
7527 int i;
7528
7529 for (i = 0; i < len; i++)
7530 table[i] = &invalid_handler;
7531}
7532
c227f099 7533static int create_new_table (opc_handler_t **table, unsigned char idx)
a750fc0b 7534{
c227f099 7535 opc_handler_t **tmp;
a750fc0b 7536
b048960f 7537 tmp = g_malloc(0x20 * sizeof(opc_handler_t));
a750fc0b 7538 fill_new_table(tmp, 0x20);
5724753e 7539 table[idx] = (opc_handler_t *)((uintptr_t)tmp | PPC_INDIRECT);
a750fc0b
JM
7540
7541 return 0;
7542}
7543
c227f099
AL
7544static int insert_in_table (opc_handler_t **table, unsigned char idx,
7545 opc_handler_t *handler)
a750fc0b
JM
7546{
7547 if (table[idx] != &invalid_handler)
7548 return -1;
7549 table[idx] = handler;
7550
7551 return 0;
7552}
7553
c227f099
AL
7554static int register_direct_insn (opc_handler_t **ppc_opcodes,
7555 unsigned char idx, opc_handler_t *handler)
a750fc0b
JM
7556{
7557 if (insert_in_table(ppc_opcodes, idx, handler) < 0) {
7558 printf("*** ERROR: opcode %02x already assigned in main "
7559 "opcode table\n", idx);
4c1b1bfe
JM
7560#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
7561 printf(" Registered handler '%s' - new handler '%s'\n",
7562 ppc_opcodes[idx]->oname, handler->oname);
7563#endif
a750fc0b
JM
7564 return -1;
7565 }
7566
7567 return 0;
7568}
7569
c227f099 7570static int register_ind_in_table (opc_handler_t **table,
a750fc0b 7571 unsigned char idx1, unsigned char idx2,
c227f099 7572 opc_handler_t *handler)
a750fc0b
JM
7573{
7574 if (table[idx1] == &invalid_handler) {
7575 if (create_new_table(table, idx1) < 0) {
7576 printf("*** ERROR: unable to create indirect table "
7577 "idx=%02x\n", idx1);
7578 return -1;
7579 }
7580 } else {
7581 if (!is_indirect_opcode(table[idx1])) {
7582 printf("*** ERROR: idx %02x already assigned to a direct "
7583 "opcode\n", idx1);
4c1b1bfe
JM
7584#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
7585 printf(" Registered handler '%s' - new handler '%s'\n",
7586 ind_table(table[idx1])[idx2]->oname, handler->oname);
7587#endif
a750fc0b
JM
7588 return -1;
7589 }
3a607854 7590 }
a750fc0b
JM
7591 if (handler != NULL &&
7592 insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) {
7593 printf("*** ERROR: opcode %02x already assigned in "
7594 "opcode table %02x\n", idx2, idx1);
4c1b1bfe
JM
7595#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
7596 printf(" Registered handler '%s' - new handler '%s'\n",
7597 ind_table(table[idx1])[idx2]->oname, handler->oname);
7598#endif
a750fc0b 7599 return -1;
3a607854 7600 }
a750fc0b
JM
7601
7602 return 0;
7603}
7604
c227f099 7605static int register_ind_insn (opc_handler_t **ppc_opcodes,
a750fc0b 7606 unsigned char idx1, unsigned char idx2,
c227f099 7607 opc_handler_t *handler)
a750fc0b
JM
7608{
7609 int ret;
7610
7611 ret = register_ind_in_table(ppc_opcodes, idx1, idx2, handler);
7612
7613 return ret;
7614}
7615
c227f099 7616static int register_dblind_insn (opc_handler_t **ppc_opcodes,
a750fc0b 7617 unsigned char idx1, unsigned char idx2,
c227f099 7618 unsigned char idx3, opc_handler_t *handler)
a750fc0b
JM
7619{
7620 if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
7621 printf("*** ERROR: unable to join indirect table idx "
7622 "[%02x-%02x]\n", idx1, idx2);
7623 return -1;
7624 }
7625 if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3,
7626 handler) < 0) {
7627 printf("*** ERROR: unable to insert opcode "
7628 "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
7629 return -1;
7630 }
7631
7632 return 0;
7633}
7634
c227f099 7635static int register_insn (opc_handler_t **ppc_opcodes, opcode_t *insn)
a750fc0b
JM
7636{
7637 if (insn->opc2 != 0xFF) {
7638 if (insn->opc3 != 0xFF) {
7639 if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2,
7640 insn->opc3, &insn->handler) < 0)
7641 return -1;
7642 } else {
7643 if (register_ind_insn(ppc_opcodes, insn->opc1,
7644 insn->opc2, &insn->handler) < 0)
7645 return -1;
7646 }
7647 } else {
7648 if (register_direct_insn(ppc_opcodes, insn->opc1, &insn->handler) < 0)
7649 return -1;
7650 }
7651
7652 return 0;
7653}
7654
c227f099 7655static int test_opcode_table (opc_handler_t **table, int len)
a750fc0b
JM
7656{
7657 int i, count, tmp;
7658
7659 for (i = 0, count = 0; i < len; i++) {
7660 /* Consistency fixup */
7661 if (table[i] == NULL)
7662 table[i] = &invalid_handler;
7663 if (table[i] != &invalid_handler) {
7664 if (is_indirect_opcode(table[i])) {
c227f099 7665 tmp = test_opcode_table(ind_table(table[i]), 0x20);
a750fc0b
JM
7666 if (tmp == 0) {
7667 free(table[i]);
7668 table[i] = &invalid_handler;
7669 } else {
7670 count++;
7671 }
7672 } else {
7673 count++;
7674 }
7675 }
7676 }
7677
7678 return count;
7679}
7680
c227f099 7681static void fix_opcode_tables (opc_handler_t **ppc_opcodes)
a750fc0b 7682{
c227f099 7683 if (test_opcode_table(ppc_opcodes, 0x40) == 0)
a750fc0b
JM
7684 printf("*** WARNING: no opcode defined !\n");
7685}
7686
7687/*****************************************************************************/
2985b86b 7688static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp)
a750fc0b 7689{
2985b86b
AF
7690 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
7691 CPUPPCState *env = &cpu->env;
c227f099 7692 opcode_t *opc;
a750fc0b
JM
7693
7694 fill_new_table(env->opcodes, 0x40);
5c55ff99 7695 for (opc = opcodes; opc < &opcodes[ARRAY_SIZE(opcodes)]; opc++) {
cfe34f44
AF
7696 if (((opc->handler.type & pcc->insns_flags) != 0) ||
7697 ((opc->handler.type2 & pcc->insns_flags2) != 0)) {
a750fc0b 7698 if (register_insn(env->opcodes, opc) < 0) {
2985b86b 7699 error_setg(errp, "ERROR initializing PowerPC instruction "
312fd5f2 7700 "0x%02x 0x%02x 0x%02x", opc->opc1, opc->opc2,
2985b86b
AF
7701 opc->opc3);
7702 return;
a750fc0b
JM
7703 }
7704 }
7705 }
c227f099 7706 fix_opcode_tables(env->opcodes);
a750fc0b
JM
7707 fflush(stdout);
7708 fflush(stderr);
a750fc0b
JM
7709}
7710
7711#if defined(PPC_DUMP_CPU)
25ba3a68 7712static void dump_ppc_insns (CPUPPCState *env)
a750fc0b 7713{
c227f099 7714 opc_handler_t **table, *handler;
b55266b5 7715 const char *p, *q;
a750fc0b
JM
7716 uint8_t opc1, opc2, opc3;
7717
7718 printf("Instructions set:\n");
7719 /* opc1 is 6 bits long */
7720 for (opc1 = 0x00; opc1 < 0x40; opc1++) {
7721 table = env->opcodes;
7722 handler = table[opc1];
7723 if (is_indirect_opcode(handler)) {
7724 /* opc2 is 5 bits long */
7725 for (opc2 = 0; opc2 < 0x20; opc2++) {
7726 table = env->opcodes;
7727 handler = env->opcodes[opc1];
7728 table = ind_table(handler);
7729 handler = table[opc2];
7730 if (is_indirect_opcode(handler)) {
7731 table = ind_table(handler);
7732 /* opc3 is 5 bits long */
7733 for (opc3 = 0; opc3 < 0x20; opc3++) {
7734 handler = table[opc3];
7735 if (handler->handler != &gen_invalid) {
4c1b1bfe
JM
7736 /* Special hack to properly dump SPE insns */
7737 p = strchr(handler->oname, '_');
7738 if (p == NULL) {
7739 printf("INSN: %02x %02x %02x (%02d %04d) : "
7740 "%s\n",
7741 opc1, opc2, opc3, opc1,
7742 (opc3 << 5) | opc2,
7743 handler->oname);
7744 } else {
7745 q = "speundef";
7746 if ((p - handler->oname) != strlen(q) ||
7747 memcmp(handler->oname, q, strlen(q)) != 0) {
7748 /* First instruction */
7749 printf("INSN: %02x %02x %02x (%02d %04d) : "
7750 "%.*s\n",
7751 opc1, opc2 << 1, opc3, opc1,
7752 (opc3 << 6) | (opc2 << 1),
7753 (int)(p - handler->oname),
7754 handler->oname);
7755 }
7756 if (strcmp(p + 1, q) != 0) {
7757 /* Second instruction */
7758 printf("INSN: %02x %02x %02x (%02d %04d) : "
7759 "%s\n",
7760 opc1, (opc2 << 1) | 1, opc3, opc1,
7761 (opc3 << 6) | (opc2 << 1) | 1,
7762 p + 1);
7763 }
7764 }
a750fc0b
JM
7765 }
7766 }
7767 } else {
7768 if (handler->handler != &gen_invalid) {
7769 printf("INSN: %02x %02x -- (%02d %04d) : %s\n",
7770 opc1, opc2, opc1, opc2, handler->oname);
7771 }
7772 }
7773 }
7774 } else {
7775 if (handler->handler != &gen_invalid) {
7776 printf("INSN: %02x -- -- (%02d ----) : %s\n",
7777 opc1, opc1, handler->oname);
7778 }
7779 }
7780 }
7781}
3a607854 7782#endif
a750fc0b 7783
1328c2bf 7784static int gdb_get_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
24951522
AJ
7785{
7786 if (n < 32) {
7787 stfq_p(mem_buf, env->fpr[n]);
7788 return 8;
7789 }
7790 if (n == 32) {
5a576fb3 7791 stl_p(mem_buf, env->fpscr);
24951522
AJ
7792 return 4;
7793 }
7794 return 0;
7795}
7796
1328c2bf 7797static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
24951522
AJ
7798{
7799 if (n < 32) {
7800 env->fpr[n] = ldfq_p(mem_buf);
7801 return 8;
7802 }
7803 if (n == 32) {
d6478bc7 7804 helper_store_fpscr(env, ldl_p(mem_buf), 0xffffffff);
24951522
AJ
7805 return 4;
7806 }
7807 return 0;
7808}
7809
1328c2bf 7810static int gdb_get_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
b4f8d821
AJ
7811{
7812 if (n < 32) {
e2542fe2 7813#ifdef HOST_WORDS_BIGENDIAN
b4f8d821
AJ
7814 stq_p(mem_buf, env->avr[n].u64[0]);
7815 stq_p(mem_buf+8, env->avr[n].u64[1]);
7816#else
7817 stq_p(mem_buf, env->avr[n].u64[1]);
7818 stq_p(mem_buf+8, env->avr[n].u64[0]);
7819#endif
7820 return 16;
7821 }
70976a79 7822 if (n == 32) {
b4f8d821
AJ
7823 stl_p(mem_buf, env->vscr);
7824 return 4;
7825 }
70976a79 7826 if (n == 33) {
b4f8d821
AJ
7827 stl_p(mem_buf, (uint32_t)env->spr[SPR_VRSAVE]);
7828 return 4;
7829 }
7830 return 0;
7831}
7832
1328c2bf 7833static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
b4f8d821
AJ
7834{
7835 if (n < 32) {
e2542fe2 7836#ifdef HOST_WORDS_BIGENDIAN
b4f8d821
AJ
7837 env->avr[n].u64[0] = ldq_p(mem_buf);
7838 env->avr[n].u64[1] = ldq_p(mem_buf+8);
7839#else
7840 env->avr[n].u64[1] = ldq_p(mem_buf);
7841 env->avr[n].u64[0] = ldq_p(mem_buf+8);
7842#endif
7843 return 16;
7844 }
70976a79 7845 if (n == 32) {
b4f8d821
AJ
7846 env->vscr = ldl_p(mem_buf);
7847 return 4;
7848 }
70976a79 7849 if (n == 33) {
b4f8d821
AJ
7850 env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf);
7851 return 4;
7852 }
7853 return 0;
7854}
7855
1328c2bf 7856static int gdb_get_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
688890f7
AJ
7857{
7858 if (n < 32) {
7859#if defined(TARGET_PPC64)
7860 stl_p(mem_buf, env->gpr[n] >> 32);
7861#else
7862 stl_p(mem_buf, env->gprh[n]);
7863#endif
7864 return 4;
7865 }
70976a79 7866 if (n == 32) {
688890f7
AJ
7867 stq_p(mem_buf, env->spe_acc);
7868 return 8;
7869 }
70976a79 7870 if (n == 33) {
d34defbc 7871 stl_p(mem_buf, env->spe_fscr);
688890f7
AJ
7872 return 4;
7873 }
7874 return 0;
7875}
7876
1328c2bf 7877static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
688890f7
AJ
7878{
7879 if (n < 32) {
7880#if defined(TARGET_PPC64)
7881 target_ulong lo = (uint32_t)env->gpr[n];
7882 target_ulong hi = (target_ulong)ldl_p(mem_buf) << 32;
7883 env->gpr[n] = lo | hi;
7884#else
7885 env->gprh[n] = ldl_p(mem_buf);
7886#endif
7887 return 4;
7888 }
70976a79 7889 if (n == 32) {
688890f7
AJ
7890 env->spe_acc = ldq_p(mem_buf);
7891 return 8;
7892 }
70976a79 7893 if (n == 33) {
d34defbc 7894 env->spe_fscr = ldl_p(mem_buf);
688890f7
AJ
7895 return 4;
7896 }
7897 return 0;
7898}
7899
55e5c285 7900static int ppc_fixup_cpu(PowerPCCPU *cpu)
12b1143b 7901{
55e5c285
AF
7902 CPUPPCState *env = &cpu->env;
7903
12b1143b
DG
7904 /* TCG doesn't (yet) emulate some groups of instructions that
7905 * are implemented on some otherwise supported CPUs (e.g. VSX
7906 * and decimal floating point instructions on POWER7). We
7907 * remove unsupported instruction groups from the cpu state's
7908 * instruction masks and hope the guest can cope. For at
7909 * least the pseries machine, the unavailability of these
7910 * instructions can be advertised to the guest via the device
7911 * tree. */
7912 if ((env->insns_flags & ~PPC_TCG_INSNS)
7913 || (env->insns_flags2 & ~PPC_TCG_INSNS2)) {
7914 fprintf(stderr, "Warning: Disabling some instructions which are not "
7915 "emulated by TCG (0x%" PRIx64 ", 0x%" PRIx64 ")\n",
7916 env->insns_flags & ~PPC_TCG_INSNS,
7917 env->insns_flags2 & ~PPC_TCG_INSNS2);
7918 }
7919 env->insns_flags &= PPC_TCG_INSNS;
7920 env->insns_flags2 &= PPC_TCG_INSNS2;
7921 return 0;
7922}
7923
4776ce60 7924static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
a750fc0b 7925{
22169d41 7926 CPUState *cs = CPU(dev);
4776ce60 7927 PowerPCCPU *cpu = POWERPC_CPU(dev);
2985b86b 7928 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
2985b86b 7929 Error *local_err = NULL;
fe828a4d
MQ
7930#if !defined(CONFIG_USER_ONLY)
7931 int max_smt = kvm_enabled() ? kvmppc_smt_threads() : 1;
7932#endif
7933
7934#if !defined(CONFIG_USER_ONLY)
7935 if (smp_threads > max_smt) {
5e95acc8
AF
7936 error_setg(errp, "Cannot support more than %d threads on PPC with %s",
7937 max_smt, kvm_enabled() ? "KVM" : "TCG");
7938 return;
fe828a4d
MQ
7939 }
7940#endif
4656e1f0 7941
12b1143b 7942 if (kvm_enabled()) {
55e5c285 7943 if (kvmppc_fixup_cpu(cpu) != 0) {
2985b86b
AF
7944 error_setg(errp, "Unable to virtualize selected CPU with KVM");
7945 return;
12b1143b 7946 }
96b3bfa0 7947 } else if (tcg_enabled()) {
55e5c285 7948 if (ppc_fixup_cpu(cpu) != 0) {
2985b86b
AF
7949 error_setg(errp, "Unable to emulate selected CPU with TCG");
7950 return;
12b1143b
DG
7951 }
7952 }
7953
4d7fb187
AF
7954#if defined(TARGET_PPCEMB)
7955 if (pcc->mmu_model != POWERPC_MMU_BOOKE) {
7956 error_setg(errp, "CPU does not possess a BookE MMU. "
7957 "Please use qemu-system-ppc or qemu-system-ppc64 instead "
7958 "or choose another CPU model.");
7959 return;
7960 }
7961#endif
7962
2985b86b
AF
7963 create_ppc_opcodes(cpu, &local_err);
7964 if (local_err != NULL) {
7965 error_propagate(errp, local_err);
7966 return;
7967 }
cfe34f44 7968 init_ppc_proc(cpu);
24951522 7969
cfe34f44 7970 if (pcc->insns_flags & PPC_FLOAT) {
22169d41 7971 gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
24951522
AJ
7972 33, "power-fpu.xml", 0);
7973 }
cfe34f44 7974 if (pcc->insns_flags & PPC_ALTIVEC) {
22169d41 7975 gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg,
b4f8d821
AJ
7976 34, "power-altivec.xml", 0);
7977 }
cfe34f44 7978 if (pcc->insns_flags & PPC_SPE) {
22169d41 7979 gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
688890f7
AJ
7980 34, "power-spe.xml", 0);
7981 }
7982
14a10fc3
AF
7983 qemu_init_vcpu(cs);
7984
4776ce60
AF
7985 pcc->parent_realize(dev, errp);
7986
a750fc0b 7987#if defined(PPC_DUMP_CPU)
3a607854 7988 {
22169d41 7989 CPUPPCState *env = &cpu->env;
b55266b5 7990 const char *mmu_model, *excp_model, *bus_model;
a750fc0b
JM
7991 switch (env->mmu_model) {
7992 case POWERPC_MMU_32B:
7993 mmu_model = "PowerPC 32";
7994 break;
a750fc0b
JM
7995 case POWERPC_MMU_SOFT_6xx:
7996 mmu_model = "PowerPC 6xx/7xx with software driven TLBs";
7997 break;
7998 case POWERPC_MMU_SOFT_74xx:
7999 mmu_model = "PowerPC 74xx with software driven TLBs";
8000 break;
8001 case POWERPC_MMU_SOFT_4xx:
8002 mmu_model = "PowerPC 4xx with software driven TLBs";
8003 break;
8004 case POWERPC_MMU_SOFT_4xx_Z:
8005 mmu_model = "PowerPC 4xx with software driven TLBs "
8006 "and zones protections";
8007 break;
b4095fed
JM
8008 case POWERPC_MMU_REAL:
8009 mmu_model = "PowerPC real mode only";
8010 break;
8011 case POWERPC_MMU_MPC8xx:
8012 mmu_model = "PowerPC MPC8xx";
a750fc0b
JM
8013 break;
8014 case POWERPC_MMU_BOOKE:
8015 mmu_model = "PowerPC BookE";
8016 break;
01662f3e
AG
8017 case POWERPC_MMU_BOOKE206:
8018 mmu_model = "PowerPC BookE 2.06";
a750fc0b 8019 break;
b4095fed
JM
8020 case POWERPC_MMU_601:
8021 mmu_model = "PowerPC 601";
8022 break;
00af685f
JM
8023#if defined (TARGET_PPC64)
8024 case POWERPC_MMU_64B:
8025 mmu_model = "PowerPC 64";
8026 break;
00af685f 8027#endif
a750fc0b
JM
8028 default:
8029 mmu_model = "Unknown or invalid";
8030 break;
8031 }
8032 switch (env->excp_model) {
8033 case POWERPC_EXCP_STD:
8034 excp_model = "PowerPC";
8035 break;
8036 case POWERPC_EXCP_40x:
8037 excp_model = "PowerPC 40x";
8038 break;
8039 case POWERPC_EXCP_601:
8040 excp_model = "PowerPC 601";
8041 break;
8042 case POWERPC_EXCP_602:
8043 excp_model = "PowerPC 602";
8044 break;
8045 case POWERPC_EXCP_603:
8046 excp_model = "PowerPC 603";
8047 break;
8048 case POWERPC_EXCP_603E:
8049 excp_model = "PowerPC 603e";
8050 break;
8051 case POWERPC_EXCP_604:
8052 excp_model = "PowerPC 604";
8053 break;
8054 case POWERPC_EXCP_7x0:
8055 excp_model = "PowerPC 740/750";
8056 break;
8057 case POWERPC_EXCP_7x5:
8058 excp_model = "PowerPC 745/755";
8059 break;
8060 case POWERPC_EXCP_74xx:
8061 excp_model = "PowerPC 74xx";
8062 break;
a750fc0b
JM
8063 case POWERPC_EXCP_BOOKE:
8064 excp_model = "PowerPC BookE";
8065 break;
00af685f
JM
8066#if defined (TARGET_PPC64)
8067 case POWERPC_EXCP_970:
8068 excp_model = "PowerPC 970";
8069 break;
8070#endif
a750fc0b
JM
8071 default:
8072 excp_model = "Unknown or invalid";
8073 break;
8074 }
8075 switch (env->bus_model) {
8076 case PPC_FLAGS_INPUT_6xx:
8077 bus_model = "PowerPC 6xx";
8078 break;
8079 case PPC_FLAGS_INPUT_BookE:
8080 bus_model = "PowerPC BookE";
8081 break;
8082 case PPC_FLAGS_INPUT_405:
8083 bus_model = "PowerPC 405";
8084 break;
a750fc0b
JM
8085 case PPC_FLAGS_INPUT_401:
8086 bus_model = "PowerPC 401/403";
8087 break;
b4095fed
JM
8088 case PPC_FLAGS_INPUT_RCPU:
8089 bus_model = "RCPU / MPC8xx";
8090 break;
00af685f
JM
8091#if defined (TARGET_PPC64)
8092 case PPC_FLAGS_INPUT_970:
8093 bus_model = "PowerPC 970";
8094 break;
8095#endif
a750fc0b
JM
8096 default:
8097 bus_model = "Unknown or invalid";
8098 break;
8099 }
8100 printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64 "\n"
8101 " MMU model : %s\n",
cfe34f44 8102 pcc->name, pcc->pvr, pcc->msr_mask, mmu_model);
f2e63a42 8103#if !defined(CONFIG_USER_ONLY)
a750fc0b
JM
8104 if (env->tlb != NULL) {
8105 printf(" %d %s TLB in %d ways\n",
8106 env->nb_tlb, env->id_tlbs ? "splitted" : "merged",
8107 env->nb_ways);
8108 }
f2e63a42 8109#endif
a750fc0b
JM
8110 printf(" Exceptions model : %s\n"
8111 " Bus model : %s\n",
8112 excp_model, bus_model);
25ba3a68
JM
8113 printf(" MSR features :\n");
8114 if (env->flags & POWERPC_FLAG_SPE)
8115 printf(" signal processing engine enable"
8116 "\n");
8117 else if (env->flags & POWERPC_FLAG_VRE)
8118 printf(" vector processor enable\n");
8119 if (env->flags & POWERPC_FLAG_TGPR)
8120 printf(" temporary GPRs\n");
8121 else if (env->flags & POWERPC_FLAG_CE)
8122 printf(" critical input enable\n");
8123 if (env->flags & POWERPC_FLAG_SE)
8124 printf(" single-step trace mode\n");
8125 else if (env->flags & POWERPC_FLAG_DWE)
8126 printf(" debug wait enable\n");
8127 else if (env->flags & POWERPC_FLAG_UBLE)
8128 printf(" user BTB lock enable\n");
8129 if (env->flags & POWERPC_FLAG_BE)
8130 printf(" branch-step trace mode\n");
8131 else if (env->flags & POWERPC_FLAG_DE)
8132 printf(" debug interrupt enable\n");
8133 if (env->flags & POWERPC_FLAG_PX)
8134 printf(" inclusive protection\n");
8135 else if (env->flags & POWERPC_FLAG_PMM)
8136 printf(" performance monitor mark\n");
8137 if (env->flags == POWERPC_FLAG_NONE)
8138 printf(" none\n");
4018bae9
JM
8139 printf(" Time-base/decrementer clock source: %s\n",
8140 env->flags & POWERPC_FLAG_RTC_CLK ? "RTC clock" : "bus clock");
22169d41
AF
8141 dump_ppc_insns(env);
8142 dump_ppc_sprs(env);
8143 fflush(stdout);
a750fc0b 8144 }
3a607854 8145#endif
a750fc0b 8146}
3fc6c082 8147
b048960f
AF
8148static void ppc_cpu_unrealizefn(DeviceState *dev, Error **errp)
8149{
8150 PowerPCCPU *cpu = POWERPC_CPU(dev);
8151 CPUPPCState *env = &cpu->env;
8152 int i;
8153
8154 for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) {
8155 if (env->opcodes[i] != &invalid_handler) {
8156 g_free(env->opcodes[i]);
8157 }
8158 }
8159}
8160
2985b86b 8161static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b)
f0ad8c34 8162{
2985b86b
AF
8163 ObjectClass *oc = (ObjectClass *)a;
8164 uint32_t pvr = *(uint32_t *)b;
8165 PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
8166
8167 /* -cpu host does a PVR lookup during construction */
8168 if (unlikely(strcmp(object_class_get_name(oc),
8169 TYPE_HOST_POWERPC_CPU) == 0)) {
8170 return -1;
f0ad8c34 8171 }
f0ad8c34 8172
4d7fb187
AF
8173#if defined(TARGET_PPCEMB)
8174 if (pcc->mmu_model != POWERPC_MMU_BOOKE) {
8175 return -1;
8176 }
8177#endif
8178
cfe34f44 8179 return pcc->pvr == pvr ? 0 : -1;
f0ad8c34
AG
8180}
8181
2985b86b 8182PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr)
3fc6c082 8183{
2985b86b
AF
8184 GSList *list, *item;
8185 PowerPCCPUClass *pcc = NULL;
be40edcd 8186
2985b86b
AF
8187 list = object_class_get_list(TYPE_POWERPC_CPU, false);
8188 item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr);
8189 if (item != NULL) {
8190 pcc = POWERPC_CPU_CLASS(item->data);
3fc6c082 8191 }
2985b86b
AF
8192 g_slist_free(list);
8193
8194 return pcc;
8195}
8196
3bc9ccc0
AK
8197static gint ppc_cpu_compare_class_pvr_mask(gconstpointer a, gconstpointer b)
8198{
8199 ObjectClass *oc = (ObjectClass *)a;
8200 uint32_t pvr = *(uint32_t *)b;
8201 PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
8202 gint ret;
8203
8204 /* -cpu host does a PVR lookup during construction */
8205 if (unlikely(strcmp(object_class_get_name(oc),
8206 TYPE_HOST_POWERPC_CPU) == 0)) {
8207 return -1;
8208 }
8209
8210#if defined(TARGET_PPCEMB)
8211 if (pcc->mmu_model != POWERPC_MMU_BOOKE) {
8212 return -1;
8213 }
8214#endif
8215 ret = (((pcc->pvr & pcc->pvr_mask) == (pvr & pcc->pvr_mask)) ? 0 : -1);
8216
8217 return ret;
8218}
8219
8220PowerPCCPUClass *ppc_cpu_class_by_pvr_mask(uint32_t pvr)
8221{
8222 GSList *list, *item;
8223 PowerPCCPUClass *pcc = NULL;
8224
8225 list = object_class_get_list(TYPE_POWERPC_CPU, true);
8226 item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr_mask);
8227 if (item != NULL) {
8228 pcc = POWERPC_CPU_CLASS(item->data);
8229 }
8230 g_slist_free(list);
8231
8232 return pcc;
8233}
8234
2985b86b
AF
8235static gint ppc_cpu_compare_class_name(gconstpointer a, gconstpointer b)
8236{
8237 ObjectClass *oc = (ObjectClass *)a;
8238 const char *name = b;
4d7fb187
AF
8239#if defined(TARGET_PPCEMB)
8240 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8241#endif
ee4e83ed 8242
2985b86b 8243 if (strncasecmp(name, object_class_get_name(oc), strlen(name)) == 0 &&
4d7fb187
AF
8244#if defined(TARGET_PPCEMB)
8245 pcc->mmu_model == POWERPC_MMU_BOOKE &&
8246#endif
2985b86b
AF
8247 strcmp(object_class_get_name(oc) + strlen(name),
8248 "-" TYPE_POWERPC_CPU) == 0) {
8249 return 0;
8250 }
8251 return -1;
3fc6c082
FB
8252}
8253
ee4e83ed 8254#include <ctype.h>
3fc6c082 8255
9761ad75
AG
8256static ObjectClass *ppc_cpu_class_by_name(const char *name);
8257
8258static ObjectClass *ppc_cpu_class_by_alias(PowerPCCPUAlias *alias)
8259{
8260 ObjectClass *invalid_class = (void*)ppc_cpu_class_by_alias;
8261
8262 /* Cache target class lookups in the alias table */
8263 if (!alias->oc) {
8264 alias->oc = ppc_cpu_class_by_name(alias->model);
8265 if (!alias->oc) {
8266 /* Fast check for non-existing aliases */
8267 alias->oc = invalid_class;
8268 }
8269 }
8270
8271 if (alias->oc == invalid_class) {
8272 return NULL;
8273 } else {
8274 return alias->oc;
8275 }
8276}
8277
2985b86b 8278static ObjectClass *ppc_cpu_class_by_name(const char *name)
ee4e83ed 8279{
2985b86b
AF
8280 GSList *list, *item;
8281 ObjectClass *ret = NULL;
b55266b5 8282 const char *p;
2985b86b 8283 int i, len;
ee4e83ed
JM
8284
8285 /* Check if the given name is a PVR */
8286 len = strlen(name);
8287 if (len == 10 && name[0] == '0' && name[1] == 'x') {
8288 p = name + 2;
8289 goto check_pvr;
8290 } else if (len == 8) {
8291 p = name;
8292 check_pvr:
8293 for (i = 0; i < 8; i++) {
cd390083 8294 if (!qemu_isxdigit(*p++))
ee4e83ed
JM
8295 break;
8296 }
2985b86b
AF
8297 if (i == 8) {
8298 ret = OBJECT_CLASS(ppc_cpu_class_by_pvr(strtoul(name, NULL, 16)));
8299 return ret;
f0ad8c34 8300 }
2985b86b 8301 }
f0ad8c34 8302
e9a96075 8303 for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
fd5ed418 8304 if (strcmp(ppc_cpu_aliases[i].alias, name) == 0) {
9761ad75 8305 return ppc_cpu_class_by_alias(&ppc_cpu_aliases[i]);
fd5ed418
AF
8306 }
8307 }
8308
2985b86b
AF
8309 list = object_class_get_list(TYPE_POWERPC_CPU, false);
8310 item = g_slist_find_custom(list, name, ppc_cpu_compare_class_name);
8311 if (item != NULL) {
8312 ret = OBJECT_CLASS(item->data);
3fc6c082 8313 }
2985b86b 8314 g_slist_free(list);
ee4e83ed
JM
8315
8316 return ret;
3fc6c082
FB
8317}
8318
2985b86b 8319PowerPCCPU *cpu_ppc_init(const char *cpu_model)
3fc6c082 8320{
2985b86b 8321 PowerPCCPU *cpu;
2985b86b
AF
8322 ObjectClass *oc;
8323 Error *err = NULL;
3fc6c082 8324
2985b86b
AF
8325 oc = ppc_cpu_class_by_name(cpu_model);
8326 if (oc == NULL) {
8327 return NULL;
8328 }
f0ad8c34 8329
2985b86b 8330 cpu = POWERPC_CPU(object_new(object_class_get_name(oc)));
2985b86b 8331
4776ce60 8332 object_property_set_bool(OBJECT(cpu), true, "realized", &err);
2985b86b 8333 if (err != NULL) {
4a44d85e 8334 error_report("%s", error_get_pretty(err));
2985b86b 8335 error_free(err);
5c099537 8336 object_unref(OBJECT(cpu));
2985b86b
AF
8337 return NULL;
8338 }
8339
8340 return cpu;
8341}
8342
8343/* Sort by PVR, ordering special case "host" last. */
8344static gint ppc_cpu_list_compare(gconstpointer a, gconstpointer b)
8345{
8346 ObjectClass *oc_a = (ObjectClass *)a;
8347 ObjectClass *oc_b = (ObjectClass *)b;
8348 PowerPCCPUClass *pcc_a = POWERPC_CPU_CLASS(oc_a);
8349 PowerPCCPUClass *pcc_b = POWERPC_CPU_CLASS(oc_b);
8350 const char *name_a = object_class_get_name(oc_a);
8351 const char *name_b = object_class_get_name(oc_b);
8352
8353 if (strcmp(name_a, TYPE_HOST_POWERPC_CPU) == 0) {
8354 return 1;
8355 } else if (strcmp(name_b, TYPE_HOST_POWERPC_CPU) == 0) {
8356 return -1;
8357 } else {
8358 /* Avoid an integer overflow during subtraction */
cfe34f44 8359 if (pcc_a->pvr < pcc_b->pvr) {
2985b86b 8360 return -1;
cfe34f44 8361 } else if (pcc_a->pvr > pcc_b->pvr) {
2985b86b
AF
8362 return 1;
8363 } else {
8364 return 0;
8365 }
8366 }
8367}
8368
8369static void ppc_cpu_list_entry(gpointer data, gpointer user_data)
8370{
8371 ObjectClass *oc = data;
8372 CPUListState *s = user_data;
8373 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
de400129
AF
8374 const char *typename = object_class_get_name(oc);
8375 char *name;
55d3d1a4 8376 int i;
2985b86b 8377
4d7fb187
AF
8378#if defined(TARGET_PPCEMB)
8379 if (pcc->mmu_model != POWERPC_MMU_BOOKE) {
8380 return;
8381 }
8382#endif
5ba4576b
AF
8383 if (unlikely(strcmp(typename, TYPE_HOST_POWERPC_CPU) == 0)) {
8384 return;
8385 }
4d7fb187 8386
de400129
AF
8387 name = g_strndup(typename,
8388 strlen(typename) - strlen("-" TYPE_POWERPC_CPU));
2985b86b 8389 (*s->cpu_fprintf)(s->file, "PowerPC %-16s PVR %08x\n",
cfe34f44 8390 name, pcc->pvr);
e9a96075 8391 for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
9761ad75
AG
8392 PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
8393 ObjectClass *alias_oc = ppc_cpu_class_by_alias(alias);
55d3d1a4
AF
8394
8395 if (alias_oc != oc) {
8396 continue;
8397 }
8398 (*s->cpu_fprintf)(s->file, "PowerPC %-16s (alias for %s)\n",
8399 alias->alias, name);
8400 }
de400129 8401 g_free(name);
2985b86b
AF
8402}
8403
8404void ppc_cpu_list(FILE *f, fprintf_function cpu_fprintf)
8405{
8406 CPUListState s = {
8407 .file = f,
8408 .cpu_fprintf = cpu_fprintf,
8409 };
8410 GSList *list;
8411
8412 list = object_class_get_list(TYPE_POWERPC_CPU, false);
8413 list = g_slist_sort(list, ppc_cpu_list_compare);
8414 g_slist_foreach(list, ppc_cpu_list_entry, &s);
8415 g_slist_free(list);
fd5ed418 8416
5ba4576b
AF
8417#ifdef CONFIG_KVM
8418 cpu_fprintf(f, "\n");
8419 cpu_fprintf(f, "PowerPC %-16s\n", "host");
8420#endif
2985b86b
AF
8421}
8422
8423static void ppc_cpu_defs_entry(gpointer data, gpointer user_data)
8424{
8425 ObjectClass *oc = data;
8426 CpuDefinitionInfoList **first = user_data;
de400129 8427 const char *typename;
2985b86b
AF
8428 CpuDefinitionInfoList *entry;
8429 CpuDefinitionInfo *info;
4d7fb187
AF
8430#if defined(TARGET_PPCEMB)
8431 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8432
8433 if (pcc->mmu_model != POWERPC_MMU_BOOKE) {
8434 return;
8435 }
8436#endif
2985b86b 8437
de400129 8438 typename = object_class_get_name(oc);
2985b86b 8439 info = g_malloc0(sizeof(*info));
de400129
AF
8440 info->name = g_strndup(typename,
8441 strlen(typename) - strlen("-" TYPE_POWERPC_CPU));
2985b86b
AF
8442
8443 entry = g_malloc0(sizeof(*entry));
8444 entry->value = info;
8445 entry->next = *first;
8446 *first = entry;
3fc6c082 8447}
1d0cb67d 8448
76b64a7a 8449CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
70b7660a
AL
8450{
8451 CpuDefinitionInfoList *cpu_list = NULL;
2985b86b 8452 GSList *list;
35e21d3f 8453 int i;
70b7660a 8454
2985b86b
AF
8455 list = object_class_get_list(TYPE_POWERPC_CPU, false);
8456 g_slist_foreach(list, ppc_cpu_defs_entry, &cpu_list);
8457 g_slist_free(list);
70b7660a 8458
e9a96075 8459 for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
9761ad75 8460 PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
35e21d3f
AF
8461 ObjectClass *oc;
8462 CpuDefinitionInfoList *entry;
8463 CpuDefinitionInfo *info;
8464
9761ad75 8465 oc = ppc_cpu_class_by_alias(alias);
35e21d3f
AF
8466 if (oc == NULL) {
8467 continue;
8468 }
8469
8470 info = g_malloc0(sizeof(*info));
8471 info->name = g_strdup(alias->alias);
8472
8473 entry = g_malloc0(sizeof(*entry));
8474 entry->value = info;
8475 entry->next = cpu_list;
8476 cpu_list = entry;
8477 }
8478
2985b86b
AF
8479 return cpu_list;
8480}
70b7660a 8481
f45748f1
AF
8482static void ppc_cpu_set_pc(CPUState *cs, vaddr value)
8483{
8484 PowerPCCPU *cpu = POWERPC_CPU(cs);
8485
8486 cpu->env.nip = value;
8487}
8488
1d0cb67d
AF
8489/* CPUClass::reset() */
8490static void ppc_cpu_reset(CPUState *s)
8491{
8492 PowerPCCPU *cpu = POWERPC_CPU(s);
8493 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
8494 CPUPPCState *env = &cpu->env;
a1389542
AF
8495 target_ulong msr;
8496
1d0cb67d
AF
8497 pcc->parent_reset(s);
8498
a1389542
AF
8499 msr = (target_ulong)0;
8500 if (0) {
8501 /* XXX: find a suitable condition to enable the hypervisor mode */
8502 msr |= (target_ulong)MSR_HVB;
8503 }
8504 msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */
8505 msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */
8506 msr |= (target_ulong)1 << MSR_EP;
8507#if defined(DO_SINGLE_STEP) && 0
8508 /* Single step trace mode */
8509 msr |= (target_ulong)1 << MSR_SE;
8510 msr |= (target_ulong)1 << MSR_BE;
8511#endif
8512#if defined(CONFIG_USER_ONLY)
8513 msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
8514 msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
8515 msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
8516 msr |= (target_ulong)1 << MSR_PR;
a1389542 8517#endif
2cf3eb6d 8518
a1389542
AF
8519#if defined(TARGET_PPC64)
8520 if (env->mmu_model & POWERPC_MMU_64) {
8521 env->msr |= (1ULL << MSR_SF);
8522 }
8523#endif
2cf3eb6d
FC
8524
8525 hreg_store_msr(env, msr, 1);
8526
8527#if !defined(CONFIG_USER_ONLY)
8528 env->nip = env->hreset_vector | env->excp_prefix;
8529 if (env->mmu_model != POWERPC_MMU_REAL) {
8530 ppc_tlb_invalidate_all(env);
8531 }
8532#endif
8533
a1389542
AF
8534 hreg_compute_hflags(env);
8535 env->reserve_addr = (target_ulong)-1ULL;
8536 /* Be sure no exception or interrupt is pending */
8537 env->pending_interrupts = 0;
8538 env->exception_index = POWERPC_EXCP_NONE;
8539 env->error_code = 0;
2b15811c
DG
8540
8541#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
1bfb37d1
DG
8542 env->vpa_addr = 0;
8543 env->slb_shadow_addr = 0;
8544 env->slb_shadow_size = 0;
8545 env->dtl_addr = 0;
2b15811c
DG
8546 env->dtl_size = 0;
8547#endif /* TARGET_PPC64 */
8548
a1389542
AF
8549 /* Flush all TLBs */
8550 tlb_flush(env, 1);
1d0cb67d
AF
8551}
8552
6cca7ad6
AF
8553static void ppc_cpu_initfn(Object *obj)
8554{
c05efcb1 8555 CPUState *cs = CPU(obj);
6cca7ad6 8556 PowerPCCPU *cpu = POWERPC_CPU(obj);
2985b86b 8557 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
6cca7ad6
AF
8558 CPUPPCState *env = &cpu->env;
8559
c05efcb1 8560 cs->env_ptr = env;
6cca7ad6 8561 cpu_exec_init(env);
2985b86b 8562
cfe34f44
AF
8563 env->msr_mask = pcc->msr_mask;
8564 env->mmu_model = pcc->mmu_model;
8565 env->excp_model = pcc->excp_model;
8566 env->bus_model = pcc->bus_model;
8567 env->insns_flags = pcc->insns_flags;
8568 env->insns_flags2 = pcc->insns_flags2;
8569 env->flags = pcc->flags;
8570 env->bfd_mach = pcc->bfd_mach;
8571 env->check_pow = pcc->check_pow;
2985b86b
AF
8572
8573#if defined(TARGET_PPC64)
cfe34f44
AF
8574 if (pcc->sps) {
8575 env->sps = *pcc->sps;
2985b86b
AF
8576 } else if (env->mmu_model & POWERPC_MMU_64) {
8577 /* Use default sets of page sizes */
8578 static const struct ppc_segment_page_sizes defsps = {
8579 .sps = {
8580 { .page_shift = 12, /* 4K */
8581 .slb_enc = 0,
8582 .enc = { { .page_shift = 12, .pte_enc = 0 } }
8583 },
8584 { .page_shift = 24, /* 16M */
8585 .slb_enc = 0x100,
8586 .enc = { { .page_shift = 24, .pte_enc = 0 } }
8587 },
8588 },
8589 };
8590 env->sps = defsps;
8591 }
8592#endif /* defined(TARGET_PPC64) */
60925d26
AF
8593
8594 if (tcg_enabled()) {
8595 ppc_translate_init();
8596 }
6cca7ad6
AF
8597}
8598
1d0cb67d
AF
8599static void ppc_cpu_class_init(ObjectClass *oc, void *data)
8600{
8601 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8602 CPUClass *cc = CPU_CLASS(oc);
4776ce60
AF
8603 DeviceClass *dc = DEVICE_CLASS(oc);
8604
8605 pcc->parent_realize = dc->realize;
3bc9ccc0
AK
8606 pcc->pvr = CPU_POWERPC_DEFAULT_MASK;
8607 pcc->pvr_mask = CPU_POWERPC_DEFAULT_MASK;
4776ce60 8608 dc->realize = ppc_cpu_realizefn;
b048960f 8609 dc->unrealize = ppc_cpu_unrealizefn;
1d0cb67d
AF
8610
8611 pcc->parent_reset = cc->reset;
8612 cc->reset = ppc_cpu_reset;
2b8c2754
AF
8613
8614 cc->class_by_name = ppc_cpu_class_by_name;
97a8ea5a 8615 cc->do_interrupt = ppc_cpu_do_interrupt;
878096ee
AF
8616 cc->dump_state = ppc_cpu_dump_state;
8617 cc->dump_statistics = ppc_cpu_dump_statistics;
f45748f1 8618 cc->set_pc = ppc_cpu_set_pc;
5b50e790
AF
8619 cc->gdb_read_register = ppc_cpu_gdb_read_register;
8620 cc->gdb_write_register = ppc_cpu_gdb_write_register;
00b941e5
AF
8621#ifndef CONFIG_USER_ONLY
8622 cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
a90db158 8623 cc->vmsd = &vmstate_ppc_cpu;
e62fbc54
AK
8624#if defined(TARGET_PPC64)
8625 cc->write_elf64_note = ppc64_cpu_write_elf64_note;
8626 cc->write_elf64_qemunote = ppc64_cpu_write_elf64_qemunote;
8627#endif
00b941e5 8628#endif
a0e372f0
AF
8629
8630 cc->gdb_num_core_regs = 71;
5b24c641
AF
8631#if defined(TARGET_PPC64)
8632 cc->gdb_core_xml_file = "power64-core.xml";
8633#else
8634 cc->gdb_core_xml_file = "power-core.xml";
8635#endif
3bbf37f2
AF
8636
8637 dc->fw_name = "PowerPC,UNKNOWN";
1d0cb67d
AF
8638}
8639
8640static const TypeInfo ppc_cpu_type_info = {
8641 .name = TYPE_POWERPC_CPU,
8642 .parent = TYPE_CPU,
8643 .instance_size = sizeof(PowerPCCPU),
6cca7ad6 8644 .instance_init = ppc_cpu_initfn,
2985b86b 8645 .abstract = true,
1d0cb67d
AF
8646 .class_size = sizeof(PowerPCCPUClass),
8647 .class_init = ppc_cpu_class_init,
8648};
8649
8650static void ppc_cpu_register_types(void)
8651{
8652 type_register_static(&ppc_cpu_type_info);
8653}
8654
8655type_init(ppc_cpu_register_types)