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