]> git.proxmox.com Git - mirror_qemu.git/blame - target-ppc/translate_init.c
atomic: fix position of volatile qualifier
[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;
8412d112 2789 env->ivor_mask = 0x0000FFF0UL;
80d11f44
JM
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
b8c867ed
PM
3926POWERPC_FAMILY(440x5wDFPU)(ObjectClass *oc, void *data)
3927{
3928 DeviceClass *dc = DEVICE_CLASS(oc);
3929 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3930
3931 dc->desc = "PowerPC 440x5 with double precision FPU";
3932 pcc->init_proc = init_proc_440x5;
3933 pcc->check_pow = check_pow_nocheck;
3934 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3935 PPC_FLOAT | PPC_FLOAT_FSQRT |
3936 PPC_FLOAT_STFIWX |
3937 PPC_DCR | PPC_WRTEE | PPC_RFMCI |
3938 PPC_CACHE | PPC_CACHE_ICBI |
3939 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3940 PPC_MEM_TLBSYNC | PPC_MFTB |
3941 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
3942 PPC_440_SPEC;
3943 pcc->insns_flags2 = PPC2_FP_CVT_S64;
3944 pcc->msr_mask = (1ull << MSR_POW) |
3945 (1ull << MSR_CE) |
3946 (1ull << MSR_EE) |
3947 (1ull << MSR_PR) |
3948 (1ull << MSR_FP) |
3949 (1ull << MSR_ME) |
3950 (1ull << MSR_FE0) |
3951 (1ull << MSR_DWE) |
3952 (1ull << MSR_DE) |
3953 (1ull << MSR_FE1) |
3954 (1ull << MSR_IR) |
3955 (1ull << MSR_DR);
3956 pcc->mmu_model = POWERPC_MMU_BOOKE;
3957 pcc->excp_model = POWERPC_EXCP_BOOKE;
3958 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
3959 pcc->bfd_mach = bfd_mach_ppc_403;
3960 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
3961 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
3962}
3963
80d11f44 3964static void init_proc_460 (CPUPPCState *env)
3fc6c082 3965{
a750fc0b
JM
3966 /* Time base */
3967 gen_tbl(env);
80d11f44 3968 gen_spr_BookE(env, 0x000000000000FFFFULL);
a750fc0b 3969 gen_spr_440(env);
80d11f44
JM
3970 gen_spr_usprgh(env);
3971 /* Processor identification */
3972 spr_register(env, SPR_BOOKE_PIR, "PIR",
3973 SPR_NOACCESS, SPR_NOACCESS,
3974 &spr_read_generic, &spr_write_pir,
3975 0x00000000);
3976 /* XXX : not implemented */
3977 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
3978 SPR_NOACCESS, SPR_NOACCESS,
3979 &spr_read_generic, &spr_write_generic,
3980 0x00000000);
3981 /* XXX : not implemented */
3982 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
3983 SPR_NOACCESS, SPR_NOACCESS,
3984 &spr_read_generic, &spr_write_generic,
3985 0x00000000);
3986 /* XXX : not implemented */
3987 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
3988 SPR_NOACCESS, SPR_NOACCESS,
3989 &spr_read_generic, &spr_write_generic,
3990 0x00000000);
3991 /* XXX : not implemented */
3992 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
3993 SPR_NOACCESS, SPR_NOACCESS,
3994 &spr_read_generic, &spr_write_generic,
3995 0x00000000);
578bb252 3996 /* XXX : not implemented */
a750fc0b
JM
3997 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
3998 SPR_NOACCESS, SPR_NOACCESS,
3999 &spr_read_generic, &spr_write_generic,
4000 0x00000000);
4001 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
4002 SPR_NOACCESS, SPR_NOACCESS,
4003 &spr_read_generic, &spr_write_generic,
4004 0x00000000);
4005 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
4006 SPR_NOACCESS, SPR_NOACCESS,
4007 &spr_read_generic, &spr_write_generic,
4008 0x00000000);
578bb252 4009 /* XXX : not implemented */
a750fc0b
JM
4010 spr_register(env, SPR_440_CCR1, "CCR1",
4011 SPR_NOACCESS, SPR_NOACCESS,
4012 &spr_read_generic, &spr_write_generic,
4013 0x00000000);
80d11f44
JM
4014 /* XXX : not implemented */
4015 spr_register(env, SPR_DCRIPR, "SPR_DCRIPR",
4016 &spr_read_generic, &spr_write_generic,
4017 &spr_read_generic, &spr_write_generic,
4018 0x00000000);
a750fc0b 4019 /* Memory management */
f2e63a42 4020#if !defined(CONFIG_USER_ONLY)
a750fc0b
JM
4021 env->nb_tlb = 64;
4022 env->nb_ways = 1;
4023 env->id_tlbs = 0;
1c53accc 4024 env->tlb_type = TLB_EMB;
f2e63a42 4025#endif
e1833e1f 4026 init_excp_BookE(env);
d63001d1
JM
4027 env->dcache_line_size = 32;
4028 env->icache_line_size = 32;
a750fc0b 4029 /* XXX: TODO: allocate internal IRQ controller */
ddd1055b
FC
4030
4031 SET_FIT_PERIOD(12, 16, 20, 24);
4032 SET_WDT_PERIOD(20, 24, 28, 32);
3fc6c082
FB
4033}
4034
7856e3a4
AF
4035POWERPC_FAMILY(460)(ObjectClass *oc, void *data)
4036{
ca5dff0a 4037 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4038 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4039
ca5dff0a 4040 dc->desc = "PowerPC 460 (guessed)";
7856e3a4
AF
4041 pcc->init_proc = init_proc_460;
4042 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
4043 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4044 PPC_DCR | PPC_DCRX | PPC_DCRUX |
4045 PPC_WRTEE | PPC_MFAPIDI | PPC_MFTB |
4046 PPC_CACHE | PPC_CACHE_ICBI |
4047 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4048 PPC_MEM_TLBSYNC | PPC_TLBIVA |
4049 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4050 PPC_440_SPEC;
9df5a466
TM
4051 pcc->msr_mask = (1ull << MSR_POW) |
4052 (1ull << MSR_CE) |
4053 (1ull << MSR_EE) |
4054 (1ull << MSR_PR) |
4055 (1ull << MSR_FP) |
4056 (1ull << MSR_ME) |
4057 (1ull << MSR_FE0) |
4058 (1ull << MSR_DWE) |
4059 (1ull << MSR_DE) |
4060 (1ull << MSR_FE1) |
4061 (1ull << MSR_IR) |
4062 (1ull << MSR_DR);
ba9fd9f1
AF
4063 pcc->mmu_model = POWERPC_MMU_BOOKE;
4064 pcc->excp_model = POWERPC_EXCP_BOOKE;
4065 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4066 pcc->bfd_mach = bfd_mach_ppc_403;
4067 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4068 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4069}
4070
80d11f44 4071static void init_proc_460F (CPUPPCState *env)
3fc6c082 4072{
a750fc0b
JM
4073 /* Time base */
4074 gen_tbl(env);
80d11f44 4075 gen_spr_BookE(env, 0x000000000000FFFFULL);
a750fc0b 4076 gen_spr_440(env);
80d11f44
JM
4077 gen_spr_usprgh(env);
4078 /* Processor identification */
4079 spr_register(env, SPR_BOOKE_PIR, "PIR",
4080 SPR_NOACCESS, SPR_NOACCESS,
4081 &spr_read_generic, &spr_write_pir,
4082 0x00000000);
4083 /* XXX : not implemented */
4084 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4085 SPR_NOACCESS, SPR_NOACCESS,
4086 &spr_read_generic, &spr_write_generic,
4087 0x00000000);
4088 /* XXX : not implemented */
4089 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4090 SPR_NOACCESS, SPR_NOACCESS,
4091 &spr_read_generic, &spr_write_generic,
4092 0x00000000);
4093 /* XXX : not implemented */
4094 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
4095 SPR_NOACCESS, SPR_NOACCESS,
4096 &spr_read_generic, &spr_write_generic,
4097 0x00000000);
4098 /* XXX : not implemented */
4099 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
4100 SPR_NOACCESS, SPR_NOACCESS,
4101 &spr_read_generic, &spr_write_generic,
4102 0x00000000);
4103 /* XXX : not implemented */
4104 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
4105 SPR_NOACCESS, SPR_NOACCESS,
4106 &spr_read_generic, &spr_write_generic,
4107 0x00000000);
4108 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
4109 SPR_NOACCESS, SPR_NOACCESS,
4110 &spr_read_generic, &spr_write_generic,
4111 0x00000000);
4112 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
4113 SPR_NOACCESS, SPR_NOACCESS,
4114 &spr_read_generic, &spr_write_generic,
4115 0x00000000);
4116 /* XXX : not implemented */
4117 spr_register(env, SPR_440_CCR1, "CCR1",
4118 SPR_NOACCESS, SPR_NOACCESS,
4119 &spr_read_generic, &spr_write_generic,
4120 0x00000000);
4121 /* XXX : not implemented */
4122 spr_register(env, SPR_DCRIPR, "SPR_DCRIPR",
4123 &spr_read_generic, &spr_write_generic,
4124 &spr_read_generic, &spr_write_generic,
4125 0x00000000);
a750fc0b 4126 /* Memory management */
f2e63a42 4127#if !defined(CONFIG_USER_ONLY)
a750fc0b
JM
4128 env->nb_tlb = 64;
4129 env->nb_ways = 1;
4130 env->id_tlbs = 0;
1c53accc 4131 env->tlb_type = TLB_EMB;
f2e63a42 4132#endif
e1833e1f 4133 init_excp_BookE(env);
d63001d1
JM
4134 env->dcache_line_size = 32;
4135 env->icache_line_size = 32;
a750fc0b 4136 /* XXX: TODO: allocate internal IRQ controller */
ddd1055b
FC
4137
4138 SET_FIT_PERIOD(12, 16, 20, 24);
4139 SET_WDT_PERIOD(20, 24, 28, 32);
3fc6c082
FB
4140}
4141
7856e3a4
AF
4142POWERPC_FAMILY(460F)(ObjectClass *oc, void *data)
4143{
ca5dff0a 4144 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4145 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4146
ca5dff0a 4147 dc->desc = "PowerPC 460F (guessed)";
7856e3a4
AF
4148 pcc->init_proc = init_proc_460F;
4149 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
4150 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4151 PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL |
4152 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
4153 PPC_FLOAT_STFIWX | PPC_MFTB |
4154 PPC_DCR | PPC_DCRX | PPC_DCRUX |
4155 PPC_WRTEE | PPC_MFAPIDI |
4156 PPC_CACHE | PPC_CACHE_ICBI |
4157 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4158 PPC_MEM_TLBSYNC | PPC_TLBIVA |
4159 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4160 PPC_440_SPEC;
9df5a466
TM
4161 pcc->msr_mask = (1ull << MSR_POW) |
4162 (1ull << MSR_CE) |
4163 (1ull << MSR_EE) |
4164 (1ull << MSR_PR) |
4165 (1ull << MSR_FP) |
4166 (1ull << MSR_ME) |
4167 (1ull << MSR_FE0) |
4168 (1ull << MSR_DWE) |
4169 (1ull << MSR_DE) |
4170 (1ull << MSR_FE1) |
4171 (1ull << MSR_IR) |
4172 (1ull << MSR_DR);
ba9fd9f1
AF
4173 pcc->mmu_model = POWERPC_MMU_BOOKE;
4174 pcc->excp_model = POWERPC_EXCP_BOOKE;
4175 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4176 pcc->bfd_mach = bfd_mach_ppc_403;
4177 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4178 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4179}
4180
80d11f44
JM
4181static void init_proc_MPC5xx (CPUPPCState *env)
4182{
4183 /* Time base */
4184 gen_tbl(env);
4185 gen_spr_5xx_8xx(env);
4186 gen_spr_5xx(env);
4187 init_excp_MPC5xx(env);
4188 env->dcache_line_size = 32;
4189 env->icache_line_size = 32;
4190 /* XXX: TODO: allocate internal IRQ controller */
4191}
4192
7856e3a4
AF
4193POWERPC_FAMILY(MPC5xx)(ObjectClass *oc, void *data)
4194{
ca5dff0a 4195 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4196 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4197
ca5dff0a 4198 dc->desc = "Freescale 5xx cores (aka RCPU)";
7856e3a4
AF
4199 pcc->init_proc = init_proc_MPC5xx;
4200 pcc->check_pow = check_pow_none;
53116ebf
AF
4201 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4202 PPC_MEM_EIEIO | PPC_MEM_SYNC |
4203 PPC_CACHE_ICBI | PPC_FLOAT | PPC_FLOAT_STFIWX |
4204 PPC_MFTB;
9df5a466
TM
4205 pcc->msr_mask = (1ull << MSR_ILE) |
4206 (1ull << MSR_EE) |
4207 (1ull << MSR_PR) |
4208 (1ull << MSR_FP) |
4209 (1ull << MSR_ME) |
4210 (1ull << MSR_FE0) |
4211 (1ull << MSR_SE) |
4212 (1ull << MSR_DE) |
4213 (1ull << MSR_FE1) |
4214 (1ull << MSR_EP) |
4215 (1ull << MSR_RI) |
4216 (1ull << MSR_LE);
ba9fd9f1
AF
4217 pcc->mmu_model = POWERPC_MMU_REAL;
4218 pcc->excp_model = POWERPC_EXCP_603;
4219 pcc->bus_model = PPC_FLAGS_INPUT_RCPU;
4220 pcc->bfd_mach = bfd_mach_ppc_505;
4221 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
4222 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4223}
4224
80d11f44
JM
4225static void init_proc_MPC8xx (CPUPPCState *env)
4226{
4227 /* Time base */
4228 gen_tbl(env);
4229 gen_spr_5xx_8xx(env);
4230 gen_spr_8xx(env);
4231 init_excp_MPC8xx(env);
4232 env->dcache_line_size = 32;
4233 env->icache_line_size = 32;
4234 /* XXX: TODO: allocate internal IRQ controller */
4235}
4236
7856e3a4
AF
4237POWERPC_FAMILY(MPC8xx)(ObjectClass *oc, void *data)
4238{
ca5dff0a 4239 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4240 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4241
ca5dff0a 4242 dc->desc = "Freescale 8xx cores (aka PowerQUICC)";
7856e3a4
AF
4243 pcc->init_proc = init_proc_MPC8xx;
4244 pcc->check_pow = check_pow_none;
53116ebf
AF
4245 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4246 PPC_MEM_EIEIO | PPC_MEM_SYNC |
4247 PPC_CACHE_ICBI | PPC_MFTB;
9df5a466
TM
4248 pcc->msr_mask = (1ull << MSR_ILE) |
4249 (1ull << MSR_EE) |
4250 (1ull << MSR_PR) |
4251 (1ull << MSR_FP) |
4252 (1ull << MSR_ME) |
4253 (1ull << MSR_SE) |
4254 (1ull << MSR_DE) |
4255 (1ull << MSR_EP) |
4256 (1ull << MSR_IR) |
4257 (1ull << MSR_DR) |
4258 (1ull << MSR_RI) |
4259 (1ull << MSR_LE);
ba9fd9f1
AF
4260 pcc->mmu_model = POWERPC_MMU_MPC8xx;
4261 pcc->excp_model = POWERPC_EXCP_603;
4262 pcc->bus_model = PPC_FLAGS_INPUT_RCPU;
4263 pcc->bfd_mach = bfd_mach_ppc_860;
4264 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
4265 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4266}
4267
80d11f44 4268/* Freescale 82xx cores (aka PowerQUICC-II) */
ca5dff0a 4269
80d11f44 4270static void init_proc_G2 (CPUPPCState *env)
3fc6c082 4271{
80d11f44
JM
4272 gen_spr_ne_601(env);
4273 gen_spr_G2_755(env);
4274 gen_spr_G2(env);
a750fc0b
JM
4275 /* Time base */
4276 gen_tbl(env);
bd928eba
JM
4277 /* External access control */
4278 /* XXX : not implemented */
4279 spr_register(env, SPR_EAR, "EAR",
4280 SPR_NOACCESS, SPR_NOACCESS,
4281 &spr_read_generic, &spr_write_generic,
4282 0x00000000);
80d11f44
JM
4283 /* Hardware implementation register */
4284 /* XXX : not implemented */
4285 spr_register(env, SPR_HID0, "HID0",
4286 SPR_NOACCESS, SPR_NOACCESS,
4287 &spr_read_generic, &spr_write_generic,
4288 0x00000000);
4289 /* XXX : not implemented */
4290 spr_register(env, SPR_HID1, "HID1",
4291 SPR_NOACCESS, SPR_NOACCESS,
4292 &spr_read_generic, &spr_write_generic,
4293 0x00000000);
4294 /* XXX : not implemented */
4295 spr_register(env, SPR_HID2, "HID2",
4296 SPR_NOACCESS, SPR_NOACCESS,
4297 &spr_read_generic, &spr_write_generic,
4298 0x00000000);
a750fc0b 4299 /* Memory management */
80d11f44
JM
4300 gen_low_BATs(env);
4301 gen_high_BATs(env);
4302 gen_6xx_7xx_soft_tlb(env, 64, 2);
4303 init_excp_G2(env);
d63001d1
JM
4304 env->dcache_line_size = 32;
4305 env->icache_line_size = 32;
80d11f44
JM
4306 /* Allocate hardware IRQ controller */
4307 ppc6xx_irq_init(env);
3fc6c082 4308}
a750fc0b 4309
7856e3a4
AF
4310POWERPC_FAMILY(G2)(ObjectClass *oc, void *data)
4311{
ca5dff0a 4312 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4313 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4314
ca5dff0a 4315 dc->desc = "PowerPC G2";
7856e3a4
AF
4316 pcc->init_proc = init_proc_G2;
4317 pcc->check_pow = check_pow_hid0;
53116ebf
AF
4318 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4319 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4320 PPC_FLOAT_STFIWX |
4321 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4322 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4323 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4324 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
4325 pcc->msr_mask = (1ull << MSR_POW) |
4326 (1ull << MSR_TGPR) |
4327 (1ull << MSR_EE) |
4328 (1ull << MSR_PR) |
4329 (1ull << MSR_FP) |
4330 (1ull << MSR_ME) |
4331 (1ull << MSR_FE0) |
4332 (1ull << MSR_SE) |
4333 (1ull << MSR_DE) |
4334 (1ull << MSR_FE1) |
4335 (1ull << MSR_AL) |
4336 (1ull << MSR_EP) |
4337 (1ull << MSR_IR) |
4338 (1ull << MSR_DR) |
4339 (1ull << MSR_RI);
ba9fd9f1
AF
4340 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4341 pcc->excp_model = POWERPC_EXCP_G2;
4342 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4343 pcc->bfd_mach = bfd_mach_ppc_ec603e;
4344 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4345 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4346}
4347
80d11f44 4348static void init_proc_G2LE (CPUPPCState *env)
3fc6c082 4349{
80d11f44
JM
4350 gen_spr_ne_601(env);
4351 gen_spr_G2_755(env);
4352 gen_spr_G2(env);
a750fc0b
JM
4353 /* Time base */
4354 gen_tbl(env);
bd928eba
JM
4355 /* External access control */
4356 /* XXX : not implemented */
4357 spr_register(env, SPR_EAR, "EAR",
4358 SPR_NOACCESS, SPR_NOACCESS,
4359 &spr_read_generic, &spr_write_generic,
4360 0x00000000);
80d11f44 4361 /* Hardware implementation register */
578bb252 4362 /* XXX : not implemented */
80d11f44 4363 spr_register(env, SPR_HID0, "HID0",
a750fc0b
JM
4364 SPR_NOACCESS, SPR_NOACCESS,
4365 &spr_read_generic, &spr_write_generic,
4366 0x00000000);
80d11f44
JM
4367 /* XXX : not implemented */
4368 spr_register(env, SPR_HID1, "HID1",
a750fc0b
JM
4369 SPR_NOACCESS, SPR_NOACCESS,
4370 &spr_read_generic, &spr_write_generic,
4371 0x00000000);
578bb252 4372 /* XXX : not implemented */
80d11f44 4373 spr_register(env, SPR_HID2, "HID2",
a750fc0b
JM
4374 SPR_NOACCESS, SPR_NOACCESS,
4375 &spr_read_generic, &spr_write_generic,
4376 0x00000000);
2bc17322 4377
a750fc0b 4378 /* Memory management */
80d11f44
JM
4379 gen_low_BATs(env);
4380 gen_high_BATs(env);
4381 gen_6xx_7xx_soft_tlb(env, 64, 2);
4382 init_excp_G2(env);
d63001d1
JM
4383 env->dcache_line_size = 32;
4384 env->icache_line_size = 32;
80d11f44
JM
4385 /* Allocate hardware IRQ controller */
4386 ppc6xx_irq_init(env);
3fc6c082
FB
4387}
4388
7856e3a4
AF
4389POWERPC_FAMILY(G2LE)(ObjectClass *oc, void *data)
4390{
ca5dff0a 4391 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4392 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4393
ca5dff0a 4394 dc->desc = "PowerPC G2LE";
7856e3a4
AF
4395 pcc->init_proc = init_proc_G2LE;
4396 pcc->check_pow = check_pow_hid0;
53116ebf
AF
4397 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4398 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4399 PPC_FLOAT_STFIWX |
4400 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4401 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4402 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4403 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
4404 pcc->msr_mask = (1ull << MSR_POW) |
4405 (1ull << MSR_TGPR) |
4406 (1ull << MSR_ILE) |
4407 (1ull << MSR_EE) |
4408 (1ull << MSR_PR) |
4409 (1ull << MSR_FP) |
4410 (1ull << MSR_ME) |
4411 (1ull << MSR_FE0) |
4412 (1ull << MSR_SE) |
4413 (1ull << MSR_DE) |
4414 (1ull << MSR_FE1) |
4415 (1ull << MSR_AL) |
4416 (1ull << MSR_EP) |
4417 (1ull << MSR_IR) |
4418 (1ull << MSR_DR) |
4419 (1ull << MSR_RI) |
4420 (1ull << MSR_LE);
ba9fd9f1
AF
4421 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4422 pcc->excp_model = POWERPC_EXCP_G2;
4423 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4424 pcc->bfd_mach = bfd_mach_ppc_ec603e;
4425 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4426 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4427}
4428
80d11f44 4429static void init_proc_e200 (CPUPPCState *env)
3fc6c082 4430{
e1833e1f
JM
4431 /* Time base */
4432 gen_tbl(env);
80d11f44 4433 gen_spr_BookE(env, 0x000000070000FFFFULL);
578bb252 4434 /* XXX : not implemented */
80d11f44 4435 spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
d34defbc
AJ
4436 &spr_read_spefscr, &spr_write_spefscr,
4437 &spr_read_spefscr, &spr_write_spefscr,
e1833e1f 4438 0x00000000);
80d11f44 4439 /* Memory management */
01662f3e 4440 gen_spr_BookE206(env, 0x0000005D, NULL);
80d11f44
JM
4441 /* XXX : not implemented */
4442 spr_register(env, SPR_HID0, "HID0",
e1833e1f
JM
4443 SPR_NOACCESS, SPR_NOACCESS,
4444 &spr_read_generic, &spr_write_generic,
4445 0x00000000);
80d11f44
JM
4446 /* XXX : not implemented */
4447 spr_register(env, SPR_HID1, "HID1",
e1833e1f
JM
4448 SPR_NOACCESS, SPR_NOACCESS,
4449 &spr_read_generic, &spr_write_generic,
4450 0x00000000);
578bb252 4451 /* XXX : not implemented */
80d11f44 4452 spr_register(env, SPR_Exxx_ALTCTXCR, "ALTCTXCR",
e1833e1f
JM
4453 SPR_NOACCESS, SPR_NOACCESS,
4454 &spr_read_generic, &spr_write_generic,
4455 0x00000000);
578bb252 4456 /* XXX : not implemented */
80d11f44
JM
4457 spr_register(env, SPR_Exxx_BUCSR, "BUCSR",
4458 SPR_NOACCESS, SPR_NOACCESS,
e1833e1f 4459 &spr_read_generic, &spr_write_generic,
80d11f44
JM
4460 0x00000000);
4461 /* XXX : not implemented */
4462 spr_register(env, SPR_Exxx_CTXCR, "CTXCR",
4463 SPR_NOACCESS, SPR_NOACCESS,
4464 &spr_read_generic, &spr_write_generic,
4465 0x00000000);
4466 /* XXX : not implemented */
4467 spr_register(env, SPR_Exxx_DBCNT, "DBCNT",
4468 SPR_NOACCESS, SPR_NOACCESS,
4469 &spr_read_generic, &spr_write_generic,
4470 0x00000000);
4471 /* XXX : not implemented */
4472 spr_register(env, SPR_Exxx_DBCR3, "DBCR3",
4473 SPR_NOACCESS, SPR_NOACCESS,
4474 &spr_read_generic, &spr_write_generic,
4475 0x00000000);
4476 /* XXX : not implemented */
4477 spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0",
deb05c4c
AG
4478 &spr_read_generic, SPR_NOACCESS,
4479 &spr_read_generic, SPR_NOACCESS,
80d11f44
JM
4480 0x00000000);
4481 /* XXX : not implemented */
4482 spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0",
4483 SPR_NOACCESS, SPR_NOACCESS,
4484 &spr_read_generic, &spr_write_generic,
4485 0x00000000);
4486 /* XXX : not implemented */
4487 spr_register(env, SPR_Exxx_L1FINV0, "L1FINV0",
4488 SPR_NOACCESS, SPR_NOACCESS,
4489 &spr_read_generic, &spr_write_generic,
4490 0x00000000);
4491 /* XXX : not implemented */
4492 spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG",
4493 SPR_NOACCESS, SPR_NOACCESS,
4494 &spr_read_generic, &spr_write_generic,
4495 0x00000000);
4496 /* XXX : not implemented */
4497 spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG",
4498 SPR_NOACCESS, SPR_NOACCESS,
4499 &spr_read_generic, &spr_write_generic,
4500 0x00000000);
4501 /* XXX : not implemented */
4502 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4503 SPR_NOACCESS, SPR_NOACCESS,
4504 &spr_read_generic, &spr_write_generic,
4505 0x00000000);
4506 /* XXX : not implemented */
4507 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4508 SPR_NOACCESS, SPR_NOACCESS,
4509 &spr_read_generic, &spr_write_generic,
4510 0x00000000);
01662f3e
AG
4511 /* XXX : not implemented */
4512 spr_register(env, SPR_MMUCSR0, "MMUCSR0",
4513 SPR_NOACCESS, SPR_NOACCESS,
4514 &spr_read_generic, &spr_write_generic,
4515 0x00000000); /* TOFIX */
80d11f44
JM
4516 spr_register(env, SPR_BOOKE_DSRR0, "DSRR0",
4517 SPR_NOACCESS, SPR_NOACCESS,
4518 &spr_read_generic, &spr_write_generic,
4519 0x00000000);
4520 spr_register(env, SPR_BOOKE_DSRR1, "DSRR1",
4521 SPR_NOACCESS, SPR_NOACCESS,
e1833e1f
JM
4522 &spr_read_generic, &spr_write_generic,
4523 0x00000000);
f2e63a42 4524#if !defined(CONFIG_USER_ONLY)
e1833e1f
JM
4525 env->nb_tlb = 64;
4526 env->nb_ways = 1;
4527 env->id_tlbs = 0;
1c53accc 4528 env->tlb_type = TLB_EMB;
f2e63a42 4529#endif
e9cd84b9 4530 init_excp_e200(env, 0xFFFF0000UL);
d63001d1
JM
4531 env->dcache_line_size = 32;
4532 env->icache_line_size = 32;
e1833e1f 4533 /* XXX: TODO: allocate internal IRQ controller */
3fc6c082 4534}
a750fc0b 4535
7856e3a4
AF
4536POWERPC_FAMILY(e200)(ObjectClass *oc, void *data)
4537{
ca5dff0a 4538 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4539 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4540
ca5dff0a 4541 dc->desc = "e200 core";
7856e3a4
AF
4542 pcc->init_proc = init_proc_e200;
4543 pcc->check_pow = check_pow_hid0;
53116ebf
AF
4544 /* XXX: unimplemented instructions:
4545 * dcblc
4546 * dcbtlst
4547 * dcbtstls
4548 * icblc
4549 * icbtls
4550 * tlbivax
4551 * all SPE multiply-accumulate instructions
4552 */
4553 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
4554 PPC_SPE | PPC_SPE_SINGLE |
4555 PPC_WRTEE | PPC_RFDI |
4556 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
4557 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4558 PPC_MEM_TLBSYNC | PPC_TLBIVAX |
4559 PPC_BOOKE;
9df5a466
TM
4560 pcc->msr_mask = (1ull << MSR_UCLE) |
4561 (1ull << MSR_SPE) |
4562 (1ull << MSR_POW) |
4563 (1ull << MSR_CE) |
4564 (1ull << MSR_EE) |
4565 (1ull << MSR_PR) |
4566 (1ull << MSR_FP) |
4567 (1ull << MSR_ME) |
4568 (1ull << MSR_FE0) |
4569 (1ull << MSR_DWE) |
4570 (1ull << MSR_DE) |
4571 (1ull << MSR_FE1) |
4572 (1ull << MSR_IR) |
4573 (1ull << MSR_DR);
ba9fd9f1
AF
4574 pcc->mmu_model = POWERPC_MMU_BOOKE206;
4575 pcc->excp_model = POWERPC_EXCP_BOOKE;
4576 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4577 pcc->bfd_mach = bfd_mach_ppc_860;
4578 pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
4579 POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
4580 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4581}
4582
80d11f44 4583static void init_proc_e300 (CPUPPCState *env)
3fc6c082 4584{
80d11f44
JM
4585 gen_spr_ne_601(env);
4586 gen_spr_603(env);
a750fc0b
JM
4587 /* Time base */
4588 gen_tbl(env);
80d11f44
JM
4589 /* hardware implementation registers */
4590 /* XXX : not implemented */
4591 spr_register(env, SPR_HID0, "HID0",
4592 SPR_NOACCESS, SPR_NOACCESS,
4593 &spr_read_generic, &spr_write_generic,
4594 0x00000000);
4595 /* XXX : not implemented */
4596 spr_register(env, SPR_HID1, "HID1",
4597 SPR_NOACCESS, SPR_NOACCESS,
4598 &spr_read_generic, &spr_write_generic,
4599 0x00000000);
8daf1781
TM
4600 /* XXX : not implemented */
4601 spr_register(env, SPR_HID2, "HID2",
4602 SPR_NOACCESS, SPR_NOACCESS,
4603 &spr_read_generic, &spr_write_generic,
4604 0x00000000);
3ade1a05
FC
4605 /* Breakpoints */
4606 /* XXX : not implemented */
4607 spr_register(env, SPR_DABR, "DABR",
4608 SPR_NOACCESS, SPR_NOACCESS,
4609 &spr_read_generic, &spr_write_generic,
4610 0x00000000);
4611 /* XXX : not implemented */
4612 spr_register(env, SPR_DABR2, "DABR2",
4613 SPR_NOACCESS, SPR_NOACCESS,
4614 &spr_read_generic, &spr_write_generic,
4615 0x00000000);
4616 /* XXX : not implemented */
4617 spr_register(env, SPR_IABR2, "IABR2",
4618 SPR_NOACCESS, SPR_NOACCESS,
4619 &spr_read_generic, &spr_write_generic,
4620 0x00000000);
4621 /* XXX : not implemented */
4622 spr_register(env, SPR_IBCR, "IBCR",
4623 SPR_NOACCESS, SPR_NOACCESS,
4624 &spr_read_generic, &spr_write_generic,
4625 0x00000000);
4626 /* XXX : not implemented */
4627 spr_register(env, SPR_DBCR, "DBCR",
4628 SPR_NOACCESS, SPR_NOACCESS,
4629 &spr_read_generic, &spr_write_generic,
4630 0x00000000);
80d11f44
JM
4631 /* Memory management */
4632 gen_low_BATs(env);
8daf1781 4633 gen_high_BATs(env);
80d11f44
JM
4634 gen_6xx_7xx_soft_tlb(env, 64, 2);
4635 init_excp_603(env);
4636 env->dcache_line_size = 32;
4637 env->icache_line_size = 32;
4638 /* Allocate hardware IRQ controller */
4639 ppc6xx_irq_init(env);
4640}
4641
7856e3a4
AF
4642POWERPC_FAMILY(e300)(ObjectClass *oc, void *data)
4643{
ca5dff0a 4644 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4645 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4646
ca5dff0a 4647 dc->desc = "e300 core";
7856e3a4
AF
4648 pcc->init_proc = init_proc_e300;
4649 pcc->check_pow = check_pow_hid0;
53116ebf
AF
4650 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4651 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4652 PPC_FLOAT_STFIWX |
4653 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4654 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4655 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4656 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
4657 pcc->msr_mask = (1ull << MSR_POW) |
4658 (1ull << MSR_TGPR) |
4659 (1ull << MSR_ILE) |
4660 (1ull << MSR_EE) |
4661 (1ull << MSR_PR) |
4662 (1ull << MSR_FP) |
4663 (1ull << MSR_ME) |
4664 (1ull << MSR_FE0) |
4665 (1ull << MSR_SE) |
4666 (1ull << MSR_DE) |
4667 (1ull << MSR_FE1) |
4668 (1ull << MSR_AL) |
4669 (1ull << MSR_EP) |
4670 (1ull << MSR_IR) |
4671 (1ull << MSR_DR) |
4672 (1ull << MSR_RI) |
4673 (1ull << MSR_LE);
ba9fd9f1
AF
4674 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4675 pcc->excp_model = POWERPC_EXCP_603;
4676 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4677 pcc->bfd_mach = bfd_mach_ppc_603;
4678 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4679 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4680}
4681
b81ccf8a
AG
4682#if !defined(CONFIG_USER_ONLY)
4683static void spr_write_mas73(void *opaque, int sprn, int gprn)
4684{
4685 TCGv val = tcg_temp_new();
4686 tcg_gen_ext32u_tl(val, cpu_gpr[gprn]);
4687 gen_store_spr(SPR_BOOKE_MAS3, val);
cfee0218 4688 tcg_gen_shri_tl(val, cpu_gpr[gprn], 32);
b81ccf8a
AG
4689 gen_store_spr(SPR_BOOKE_MAS7, val);
4690 tcg_temp_free(val);
4691}
4692
4693static void spr_read_mas73(void *opaque, int gprn, int sprn)
4694{
4695 TCGv mas7 = tcg_temp_new();
4696 TCGv mas3 = tcg_temp_new();
4697 gen_load_spr(mas7, SPR_BOOKE_MAS7);
4698 tcg_gen_shli_tl(mas7, mas7, 32);
4699 gen_load_spr(mas3, SPR_BOOKE_MAS3);
4700 tcg_gen_or_tl(cpu_gpr[gprn], mas3, mas7);
4701 tcg_temp_free(mas3);
4702 tcg_temp_free(mas7);
4703}
4704
b81ccf8a
AG
4705#endif
4706
f7aa5583
VS
4707enum fsl_e500_version {
4708 fsl_e500v1,
4709 fsl_e500v2,
4710 fsl_e500mc,
b81ccf8a 4711 fsl_e5500,
f7aa5583
VS
4712};
4713
01662f3e 4714static void init_proc_e500 (CPUPPCState *env, int version)
80d11f44 4715{
a47dddd7 4716 PowerPCCPU *cpu = ppc_env_get_cpu(env);
01662f3e 4717 uint32_t tlbncfg[2];
b81ccf8a 4718 uint64_t ivor_mask;
e9cd84b9 4719 uint64_t ivpr_mask = 0xFFFF0000ULL;
a496e8ee
AG
4720 uint32_t l1cfg0 = 0x3800 /* 8 ways */
4721 | 0x0020; /* 32 kb */
d2ea2bf7
AG
4722 uint32_t l1cfg1 = 0x3800 /* 8 ways */
4723 | 0x0020; /* 32 kb */
01662f3e
AG
4724#if !defined(CONFIG_USER_ONLY)
4725 int i;
4726#endif
4727
80d11f44
JM
4728 /* Time base */
4729 gen_tbl(env);
01662f3e
AG
4730 /*
4731 * XXX The e500 doesn't implement IVOR7 and IVOR9, but doesn't
4732 * complain when accessing them.
4733 * gen_spr_BookE(env, 0x0000000F0000FD7FULL);
4734 */
b81ccf8a
AG
4735 switch (version) {
4736 case fsl_e500v1:
4737 case fsl_e500v2:
4738 default:
4739 ivor_mask = 0x0000000F0000FFFFULL;
4740 break;
4741 case fsl_e500mc:
4742 case fsl_e5500:
4743 ivor_mask = 0x000003FE0000FFFFULL;
4744 break;
2c9732db
AG
4745 }
4746 gen_spr_BookE(env, ivor_mask);
80d11f44
JM
4747 /* Processor identification */
4748 spr_register(env, SPR_BOOKE_PIR, "PIR",
4749 SPR_NOACCESS, SPR_NOACCESS,
4750 &spr_read_generic, &spr_write_pir,
4751 0x00000000);
4752 /* XXX : not implemented */
4753 spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
d34defbc
AJ
4754 &spr_read_spefscr, &spr_write_spefscr,
4755 &spr_read_spefscr, &spr_write_spefscr,
80d11f44 4756 0x00000000);
892c587f 4757#if !defined(CONFIG_USER_ONLY)
80d11f44 4758 /* Memory management */
80d11f44 4759 env->nb_pids = 3;
01662f3e
AG
4760 env->nb_ways = 2;
4761 env->id_tlbs = 0;
4762 switch (version) {
f7aa5583 4763 case fsl_e500v1:
01662f3e
AG
4764 tlbncfg[0] = gen_tlbncfg(2, 1, 1, 0, 256);
4765 tlbncfg[1] = gen_tlbncfg(16, 1, 9, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16);
4766 break;
f7aa5583 4767 case fsl_e500v2:
01662f3e
AG
4768 tlbncfg[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4769 tlbncfg[1] = gen_tlbncfg(16, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16);
f7aa5583
VS
4770 break;
4771 case fsl_e500mc:
b81ccf8a 4772 case fsl_e5500:
f7aa5583
VS
4773 tlbncfg[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4774 tlbncfg[1] = gen_tlbncfg(64, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 64);
892c587f
AG
4775 break;
4776 default:
a47dddd7 4777 cpu_abort(CPU(cpu), "Unknown CPU: " TARGET_FMT_lx "\n", env->spr[SPR_PVR]);
892c587f
AG
4778 }
4779#endif
4780 /* Cache sizes */
4781 switch (version) {
4782 case fsl_e500v1:
4783 case fsl_e500v2:
4784 env->dcache_line_size = 32;
4785 env->icache_line_size = 32;
4786 break;
4787 case fsl_e500mc:
b81ccf8a 4788 case fsl_e5500:
f7aa5583
VS
4789 env->dcache_line_size = 64;
4790 env->icache_line_size = 64;
a496e8ee 4791 l1cfg0 |= 0x1000000; /* 64 byte cache block size */
d2ea2bf7 4792 l1cfg1 |= 0x1000000; /* 64 byte cache block size */
01662f3e
AG
4793 break;
4794 default:
a47dddd7 4795 cpu_abort(CPU(cpu), "Unknown CPU: " TARGET_FMT_lx "\n", env->spr[SPR_PVR]);
01662f3e 4796 }
01662f3e 4797 gen_spr_BookE206(env, 0x000000DF, tlbncfg);
80d11f44
JM
4798 /* XXX : not implemented */
4799 spr_register(env, SPR_HID0, "HID0",
4800 SPR_NOACCESS, SPR_NOACCESS,
4801 &spr_read_generic, &spr_write_generic,
4802 0x00000000);
4803 /* XXX : not implemented */
4804 spr_register(env, SPR_HID1, "HID1",
4805 SPR_NOACCESS, SPR_NOACCESS,
4806 &spr_read_generic, &spr_write_generic,
4807 0x00000000);
4808 /* XXX : not implemented */
4809 spr_register(env, SPR_Exxx_BBEAR, "BBEAR",
4810 SPR_NOACCESS, SPR_NOACCESS,
4811 &spr_read_generic, &spr_write_generic,
4812 0x00000000);
4813 /* XXX : not implemented */
4814 spr_register(env, SPR_Exxx_BBTAR, "BBTAR",
4815 SPR_NOACCESS, SPR_NOACCESS,
4816 &spr_read_generic, &spr_write_generic,
4817 0x00000000);
4818 /* XXX : not implemented */
4819 spr_register(env, SPR_Exxx_MCAR, "MCAR",
4820 SPR_NOACCESS, SPR_NOACCESS,
4821 &spr_read_generic, &spr_write_generic,
4822 0x00000000);
578bb252 4823 /* XXX : not implemented */
a750fc0b
JM
4824 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
4825 SPR_NOACCESS, SPR_NOACCESS,
4826 &spr_read_generic, &spr_write_generic,
4827 0x00000000);
80d11f44
JM
4828 /* XXX : not implemented */
4829 spr_register(env, SPR_Exxx_NPIDR, "NPIDR",
a750fc0b
JM
4830 SPR_NOACCESS, SPR_NOACCESS,
4831 &spr_read_generic, &spr_write_generic,
4832 0x00000000);
80d11f44
JM
4833 /* XXX : not implemented */
4834 spr_register(env, SPR_Exxx_BUCSR, "BUCSR",
a750fc0b
JM
4835 SPR_NOACCESS, SPR_NOACCESS,
4836 &spr_read_generic, &spr_write_generic,
4837 0x00000000);
578bb252 4838 /* XXX : not implemented */
80d11f44 4839 spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0",
deb05c4c
AG
4840 &spr_read_generic, SPR_NOACCESS,
4841 &spr_read_generic, SPR_NOACCESS,
a496e8ee 4842 l1cfg0);
d2ea2bf7
AG
4843 spr_register(env, SPR_Exxx_L1CFG1, "L1CFG1",
4844 &spr_read_generic, SPR_NOACCESS,
4845 &spr_read_generic, SPR_NOACCESS,
4846 l1cfg1);
80d11f44
JM
4847 spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0",
4848 SPR_NOACCESS, SPR_NOACCESS,
01662f3e 4849 &spr_read_generic, &spr_write_e500_l1csr0,
80d11f44 4850 0x00000000);
80d11f44
JM
4851 spr_register(env, SPR_Exxx_L1CSR1, "L1CSR1",
4852 SPR_NOACCESS, SPR_NOACCESS,
ea71258d 4853 &spr_read_generic, &spr_write_e500_l1csr1,
80d11f44 4854 0x00000000);
80d11f44
JM
4855 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
4856 SPR_NOACCESS, SPR_NOACCESS,
4857 &spr_read_generic, &spr_write_generic,
4858 0x00000000);
4859 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
4860 SPR_NOACCESS, SPR_NOACCESS,
a750fc0b
JM
4861 &spr_read_generic, &spr_write_generic,
4862 0x00000000);
01662f3e
AG
4863 spr_register(env, SPR_MMUCSR0, "MMUCSR0",
4864 SPR_NOACCESS, SPR_NOACCESS,
4865 &spr_read_generic, &spr_write_booke206_mmucsr0,
4866 0x00000000);
b81ccf8a
AG
4867 spr_register(env, SPR_BOOKE_EPR, "EPR",
4868 SPR_NOACCESS, SPR_NOACCESS,
68c2dd70 4869 &spr_read_generic, SPR_NOACCESS,
b81ccf8a
AG
4870 0x00000000);
4871 /* XXX better abstract into Emb.xxx features */
4872 if (version == fsl_e5500) {
4873 spr_register(env, SPR_BOOKE_EPCR, "EPCR",
4874 SPR_NOACCESS, SPR_NOACCESS,
4875 &spr_read_generic, &spr_write_generic,
4876 0x00000000);
4877 spr_register(env, SPR_BOOKE_MAS7_MAS3, "MAS7_MAS3",
4878 SPR_NOACCESS, SPR_NOACCESS,
4879 &spr_read_mas73, &spr_write_mas73,
4880 0x00000000);
4881 ivpr_mask = (target_ulong)~0xFFFFULL;
4882 }
01662f3e 4883
f2e63a42 4884#if !defined(CONFIG_USER_ONLY)
01662f3e 4885 env->nb_tlb = 0;
1c53accc 4886 env->tlb_type = TLB_MAS;
01662f3e
AG
4887 for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
4888 env->nb_tlb += booke206_tlb_size(env, i);
4889 }
f2e63a42 4890#endif
01662f3e 4891
e9cd84b9 4892 init_excp_e200(env, ivpr_mask);
9fdc60bf
AJ
4893 /* Allocate hardware IRQ controller */
4894 ppce500_irq_init(env);
3fc6c082 4895}
a750fc0b 4896
01662f3e
AG
4897static void init_proc_e500v1(CPUPPCState *env)
4898{
f7aa5583 4899 init_proc_e500(env, fsl_e500v1);
01662f3e
AG
4900}
4901
7856e3a4
AF
4902POWERPC_FAMILY(e500v1)(ObjectClass *oc, void *data)
4903{
ca5dff0a 4904 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4905 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4906
ca5dff0a 4907 dc->desc = "e500v1 core";
7856e3a4
AF
4908 pcc->init_proc = init_proc_e500v1;
4909 pcc->check_pow = check_pow_hid0;
53116ebf
AF
4910 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
4911 PPC_SPE | PPC_SPE_SINGLE |
4912 PPC_WRTEE | PPC_RFDI |
4913 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
4914 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4915 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
4916 pcc->insns_flags2 = PPC2_BOOKE206;
9df5a466
TM
4917 pcc->msr_mask = (1ull << MSR_UCLE) |
4918 (1ull << MSR_SPE) |
4919 (1ull << MSR_POW) |
4920 (1ull << MSR_CE) |
4921 (1ull << MSR_EE) |
4922 (1ull << MSR_PR) |
4923 (1ull << MSR_FP) |
4924 (1ull << MSR_ME) |
4925 (1ull << MSR_FE0) |
4926 (1ull << MSR_DWE) |
4927 (1ull << MSR_DE) |
4928 (1ull << MSR_FE1) |
4929 (1ull << MSR_IR) |
4930 (1ull << MSR_DR);
ba9fd9f1
AF
4931 pcc->mmu_model = POWERPC_MMU_BOOKE206;
4932 pcc->excp_model = POWERPC_EXCP_BOOKE;
4933 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4934 pcc->bfd_mach = bfd_mach_ppc_860;
4935 pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
4936 POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
4937 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4938}
4939
01662f3e
AG
4940static void init_proc_e500v2(CPUPPCState *env)
4941{
f7aa5583
VS
4942 init_proc_e500(env, fsl_e500v2);
4943}
4944
7856e3a4
AF
4945POWERPC_FAMILY(e500v2)(ObjectClass *oc, void *data)
4946{
ca5dff0a 4947 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4948 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4949
ca5dff0a 4950 dc->desc = "e500v2 core";
7856e3a4
AF
4951 pcc->init_proc = init_proc_e500v2;
4952 pcc->check_pow = check_pow_hid0;
53116ebf
AF
4953 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
4954 PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE |
4955 PPC_WRTEE | PPC_RFDI |
4956 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
4957 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4958 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
4959 pcc->insns_flags2 = PPC2_BOOKE206;
9df5a466
TM
4960 pcc->msr_mask = (1ull << MSR_UCLE) |
4961 (1ull << MSR_SPE) |
4962 (1ull << MSR_POW) |
4963 (1ull << MSR_CE) |
4964 (1ull << MSR_EE) |
4965 (1ull << MSR_PR) |
4966 (1ull << MSR_FP) |
4967 (1ull << MSR_ME) |
4968 (1ull << MSR_FE0) |
4969 (1ull << MSR_DWE) |
4970 (1ull << MSR_DE) |
4971 (1ull << MSR_FE1) |
4972 (1ull << MSR_IR) |
4973 (1ull << MSR_DR);
ba9fd9f1
AF
4974 pcc->mmu_model = POWERPC_MMU_BOOKE206;
4975 pcc->excp_model = POWERPC_EXCP_BOOKE;
4976 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4977 pcc->bfd_mach = bfd_mach_ppc_860;
4978 pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
4979 POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
4980 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
4981}
4982
f7aa5583
VS
4983static void init_proc_e500mc(CPUPPCState *env)
4984{
4985 init_proc_e500(env, fsl_e500mc);
01662f3e
AG
4986}
4987
7856e3a4
AF
4988POWERPC_FAMILY(e500mc)(ObjectClass *oc, void *data)
4989{
ca5dff0a 4990 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
4991 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4992
ca5dff0a 4993 dc->desc = "e500mc core";
7856e3a4
AF
4994 pcc->init_proc = init_proc_e500mc;
4995 pcc->check_pow = check_pow_none;
53116ebf
AF
4996 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
4997 PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
4998 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
4999 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5000 PPC_FLOAT | PPC_FLOAT_FRES |
5001 PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
5002 PPC_FLOAT_STFIWX | PPC_WAIT |
5003 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
5004 pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL;
9df5a466
TM
5005 pcc->msr_mask = (1ull << MSR_GS) |
5006 (1ull << MSR_UCLE) |
5007 (1ull << MSR_CE) |
5008 (1ull << MSR_EE) |
5009 (1ull << MSR_PR) |
5010 (1ull << MSR_FP) |
5011 (1ull << MSR_ME) |
5012 (1ull << MSR_FE0) |
5013 (1ull << MSR_DE) |
5014 (1ull << MSR_FE1) |
5015 (1ull << MSR_IR) |
5016 (1ull << MSR_DR) |
5017 (1ull << MSR_PX) |
5018 (1ull << MSR_RI);
ba9fd9f1
AF
5019 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5020 pcc->excp_model = POWERPC_EXCP_BOOKE;
5021 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5022 /* FIXME: figure out the correct flag for e500mc */
5023 pcc->bfd_mach = bfd_mach_ppc_e500;
5024 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
5025 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5026}
5027
b81ccf8a
AG
5028#ifdef TARGET_PPC64
5029static void init_proc_e5500(CPUPPCState *env)
5030{
5031 init_proc_e500(env, fsl_e5500);
5032}
7856e3a4
AF
5033
5034POWERPC_FAMILY(e5500)(ObjectClass *oc, void *data)
5035{
ca5dff0a 5036 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5037 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5038
ca5dff0a 5039 dc->desc = "e5500 core";
7856e3a4
AF
5040 pcc->init_proc = init_proc_e5500;
5041 pcc->check_pow = check_pow_none;
53116ebf
AF
5042 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
5043 PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
5044 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5045 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5046 PPC_FLOAT | PPC_FLOAT_FRES |
5047 PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
5048 PPC_FLOAT_STFIWX | PPC_WAIT |
5049 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC |
5050 PPC_64B | PPC_POPCNTB | PPC_POPCNTWD;
4171853c
PM
5051 pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL | PPC2_PERM_ISA206 | \
5052 PPC2_FP_CVT_S64;
9df5a466
TM
5053 pcc->msr_mask = (1ull << MSR_CM) |
5054 (1ull << MSR_GS) |
5055 (1ull << MSR_UCLE) |
5056 (1ull << MSR_CE) |
5057 (1ull << MSR_EE) |
5058 (1ull << MSR_PR) |
5059 (1ull << MSR_FP) |
5060 (1ull << MSR_ME) |
5061 (1ull << MSR_FE0) |
5062 (1ull << MSR_DE) |
5063 (1ull << MSR_FE1) |
5064 (1ull << MSR_IR) |
5065 (1ull << MSR_DR) |
5066 (1ull << MSR_PX) |
5067 (1ull << MSR_RI);
ba9fd9f1
AF
5068 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5069 pcc->excp_model = POWERPC_EXCP_BOOKE;
5070 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5071 /* FIXME: figure out the correct flag for e5500 */
5072 pcc->bfd_mach = bfd_mach_ppc_e500;
5073 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
5074 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4 5075}
b81ccf8a
AG
5076#endif
5077
a750fc0b 5078/* Non-embedded PowerPC */
a750fc0b
JM
5079
5080/* POWER : same as 601, without mfmsr, mfsr */
53116ebf
AF
5081POWERPC_FAMILY(POWER)(ObjectClass *oc, void *data)
5082{
ca5dff0a 5083 DeviceClass *dc = DEVICE_CLASS(oc);
53116ebf
AF
5084 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5085
ca5dff0a 5086 dc->desc = "POWER";
953af181 5087 /* pcc->insns_flags = XXX_TODO; */
ba9fd9f1 5088 /* POWER RSC (from RAD6000) */
9df5a466
TM
5089 pcc->msr_mask = (1ull << MSR_EE) |
5090 (1ull << MSR_PR) |
5091 (1ull << MSR_FP) |
5092 (1ull << MSR_ME) |
5093 (1ull << MSR_FE0) |
5094 (1ull << MSR_SE) |
5095 (1ull << MSR_DE) |
5096 (1ull << MSR_AL) |
5097 (1ull << MSR_EP) |
5098 (1ull << MSR_IR) |
5099 (1ull << MSR_DR);
53116ebf 5100}
a750fc0b 5101
082c6681 5102#define POWERPC_MSRR_601 (0x0000000000001040ULL)
a750fc0b
JM
5103
5104static void init_proc_601 (CPUPPCState *env)
3fc6c082 5105{
a750fc0b
JM
5106 gen_spr_ne_601(env);
5107 gen_spr_601(env);
5108 /* Hardware implementation registers */
5109 /* XXX : not implemented */
5110 spr_register(env, SPR_HID0, "HID0",
5111 SPR_NOACCESS, SPR_NOACCESS,
056401ea 5112 &spr_read_generic, &spr_write_hid0_601,
faadf50e 5113 0x80010080);
a750fc0b
JM
5114 /* XXX : not implemented */
5115 spr_register(env, SPR_HID1, "HID1",
5116 SPR_NOACCESS, SPR_NOACCESS,
5117 &spr_read_generic, &spr_write_generic,
5118 0x00000000);
5119 /* XXX : not implemented */
5120 spr_register(env, SPR_601_HID2, "HID2",
5121 SPR_NOACCESS, SPR_NOACCESS,
5122 &spr_read_generic, &spr_write_generic,
5123 0x00000000);
5124 /* XXX : not implemented */
5125 spr_register(env, SPR_601_HID5, "HID5",
5126 SPR_NOACCESS, SPR_NOACCESS,
5127 &spr_read_generic, &spr_write_generic,
5128 0x00000000);
a750fc0b 5129 /* Memory management */
e1833e1f 5130 init_excp_601(env);
082c6681
JM
5131 /* XXX: beware that dcache line size is 64
5132 * but dcbz uses 32 bytes "sectors"
5133 * XXX: this breaks clcs instruction !
5134 */
5135 env->dcache_line_size = 32;
d63001d1 5136 env->icache_line_size = 64;
faadf50e
JM
5137 /* Allocate hardware IRQ controller */
5138 ppc6xx_irq_init(env);
3fc6c082
FB
5139}
5140
7856e3a4
AF
5141POWERPC_FAMILY(601)(ObjectClass *oc, void *data)
5142{
ca5dff0a 5143 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5144 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5145
ca5dff0a 5146 dc->desc = "PowerPC 601";
7856e3a4
AF
5147 pcc->init_proc = init_proc_601;
5148 pcc->check_pow = check_pow_none;
53116ebf
AF
5149 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
5150 PPC_FLOAT |
5151 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5152 PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
5153 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
5154 pcc->msr_mask = (1ull << MSR_EE) |
5155 (1ull << MSR_PR) |
5156 (1ull << MSR_FP) |
5157 (1ull << MSR_ME) |
5158 (1ull << MSR_FE0) |
5159 (1ull << MSR_SE) |
5160 (1ull << MSR_FE1) |
5161 (1ull << MSR_EP) |
5162 (1ull << MSR_IR) |
5163 (1ull << MSR_DR);
ba9fd9f1 5164 pcc->mmu_model = POWERPC_MMU_601;
b632a148
DG
5165#if defined(CONFIG_SOFTMMU)
5166 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5167#endif
ba9fd9f1
AF
5168 pcc->excp_model = POWERPC_EXCP_601;
5169 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5170 pcc->bfd_mach = bfd_mach_ppc_601;
5171 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK;
7856e3a4
AF
5172}
5173
082c6681 5174#define POWERPC_MSRR_601v (0x0000000000001040ULL)
082c6681
JM
5175
5176static void init_proc_601v (CPUPPCState *env)
5177{
5178 init_proc_601(env);
5179 /* XXX : not implemented */
5180 spr_register(env, SPR_601_HID15, "HID15",
5181 SPR_NOACCESS, SPR_NOACCESS,
5182 &spr_read_generic, &spr_write_generic,
5183 0x00000000);
5184}
5185
7856e3a4
AF
5186POWERPC_FAMILY(601v)(ObjectClass *oc, void *data)
5187{
ca5dff0a 5188 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5189 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5190
ca5dff0a 5191 dc->desc = "PowerPC 601v";
7856e3a4
AF
5192 pcc->init_proc = init_proc_601v;
5193 pcc->check_pow = check_pow_none;
53116ebf
AF
5194 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
5195 PPC_FLOAT |
5196 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5197 PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
5198 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
5199 pcc->msr_mask = (1ull << MSR_EE) |
5200 (1ull << MSR_PR) |
5201 (1ull << MSR_FP) |
5202 (1ull << MSR_ME) |
5203 (1ull << MSR_FE0) |
5204 (1ull << MSR_SE) |
5205 (1ull << MSR_FE1) |
5206 (1ull << MSR_EP) |
5207 (1ull << MSR_IR) |
5208 (1ull << MSR_DR);
ba9fd9f1 5209 pcc->mmu_model = POWERPC_MMU_601;
b632a148
DG
5210#if defined(CONFIG_SOFTMMU)
5211 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5212#endif
ba9fd9f1
AF
5213 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5214 pcc->bfd_mach = bfd_mach_ppc_601;
5215 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK;
7856e3a4
AF
5216}
5217
a750fc0b 5218static void init_proc_602 (CPUPPCState *env)
3fc6c082 5219{
a750fc0b
JM
5220 gen_spr_ne_601(env);
5221 gen_spr_602(env);
5222 /* Time base */
5223 gen_tbl(env);
5224 /* hardware implementation registers */
5225 /* XXX : not implemented */
5226 spr_register(env, SPR_HID0, "HID0",
5227 SPR_NOACCESS, SPR_NOACCESS,
5228 &spr_read_generic, &spr_write_generic,
5229 0x00000000);
5230 /* XXX : not implemented */
5231 spr_register(env, SPR_HID1, "HID1",
5232 SPR_NOACCESS, SPR_NOACCESS,
5233 &spr_read_generic, &spr_write_generic,
5234 0x00000000);
5235 /* Memory management */
5236 gen_low_BATs(env);
5237 gen_6xx_7xx_soft_tlb(env, 64, 2);
e1833e1f 5238 init_excp_602(env);
d63001d1
JM
5239 env->dcache_line_size = 32;
5240 env->icache_line_size = 32;
a750fc0b
JM
5241 /* Allocate hardware IRQ controller */
5242 ppc6xx_irq_init(env);
5243}
3fc6c082 5244
7856e3a4
AF
5245POWERPC_FAMILY(602)(ObjectClass *oc, void *data)
5246{
ca5dff0a 5247 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5248 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5249
ca5dff0a 5250 dc->desc = "PowerPC 602";
7856e3a4
AF
5251 pcc->init_proc = init_proc_602;
5252 pcc->check_pow = check_pow_hid0;
53116ebf
AF
5253 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5254 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5255 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5256 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5257 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5258 PPC_MEM_TLBIE | PPC_6xx_TLB | PPC_MEM_TLBSYNC |
5259 PPC_SEGMENT | PPC_602_SPEC;
9df5a466
TM
5260 pcc->msr_mask = (1ull << MSR_VSX) |
5261 (1ull << MSR_SA) |
5262 (1ull << MSR_POW) |
5263 (1ull << MSR_TGPR) |
5264 (1ull << MSR_ILE) |
5265 (1ull << MSR_EE) |
5266 (1ull << MSR_PR) |
5267 (1ull << MSR_FP) |
5268 (1ull << MSR_ME) |
5269 (1ull << MSR_FE0) |
5270 (1ull << MSR_SE) |
5271 (1ull << MSR_DE) |
5272 (1ull << MSR_FE1) |
5273 (1ull << MSR_EP) |
5274 (1ull << MSR_IR) |
5275 (1ull << MSR_DR) |
5276 (1ull << MSR_RI) |
5277 (1ull << MSR_LE);
ba9fd9f1
AF
5278 /* XXX: 602 MMU is quite specific. Should add a special case */
5279 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
5280 pcc->excp_model = POWERPC_EXCP_602;
5281 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5282 pcc->bfd_mach = bfd_mach_ppc_602;
5283 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
5284 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5285}
5286
a750fc0b
JM
5287static void init_proc_603 (CPUPPCState *env)
5288{
5289 gen_spr_ne_601(env);
5290 gen_spr_603(env);
5291 /* Time base */
5292 gen_tbl(env);
5293 /* hardware implementation registers */
5294 /* XXX : not implemented */
5295 spr_register(env, SPR_HID0, "HID0",
5296 SPR_NOACCESS, SPR_NOACCESS,
5297 &spr_read_generic, &spr_write_generic,
5298 0x00000000);
5299 /* XXX : not implemented */
5300 spr_register(env, SPR_HID1, "HID1",
5301 SPR_NOACCESS, SPR_NOACCESS,
5302 &spr_read_generic, &spr_write_generic,
5303 0x00000000);
5304 /* Memory management */
5305 gen_low_BATs(env);
5306 gen_6xx_7xx_soft_tlb(env, 64, 2);
e1833e1f 5307 init_excp_603(env);
d63001d1
JM
5308 env->dcache_line_size = 32;
5309 env->icache_line_size = 32;
a750fc0b
JM
5310 /* Allocate hardware IRQ controller */
5311 ppc6xx_irq_init(env);
3fc6c082
FB
5312}
5313
7856e3a4
AF
5314POWERPC_FAMILY(603)(ObjectClass *oc, void *data)
5315{
ca5dff0a 5316 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5317 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5318
ca5dff0a 5319 dc->desc = "PowerPC 603";
7856e3a4
AF
5320 pcc->init_proc = init_proc_603;
5321 pcc->check_pow = check_pow_hid0;
53116ebf
AF
5322 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5323 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5324 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5325 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5326 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5327 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
5328 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
5329 pcc->msr_mask = (1ull << MSR_POW) |
5330 (1ull << MSR_TGPR) |
5331 (1ull << MSR_ILE) |
5332 (1ull << MSR_EE) |
5333 (1ull << MSR_PR) |
5334 (1ull << MSR_FP) |
5335 (1ull << MSR_ME) |
5336 (1ull << MSR_FE0) |
5337 (1ull << MSR_SE) |
5338 (1ull << MSR_DE) |
5339 (1ull << MSR_FE1) |
5340 (1ull << MSR_EP) |
5341 (1ull << MSR_IR) |
5342 (1ull << MSR_DR) |
5343 (1ull << MSR_RI) |
5344 (1ull << MSR_LE);
ba9fd9f1
AF
5345 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
5346 pcc->excp_model = POWERPC_EXCP_603;
5347 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5348 pcc->bfd_mach = bfd_mach_ppc_603;
5349 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
5350 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5351}
5352
a750fc0b
JM
5353static void init_proc_603E (CPUPPCState *env)
5354{
5355 gen_spr_ne_601(env);
5356 gen_spr_603(env);
5357 /* Time base */
5358 gen_tbl(env);
5359 /* hardware implementation registers */
5360 /* XXX : not implemented */
5361 spr_register(env, SPR_HID0, "HID0",
5362 SPR_NOACCESS, SPR_NOACCESS,
5363 &spr_read_generic, &spr_write_generic,
5364 0x00000000);
5365 /* XXX : not implemented */
5366 spr_register(env, SPR_HID1, "HID1",
5367 SPR_NOACCESS, SPR_NOACCESS,
5368 &spr_read_generic, &spr_write_generic,
5369 0x00000000);
a750fc0b
JM
5370 /* Memory management */
5371 gen_low_BATs(env);
5372 gen_6xx_7xx_soft_tlb(env, 64, 2);
e1833e1f 5373 init_excp_603(env);
d63001d1
JM
5374 env->dcache_line_size = 32;
5375 env->icache_line_size = 32;
a750fc0b
JM
5376 /* Allocate hardware IRQ controller */
5377 ppc6xx_irq_init(env);
5378}
5379
7856e3a4
AF
5380POWERPC_FAMILY(603E)(ObjectClass *oc, void *data)
5381{
ca5dff0a 5382 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5383 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5384
ca5dff0a 5385 dc->desc = "PowerPC 603e";
7856e3a4
AF
5386 pcc->init_proc = init_proc_603E;
5387 pcc->check_pow = check_pow_hid0;
53116ebf
AF
5388 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5389 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5390 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5391 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5392 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5393 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
5394 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
5395 pcc->msr_mask = (1ull << MSR_POW) |
5396 (1ull << MSR_TGPR) |
5397 (1ull << MSR_ILE) |
5398 (1ull << MSR_EE) |
5399 (1ull << MSR_PR) |
5400 (1ull << MSR_FP) |
5401 (1ull << MSR_ME) |
5402 (1ull << MSR_FE0) |
5403 (1ull << MSR_SE) |
5404 (1ull << MSR_DE) |
5405 (1ull << MSR_FE1) |
5406 (1ull << MSR_EP) |
5407 (1ull << MSR_IR) |
5408 (1ull << MSR_DR) |
5409 (1ull << MSR_RI) |
5410 (1ull << MSR_LE);
ba9fd9f1
AF
5411 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
5412 pcc->excp_model = POWERPC_EXCP_603E;
5413 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5414 pcc->bfd_mach = bfd_mach_ppc_ec603e;
5415 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
5416 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5417}
5418
a750fc0b
JM
5419static void init_proc_604 (CPUPPCState *env)
5420{
5421 gen_spr_ne_601(env);
5422 gen_spr_604(env);
5423 /* Time base */
5424 gen_tbl(env);
5425 /* Hardware implementation registers */
5426 /* XXX : not implemented */
082c6681
JM
5427 spr_register(env, SPR_HID0, "HID0",
5428 SPR_NOACCESS, SPR_NOACCESS,
5429 &spr_read_generic, &spr_write_generic,
5430 0x00000000);
5431 /* Memory management */
5432 gen_low_BATs(env);
5433 init_excp_604(env);
5434 env->dcache_line_size = 32;
5435 env->icache_line_size = 32;
5436 /* Allocate hardware IRQ controller */
5437 ppc6xx_irq_init(env);
5438}
5439
7856e3a4
AF
5440POWERPC_FAMILY(604)(ObjectClass *oc, void *data)
5441{
ca5dff0a 5442 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5443 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5444
ca5dff0a 5445 dc->desc = "PowerPC 604";
7856e3a4
AF
5446 pcc->init_proc = init_proc_604;
5447 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
5448 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5449 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5450 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5451 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5452 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5453 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5454 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
5455 pcc->msr_mask = (1ull << MSR_POW) |
5456 (1ull << MSR_ILE) |
5457 (1ull << MSR_EE) |
5458 (1ull << MSR_PR) |
5459 (1ull << MSR_FP) |
5460 (1ull << MSR_ME) |
5461 (1ull << MSR_FE0) |
5462 (1ull << MSR_SE) |
5463 (1ull << MSR_DE) |
5464 (1ull << MSR_FE1) |
5465 (1ull << MSR_EP) |
5466 (1ull << MSR_IR) |
5467 (1ull << MSR_DR) |
5468 (1ull << MSR_PMM) |
5469 (1ull << MSR_RI) |
5470 (1ull << MSR_LE);
ba9fd9f1 5471 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
5472#if defined(CONFIG_SOFTMMU)
5473 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5474#endif
ba9fd9f1
AF
5475 pcc->excp_model = POWERPC_EXCP_604;
5476 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5477 pcc->bfd_mach = bfd_mach_ppc_604;
5478 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5479 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5480}
5481
082c6681
JM
5482static void init_proc_604E (CPUPPCState *env)
5483{
5484 gen_spr_ne_601(env);
5485 gen_spr_604(env);
5486 /* XXX : not implemented */
cb8b8bf8 5487 spr_register(env, SPR_7XX_MMCR1, "MMCR1",
082c6681
JM
5488 SPR_NOACCESS, SPR_NOACCESS,
5489 &spr_read_generic, &spr_write_generic,
5490 0x00000000);
5491 /* XXX : not implemented */
cb8b8bf8 5492 spr_register(env, SPR_7XX_PMC3, "PMC3",
082c6681
JM
5493 SPR_NOACCESS, SPR_NOACCESS,
5494 &spr_read_generic, &spr_write_generic,
5495 0x00000000);
5496 /* XXX : not implemented */
cb8b8bf8 5497 spr_register(env, SPR_7XX_PMC4, "PMC4",
082c6681
JM
5498 SPR_NOACCESS, SPR_NOACCESS,
5499 &spr_read_generic, &spr_write_generic,
5500 0x00000000);
5501 /* Time base */
5502 gen_tbl(env);
5503 /* Hardware implementation registers */
5504 /* XXX : not implemented */
a750fc0b
JM
5505 spr_register(env, SPR_HID0, "HID0",
5506 SPR_NOACCESS, SPR_NOACCESS,
5507 &spr_read_generic, &spr_write_generic,
5508 0x00000000);
5509 /* XXX : not implemented */
5510 spr_register(env, SPR_HID1, "HID1",
5511 SPR_NOACCESS, SPR_NOACCESS,
5512 &spr_read_generic, &spr_write_generic,
5513 0x00000000);
5514 /* Memory management */
5515 gen_low_BATs(env);
e1833e1f 5516 init_excp_604(env);
d63001d1
JM
5517 env->dcache_line_size = 32;
5518 env->icache_line_size = 32;
a750fc0b
JM
5519 /* Allocate hardware IRQ controller */
5520 ppc6xx_irq_init(env);
5521}
5522
7856e3a4
AF
5523POWERPC_FAMILY(604E)(ObjectClass *oc, void *data)
5524{
ca5dff0a 5525 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5526 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5527
ca5dff0a 5528 dc->desc = "PowerPC 604E";
7856e3a4
AF
5529 pcc->init_proc = init_proc_604E;
5530 pcc->check_pow = check_pow_nocheck;
53116ebf
AF
5531 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5532 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5533 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5534 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5535 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5536 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5537 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
5538 pcc->msr_mask = (1ull << MSR_POW) |
5539 (1ull << MSR_ILE) |
5540 (1ull << MSR_EE) |
5541 (1ull << MSR_PR) |
5542 (1ull << MSR_FP) |
5543 (1ull << MSR_ME) |
5544 (1ull << MSR_FE0) |
5545 (1ull << MSR_SE) |
5546 (1ull << MSR_DE) |
5547 (1ull << MSR_FE1) |
5548 (1ull << MSR_EP) |
5549 (1ull << MSR_IR) |
5550 (1ull << MSR_DR) |
5551 (1ull << MSR_PMM) |
5552 (1ull << MSR_RI) |
5553 (1ull << MSR_LE);
ba9fd9f1 5554 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
5555#if defined(CONFIG_SOFTMMU)
5556 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5557#endif
ba9fd9f1
AF
5558 pcc->excp_model = POWERPC_EXCP_604;
5559 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5560 pcc->bfd_mach = bfd_mach_ppc_604;
5561 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5562 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5563}
5564
bd928eba 5565static void init_proc_740 (CPUPPCState *env)
a750fc0b
JM
5566{
5567 gen_spr_ne_601(env);
5568 gen_spr_7xx(env);
5569 /* Time base */
5570 gen_tbl(env);
5571 /* Thermal management */
5572 gen_spr_thrm(env);
5573 /* Hardware implementation registers */
5574 /* XXX : not implemented */
5575 spr_register(env, SPR_HID0, "HID0",
5576 SPR_NOACCESS, SPR_NOACCESS,
5577 &spr_read_generic, &spr_write_generic,
5578 0x00000000);
5579 /* XXX : not implemented */
5580 spr_register(env, SPR_HID1, "HID1",
5581 SPR_NOACCESS, SPR_NOACCESS,
5582 &spr_read_generic, &spr_write_generic,
5583 0x00000000);
5584 /* Memory management */
5585 gen_low_BATs(env);
e1833e1f 5586 init_excp_7x0(env);
d63001d1
JM
5587 env->dcache_line_size = 32;
5588 env->icache_line_size = 32;
a750fc0b
JM
5589 /* Allocate hardware IRQ controller */
5590 ppc6xx_irq_init(env);
5591}
5592
7856e3a4
AF
5593POWERPC_FAMILY(740)(ObjectClass *oc, void *data)
5594{
ca5dff0a 5595 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5596 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5597
ca5dff0a 5598 dc->desc = "PowerPC 740";
7856e3a4
AF
5599 pcc->init_proc = init_proc_740;
5600 pcc->check_pow = check_pow_hid0;
53116ebf
AF
5601 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5602 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5603 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5604 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5605 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5606 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5607 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
5608 pcc->msr_mask = (1ull << MSR_POW) |
5609 (1ull << MSR_ILE) |
5610 (1ull << MSR_EE) |
5611 (1ull << MSR_PR) |
5612 (1ull << MSR_FP) |
5613 (1ull << MSR_ME) |
5614 (1ull << MSR_FE0) |
5615 (1ull << MSR_SE) |
5616 (1ull << MSR_DE) |
5617 (1ull << MSR_FE1) |
5618 (1ull << MSR_EP) |
5619 (1ull << MSR_IR) |
5620 (1ull << MSR_DR) |
5621 (1ull << MSR_PMM) |
5622 (1ull << MSR_RI) |
5623 (1ull << MSR_LE);
ba9fd9f1 5624 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
5625#if defined(CONFIG_SOFTMMU)
5626 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5627#endif
ba9fd9f1
AF
5628 pcc->excp_model = POWERPC_EXCP_7x0;
5629 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5630 pcc->bfd_mach = bfd_mach_ppc_750;
5631 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5632 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5633}
5634
bd928eba
JM
5635static void init_proc_750 (CPUPPCState *env)
5636{
5637 gen_spr_ne_601(env);
5638 gen_spr_7xx(env);
5639 /* XXX : not implemented */
5640 spr_register(env, SPR_L2CR, "L2CR",
5641 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 5642 &spr_read_generic, spr_access_nop,
bd928eba
JM
5643 0x00000000);
5644 /* Time base */
5645 gen_tbl(env);
5646 /* Thermal management */
5647 gen_spr_thrm(env);
5648 /* Hardware implementation registers */
5649 /* XXX : not implemented */
5650 spr_register(env, SPR_HID0, "HID0",
5651 SPR_NOACCESS, SPR_NOACCESS,
5652 &spr_read_generic, &spr_write_generic,
5653 0x00000000);
5654 /* XXX : not implemented */
5655 spr_register(env, SPR_HID1, "HID1",
5656 SPR_NOACCESS, SPR_NOACCESS,
5657 &spr_read_generic, &spr_write_generic,
5658 0x00000000);
5659 /* Memory management */
5660 gen_low_BATs(env);
5661 /* XXX: high BATs are also present but are known to be bugged on
5662 * die version 1.x
5663 */
5664 init_excp_7x0(env);
5665 env->dcache_line_size = 32;
5666 env->icache_line_size = 32;
5667 /* Allocate hardware IRQ controller */
5668 ppc6xx_irq_init(env);
5669}
5670
7856e3a4
AF
5671POWERPC_FAMILY(750)(ObjectClass *oc, void *data)
5672{
ca5dff0a 5673 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5674 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5675
ca5dff0a 5676 dc->desc = "PowerPC 750";
7856e3a4
AF
5677 pcc->init_proc = init_proc_750;
5678 pcc->check_pow = check_pow_hid0;
53116ebf
AF
5679 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5680 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5681 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5682 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5683 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5684 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5685 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
5686 pcc->msr_mask = (1ull << MSR_POW) |
5687 (1ull << MSR_ILE) |
5688 (1ull << MSR_EE) |
5689 (1ull << MSR_PR) |
5690 (1ull << MSR_FP) |
5691 (1ull << MSR_ME) |
5692 (1ull << MSR_FE0) |
5693 (1ull << MSR_SE) |
5694 (1ull << MSR_DE) |
5695 (1ull << MSR_FE1) |
5696 (1ull << MSR_EP) |
5697 (1ull << MSR_IR) |
5698 (1ull << MSR_DR) |
5699 (1ull << MSR_PMM) |
5700 (1ull << MSR_RI) |
5701 (1ull << MSR_LE);
ba9fd9f1 5702 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
5703#if defined(CONFIG_SOFTMMU)
5704 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5705#endif
ba9fd9f1
AF
5706 pcc->excp_model = POWERPC_EXCP_7x0;
5707 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5708 pcc->bfd_mach = bfd_mach_ppc_750;
5709 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5710 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5711}
5712
bd928eba
JM
5713static void init_proc_750cl (CPUPPCState *env)
5714{
5715 gen_spr_ne_601(env);
5716 gen_spr_7xx(env);
5717 /* XXX : not implemented */
5718 spr_register(env, SPR_L2CR, "L2CR",
5719 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 5720 &spr_read_generic, spr_access_nop,
bd928eba
JM
5721 0x00000000);
5722 /* Time base */
5723 gen_tbl(env);
5724 /* Thermal management */
5725 /* Those registers are fake on 750CL */
5726 spr_register(env, SPR_THRM1, "THRM1",
5727 SPR_NOACCESS, SPR_NOACCESS,
5728 &spr_read_generic, &spr_write_generic,
5729 0x00000000);
5730 spr_register(env, SPR_THRM2, "THRM2",
5731 SPR_NOACCESS, SPR_NOACCESS,
5732 &spr_read_generic, &spr_write_generic,
5733 0x00000000);
5734 spr_register(env, SPR_THRM3, "THRM3",
5735 SPR_NOACCESS, SPR_NOACCESS,
5736 &spr_read_generic, &spr_write_generic,
5737 0x00000000);
5738 /* XXX: not implemented */
5739 spr_register(env, SPR_750_TDCL, "TDCL",
5740 SPR_NOACCESS, SPR_NOACCESS,
5741 &spr_read_generic, &spr_write_generic,
5742 0x00000000);
5743 spr_register(env, SPR_750_TDCH, "TDCH",
5744 SPR_NOACCESS, SPR_NOACCESS,
5745 &spr_read_generic, &spr_write_generic,
5746 0x00000000);
5747 /* DMA */
5748 /* XXX : not implemented */
5749 spr_register(env, SPR_750_WPAR, "WPAR",
5750 SPR_NOACCESS, SPR_NOACCESS,
5751 &spr_read_generic, &spr_write_generic,
5752 0x00000000);
5753 spr_register(env, SPR_750_DMAL, "DMAL",
5754 SPR_NOACCESS, SPR_NOACCESS,
5755 &spr_read_generic, &spr_write_generic,
5756 0x00000000);
5757 spr_register(env, SPR_750_DMAU, "DMAU",
5758 SPR_NOACCESS, SPR_NOACCESS,
5759 &spr_read_generic, &spr_write_generic,
5760 0x00000000);
5761 /* Hardware implementation registers */
5762 /* XXX : not implemented */
5763 spr_register(env, SPR_HID0, "HID0",
5764 SPR_NOACCESS, SPR_NOACCESS,
5765 &spr_read_generic, &spr_write_generic,
5766 0x00000000);
5767 /* XXX : not implemented */
5768 spr_register(env, SPR_HID1, "HID1",
5769 SPR_NOACCESS, SPR_NOACCESS,
5770 &spr_read_generic, &spr_write_generic,
5771 0x00000000);
5772 /* XXX : not implemented */
5773 spr_register(env, SPR_750CL_HID2, "HID2",
5774 SPR_NOACCESS, SPR_NOACCESS,
5775 &spr_read_generic, &spr_write_generic,
5776 0x00000000);
5777 /* XXX : not implemented */
5778 spr_register(env, SPR_750CL_HID4, "HID4",
5779 SPR_NOACCESS, SPR_NOACCESS,
5780 &spr_read_generic, &spr_write_generic,
5781 0x00000000);
5782 /* Quantization registers */
5783 /* XXX : not implemented */
5784 spr_register(env, SPR_750_GQR0, "GQR0",
5785 SPR_NOACCESS, SPR_NOACCESS,
5786 &spr_read_generic, &spr_write_generic,
5787 0x00000000);
5788 /* XXX : not implemented */
5789 spr_register(env, SPR_750_GQR1, "GQR1",
5790 SPR_NOACCESS, SPR_NOACCESS,
5791 &spr_read_generic, &spr_write_generic,
5792 0x00000000);
5793 /* XXX : not implemented */
5794 spr_register(env, SPR_750_GQR2, "GQR2",
5795 SPR_NOACCESS, SPR_NOACCESS,
5796 &spr_read_generic, &spr_write_generic,
5797 0x00000000);
5798 /* XXX : not implemented */
5799 spr_register(env, SPR_750_GQR3, "GQR3",
5800 SPR_NOACCESS, SPR_NOACCESS,
5801 &spr_read_generic, &spr_write_generic,
5802 0x00000000);
5803 /* XXX : not implemented */
5804 spr_register(env, SPR_750_GQR4, "GQR4",
5805 SPR_NOACCESS, SPR_NOACCESS,
5806 &spr_read_generic, &spr_write_generic,
5807 0x00000000);
5808 /* XXX : not implemented */
5809 spr_register(env, SPR_750_GQR5, "GQR5",
5810 SPR_NOACCESS, SPR_NOACCESS,
5811 &spr_read_generic, &spr_write_generic,
5812 0x00000000);
5813 /* XXX : not implemented */
5814 spr_register(env, SPR_750_GQR6, "GQR6",
5815 SPR_NOACCESS, SPR_NOACCESS,
5816 &spr_read_generic, &spr_write_generic,
5817 0x00000000);
5818 /* XXX : not implemented */
5819 spr_register(env, SPR_750_GQR7, "GQR7",
5820 SPR_NOACCESS, SPR_NOACCESS,
5821 &spr_read_generic, &spr_write_generic,
5822 0x00000000);
5823 /* Memory management */
5824 gen_low_BATs(env);
5825 /* PowerPC 750cl has 8 DBATs and 8 IBATs */
5826 gen_high_BATs(env);
5827 init_excp_750cl(env);
5828 env->dcache_line_size = 32;
5829 env->icache_line_size = 32;
5830 /* Allocate hardware IRQ controller */
5831 ppc6xx_irq_init(env);
5832}
5833
7856e3a4
AF
5834POWERPC_FAMILY(750cl)(ObjectClass *oc, void *data)
5835{
ca5dff0a 5836 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5837 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5838
ca5dff0a 5839 dc->desc = "PowerPC 750 CL";
7856e3a4
AF
5840 pcc->init_proc = init_proc_750cl;
5841 pcc->check_pow = check_pow_hid0;
53116ebf
AF
5842 /* XXX: not implemented:
5843 * cache lock instructions:
5844 * dcbz_l
5845 * floating point paired instructions
5846 * psq_lux
5847 * psq_lx
5848 * psq_stux
5849 * psq_stx
5850 * ps_abs
5851 * ps_add
5852 * ps_cmpo0
5853 * ps_cmpo1
5854 * ps_cmpu0
5855 * ps_cmpu1
5856 * ps_div
5857 * ps_madd
5858 * ps_madds0
5859 * ps_madds1
5860 * ps_merge00
5861 * ps_merge01
5862 * ps_merge10
5863 * ps_merge11
5864 * ps_mr
5865 * ps_msub
5866 * ps_mul
5867 * ps_muls0
5868 * ps_muls1
5869 * ps_nabs
5870 * ps_neg
5871 * ps_nmadd
5872 * ps_nmsub
5873 * ps_res
5874 * ps_rsqrte
5875 * ps_sel
5876 * ps_sub
5877 * ps_sum0
5878 * ps_sum1
5879 */
5880 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5881 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5882 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5883 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5884 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5885 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5886 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
5887 pcc->msr_mask = (1ull << MSR_POW) |
5888 (1ull << MSR_ILE) |
5889 (1ull << MSR_EE) |
5890 (1ull << MSR_PR) |
5891 (1ull << MSR_FP) |
5892 (1ull << MSR_ME) |
5893 (1ull << MSR_FE0) |
5894 (1ull << MSR_SE) |
5895 (1ull << MSR_DE) |
5896 (1ull << MSR_FE1) |
5897 (1ull << MSR_EP) |
5898 (1ull << MSR_IR) |
5899 (1ull << MSR_DR) |
5900 (1ull << MSR_PMM) |
5901 (1ull << MSR_RI) |
5902 (1ull << MSR_LE);
ba9fd9f1 5903 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
5904#if defined(CONFIG_SOFTMMU)
5905 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5906#endif
ba9fd9f1
AF
5907 pcc->excp_model = POWERPC_EXCP_7x0;
5908 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5909 pcc->bfd_mach = bfd_mach_ppc_750;
5910 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5911 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5912}
5913
bd928eba
JM
5914static void init_proc_750cx (CPUPPCState *env)
5915{
5916 gen_spr_ne_601(env);
5917 gen_spr_7xx(env);
5918 /* XXX : not implemented */
5919 spr_register(env, SPR_L2CR, "L2CR",
5920 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 5921 &spr_read_generic, spr_access_nop,
bd928eba
JM
5922 0x00000000);
5923 /* Time base */
5924 gen_tbl(env);
5925 /* Thermal management */
5926 gen_spr_thrm(env);
5927 /* This register is not implemented but is present for compatibility */
5928 spr_register(env, SPR_SDA, "SDA",
5929 SPR_NOACCESS, SPR_NOACCESS,
5930 &spr_read_generic, &spr_write_generic,
5931 0x00000000);
5932 /* Hardware implementation registers */
5933 /* XXX : not implemented */
5934 spr_register(env, SPR_HID0, "HID0",
5935 SPR_NOACCESS, SPR_NOACCESS,
5936 &spr_read_generic, &spr_write_generic,
5937 0x00000000);
5938 /* XXX : not implemented */
5939 spr_register(env, SPR_HID1, "HID1",
5940 SPR_NOACCESS, SPR_NOACCESS,
5941 &spr_read_generic, &spr_write_generic,
5942 0x00000000);
5943 /* Memory management */
5944 gen_low_BATs(env);
4e777442
JM
5945 /* PowerPC 750cx has 8 DBATs and 8 IBATs */
5946 gen_high_BATs(env);
bd928eba
JM
5947 init_excp_750cx(env);
5948 env->dcache_line_size = 32;
5949 env->icache_line_size = 32;
5950 /* Allocate hardware IRQ controller */
5951 ppc6xx_irq_init(env);
5952}
5953
7856e3a4
AF
5954POWERPC_FAMILY(750cx)(ObjectClass *oc, void *data)
5955{
ca5dff0a 5956 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
5957 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5958
ca5dff0a 5959 dc->desc = "PowerPC 750CX";
7856e3a4
AF
5960 pcc->init_proc = init_proc_750cx;
5961 pcc->check_pow = check_pow_hid0;
53116ebf
AF
5962 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5963 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5964 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5965 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5966 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5967 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5968 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
5969 pcc->msr_mask = (1ull << MSR_POW) |
5970 (1ull << MSR_ILE) |
5971 (1ull << MSR_EE) |
5972 (1ull << MSR_PR) |
5973 (1ull << MSR_FP) |
5974 (1ull << MSR_ME) |
5975 (1ull << MSR_FE0) |
5976 (1ull << MSR_SE) |
5977 (1ull << MSR_DE) |
5978 (1ull << MSR_FE1) |
5979 (1ull << MSR_EP) |
5980 (1ull << MSR_IR) |
5981 (1ull << MSR_DR) |
5982 (1ull << MSR_PMM) |
5983 (1ull << MSR_RI) |
5984 (1ull << MSR_LE);
ba9fd9f1 5985 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
5986#if defined(CONFIG_SOFTMMU)
5987 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5988#endif
ba9fd9f1
AF
5989 pcc->excp_model = POWERPC_EXCP_7x0;
5990 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5991 pcc->bfd_mach = bfd_mach_ppc_750;
5992 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5993 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
5994}
5995
a750fc0b
JM
5996static void init_proc_750fx (CPUPPCState *env)
5997{
5998 gen_spr_ne_601(env);
5999 gen_spr_7xx(env);
bd928eba
JM
6000 /* XXX : not implemented */
6001 spr_register(env, SPR_L2CR, "L2CR",
6002 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 6003 &spr_read_generic, spr_access_nop,
bd928eba 6004 0x00000000);
a750fc0b
JM
6005 /* Time base */
6006 gen_tbl(env);
6007 /* Thermal management */
6008 gen_spr_thrm(env);
bd928eba
JM
6009 /* XXX : not implemented */
6010 spr_register(env, SPR_750_THRM4, "THRM4",
6011 SPR_NOACCESS, SPR_NOACCESS,
6012 &spr_read_generic, &spr_write_generic,
6013 0x00000000);
a750fc0b
JM
6014 /* Hardware implementation registers */
6015 /* XXX : not implemented */
6016 spr_register(env, SPR_HID0, "HID0",
6017 SPR_NOACCESS, SPR_NOACCESS,
6018 &spr_read_generic, &spr_write_generic,
6019 0x00000000);
6020 /* XXX : not implemented */
6021 spr_register(env, SPR_HID1, "HID1",
6022 SPR_NOACCESS, SPR_NOACCESS,
6023 &spr_read_generic, &spr_write_generic,
6024 0x00000000);
6025 /* XXX : not implemented */
bd928eba 6026 spr_register(env, SPR_750FX_HID2, "HID2",
a750fc0b
JM
6027 SPR_NOACCESS, SPR_NOACCESS,
6028 &spr_read_generic, &spr_write_generic,
6029 0x00000000);
6030 /* Memory management */
6031 gen_low_BATs(env);
6032 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6033 gen_high_BATs(env);
bd928eba 6034 init_excp_7x0(env);
d63001d1
JM
6035 env->dcache_line_size = 32;
6036 env->icache_line_size = 32;
a750fc0b
JM
6037 /* Allocate hardware IRQ controller */
6038 ppc6xx_irq_init(env);
6039}
6040
7856e3a4
AF
6041POWERPC_FAMILY(750fx)(ObjectClass *oc, void *data)
6042{
ca5dff0a 6043 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6044 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6045
ca5dff0a 6046 dc->desc = "PowerPC 750FX";
7856e3a4
AF
6047 pcc->init_proc = init_proc_750fx;
6048 pcc->check_pow = check_pow_hid0;
53116ebf
AF
6049 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6050 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6051 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6052 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6053 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6054 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6055 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
6056 pcc->msr_mask = (1ull << MSR_POW) |
6057 (1ull << MSR_ILE) |
6058 (1ull << MSR_EE) |
6059 (1ull << MSR_PR) |
6060 (1ull << MSR_FP) |
6061 (1ull << MSR_ME) |
6062 (1ull << MSR_FE0) |
6063 (1ull << MSR_SE) |
6064 (1ull << MSR_DE) |
6065 (1ull << MSR_FE1) |
6066 (1ull << MSR_EP) |
6067 (1ull << MSR_IR) |
6068 (1ull << MSR_DR) |
6069 (1ull << MSR_PMM) |
6070 (1ull << MSR_RI) |
6071 (1ull << MSR_LE);
ba9fd9f1 6072 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
6073#if defined(CONFIG_SOFTMMU)
6074 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6075#endif
ba9fd9f1
AF
6076 pcc->excp_model = POWERPC_EXCP_7x0;
6077 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6078 pcc->bfd_mach = bfd_mach_ppc_750;
6079 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6080 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6081}
6082
bd928eba
JM
6083static void init_proc_750gx (CPUPPCState *env)
6084{
6085 gen_spr_ne_601(env);
6086 gen_spr_7xx(env);
6087 /* XXX : not implemented (XXX: different from 750fx) */
6088 spr_register(env, SPR_L2CR, "L2CR",
6089 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 6090 &spr_read_generic, spr_access_nop,
bd928eba
JM
6091 0x00000000);
6092 /* Time base */
6093 gen_tbl(env);
6094 /* Thermal management */
6095 gen_spr_thrm(env);
6096 /* XXX : not implemented */
6097 spr_register(env, SPR_750_THRM4, "THRM4",
6098 SPR_NOACCESS, SPR_NOACCESS,
6099 &spr_read_generic, &spr_write_generic,
6100 0x00000000);
6101 /* Hardware implementation registers */
6102 /* XXX : not implemented (XXX: different from 750fx) */
6103 spr_register(env, SPR_HID0, "HID0",
6104 SPR_NOACCESS, SPR_NOACCESS,
6105 &spr_read_generic, &spr_write_generic,
6106 0x00000000);
6107 /* XXX : not implemented */
6108 spr_register(env, SPR_HID1, "HID1",
6109 SPR_NOACCESS, SPR_NOACCESS,
6110 &spr_read_generic, &spr_write_generic,
6111 0x00000000);
6112 /* XXX : not implemented (XXX: different from 750fx) */
6113 spr_register(env, SPR_750FX_HID2, "HID2",
6114 SPR_NOACCESS, SPR_NOACCESS,
6115 &spr_read_generic, &spr_write_generic,
6116 0x00000000);
6117 /* Memory management */
6118 gen_low_BATs(env);
6119 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6120 gen_high_BATs(env);
6121 init_excp_7x0(env);
6122 env->dcache_line_size = 32;
6123 env->icache_line_size = 32;
6124 /* Allocate hardware IRQ controller */
6125 ppc6xx_irq_init(env);
6126}
6127
7856e3a4
AF
6128POWERPC_FAMILY(750gx)(ObjectClass *oc, void *data)
6129{
ca5dff0a 6130 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6131 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6132
ca5dff0a 6133 dc->desc = "PowerPC 750GX";
7856e3a4
AF
6134 pcc->init_proc = init_proc_750gx;
6135 pcc->check_pow = check_pow_hid0;
53116ebf
AF
6136 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6137 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6138 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6139 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6140 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6141 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6142 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
6143 pcc->msr_mask = (1ull << MSR_POW) |
6144 (1ull << MSR_ILE) |
6145 (1ull << MSR_EE) |
6146 (1ull << MSR_PR) |
6147 (1ull << MSR_FP) |
6148 (1ull << MSR_ME) |
6149 (1ull << MSR_FE0) |
6150 (1ull << MSR_SE) |
6151 (1ull << MSR_DE) |
6152 (1ull << MSR_FE1) |
6153 (1ull << MSR_EP) |
6154 (1ull << MSR_IR) |
6155 (1ull << MSR_DR) |
6156 (1ull << MSR_PMM) |
6157 (1ull << MSR_RI) |
6158 (1ull << MSR_LE);
ba9fd9f1 6159 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
6160#if defined(CONFIG_SOFTMMU)
6161 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6162#endif
ba9fd9f1
AF
6163 pcc->excp_model = POWERPC_EXCP_7x0;
6164 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6165 pcc->bfd_mach = bfd_mach_ppc_750;
6166 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6167 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6168}
6169
bd928eba
JM
6170static void init_proc_745 (CPUPPCState *env)
6171{
6172 gen_spr_ne_601(env);
6173 gen_spr_7xx(env);
6174 gen_spr_G2_755(env);
6175 /* Time base */
6176 gen_tbl(env);
6177 /* Thermal management */
6178 gen_spr_thrm(env);
6179 /* Hardware implementation registers */
6180 /* XXX : not implemented */
6181 spr_register(env, SPR_HID0, "HID0",
6182 SPR_NOACCESS, SPR_NOACCESS,
6183 &spr_read_generic, &spr_write_generic,
6184 0x00000000);
6185 /* XXX : not implemented */
6186 spr_register(env, SPR_HID1, "HID1",
6187 SPR_NOACCESS, SPR_NOACCESS,
6188 &spr_read_generic, &spr_write_generic,
6189 0x00000000);
6190 /* XXX : not implemented */
6191 spr_register(env, SPR_HID2, "HID2",
6192 SPR_NOACCESS, SPR_NOACCESS,
6193 &spr_read_generic, &spr_write_generic,
6194 0x00000000);
6195 /* Memory management */
6196 gen_low_BATs(env);
6197 gen_high_BATs(env);
6198 gen_6xx_7xx_soft_tlb(env, 64, 2);
6199 init_excp_7x5(env);
6200 env->dcache_line_size = 32;
6201 env->icache_line_size = 32;
6202 /* Allocate hardware IRQ controller */
6203 ppc6xx_irq_init(env);
6204}
6205
7856e3a4
AF
6206POWERPC_FAMILY(745)(ObjectClass *oc, void *data)
6207{
ca5dff0a 6208 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6209 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6210
ca5dff0a 6211 dc->desc = "PowerPC 745";
7856e3a4
AF
6212 pcc->init_proc = init_proc_745;
6213 pcc->check_pow = check_pow_hid0;
53116ebf
AF
6214 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6215 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6216 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6217 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6218 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6219 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
6220 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
6221 pcc->msr_mask = (1ull << MSR_POW) |
6222 (1ull << MSR_ILE) |
6223 (1ull << MSR_EE) |
6224 (1ull << MSR_PR) |
6225 (1ull << MSR_FP) |
6226 (1ull << MSR_ME) |
6227 (1ull << MSR_FE0) |
6228 (1ull << MSR_SE) |
6229 (1ull << MSR_DE) |
6230 (1ull << MSR_FE1) |
6231 (1ull << MSR_EP) |
6232 (1ull << MSR_IR) |
6233 (1ull << MSR_DR) |
6234 (1ull << MSR_PMM) |
6235 (1ull << MSR_RI) |
6236 (1ull << MSR_LE);
ba9fd9f1
AF
6237 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
6238 pcc->excp_model = POWERPC_EXCP_7x5;
6239 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6240 pcc->bfd_mach = bfd_mach_ppc_750;
6241 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6242 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6243}
6244
bd928eba 6245static void init_proc_755 (CPUPPCState *env)
a750fc0b
JM
6246{
6247 gen_spr_ne_601(env);
bd928eba 6248 gen_spr_7xx(env);
a750fc0b
JM
6249 gen_spr_G2_755(env);
6250 /* Time base */
6251 gen_tbl(env);
6252 /* L2 cache control */
6253 /* XXX : not implemented */
bd928eba 6254 spr_register(env, SPR_L2CR, "L2CR",
a750fc0b 6255 SPR_NOACCESS, SPR_NOACCESS,
9633fcc6 6256 &spr_read_generic, spr_access_nop,
a750fc0b
JM
6257 0x00000000);
6258 /* XXX : not implemented */
6259 spr_register(env, SPR_L2PMCR, "L2PMCR",
6260 SPR_NOACCESS, SPR_NOACCESS,
6261 &spr_read_generic, &spr_write_generic,
6262 0x00000000);
bd928eba
JM
6263 /* Thermal management */
6264 gen_spr_thrm(env);
a750fc0b
JM
6265 /* Hardware implementation registers */
6266 /* XXX : not implemented */
6267 spr_register(env, SPR_HID0, "HID0",
6268 SPR_NOACCESS, SPR_NOACCESS,
6269 &spr_read_generic, &spr_write_generic,
6270 0x00000000);
6271 /* XXX : not implemented */
6272 spr_register(env, SPR_HID1, "HID1",
6273 SPR_NOACCESS, SPR_NOACCESS,
6274 &spr_read_generic, &spr_write_generic,
6275 0x00000000);
6276 /* XXX : not implemented */
6277 spr_register(env, SPR_HID2, "HID2",
6278 SPR_NOACCESS, SPR_NOACCESS,
6279 &spr_read_generic, &spr_write_generic,
6280 0x00000000);
6281 /* Memory management */
6282 gen_low_BATs(env);
6283 gen_high_BATs(env);
6284 gen_6xx_7xx_soft_tlb(env, 64, 2);
7a3a6927 6285 init_excp_7x5(env);
d63001d1
JM
6286 env->dcache_line_size = 32;
6287 env->icache_line_size = 32;
a750fc0b
JM
6288 /* Allocate hardware IRQ controller */
6289 ppc6xx_irq_init(env);
6290}
6291
7856e3a4
AF
6292POWERPC_FAMILY(755)(ObjectClass *oc, void *data)
6293{
ca5dff0a 6294 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6295 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6296
ca5dff0a 6297 dc->desc = "PowerPC 755";
7856e3a4
AF
6298 pcc->init_proc = init_proc_755;
6299 pcc->check_pow = check_pow_hid0;
53116ebf
AF
6300 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6301 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6302 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6303 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6304 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6305 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
6306 PPC_SEGMENT | PPC_EXTERN;
9df5a466
TM
6307 pcc->msr_mask = (1ull << MSR_POW) |
6308 (1ull << MSR_ILE) |
6309 (1ull << MSR_EE) |
6310 (1ull << MSR_PR) |
6311 (1ull << MSR_FP) |
6312 (1ull << MSR_ME) |
6313 (1ull << MSR_FE0) |
6314 (1ull << MSR_SE) |
6315 (1ull << MSR_DE) |
6316 (1ull << MSR_FE1) |
6317 (1ull << MSR_EP) |
6318 (1ull << MSR_IR) |
6319 (1ull << MSR_DR) |
6320 (1ull << MSR_PMM) |
6321 (1ull << MSR_RI) |
6322 (1ull << MSR_LE);
ba9fd9f1
AF
6323 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
6324 pcc->excp_model = POWERPC_EXCP_7x5;
6325 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6326 pcc->bfd_mach = bfd_mach_ppc_750;
6327 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6328 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6329}
6330
a750fc0b
JM
6331static void init_proc_7400 (CPUPPCState *env)
6332{
6333 gen_spr_ne_601(env);
6334 gen_spr_7xx(env);
6335 /* Time base */
6336 gen_tbl(env);
6337 /* 74xx specific SPR */
6338 gen_spr_74xx(env);
4e777442
JM
6339 /* XXX : not implemented */
6340 spr_register(env, SPR_UBAMR, "UBAMR",
6341 &spr_read_ureg, SPR_NOACCESS,
6342 &spr_read_ureg, SPR_NOACCESS,
6343 0x00000000);
6344 /* XXX: this seems not implemented on all revisions. */
6345 /* XXX : not implemented */
6346 spr_register(env, SPR_MSSCR1, "MSSCR1",
6347 SPR_NOACCESS, SPR_NOACCESS,
6348 &spr_read_generic, &spr_write_generic,
6349 0x00000000);
a750fc0b
JM
6350 /* Thermal management */
6351 gen_spr_thrm(env);
6352 /* Memory management */
6353 gen_low_BATs(env);
e1833e1f 6354 init_excp_7400(env);
d63001d1
JM
6355 env->dcache_line_size = 32;
6356 env->icache_line_size = 32;
a750fc0b
JM
6357 /* Allocate hardware IRQ controller */
6358 ppc6xx_irq_init(env);
6359}
6360
7856e3a4
AF
6361POWERPC_FAMILY(7400)(ObjectClass *oc, void *data)
6362{
ca5dff0a 6363 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6364 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6365
ca5dff0a 6366 dc->desc = "PowerPC 7400 (aka G4)";
7856e3a4
AF
6367 pcc->init_proc = init_proc_7400;
6368 pcc->check_pow = check_pow_hid0;
53116ebf
AF
6369 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6370 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6371 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6372 PPC_FLOAT_STFIWX |
6373 PPC_CACHE | PPC_CACHE_ICBI |
6374 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6375 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6376 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6377 PPC_MEM_TLBIA |
6378 PPC_SEGMENT | PPC_EXTERN |
6379 PPC_ALTIVEC;
9df5a466
TM
6380 pcc->msr_mask = (1ull << MSR_VR) |
6381 (1ull << MSR_POW) |
6382 (1ull << MSR_ILE) |
6383 (1ull << MSR_EE) |
6384 (1ull << MSR_PR) |
6385 (1ull << MSR_FP) |
6386 (1ull << MSR_ME) |
6387 (1ull << MSR_FE0) |
6388 (1ull << MSR_SE) |
6389 (1ull << MSR_DE) |
6390 (1ull << MSR_FE1) |
6391 (1ull << MSR_EP) |
6392 (1ull << MSR_IR) |
6393 (1ull << MSR_DR) |
6394 (1ull << MSR_PMM) |
6395 (1ull << MSR_RI) |
6396 (1ull << MSR_LE);
ba9fd9f1 6397 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
6398#if defined(CONFIG_SOFTMMU)
6399 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6400#endif
ba9fd9f1
AF
6401 pcc->excp_model = POWERPC_EXCP_74xx;
6402 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6403 pcc->bfd_mach = bfd_mach_ppc_7400;
6404 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6405 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6406 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6407}
6408
a750fc0b
JM
6409static void init_proc_7410 (CPUPPCState *env)
6410{
6411 gen_spr_ne_601(env);
6412 gen_spr_7xx(env);
6413 /* Time base */
6414 gen_tbl(env);
6415 /* 74xx specific SPR */
6416 gen_spr_74xx(env);
4e777442
JM
6417 /* XXX : not implemented */
6418 spr_register(env, SPR_UBAMR, "UBAMR",
6419 &spr_read_ureg, SPR_NOACCESS,
6420 &spr_read_ureg, SPR_NOACCESS,
6421 0x00000000);
a750fc0b
JM
6422 /* Thermal management */
6423 gen_spr_thrm(env);
6424 /* L2PMCR */
6425 /* XXX : not implemented */
6426 spr_register(env, SPR_L2PMCR, "L2PMCR",
6427 SPR_NOACCESS, SPR_NOACCESS,
6428 &spr_read_generic, &spr_write_generic,
6429 0x00000000);
6430 /* LDSTDB */
6431 /* XXX : not implemented */
6432 spr_register(env, SPR_LDSTDB, "LDSTDB",
6433 SPR_NOACCESS, SPR_NOACCESS,
6434 &spr_read_generic, &spr_write_generic,
6435 0x00000000);
6436 /* Memory management */
6437 gen_low_BATs(env);
e1833e1f 6438 init_excp_7400(env);
d63001d1
JM
6439 env->dcache_line_size = 32;
6440 env->icache_line_size = 32;
a750fc0b
JM
6441 /* Allocate hardware IRQ controller */
6442 ppc6xx_irq_init(env);
6443}
6444
7856e3a4
AF
6445POWERPC_FAMILY(7410)(ObjectClass *oc, void *data)
6446{
ca5dff0a 6447 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6448 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6449
ca5dff0a 6450 dc->desc = "PowerPC 7410 (aka G4)";
7856e3a4
AF
6451 pcc->init_proc = init_proc_7410;
6452 pcc->check_pow = check_pow_hid0;
53116ebf
AF
6453 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6454 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6455 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6456 PPC_FLOAT_STFIWX |
6457 PPC_CACHE | PPC_CACHE_ICBI |
6458 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6459 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6460 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6461 PPC_MEM_TLBIA |
6462 PPC_SEGMENT | PPC_EXTERN |
6463 PPC_ALTIVEC;
9df5a466
TM
6464 pcc->msr_mask = (1ull << MSR_VR) |
6465 (1ull << MSR_POW) |
6466 (1ull << MSR_ILE) |
6467 (1ull << MSR_EE) |
6468 (1ull << MSR_PR) |
6469 (1ull << MSR_FP) |
6470 (1ull << MSR_ME) |
6471 (1ull << MSR_FE0) |
6472 (1ull << MSR_SE) |
6473 (1ull << MSR_DE) |
6474 (1ull << MSR_FE1) |
6475 (1ull << MSR_EP) |
6476 (1ull << MSR_IR) |
6477 (1ull << MSR_DR) |
6478 (1ull << MSR_PMM) |
6479 (1ull << MSR_RI) |
6480 (1ull << MSR_LE);
ba9fd9f1 6481 pcc->mmu_model = POWERPC_MMU_32B;
b632a148
DG
6482#if defined(CONFIG_SOFTMMU)
6483 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6484#endif
ba9fd9f1
AF
6485 pcc->excp_model = POWERPC_EXCP_74xx;
6486 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6487 pcc->bfd_mach = bfd_mach_ppc_7400;
6488 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6489 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6490 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6491}
6492
a750fc0b
JM
6493static void init_proc_7440 (CPUPPCState *env)
6494{
6495 gen_spr_ne_601(env);
6496 gen_spr_7xx(env);
6497 /* Time base */
6498 gen_tbl(env);
6499 /* 74xx specific SPR */
6500 gen_spr_74xx(env);
4e777442
JM
6501 /* XXX : not implemented */
6502 spr_register(env, SPR_UBAMR, "UBAMR",
6503 &spr_read_ureg, SPR_NOACCESS,
6504 &spr_read_ureg, SPR_NOACCESS,
6505 0x00000000);
a750fc0b
JM
6506 /* LDSTCR */
6507 /* XXX : not implemented */
6508 spr_register(env, SPR_LDSTCR, "LDSTCR",
6509 SPR_NOACCESS, SPR_NOACCESS,
6510 &spr_read_generic, &spr_write_generic,
6511 0x00000000);
6512 /* ICTRL */
6513 /* XXX : not implemented */
6514 spr_register(env, SPR_ICTRL, "ICTRL",
6515 SPR_NOACCESS, SPR_NOACCESS,
6516 &spr_read_generic, &spr_write_generic,
6517 0x00000000);
6518 /* MSSSR0 */
578bb252 6519 /* XXX : not implemented */
a750fc0b
JM
6520 spr_register(env, SPR_MSSSR0, "MSSSR0",
6521 SPR_NOACCESS, SPR_NOACCESS,
6522 &spr_read_generic, &spr_write_generic,
6523 0x00000000);
6524 /* PMC */
6525 /* XXX : not implemented */
cb8b8bf8 6526 spr_register(env, SPR_7XX_PMC5, "PMC5",
a750fc0b
JM
6527 SPR_NOACCESS, SPR_NOACCESS,
6528 &spr_read_generic, &spr_write_generic,
6529 0x00000000);
578bb252 6530 /* XXX : not implemented */
cb8b8bf8 6531 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
a750fc0b
JM
6532 &spr_read_ureg, SPR_NOACCESS,
6533 &spr_read_ureg, SPR_NOACCESS,
6534 0x00000000);
578bb252 6535 /* XXX : not implemented */
cb8b8bf8 6536 spr_register(env, SPR_7XX_PMC6, "PMC6",
a750fc0b
JM
6537 SPR_NOACCESS, SPR_NOACCESS,
6538 &spr_read_generic, &spr_write_generic,
6539 0x00000000);
578bb252 6540 /* XXX : not implemented */
cb8b8bf8 6541 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
a750fc0b
JM
6542 &spr_read_ureg, SPR_NOACCESS,
6543 &spr_read_ureg, SPR_NOACCESS,
6544 0x00000000);
6545 /* Memory management */
6546 gen_low_BATs(env);
578bb252 6547 gen_74xx_soft_tlb(env, 128, 2);
1c27f8fb 6548 init_excp_7450(env);
d63001d1
JM
6549 env->dcache_line_size = 32;
6550 env->icache_line_size = 32;
a750fc0b
JM
6551 /* Allocate hardware IRQ controller */
6552 ppc6xx_irq_init(env);
6553}
a750fc0b 6554
7856e3a4
AF
6555POWERPC_FAMILY(7440)(ObjectClass *oc, void *data)
6556{
ca5dff0a 6557 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6558 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6559
ca5dff0a 6560 dc->desc = "PowerPC 7440 (aka G4)";
7856e3a4
AF
6561 pcc->init_proc = init_proc_7440;
6562 pcc->check_pow = check_pow_hid0_74xx;
53116ebf
AF
6563 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6564 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6565 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6566 PPC_FLOAT_STFIWX |
6567 PPC_CACHE | PPC_CACHE_ICBI |
6568 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6569 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6570 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6571 PPC_MEM_TLBIA | PPC_74xx_TLB |
6572 PPC_SEGMENT | PPC_EXTERN |
6573 PPC_ALTIVEC;
9df5a466
TM
6574 pcc->msr_mask = (1ull << MSR_VR) |
6575 (1ull << MSR_POW) |
6576 (1ull << MSR_ILE) |
6577 (1ull << MSR_EE) |
6578 (1ull << MSR_PR) |
6579 (1ull << MSR_FP) |
6580 (1ull << MSR_ME) |
6581 (1ull << MSR_FE0) |
6582 (1ull << MSR_SE) |
6583 (1ull << MSR_DE) |
6584 (1ull << MSR_FE1) |
6585 (1ull << MSR_EP) |
6586 (1ull << MSR_IR) |
6587 (1ull << MSR_DR) |
6588 (1ull << MSR_PMM) |
6589 (1ull << MSR_RI) |
6590 (1ull << MSR_LE);
ba9fd9f1
AF
6591 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
6592 pcc->excp_model = POWERPC_EXCP_74xx;
6593 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6594 pcc->bfd_mach = bfd_mach_ppc_7400;
6595 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6596 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6597 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6598}
6599
a750fc0b
JM
6600static void init_proc_7450 (CPUPPCState *env)
6601{
6602 gen_spr_ne_601(env);
6603 gen_spr_7xx(env);
6604 /* Time base */
6605 gen_tbl(env);
6606 /* 74xx specific SPR */
6607 gen_spr_74xx(env);
6608 /* Level 3 cache control */
6609 gen_l3_ctrl(env);
4e777442
JM
6610 /* L3ITCR1 */
6611 /* XXX : not implemented */
6612 spr_register(env, SPR_L3ITCR1, "L3ITCR1",
6613 SPR_NOACCESS, SPR_NOACCESS,
6614 &spr_read_generic, &spr_write_generic,
6615 0x00000000);
6616 /* L3ITCR2 */
6617 /* XXX : not implemented */
6618 spr_register(env, SPR_L3ITCR2, "L3ITCR2",
6619 SPR_NOACCESS, SPR_NOACCESS,
6620 &spr_read_generic, &spr_write_generic,
6621 0x00000000);
6622 /* L3ITCR3 */
6623 /* XXX : not implemented */
6624 spr_register(env, SPR_L3ITCR3, "L3ITCR3",
6625 SPR_NOACCESS, SPR_NOACCESS,
6626 &spr_read_generic, &spr_write_generic,
6627 0x00000000);
6628 /* L3OHCR */
6629 /* XXX : not implemented */
6630 spr_register(env, SPR_L3OHCR, "L3OHCR",
6631 SPR_NOACCESS, SPR_NOACCESS,
6632 &spr_read_generic, &spr_write_generic,
6633 0x00000000);
6634 /* XXX : not implemented */
6635 spr_register(env, SPR_UBAMR, "UBAMR",
6636 &spr_read_ureg, SPR_NOACCESS,
6637 &spr_read_ureg, SPR_NOACCESS,
6638 0x00000000);
a750fc0b
JM
6639 /* LDSTCR */
6640 /* XXX : not implemented */
6641 spr_register(env, SPR_LDSTCR, "LDSTCR",
6642 SPR_NOACCESS, SPR_NOACCESS,
6643 &spr_read_generic, &spr_write_generic,
6644 0x00000000);
6645 /* ICTRL */
6646 /* XXX : not implemented */
6647 spr_register(env, SPR_ICTRL, "ICTRL",
6648 SPR_NOACCESS, SPR_NOACCESS,
6649 &spr_read_generic, &spr_write_generic,
6650 0x00000000);
6651 /* MSSSR0 */
578bb252 6652 /* XXX : not implemented */
a750fc0b
JM
6653 spr_register(env, SPR_MSSSR0, "MSSSR0",
6654 SPR_NOACCESS, SPR_NOACCESS,
6655 &spr_read_generic, &spr_write_generic,
6656 0x00000000);
6657 /* PMC */
6658 /* XXX : not implemented */
cb8b8bf8 6659 spr_register(env, SPR_7XX_PMC5, "PMC5",
a750fc0b
JM
6660 SPR_NOACCESS, SPR_NOACCESS,
6661 &spr_read_generic, &spr_write_generic,
6662 0x00000000);
578bb252 6663 /* XXX : not implemented */
cb8b8bf8 6664 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
a750fc0b
JM
6665 &spr_read_ureg, SPR_NOACCESS,
6666 &spr_read_ureg, SPR_NOACCESS,
6667 0x00000000);
578bb252 6668 /* XXX : not implemented */
cb8b8bf8 6669 spr_register(env, SPR_7XX_PMC6, "PMC6",
a750fc0b
JM
6670 SPR_NOACCESS, SPR_NOACCESS,
6671 &spr_read_generic, &spr_write_generic,
6672 0x00000000);
578bb252 6673 /* XXX : not implemented */
cb8b8bf8 6674 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
a750fc0b
JM
6675 &spr_read_ureg, SPR_NOACCESS,
6676 &spr_read_ureg, SPR_NOACCESS,
6677 0x00000000);
6678 /* Memory management */
6679 gen_low_BATs(env);
578bb252 6680 gen_74xx_soft_tlb(env, 128, 2);
e1833e1f 6681 init_excp_7450(env);
d63001d1
JM
6682 env->dcache_line_size = 32;
6683 env->icache_line_size = 32;
a750fc0b
JM
6684 /* Allocate hardware IRQ controller */
6685 ppc6xx_irq_init(env);
6686}
a750fc0b 6687
7856e3a4
AF
6688POWERPC_FAMILY(7450)(ObjectClass *oc, void *data)
6689{
ca5dff0a 6690 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6691 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6692
ca5dff0a 6693 dc->desc = "PowerPC 7450 (aka G4)";
7856e3a4
AF
6694 pcc->init_proc = init_proc_7450;
6695 pcc->check_pow = check_pow_hid0_74xx;
53116ebf
AF
6696 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6697 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6698 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6699 PPC_FLOAT_STFIWX |
6700 PPC_CACHE | PPC_CACHE_ICBI |
6701 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6702 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6703 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6704 PPC_MEM_TLBIA | PPC_74xx_TLB |
6705 PPC_SEGMENT | PPC_EXTERN |
6706 PPC_ALTIVEC;
9df5a466
TM
6707 pcc->msr_mask = (1ull << MSR_VR) |
6708 (1ull << MSR_POW) |
6709 (1ull << MSR_ILE) |
6710 (1ull << MSR_EE) |
6711 (1ull << MSR_PR) |
6712 (1ull << MSR_FP) |
6713 (1ull << MSR_ME) |
6714 (1ull << MSR_FE0) |
6715 (1ull << MSR_SE) |
6716 (1ull << MSR_DE) |
6717 (1ull << MSR_FE1) |
6718 (1ull << MSR_EP) |
6719 (1ull << MSR_IR) |
6720 (1ull << MSR_DR) |
6721 (1ull << MSR_PMM) |
6722 (1ull << MSR_RI) |
6723 (1ull << MSR_LE);
ba9fd9f1
AF
6724 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
6725 pcc->excp_model = POWERPC_EXCP_74xx;
6726 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6727 pcc->bfd_mach = bfd_mach_ppc_7400;
6728 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6729 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6730 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6731}
6732
a750fc0b
JM
6733static void init_proc_7445 (CPUPPCState *env)
6734{
6735 gen_spr_ne_601(env);
6736 gen_spr_7xx(env);
6737 /* Time base */
6738 gen_tbl(env);
6739 /* 74xx specific SPR */
6740 gen_spr_74xx(env);
6741 /* LDSTCR */
6742 /* XXX : not implemented */
6743 spr_register(env, SPR_LDSTCR, "LDSTCR",
6744 SPR_NOACCESS, SPR_NOACCESS,
6745 &spr_read_generic, &spr_write_generic,
6746 0x00000000);
6747 /* ICTRL */
6748 /* XXX : not implemented */
6749 spr_register(env, SPR_ICTRL, "ICTRL",
6750 SPR_NOACCESS, SPR_NOACCESS,
6751 &spr_read_generic, &spr_write_generic,
6752 0x00000000);
6753 /* MSSSR0 */
578bb252 6754 /* XXX : not implemented */
a750fc0b
JM
6755 spr_register(env, SPR_MSSSR0, "MSSSR0",
6756 SPR_NOACCESS, SPR_NOACCESS,
6757 &spr_read_generic, &spr_write_generic,
6758 0x00000000);
6759 /* PMC */
6760 /* XXX : not implemented */
cb8b8bf8 6761 spr_register(env, SPR_7XX_PMC5, "PMC5",
a750fc0b
JM
6762 SPR_NOACCESS, SPR_NOACCESS,
6763 &spr_read_generic, &spr_write_generic,
6764 0x00000000);
578bb252 6765 /* XXX : not implemented */
cb8b8bf8 6766 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
a750fc0b
JM
6767 &spr_read_ureg, SPR_NOACCESS,
6768 &spr_read_ureg, SPR_NOACCESS,
6769 0x00000000);
578bb252 6770 /* XXX : not implemented */
cb8b8bf8 6771 spr_register(env, SPR_7XX_PMC6, "PMC6",
a750fc0b
JM
6772 SPR_NOACCESS, SPR_NOACCESS,
6773 &spr_read_generic, &spr_write_generic,
6774 0x00000000);
578bb252 6775 /* XXX : not implemented */
cb8b8bf8 6776 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
a750fc0b
JM
6777 &spr_read_ureg, SPR_NOACCESS,
6778 &spr_read_ureg, SPR_NOACCESS,
6779 0x00000000);
6780 /* SPRGs */
6781 spr_register(env, SPR_SPRG4, "SPRG4",
6782 SPR_NOACCESS, SPR_NOACCESS,
6783 &spr_read_generic, &spr_write_generic,
6784 0x00000000);
6785 spr_register(env, SPR_USPRG4, "USPRG4",
6786 &spr_read_ureg, SPR_NOACCESS,
6787 &spr_read_ureg, SPR_NOACCESS,
6788 0x00000000);
6789 spr_register(env, SPR_SPRG5, "SPRG5",
6790 SPR_NOACCESS, SPR_NOACCESS,
6791 &spr_read_generic, &spr_write_generic,
6792 0x00000000);
6793 spr_register(env, SPR_USPRG5, "USPRG5",
6794 &spr_read_ureg, SPR_NOACCESS,
6795 &spr_read_ureg, SPR_NOACCESS,
6796 0x00000000);
6797 spr_register(env, SPR_SPRG6, "SPRG6",
6798 SPR_NOACCESS, SPR_NOACCESS,
6799 &spr_read_generic, &spr_write_generic,
6800 0x00000000);
6801 spr_register(env, SPR_USPRG6, "USPRG6",
6802 &spr_read_ureg, SPR_NOACCESS,
6803 &spr_read_ureg, SPR_NOACCESS,
6804 0x00000000);
6805 spr_register(env, SPR_SPRG7, "SPRG7",
6806 SPR_NOACCESS, SPR_NOACCESS,
6807 &spr_read_generic, &spr_write_generic,
6808 0x00000000);
6809 spr_register(env, SPR_USPRG7, "USPRG7",
6810 &spr_read_ureg, SPR_NOACCESS,
6811 &spr_read_ureg, SPR_NOACCESS,
6812 0x00000000);
6813 /* Memory management */
6814 gen_low_BATs(env);
6815 gen_high_BATs(env);
578bb252 6816 gen_74xx_soft_tlb(env, 128, 2);
e1833e1f 6817 init_excp_7450(env);
d63001d1
JM
6818 env->dcache_line_size = 32;
6819 env->icache_line_size = 32;
a750fc0b
JM
6820 /* Allocate hardware IRQ controller */
6821 ppc6xx_irq_init(env);
6822}
a750fc0b 6823
7856e3a4
AF
6824POWERPC_FAMILY(7445)(ObjectClass *oc, void *data)
6825{
ca5dff0a 6826 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6827 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6828
ca5dff0a 6829 dc->desc = "PowerPC 7445 (aka G4)";
7856e3a4
AF
6830 pcc->init_proc = init_proc_7445;
6831 pcc->check_pow = check_pow_hid0_74xx;
53116ebf
AF
6832 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6833 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6834 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6835 PPC_FLOAT_STFIWX |
6836 PPC_CACHE | PPC_CACHE_ICBI |
6837 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6838 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6839 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6840 PPC_MEM_TLBIA | PPC_74xx_TLB |
6841 PPC_SEGMENT | PPC_EXTERN |
6842 PPC_ALTIVEC;
9df5a466
TM
6843 pcc->msr_mask = (1ull << MSR_VR) |
6844 (1ull << MSR_POW) |
6845 (1ull << MSR_ILE) |
6846 (1ull << MSR_EE) |
6847 (1ull << MSR_PR) |
6848 (1ull << MSR_FP) |
6849 (1ull << MSR_ME) |
6850 (1ull << MSR_FE0) |
6851 (1ull << MSR_SE) |
6852 (1ull << MSR_DE) |
6853 (1ull << MSR_FE1) |
6854 (1ull << MSR_EP) |
6855 (1ull << MSR_IR) |
6856 (1ull << MSR_DR) |
6857 (1ull << MSR_PMM) |
6858 (1ull << MSR_RI) |
6859 (1ull << MSR_LE);
ba9fd9f1
AF
6860 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
6861 pcc->excp_model = POWERPC_EXCP_74xx;
6862 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6863 pcc->bfd_mach = bfd_mach_ppc_7400;
6864 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6865 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6866 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
6867}
6868
a750fc0b
JM
6869static void init_proc_7455 (CPUPPCState *env)
6870{
6871 gen_spr_ne_601(env);
6872 gen_spr_7xx(env);
6873 /* Time base */
6874 gen_tbl(env);
6875 /* 74xx specific SPR */
6876 gen_spr_74xx(env);
6877 /* Level 3 cache control */
6878 gen_l3_ctrl(env);
6879 /* LDSTCR */
6880 /* XXX : not implemented */
6881 spr_register(env, SPR_LDSTCR, "LDSTCR",
6882 SPR_NOACCESS, SPR_NOACCESS,
6883 &spr_read_generic, &spr_write_generic,
6884 0x00000000);
6885 /* ICTRL */
6886 /* XXX : not implemented */
6887 spr_register(env, SPR_ICTRL, "ICTRL",
6888 SPR_NOACCESS, SPR_NOACCESS,
6889 &spr_read_generic, &spr_write_generic,
6890 0x00000000);
6891 /* MSSSR0 */
578bb252 6892 /* XXX : not implemented */
a750fc0b
JM
6893 spr_register(env, SPR_MSSSR0, "MSSSR0",
6894 SPR_NOACCESS, SPR_NOACCESS,
6895 &spr_read_generic, &spr_write_generic,
6896 0x00000000);
6897 /* PMC */
6898 /* XXX : not implemented */
cb8b8bf8 6899 spr_register(env, SPR_7XX_PMC5, "PMC5",
a750fc0b
JM
6900 SPR_NOACCESS, SPR_NOACCESS,
6901 &spr_read_generic, &spr_write_generic,
6902 0x00000000);
578bb252 6903 /* XXX : not implemented */
cb8b8bf8 6904 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
a750fc0b
JM
6905 &spr_read_ureg, SPR_NOACCESS,
6906 &spr_read_ureg, SPR_NOACCESS,
6907 0x00000000);
578bb252 6908 /* XXX : not implemented */
cb8b8bf8 6909 spr_register(env, SPR_7XX_PMC6, "PMC6",
a750fc0b
JM
6910 SPR_NOACCESS, SPR_NOACCESS,
6911 &spr_read_generic, &spr_write_generic,
6912 0x00000000);
578bb252 6913 /* XXX : not implemented */
cb8b8bf8 6914 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
a750fc0b
JM
6915 &spr_read_ureg, SPR_NOACCESS,
6916 &spr_read_ureg, SPR_NOACCESS,
6917 0x00000000);
6918 /* SPRGs */
6919 spr_register(env, SPR_SPRG4, "SPRG4",
6920 SPR_NOACCESS, SPR_NOACCESS,
6921 &spr_read_generic, &spr_write_generic,
6922 0x00000000);
6923 spr_register(env, SPR_USPRG4, "USPRG4",
6924 &spr_read_ureg, SPR_NOACCESS,
6925 &spr_read_ureg, SPR_NOACCESS,
6926 0x00000000);
6927 spr_register(env, SPR_SPRG5, "SPRG5",
6928 SPR_NOACCESS, SPR_NOACCESS,
6929 &spr_read_generic, &spr_write_generic,
6930 0x00000000);
6931 spr_register(env, SPR_USPRG5, "USPRG5",
6932 &spr_read_ureg, SPR_NOACCESS,
6933 &spr_read_ureg, SPR_NOACCESS,
6934 0x00000000);
6935 spr_register(env, SPR_SPRG6, "SPRG6",
6936 SPR_NOACCESS, SPR_NOACCESS,
6937 &spr_read_generic, &spr_write_generic,
6938 0x00000000);
6939 spr_register(env, SPR_USPRG6, "USPRG6",
6940 &spr_read_ureg, SPR_NOACCESS,
6941 &spr_read_ureg, SPR_NOACCESS,
6942 0x00000000);
6943 spr_register(env, SPR_SPRG7, "SPRG7",
6944 SPR_NOACCESS, SPR_NOACCESS,
6945 &spr_read_generic, &spr_write_generic,
6946 0x00000000);
6947 spr_register(env, SPR_USPRG7, "USPRG7",
6948 &spr_read_ureg, SPR_NOACCESS,
6949 &spr_read_ureg, SPR_NOACCESS,
6950 0x00000000);
6951 /* Memory management */
6952 gen_low_BATs(env);
6953 gen_high_BATs(env);
578bb252 6954 gen_74xx_soft_tlb(env, 128, 2);
e1833e1f 6955 init_excp_7450(env);
d63001d1
JM
6956 env->dcache_line_size = 32;
6957 env->icache_line_size = 32;
a750fc0b
JM
6958 /* Allocate hardware IRQ controller */
6959 ppc6xx_irq_init(env);
6960}
a750fc0b 6961
7856e3a4
AF
6962POWERPC_FAMILY(7455)(ObjectClass *oc, void *data)
6963{
ca5dff0a 6964 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
6965 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6966
ca5dff0a 6967 dc->desc = "PowerPC 7455 (aka G4)";
7856e3a4
AF
6968 pcc->init_proc = init_proc_7455;
6969 pcc->check_pow = check_pow_hid0_74xx;
53116ebf
AF
6970 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6971 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6972 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6973 PPC_FLOAT_STFIWX |
6974 PPC_CACHE | PPC_CACHE_ICBI |
6975 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6976 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6977 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6978 PPC_MEM_TLBIA | PPC_74xx_TLB |
6979 PPC_SEGMENT | PPC_EXTERN |
6980 PPC_ALTIVEC;
9df5a466
TM
6981 pcc->msr_mask = (1ull << MSR_VR) |
6982 (1ull << MSR_POW) |
6983 (1ull << MSR_ILE) |
6984 (1ull << MSR_EE) |
6985 (1ull << MSR_PR) |
6986 (1ull << MSR_FP) |
6987 (1ull << MSR_ME) |
6988 (1ull << MSR_FE0) |
6989 (1ull << MSR_SE) |
6990 (1ull << MSR_DE) |
6991 (1ull << MSR_FE1) |
6992 (1ull << MSR_EP) |
6993 (1ull << MSR_IR) |
6994 (1ull << MSR_DR) |
6995 (1ull << MSR_PMM) |
6996 (1ull << MSR_RI) |
6997 (1ull << MSR_LE);
ba9fd9f1
AF
6998 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
6999 pcc->excp_model = POWERPC_EXCP_74xx;
7000 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7001 pcc->bfd_mach = bfd_mach_ppc_7400;
7002 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7003 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7004 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
7005}
7006
4e777442
JM
7007static void init_proc_7457 (CPUPPCState *env)
7008{
7009 gen_spr_ne_601(env);
7010 gen_spr_7xx(env);
7011 /* Time base */
7012 gen_tbl(env);
7013 /* 74xx specific SPR */
7014 gen_spr_74xx(env);
7015 /* Level 3 cache control */
7016 gen_l3_ctrl(env);
7017 /* L3ITCR1 */
7018 /* XXX : not implemented */
7019 spr_register(env, SPR_L3ITCR1, "L3ITCR1",
7020 SPR_NOACCESS, SPR_NOACCESS,
7021 &spr_read_generic, &spr_write_generic,
7022 0x00000000);
7023 /* L3ITCR2 */
7024 /* XXX : not implemented */
7025 spr_register(env, SPR_L3ITCR2, "L3ITCR2",
7026 SPR_NOACCESS, SPR_NOACCESS,
7027 &spr_read_generic, &spr_write_generic,
7028 0x00000000);
7029 /* L3ITCR3 */
7030 /* XXX : not implemented */
7031 spr_register(env, SPR_L3ITCR3, "L3ITCR3",
7032 SPR_NOACCESS, SPR_NOACCESS,
7033 &spr_read_generic, &spr_write_generic,
7034 0x00000000);
7035 /* L3OHCR */
7036 /* XXX : not implemented */
7037 spr_register(env, SPR_L3OHCR, "L3OHCR",
7038 SPR_NOACCESS, SPR_NOACCESS,
7039 &spr_read_generic, &spr_write_generic,
7040 0x00000000);
7041 /* LDSTCR */
7042 /* XXX : not implemented */
7043 spr_register(env, SPR_LDSTCR, "LDSTCR",
7044 SPR_NOACCESS, SPR_NOACCESS,
7045 &spr_read_generic, &spr_write_generic,
7046 0x00000000);
7047 /* ICTRL */
7048 /* XXX : not implemented */
7049 spr_register(env, SPR_ICTRL, "ICTRL",
7050 SPR_NOACCESS, SPR_NOACCESS,
7051 &spr_read_generic, &spr_write_generic,
7052 0x00000000);
7053 /* MSSSR0 */
7054 /* XXX : not implemented */
7055 spr_register(env, SPR_MSSSR0, "MSSSR0",
7056 SPR_NOACCESS, SPR_NOACCESS,
7057 &spr_read_generic, &spr_write_generic,
7058 0x00000000);
7059 /* PMC */
7060 /* XXX : not implemented */
cb8b8bf8 7061 spr_register(env, SPR_7XX_PMC5, "PMC5",
4e777442
JM
7062 SPR_NOACCESS, SPR_NOACCESS,
7063 &spr_read_generic, &spr_write_generic,
7064 0x00000000);
7065 /* XXX : not implemented */
cb8b8bf8 7066 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
4e777442
JM
7067 &spr_read_ureg, SPR_NOACCESS,
7068 &spr_read_ureg, SPR_NOACCESS,
7069 0x00000000);
7070 /* XXX : not implemented */
cb8b8bf8 7071 spr_register(env, SPR_7XX_PMC6, "PMC6",
4e777442
JM
7072 SPR_NOACCESS, SPR_NOACCESS,
7073 &spr_read_generic, &spr_write_generic,
7074 0x00000000);
7075 /* XXX : not implemented */
cb8b8bf8 7076 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
4e777442
JM
7077 &spr_read_ureg, SPR_NOACCESS,
7078 &spr_read_ureg, SPR_NOACCESS,
7079 0x00000000);
7080 /* SPRGs */
7081 spr_register(env, SPR_SPRG4, "SPRG4",
7082 SPR_NOACCESS, SPR_NOACCESS,
7083 &spr_read_generic, &spr_write_generic,
7084 0x00000000);
7085 spr_register(env, SPR_USPRG4, "USPRG4",
7086 &spr_read_ureg, SPR_NOACCESS,
7087 &spr_read_ureg, SPR_NOACCESS,
7088 0x00000000);
7089 spr_register(env, SPR_SPRG5, "SPRG5",
7090 SPR_NOACCESS, SPR_NOACCESS,
7091 &spr_read_generic, &spr_write_generic,
7092 0x00000000);
7093 spr_register(env, SPR_USPRG5, "USPRG5",
7094 &spr_read_ureg, SPR_NOACCESS,
7095 &spr_read_ureg, SPR_NOACCESS,
7096 0x00000000);
7097 spr_register(env, SPR_SPRG6, "SPRG6",
7098 SPR_NOACCESS, SPR_NOACCESS,
7099 &spr_read_generic, &spr_write_generic,
7100 0x00000000);
7101 spr_register(env, SPR_USPRG6, "USPRG6",
7102 &spr_read_ureg, SPR_NOACCESS,
7103 &spr_read_ureg, SPR_NOACCESS,
7104 0x00000000);
7105 spr_register(env, SPR_SPRG7, "SPRG7",
7106 SPR_NOACCESS, SPR_NOACCESS,
7107 &spr_read_generic, &spr_write_generic,
7108 0x00000000);
7109 spr_register(env, SPR_USPRG7, "USPRG7",
7110 &spr_read_ureg, SPR_NOACCESS,
7111 &spr_read_ureg, SPR_NOACCESS,
7112 0x00000000);
7113 /* Memory management */
7114 gen_low_BATs(env);
7115 gen_high_BATs(env);
7116 gen_74xx_soft_tlb(env, 128, 2);
7117 init_excp_7450(env);
7118 env->dcache_line_size = 32;
7119 env->icache_line_size = 32;
7120 /* Allocate hardware IRQ controller */
7121 ppc6xx_irq_init(env);
7122}
7123
7856e3a4
AF
7124POWERPC_FAMILY(7457)(ObjectClass *oc, void *data)
7125{
ca5dff0a 7126 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
7127 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7128
ca5dff0a 7129 dc->desc = "PowerPC 7457 (aka G4)";
7856e3a4
AF
7130 pcc->init_proc = init_proc_7457;
7131 pcc->check_pow = check_pow_hid0_74xx;
53116ebf
AF
7132 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7133 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7134 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7135 PPC_FLOAT_STFIWX |
7136 PPC_CACHE | PPC_CACHE_ICBI |
7137 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
7138 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7139 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7140 PPC_MEM_TLBIA | PPC_74xx_TLB |
7141 PPC_SEGMENT | PPC_EXTERN |
7142 PPC_ALTIVEC;
9df5a466
TM
7143 pcc->msr_mask = (1ull << MSR_VR) |
7144 (1ull << MSR_POW) |
7145 (1ull << MSR_ILE) |
7146 (1ull << MSR_EE) |
7147 (1ull << MSR_PR) |
7148 (1ull << MSR_FP) |
7149 (1ull << MSR_ME) |
7150 (1ull << MSR_FE0) |
7151 (1ull << MSR_SE) |
7152 (1ull << MSR_DE) |
7153 (1ull << MSR_FE1) |
7154 (1ull << MSR_EP) |
7155 (1ull << MSR_IR) |
7156 (1ull << MSR_DR) |
7157 (1ull << MSR_PMM) |
7158 (1ull << MSR_RI) |
7159 (1ull << MSR_LE);
ba9fd9f1
AF
7160 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
7161 pcc->excp_model = POWERPC_EXCP_74xx;
7162 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7163 pcc->bfd_mach = bfd_mach_ppc_7400;
7164 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7165 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7166 POWERPC_FLAG_BUS_CLK;
7856e3a4
AF
7167}
7168
7162bdea
JG
7169static void init_proc_e600 (CPUPPCState *env)
7170{
7171 gen_spr_ne_601(env);
7172 gen_spr_7xx(env);
7173 /* Time base */
7174 gen_tbl(env);
7175 /* 74xx specific SPR */
7176 gen_spr_74xx(env);
7177 /* XXX : not implemented */
7178 spr_register(env, SPR_UBAMR, "UBAMR",
7179 &spr_read_ureg, SPR_NOACCESS,
7180 &spr_read_ureg, SPR_NOACCESS,
7181 0x00000000);
7182 /* XXX : not implemented */
7183 spr_register(env, SPR_LDSTCR, "LDSTCR",
7184 SPR_NOACCESS, SPR_NOACCESS,
7185 &spr_read_generic, &spr_write_generic,
7186 0x00000000);
7187 /* XXX : not implemented */
7188 spr_register(env, SPR_ICTRL, "ICTRL",
7189 SPR_NOACCESS, SPR_NOACCESS,
7190 &spr_read_generic, &spr_write_generic,
7191 0x00000000);
7192 /* XXX : not implemented */
7193 spr_register(env, SPR_MSSSR0, "MSSSR0",
7194 SPR_NOACCESS, SPR_NOACCESS,
7195 &spr_read_generic, &spr_write_generic,
7196 0x00000000);
7197 /* XXX : not implemented */
cb8b8bf8 7198 spr_register(env, SPR_7XX_PMC5, "PMC5",
7162bdea
JG
7199 SPR_NOACCESS, SPR_NOACCESS,
7200 &spr_read_generic, &spr_write_generic,
7201 0x00000000);
7202 /* XXX : not implemented */
cb8b8bf8 7203 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
7162bdea
JG
7204 &spr_read_ureg, SPR_NOACCESS,
7205 &spr_read_ureg, SPR_NOACCESS,
7206 0x00000000);
7207 /* XXX : not implemented */
cb8b8bf8 7208 spr_register(env, SPR_7XX_PMC6, "PMC6",
7162bdea
JG
7209 SPR_NOACCESS, SPR_NOACCESS,
7210 &spr_read_generic, &spr_write_generic,
7211 0x00000000);
7212 /* XXX : not implemented */
cb8b8bf8 7213 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
7162bdea
JG
7214 &spr_read_ureg, SPR_NOACCESS,
7215 &spr_read_ureg, SPR_NOACCESS,
7216 0x00000000);
7217 /* SPRGs */
7218 spr_register(env, SPR_SPRG4, "SPRG4",
7219 SPR_NOACCESS, SPR_NOACCESS,
7220 &spr_read_generic, &spr_write_generic,
7221 0x00000000);
7222 spr_register(env, SPR_USPRG4, "USPRG4",
7223 &spr_read_ureg, SPR_NOACCESS,
7224 &spr_read_ureg, SPR_NOACCESS,
7225 0x00000000);
7226 spr_register(env, SPR_SPRG5, "SPRG5",
7227 SPR_NOACCESS, SPR_NOACCESS,
7228 &spr_read_generic, &spr_write_generic,
7229 0x00000000);
7230 spr_register(env, SPR_USPRG5, "USPRG5",
7231 &spr_read_ureg, SPR_NOACCESS,
7232 &spr_read_ureg, SPR_NOACCESS,
7233 0x00000000);
7234 spr_register(env, SPR_SPRG6, "SPRG6",
7235 SPR_NOACCESS, SPR_NOACCESS,
7236 &spr_read_generic, &spr_write_generic,
7237 0x00000000);
7238 spr_register(env, SPR_USPRG6, "USPRG6",
7239 &spr_read_ureg, SPR_NOACCESS,
7240 &spr_read_ureg, SPR_NOACCESS,
7241 0x00000000);
7242 spr_register(env, SPR_SPRG7, "SPRG7",
7243 SPR_NOACCESS, SPR_NOACCESS,
7244 &spr_read_generic, &spr_write_generic,
7245 0x00000000);
7246 spr_register(env, SPR_USPRG7, "USPRG7",
7247 &spr_read_ureg, SPR_NOACCESS,
7248 &spr_read_ureg, SPR_NOACCESS,
7249 0x00000000);
7250 /* Memory management */
7251 gen_low_BATs(env);
7252 gen_high_BATs(env);
7253 gen_74xx_soft_tlb(env, 128, 2);
7254 init_excp_7450(env);
7255 env->dcache_line_size = 32;
7256 env->icache_line_size = 32;
7257 /* Allocate hardware IRQ controller */
7258 ppc6xx_irq_init(env);
7259}
7260
7261POWERPC_FAMILY(e600)(ObjectClass *oc, void *data)
7262{
7263 DeviceClass *dc = DEVICE_CLASS(oc);
7264 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7265
7266 dc->desc = "PowerPC e600";
7267 pcc->init_proc = init_proc_e600;
7268 pcc->check_pow = check_pow_hid0_74xx;
7269 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7270 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7271 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7272 PPC_FLOAT_STFIWX |
7273 PPC_CACHE | PPC_CACHE_ICBI |
7274 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
7275 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7276 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7277 PPC_MEM_TLBIA | PPC_74xx_TLB |
7278 PPC_SEGMENT | PPC_EXTERN |
7279 PPC_ALTIVEC;
7280 pcc->insns_flags2 = PPC_NONE;
9df5a466
TM
7281 pcc->msr_mask = (1ull << MSR_VR) |
7282 (1ull << MSR_POW) |
7283 (1ull << MSR_ILE) |
7284 (1ull << MSR_EE) |
7285 (1ull << MSR_PR) |
7286 (1ull << MSR_FP) |
7287 (1ull << MSR_ME) |
7288 (1ull << MSR_FE0) |
7289 (1ull << MSR_SE) |
7290 (1ull << MSR_DE) |
7291 (1ull << MSR_FE1) |
7292 (1ull << MSR_EP) |
7293 (1ull << MSR_IR) |
7294 (1ull << MSR_DR) |
7295 (1ull << MSR_PMM) |
7296 (1ull << MSR_RI) |
7297 (1ull << MSR_LE);
7162bdea
JG
7298 pcc->mmu_model = POWERPC_MMU_32B;
7299#if defined(CONFIG_SOFTMMU)
7300 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
7301#endif
7302 pcc->excp_model = POWERPC_EXCP_74xx;
7303 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7304 pcc->bfd_mach = bfd_mach_ppc_7400;
7305 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7306 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7307 POWERPC_FLAG_BUS_CLK;
7308}
7309
a750fc0b 7310#if defined (TARGET_PPC64)
417bf010
JM
7311#if defined(CONFIG_USER_ONLY)
7312#define POWERPC970_HID5_INIT 0x00000080
7313#else
7314#define POWERPC970_HID5_INIT 0x00000000
7315#endif
7316
7488d481
AK
7317enum BOOK3S_CPU_TYPE {
7318 BOOK3S_CPU_970,
7319 BOOK3S_CPU_POWER5PLUS,
a2428814
AK
7320 BOOK3S_CPU_POWER6,
7321 BOOK3S_CPU_POWER7,
7322 BOOK3S_CPU_POWER8
7488d481
AK
7323};
7324
45ed0be1
AK
7325static void gen_fscr_facility_check(void *opaque, int facility_sprn, int bit,
7326 int sprn, int cause)
7327{
7328 TCGv_i32 t1 = tcg_const_i32(bit);
7329 TCGv_i32 t2 = tcg_const_i32(sprn);
7330 TCGv_i32 t3 = tcg_const_i32(cause);
7331
7332 gen_update_current_nip(opaque);
7333 gen_helper_fscr_facility_check(cpu_env, t1, t2, t3);
7334
7335 tcg_temp_free_i32(t3);
7336 tcg_temp_free_i32(t2);
7337 tcg_temp_free_i32(t1);
7338}
7339
cdcdda27
AK
7340static void gen_msr_facility_check(void *opaque, int facility_sprn, int bit,
7341 int sprn, int cause)
7342{
7343 TCGv_i32 t1 = tcg_const_i32(bit);
7344 TCGv_i32 t2 = tcg_const_i32(sprn);
7345 TCGv_i32 t3 = tcg_const_i32(cause);
7346
7347 gen_update_current_nip(opaque);
7348 gen_helper_msr_facility_check(cpu_env, t1, t2, t3);
7349
7350 tcg_temp_free_i32(t3);
7351 tcg_temp_free_i32(t2);
7352 tcg_temp_free_i32(t1);
7353}
7354
7355static void spr_read_prev_upper32(void *opaque, int gprn, int sprn)
7356{
7357 TCGv spr_up = tcg_temp_new();
7358 TCGv spr = tcg_temp_new();
7359
7360 gen_load_spr(spr, sprn - 1);
7361 tcg_gen_shri_tl(spr_up, spr, 32);
7362 tcg_gen_ext32u_tl(cpu_gpr[gprn], spr_up);
7363
7364 tcg_temp_free(spr);
7365 tcg_temp_free(spr_up);
7366}
7367
7368static void spr_write_prev_upper32(void *opaque, int sprn, int gprn)
7369{
7370 TCGv spr = tcg_temp_new();
7371
7372 gen_load_spr(spr, sprn - 1);
7373 tcg_gen_deposit_tl(spr, spr, cpu_gpr[gprn], 32, 32);
7374 gen_store_spr(sprn - 1, spr);
7375
7376 tcg_temp_free(spr);
7377}
7378
2f462816
JM
7379static int check_pow_970 (CPUPPCState *env)
7380{
bbc01ca7 7381 if (env->spr[SPR_HID0] & (HID0_DEEPNAP | HID0_DOZE | HID0_NAP)) {
2f462816 7382 return 1;
bbc01ca7 7383 }
2f462816
JM
7384
7385 return 0;
7386}
7387
42382f62 7388static void gen_spr_970_hid(CPUPPCState *env)
a750fc0b 7389{
a750fc0b
JM
7390 /* Hardware implementation registers */
7391 /* XXX : not implemented */
7392 spr_register(env, SPR_HID0, "HID0",
7393 SPR_NOACCESS, SPR_NOACCESS,
06403421 7394 &spr_read_generic, &spr_write_clear,
d63001d1 7395 0x60000000);
a750fc0b
JM
7396 spr_register(env, SPR_HID1, "HID1",
7397 SPR_NOACCESS, SPR_NOACCESS,
7398 &spr_read_generic, &spr_write_generic,
7399 0x00000000);
e57448f1
JM
7400 spr_register(env, SPR_970_HID5, "HID5",
7401 SPR_NOACCESS, SPR_NOACCESS,
7402 &spr_read_generic, &spr_write_generic,
417bf010 7403 POWERPC970_HID5_INIT);
42382f62
AK
7404}
7405
7406static void gen_spr_970_hior(CPUPPCState *env)
7407{
12de9a39
JM
7408 spr_register(env, SPR_HIOR, "SPR_HIOR",
7409 SPR_NOACCESS, SPR_NOACCESS,
2adab7d6
BS
7410 &spr_read_hior, &spr_write_hior,
7411 0x00000000);
42382f62 7412}
7856e3a4 7413
ba881002
AK
7414static void gen_spr_970_lpar(CPUPPCState *env)
7415{
7416 /* Logical partitionning */
7417 /* PPC970: HID4 is effectively the LPCR */
7418 spr_register(env, SPR_970_HID4, "HID4",
7419 SPR_NOACCESS, SPR_NOACCESS,
7420 &spr_read_generic, &spr_write_generic,
7421 0x00000000);
7422}
7423
42382f62
AK
7424static void gen_spr_book3s_common(CPUPPCState *env)
7425{
4e98d8cf
BS
7426 spr_register(env, SPR_CTRL, "SPR_CTRL",
7427 SPR_NOACCESS, SPR_NOACCESS,
4e381819 7428 SPR_NOACCESS, &spr_write_generic,
4e98d8cf
BS
7429 0x00000000);
7430 spr_register(env, SPR_UCTRL, "SPR_UCTRL",
eb16dd9c
AK
7431 &spr_read_ureg, SPR_NOACCESS,
7432 &spr_read_ureg, SPR_NOACCESS,
4e98d8cf 7433 0x00000000);
42382f62
AK
7434}
7435
7436static void gen_spr_book3s_altivec(CPUPPCState *env)
7437{
7438 if (!(env->insns_flags & PPC_ALTIVEC)) {
7439 return;
7440 }
7441
7303f83d
AK
7442 spr_register_kvm(env, SPR_VRSAVE, "VRSAVE",
7443 &spr_read_generic, &spr_write_generic,
7444 &spr_read_generic, &spr_write_generic,
7445 KVM_REG_PPC_VRSAVE, 0x00000000);
42382f62
AK
7446
7447 /* Can't find information on what this should be on reset. This
7448 * value is the one used by 74xx processors. */
7449 vscr_init(env, 0x00010000);
7450}
7451
fd51ff63
AK
7452static void gen_spr_book3s_dbg(CPUPPCState *env)
7453{
cd9adfdd
AK
7454 /*
7455 * TODO: different specs define different scopes for these,
7456 * will have to address this:
7457 * 970: super/write and super/read
7458 * powerisa 2.03..2.04: hypv/write and super/read.
7459 * powerisa 2.05 and newer: hypv/write and hypv/read.
7460 */
fd51ff63
AK
7461 spr_register_kvm(env, SPR_DABR, "DABR",
7462 SPR_NOACCESS, SPR_NOACCESS,
7463 &spr_read_generic, &spr_write_generic,
7464 KVM_REG_PPC_DABR, 0x00000000);
cd9adfdd
AK
7465 spr_register_kvm(env, SPR_DABRX, "DABRX",
7466 SPR_NOACCESS, SPR_NOACCESS,
7467 &spr_read_generic, &spr_write_generic,
7468 KVM_REG_PPC_DABRX, 0x00000000);
fd51ff63
AK
7469}
7470
7471static void gen_spr_970_dbg(CPUPPCState *env)
7472{
7473 /* Breakpoints */
7474 spr_register(env, SPR_IABR, "IABR",
7475 SPR_NOACCESS, SPR_NOACCESS,
7476 &spr_read_generic, &spr_write_generic,
7477 0x00000000);
7478}
7479
7480static void gen_spr_book3s_pmu_sup(CPUPPCState *env)
7481{
83cc6f8c
AK
7482 spr_register_kvm(env, SPR_POWER_MMCR0, "MMCR0",
7483 SPR_NOACCESS, SPR_NOACCESS,
7484 &spr_read_generic, &spr_write_generic,
7485 KVM_REG_PPC_MMCR0, 0x00000000);
7486 spr_register_kvm(env, SPR_POWER_MMCR1, "MMCR1",
7487 SPR_NOACCESS, SPR_NOACCESS,
7488 &spr_read_generic, &spr_write_generic,
7489 KVM_REG_PPC_MMCR1, 0x00000000);
7490 spr_register_kvm(env, SPR_POWER_MMCRA, "MMCRA",
7491 SPR_NOACCESS, SPR_NOACCESS,
7492 &spr_read_generic, &spr_write_generic,
7493 KVM_REG_PPC_MMCRA, 0x00000000);
7494 spr_register_kvm(env, SPR_POWER_PMC1, "PMC1",
7495 SPR_NOACCESS, SPR_NOACCESS,
7496 &spr_read_generic, &spr_write_generic,
7497 KVM_REG_PPC_PMC1, 0x00000000);
7498 spr_register_kvm(env, SPR_POWER_PMC2, "PMC2",
7499 SPR_NOACCESS, SPR_NOACCESS,
7500 &spr_read_generic, &spr_write_generic,
7501 KVM_REG_PPC_PMC2, 0x00000000);
7502 spr_register_kvm(env, SPR_POWER_PMC3, "PMC3",
7503 SPR_NOACCESS, SPR_NOACCESS,
7504 &spr_read_generic, &spr_write_generic,
7505 KVM_REG_PPC_PMC3, 0x00000000);
7506 spr_register_kvm(env, SPR_POWER_PMC4, "PMC4",
7507 SPR_NOACCESS, SPR_NOACCESS,
7508 &spr_read_generic, &spr_write_generic,
7509 KVM_REG_PPC_PMC4, 0x00000000);
7510 spr_register_kvm(env, SPR_POWER_PMC5, "PMC5",
7511 SPR_NOACCESS, SPR_NOACCESS,
7512 &spr_read_generic, &spr_write_generic,
7513 KVM_REG_PPC_PMC5, 0x00000000);
7514 spr_register_kvm(env, SPR_POWER_PMC6, "PMC6",
7515 SPR_NOACCESS, SPR_NOACCESS,
7516 &spr_read_generic, &spr_write_generic,
7517 KVM_REG_PPC_PMC6, 0x00000000);
7518 spr_register_kvm(env, SPR_POWER_SIAR, "SIAR",
7519 SPR_NOACCESS, SPR_NOACCESS,
7520 &spr_read_generic, &spr_write_generic,
7521 KVM_REG_PPC_SIAR, 0x00000000);
7522 spr_register_kvm(env, SPR_POWER_SDAR, "SDAR",
7523 SPR_NOACCESS, SPR_NOACCESS,
7524 &spr_read_generic, &spr_write_generic,
7525 KVM_REG_PPC_SDAR, 0x00000000);
fd51ff63
AK
7526}
7527
7528static void gen_spr_book3s_pmu_user(CPUPPCState *env)
7529{
7530 spr_register(env, SPR_POWER_UMMCR0, "UMMCR0",
7531 &spr_read_ureg, SPR_NOACCESS,
7532 &spr_read_ureg, &spr_write_ureg,
7533 0x00000000);
7534 spr_register(env, SPR_POWER_UMMCR1, "UMMCR1",
7535 &spr_read_ureg, SPR_NOACCESS,
7536 &spr_read_ureg, &spr_write_ureg,
7537 0x00000000);
077850b0
AK
7538 spr_register(env, SPR_POWER_UMMCRA, "UMMCRA",
7539 &spr_read_ureg, SPR_NOACCESS,
7540 &spr_read_ureg, &spr_write_ureg,
7541 0x00000000);
fd51ff63
AK
7542 spr_register(env, SPR_POWER_UPMC1, "UPMC1",
7543 &spr_read_ureg, SPR_NOACCESS,
7544 &spr_read_ureg, &spr_write_ureg,
7545 0x00000000);
7546 spr_register(env, SPR_POWER_UPMC2, "UPMC2",
7547 &spr_read_ureg, SPR_NOACCESS,
7548 &spr_read_ureg, &spr_write_ureg,
7549 0x00000000);
7550 spr_register(env, SPR_POWER_UPMC3, "UPMC3",
7551 &spr_read_ureg, SPR_NOACCESS,
7552 &spr_read_ureg, &spr_write_ureg,
7553 0x00000000);
7554 spr_register(env, SPR_POWER_UPMC4, "UPMC4",
7555 &spr_read_ureg, SPR_NOACCESS,
7556 &spr_read_ureg, &spr_write_ureg,
7557 0x00000000);
077850b0
AK
7558 spr_register(env, SPR_POWER_UPMC5, "UPMC5",
7559 &spr_read_ureg, SPR_NOACCESS,
7560 &spr_read_ureg, &spr_write_ureg,
7561 0x00000000);
7562 spr_register(env, SPR_POWER_UPMC6, "UPMC6",
7563 &spr_read_ureg, SPR_NOACCESS,
7564 &spr_read_ureg, &spr_write_ureg,
7565 0x00000000);
fd51ff63
AK
7566 spr_register(env, SPR_POWER_USIAR, "USIAR",
7567 &spr_read_ureg, SPR_NOACCESS,
7568 &spr_read_ureg, &spr_write_ureg,
7569 0x00000000);
077850b0
AK
7570 spr_register(env, SPR_POWER_USDAR, "USDAR",
7571 &spr_read_ureg, SPR_NOACCESS,
7572 &spr_read_ureg, &spr_write_ureg,
7573 0x00000000);
fd51ff63
AK
7574}
7575
c36c97f8
AK
7576static void gen_spr_970_pmu_sup(CPUPPCState *env)
7577{
83cc6f8c
AK
7578 spr_register_kvm(env, SPR_970_PMC7, "PMC7",
7579 SPR_NOACCESS, SPR_NOACCESS,
7580 &spr_read_generic, &spr_write_generic,
7581 KVM_REG_PPC_PMC7, 0x00000000);
7582 spr_register_kvm(env, SPR_970_PMC8, "PMC8",
7583 SPR_NOACCESS, SPR_NOACCESS,
7584 &spr_read_generic, &spr_write_generic,
7585 KVM_REG_PPC_PMC8, 0x00000000);
c36c97f8
AK
7586}
7587
7588static void gen_spr_970_pmu_user(CPUPPCState *env)
7589{
7590 spr_register(env, SPR_970_UPMC7, "UPMC7",
7591 &spr_read_ureg, SPR_NOACCESS,
7592 &spr_read_ureg, &spr_write_ureg,
7593 0x00000000);
7594 spr_register(env, SPR_970_UPMC8, "UPMC8",
7595 &spr_read_ureg, SPR_NOACCESS,
7596 &spr_read_ureg, &spr_write_ureg,
7597 0x00000000);
7598}
7599
70c53407
AK
7600static void gen_spr_power8_pmu_sup(CPUPPCState *env)
7601{
7602 spr_register_kvm(env, SPR_POWER_MMCR2, "MMCR2",
7603 SPR_NOACCESS, SPR_NOACCESS,
7604 &spr_read_generic, &spr_write_generic,
7605 KVM_REG_PPC_MMCR2, 0x00000000);
7606 spr_register_kvm(env, SPR_POWER_MMCRS, "MMCRS",
7607 SPR_NOACCESS, SPR_NOACCESS,
7608 &spr_read_generic, &spr_write_generic,
7609 KVM_REG_PPC_MMCRS, 0x00000000);
7610}
7611
7612static void gen_spr_power8_pmu_user(CPUPPCState *env)
7613{
7614 spr_register(env, SPR_POWER_UMMCR2, "UMMCR2",
7615 &spr_read_ureg, SPR_NOACCESS,
7616 &spr_read_ureg, &spr_write_ureg,
7617 0x00000000);
7618}
7619
fd51ff63
AK
7620static void gen_spr_power5p_ear(CPUPPCState *env)
7621{
7622 /* External access control */
7623 spr_register(env, SPR_EAR, "EAR",
7624 SPR_NOACCESS, SPR_NOACCESS,
7625 &spr_read_generic, &spr_write_generic,
7626 0x00000000);
7627}
7628
7488d481
AK
7629static void gen_spr_power5p_lpar(CPUPPCState *env)
7630{
7631 /* Logical partitionning */
7632 spr_register_kvm(env, SPR_LPCR, "LPCR",
7633 SPR_NOACCESS, SPR_NOACCESS,
7634 &spr_read_generic, &spr_write_generic,
7635 KVM_REG_PPC_LPCR, 0x00000000);
7636}
7637
e61716aa
AK
7638static void gen_spr_book3s_ids(CPUPPCState *env)
7639{
7640 /* Processor identification */
7641 spr_register(env, SPR_PIR, "PIR",
7642 SPR_NOACCESS, SPR_NOACCESS,
7643 &spr_read_generic, &spr_write_pir,
7644 0x00000000);
7645}
7646
d1a721ab
AK
7647static void gen_spr_power8_ids(CPUPPCState *env)
7648{
7649 /* Thread identification */
7650 spr_register(env, SPR_TIR, "TIR",
7651 SPR_NOACCESS, SPR_NOACCESS,
7652 &spr_read_generic, SPR_NOACCESS,
7653 0x00000000);
7654}
7655
e61716aa
AK
7656static void gen_spr_book3s_purr(CPUPPCState *env)
7657{
7658#if !defined(CONFIG_USER_ONLY)
7659 /* PURR & SPURR: Hack - treat these as aliases for the TB for now */
7660 spr_register_kvm(env, SPR_PURR, "PURR",
7661 &spr_read_purr, SPR_NOACCESS,
7662 &spr_read_purr, SPR_NOACCESS,
7663 KVM_REG_PPC_PURR, 0x00000000);
7664 spr_register_kvm(env, SPR_SPURR, "SPURR",
7665 &spr_read_purr, SPR_NOACCESS,
7666 &spr_read_purr, SPR_NOACCESS,
7667 KVM_REG_PPC_SPURR, 0x00000000);
7668#endif
7669}
7670
5db7d4fa
AK
7671static void gen_spr_power6_dbg(CPUPPCState *env)
7672{
7673#if !defined(CONFIG_USER_ONLY)
7674 spr_register(env, SPR_CFAR, "SPR_CFAR",
7675 SPR_NOACCESS, SPR_NOACCESS,
7676 &spr_read_cfar, &spr_write_cfar,
7677 0x00000000);
7678#endif
7679}
7680
7681static void gen_spr_power5p_common(CPUPPCState *env)
7682{
7303f83d
AK
7683 spr_register_kvm(env, SPR_PPR, "PPR",
7684 &spr_read_generic, &spr_write_generic,
7685 &spr_read_generic, &spr_write_generic,
7686 KVM_REG_PPC_PPR, 0x00000000);
5db7d4fa
AK
7687}
7688
7689static void gen_spr_power6_common(CPUPPCState *env)
7690{
7691#if !defined(CONFIG_USER_ONLY)
7692 spr_register_kvm(env, SPR_DSCR, "SPR_DSCR",
7693 SPR_NOACCESS, SPR_NOACCESS,
7694 &spr_read_generic, &spr_write_generic,
7695 KVM_REG_PPC_DSCR, 0x00000000);
7696#endif
7697 /*
7698 * Register PCR to report POWERPC_EXCP_PRIV_REG instead of
7699 * POWERPC_EXCP_INVAL_SPR.
7700 */
7701 spr_register(env, SPR_PCR, "PCR",
7702 SPR_NOACCESS, SPR_NOACCESS,
7703 SPR_NOACCESS, SPR_NOACCESS,
7704 0x00000000);
7705}
7706
45ed0be1
AK
7707static void spr_read_tar(void *opaque, int gprn, int sprn)
7708{
7709 gen_fscr_facility_check(opaque, SPR_FSCR, FSCR_TAR, sprn, FSCR_IC_TAR);
7710 spr_read_generic(opaque, gprn, sprn);
7711}
7712
7713static void spr_write_tar(void *opaque, int sprn, int gprn)
7714{
7715 gen_fscr_facility_check(opaque, SPR_FSCR, FSCR_TAR, sprn, FSCR_IC_TAR);
7716 spr_write_generic(opaque, sprn, gprn);
7717}
7718
768167ab
AK
7719static void gen_spr_power8_tce_address_control(CPUPPCState *env)
7720{
7721 spr_register(env, SPR_TAR, "TAR",
45ed0be1 7722 &spr_read_tar, &spr_write_tar,
768167ab
AK
7723 &spr_read_generic, &spr_write_generic,
7724 0x00000000);
7725}
7726
cdcdda27
AK
7727static void spr_read_tm(void *opaque, int gprn, int sprn)
7728{
7729 gen_msr_facility_check(opaque, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
7730 spr_read_generic(opaque, gprn, sprn);
7731}
7732
7733static void spr_write_tm(void *opaque, int sprn, int gprn)
7734{
7735 gen_msr_facility_check(opaque, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
7736 spr_write_generic(opaque, sprn, gprn);
7737}
7738
7739static void spr_read_tm_upper32(void *opaque, int gprn, int sprn)
7740{
7741 gen_msr_facility_check(opaque, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
7742 spr_read_prev_upper32(opaque, gprn, sprn);
7743}
7744
7745static void spr_write_tm_upper32(void *opaque, int sprn, int gprn)
7746{
7747 gen_msr_facility_check(opaque, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
7748 spr_write_prev_upper32(opaque, sprn, gprn);
7749}
7750
7751static void gen_spr_power8_tm(CPUPPCState *env)
7752{
7753 spr_register_kvm(env, SPR_TFHAR, "TFHAR",
7754 &spr_read_tm, &spr_write_tm,
7755 &spr_read_tm, &spr_write_tm,
7756 KVM_REG_PPC_TFHAR, 0x00000000);
7757 spr_register_kvm(env, SPR_TFIAR, "TFIAR",
7758 &spr_read_tm, &spr_write_tm,
7759 &spr_read_tm, &spr_write_tm,
7760 KVM_REG_PPC_TFIAR, 0x00000000);
7761 spr_register_kvm(env, SPR_TEXASR, "TEXASR",
7762 &spr_read_tm, &spr_write_tm,
7763 &spr_read_tm, &spr_write_tm,
7764 KVM_REG_PPC_TEXASR, 0x00000000);
7765 spr_register(env, SPR_TEXASRU, "TEXASRU",
7766 &spr_read_tm_upper32, &spr_write_tm_upper32,
7767 &spr_read_tm_upper32, &spr_write_tm_upper32,
7768 0x00000000);
7769}
7770
4ee4a03b
AK
7771static void spr_read_ebb(void *opaque, int gprn, int sprn)
7772{
7773 gen_fscr_facility_check(opaque, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
7774 spr_read_generic(opaque, gprn, sprn);
7775}
7776
7777static void spr_write_ebb(void *opaque, int sprn, int gprn)
7778{
7779 gen_fscr_facility_check(opaque, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
7780 spr_write_generic(opaque, sprn, gprn);
7781}
7782
7783static void spr_read_ebb_upper32(void *opaque, int gprn, int sprn)
7784{
7785 gen_fscr_facility_check(opaque, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
7786 spr_read_prev_upper32(opaque, gprn, sprn);
7787}
7788
7789static void spr_write_ebb_upper32(void *opaque, int sprn, int gprn)
7790{
7791 gen_fscr_facility_check(opaque, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
7792 spr_write_prev_upper32(opaque, sprn, gprn);
7793}
7794
7795static void gen_spr_power8_ebb(CPUPPCState *env)
7796{
7797 spr_register(env, SPR_BESCRS, "BESCRS",
7798 &spr_read_ebb, &spr_write_ebb,
7799 &spr_read_generic, &spr_write_generic,
7800 0x00000000);
7801 spr_register(env, SPR_BESCRSU, "BESCRSU",
7802 &spr_read_ebb_upper32, &spr_write_ebb_upper32,
7803 &spr_read_prev_upper32, &spr_write_prev_upper32,
7804 0x00000000);
7805 spr_register(env, SPR_BESCRR, "BESCRR",
7806 &spr_read_ebb, &spr_write_ebb,
7807 &spr_read_generic, &spr_write_generic,
7808 0x00000000);
7809 spr_register(env, SPR_BESCRRU, "BESCRRU",
7810 &spr_read_ebb_upper32, &spr_write_ebb_upper32,
7811 &spr_read_prev_upper32, &spr_write_prev_upper32,
7812 0x00000000);
7813 spr_register_kvm(env, SPR_EBBHR, "EBBHR",
7814 &spr_read_ebb, &spr_write_ebb,
7815 &spr_read_generic, &spr_write_generic,
7816 KVM_REG_PPC_EBBHR, 0x00000000);
7817 spr_register_kvm(env, SPR_EBBRR, "EBBRR",
7818 &spr_read_ebb, &spr_write_ebb,
7819 &spr_read_generic, &spr_write_generic,
7820 KVM_REG_PPC_EBBRR, 0x00000000);
7821 spr_register_kvm(env, SPR_BESCR, "BESCR",
7822 &spr_read_ebb, &spr_write_ebb,
7823 &spr_read_generic, &spr_write_generic,
7824 KVM_REG_PPC_BESCR, 0x00000000);
7825}
7826
7019cb3d
AK
7827static void gen_spr_power8_fscr(CPUPPCState *env)
7828{
45ed0be1
AK
7829#if defined(CONFIG_USER_ONLY)
7830 target_ulong initval = 1ULL << FSCR_TAR;
7831#else
7832 target_ulong initval = 0;
7833#endif
7019cb3d
AK
7834 spr_register_kvm(env, SPR_FSCR, "FSCR",
7835 SPR_NOACCESS, SPR_NOACCESS,
7836 &spr_read_generic, &spr_write_generic,
45ed0be1 7837 KVM_REG_PPC_FSCR, initval);
7019cb3d
AK
7838}
7839
7488d481 7840static void init_proc_book3s_64(CPUPPCState *env, int version)
42382f62
AK
7841{
7842 gen_spr_ne_601(env);
42382f62
AK
7843 gen_tbl(env);
7844 gen_spr_book3s_altivec(env);
fd51ff63
AK
7845 gen_spr_book3s_pmu_sup(env);
7846 gen_spr_book3s_pmu_user(env);
42382f62 7847 gen_spr_book3s_common(env);
fd51ff63 7848
a2428814
AK
7849 switch (version) {
7850 case BOOK3S_CPU_970:
7851 case BOOK3S_CPU_POWER5PLUS:
7852 gen_spr_970_hid(env);
7853 gen_spr_970_hior(env);
7854 gen_low_BATs(env);
7855 gen_spr_970_pmu_sup(env);
7856 gen_spr_970_pmu_user(env);
7857 break;
7858 case BOOK3S_CPU_POWER7:
7859 case BOOK3S_CPU_POWER8:
7860 gen_spr_book3s_ids(env);
7861 gen_spr_amr(env);
7862 gen_spr_book3s_purr(env);
7863 break;
7864 default:
7865 g_assert_not_reached();
7866 }
7488d481 7867 if (version >= BOOK3S_CPU_POWER5PLUS) {
a2428814 7868 gen_spr_power5p_common(env);
7488d481
AK
7869 gen_spr_power5p_lpar(env);
7870 gen_spr_power5p_ear(env);
7871 } else {
7872 gen_spr_970_lpar(env);
7873 }
a2428814
AK
7874 if (version == BOOK3S_CPU_970) {
7875 gen_spr_970_dbg(env);
7876 }
7877 if (version >= BOOK3S_CPU_POWER6) {
7878 gen_spr_power6_common(env);
7879 gen_spr_power6_dbg(env);
7880 }
7881 if (version >= BOOK3S_CPU_POWER8) {
7882 gen_spr_power8_tce_address_control(env);
d1a721ab 7883 gen_spr_power8_ids(env);
4ee4a03b 7884 gen_spr_power8_ebb(env);
7019cb3d 7885 gen_spr_power8_fscr(env);
70c53407
AK
7886 gen_spr_power8_pmu_sup(env);
7887 gen_spr_power8_pmu_user(env);
cdcdda27 7888 gen_spr_power8_tm(env);
a2428814 7889 }
cd9adfdd
AK
7890 if (version < BOOK3S_CPU_POWER8) {
7891 gen_spr_book3s_dbg(env);
7892 }
f2e63a42 7893#if !defined(CONFIG_USER_ONLY)
a2428814
AK
7894 switch (version) {
7895 case BOOK3S_CPU_970:
7896 case BOOK3S_CPU_POWER5PLUS:
7897 env->slb_nr = 64;
7898 break;
7899 case BOOK3S_CPU_POWER7:
7900 case BOOK3S_CPU_POWER8:
7901 default:
7902 env->slb_nr = 32;
7903 break;
7904 }
f2e63a42 7905#endif
a2428814
AK
7906 /* Allocate hardware IRQ controller */
7907 switch (version) {
7908 case BOOK3S_CPU_970:
7909 case BOOK3S_CPU_POWER5PLUS:
7910 init_excp_970(env);
7911 ppc970_irq_init(env);
7912 break;
7913 case BOOK3S_CPU_POWER7:
7914 case BOOK3S_CPU_POWER8:
7915 init_excp_POWER7(env);
7916 ppcPOWER7_irq_init(env);
7917 break;
7918 default:
7919 g_assert_not_reached();
7920 }
7921
d63001d1
JM
7922 env->dcache_line_size = 128;
7923 env->icache_line_size = 128;
a750fc0b 7924}
a750fc0b 7925
7488d481
AK
7926static void init_proc_970(CPUPPCState *env)
7927{
7928 init_proc_book3s_64(env, BOOK3S_CPU_970);
7929}
7930
bbc01ca7 7931POWERPC_FAMILY(970)(ObjectClass *oc, void *data)
7856e3a4 7932{
ca5dff0a 7933 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
7934 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7935
bbc01ca7
AK
7936 dc->desc = "PowerPC 970";
7937 pcc->init_proc = init_proc_970;
7938 pcc->check_pow = check_pow_970;
53116ebf
AF
7939 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7940 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7941 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7942 PPC_FLOAT_STFIWX |
7943 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
7944 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7945 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7946 PPC_64B | PPC_ALTIVEC |
7947 PPC_SEGMENT_64B | PPC_SLBI;
4171853c 7948 pcc->insns_flags2 = PPC2_FP_CVT_S64;
9df5a466
TM
7949 pcc->msr_mask = (1ull << MSR_SF) |
7950 (1ull << MSR_VR) |
7951 (1ull << MSR_POW) |
7952 (1ull << MSR_EE) |
7953 (1ull << MSR_PR) |
7954 (1ull << MSR_FP) |
7955 (1ull << MSR_ME) |
7956 (1ull << MSR_FE0) |
7957 (1ull << MSR_SE) |
7958 (1ull << MSR_DE) |
7959 (1ull << MSR_FE1) |
7960 (1ull << MSR_IR) |
7961 (1ull << MSR_DR) |
7962 (1ull << MSR_PMM) |
7963 (1ull << MSR_RI);
ba9fd9f1 7964 pcc->mmu_model = POWERPC_MMU_64B;
b632a148
DG
7965#if defined(CONFIG_SOFTMMU)
7966 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
7967#endif
ba9fd9f1
AF
7968 pcc->excp_model = POWERPC_EXCP_970;
7969 pcc->bus_model = PPC_FLAGS_INPUT_970;
7970 pcc->bfd_mach = bfd_mach_ppc64;
7971 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7972 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7973 POWERPC_FLAG_BUS_CLK;
06f6e124
AG
7974 pcc->l1_dcache_size = 0x8000;
7975 pcc->l1_icache_size = 0x10000;
7856e3a4
AF
7976}
7977
35ebcb2b
AF
7978static void init_proc_power5plus(CPUPPCState *env)
7979{
7488d481 7980 init_proc_book3s_64(env, BOOK3S_CPU_POWER5PLUS);
35ebcb2b
AF
7981}
7982
7983POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data)
7984{
7985 DeviceClass *dc = DEVICE_CLASS(oc);
7986 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7987
793826cd 7988 dc->fw_name = "PowerPC,POWER5";
35ebcb2b
AF
7989 dc->desc = "POWER5+";
7990 pcc->init_proc = init_proc_power5plus;
90618f4f 7991 pcc->check_pow = check_pow_970;
35ebcb2b
AF
7992 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7993 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7994 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7995 PPC_FLOAT_STFIWX |
7996 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
7997 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7998 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7999 PPC_64B |
8000 PPC_SEGMENT_64B | PPC_SLBI;
4171853c 8001 pcc->insns_flags2 = PPC2_FP_CVT_S64;
9df5a466
TM
8002 pcc->msr_mask = (1ull << MSR_SF) |
8003 (1ull << MSR_VR) |
8004 (1ull << MSR_POW) |
8005 (1ull << MSR_EE) |
8006 (1ull << MSR_PR) |
8007 (1ull << MSR_FP) |
8008 (1ull << MSR_ME) |
8009 (1ull << MSR_FE0) |
8010 (1ull << MSR_SE) |
8011 (1ull << MSR_DE) |
8012 (1ull << MSR_FE1) |
8013 (1ull << MSR_IR) |
8014 (1ull << MSR_DR) |
8015 (1ull << MSR_PMM) |
8016 (1ull << MSR_RI);
35ebcb2b
AF
8017 pcc->mmu_model = POWERPC_MMU_64B;
8018#if defined(CONFIG_SOFTMMU)
8019 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
8020#endif
8021 pcc->excp_model = POWERPC_EXCP_970;
8022 pcc->bus_model = PPC_FLAGS_INPUT_970;
8023 pcc->bfd_mach = bfd_mach_ppc64;
8024 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8025 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8026 POWERPC_FLAG_BUS_CLK;
06f6e124
AG
8027 pcc->l1_dcache_size = 0x8000;
8028 pcc->l1_icache_size = 0x10000;
35ebcb2b
AF
8029}
8030
8dfa3a5e
AK
8031static void powerpc_get_compat(Object *obj, Visitor *v,
8032 void *opaque, const char *name, Error **errp)
8033{
8034 char *value = (char *)"";
8035 Property *prop = opaque;
8036 uint32_t *max_compat = qdev_get_prop_ptr(DEVICE(obj), prop);
8037
8038 switch (*max_compat) {
8039 case CPU_POWERPC_LOGICAL_2_05:
8040 value = (char *)"power6";
8041 break;
8042 case CPU_POWERPC_LOGICAL_2_06:
8043 value = (char *)"power7";
8044 break;
8045 case CPU_POWERPC_LOGICAL_2_07:
8046 value = (char *)"power8";
8047 break;
8048 case 0:
8049 break;
8050 default:
8051 error_setg(errp, "Internal error: compat is set to %x",
8052 max_compat ? *max_compat : -1);
8053 break;
8054 }
8055
8056 visit_type_str(v, &value, name, errp);
8057}
8058
8059static void powerpc_set_compat(Object *obj, Visitor *v,
8060 void *opaque, const char *name, Error **errp)
8061{
8062 Error *error = NULL;
8063 char *value = NULL;
8064 Property *prop = opaque;
8065 uint32_t *max_compat = qdev_get_prop_ptr(DEVICE(obj), prop);
8066
8067 visit_type_str(v, &value, name, &error);
8068 if (error) {
8069 error_propagate(errp, error);
8070 return;
8071 }
8072
8073 if (strcmp(value, "power6") == 0) {
8074 *max_compat = CPU_POWERPC_LOGICAL_2_05;
8075 } else if (strcmp(value, "power7") == 0) {
8076 *max_compat = CPU_POWERPC_LOGICAL_2_06;
8077 } else if (strcmp(value, "power8") == 0) {
8078 *max_compat = CPU_POWERPC_LOGICAL_2_07;
8079 } else {
8080 error_setg(errp, "Invalid compatibility mode \"%s\"", value);
8081 }
8082
8083 g_free(value);
8084}
8085
8086static PropertyInfo powerpc_compat_propinfo = {
8087 .name = "str",
51b2e8c3 8088 .description = "compatibility mode, power6/power7/power8",
8dfa3a5e
AK
8089 .get = powerpc_get_compat,
8090 .set = powerpc_set_compat,
8091};
8092
8093#define DEFINE_PROP_POWERPC_COMPAT(_n, _s, _f) \
8094 DEFINE_PROP(_n, _s, _f, powerpc_compat_propinfo, uint32_t)
8095
8096static Property powerpc_servercpu_properties[] = {
8097 DEFINE_PROP_POWERPC_COMPAT("compat", PowerPCCPU, max_compat),
8098 DEFINE_PROP_END_OF_LIST(),
8099};
8100
9d52e907
DG
8101static void init_proc_POWER7 (CPUPPCState *env)
8102{
a2428814 8103 init_proc_book3s_64(env, BOOK3S_CPU_POWER7);
9d52e907 8104}
9d52e907 8105
03ae4133
AK
8106static bool ppc_pvr_match_power7(PowerPCCPUClass *pcc, uint32_t pvr)
8107{
8108 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7P_BASE) {
8109 return true;
8110 }
8111 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7_BASE) {
8112 return true;
8113 }
8114 return false;
8115}
8116
7856e3a4
AF
8117POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
8118{
ca5dff0a 8119 DeviceClass *dc = DEVICE_CLASS(oc);
7856e3a4
AF
8120 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8121
793826cd 8122 dc->fw_name = "PowerPC,POWER7";
ca5dff0a 8123 dc->desc = "POWER7";
8dfa3a5e 8124 dc->props = powerpc_servercpu_properties;
03ae4133 8125 pcc->pvr_match = ppc_pvr_match_power7;
1a68b714 8126 pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06;
7856e3a4
AF
8127 pcc->init_proc = init_proc_POWER7;
8128 pcc->check_pow = check_pow_nocheck;
e71ec2e9 8129 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
53116ebf
AF
8130 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8131 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
ce8ca30b 8132 PPC_FLOAT_FRSQRTES |
53116ebf 8133 PPC_FLOAT_STFIWX |
c7386080 8134 PPC_FLOAT_EXT |
53116ebf
AF
8135 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8136 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8137 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
8138 PPC_64B | PPC_ALTIVEC |
8139 PPC_SEGMENT_64B | PPC_SLBI |
8140 PPC_POPCNTB | PPC_POPCNTWD;
86ba37ed 8141 pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
1fa6c533 8142 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
29a0e4e9 8143 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
4171853c 8144 PPC2_FP_TST_ISA206 | PPC2_FP_CVT_S64;
9df5a466
TM
8145 pcc->msr_mask = (1ull << MSR_SF) |
8146 (1ull << MSR_VR) |
8147 (1ull << MSR_VSX) |
8148 (1ull << MSR_EE) |
8149 (1ull << MSR_PR) |
8150 (1ull << MSR_FP) |
8151 (1ull << MSR_ME) |
8152 (1ull << MSR_FE0) |
8153 (1ull << MSR_SE) |
8154 (1ull << MSR_DE) |
8155 (1ull << MSR_FE1) |
8156 (1ull << MSR_IR) |
8157 (1ull << MSR_DR) |
8158 (1ull << MSR_PMM) |
8159 (1ull << MSR_RI) |
8160 (1ull << MSR_LE);
ba9fd9f1 8161 pcc->mmu_model = POWERPC_MMU_2_06;
b632a148
DG
8162#if defined(CONFIG_SOFTMMU)
8163 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
b650d6a2
AK
8164#endif
8165 pcc->excp_model = POWERPC_EXCP_POWER7;
8166 pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
8167 pcc->bfd_mach = bfd_mach_ppc64;
8168 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8169 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8170 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
8171 POWERPC_FLAG_VSX;
8172 pcc->l1_dcache_size = 0x8000;
8173 pcc->l1_icache_size = 0x8000;
382d2db6 8174 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
b650d6a2
AK
8175}
8176
60511041
TM
8177static void init_proc_POWER8(CPUPPCState *env)
8178{
a2428814 8179 init_proc_book3s_64(env, BOOK3S_CPU_POWER8);
60511041
TM
8180}
8181
03ae4133
AK
8182static bool ppc_pvr_match_power8(PowerPCCPUClass *pcc, uint32_t pvr)
8183{
8184 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8E_BASE) {
8185 return true;
8186 }
8187 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8_BASE) {
8188 return true;
8189 }
8190 return false;
8191}
8192
b60c6007 8193POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
8d43ea1c
PS
8194{
8195 DeviceClass *dc = DEVICE_CLASS(oc);
8196 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8197
793826cd 8198 dc->fw_name = "PowerPC,POWER8";
b60c6007 8199 dc->desc = "POWER8";
8dfa3a5e 8200 dc->props = powerpc_servercpu_properties;
03ae4133 8201 pcc->pvr_match = ppc_pvr_match_power8;
1a68b714 8202 pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06;
60511041 8203 pcc->init_proc = init_proc_POWER8;
8d43ea1c 8204 pcc->check_pow = check_pow_nocheck;
536492eb 8205 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
8d43ea1c
PS
8206 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8207 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
ce8ca30b 8208 PPC_FLOAT_FRSQRTES |
8d43ea1c 8209 PPC_FLOAT_STFIWX |
c7386080 8210 PPC_FLOAT_EXT |
8d43ea1c
PS
8211 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8212 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8213 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
e0498daa 8214 PPC_64B | PPC_64BX | PPC_ALTIVEC |
8d43ea1c
PS
8215 PPC_SEGMENT_64B | PPC_SLBI |
8216 PPC_POPCNTB | PPC_POPCNTWD;
86ba37ed 8217 pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
1fa6c533 8218 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
29a0e4e9 8219 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
38a85337 8220 PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
df99d30d 8221 PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
4171853c 8222 PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64;
9df5a466 8223 pcc->msr_mask = (1ull << MSR_SF) |
cdcdda27 8224 (1ull << MSR_TM) |
9df5a466
TM
8225 (1ull << MSR_VR) |
8226 (1ull << MSR_VSX) |
8227 (1ull << MSR_EE) |
8228 (1ull << MSR_PR) |
8229 (1ull << MSR_FP) |
8230 (1ull << MSR_ME) |
8231 (1ull << MSR_FE0) |
8232 (1ull << MSR_SE) |
8233 (1ull << MSR_DE) |
8234 (1ull << MSR_FE1) |
8235 (1ull << MSR_IR) |
8236 (1ull << MSR_DR) |
8237 (1ull << MSR_PMM) |
8238 (1ull << MSR_RI) |
8239 (1ull << MSR_LE);
8d43ea1c
PS
8240 pcc->mmu_model = POWERPC_MMU_2_06;
8241#if defined(CONFIG_SOFTMMU)
8242 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
8243#endif
8244 pcc->excp_model = POWERPC_EXCP_POWER7;
8245 pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
8246 pcc->bfd_mach = bfd_mach_ppc64;
8247 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8248 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
74f23997
TM
8249 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
8250 POWERPC_FLAG_VSX;
8d43ea1c
PS
8251 pcc->l1_dcache_size = 0x8000;
8252 pcc->l1_icache_size = 0x8000;
382d2db6 8253 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
8d43ea1c 8254}
a750fc0b
JM
8255#endif /* defined (TARGET_PPC64) */
8256
fd5ed418 8257
a750fc0b 8258/*****************************************************************************/
60b14d95 8259/* Generic CPU instantiation routine */
cfe34f44 8260static void init_ppc_proc(PowerPCCPU *cpu)
a750fc0b 8261{
cfe34f44
AF
8262 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
8263 CPUPPCState *env = &cpu->env;
a750fc0b 8264#if !defined(CONFIG_USER_ONLY)
e1833e1f
JM
8265 int i;
8266
a750fc0b 8267 env->irq_inputs = NULL;
e1833e1f
JM
8268 /* Set all exception vectors to an invalid address */
8269 for (i = 0; i < POWERPC_EXCP_NB; i++)
8270 env->excp_vectors[i] = (target_ulong)(-1ULL);
e1833e1f
JM
8271 env->ivor_mask = 0x00000000;
8272 env->ivpr_mask = 0x00000000;
a750fc0b
JM
8273 /* Default MMU definitions */
8274 env->nb_BATs = 0;
8275 env->nb_tlb = 0;
8276 env->nb_ways = 0;
1c53accc 8277 env->tlb_type = TLB_NONE;
f2e63a42 8278#endif
a750fc0b
JM
8279 /* Register SPR common to all PowerPC implementations */
8280 gen_spr_generic(env);
8281 spr_register(env, SPR_PVR, "PVR",
a139aa17
NF
8282 /* Linux permits userspace to read PVR */
8283#if defined(CONFIG_LINUX_USER)
8284 &spr_read_generic,
8285#else
8286 SPR_NOACCESS,
8287#endif
8288 SPR_NOACCESS,
a750fc0b 8289 &spr_read_generic, SPR_NOACCESS,
cfe34f44 8290 pcc->pvr);
80d11f44 8291 /* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
cfe34f44
AF
8292 if (pcc->svr != POWERPC_SVR_NONE) {
8293 if (pcc->svr & POWERPC_SVR_E500) {
80d11f44
JM
8294 spr_register(env, SPR_E500_SVR, "SVR",
8295 SPR_NOACCESS, SPR_NOACCESS,
8296 &spr_read_generic, SPR_NOACCESS,
cfe34f44 8297 pcc->svr & ~POWERPC_SVR_E500);
80d11f44
JM
8298 } else {
8299 spr_register(env, SPR_SVR, "SVR",
8300 SPR_NOACCESS, SPR_NOACCESS,
8301 &spr_read_generic, SPR_NOACCESS,
cfe34f44 8302 pcc->svr);
80d11f44
JM
8303 }
8304 }
a750fc0b 8305 /* PowerPC implementation specific initialisations (SPRs, timers, ...) */
cfe34f44 8306 (*pcc->init_proc)(env);
2cf3eb6d 8307
25ba3a68
JM
8308 /* MSR bits & flags consistency checks */
8309 if (env->msr_mask & (1 << 25)) {
8310 switch (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
8311 case POWERPC_FLAG_SPE:
8312 case POWERPC_FLAG_VRE:
8313 break;
8314 default:
8315 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
8316 "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n");
8317 exit(1);
8318 }
8319 } else if (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
8320 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
8321 "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n");
8322 exit(1);
8323 }
8324 if (env->msr_mask & (1 << 17)) {
8325 switch (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
8326 case POWERPC_FLAG_TGPR:
8327 case POWERPC_FLAG_CE:
8328 break;
8329 default:
8330 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
8331 "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n");
8332 exit(1);
8333 }
8334 } else if (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
8335 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
8336 "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n");
8337 exit(1);
8338 }
8339 if (env->msr_mask & (1 << 10)) {
8340 switch (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
8341 POWERPC_FLAG_UBLE)) {
8342 case POWERPC_FLAG_SE:
8343 case POWERPC_FLAG_DWE:
8344 case POWERPC_FLAG_UBLE:
8345 break;
8346 default:
8347 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
8348 "Should define POWERPC_FLAG_SE or POWERPC_FLAG_DWE or "
8349 "POWERPC_FLAG_UBLE\n");
8350 exit(1);
8351 }
8352 } else if (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
8353 POWERPC_FLAG_UBLE)) {
8354 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
8355 "Should not define POWERPC_FLAG_SE nor POWERPC_FLAG_DWE nor "
8356 "POWERPC_FLAG_UBLE\n");
8357 exit(1);
8358 }
8359 if (env->msr_mask & (1 << 9)) {
8360 switch (env->flags & (POWERPC_FLAG_BE | POWERPC_FLAG_DE)) {
8361 case POWERPC_FLAG_BE:
8362 case POWERPC_FLAG_DE:
8363 break;
8364 default:
8365 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
8366 "Should define POWERPC_FLAG_BE or POWERPC_FLAG_DE\n");
8367 exit(1);
8368 }
8369 } else if (env->flags & (POWERPC_FLAG_BE | POWERPC_FLAG_DE)) {
8370 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
8371 "Should not define POWERPC_FLAG_BE nor POWERPC_FLAG_DE\n");
8372 exit(1);
8373 }
8374 if (env->msr_mask & (1 << 2)) {
8375 switch (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
8376 case POWERPC_FLAG_PX:
8377 case POWERPC_FLAG_PMM:
8378 break;
8379 default:
8380 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
8381 "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n");
8382 exit(1);
8383 }
8384 } else if (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
8385 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
8386 "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n");
8387 exit(1);
8388 }
4018bae9
JM
8389 if ((env->flags & (POWERPC_FLAG_RTC_CLK | POWERPC_FLAG_BUS_CLK)) == 0) {
8390 fprintf(stderr, "PowerPC flags inconsistency\n"
8391 "Should define the time-base and decrementer clock source\n");
8392 exit(1);
8393 }
a750fc0b 8394 /* Allocate TLBs buffer when needed */
f2e63a42 8395#if !defined(CONFIG_USER_ONLY)
a750fc0b
JM
8396 if (env->nb_tlb != 0) {
8397 int nb_tlb = env->nb_tlb;
8398 if (env->id_tlbs != 0)
8399 nb_tlb *= 2;
1c53accc
AG
8400 switch (env->tlb_type) {
8401 case TLB_6XX:
7267c094 8402 env->tlb.tlb6 = g_malloc0(nb_tlb * sizeof(ppc6xx_tlb_t));
1c53accc
AG
8403 break;
8404 case TLB_EMB:
7267c094 8405 env->tlb.tlbe = g_malloc0(nb_tlb * sizeof(ppcemb_tlb_t));
1c53accc
AG
8406 break;
8407 case TLB_MAS:
7267c094 8408 env->tlb.tlbm = g_malloc0(nb_tlb * sizeof(ppcmas_tlb_t));
1c53accc
AG
8409 break;
8410 }
a750fc0b
JM
8411 /* Pre-compute some useful values */
8412 env->tlb_per_way = env->nb_tlb / env->nb_ways;
8413 }
a750fc0b
JM
8414 if (env->irq_inputs == NULL) {
8415 fprintf(stderr, "WARNING: no internal IRQ controller registered.\n"
5cbdb3a3 8416 " Attempt QEMU to crash very soon !\n");
a750fc0b
JM
8417 }
8418#endif
2f462816
JM
8419 if (env->check_pow == NULL) {
8420 fprintf(stderr, "WARNING: no power management check handler "
8421 "registered.\n"
5cbdb3a3 8422 " Attempt QEMU to crash very soon !\n");
2f462816 8423 }
a750fc0b
JM
8424}
8425
8426#if defined(PPC_DUMP_CPU)
8427static void dump_ppc_sprs (CPUPPCState *env)
8428{
8429 ppc_spr_t *spr;
8430#if !defined(CONFIG_USER_ONLY)
8431 uint32_t sr, sw;
8432#endif
8433 uint32_t ur, uw;
8434 int i, j, n;
8435
8436 printf("Special purpose registers:\n");
8437 for (i = 0; i < 32; i++) {
8438 for (j = 0; j < 32; j++) {
8439 n = (i << 5) | j;
8440 spr = &env->spr_cb[n];
8441 uw = spr->uea_write != NULL && spr->uea_write != SPR_NOACCESS;
8442 ur = spr->uea_read != NULL && spr->uea_read != SPR_NOACCESS;
8443#if !defined(CONFIG_USER_ONLY)
8444 sw = spr->oea_write != NULL && spr->oea_write != SPR_NOACCESS;
8445 sr = spr->oea_read != NULL && spr->oea_read != SPR_NOACCESS;
8446 if (sw || sr || uw || ur) {
8447 printf("SPR: %4d (%03x) %-8s s%c%c u%c%c\n",
8448 (i << 5) | j, (i << 5) | j, spr->name,
8449 sw ? 'w' : '-', sr ? 'r' : '-',
8450 uw ? 'w' : '-', ur ? 'r' : '-');
8451 }
8452#else
8453 if (uw || ur) {
8454 printf("SPR: %4d (%03x) %-8s u%c%c\n",
8455 (i << 5) | j, (i << 5) | j, spr->name,
8456 uw ? 'w' : '-', ur ? 'r' : '-');
8457 }
8458#endif
8459 }
8460 }
8461 fflush(stdout);
8462 fflush(stderr);
8463}
8464#endif
8465
8466/*****************************************************************************/
8467#include <stdlib.h>
8468#include <string.h>
8469
a750fc0b
JM
8470/* Opcode types */
8471enum {
8472 PPC_DIRECT = 0, /* Opcode routine */
8473 PPC_INDIRECT = 1, /* Indirect opcode table */
8474};
8475
54ff58bb
BR
8476#define PPC_OPCODE_MASK 0x3
8477
a750fc0b
JM
8478static inline int is_indirect_opcode (void *handler)
8479{
54ff58bb 8480 return ((uintptr_t)handler & PPC_OPCODE_MASK) == PPC_INDIRECT;
a750fc0b
JM
8481}
8482
c227f099 8483static inline opc_handler_t **ind_table(void *handler)
a750fc0b 8484{
54ff58bb 8485 return (opc_handler_t **)((uintptr_t)handler & ~PPC_OPCODE_MASK);
a750fc0b
JM
8486}
8487
8488/* Instruction table creation */
8489/* Opcodes tables creation */
c227f099 8490static void fill_new_table (opc_handler_t **table, int len)
a750fc0b
JM
8491{
8492 int i;
8493
8494 for (i = 0; i < len; i++)
8495 table[i] = &invalid_handler;
8496}
8497
c227f099 8498static int create_new_table (opc_handler_t **table, unsigned char idx)
a750fc0b 8499{
c227f099 8500 opc_handler_t **tmp;
a750fc0b 8501
54ff58bb
BR
8502 tmp = g_new(opc_handler_t *, PPC_CPU_INDIRECT_OPCODES_LEN);
8503 fill_new_table(tmp, PPC_CPU_INDIRECT_OPCODES_LEN);
5724753e 8504 table[idx] = (opc_handler_t *)((uintptr_t)tmp | PPC_INDIRECT);
a750fc0b
JM
8505
8506 return 0;
8507}
8508
c227f099
AL
8509static int insert_in_table (opc_handler_t **table, unsigned char idx,
8510 opc_handler_t *handler)
a750fc0b
JM
8511{
8512 if (table[idx] != &invalid_handler)
8513 return -1;
8514 table[idx] = handler;
8515
8516 return 0;
8517}
8518
c227f099
AL
8519static int register_direct_insn (opc_handler_t **ppc_opcodes,
8520 unsigned char idx, opc_handler_t *handler)
a750fc0b
JM
8521{
8522 if (insert_in_table(ppc_opcodes, idx, handler) < 0) {
8523 printf("*** ERROR: opcode %02x already assigned in main "
8524 "opcode table\n", idx);
4c1b1bfe
JM
8525#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
8526 printf(" Registered handler '%s' - new handler '%s'\n",
8527 ppc_opcodes[idx]->oname, handler->oname);
8528#endif
a750fc0b
JM
8529 return -1;
8530 }
8531
8532 return 0;
8533}
8534
c227f099 8535static int register_ind_in_table (opc_handler_t **table,
a750fc0b 8536 unsigned char idx1, unsigned char idx2,
c227f099 8537 opc_handler_t *handler)
a750fc0b
JM
8538{
8539 if (table[idx1] == &invalid_handler) {
8540 if (create_new_table(table, idx1) < 0) {
8541 printf("*** ERROR: unable to create indirect table "
8542 "idx=%02x\n", idx1);
8543 return -1;
8544 }
8545 } else {
8546 if (!is_indirect_opcode(table[idx1])) {
8547 printf("*** ERROR: idx %02x already assigned to a direct "
8548 "opcode\n", idx1);
4c1b1bfe
JM
8549#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
8550 printf(" Registered handler '%s' - new handler '%s'\n",
8551 ind_table(table[idx1])[idx2]->oname, handler->oname);
8552#endif
a750fc0b
JM
8553 return -1;
8554 }
3a607854 8555 }
a750fc0b
JM
8556 if (handler != NULL &&
8557 insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) {
8558 printf("*** ERROR: opcode %02x already assigned in "
8559 "opcode table %02x\n", idx2, idx1);
4c1b1bfe
JM
8560#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
8561 printf(" Registered handler '%s' - new handler '%s'\n",
8562 ind_table(table[idx1])[idx2]->oname, handler->oname);
8563#endif
a750fc0b 8564 return -1;
3a607854 8565 }
a750fc0b
JM
8566
8567 return 0;
8568}
8569
c227f099 8570static int register_ind_insn (opc_handler_t **ppc_opcodes,
a750fc0b 8571 unsigned char idx1, unsigned char idx2,
c227f099 8572 opc_handler_t *handler)
a750fc0b
JM
8573{
8574 int ret;
8575
8576 ret = register_ind_in_table(ppc_opcodes, idx1, idx2, handler);
8577
8578 return ret;
8579}
8580
c227f099 8581static int register_dblind_insn (opc_handler_t **ppc_opcodes,
a750fc0b 8582 unsigned char idx1, unsigned char idx2,
c227f099 8583 unsigned char idx3, opc_handler_t *handler)
a750fc0b
JM
8584{
8585 if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
8586 printf("*** ERROR: unable to join indirect table idx "
8587 "[%02x-%02x]\n", idx1, idx2);
8588 return -1;
8589 }
8590 if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3,
8591 handler) < 0) {
8592 printf("*** ERROR: unable to insert opcode "
8593 "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
8594 return -1;
8595 }
8596
8597 return 0;
8598}
8599
c227f099 8600static int register_insn (opc_handler_t **ppc_opcodes, opcode_t *insn)
a750fc0b
JM
8601{
8602 if (insn->opc2 != 0xFF) {
8603 if (insn->opc3 != 0xFF) {
8604 if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2,
8605 insn->opc3, &insn->handler) < 0)
8606 return -1;
8607 } else {
8608 if (register_ind_insn(ppc_opcodes, insn->opc1,
8609 insn->opc2, &insn->handler) < 0)
8610 return -1;
8611 }
8612 } else {
8613 if (register_direct_insn(ppc_opcodes, insn->opc1, &insn->handler) < 0)
8614 return -1;
8615 }
8616
8617 return 0;
8618}
8619
c227f099 8620static int test_opcode_table (opc_handler_t **table, int len)
a750fc0b
JM
8621{
8622 int i, count, tmp;
8623
8624 for (i = 0, count = 0; i < len; i++) {
8625 /* Consistency fixup */
8626 if (table[i] == NULL)
8627 table[i] = &invalid_handler;
8628 if (table[i] != &invalid_handler) {
8629 if (is_indirect_opcode(table[i])) {
54ff58bb
BR
8630 tmp = test_opcode_table(ind_table(table[i]),
8631 PPC_CPU_INDIRECT_OPCODES_LEN);
a750fc0b
JM
8632 if (tmp == 0) {
8633 free(table[i]);
8634 table[i] = &invalid_handler;
8635 } else {
8636 count++;
8637 }
8638 } else {
8639 count++;
8640 }
8641 }
8642 }
8643
8644 return count;
8645}
8646
c227f099 8647static void fix_opcode_tables (opc_handler_t **ppc_opcodes)
a750fc0b 8648{
54ff58bb 8649 if (test_opcode_table(ppc_opcodes, PPC_CPU_OPCODES_LEN) == 0)
a750fc0b
JM
8650 printf("*** WARNING: no opcode defined !\n");
8651}
8652
8653/*****************************************************************************/
2985b86b 8654static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp)
a750fc0b 8655{
2985b86b
AF
8656 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
8657 CPUPPCState *env = &cpu->env;
c227f099 8658 opcode_t *opc;
a750fc0b 8659
54ff58bb 8660 fill_new_table(env->opcodes, PPC_CPU_OPCODES_LEN);
5c55ff99 8661 for (opc = opcodes; opc < &opcodes[ARRAY_SIZE(opcodes)]; opc++) {
cfe34f44
AF
8662 if (((opc->handler.type & pcc->insns_flags) != 0) ||
8663 ((opc->handler.type2 & pcc->insns_flags2) != 0)) {
a750fc0b 8664 if (register_insn(env->opcodes, opc) < 0) {
2985b86b 8665 error_setg(errp, "ERROR initializing PowerPC instruction "
312fd5f2 8666 "0x%02x 0x%02x 0x%02x", opc->opc1, opc->opc2,
2985b86b
AF
8667 opc->opc3);
8668 return;
a750fc0b
JM
8669 }
8670 }
8671 }
c227f099 8672 fix_opcode_tables(env->opcodes);
a750fc0b
JM
8673 fflush(stdout);
8674 fflush(stderr);
a750fc0b
JM
8675}
8676
8677#if defined(PPC_DUMP_CPU)
25ba3a68 8678static void dump_ppc_insns (CPUPPCState *env)
a750fc0b 8679{
c227f099 8680 opc_handler_t **table, *handler;
b55266b5 8681 const char *p, *q;
a750fc0b
JM
8682 uint8_t opc1, opc2, opc3;
8683
8684 printf("Instructions set:\n");
8685 /* opc1 is 6 bits long */
54ff58bb 8686 for (opc1 = 0x00; opc1 < PPC_CPU_OPCODES_LEN; opc1++) {
a750fc0b
JM
8687 table = env->opcodes;
8688 handler = table[opc1];
8689 if (is_indirect_opcode(handler)) {
8690 /* opc2 is 5 bits long */
54ff58bb 8691 for (opc2 = 0; opc2 < PPC_CPU_INDIRECT_OPCODES_LEN; opc2++) {
a750fc0b
JM
8692 table = env->opcodes;
8693 handler = env->opcodes[opc1];
8694 table = ind_table(handler);
8695 handler = table[opc2];
8696 if (is_indirect_opcode(handler)) {
8697 table = ind_table(handler);
8698 /* opc3 is 5 bits long */
54ff58bb
BR
8699 for (opc3 = 0; opc3 < PPC_CPU_INDIRECT_OPCODES_LEN;
8700 opc3++) {
a750fc0b
JM
8701 handler = table[opc3];
8702 if (handler->handler != &gen_invalid) {
4c1b1bfe
JM
8703 /* Special hack to properly dump SPE insns */
8704 p = strchr(handler->oname, '_');
8705 if (p == NULL) {
8706 printf("INSN: %02x %02x %02x (%02d %04d) : "
8707 "%s\n",
8708 opc1, opc2, opc3, opc1,
8709 (opc3 << 5) | opc2,
8710 handler->oname);
8711 } else {
8712 q = "speundef";
8713 if ((p - handler->oname) != strlen(q) ||
8714 memcmp(handler->oname, q, strlen(q)) != 0) {
8715 /* First instruction */
8716 printf("INSN: %02x %02x %02x (%02d %04d) : "
8717 "%.*s\n",
8718 opc1, opc2 << 1, opc3, opc1,
8719 (opc3 << 6) | (opc2 << 1),
8720 (int)(p - handler->oname),
8721 handler->oname);
8722 }
8723 if (strcmp(p + 1, q) != 0) {
8724 /* Second instruction */
8725 printf("INSN: %02x %02x %02x (%02d %04d) : "
8726 "%s\n",
8727 opc1, (opc2 << 1) | 1, opc3, opc1,
8728 (opc3 << 6) | (opc2 << 1) | 1,
8729 p + 1);
8730 }
8731 }
a750fc0b
JM
8732 }
8733 }
8734 } else {
8735 if (handler->handler != &gen_invalid) {
8736 printf("INSN: %02x %02x -- (%02d %04d) : %s\n",
8737 opc1, opc2, opc1, opc2, handler->oname);
8738 }
8739 }
8740 }
8741 } else {
8742 if (handler->handler != &gen_invalid) {
8743 printf("INSN: %02x -- -- (%02d ----) : %s\n",
8744 opc1, opc1, handler->oname);
8745 }
8746 }
8747 }
8748}
3a607854 8749#endif
a750fc0b 8750
1328c2bf 8751static int gdb_get_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
24951522
AJ
8752{
8753 if (n < 32) {
8754 stfq_p(mem_buf, env->fpr[n]);
8755 return 8;
8756 }
8757 if (n == 32) {
5a576fb3 8758 stl_p(mem_buf, env->fpscr);
24951522
AJ
8759 return 4;
8760 }
8761 return 0;
8762}
8763
1328c2bf 8764static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
24951522
AJ
8765{
8766 if (n < 32) {
8767 env->fpr[n] = ldfq_p(mem_buf);
8768 return 8;
8769 }
8770 if (n == 32) {
d6478bc7 8771 helper_store_fpscr(env, ldl_p(mem_buf), 0xffffffff);
24951522
AJ
8772 return 4;
8773 }
8774 return 0;
8775}
8776
1328c2bf 8777static int gdb_get_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
b4f8d821
AJ
8778{
8779 if (n < 32) {
e2542fe2 8780#ifdef HOST_WORDS_BIGENDIAN
b4f8d821
AJ
8781 stq_p(mem_buf, env->avr[n].u64[0]);
8782 stq_p(mem_buf+8, env->avr[n].u64[1]);
8783#else
8784 stq_p(mem_buf, env->avr[n].u64[1]);
8785 stq_p(mem_buf+8, env->avr[n].u64[0]);
8786#endif
8787 return 16;
8788 }
70976a79 8789 if (n == 32) {
b4f8d821
AJ
8790 stl_p(mem_buf, env->vscr);
8791 return 4;
8792 }
70976a79 8793 if (n == 33) {
b4f8d821
AJ
8794 stl_p(mem_buf, (uint32_t)env->spr[SPR_VRSAVE]);
8795 return 4;
8796 }
8797 return 0;
8798}
8799
1328c2bf 8800static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
b4f8d821
AJ
8801{
8802 if (n < 32) {
e2542fe2 8803#ifdef HOST_WORDS_BIGENDIAN
b4f8d821
AJ
8804 env->avr[n].u64[0] = ldq_p(mem_buf);
8805 env->avr[n].u64[1] = ldq_p(mem_buf+8);
8806#else
8807 env->avr[n].u64[1] = ldq_p(mem_buf);
8808 env->avr[n].u64[0] = ldq_p(mem_buf+8);
8809#endif
8810 return 16;
8811 }
70976a79 8812 if (n == 32) {
b4f8d821
AJ
8813 env->vscr = ldl_p(mem_buf);
8814 return 4;
8815 }
70976a79 8816 if (n == 33) {
b4f8d821
AJ
8817 env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf);
8818 return 4;
8819 }
8820 return 0;
8821}
8822
1328c2bf 8823static int gdb_get_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
688890f7
AJ
8824{
8825 if (n < 32) {
8826#if defined(TARGET_PPC64)
8827 stl_p(mem_buf, env->gpr[n] >> 32);
8828#else
8829 stl_p(mem_buf, env->gprh[n]);
8830#endif
8831 return 4;
8832 }
70976a79 8833 if (n == 32) {
688890f7
AJ
8834 stq_p(mem_buf, env->spe_acc);
8835 return 8;
8836 }
70976a79 8837 if (n == 33) {
d34defbc 8838 stl_p(mem_buf, env->spe_fscr);
688890f7
AJ
8839 return 4;
8840 }
8841 return 0;
8842}
8843
1328c2bf 8844static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
688890f7
AJ
8845{
8846 if (n < 32) {
8847#if defined(TARGET_PPC64)
8848 target_ulong lo = (uint32_t)env->gpr[n];
8849 target_ulong hi = (target_ulong)ldl_p(mem_buf) << 32;
8850 env->gpr[n] = lo | hi;
8851#else
8852 env->gprh[n] = ldl_p(mem_buf);
8853#endif
8854 return 4;
8855 }
70976a79 8856 if (n == 32) {
688890f7
AJ
8857 env->spe_acc = ldq_p(mem_buf);
8858 return 8;
8859 }
70976a79 8860 if (n == 33) {
d34defbc 8861 env->spe_fscr = ldl_p(mem_buf);
688890f7
AJ
8862 return 4;
8863 }
8864 return 0;
8865}
8866
55e5c285 8867static int ppc_fixup_cpu(PowerPCCPU *cpu)
12b1143b 8868{
55e5c285
AF
8869 CPUPPCState *env = &cpu->env;
8870
12b1143b
DG
8871 /* TCG doesn't (yet) emulate some groups of instructions that
8872 * are implemented on some otherwise supported CPUs (e.g. VSX
8873 * and decimal floating point instructions on POWER7). We
8874 * remove unsupported instruction groups from the cpu state's
8875 * instruction masks and hope the guest can cope. For at
8876 * least the pseries machine, the unavailability of these
8877 * instructions can be advertised to the guest via the device
8878 * tree. */
8879 if ((env->insns_flags & ~PPC_TCG_INSNS)
8880 || (env->insns_flags2 & ~PPC_TCG_INSNS2)) {
8881 fprintf(stderr, "Warning: Disabling some instructions which are not "
8882 "emulated by TCG (0x%" PRIx64 ", 0x%" PRIx64 ")\n",
8883 env->insns_flags & ~PPC_TCG_INSNS,
8884 env->insns_flags2 & ~PPC_TCG_INSNS2);
8885 }
8886 env->insns_flags &= PPC_TCG_INSNS;
8887 env->insns_flags2 &= PPC_TCG_INSNS2;
8888 return 0;
8889}
8890
292363e1
AF
8891static inline bool ppc_cpu_is_valid(PowerPCCPUClass *pcc)
8892{
8893#ifdef TARGET_PPCEMB
8894 return pcc->mmu_model == POWERPC_MMU_BOOKE ||
8895 pcc->mmu_model == POWERPC_MMU_SOFT_4xx ||
8896 pcc->mmu_model == POWERPC_MMU_SOFT_4xx_Z;
8897#else
8898 return true;
8899#endif
8900}
8901
4776ce60 8902static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
a750fc0b 8903{
22169d41 8904 CPUState *cs = CPU(dev);
4776ce60 8905 PowerPCCPU *cpu = POWERPC_CPU(dev);
2985b86b 8906 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
2985b86b 8907 Error *local_err = NULL;
fe828a4d
MQ
8908#if !defined(CONFIG_USER_ONLY)
8909 int max_smt = kvm_enabled() ? kvmppc_smt_threads() : 1;
8910#endif
8911
8912#if !defined(CONFIG_USER_ONLY)
8913 if (smp_threads > max_smt) {
5e95acc8
AF
8914 error_setg(errp, "Cannot support more than %d threads on PPC with %s",
8915 max_smt, kvm_enabled() ? "KVM" : "TCG");
8916 return;
fe828a4d 8917 }
5ec83c73
BR
8918 if (!is_power_of_2(smp_threads)) {
8919 error_setg(errp, "Cannot support %d threads on PPC with %s, "
8920 "threads count must be a power of 2.",
8921 smp_threads, kvm_enabled() ? "KVM" : "TCG");
8922 return;
8923 }
0ce470cd
AK
8924
8925 cpu->cpu_dt_id = (cs->cpu_index / smp_threads) * max_smt
8926 + (cs->cpu_index % smp_threads);
fe828a4d 8927#endif
4656e1f0 8928
0ce470cd 8929 if (tcg_enabled()) {
55e5c285 8930 if (ppc_fixup_cpu(cpu) != 0) {
2985b86b
AF
8931 error_setg(errp, "Unable to emulate selected CPU with TCG");
8932 return;
12b1143b
DG
8933 }
8934 }
8935
4d7fb187 8936#if defined(TARGET_PPCEMB)
292363e1
AF
8937 if (!ppc_cpu_is_valid(pcc)) {
8938 error_setg(errp, "CPU does not possess a BookE or 4xx MMU. "
4d7fb187
AF
8939 "Please use qemu-system-ppc or qemu-system-ppc64 instead "
8940 "or choose another CPU model.");
8941 return;
8942 }
8943#endif
8944
2985b86b
AF
8945 create_ppc_opcodes(cpu, &local_err);
8946 if (local_err != NULL) {
8947 error_propagate(errp, local_err);
8948 return;
8949 }
cfe34f44 8950 init_ppc_proc(cpu);
24951522 8951
cfe34f44 8952 if (pcc->insns_flags & PPC_FLOAT) {
22169d41 8953 gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
24951522
AJ
8954 33, "power-fpu.xml", 0);
8955 }
cfe34f44 8956 if (pcc->insns_flags & PPC_ALTIVEC) {
22169d41 8957 gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg,
b4f8d821
AJ
8958 34, "power-altivec.xml", 0);
8959 }
cfe34f44 8960 if (pcc->insns_flags & PPC_SPE) {
22169d41 8961 gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
688890f7
AJ
8962 34, "power-spe.xml", 0);
8963 }
8964
14a10fc3
AF
8965 qemu_init_vcpu(cs);
8966
4776ce60
AF
8967 pcc->parent_realize(dev, errp);
8968
a750fc0b 8969#if defined(PPC_DUMP_CPU)
3a607854 8970 {
22169d41 8971 CPUPPCState *env = &cpu->env;
b55266b5 8972 const char *mmu_model, *excp_model, *bus_model;
a750fc0b
JM
8973 switch (env->mmu_model) {
8974 case POWERPC_MMU_32B:
8975 mmu_model = "PowerPC 32";
8976 break;
a750fc0b
JM
8977 case POWERPC_MMU_SOFT_6xx:
8978 mmu_model = "PowerPC 6xx/7xx with software driven TLBs";
8979 break;
8980 case POWERPC_MMU_SOFT_74xx:
8981 mmu_model = "PowerPC 74xx with software driven TLBs";
8982 break;
8983 case POWERPC_MMU_SOFT_4xx:
8984 mmu_model = "PowerPC 4xx with software driven TLBs";
8985 break;
8986 case POWERPC_MMU_SOFT_4xx_Z:
8987 mmu_model = "PowerPC 4xx with software driven TLBs "
8988 "and zones protections";
8989 break;
b4095fed
JM
8990 case POWERPC_MMU_REAL:
8991 mmu_model = "PowerPC real mode only";
8992 break;
8993 case POWERPC_MMU_MPC8xx:
8994 mmu_model = "PowerPC MPC8xx";
a750fc0b
JM
8995 break;
8996 case POWERPC_MMU_BOOKE:
8997 mmu_model = "PowerPC BookE";
8998 break;
01662f3e
AG
8999 case POWERPC_MMU_BOOKE206:
9000 mmu_model = "PowerPC BookE 2.06";
a750fc0b 9001 break;
b4095fed
JM
9002 case POWERPC_MMU_601:
9003 mmu_model = "PowerPC 601";
9004 break;
00af685f
JM
9005#if defined (TARGET_PPC64)
9006 case POWERPC_MMU_64B:
9007 mmu_model = "PowerPC 64";
9008 break;
00af685f 9009#endif
a750fc0b
JM
9010 default:
9011 mmu_model = "Unknown or invalid";
9012 break;
9013 }
9014 switch (env->excp_model) {
9015 case POWERPC_EXCP_STD:
9016 excp_model = "PowerPC";
9017 break;
9018 case POWERPC_EXCP_40x:
9019 excp_model = "PowerPC 40x";
9020 break;
9021 case POWERPC_EXCP_601:
9022 excp_model = "PowerPC 601";
9023 break;
9024 case POWERPC_EXCP_602:
9025 excp_model = "PowerPC 602";
9026 break;
9027 case POWERPC_EXCP_603:
9028 excp_model = "PowerPC 603";
9029 break;
9030 case POWERPC_EXCP_603E:
9031 excp_model = "PowerPC 603e";
9032 break;
9033 case POWERPC_EXCP_604:
9034 excp_model = "PowerPC 604";
9035 break;
9036 case POWERPC_EXCP_7x0:
9037 excp_model = "PowerPC 740/750";
9038 break;
9039 case POWERPC_EXCP_7x5:
9040 excp_model = "PowerPC 745/755";
9041 break;
9042 case POWERPC_EXCP_74xx:
9043 excp_model = "PowerPC 74xx";
9044 break;
a750fc0b
JM
9045 case POWERPC_EXCP_BOOKE:
9046 excp_model = "PowerPC BookE";
9047 break;
00af685f
JM
9048#if defined (TARGET_PPC64)
9049 case POWERPC_EXCP_970:
9050 excp_model = "PowerPC 970";
9051 break;
9052#endif
a750fc0b
JM
9053 default:
9054 excp_model = "Unknown or invalid";
9055 break;
9056 }
9057 switch (env->bus_model) {
9058 case PPC_FLAGS_INPUT_6xx:
9059 bus_model = "PowerPC 6xx";
9060 break;
9061 case PPC_FLAGS_INPUT_BookE:
9062 bus_model = "PowerPC BookE";
9063 break;
9064 case PPC_FLAGS_INPUT_405:
9065 bus_model = "PowerPC 405";
9066 break;
a750fc0b
JM
9067 case PPC_FLAGS_INPUT_401:
9068 bus_model = "PowerPC 401/403";
9069 break;
b4095fed
JM
9070 case PPC_FLAGS_INPUT_RCPU:
9071 bus_model = "RCPU / MPC8xx";
9072 break;
00af685f
JM
9073#if defined (TARGET_PPC64)
9074 case PPC_FLAGS_INPUT_970:
9075 bus_model = "PowerPC 970";
9076 break;
9077#endif
a750fc0b
JM
9078 default:
9079 bus_model = "Unknown or invalid";
9080 break;
9081 }
9082 printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64 "\n"
9083 " MMU model : %s\n",
a5100e75
AK
9084 object_class_get_name(OBJECT_CLASS(pcc)),
9085 pcc->pvr, pcc->msr_mask, mmu_model);
f2e63a42 9086#if !defined(CONFIG_USER_ONLY)
a5100e75 9087 if (env->tlb.tlb6) {
a750fc0b
JM
9088 printf(" %d %s TLB in %d ways\n",
9089 env->nb_tlb, env->id_tlbs ? "splitted" : "merged",
9090 env->nb_ways);
9091 }
f2e63a42 9092#endif
a750fc0b
JM
9093 printf(" Exceptions model : %s\n"
9094 " Bus model : %s\n",
9095 excp_model, bus_model);
25ba3a68
JM
9096 printf(" MSR features :\n");
9097 if (env->flags & POWERPC_FLAG_SPE)
9098 printf(" signal processing engine enable"
9099 "\n");
9100 else if (env->flags & POWERPC_FLAG_VRE)
9101 printf(" vector processor enable\n");
9102 if (env->flags & POWERPC_FLAG_TGPR)
9103 printf(" temporary GPRs\n");
9104 else if (env->flags & POWERPC_FLAG_CE)
9105 printf(" critical input enable\n");
9106 if (env->flags & POWERPC_FLAG_SE)
9107 printf(" single-step trace mode\n");
9108 else if (env->flags & POWERPC_FLAG_DWE)
9109 printf(" debug wait enable\n");
9110 else if (env->flags & POWERPC_FLAG_UBLE)
9111 printf(" user BTB lock enable\n");
9112 if (env->flags & POWERPC_FLAG_BE)
9113 printf(" branch-step trace mode\n");
9114 else if (env->flags & POWERPC_FLAG_DE)
9115 printf(" debug interrupt enable\n");
9116 if (env->flags & POWERPC_FLAG_PX)
9117 printf(" inclusive protection\n");
9118 else if (env->flags & POWERPC_FLAG_PMM)
9119 printf(" performance monitor mark\n");
9120 if (env->flags == POWERPC_FLAG_NONE)
9121 printf(" none\n");
4018bae9
JM
9122 printf(" Time-base/decrementer clock source: %s\n",
9123 env->flags & POWERPC_FLAG_RTC_CLK ? "RTC clock" : "bus clock");
22169d41
AF
9124 dump_ppc_insns(env);
9125 dump_ppc_sprs(env);
9126 fflush(stdout);
a750fc0b 9127 }
3a607854 9128#endif
a750fc0b 9129}
3fc6c082 9130
b048960f
AF
9131static void ppc_cpu_unrealizefn(DeviceState *dev, Error **errp)
9132{
9133 PowerPCCPU *cpu = POWERPC_CPU(dev);
9134 CPUPPCState *env = &cpu->env;
81f194dd
BR
9135 opc_handler_t **table;
9136 int i, j;
b048960f
AF
9137
9138 for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) {
81f194dd
BR
9139 if (env->opcodes[i] == &invalid_handler) {
9140 continue;
9141 }
9142 if (is_indirect_opcode(env->opcodes[i])) {
9143 table = ind_table(env->opcodes[i]);
9144 for (j = 0; j < PPC_CPU_INDIRECT_OPCODES_LEN; j++) {
9145 if (table[j] != &invalid_handler &&
9146 is_indirect_opcode(table[j])) {
9147 g_free((opc_handler_t *)((uintptr_t)table[j] &
9148 ~PPC_INDIRECT));
9149 }
9150 }
9151 g_free((opc_handler_t *)((uintptr_t)env->opcodes[i] &
9152 ~PPC_INDIRECT));
b048960f
AF
9153 }
9154 }
9155}
9156
2a48d993
AK
9157int ppc_get_compat_smt_threads(PowerPCCPU *cpu)
9158{
063cac53 9159 int ret = MIN(smp_threads, kvmppc_smt_threads());
2a48d993
AK
9160
9161 switch (cpu->cpu_version) {
9162 case CPU_POWERPC_LOGICAL_2_05:
063cac53 9163 ret = MIN(ret, 2);
2a48d993
AK
9164 break;
9165 case CPU_POWERPC_LOGICAL_2_06:
063cac53 9166 ret = MIN(ret, 4);
2a48d993
AK
9167 break;
9168 case CPU_POWERPC_LOGICAL_2_07:
063cac53 9169 ret = MIN(ret, 8);
2a48d993
AK
9170 break;
9171 }
9172
063cac53 9173 return ret;
2a48d993
AK
9174}
9175
6d9412ea
AK
9176int ppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version)
9177{
9178 int ret = 0;
9179 CPUPPCState *env = &cpu->env;
9180
9181 cpu->cpu_version = cpu_version;
9182
9183 switch (cpu_version) {
9184 case CPU_POWERPC_LOGICAL_2_05:
9185 env->spr[SPR_PCR] = PCR_COMPAT_2_05;
9186 break;
9187 case CPU_POWERPC_LOGICAL_2_06:
9188 env->spr[SPR_PCR] = PCR_COMPAT_2_06;
9189 break;
9190 case CPU_POWERPC_LOGICAL_2_06_PLUS:
9191 env->spr[SPR_PCR] = PCR_COMPAT_2_06;
9192 break;
9193 default:
9194 env->spr[SPR_PCR] = 0;
9195 break;
9196 }
9197
0b6ff576 9198 if (kvm_enabled() && kvmppc_set_compat(cpu, cpu->cpu_version) < 0) {
6db5bb0f
AK
9199 error_report("Unable to set compatibility mode in KVM");
9200 ret = -1;
9201 }
9202
6d9412ea
AK
9203 return ret;
9204}
9205
2985b86b 9206static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b)
f0ad8c34 9207{
2985b86b
AF
9208 ObjectClass *oc = (ObjectClass *)a;
9209 uint32_t pvr = *(uint32_t *)b;
9210 PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
9211
9212 /* -cpu host does a PVR lookup during construction */
9213 if (unlikely(strcmp(object_class_get_name(oc),
9214 TYPE_HOST_POWERPC_CPU) == 0)) {
9215 return -1;
f0ad8c34 9216 }
f0ad8c34 9217
292363e1 9218 if (!ppc_cpu_is_valid(pcc)) {
4d7fb187
AF
9219 return -1;
9220 }
4d7fb187 9221
cfe34f44 9222 return pcc->pvr == pvr ? 0 : -1;
f0ad8c34
AG
9223}
9224
2985b86b 9225PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr)
3fc6c082 9226{
2985b86b
AF
9227 GSList *list, *item;
9228 PowerPCCPUClass *pcc = NULL;
be40edcd 9229
2985b86b
AF
9230 list = object_class_get_list(TYPE_POWERPC_CPU, false);
9231 item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr);
9232 if (item != NULL) {
9233 pcc = POWERPC_CPU_CLASS(item->data);
3fc6c082 9234 }
2985b86b
AF
9235 g_slist_free(list);
9236
9237 return pcc;
9238}
9239
3bc9ccc0
AK
9240static gint ppc_cpu_compare_class_pvr_mask(gconstpointer a, gconstpointer b)
9241{
9242 ObjectClass *oc = (ObjectClass *)a;
9243 uint32_t pvr = *(uint32_t *)b;
9244 PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
3bc9ccc0
AK
9245
9246 /* -cpu host does a PVR lookup during construction */
9247 if (unlikely(strcmp(object_class_get_name(oc),
9248 TYPE_HOST_POWERPC_CPU) == 0)) {
9249 return -1;
9250 }
9251
292363e1 9252 if (!ppc_cpu_is_valid(pcc)) {
3bc9ccc0
AK
9253 return -1;
9254 }
292363e1 9255
03ae4133
AK
9256 if (pcc->pvr_match(pcc, pvr)) {
9257 return 0;
9258 }
3bc9ccc0 9259
03ae4133 9260 return -1;
3bc9ccc0
AK
9261}
9262
9263PowerPCCPUClass *ppc_cpu_class_by_pvr_mask(uint32_t pvr)
9264{
9265 GSList *list, *item;
9266 PowerPCCPUClass *pcc = NULL;
9267
9268 list = object_class_get_list(TYPE_POWERPC_CPU, true);
9269 item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr_mask);
9270 if (item != NULL) {
9271 pcc = POWERPC_CPU_CLASS(item->data);
9272 }
9273 g_slist_free(list);
9274
9275 return pcc;
9276}
9277
2985b86b
AF
9278static gint ppc_cpu_compare_class_name(gconstpointer a, gconstpointer b)
9279{
9280 ObjectClass *oc = (ObjectClass *)a;
9281 const char *name = b;
4d7fb187 9282 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
ee4e83ed 9283
2985b86b 9284 if (strncasecmp(name, object_class_get_name(oc), strlen(name)) == 0 &&
292363e1 9285 ppc_cpu_is_valid(pcc) &&
2985b86b
AF
9286 strcmp(object_class_get_name(oc) + strlen(name),
9287 "-" TYPE_POWERPC_CPU) == 0) {
9288 return 0;
9289 }
9290 return -1;
3fc6c082
FB
9291}
9292
ee4e83ed 9293#include <ctype.h>
3fc6c082 9294
9761ad75
AG
9295static ObjectClass *ppc_cpu_class_by_name(const char *name);
9296
9297static ObjectClass *ppc_cpu_class_by_alias(PowerPCCPUAlias *alias)
9298{
9299 ObjectClass *invalid_class = (void*)ppc_cpu_class_by_alias;
9300
9301 /* Cache target class lookups in the alias table */
9302 if (!alias->oc) {
9303 alias->oc = ppc_cpu_class_by_name(alias->model);
9304 if (!alias->oc) {
9305 /* Fast check for non-existing aliases */
9306 alias->oc = invalid_class;
9307 }
9308 }
9309
9310 if (alias->oc == invalid_class) {
9311 return NULL;
9312 } else {
9313 return alias->oc;
9314 }
9315}
9316
2985b86b 9317static ObjectClass *ppc_cpu_class_by_name(const char *name)
ee4e83ed 9318{
2985b86b
AF
9319 GSList *list, *item;
9320 ObjectClass *ret = NULL;
b55266b5 9321 const char *p;
2985b86b 9322 int i, len;
ee4e83ed
JM
9323
9324 /* Check if the given name is a PVR */
9325 len = strlen(name);
9326 if (len == 10 && name[0] == '0' && name[1] == 'x') {
9327 p = name + 2;
9328 goto check_pvr;
9329 } else if (len == 8) {
9330 p = name;
9331 check_pvr:
9332 for (i = 0; i < 8; i++) {
cd390083 9333 if (!qemu_isxdigit(*p++))
ee4e83ed
JM
9334 break;
9335 }
2985b86b
AF
9336 if (i == 8) {
9337 ret = OBJECT_CLASS(ppc_cpu_class_by_pvr(strtoul(name, NULL, 16)));
9338 return ret;
f0ad8c34 9339 }
2985b86b 9340 }
f0ad8c34 9341
2985b86b
AF
9342 list = object_class_get_list(TYPE_POWERPC_CPU, false);
9343 item = g_slist_find_custom(list, name, ppc_cpu_compare_class_name);
9344 if (item != NULL) {
9345 ret = OBJECT_CLASS(item->data);
3fc6c082 9346 }
2985b86b 9347 g_slist_free(list);
ee4e83ed 9348
fdf8a960
AK
9349 if (ret) {
9350 return ret;
9351 }
9352
9353 for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
9354 if (strcmp(ppc_cpu_aliases[i].alias, name) == 0) {
9355 return ppc_cpu_class_by_alias(&ppc_cpu_aliases[i]);
9356 }
9357 }
9358
9359 return NULL;
3fc6c082
FB
9360}
9361
2985b86b 9362PowerPCCPU *cpu_ppc_init(const char *cpu_model)
3fc6c082 9363{
9262685b 9364 return POWERPC_CPU(cpu_generic_init(TYPE_POWERPC_CPU, cpu_model));
2985b86b
AF
9365}
9366
9367/* Sort by PVR, ordering special case "host" last. */
9368static gint ppc_cpu_list_compare(gconstpointer a, gconstpointer b)
9369{
9370 ObjectClass *oc_a = (ObjectClass *)a;
9371 ObjectClass *oc_b = (ObjectClass *)b;
9372 PowerPCCPUClass *pcc_a = POWERPC_CPU_CLASS(oc_a);
9373 PowerPCCPUClass *pcc_b = POWERPC_CPU_CLASS(oc_b);
9374 const char *name_a = object_class_get_name(oc_a);
9375 const char *name_b = object_class_get_name(oc_b);
9376
9377 if (strcmp(name_a, TYPE_HOST_POWERPC_CPU) == 0) {
9378 return 1;
9379 } else if (strcmp(name_b, TYPE_HOST_POWERPC_CPU) == 0) {
9380 return -1;
9381 } else {
9382 /* Avoid an integer overflow during subtraction */
cfe34f44 9383 if (pcc_a->pvr < pcc_b->pvr) {
2985b86b 9384 return -1;
cfe34f44 9385 } else if (pcc_a->pvr > pcc_b->pvr) {
2985b86b
AF
9386 return 1;
9387 } else {
9388 return 0;
9389 }
9390 }
9391}
9392
9393static void ppc_cpu_list_entry(gpointer data, gpointer user_data)
9394{
9395 ObjectClass *oc = data;
9396 CPUListState *s = user_data;
9397 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
de400129
AF
9398 const char *typename = object_class_get_name(oc);
9399 char *name;
55d3d1a4 9400 int i;
2985b86b 9401
292363e1 9402 if (!ppc_cpu_is_valid(pcc)) {
4d7fb187
AF
9403 return;
9404 }
5ba4576b
AF
9405 if (unlikely(strcmp(typename, TYPE_HOST_POWERPC_CPU) == 0)) {
9406 return;
9407 }
4d7fb187 9408
de400129
AF
9409 name = g_strndup(typename,
9410 strlen(typename) - strlen("-" TYPE_POWERPC_CPU));
2985b86b 9411 (*s->cpu_fprintf)(s->file, "PowerPC %-16s PVR %08x\n",
cfe34f44 9412 name, pcc->pvr);
e9a96075 9413 for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
9761ad75
AG
9414 PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
9415 ObjectClass *alias_oc = ppc_cpu_class_by_alias(alias);
55d3d1a4
AF
9416
9417 if (alias_oc != oc) {
9418 continue;
9419 }
9420 (*s->cpu_fprintf)(s->file, "PowerPC %-16s (alias for %s)\n",
9421 alias->alias, name);
9422 }
de400129 9423 g_free(name);
2985b86b
AF
9424}
9425
9426void ppc_cpu_list(FILE *f, fprintf_function cpu_fprintf)
9427{
9428 CPUListState s = {
9429 .file = f,
9430 .cpu_fprintf = cpu_fprintf,
9431 };
9432 GSList *list;
9433
9434 list = object_class_get_list(TYPE_POWERPC_CPU, false);
9435 list = g_slist_sort(list, ppc_cpu_list_compare);
9436 g_slist_foreach(list, ppc_cpu_list_entry, &s);
9437 g_slist_free(list);
fd5ed418 9438
5ba4576b
AF
9439#ifdef CONFIG_KVM
9440 cpu_fprintf(f, "\n");
9441 cpu_fprintf(f, "PowerPC %-16s\n", "host");
9442#endif
2985b86b
AF
9443}
9444
9445static void ppc_cpu_defs_entry(gpointer data, gpointer user_data)
9446{
9447 ObjectClass *oc = data;
9448 CpuDefinitionInfoList **first = user_data;
de400129 9449 const char *typename;
2985b86b
AF
9450 CpuDefinitionInfoList *entry;
9451 CpuDefinitionInfo *info;
4d7fb187
AF
9452 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
9453
292363e1 9454 if (!ppc_cpu_is_valid(pcc)) {
4d7fb187
AF
9455 return;
9456 }
2985b86b 9457
de400129 9458 typename = object_class_get_name(oc);
2985b86b 9459 info = g_malloc0(sizeof(*info));
de400129
AF
9460 info->name = g_strndup(typename,
9461 strlen(typename) - strlen("-" TYPE_POWERPC_CPU));
2985b86b
AF
9462
9463 entry = g_malloc0(sizeof(*entry));
9464 entry->value = info;
9465 entry->next = *first;
9466 *first = entry;
3fc6c082 9467}
1d0cb67d 9468
76b64a7a 9469CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
70b7660a
AL
9470{
9471 CpuDefinitionInfoList *cpu_list = NULL;
2985b86b 9472 GSList *list;
35e21d3f 9473 int i;
70b7660a 9474
2985b86b
AF
9475 list = object_class_get_list(TYPE_POWERPC_CPU, false);
9476 g_slist_foreach(list, ppc_cpu_defs_entry, &cpu_list);
9477 g_slist_free(list);
70b7660a 9478
e9a96075 9479 for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
9761ad75 9480 PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
35e21d3f
AF
9481 ObjectClass *oc;
9482 CpuDefinitionInfoList *entry;
9483 CpuDefinitionInfo *info;
9484
9761ad75 9485 oc = ppc_cpu_class_by_alias(alias);
35e21d3f
AF
9486 if (oc == NULL) {
9487 continue;
9488 }
9489
9490 info = g_malloc0(sizeof(*info));
9491 info->name = g_strdup(alias->alias);
9492
9493 entry = g_malloc0(sizeof(*entry));
9494 entry->value = info;
9495 entry->next = cpu_list;
9496 cpu_list = entry;
9497 }
9498
2985b86b
AF
9499 return cpu_list;
9500}
70b7660a 9501
f45748f1
AF
9502static void ppc_cpu_set_pc(CPUState *cs, vaddr value)
9503{
9504 PowerPCCPU *cpu = POWERPC_CPU(cs);
9505
9506 cpu->env.nip = value;
9507}
9508
8c2e1b00
AF
9509static bool ppc_cpu_has_work(CPUState *cs)
9510{
9511 PowerPCCPU *cpu = POWERPC_CPU(cs);
9512 CPUPPCState *env = &cpu->env;
9513
9514 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
9515}
9516
774f0abe
RH
9517static void ppc_cpu_exec_enter(CPUState *cs)
9518{
9519 PowerPCCPU *cpu = POWERPC_CPU(cs);
9520 CPUPPCState *env = &cpu->env;
9521
9522 env->reserve_addr = -1;
9523}
9524
1d0cb67d
AF
9525/* CPUClass::reset() */
9526static void ppc_cpu_reset(CPUState *s)
9527{
9528 PowerPCCPU *cpu = POWERPC_CPU(s);
9529 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
9530 CPUPPCState *env = &cpu->env;
a1389542 9531 target_ulong msr;
d197fdbc 9532 int i;
a1389542 9533
1d0cb67d
AF
9534 pcc->parent_reset(s);
9535
a1389542
AF
9536 msr = (target_ulong)0;
9537 if (0) {
9538 /* XXX: find a suitable condition to enable the hypervisor mode */
9539 msr |= (target_ulong)MSR_HVB;
9540 }
9541 msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */
9542 msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */
9543 msr |= (target_ulong)1 << MSR_EP;
9544#if defined(DO_SINGLE_STEP) && 0
9545 /* Single step trace mode */
9546 msr |= (target_ulong)1 << MSR_SE;
9547 msr |= (target_ulong)1 << MSR_BE;
9548#endif
9549#if defined(CONFIG_USER_ONLY)
9550 msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
9551 msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
5b274ed7 9552 msr |= (target_ulong)1 << MSR_VSX; /* Allow VSX usage */
a1389542
AF
9553 msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
9554 msr |= (target_ulong)1 << MSR_PR;
cdcdda27
AK
9555#if defined(TARGET_PPC64)
9556 msr |= (target_ulong)1 << MSR_TM; /* Transactional memory */
9557#endif
e22c357b
DK
9558#if !defined(TARGET_WORDS_BIGENDIAN)
9559 msr |= (target_ulong)1 << MSR_LE; /* Little-endian user mode */
a74029f6
RH
9560 if (!((env->msr_mask >> MSR_LE) & 1)) {
9561 fprintf(stderr, "Selected CPU does not support little-endian.\n");
9562 exit(1);
9563 }
e22c357b 9564#endif
a1389542 9565#endif
2cf3eb6d 9566
a1389542
AF
9567#if defined(TARGET_PPC64)
9568 if (env->mmu_model & POWERPC_MMU_64) {
9569 env->msr |= (1ULL << MSR_SF);
9570 }
9571#endif
2cf3eb6d
FC
9572
9573 hreg_store_msr(env, msr, 1);
9574
9575#if !defined(CONFIG_USER_ONLY)
9576 env->nip = env->hreset_vector | env->excp_prefix;
9577 if (env->mmu_model != POWERPC_MMU_REAL) {
9578 ppc_tlb_invalidate_all(env);
9579 }
9580#endif
9581
a1389542
AF
9582 hreg_compute_hflags(env);
9583 env->reserve_addr = (target_ulong)-1ULL;
9584 /* Be sure no exception or interrupt is pending */
9585 env->pending_interrupts = 0;
27103424 9586 s->exception_index = POWERPC_EXCP_NONE;
a1389542 9587 env->error_code = 0;
2b15811c
DG
9588
9589#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
1bfb37d1
DG
9590 env->vpa_addr = 0;
9591 env->slb_shadow_addr = 0;
9592 env->slb_shadow_size = 0;
9593 env->dtl_addr = 0;
2b15811c
DG
9594 env->dtl_size = 0;
9595#endif /* TARGET_PPC64 */
9596
d197fdbc
AK
9597 for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
9598 ppc_spr_t *spr = &env->spr_cb[i];
9599
9600 if (!spr->name) {
9601 continue;
9602 }
9603 env->spr[i] = spr->default_value;
9604 }
9605
a1389542 9606 /* Flush all TLBs */
00c8cb0a 9607 tlb_flush(s, 1);
1d0cb67d
AF
9608}
9609
7826c2b2
GK
9610#ifndef CONFIG_USER_ONLY
9611static bool ppc_cpu_is_big_endian(CPUState *cs)
9612{
9613 PowerPCCPU *cpu = POWERPC_CPU(cs);
9614 CPUPPCState *env = &cpu->env;
9615
9616 cpu_synchronize_state(cs);
9617
9618 return !msr_le;
9619}
9620#endif
9621
6cca7ad6
AF
9622static void ppc_cpu_initfn(Object *obj)
9623{
c05efcb1 9624 CPUState *cs = CPU(obj);
6cca7ad6 9625 PowerPCCPU *cpu = POWERPC_CPU(obj);
2985b86b 9626 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
6cca7ad6
AF
9627 CPUPPCState *env = &cpu->env;
9628
c05efcb1 9629 cs->env_ptr = env;
6cca7ad6 9630 cpu_exec_init(env);
0f20ba62 9631 cpu->cpu_dt_id = cs->cpu_index;
2985b86b 9632
cfe34f44
AF
9633 env->msr_mask = pcc->msr_mask;
9634 env->mmu_model = pcc->mmu_model;
9635 env->excp_model = pcc->excp_model;
9636 env->bus_model = pcc->bus_model;
9637 env->insns_flags = pcc->insns_flags;
9638 env->insns_flags2 = pcc->insns_flags2;
9639 env->flags = pcc->flags;
9640 env->bfd_mach = pcc->bfd_mach;
9641 env->check_pow = pcc->check_pow;
2985b86b
AF
9642
9643#if defined(TARGET_PPC64)
cfe34f44
AF
9644 if (pcc->sps) {
9645 env->sps = *pcc->sps;
2985b86b
AF
9646 } else if (env->mmu_model & POWERPC_MMU_64) {
9647 /* Use default sets of page sizes */
9648 static const struct ppc_segment_page_sizes defsps = {
9649 .sps = {
9650 { .page_shift = 12, /* 4K */
9651 .slb_enc = 0,
9652 .enc = { { .page_shift = 12, .pte_enc = 0 } }
9653 },
9654 { .page_shift = 24, /* 16M */
9655 .slb_enc = 0x100,
9656 .enc = { { .page_shift = 24, .pte_enc = 0 } }
9657 },
9658 },
9659 };
9660 env->sps = defsps;
9661 }
9662#endif /* defined(TARGET_PPC64) */
60925d26
AF
9663
9664 if (tcg_enabled()) {
9665 ppc_translate_init();
9666 }
6cca7ad6
AF
9667}
9668
03ae4133
AK
9669static bool ppc_pvr_match_default(PowerPCCPUClass *pcc, uint32_t pvr)
9670{
9671 return pcc->pvr == pvr;
9672}
9673
1d0cb67d
AF
9674static void ppc_cpu_class_init(ObjectClass *oc, void *data)
9675{
9676 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
9677 CPUClass *cc = CPU_CLASS(oc);
4776ce60
AF
9678 DeviceClass *dc = DEVICE_CLASS(oc);
9679
9680 pcc->parent_realize = dc->realize;
03ae4133 9681 pcc->pvr_match = ppc_pvr_match_default;
382d2db6 9682 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_always;
4776ce60 9683 dc->realize = ppc_cpu_realizefn;
b048960f 9684 dc->unrealize = ppc_cpu_unrealizefn;
1d0cb67d
AF
9685
9686 pcc->parent_reset = cc->reset;
9687 cc->reset = ppc_cpu_reset;
2b8c2754
AF
9688
9689 cc->class_by_name = ppc_cpu_class_by_name;
8c2e1b00 9690 cc->has_work = ppc_cpu_has_work;
97a8ea5a 9691 cc->do_interrupt = ppc_cpu_do_interrupt;
458dd766 9692 cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt;
878096ee
AF
9693 cc->dump_state = ppc_cpu_dump_state;
9694 cc->dump_statistics = ppc_cpu_dump_statistics;
f45748f1 9695 cc->set_pc = ppc_cpu_set_pc;
5b50e790
AF
9696 cc->gdb_read_register = ppc_cpu_gdb_read_register;
9697 cc->gdb_write_register = ppc_cpu_gdb_write_register;
7510454e
AF
9698#ifdef CONFIG_USER_ONLY
9699 cc->handle_mmu_fault = ppc_cpu_handle_mmu_fault;
9700#else
00b941e5 9701 cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
a90db158 9702 cc->vmsd = &vmstate_ppc_cpu;
e62fbc54
AK
9703#if defined(TARGET_PPC64)
9704 cc->write_elf64_note = ppc64_cpu_write_elf64_note;
9705 cc->write_elf64_qemunote = ppc64_cpu_write_elf64_qemunote;
9706#endif
00b941e5 9707#endif
774f0abe 9708 cc->cpu_exec_enter = ppc_cpu_exec_enter;
a0e372f0
AF
9709
9710 cc->gdb_num_core_regs = 71;
b3cad3ab
AG
9711
9712#ifdef USE_APPLE_GDB
9713 cc->gdb_read_register = ppc_cpu_gdb_read_register_apple;
9714 cc->gdb_write_register = ppc_cpu_gdb_write_register_apple;
9715 cc->gdb_num_core_regs = 71 + 32;
9716#endif
9717
5b24c641
AF
9718#if defined(TARGET_PPC64)
9719 cc->gdb_core_xml_file = "power64-core.xml";
9720#else
9721 cc->gdb_core_xml_file = "power-core.xml";
9722#endif
7826c2b2
GK
9723#ifndef CONFIG_USER_ONLY
9724 cc->virtio_is_big_endian = ppc_cpu_is_big_endian;
9725#endif
3bbf37f2
AF
9726
9727 dc->fw_name = "PowerPC,UNKNOWN";
1d0cb67d
AF
9728}
9729
9730static const TypeInfo ppc_cpu_type_info = {
9731 .name = TYPE_POWERPC_CPU,
9732 .parent = TYPE_CPU,
9733 .instance_size = sizeof(PowerPCCPU),
6cca7ad6 9734 .instance_init = ppc_cpu_initfn,
2985b86b 9735 .abstract = true,
1d0cb67d
AF
9736 .class_size = sizeof(PowerPCCPUClass),
9737 .class_init = ppc_cpu_class_init,
9738};
9739
9740static void ppc_cpu_register_types(void)
9741{
9742 type_register_static(&ppc_cpu_type_info);
9743}
9744
9745type_init(ppc_cpu_register_types)