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