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