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