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