blob: 208fa1ea534c3538eff2ca39f777be43c7d0f302 [file] [log] [blame]
bellard3fc6c082005-07-02 20:59:34 +00001/*
2 * PowerPC CPU initialization for qemu.
ths5fafdf22007-09-16 21:08:06 +00003 *
j_mayer76a66252007-03-07 08:32:30 +00004 * Copyright (c) 2003-2007 Jocelyn Mayer
Varun Sethif7aa5582011-12-22 12:26:17 +00005 * Copyright 2011 Freescale Semiconductor, Inc.
bellard3fc6c082005-07-02 20:59:34 +00006 *
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
Blue Swirl8167ee82009-07-16 20:47:01 +000018 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
bellard3fc6c082005-07-02 20:59:34 +000019 */
20
Peter Maydell0d755902016-01-26 18:16:58 +000021#include "qemu/osdep.h"
Paolo Bonzini76cad712012-10-24 11:12:21 +020022#include "disas/bfd.h"
Paolo Bonzini022c62c2012-12-17 18:19:49 +010023#include "exec/gdbstub.h"
Markus Armbrustera9c94272016-06-22 19:11:19 +020024#include "sysemu/kvm.h"
David Gibsona1e98582011-10-12 22:40:32 +000025#include "kvm_ppc.h"
Paolo Bonzini9c17d612012-12-17 18:20:04 +010026#include "sysemu/arch_init.h"
Mike Qiufe828a42013-01-23 17:20:38 +000027#include "sysemu/cpus.h"
Andreas Färber953af182013-02-17 23:16:49 +000028#include "cpu-models.h"
David Gibsonb632a142013-03-13 11:40:33 +110029#include "mmu-hash32.h"
30#include "mmu-hash64.h"
Seiji Aguchi4a44d852013-08-05 15:40:44 -040031#include "qemu/error-report.h"
Alexey Kardashevskiy8dfa3a52014-05-23 12:26:50 +100032#include "qapi/visitor.h"
33#include "hw/qdev-properties.h"
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +010034#include "hw/ppc/ppc.h"
j_mayer237c0af2007-09-29 12:01:46 +000035
bellard3fc6c082005-07-02 20:59:34 +000036//#define PPC_DUMP_CPU
37//#define PPC_DEBUG_SPR
j_mayer80d11f42007-11-17 23:02:20 +000038//#define PPC_DUMP_SPR_ACCESSES
Alexander Grafb3cad3a2014-06-23 15:23:08 +020039/* #define USE_APPLE_GDB */
bellard3fc6c082005-07-02 20:59:34 +000040
bellard3fc6c082005-07-02 20:59:34 +000041/* Generic callbacks:
42 * do nothing but store/retrieve spr value
43 */
Alexander Graf91f477f2012-06-21 13:39:48 +020044static void spr_load_dump_spr(int sprn)
45{
46#ifdef PPC_DUMP_SPR_ACCESSES
47 TCGv_i32 t0 = tcg_const_i32(sprn);
Andreas Färberedbe35e2013-02-20 18:24:57 +000048 gen_helper_load_dump_spr(cpu_env, t0);
Alexander Graf91f477f2012-06-21 13:39:48 +020049 tcg_temp_free_i32(t0);
50#endif
51}
52
Paolo Bonzini69b058c2014-11-26 13:39:48 +030053static void spr_read_generic (DisasContext *ctx, int gprn, int sprn)
aurel3245d827d2008-12-07 13:40:29 +000054{
55 gen_load_spr(cpu_gpr[gprn], sprn);
Alexander Graf91f477f2012-06-21 13:39:48 +020056 spr_load_dump_spr(sprn);
57}
58
59static void spr_store_dump_spr(int sprn)
60{
j_mayer04f20792007-04-17 02:50:56 +000061#ifdef PPC_DUMP_SPR_ACCESSES
Alexander Graf91f477f2012-06-21 13:39:48 +020062 TCGv_i32 t0 = tcg_const_i32(sprn);
Andreas Färberedbe35e2013-02-20 18:24:57 +000063 gen_helper_store_dump_spr(cpu_env, t0);
Alexander Graf91f477f2012-06-21 13:39:48 +020064 tcg_temp_free_i32(t0);
j_mayer04f20792007-04-17 02:50:56 +000065#endif
aurel3245d827d2008-12-07 13:40:29 +000066}
67
Paolo Bonzini69b058c2014-11-26 13:39:48 +030068static void spr_write_generic (DisasContext *ctx, int sprn, int gprn)
aurel3245d827d2008-12-07 13:40:29 +000069{
70 gen_store_spr(sprn, cpu_gpr[gprn]);
Alexander Graf91f477f2012-06-21 13:39:48 +020071 spr_store_dump_spr(sprn);
aurel3245d827d2008-12-07 13:40:29 +000072}
j_mayera4967752007-04-16 07:10:48 +000073
74#if !defined(CONFIG_USER_ONLY)
Paolo Bonzini69b058c2014-11-26 13:39:48 +030075static void spr_write_generic32(DisasContext *ctx, int sprn, int gprn)
Alexander Grafba38ab82012-06-21 14:01:06 +020076{
77#ifdef TARGET_PPC64
78 TCGv t0 = tcg_temp_new();
79 tcg_gen_ext32u_tl(t0, cpu_gpr[gprn]);
80 gen_store_spr(sprn, t0);
81 tcg_temp_free(t0);
82 spr_store_dump_spr(sprn);
83#else
Paolo Bonzini69b058c2014-11-26 13:39:48 +030084 spr_write_generic(ctx, sprn, gprn);
Alexander Grafba38ab82012-06-21 14:01:06 +020085#endif
86}
87
Paolo Bonzini69b058c2014-11-26 13:39:48 +030088static void spr_write_clear (DisasContext *ctx, int sprn, int gprn)
j_mayera4967752007-04-16 07:10:48 +000089{
aurel3245d827d2008-12-07 13:40:29 +000090 TCGv t0 = tcg_temp_new();
91 TCGv t1 = tcg_temp_new();
92 gen_load_spr(t0, sprn);
93 tcg_gen_neg_tl(t1, cpu_gpr[gprn]);
94 tcg_gen_and_tl(t0, t0, t1);
95 gen_store_spr(sprn, t0);
96 tcg_temp_free(t0);
97 tcg_temp_free(t1);
j_mayera4967752007-04-16 07:10:48 +000098}
Alexander Graf9633fcc2013-09-25 15:41:12 +020099
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300100static void spr_access_nop(DisasContext *ctx, int sprn, int gprn)
Alexander Graf9633fcc2013-09-25 15:41:12 +0200101{
102}
103
j_mayera4967752007-04-16 07:10:48 +0000104#endif
105
j_mayer76a66252007-03-07 08:32:30 +0000106/* SPR common to all PowerPC */
bellard3fc6c082005-07-02 20:59:34 +0000107/* XER */
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300108static void spr_read_xer (DisasContext *ctx, int gprn, int sprn)
bellard3fc6c082005-07-02 20:59:34 +0000109{
Richard Hendersonda91a002013-02-19 23:52:13 -0800110 gen_read_xer(cpu_gpr[gprn]);
bellard3fc6c082005-07-02 20:59:34 +0000111}
112
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300113static void spr_write_xer (DisasContext *ctx, int sprn, int gprn)
bellard3fc6c082005-07-02 20:59:34 +0000114{
Richard Hendersonda91a002013-02-19 23:52:13 -0800115 gen_write_xer(cpu_gpr[gprn]);
bellard3fc6c082005-07-02 20:59:34 +0000116}
117
118/* LR */
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300119static void spr_read_lr (DisasContext *ctx, int gprn, int sprn)
bellard3fc6c082005-07-02 20:59:34 +0000120{
aurel3245d827d2008-12-07 13:40:29 +0000121 tcg_gen_mov_tl(cpu_gpr[gprn], cpu_lr);
bellard3fc6c082005-07-02 20:59:34 +0000122}
123
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300124static void spr_write_lr (DisasContext *ctx, int sprn, int gprn)
bellard3fc6c082005-07-02 20:59:34 +0000125{
aurel3245d827d2008-12-07 13:40:29 +0000126 tcg_gen_mov_tl(cpu_lr, cpu_gpr[gprn]);
bellard3fc6c082005-07-02 20:59:34 +0000127}
128
David Gibson697ab892011-08-31 15:45:10 +0000129/* CFAR */
130#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300131static void spr_read_cfar (DisasContext *ctx, int gprn, int sprn)
David Gibson697ab892011-08-31 15:45:10 +0000132{
133 tcg_gen_mov_tl(cpu_gpr[gprn], cpu_cfar);
134}
135
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300136static void spr_write_cfar (DisasContext *ctx, int sprn, int gprn)
David Gibson697ab892011-08-31 15:45:10 +0000137{
138 tcg_gen_mov_tl(cpu_cfar, cpu_gpr[gprn]);
139}
140#endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
141
bellard3fc6c082005-07-02 20:59:34 +0000142/* CTR */
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300143static void spr_read_ctr (DisasContext *ctx, int gprn, int sprn)
bellard3fc6c082005-07-02 20:59:34 +0000144{
aurel3245d827d2008-12-07 13:40:29 +0000145 tcg_gen_mov_tl(cpu_gpr[gprn], cpu_ctr);
bellard3fc6c082005-07-02 20:59:34 +0000146}
147
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300148static void spr_write_ctr (DisasContext *ctx, int sprn, int gprn)
bellard3fc6c082005-07-02 20:59:34 +0000149{
aurel3245d827d2008-12-07 13:40:29 +0000150 tcg_gen_mov_tl(cpu_ctr, cpu_gpr[gprn]);
bellard3fc6c082005-07-02 20:59:34 +0000151}
152
153/* User read access to SPR */
154/* USPRx */
155/* UMMCRx */
156/* UPMCx */
157/* USIA */
158/* UDECR */
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300159static void spr_read_ureg (DisasContext *ctx, int gprn, int sprn)
bellard3fc6c082005-07-02 20:59:34 +0000160{
aurel3245d827d2008-12-07 13:40:29 +0000161 gen_load_spr(cpu_gpr[gprn], sprn + 0x10);
bellard3fc6c082005-07-02 20:59:34 +0000162}
163
Alexey Kardashevskiyfd51ff62014-06-04 22:50:40 +1000164#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300165static void spr_write_ureg(DisasContext *ctx, int sprn, int gprn)
Alexey Kardashevskiyfd51ff62014-06-04 22:50:40 +1000166{
167 gen_store_spr(sprn + 0x10, cpu_gpr[gprn]);
168}
169#endif
170
j_mayer76a66252007-03-07 08:32:30 +0000171/* SPR common to all non-embedded PowerPC */
bellard3fc6c082005-07-02 20:59:34 +0000172/* DECR */
j_mayer76a66252007-03-07 08:32:30 +0000173#if !defined(CONFIG_USER_ONLY)
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300174static void spr_read_decr (DisasContext *ctx, int gprn, int sprn)
bellard3fc6c082005-07-02 20:59:34 +0000175{
Paolo Bonzinibd792552014-11-26 13:39:59 +0300176 if (ctx->tb->cflags & CF_USE_ICOUNT) {
Tristan Gingold630ecca2011-02-15 09:39:54 +0100177 gen_io_start();
178 }
Blue Swirld0f15622012-05-30 04:23:36 +0000179 gen_helper_load_decr(cpu_gpr[gprn], cpu_env);
Paolo Bonzinibd792552014-11-26 13:39:59 +0300180 if (ctx->tb->cflags & CF_USE_ICOUNT) {
Tristan Gingold630ecca2011-02-15 09:39:54 +0100181 gen_io_end();
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300182 gen_stop_exception(ctx);
Tristan Gingold630ecca2011-02-15 09:39:54 +0100183 }
bellard3fc6c082005-07-02 20:59:34 +0000184}
185
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300186static void spr_write_decr (DisasContext *ctx, int sprn, int gprn)
bellard3fc6c082005-07-02 20:59:34 +0000187{
Paolo Bonzinibd792552014-11-26 13:39:59 +0300188 if (ctx->tb->cflags & CF_USE_ICOUNT) {
Tristan Gingold630ecca2011-02-15 09:39:54 +0100189 gen_io_start();
190 }
Blue Swirld0f15622012-05-30 04:23:36 +0000191 gen_helper_store_decr(cpu_env, cpu_gpr[gprn]);
Paolo Bonzinibd792552014-11-26 13:39:59 +0300192 if (ctx->tb->cflags & CF_USE_ICOUNT) {
Tristan Gingold630ecca2011-02-15 09:39:54 +0100193 gen_io_end();
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300194 gen_stop_exception(ctx);
Tristan Gingold630ecca2011-02-15 09:39:54 +0100195 }
bellard3fc6c082005-07-02 20:59:34 +0000196}
j_mayer76a66252007-03-07 08:32:30 +0000197#endif
bellard3fc6c082005-07-02 20:59:34 +0000198
j_mayer76a66252007-03-07 08:32:30 +0000199/* SPR common to all non-embedded PowerPC, except 601 */
bellard3fc6c082005-07-02 20:59:34 +0000200/* Time base */
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300201static void spr_read_tbl (DisasContext *ctx, int gprn, int sprn)
bellard3fc6c082005-07-02 20:59:34 +0000202{
Paolo Bonzinibd792552014-11-26 13:39:59 +0300203 if (ctx->tb->cflags & CF_USE_ICOUNT) {
Tristan Gingold630ecca2011-02-15 09:39:54 +0100204 gen_io_start();
205 }
Blue Swirld0f15622012-05-30 04:23:36 +0000206 gen_helper_load_tbl(cpu_gpr[gprn], cpu_env);
Paolo Bonzinibd792552014-11-26 13:39:59 +0300207 if (ctx->tb->cflags & CF_USE_ICOUNT) {
Tristan Gingold630ecca2011-02-15 09:39:54 +0100208 gen_io_end();
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300209 gen_stop_exception(ctx);
Tristan Gingold630ecca2011-02-15 09:39:54 +0100210 }
bellard3fc6c082005-07-02 20:59:34 +0000211}
212
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300213static void spr_read_tbu (DisasContext *ctx, int gprn, int sprn)
bellard3fc6c082005-07-02 20:59:34 +0000214{
Paolo Bonzinibd792552014-11-26 13:39:59 +0300215 if (ctx->tb->cflags & CF_USE_ICOUNT) {
Tristan Gingold630ecca2011-02-15 09:39:54 +0100216 gen_io_start();
217 }
Blue Swirld0f15622012-05-30 04:23:36 +0000218 gen_helper_load_tbu(cpu_gpr[gprn], cpu_env);
Paolo Bonzinibd792552014-11-26 13:39:59 +0300219 if (ctx->tb->cflags & CF_USE_ICOUNT) {
Tristan Gingold630ecca2011-02-15 09:39:54 +0100220 gen_io_end();
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300221 gen_stop_exception(ctx);
Tristan Gingold630ecca2011-02-15 09:39:54 +0100222 }
bellard3fc6c082005-07-02 20:59:34 +0000223}
224
j_mayera062e362007-09-30 00:38:38 +0000225__attribute__ (( unused ))
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300226static void spr_read_atbl (DisasContext *ctx, int gprn, int sprn)
j_mayera062e362007-09-30 00:38:38 +0000227{
Blue Swirld0f15622012-05-30 04:23:36 +0000228 gen_helper_load_atbl(cpu_gpr[gprn], cpu_env);
j_mayera062e362007-09-30 00:38:38 +0000229}
230
231__attribute__ (( unused ))
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300232static void spr_read_atbu (DisasContext *ctx, int gprn, int sprn)
j_mayera062e362007-09-30 00:38:38 +0000233{
Blue Swirld0f15622012-05-30 04:23:36 +0000234 gen_helper_load_atbu(cpu_gpr[gprn], cpu_env);
j_mayera062e362007-09-30 00:38:38 +0000235}
236
j_mayer76a66252007-03-07 08:32:30 +0000237#if !defined(CONFIG_USER_ONLY)
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300238static void spr_write_tbl (DisasContext *ctx, int sprn, int gprn)
j_mayer76a66252007-03-07 08:32:30 +0000239{
Paolo Bonzinibd792552014-11-26 13:39:59 +0300240 if (ctx->tb->cflags & CF_USE_ICOUNT) {
Tristan Gingold630ecca2011-02-15 09:39:54 +0100241 gen_io_start();
242 }
Blue Swirld0f15622012-05-30 04:23:36 +0000243 gen_helper_store_tbl(cpu_env, cpu_gpr[gprn]);
Paolo Bonzinibd792552014-11-26 13:39:59 +0300244 if (ctx->tb->cflags & CF_USE_ICOUNT) {
Tristan Gingold630ecca2011-02-15 09:39:54 +0100245 gen_io_end();
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300246 gen_stop_exception(ctx);
Tristan Gingold630ecca2011-02-15 09:39:54 +0100247 }
j_mayer76a66252007-03-07 08:32:30 +0000248}
249
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300250static void spr_write_tbu (DisasContext *ctx, int sprn, int gprn)
bellard3fc6c082005-07-02 20:59:34 +0000251{
Paolo Bonzinibd792552014-11-26 13:39:59 +0300252 if (ctx->tb->cflags & CF_USE_ICOUNT) {
Tristan Gingold630ecca2011-02-15 09:39:54 +0100253 gen_io_start();
254 }
Blue Swirld0f15622012-05-30 04:23:36 +0000255 gen_helper_store_tbu(cpu_env, cpu_gpr[gprn]);
Paolo Bonzinibd792552014-11-26 13:39:59 +0300256 if (ctx->tb->cflags & CF_USE_ICOUNT) {
Tristan Gingold630ecca2011-02-15 09:39:54 +0100257 gen_io_end();
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300258 gen_stop_exception(ctx);
Tristan Gingold630ecca2011-02-15 09:39:54 +0100259 }
bellard3fc6c082005-07-02 20:59:34 +0000260}
j_mayera062e362007-09-30 00:38:38 +0000261
262__attribute__ (( unused ))
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300263static void spr_write_atbl (DisasContext *ctx, int sprn, int gprn)
j_mayera062e362007-09-30 00:38:38 +0000264{
Blue Swirld0f15622012-05-30 04:23:36 +0000265 gen_helper_store_atbl(cpu_env, cpu_gpr[gprn]);
j_mayera062e362007-09-30 00:38:38 +0000266}
267
268__attribute__ (( unused ))
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300269static void spr_write_atbu (DisasContext *ctx, int sprn, int gprn)
j_mayera062e362007-09-30 00:38:38 +0000270{
Blue Swirld0f15622012-05-30 04:23:36 +0000271 gen_helper_store_atbu(cpu_env, cpu_gpr[gprn]);
j_mayera062e362007-09-30 00:38:38 +0000272}
David Gibson3a7f0092011-04-01 15:15:12 +1100273
274#if defined(TARGET_PPC64)
275__attribute__ (( unused ))
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300276static void spr_read_purr (DisasContext *ctx, int gprn, int sprn)
David Gibson3a7f0092011-04-01 15:15:12 +1100277{
Blue Swirld0f15622012-05-30 04:23:36 +0000278 gen_helper_load_purr(cpu_gpr[gprn], cpu_env);
David Gibson3a7f0092011-04-01 15:15:12 +1100279}
Benjamin Herrenschmidt4b236b62016-06-27 08:55:19 +0200280
281/* HDECR */
282static void spr_read_hdecr(DisasContext *ctx, int gprn, int sprn)
283{
284 if (ctx->tb->cflags & CF_USE_ICOUNT) {
285 gen_io_start();
286 }
287 gen_helper_load_hdecr(cpu_gpr[gprn], cpu_env);
288 if (ctx->tb->cflags & CF_USE_ICOUNT) {
289 gen_io_end();
290 gen_stop_exception(ctx);
291 }
292}
293
294static void spr_write_hdecr(DisasContext *ctx, int sprn, int gprn)
295{
296 if (ctx->tb->cflags & CF_USE_ICOUNT) {
297 gen_io_start();
298 }
299 gen_helper_store_hdecr(cpu_env, cpu_gpr[gprn]);
300 if (ctx->tb->cflags & CF_USE_ICOUNT) {
301 gen_io_end();
302 gen_stop_exception(ctx);
303 }
304}
305
David Gibson3a7f0092011-04-01 15:15:12 +1100306#endif
j_mayer76a66252007-03-07 08:32:30 +0000307#endif
bellard3fc6c082005-07-02 20:59:34 +0000308
j_mayer76a66252007-03-07 08:32:30 +0000309#if !defined(CONFIG_USER_ONLY)
bellard3fc6c082005-07-02 20:59:34 +0000310/* IBAT0U...IBAT0U */
311/* IBAT0L...IBAT7L */
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300312static void spr_read_ibat (DisasContext *ctx, int gprn, int sprn)
bellard3fc6c082005-07-02 20:59:34 +0000313{
Andreas Färber1328c2b2012-03-14 01:38:22 +0100314 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2]));
bellard3fc6c082005-07-02 20:59:34 +0000315}
316
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300317static void spr_read_ibat_h (DisasContext *ctx, int gprn, int sprn)
bellard3fc6c082005-07-02 20:59:34 +0000318{
Julio Guerra3ede8f62015-10-14 19:43:19 +0200319 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, IBAT[sprn & 1][((sprn - SPR_IBAT4U) / 2) + 4]));
bellard3fc6c082005-07-02 20:59:34 +0000320}
321
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300322static void spr_write_ibatu (DisasContext *ctx, int sprn, int gprn)
bellard3fc6c082005-07-02 20:59:34 +0000323{
aurel3245d827d2008-12-07 13:40:29 +0000324 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2);
Blue Swirlc6c7cf02012-05-30 04:23:31 +0000325 gen_helper_store_ibatu(cpu_env, t0, cpu_gpr[gprn]);
aurel3245d827d2008-12-07 13:40:29 +0000326 tcg_temp_free_i32(t0);
bellard3fc6c082005-07-02 20:59:34 +0000327}
328
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300329static void spr_write_ibatu_h (DisasContext *ctx, int sprn, int gprn)
bellard3fc6c082005-07-02 20:59:34 +0000330{
Thomas Monjalon8daf1782009-10-15 19:01:19 +0200331 TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_IBAT4U) / 2) + 4);
Blue Swirlc6c7cf02012-05-30 04:23:31 +0000332 gen_helper_store_ibatu(cpu_env, t0, cpu_gpr[gprn]);
aurel3245d827d2008-12-07 13:40:29 +0000333 tcg_temp_free_i32(t0);
bellard3fc6c082005-07-02 20:59:34 +0000334}
335
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300336static void spr_write_ibatl (DisasContext *ctx, int sprn, int gprn)
bellard3fc6c082005-07-02 20:59:34 +0000337{
aurel3245d827d2008-12-07 13:40:29 +0000338 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0L) / 2);
Blue Swirlc6c7cf02012-05-30 04:23:31 +0000339 gen_helper_store_ibatl(cpu_env, t0, cpu_gpr[gprn]);
aurel3245d827d2008-12-07 13:40:29 +0000340 tcg_temp_free_i32(t0);
bellard3fc6c082005-07-02 20:59:34 +0000341}
342
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300343static void spr_write_ibatl_h (DisasContext *ctx, int sprn, int gprn)
bellard3fc6c082005-07-02 20:59:34 +0000344{
Thomas Monjalon8daf1782009-10-15 19:01:19 +0200345 TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_IBAT4L) / 2) + 4);
Blue Swirlc6c7cf02012-05-30 04:23:31 +0000346 gen_helper_store_ibatl(cpu_env, t0, cpu_gpr[gprn]);
aurel3245d827d2008-12-07 13:40:29 +0000347 tcg_temp_free_i32(t0);
bellard3fc6c082005-07-02 20:59:34 +0000348}
349
350/* DBAT0U...DBAT7U */
351/* DBAT0L...DBAT7L */
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300352static void spr_read_dbat (DisasContext *ctx, int gprn, int sprn)
bellard3fc6c082005-07-02 20:59:34 +0000353{
Andreas Färber1328c2b2012-03-14 01:38:22 +0100354 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, DBAT[sprn & 1][(sprn - SPR_DBAT0U) / 2]));
bellard3fc6c082005-07-02 20:59:34 +0000355}
356
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300357static void spr_read_dbat_h (DisasContext *ctx, int gprn, int sprn)
bellard3fc6c082005-07-02 20:59:34 +0000358{
Andreas Färber1328c2b2012-03-14 01:38:22 +0100359 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, DBAT[sprn & 1][((sprn - SPR_DBAT4U) / 2) + 4]));
bellard3fc6c082005-07-02 20:59:34 +0000360}
361
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300362static void spr_write_dbatu (DisasContext *ctx, int sprn, int gprn)
bellard3fc6c082005-07-02 20:59:34 +0000363{
aurel3245d827d2008-12-07 13:40:29 +0000364 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_DBAT0U) / 2);
Blue Swirlc6c7cf02012-05-30 04:23:31 +0000365 gen_helper_store_dbatu(cpu_env, t0, cpu_gpr[gprn]);
aurel3245d827d2008-12-07 13:40:29 +0000366 tcg_temp_free_i32(t0);
bellard3fc6c082005-07-02 20:59:34 +0000367}
368
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300369static void spr_write_dbatu_h (DisasContext *ctx, int sprn, int gprn)
bellard3fc6c082005-07-02 20:59:34 +0000370{
aurel3245d827d2008-12-07 13:40:29 +0000371 TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_DBAT4U) / 2) + 4);
Blue Swirlc6c7cf02012-05-30 04:23:31 +0000372 gen_helper_store_dbatu(cpu_env, t0, cpu_gpr[gprn]);
aurel3245d827d2008-12-07 13:40:29 +0000373 tcg_temp_free_i32(t0);
bellard3fc6c082005-07-02 20:59:34 +0000374}
375
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300376static void spr_write_dbatl (DisasContext *ctx, int sprn, int gprn)
bellard3fc6c082005-07-02 20:59:34 +0000377{
aurel3245d827d2008-12-07 13:40:29 +0000378 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_DBAT0L) / 2);
Blue Swirlc6c7cf02012-05-30 04:23:31 +0000379 gen_helper_store_dbatl(cpu_env, t0, cpu_gpr[gprn]);
aurel3245d827d2008-12-07 13:40:29 +0000380 tcg_temp_free_i32(t0);
bellard3fc6c082005-07-02 20:59:34 +0000381}
382
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300383static void spr_write_dbatl_h (DisasContext *ctx, int sprn, int gprn)
bellard3fc6c082005-07-02 20:59:34 +0000384{
aurel3245d827d2008-12-07 13:40:29 +0000385 TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_DBAT4L) / 2) + 4);
Blue Swirlc6c7cf02012-05-30 04:23:31 +0000386 gen_helper_store_dbatl(cpu_env, t0, cpu_gpr[gprn]);
aurel3245d827d2008-12-07 13:40:29 +0000387 tcg_temp_free_i32(t0);
bellard3fc6c082005-07-02 20:59:34 +0000388}
389
390/* SDR1 */
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300391static void spr_write_sdr1 (DisasContext *ctx, int sprn, int gprn)
bellard3fc6c082005-07-02 20:59:34 +0000392{
Blue Swirld523dd02012-05-30 04:23:38 +0000393 gen_helper_store_sdr1(cpu_env, cpu_gpr[gprn]);
bellard3fc6c082005-07-02 20:59:34 +0000394}
395
j_mayer76a66252007-03-07 08:32:30 +0000396/* 64 bits PowerPC specific SPRs */
j_mayer578bb252007-10-01 04:48:45 +0000397#if defined(TARGET_PPC64)
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300398static void spr_read_hior (DisasContext *ctx, int gprn, int sprn)
blueswir12adab7d2009-02-28 18:39:42 +0000399{
Andreas Färber1328c2b2012-03-14 01:38:22 +0100400 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, excp_prefix));
blueswir12adab7d2009-02-28 18:39:42 +0000401}
402
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300403static void spr_write_hior (DisasContext *ctx, int sprn, int gprn)
blueswir12adab7d2009-02-28 18:39:42 +0000404{
405 TCGv t0 = tcg_temp_new();
406 tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0x3FFFFF00000ULL);
Andreas Färber1328c2b2012-03-14 01:38:22 +0100407 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, excp_prefix));
blueswir12adab7d2009-02-28 18:39:42 +0000408 tcg_temp_free(t0);
409}
j_mayer76a66252007-03-07 08:32:30 +0000410#endif
j_mayera750fc02007-09-26 23:54:22 +0000411#endif
j_mayer76a66252007-03-07 08:32:30 +0000412
413/* PowerPC 601 specific registers */
414/* RTC */
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300415static void spr_read_601_rtcl (DisasContext *ctx, int gprn, int sprn)
j_mayer76a66252007-03-07 08:32:30 +0000416{
Blue Swirld0f15622012-05-30 04:23:36 +0000417 gen_helper_load_601_rtcl(cpu_gpr[gprn], cpu_env);
j_mayer76a66252007-03-07 08:32:30 +0000418}
419
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300420static void spr_read_601_rtcu (DisasContext *ctx, int gprn, int sprn)
j_mayer76a66252007-03-07 08:32:30 +0000421{
Blue Swirld0f15622012-05-30 04:23:36 +0000422 gen_helper_load_601_rtcu(cpu_gpr[gprn], cpu_env);
j_mayer76a66252007-03-07 08:32:30 +0000423}
424
425#if !defined(CONFIG_USER_ONLY)
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300426static void spr_write_601_rtcu (DisasContext *ctx, int sprn, int gprn)
j_mayer76a66252007-03-07 08:32:30 +0000427{
Blue Swirld0f15622012-05-30 04:23:36 +0000428 gen_helper_store_601_rtcu(cpu_env, cpu_gpr[gprn]);
j_mayer76a66252007-03-07 08:32:30 +0000429}
430
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300431static void spr_write_601_rtcl (DisasContext *ctx, int sprn, int gprn)
j_mayer76a66252007-03-07 08:32:30 +0000432{
Blue Swirld0f15622012-05-30 04:23:36 +0000433 gen_helper_store_601_rtcl(cpu_env, cpu_gpr[gprn]);
j_mayer76a66252007-03-07 08:32:30 +0000434}
j_mayer056401e2007-11-04 02:55:33 +0000435
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300436static void spr_write_hid0_601 (DisasContext *ctx, int sprn, int gprn)
j_mayer056401e2007-11-04 02:55:33 +0000437{
Blue Swirld523dd02012-05-30 04:23:38 +0000438 gen_helper_store_hid0_601(cpu_env, cpu_gpr[gprn]);
j_mayer056401e2007-11-04 02:55:33 +0000439 /* Must stop the translation as endianness may have changed */
aurel32e06fcd72008-12-11 22:42:14 +0000440 gen_stop_exception(ctx);
j_mayer056401e2007-11-04 02:55:33 +0000441}
j_mayer76a66252007-03-07 08:32:30 +0000442#endif
443
444/* Unified bats */
445#if !defined(CONFIG_USER_ONLY)
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300446static void spr_read_601_ubat (DisasContext *ctx, int gprn, int sprn)
j_mayer76a66252007-03-07 08:32:30 +0000447{
Andreas Färber1328c2b2012-03-14 01:38:22 +0100448 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2]));
j_mayer76a66252007-03-07 08:32:30 +0000449}
450
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300451static void spr_write_601_ubatu (DisasContext *ctx, int sprn, int gprn)
j_mayer76a66252007-03-07 08:32:30 +0000452{
aurel3245d827d2008-12-07 13:40:29 +0000453 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2);
Blue Swirlc6c7cf02012-05-30 04:23:31 +0000454 gen_helper_store_601_batl(cpu_env, t0, cpu_gpr[gprn]);
aurel3245d827d2008-12-07 13:40:29 +0000455 tcg_temp_free_i32(t0);
j_mayer76a66252007-03-07 08:32:30 +0000456}
457
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300458static void spr_write_601_ubatl (DisasContext *ctx, int sprn, int gprn)
j_mayer76a66252007-03-07 08:32:30 +0000459{
aurel3245d827d2008-12-07 13:40:29 +0000460 TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2);
Blue Swirlc6c7cf02012-05-30 04:23:31 +0000461 gen_helper_store_601_batu(cpu_env, t0, cpu_gpr[gprn]);
aurel3245d827d2008-12-07 13:40:29 +0000462 tcg_temp_free_i32(t0);
j_mayer76a66252007-03-07 08:32:30 +0000463}
464#endif
465
466/* PowerPC 40x specific registers */
467#if !defined(CONFIG_USER_ONLY)
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300468static void spr_read_40x_pit (DisasContext *ctx, int gprn, int sprn)
j_mayer76a66252007-03-07 08:32:30 +0000469{
Blue Swirld0f15622012-05-30 04:23:36 +0000470 gen_helper_load_40x_pit(cpu_gpr[gprn], cpu_env);
j_mayer76a66252007-03-07 08:32:30 +0000471}
472
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300473static void spr_write_40x_pit (DisasContext *ctx, int sprn, int gprn)
j_mayer76a66252007-03-07 08:32:30 +0000474{
Blue Swirld0f15622012-05-30 04:23:36 +0000475 gen_helper_store_40x_pit(cpu_env, cpu_gpr[gprn]);
j_mayer76a66252007-03-07 08:32:30 +0000476}
477
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300478static void spr_write_40x_dbcr0 (DisasContext *ctx, int sprn, int gprn)
j_mayer8ecc7912007-04-16 20:09:45 +0000479{
Blue Swirld523dd02012-05-30 04:23:38 +0000480 gen_helper_store_40x_dbcr0(cpu_env, cpu_gpr[gprn]);
j_mayer8ecc7912007-04-16 20:09:45 +0000481 /* We must stop translation as we may have rebooted */
aurel32e06fcd72008-12-11 22:42:14 +0000482 gen_stop_exception(ctx);
j_mayer8ecc7912007-04-16 20:09:45 +0000483}
484
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300485static void spr_write_40x_sler (DisasContext *ctx, int sprn, int gprn)
j_mayerc294fc52007-04-24 06:44:14 +0000486{
Blue Swirld523dd02012-05-30 04:23:38 +0000487 gen_helper_store_40x_sler(cpu_env, cpu_gpr[gprn]);
j_mayerc294fc52007-04-24 06:44:14 +0000488}
489
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300490static void spr_write_booke_tcr (DisasContext *ctx, int sprn, int gprn)
j_mayer76a66252007-03-07 08:32:30 +0000491{
Blue Swirld0f15622012-05-30 04:23:36 +0000492 gen_helper_store_booke_tcr(cpu_env, cpu_gpr[gprn]);
j_mayer76a66252007-03-07 08:32:30 +0000493}
494
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300495static void spr_write_booke_tsr (DisasContext *ctx, int sprn, int gprn)
j_mayer76a66252007-03-07 08:32:30 +0000496{
Blue Swirld0f15622012-05-30 04:23:36 +0000497 gen_helper_store_booke_tsr(cpu_env, cpu_gpr[gprn]);
j_mayer76a66252007-03-07 08:32:30 +0000498}
499#endif
500
501/* PowerPC 403 specific registers */
502/* PBL1 / PBU1 / PBL2 / PBU2 */
503#if !defined(CONFIG_USER_ONLY)
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300504static void spr_read_403_pbr (DisasContext *ctx, int gprn, int sprn)
j_mayer76a66252007-03-07 08:32:30 +0000505{
Andreas Färber1328c2b2012-03-14 01:38:22 +0100506 tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, pb[sprn - SPR_403_PBL1]));
j_mayer76a66252007-03-07 08:32:30 +0000507}
508
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300509static void spr_write_403_pbr (DisasContext *ctx, int sprn, int gprn)
j_mayer76a66252007-03-07 08:32:30 +0000510{
aurel3245d827d2008-12-07 13:40:29 +0000511 TCGv_i32 t0 = tcg_const_i32(sprn - SPR_403_PBL1);
Blue Swirld523dd02012-05-30 04:23:38 +0000512 gen_helper_store_403_pbr(cpu_env, t0, cpu_gpr[gprn]);
aurel3245d827d2008-12-07 13:40:29 +0000513 tcg_temp_free_i32(t0);
j_mayer76a66252007-03-07 08:32:30 +0000514}
515
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300516static void spr_write_pir (DisasContext *ctx, int sprn, int gprn)
bellard3fc6c082005-07-02 20:59:34 +0000517{
aurel3245d827d2008-12-07 13:40:29 +0000518 TCGv t0 = tcg_temp_new();
519 tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0xF);
520 gen_store_spr(SPR_PIR, t0);
521 tcg_temp_free(t0);
bellard3fc6c082005-07-02 20:59:34 +0000522}
j_mayer76a66252007-03-07 08:32:30 +0000523#endif
bellard3fc6c082005-07-02 20:59:34 +0000524
aurel32d34defb2009-03-09 06:27:14 +0000525/* SPE specific registers */
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300526static void spr_read_spefscr (DisasContext *ctx, int gprn, int sprn)
aurel32d34defb2009-03-09 06:27:14 +0000527{
528 TCGv_i32 t0 = tcg_temp_new_i32();
Andreas Färber1328c2b2012-03-14 01:38:22 +0100529 tcg_gen_ld_i32(t0, cpu_env, offsetof(CPUPPCState, spe_fscr));
aurel32d34defb2009-03-09 06:27:14 +0000530 tcg_gen_extu_i32_tl(cpu_gpr[gprn], t0);
531 tcg_temp_free_i32(t0);
532}
533
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300534static void spr_write_spefscr (DisasContext *ctx, int sprn, int gprn)
aurel32d34defb2009-03-09 06:27:14 +0000535{
536 TCGv_i32 t0 = tcg_temp_new_i32();
537 tcg_gen_trunc_tl_i32(t0, cpu_gpr[gprn]);
Andreas Färber1328c2b2012-03-14 01:38:22 +0100538 tcg_gen_st_i32(t0, cpu_env, offsetof(CPUPPCState, spe_fscr));
aurel32d34defb2009-03-09 06:27:14 +0000539 tcg_temp_free_i32(t0);
540}
541
j_mayer6f5d4272007-10-01 01:32:49 +0000542#if !defined(CONFIG_USER_ONLY)
543/* Callback used to write the exception vector base */
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300544static void spr_write_excp_prefix (DisasContext *ctx, int sprn, int gprn)
j_mayer6f5d4272007-10-01 01:32:49 +0000545{
aurel3245d827d2008-12-07 13:40:29 +0000546 TCGv t0 = tcg_temp_new();
Andreas Färber1328c2b2012-03-14 01:38:22 +0100547 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUPPCState, ivpr_mask));
aurel3245d827d2008-12-07 13:40:29 +0000548 tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]);
Andreas Färber1328c2b2012-03-14 01:38:22 +0100549 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, excp_prefix));
aurel3245d827d2008-12-07 13:40:29 +0000550 gen_store_spr(sprn, t0);
aurel3269bd5822009-03-09 06:27:24 +0000551 tcg_temp_free(t0);
j_mayer6f5d4272007-10-01 01:32:49 +0000552}
553
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300554static void spr_write_excp_vector (DisasContext *ctx, int sprn, int gprn)
j_mayer6f5d4272007-10-01 01:32:49 +0000555{
Alexander Grafe9205252012-01-19 19:31:51 +0100556 int sprn_offs;
j_mayer6f5d4272007-10-01 01:32:49 +0000557
558 if (sprn >= SPR_BOOKE_IVOR0 && sprn <= SPR_BOOKE_IVOR15) {
Alexander Grafe9205252012-01-19 19:31:51 +0100559 sprn_offs = sprn - SPR_BOOKE_IVOR0;
j_mayer6f5d4272007-10-01 01:32:49 +0000560 } else if (sprn >= SPR_BOOKE_IVOR32 && sprn <= SPR_BOOKE_IVOR37) {
Alexander Grafe9205252012-01-19 19:31:51 +0100561 sprn_offs = sprn - SPR_BOOKE_IVOR32 + 32;
562 } else if (sprn >= SPR_BOOKE_IVOR38 && sprn <= SPR_BOOKE_IVOR42) {
563 sprn_offs = sprn - SPR_BOOKE_IVOR38 + 38;
j_mayer6f5d4272007-10-01 01:32:49 +0000564 } else {
565 printf("Trying to write an unknown exception vector %d %03x\n",
566 sprn, sprn);
aurel32e06fcd72008-12-11 22:42:14 +0000567 gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
Alexander Grafe9205252012-01-19 19:31:51 +0100568 return;
j_mayer6f5d4272007-10-01 01:32:49 +0000569 }
Alexander Grafe9205252012-01-19 19:31:51 +0100570
571 TCGv t0 = tcg_temp_new();
Andreas Färber1328c2b2012-03-14 01:38:22 +0100572 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUPPCState, ivor_mask));
Alexander Grafe9205252012-01-19 19:31:51 +0100573 tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]);
Andreas Färber1328c2b2012-03-14 01:38:22 +0100574 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, excp_vectors[sprn_offs]));
Alexander Grafe9205252012-01-19 19:31:51 +0100575 gen_store_spr(sprn, t0);
576 tcg_temp_free(t0);
j_mayer6f5d4272007-10-01 01:32:49 +0000577}
578#endif
579
aurel32cf8358c2009-02-03 19:55:59 +0000580static inline void vscr_init (CPUPPCState *env, uint32_t val)
581{
582 env->vscr = val;
583 /* Altivec always uses round-to-nearest */
584 set_float_rounding_mode(float_round_nearest_even, &env->vec_status);
585 set_flush_to_zero(vscr_nj, &env->vec_status);
586}
587
David Gibsond67d40e2013-02-20 16:41:50 +0000588#ifdef CONFIG_USER_ONLY
589#define spr_register_kvm(env, num, name, uea_read, uea_write, \
590 oea_read, oea_write, one_reg_id, initial_value) \
591 _spr_register(env, num, name, uea_read, uea_write, initial_value)
Benjamin Herrenschmidteb942682016-03-21 13:52:32 +0100592#define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
593 oea_read, oea_write, hea_read, hea_write, \
594 one_reg_id, initial_value) \
595 _spr_register(env, num, name, uea_read, uea_write, initial_value)
j_mayer76a66252007-03-07 08:32:30 +0000596#else
David Gibsond67d40e2013-02-20 16:41:50 +0000597#if !defined(CONFIG_KVM)
598#define spr_register_kvm(env, num, name, uea_read, uea_write, \
Benjamin Herrenschmidteb942682016-03-21 13:52:32 +0100599 oea_read, oea_write, one_reg_id, initial_value) \
David Gibsond67d40e2013-02-20 16:41:50 +0000600 _spr_register(env, num, name, uea_read, uea_write, \
Benjamin Herrenschmidteb942682016-03-21 13:52:32 +0100601 oea_read, oea_write, oea_read, oea_write, initial_value)
602#define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
603 oea_read, oea_write, hea_read, hea_write, \
604 one_reg_id, initial_value) \
605 _spr_register(env, num, name, uea_read, uea_write, \
606 oea_read, oea_write, hea_read, hea_write, initial_value)
David Gibsond67d40e2013-02-20 16:41:50 +0000607#else
608#define spr_register_kvm(env, num, name, uea_read, uea_write, \
Benjamin Herrenschmidteb942682016-03-21 13:52:32 +0100609 oea_read, oea_write, one_reg_id, initial_value) \
David Gibsond67d40e2013-02-20 16:41:50 +0000610 _spr_register(env, num, name, uea_read, uea_write, \
Benjamin Herrenschmidteb942682016-03-21 13:52:32 +0100611 oea_read, oea_write, oea_read, oea_write, \
612 one_reg_id, initial_value)
613#define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
614 oea_read, oea_write, hea_read, hea_write, \
615 one_reg_id, initial_value) \
616 _spr_register(env, num, name, uea_read, uea_write, \
617 oea_read, oea_write, hea_read, hea_write, \
618 one_reg_id, initial_value)
David Gibsond67d40e2013-02-20 16:41:50 +0000619#endif
620#endif
621
622#define spr_register(env, num, name, uea_read, uea_write, \
623 oea_read, oea_write, initial_value) \
624 spr_register_kvm(env, num, name, uea_read, uea_write, \
625 oea_read, oea_write, 0, initial_value)
626
Benjamin Herrenschmidteb942682016-03-21 13:52:32 +0100627#define spr_register_hv(env, num, name, uea_read, uea_write, \
628 oea_read, oea_write, hea_read, hea_write, \
629 initial_value) \
630 spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
631 oea_read, oea_write, hea_read, hea_write, \
632 0, initial_value)
633
David Gibsond67d40e2013-02-20 16:41:50 +0000634static inline void _spr_register(CPUPPCState *env, int num,
blueswir1b55266b2008-09-20 08:07:15 +0000635 const char *name,
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300636 void (*uea_read)(DisasContext *ctx, int gprn, int sprn),
637 void (*uea_write)(DisasContext *ctx, int sprn, int gprn),
David Gibsond67d40e2013-02-20 16:41:50 +0000638#if !defined(CONFIG_USER_ONLY)
639
Paolo Bonzini69b058c2014-11-26 13:39:48 +0300640 void (*oea_read)(DisasContext *ctx, int gprn, int sprn),
641 void (*oea_write)(DisasContext *ctx, int sprn, int gprn),
Benjamin Herrenschmidteb942682016-03-21 13:52:32 +0100642 void (*hea_read)(DisasContext *opaque, int gprn, int sprn),
643 void (*hea_write)(DisasContext *opaque, int sprn, int gprn),
j_mayer76a66252007-03-07 08:32:30 +0000644#endif
David Gibsond67d40e2013-02-20 16:41:50 +0000645#if defined(CONFIG_KVM)
646 uint64_t one_reg_id,
647#endif
648 target_ulong initial_value)
bellard3fc6c082005-07-02 20:59:34 +0000649{
Anthony Liguoric227f092009-10-01 16:12:16 -0500650 ppc_spr_t *spr;
bellard3fc6c082005-07-02 20:59:34 +0000651
652 spr = &env->spr_cb[num];
653 if (spr->name != NULL ||env-> spr[num] != 0x00000000 ||
j_mayer76a66252007-03-07 08:32:30 +0000654#if !defined(CONFIG_USER_ONLY)
655 spr->oea_read != NULL || spr->oea_write != NULL ||
656#endif
657 spr->uea_read != NULL || spr->uea_write != NULL) {
bellard3fc6c082005-07-02 20:59:34 +0000658 printf("Error: Trying to register SPR %d (%03x) twice !\n", num, num);
659 exit(1);
660 }
661#if defined(PPC_DEBUG_SPR)
Blue Swirl90e189e2009-08-16 11:13:18 +0000662 printf("*** register spr %d (%03x) %s val " TARGET_FMT_lx "\n", num, num,
663 name, initial_value);
bellard3fc6c082005-07-02 20:59:34 +0000664#endif
665 spr->name = name;
666 spr->uea_read = uea_read;
667 spr->uea_write = uea_write;
j_mayer76a66252007-03-07 08:32:30 +0000668#if !defined(CONFIG_USER_ONLY)
bellard3fc6c082005-07-02 20:59:34 +0000669 spr->oea_read = oea_read;
670 spr->oea_write = oea_write;
Benjamin Herrenschmidteb942682016-03-21 13:52:32 +0100671 spr->hea_read = hea_read;
672 spr->hea_write = hea_write;
j_mayer76a66252007-03-07 08:32:30 +0000673#endif
Alexey Kardashevskiy7a7c05d2014-01-06 16:36:40 +1100674#if defined(CONFIG_KVM)
675 spr->one_reg_id = one_reg_id,
676#endif
Alexey Kardashevskiyd197fdb2014-03-20 00:03:57 +1100677 env->spr[num] = spr->default_value = initial_value;
bellard3fc6c082005-07-02 20:59:34 +0000678}
679
680/* Generic PowerPC SPRs */
681static void gen_spr_generic (CPUPPCState *env)
682{
683 /* Integer processing */
684 spr_register(env, SPR_XER, "XER",
685 &spr_read_xer, &spr_write_xer,
686 &spr_read_xer, &spr_write_xer,
687 0x00000000);
688 /* Branch contol */
689 spr_register(env, SPR_LR, "LR",
690 &spr_read_lr, &spr_write_lr,
691 &spr_read_lr, &spr_write_lr,
692 0x00000000);
693 spr_register(env, SPR_CTR, "CTR",
694 &spr_read_ctr, &spr_write_ctr,
695 &spr_read_ctr, &spr_write_ctr,
696 0x00000000);
697 /* Interrupt processing */
698 spr_register(env, SPR_SRR0, "SRR0",
699 SPR_NOACCESS, SPR_NOACCESS,
700 &spr_read_generic, &spr_write_generic,
701 0x00000000);
702 spr_register(env, SPR_SRR1, "SRR1",
703 SPR_NOACCESS, SPR_NOACCESS,
704 &spr_read_generic, &spr_write_generic,
705 0x00000000);
706 /* Processor control */
707 spr_register(env, SPR_SPRG0, "SPRG0",
708 SPR_NOACCESS, SPR_NOACCESS,
709 &spr_read_generic, &spr_write_generic,
710 0x00000000);
711 spr_register(env, SPR_SPRG1, "SPRG1",
712 SPR_NOACCESS, SPR_NOACCESS,
713 &spr_read_generic, &spr_write_generic,
714 0x00000000);
715 spr_register(env, SPR_SPRG2, "SPRG2",
716 SPR_NOACCESS, SPR_NOACCESS,
717 &spr_read_generic, &spr_write_generic,
718 0x00000000);
719 spr_register(env, SPR_SPRG3, "SPRG3",
720 SPR_NOACCESS, SPR_NOACCESS,
721 &spr_read_generic, &spr_write_generic,
722 0x00000000);
723}
724
725/* SPR common to all non-embedded PowerPC, including 601 */
726static void gen_spr_ne_601 (CPUPPCState *env)
727{
728 /* Exception processing */
David Gibsond67d40e2013-02-20 16:41:50 +0000729 spr_register_kvm(env, SPR_DSISR, "DSISR",
730 SPR_NOACCESS, SPR_NOACCESS,
731 &spr_read_generic, &spr_write_generic,
732 KVM_REG_PPC_DSISR, 0x00000000);
733 spr_register_kvm(env, SPR_DAR, "DAR",
734 SPR_NOACCESS, SPR_NOACCESS,
735 &spr_read_generic, &spr_write_generic,
736 KVM_REG_PPC_DAR, 0x00000000);
bellard3fc6c082005-07-02 20:59:34 +0000737 /* Timer */
738 spr_register(env, SPR_DECR, "DECR",
739 SPR_NOACCESS, SPR_NOACCESS,
740 &spr_read_decr, &spr_write_decr,
741 0x00000000);
742 /* Memory management */
743 spr_register(env, SPR_SDR1, "SDR1",
744 SPR_NOACCESS, SPR_NOACCESS,
David Gibsonbb593902011-04-01 15:15:15 +1100745 &spr_read_generic, &spr_write_sdr1,
bellard3fc6c082005-07-02 20:59:34 +0000746 0x00000000);
747}
748
749/* BATs 0-3 */
750static void gen_low_BATs (CPUPPCState *env)
751{
j_mayerf2e63a42007-10-07 15:43:50 +0000752#if !defined(CONFIG_USER_ONLY)
bellard3fc6c082005-07-02 20:59:34 +0000753 spr_register(env, SPR_IBAT0U, "IBAT0U",
754 SPR_NOACCESS, SPR_NOACCESS,
755 &spr_read_ibat, &spr_write_ibatu,
756 0x00000000);
757 spr_register(env, SPR_IBAT0L, "IBAT0L",
758 SPR_NOACCESS, SPR_NOACCESS,
759 &spr_read_ibat, &spr_write_ibatl,
760 0x00000000);
761 spr_register(env, SPR_IBAT1U, "IBAT1U",
762 SPR_NOACCESS, SPR_NOACCESS,
763 &spr_read_ibat, &spr_write_ibatu,
764 0x00000000);
765 spr_register(env, SPR_IBAT1L, "IBAT1L",
766 SPR_NOACCESS, SPR_NOACCESS,
767 &spr_read_ibat, &spr_write_ibatl,
768 0x00000000);
769 spr_register(env, SPR_IBAT2U, "IBAT2U",
770 SPR_NOACCESS, SPR_NOACCESS,
771 &spr_read_ibat, &spr_write_ibatu,
772 0x00000000);
773 spr_register(env, SPR_IBAT2L, "IBAT2L",
774 SPR_NOACCESS, SPR_NOACCESS,
775 &spr_read_ibat, &spr_write_ibatl,
776 0x00000000);
777 spr_register(env, SPR_IBAT3U, "IBAT3U",
778 SPR_NOACCESS, SPR_NOACCESS,
779 &spr_read_ibat, &spr_write_ibatu,
780 0x00000000);
781 spr_register(env, SPR_IBAT3L, "IBAT3L",
782 SPR_NOACCESS, SPR_NOACCESS,
783 &spr_read_ibat, &spr_write_ibatl,
784 0x00000000);
785 spr_register(env, SPR_DBAT0U, "DBAT0U",
786 SPR_NOACCESS, SPR_NOACCESS,
787 &spr_read_dbat, &spr_write_dbatu,
788 0x00000000);
789 spr_register(env, SPR_DBAT0L, "DBAT0L",
790 SPR_NOACCESS, SPR_NOACCESS,
791 &spr_read_dbat, &spr_write_dbatl,
792 0x00000000);
793 spr_register(env, SPR_DBAT1U, "DBAT1U",
794 SPR_NOACCESS, SPR_NOACCESS,
795 &spr_read_dbat, &spr_write_dbatu,
796 0x00000000);
797 spr_register(env, SPR_DBAT1L, "DBAT1L",
798 SPR_NOACCESS, SPR_NOACCESS,
799 &spr_read_dbat, &spr_write_dbatl,
800 0x00000000);
801 spr_register(env, SPR_DBAT2U, "DBAT2U",
802 SPR_NOACCESS, SPR_NOACCESS,
803 &spr_read_dbat, &spr_write_dbatu,
804 0x00000000);
805 spr_register(env, SPR_DBAT2L, "DBAT2L",
806 SPR_NOACCESS, SPR_NOACCESS,
807 &spr_read_dbat, &spr_write_dbatl,
808 0x00000000);
809 spr_register(env, SPR_DBAT3U, "DBAT3U",
810 SPR_NOACCESS, SPR_NOACCESS,
811 &spr_read_dbat, &spr_write_dbatu,
812 0x00000000);
813 spr_register(env, SPR_DBAT3L, "DBAT3L",
814 SPR_NOACCESS, SPR_NOACCESS,
815 &spr_read_dbat, &spr_write_dbatl,
816 0x00000000);
j_mayera750fc02007-09-26 23:54:22 +0000817 env->nb_BATs += 4;
j_mayerf2e63a42007-10-07 15:43:50 +0000818#endif
bellard3fc6c082005-07-02 20:59:34 +0000819}
820
821/* BATs 4-7 */
822static void gen_high_BATs (CPUPPCState *env)
823{
j_mayerf2e63a42007-10-07 15:43:50 +0000824#if !defined(CONFIG_USER_ONLY)
bellard3fc6c082005-07-02 20:59:34 +0000825 spr_register(env, SPR_IBAT4U, "IBAT4U",
826 SPR_NOACCESS, SPR_NOACCESS,
827 &spr_read_ibat_h, &spr_write_ibatu_h,
828 0x00000000);
829 spr_register(env, SPR_IBAT4L, "IBAT4L",
830 SPR_NOACCESS, SPR_NOACCESS,
831 &spr_read_ibat_h, &spr_write_ibatl_h,
832 0x00000000);
833 spr_register(env, SPR_IBAT5U, "IBAT5U",
834 SPR_NOACCESS, SPR_NOACCESS,
835 &spr_read_ibat_h, &spr_write_ibatu_h,
836 0x00000000);
837 spr_register(env, SPR_IBAT5L, "IBAT5L",
838 SPR_NOACCESS, SPR_NOACCESS,
839 &spr_read_ibat_h, &spr_write_ibatl_h,
840 0x00000000);
841 spr_register(env, SPR_IBAT6U, "IBAT6U",
842 SPR_NOACCESS, SPR_NOACCESS,
843 &spr_read_ibat_h, &spr_write_ibatu_h,
844 0x00000000);
845 spr_register(env, SPR_IBAT6L, "IBAT6L",
846 SPR_NOACCESS, SPR_NOACCESS,
847 &spr_read_ibat_h, &spr_write_ibatl_h,
848 0x00000000);
849 spr_register(env, SPR_IBAT7U, "IBAT7U",
850 SPR_NOACCESS, SPR_NOACCESS,
851 &spr_read_ibat_h, &spr_write_ibatu_h,
852 0x00000000);
853 spr_register(env, SPR_IBAT7L, "IBAT7L",
854 SPR_NOACCESS, SPR_NOACCESS,
855 &spr_read_ibat_h, &spr_write_ibatl_h,
856 0x00000000);
857 spr_register(env, SPR_DBAT4U, "DBAT4U",
858 SPR_NOACCESS, SPR_NOACCESS,
859 &spr_read_dbat_h, &spr_write_dbatu_h,
860 0x00000000);
861 spr_register(env, SPR_DBAT4L, "DBAT4L",
862 SPR_NOACCESS, SPR_NOACCESS,
863 &spr_read_dbat_h, &spr_write_dbatl_h,
864 0x00000000);
865 spr_register(env, SPR_DBAT5U, "DBAT5U",
866 SPR_NOACCESS, SPR_NOACCESS,
867 &spr_read_dbat_h, &spr_write_dbatu_h,
868 0x00000000);
869 spr_register(env, SPR_DBAT5L, "DBAT5L",
870 SPR_NOACCESS, SPR_NOACCESS,
871 &spr_read_dbat_h, &spr_write_dbatl_h,
872 0x00000000);
873 spr_register(env, SPR_DBAT6U, "DBAT6U",
874 SPR_NOACCESS, SPR_NOACCESS,
875 &spr_read_dbat_h, &spr_write_dbatu_h,
876 0x00000000);
877 spr_register(env, SPR_DBAT6L, "DBAT6L",
878 SPR_NOACCESS, SPR_NOACCESS,
879 &spr_read_dbat_h, &spr_write_dbatl_h,
880 0x00000000);
881 spr_register(env, SPR_DBAT7U, "DBAT7U",
882 SPR_NOACCESS, SPR_NOACCESS,
883 &spr_read_dbat_h, &spr_write_dbatu_h,
884 0x00000000);
885 spr_register(env, SPR_DBAT7L, "DBAT7L",
886 SPR_NOACCESS, SPR_NOACCESS,
887 &spr_read_dbat_h, &spr_write_dbatl_h,
888 0x00000000);
j_mayera750fc02007-09-26 23:54:22 +0000889 env->nb_BATs += 4;
j_mayerf2e63a42007-10-07 15:43:50 +0000890#endif
bellard3fc6c082005-07-02 20:59:34 +0000891}
892
893/* Generic PowerPC time base */
894static void gen_tbl (CPUPPCState *env)
895{
896 spr_register(env, SPR_VTBL, "TBL",
897 &spr_read_tbl, SPR_NOACCESS,
898 &spr_read_tbl, SPR_NOACCESS,
899 0x00000000);
900 spr_register(env, SPR_TBL, "TBL",
Dmitry Ilyevskyde6a1de2010-03-26 03:25:36 +0300901 &spr_read_tbl, SPR_NOACCESS,
902 &spr_read_tbl, &spr_write_tbl,
bellard3fc6c082005-07-02 20:59:34 +0000903 0x00000000);
904 spr_register(env, SPR_VTBU, "TBU",
905 &spr_read_tbu, SPR_NOACCESS,
906 &spr_read_tbu, SPR_NOACCESS,
907 0x00000000);
908 spr_register(env, SPR_TBU, "TBU",
Dmitry Ilyevskyde6a1de2010-03-26 03:25:36 +0300909 &spr_read_tbu, SPR_NOACCESS,
910 &spr_read_tbu, &spr_write_tbu,
bellard3fc6c082005-07-02 20:59:34 +0000911 0x00000000);
912}
913
j_mayer76a66252007-03-07 08:32:30 +0000914/* Softare table search registers */
915static void gen_6xx_7xx_soft_tlb (CPUPPCState *env, int nb_tlbs, int nb_ways)
916{
j_mayerf2e63a42007-10-07 15:43:50 +0000917#if !defined(CONFIG_USER_ONLY)
j_mayer76a66252007-03-07 08:32:30 +0000918 env->nb_tlb = nb_tlbs;
919 env->nb_ways = nb_ways;
920 env->id_tlbs = 1;
Alexander Graf1c53acc2011-06-17 01:00:28 +0200921 env->tlb_type = TLB_6XX;
j_mayer76a66252007-03-07 08:32:30 +0000922 spr_register(env, SPR_DMISS, "DMISS",
923 SPR_NOACCESS, SPR_NOACCESS,
924 &spr_read_generic, SPR_NOACCESS,
925 0x00000000);
926 spr_register(env, SPR_DCMP, "DCMP",
927 SPR_NOACCESS, SPR_NOACCESS,
928 &spr_read_generic, SPR_NOACCESS,
929 0x00000000);
930 spr_register(env, SPR_HASH1, "HASH1",
931 SPR_NOACCESS, SPR_NOACCESS,
932 &spr_read_generic, SPR_NOACCESS,
933 0x00000000);
934 spr_register(env, SPR_HASH2, "HASH2",
935 SPR_NOACCESS, SPR_NOACCESS,
936 &spr_read_generic, SPR_NOACCESS,
937 0x00000000);
938 spr_register(env, SPR_IMISS, "IMISS",
939 SPR_NOACCESS, SPR_NOACCESS,
940 &spr_read_generic, SPR_NOACCESS,
941 0x00000000);
942 spr_register(env, SPR_ICMP, "ICMP",
943 SPR_NOACCESS, SPR_NOACCESS,
944 &spr_read_generic, SPR_NOACCESS,
945 0x00000000);
946 spr_register(env, SPR_RPA, "RPA",
947 SPR_NOACCESS, SPR_NOACCESS,
948 &spr_read_generic, &spr_write_generic,
949 0x00000000);
j_mayerf2e63a42007-10-07 15:43:50 +0000950#endif
j_mayer76a66252007-03-07 08:32:30 +0000951}
952
953/* SPR common to MPC755 and G2 */
954static void gen_spr_G2_755 (CPUPPCState *env)
955{
956 /* SGPRs */
957 spr_register(env, SPR_SPRG4, "SPRG4",
958 SPR_NOACCESS, SPR_NOACCESS,
959 &spr_read_generic, &spr_write_generic,
960 0x00000000);
961 spr_register(env, SPR_SPRG5, "SPRG5",
962 SPR_NOACCESS, SPR_NOACCESS,
963 &spr_read_generic, &spr_write_generic,
964 0x00000000);
965 spr_register(env, SPR_SPRG6, "SPRG6",
966 SPR_NOACCESS, SPR_NOACCESS,
967 &spr_read_generic, &spr_write_generic,
968 0x00000000);
969 spr_register(env, SPR_SPRG7, "SPRG7",
970 SPR_NOACCESS, SPR_NOACCESS,
971 &spr_read_generic, &spr_write_generic,
972 0x00000000);
j_mayer76a66252007-03-07 08:32:30 +0000973}
974
bellard3fc6c082005-07-02 20:59:34 +0000975/* SPR common to all 7xx PowerPC implementations */
976static void gen_spr_7xx (CPUPPCState *env)
977{
978 /* Breakpoints */
979 /* XXX : not implemented */
David Gibsond67d40e2013-02-20 16:41:50 +0000980 spr_register_kvm(env, SPR_DABR, "DABR",
981 SPR_NOACCESS, SPR_NOACCESS,
982 &spr_read_generic, &spr_write_generic,
983 KVM_REG_PPC_DABR, 0x00000000);
bellard3fc6c082005-07-02 20:59:34 +0000984 /* XXX : not implemented */
985 spr_register(env, SPR_IABR, "IABR",
986 SPR_NOACCESS, SPR_NOACCESS,
987 &spr_read_generic, &spr_write_generic,
988 0x00000000);
989 /* Cache management */
990 /* XXX : not implemented */
991 spr_register(env, SPR_ICTC, "ICTC",
992 SPR_NOACCESS, SPR_NOACCESS,
993 &spr_read_generic, &spr_write_generic,
994 0x00000000);
995 /* Performance monitors */
996 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +1000997 spr_register(env, SPR_7XX_MMCR0, "MMCR0",
bellard3fc6c082005-07-02 20:59:34 +0000998 SPR_NOACCESS, SPR_NOACCESS,
999 &spr_read_generic, &spr_write_generic,
1000 0x00000000);
1001 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10001002 spr_register(env, SPR_7XX_MMCR1, "MMCR1",
bellard3fc6c082005-07-02 20:59:34 +00001003 SPR_NOACCESS, SPR_NOACCESS,
1004 &spr_read_generic, &spr_write_generic,
1005 0x00000000);
1006 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10001007 spr_register(env, SPR_7XX_PMC1, "PMC1",
bellard3fc6c082005-07-02 20:59:34 +00001008 SPR_NOACCESS, SPR_NOACCESS,
1009 &spr_read_generic, &spr_write_generic,
1010 0x00000000);
1011 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10001012 spr_register(env, SPR_7XX_PMC2, "PMC2",
bellard3fc6c082005-07-02 20:59:34 +00001013 SPR_NOACCESS, SPR_NOACCESS,
1014 &spr_read_generic, &spr_write_generic,
1015 0x00000000);
1016 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10001017 spr_register(env, SPR_7XX_PMC3, "PMC3",
bellard3fc6c082005-07-02 20:59:34 +00001018 SPR_NOACCESS, SPR_NOACCESS,
1019 &spr_read_generic, &spr_write_generic,
1020 0x00000000);
1021 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10001022 spr_register(env, SPR_7XX_PMC4, "PMC4",
bellard3fc6c082005-07-02 20:59:34 +00001023 SPR_NOACCESS, SPR_NOACCESS,
1024 &spr_read_generic, &spr_write_generic,
1025 0x00000000);
1026 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10001027 spr_register(env, SPR_7XX_SIAR, "SIAR",
bellard3fc6c082005-07-02 20:59:34 +00001028 SPR_NOACCESS, SPR_NOACCESS,
1029 &spr_read_generic, SPR_NOACCESS,
1030 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00001031 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10001032 spr_register(env, SPR_7XX_UMMCR0, "UMMCR0",
bellard3fc6c082005-07-02 20:59:34 +00001033 &spr_read_ureg, SPR_NOACCESS,
1034 &spr_read_ureg, SPR_NOACCESS,
1035 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00001036 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10001037 spr_register(env, SPR_7XX_UMMCR1, "UMMCR1",
bellard3fc6c082005-07-02 20:59:34 +00001038 &spr_read_ureg, SPR_NOACCESS,
1039 &spr_read_ureg, SPR_NOACCESS,
1040 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00001041 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10001042 spr_register(env, SPR_7XX_UPMC1, "UPMC1",
bellard3fc6c082005-07-02 20:59:34 +00001043 &spr_read_ureg, SPR_NOACCESS,
1044 &spr_read_ureg, SPR_NOACCESS,
1045 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00001046 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10001047 spr_register(env, SPR_7XX_UPMC2, "UPMC2",
bellard3fc6c082005-07-02 20:59:34 +00001048 &spr_read_ureg, SPR_NOACCESS,
1049 &spr_read_ureg, SPR_NOACCESS,
1050 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00001051 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10001052 spr_register(env, SPR_7XX_UPMC3, "UPMC3",
bellard3fc6c082005-07-02 20:59:34 +00001053 &spr_read_ureg, SPR_NOACCESS,
1054 &spr_read_ureg, SPR_NOACCESS,
1055 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00001056 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10001057 spr_register(env, SPR_7XX_UPMC4, "UPMC4",
bellard3fc6c082005-07-02 20:59:34 +00001058 &spr_read_ureg, SPR_NOACCESS,
1059 &spr_read_ureg, SPR_NOACCESS,
1060 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00001061 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10001062 spr_register(env, SPR_7XX_USIAR, "USIAR",
bellard3fc6c082005-07-02 20:59:34 +00001063 &spr_read_ureg, SPR_NOACCESS,
1064 &spr_read_ureg, SPR_NOACCESS,
1065 0x00000000);
j_mayera750fc02007-09-26 23:54:22 +00001066 /* External access control */
1067 /* XXX : not implemented */
1068 spr_register(env, SPR_EAR, "EAR",
1069 SPR_NOACCESS, SPR_NOACCESS,
1070 &spr_read_generic, &spr_write_generic,
1071 0x00000000);
1072}
1073
David Gibsonf80872e2013-03-12 00:31:47 +00001074#ifdef TARGET_PPC64
1075#ifndef CONFIG_USER_ONLY
Benjamin Herrenschmidt97eaf302016-03-21 13:52:37 +01001076static void spr_write_amr(DisasContext *ctx, int sprn, int gprn)
David Gibsonf80872e2013-03-12 00:31:47 +00001077{
1078 TCGv t0 = tcg_temp_new();
Benjamin Herrenschmidt97eaf302016-03-21 13:52:37 +01001079 TCGv t1 = tcg_temp_new();
1080 TCGv t2 = tcg_temp_new();
David Gibsonf80872e2013-03-12 00:31:47 +00001081
Benjamin Herrenschmidt97eaf302016-03-21 13:52:37 +01001082 /* Note, the HV=1 PR=0 case is handled earlier by simply using
1083 * spr_write_generic for HV mode in the SPR table
1084 */
1085
1086 /* Build insertion mask into t1 based on context */
1087 if (ctx->pr) {
1088 gen_load_spr(t1, SPR_UAMOR);
1089 } else {
1090 gen_load_spr(t1, SPR_AMOR);
1091 }
1092
1093 /* Mask new bits into t2 */
1094 tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]);
1095
1096 /* Load AMR and clear new bits in t0 */
1097 gen_load_spr(t0, SPR_AMR);
1098 tcg_gen_andc_tl(t0, t0, t1);
1099
1100 /* Or'in new bits and write it out */
1101 tcg_gen_or_tl(t0, t0, t2);
David Gibsonf80872e2013-03-12 00:31:47 +00001102 gen_store_spr(SPR_AMR, t0);
1103 spr_store_dump_spr(SPR_AMR);
Benjamin Herrenschmidt97eaf302016-03-21 13:52:37 +01001104
1105 tcg_temp_free(t0);
1106 tcg_temp_free(t1);
1107 tcg_temp_free(t2);
1108}
1109
1110static void spr_write_uamor(DisasContext *ctx, int sprn, int gprn)
1111{
1112 TCGv t0 = tcg_temp_new();
1113 TCGv t1 = tcg_temp_new();
1114 TCGv t2 = tcg_temp_new();
1115
1116 /* Note, the HV=1 case is handled earlier by simply using
1117 * spr_write_generic for HV mode in the SPR table
1118 */
1119
1120 /* Build insertion mask into t1 based on context */
1121 gen_load_spr(t1, SPR_AMOR);
1122
1123 /* Mask new bits into t2 */
1124 tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]);
1125
1126 /* Load AMR and clear new bits in t0 */
1127 gen_load_spr(t0, SPR_UAMOR);
1128 tcg_gen_andc_tl(t0, t0, t1);
1129
1130 /* Or'in new bits and write it out */
1131 tcg_gen_or_tl(t0, t0, t2);
1132 gen_store_spr(SPR_UAMOR, t0);
1133 spr_store_dump_spr(SPR_UAMOR);
1134
1135 tcg_temp_free(t0);
1136 tcg_temp_free(t1);
1137 tcg_temp_free(t2);
David Gibsonf80872e2013-03-12 00:31:47 +00001138}
Benjamin Herrenschmidta6eabb92016-03-21 13:52:38 +01001139
1140static void spr_write_iamr(DisasContext *ctx, int sprn, int gprn)
1141{
1142 TCGv t0 = tcg_temp_new();
1143 TCGv t1 = tcg_temp_new();
1144 TCGv t2 = tcg_temp_new();
1145
1146 /* Note, the HV=1 case is handled earlier by simply using
1147 * spr_write_generic for HV mode in the SPR table
1148 */
1149
1150 /* Build insertion mask into t1 based on context */
1151 gen_load_spr(t1, SPR_AMOR);
1152
1153 /* Mask new bits into t2 */
1154 tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]);
1155
1156 /* Load AMR and clear new bits in t0 */
1157 gen_load_spr(t0, SPR_IAMR);
1158 tcg_gen_andc_tl(t0, t0, t1);
1159
1160 /* Or'in new bits and write it out */
1161 tcg_gen_or_tl(t0, t0, t2);
1162 gen_store_spr(SPR_IAMR, t0);
1163 spr_store_dump_spr(SPR_IAMR);
1164
1165 tcg_temp_free(t0);
1166 tcg_temp_free(t1);
1167 tcg_temp_free(t2);
1168}
David Gibsonf80872e2013-03-12 00:31:47 +00001169#endif /* CONFIG_USER_ONLY */
1170
Benjamin Herrenschmidta6eabb92016-03-21 13:52:38 +01001171static void gen_spr_amr(CPUPPCState *env, bool has_iamr)
David Gibsonf80872e2013-03-12 00:31:47 +00001172{
1173#ifndef CONFIG_USER_ONLY
1174 /* Virtual Page Class Key protection */
1175 /* The AMR is accessible either via SPR 13 or SPR 29. 13 is
1176 * userspace accessible, 29 is privileged. So we only need to set
1177 * the kvm ONE_REG id on one of them, we use 29 */
1178 spr_register(env, SPR_UAMR, "UAMR",
Benjamin Herrenschmidt97eaf302016-03-21 13:52:37 +01001179 &spr_read_generic, &spr_write_amr,
1180 &spr_read_generic, &spr_write_amr,
David Gibsonf80872e2013-03-12 00:31:47 +00001181 0);
Benjamin Herrenschmidt97eaf302016-03-21 13:52:37 +01001182 spr_register_kvm_hv(env, SPR_AMR, "AMR",
David Gibsonf80872e2013-03-12 00:31:47 +00001183 SPR_NOACCESS, SPR_NOACCESS,
Benjamin Herrenschmidt97eaf302016-03-21 13:52:37 +01001184 &spr_read_generic, &spr_write_amr,
David Gibsonf80872e2013-03-12 00:31:47 +00001185 &spr_read_generic, &spr_write_generic,
Alexey Kardashevskiy0dc083f2014-01-06 16:36:39 +11001186 KVM_REG_PPC_AMR, 0);
Benjamin Herrenschmidt97eaf302016-03-21 13:52:37 +01001187 spr_register_kvm_hv(env, SPR_UAMOR, "UAMOR",
David Gibsonf80872e2013-03-12 00:31:47 +00001188 SPR_NOACCESS, SPR_NOACCESS,
Benjamin Herrenschmidt97eaf302016-03-21 13:52:37 +01001189 &spr_read_generic, &spr_write_uamor,
David Gibsonf80872e2013-03-12 00:31:47 +00001190 &spr_read_generic, &spr_write_generic,
1191 KVM_REG_PPC_UAMOR, 0);
Benjamin Herrenschmidtf401dd32016-03-21 13:52:33 +01001192 spr_register_hv(env, SPR_AMOR, "AMOR",
1193 SPR_NOACCESS, SPR_NOACCESS,
1194 SPR_NOACCESS, SPR_NOACCESS,
1195 &spr_read_generic, &spr_write_generic,
1196 0);
Benjamin Herrenschmidta6eabb92016-03-21 13:52:38 +01001197 if (has_iamr) {
1198 spr_register_kvm_hv(env, SPR_IAMR, "IAMR",
1199 SPR_NOACCESS, SPR_NOACCESS,
1200 &spr_read_generic, &spr_write_iamr,
1201 &spr_read_generic, &spr_write_generic,
1202 KVM_REG_PPC_IAMR, 0);
1203 }
David Gibsonf80872e2013-03-12 00:31:47 +00001204#endif /* !CONFIG_USER_ONLY */
1205}
1206#endif /* TARGET_PPC64 */
1207
Benjamin Herrenschmidtf0278902016-06-20 11:27:14 +10001208#ifndef CONFIG_USER_ONLY
1209static void spr_read_thrm(DisasContext *ctx, int gprn, int sprn)
1210{
1211 gen_helper_fixup_thrm(cpu_env);
1212 gen_load_spr(cpu_gpr[gprn], sprn);
1213 spr_load_dump_spr(sprn);
1214}
1215#endif /* !CONFIG_USER_ONLY */
1216
j_mayera750fc02007-09-26 23:54:22 +00001217static void gen_spr_thrm (CPUPPCState *env)
1218{
bellard3fc6c082005-07-02 20:59:34 +00001219 /* Thermal management */
1220 /* XXX : not implemented */
1221 spr_register(env, SPR_THRM1, "THRM1",
1222 SPR_NOACCESS, SPR_NOACCESS,
Benjamin Herrenschmidtf0278902016-06-20 11:27:14 +10001223 &spr_read_thrm, &spr_write_generic,
bellard3fc6c082005-07-02 20:59:34 +00001224 0x00000000);
1225 /* XXX : not implemented */
1226 spr_register(env, SPR_THRM2, "THRM2",
1227 SPR_NOACCESS, SPR_NOACCESS,
Benjamin Herrenschmidtf0278902016-06-20 11:27:14 +10001228 &spr_read_thrm, &spr_write_generic,
bellard3fc6c082005-07-02 20:59:34 +00001229 0x00000000);
1230 /* XXX : not implemented */
1231 spr_register(env, SPR_THRM3, "THRM3",
1232 SPR_NOACCESS, SPR_NOACCESS,
Benjamin Herrenschmidtf0278902016-06-20 11:27:14 +10001233 &spr_read_thrm, &spr_write_generic,
bellard3fc6c082005-07-02 20:59:34 +00001234 0x00000000);
bellard3fc6c082005-07-02 20:59:34 +00001235}
1236
1237/* SPR specific to PowerPC 604 implementation */
1238static void gen_spr_604 (CPUPPCState *env)
1239{
1240 /* Processor identification */
1241 spr_register(env, SPR_PIR, "PIR",
1242 SPR_NOACCESS, SPR_NOACCESS,
1243 &spr_read_generic, &spr_write_pir,
1244 0x00000000);
1245 /* Breakpoints */
1246 /* XXX : not implemented */
1247 spr_register(env, SPR_IABR, "IABR",
1248 SPR_NOACCESS, SPR_NOACCESS,
1249 &spr_read_generic, &spr_write_generic,
1250 0x00000000);
1251 /* XXX : not implemented */
David Gibsond67d40e2013-02-20 16:41:50 +00001252 spr_register_kvm(env, SPR_DABR, "DABR",
1253 SPR_NOACCESS, SPR_NOACCESS,
1254 &spr_read_generic, &spr_write_generic,
1255 KVM_REG_PPC_DABR, 0x00000000);
bellard3fc6c082005-07-02 20:59:34 +00001256 /* Performance counters */
1257 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10001258 spr_register(env, SPR_7XX_MMCR0, "MMCR0",
bellard3fc6c082005-07-02 20:59:34 +00001259 SPR_NOACCESS, SPR_NOACCESS,
1260 &spr_read_generic, &spr_write_generic,
1261 0x00000000);
1262 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10001263 spr_register(env, SPR_7XX_PMC1, "PMC1",
bellard3fc6c082005-07-02 20:59:34 +00001264 SPR_NOACCESS, SPR_NOACCESS,
1265 &spr_read_generic, &spr_write_generic,
1266 0x00000000);
1267 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10001268 spr_register(env, SPR_7XX_PMC2, "PMC2",
bellard3fc6c082005-07-02 20:59:34 +00001269 SPR_NOACCESS, SPR_NOACCESS,
1270 &spr_read_generic, &spr_write_generic,
1271 0x00000000);
1272 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10001273 spr_register(env, SPR_7XX_SIAR, "SIAR",
bellard3fc6c082005-07-02 20:59:34 +00001274 SPR_NOACCESS, SPR_NOACCESS,
1275 &spr_read_generic, SPR_NOACCESS,
1276 0x00000000);
1277 /* XXX : not implemented */
1278 spr_register(env, SPR_SDA, "SDA",
1279 SPR_NOACCESS, SPR_NOACCESS,
1280 &spr_read_generic, SPR_NOACCESS,
1281 0x00000000);
1282 /* External access control */
1283 /* XXX : not implemented */
1284 spr_register(env, SPR_EAR, "EAR",
1285 SPR_NOACCESS, SPR_NOACCESS,
1286 &spr_read_generic, &spr_write_generic,
1287 0x00000000);
1288}
1289
j_mayer76a66252007-03-07 08:32:30 +00001290/* SPR specific to PowerPC 603 implementation */
1291static void gen_spr_603 (CPUPPCState *env)
1292{
1293 /* External access control */
1294 /* XXX : not implemented */
1295 spr_register(env, SPR_EAR, "EAR",
1296 SPR_NOACCESS, SPR_NOACCESS,
1297 &spr_read_generic, &spr_write_generic,
1298 0x00000000);
Fabien Chouteau2bc17322013-04-03 04:03:38 +00001299 /* Breakpoints */
1300 /* XXX : not implemented */
1301 spr_register(env, SPR_IABR, "IABR",
1302 SPR_NOACCESS, SPR_NOACCESS,
1303 &spr_read_generic, &spr_write_generic,
1304 0x00000000);
1305
j_mayer76a66252007-03-07 08:32:30 +00001306}
1307
1308/* SPR specific to PowerPC G2 implementation */
1309static void gen_spr_G2 (CPUPPCState *env)
1310{
1311 /* Memory base address */
1312 /* MBAR */
j_mayer578bb252007-10-01 04:48:45 +00001313 /* XXX : not implemented */
j_mayer76a66252007-03-07 08:32:30 +00001314 spr_register(env, SPR_MBAR, "MBAR",
1315 SPR_NOACCESS, SPR_NOACCESS,
1316 &spr_read_generic, &spr_write_generic,
1317 0x00000000);
j_mayer76a66252007-03-07 08:32:30 +00001318 /* Exception processing */
j_mayer363be492007-03-30 10:07:33 +00001319 spr_register(env, SPR_BOOKE_CSRR0, "CSRR0",
j_mayer76a66252007-03-07 08:32:30 +00001320 SPR_NOACCESS, SPR_NOACCESS,
1321 &spr_read_generic, &spr_write_generic,
1322 0x00000000);
j_mayer363be492007-03-30 10:07:33 +00001323 spr_register(env, SPR_BOOKE_CSRR1, "CSRR1",
j_mayer76a66252007-03-07 08:32:30 +00001324 SPR_NOACCESS, SPR_NOACCESS,
1325 &spr_read_generic, &spr_write_generic,
1326 0x00000000);
1327 /* Breakpoints */
1328 /* XXX : not implemented */
1329 spr_register(env, SPR_DABR, "DABR",
1330 SPR_NOACCESS, SPR_NOACCESS,
1331 &spr_read_generic, &spr_write_generic,
1332 0x00000000);
1333 /* XXX : not implemented */
1334 spr_register(env, SPR_DABR2, "DABR2",
1335 SPR_NOACCESS, SPR_NOACCESS,
1336 &spr_read_generic, &spr_write_generic,
1337 0x00000000);
1338 /* XXX : not implemented */
1339 spr_register(env, SPR_IABR, "IABR",
1340 SPR_NOACCESS, SPR_NOACCESS,
1341 &spr_read_generic, &spr_write_generic,
1342 0x00000000);
1343 /* XXX : not implemented */
1344 spr_register(env, SPR_IABR2, "IABR2",
1345 SPR_NOACCESS, SPR_NOACCESS,
1346 &spr_read_generic, &spr_write_generic,
1347 0x00000000);
1348 /* XXX : not implemented */
1349 spr_register(env, SPR_IBCR, "IBCR",
1350 SPR_NOACCESS, SPR_NOACCESS,
1351 &spr_read_generic, &spr_write_generic,
1352 0x00000000);
1353 /* XXX : not implemented */
1354 spr_register(env, SPR_DBCR, "DBCR",
1355 SPR_NOACCESS, SPR_NOACCESS,
1356 &spr_read_generic, &spr_write_generic,
1357 0x00000000);
1358}
1359
1360/* SPR specific to PowerPC 602 implementation */
1361static void gen_spr_602 (CPUPPCState *env)
1362{
1363 /* ESA registers */
1364 /* XXX : not implemented */
1365 spr_register(env, SPR_SER, "SER",
1366 SPR_NOACCESS, SPR_NOACCESS,
1367 &spr_read_generic, &spr_write_generic,
1368 0x00000000);
1369 /* XXX : not implemented */
1370 spr_register(env, SPR_SEBR, "SEBR",
1371 SPR_NOACCESS, SPR_NOACCESS,
1372 &spr_read_generic, &spr_write_generic,
1373 0x00000000);
1374 /* XXX : not implemented */
j_mayera750fc02007-09-26 23:54:22 +00001375 spr_register(env, SPR_ESASRR, "ESASRR",
j_mayer76a66252007-03-07 08:32:30 +00001376 SPR_NOACCESS, SPR_NOACCESS,
1377 &spr_read_generic, &spr_write_generic,
1378 0x00000000);
1379 /* Floating point status */
1380 /* XXX : not implemented */
1381 spr_register(env, SPR_SP, "SP",
1382 SPR_NOACCESS, SPR_NOACCESS,
1383 &spr_read_generic, &spr_write_generic,
1384 0x00000000);
1385 /* XXX : not implemented */
1386 spr_register(env, SPR_LT, "LT",
1387 SPR_NOACCESS, SPR_NOACCESS,
1388 &spr_read_generic, &spr_write_generic,
1389 0x00000000);
1390 /* Watchdog timer */
1391 /* XXX : not implemented */
1392 spr_register(env, SPR_TCR, "TCR",
1393 SPR_NOACCESS, SPR_NOACCESS,
1394 &spr_read_generic, &spr_write_generic,
1395 0x00000000);
1396 /* Interrupt base */
1397 spr_register(env, SPR_IBR, "IBR",
1398 SPR_NOACCESS, SPR_NOACCESS,
1399 &spr_read_generic, &spr_write_generic,
1400 0x00000000);
j_mayera750fc02007-09-26 23:54:22 +00001401 /* XXX : not implemented */
1402 spr_register(env, SPR_IABR, "IABR",
1403 SPR_NOACCESS, SPR_NOACCESS,
1404 &spr_read_generic, &spr_write_generic,
1405 0x00000000);
j_mayer76a66252007-03-07 08:32:30 +00001406}
1407
1408/* SPR specific to PowerPC 601 implementation */
1409static void gen_spr_601 (CPUPPCState *env)
1410{
1411 /* Multiplication/division register */
1412 /* MQ */
1413 spr_register(env, SPR_MQ, "MQ",
1414 &spr_read_generic, &spr_write_generic,
1415 &spr_read_generic, &spr_write_generic,
1416 0x00000000);
1417 /* RTC registers */
1418 spr_register(env, SPR_601_RTCU, "RTCU",
1419 SPR_NOACCESS, SPR_NOACCESS,
1420 SPR_NOACCESS, &spr_write_601_rtcu,
1421 0x00000000);
1422 spr_register(env, SPR_601_VRTCU, "RTCU",
1423 &spr_read_601_rtcu, SPR_NOACCESS,
1424 &spr_read_601_rtcu, SPR_NOACCESS,
1425 0x00000000);
1426 spr_register(env, SPR_601_RTCL, "RTCL",
1427 SPR_NOACCESS, SPR_NOACCESS,
1428 SPR_NOACCESS, &spr_write_601_rtcl,
1429 0x00000000);
1430 spr_register(env, SPR_601_VRTCL, "RTCL",
1431 &spr_read_601_rtcl, SPR_NOACCESS,
1432 &spr_read_601_rtcl, SPR_NOACCESS,
1433 0x00000000);
1434 /* Timer */
1435#if 0 /* ? */
1436 spr_register(env, SPR_601_UDECR, "UDECR",
1437 &spr_read_decr, SPR_NOACCESS,
1438 &spr_read_decr, SPR_NOACCESS,
1439 0x00000000);
1440#endif
1441 /* External access control */
1442 /* XXX : not implemented */
1443 spr_register(env, SPR_EAR, "EAR",
1444 SPR_NOACCESS, SPR_NOACCESS,
1445 &spr_read_generic, &spr_write_generic,
1446 0x00000000);
1447 /* Memory management */
j_mayerf2e63a42007-10-07 15:43:50 +00001448#if !defined(CONFIG_USER_ONLY)
j_mayer76a66252007-03-07 08:32:30 +00001449 spr_register(env, SPR_IBAT0U, "IBAT0U",
1450 SPR_NOACCESS, SPR_NOACCESS,
1451 &spr_read_601_ubat, &spr_write_601_ubatu,
1452 0x00000000);
1453 spr_register(env, SPR_IBAT0L, "IBAT0L",
1454 SPR_NOACCESS, SPR_NOACCESS,
1455 &spr_read_601_ubat, &spr_write_601_ubatl,
1456 0x00000000);
1457 spr_register(env, SPR_IBAT1U, "IBAT1U",
1458 SPR_NOACCESS, SPR_NOACCESS,
1459 &spr_read_601_ubat, &spr_write_601_ubatu,
1460 0x00000000);
1461 spr_register(env, SPR_IBAT1L, "IBAT1L",
1462 SPR_NOACCESS, SPR_NOACCESS,
1463 &spr_read_601_ubat, &spr_write_601_ubatl,
1464 0x00000000);
1465 spr_register(env, SPR_IBAT2U, "IBAT2U",
1466 SPR_NOACCESS, SPR_NOACCESS,
1467 &spr_read_601_ubat, &spr_write_601_ubatu,
1468 0x00000000);
1469 spr_register(env, SPR_IBAT2L, "IBAT2L",
1470 SPR_NOACCESS, SPR_NOACCESS,
1471 &spr_read_601_ubat, &spr_write_601_ubatl,
1472 0x00000000);
1473 spr_register(env, SPR_IBAT3U, "IBAT3U",
1474 SPR_NOACCESS, SPR_NOACCESS,
1475 &spr_read_601_ubat, &spr_write_601_ubatu,
1476 0x00000000);
1477 spr_register(env, SPR_IBAT3L, "IBAT3L",
1478 SPR_NOACCESS, SPR_NOACCESS,
1479 &spr_read_601_ubat, &spr_write_601_ubatl,
1480 0x00000000);
j_mayera750fc02007-09-26 23:54:22 +00001481 env->nb_BATs = 4;
j_mayerf2e63a42007-10-07 15:43:50 +00001482#endif
j_mayer76a66252007-03-07 08:32:30 +00001483}
1484
j_mayera750fc02007-09-26 23:54:22 +00001485static void gen_spr_74xx (CPUPPCState *env)
1486{
1487 /* Processor identification */
1488 spr_register(env, SPR_PIR, "PIR",
1489 SPR_NOACCESS, SPR_NOACCESS,
1490 &spr_read_generic, &spr_write_pir,
1491 0x00000000);
1492 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10001493 spr_register(env, SPR_74XX_MMCR2, "MMCR2",
j_mayera750fc02007-09-26 23:54:22 +00001494 SPR_NOACCESS, SPR_NOACCESS,
1495 &spr_read_generic, &spr_write_generic,
1496 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00001497 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10001498 spr_register(env, SPR_74XX_UMMCR2, "UMMCR2",
j_mayera750fc02007-09-26 23:54:22 +00001499 &spr_read_ureg, SPR_NOACCESS,
1500 &spr_read_ureg, SPR_NOACCESS,
1501 0x00000000);
1502 /* XXX: not implemented */
1503 spr_register(env, SPR_BAMR, "BAMR",
1504 SPR_NOACCESS, SPR_NOACCESS,
1505 &spr_read_generic, &spr_write_generic,
1506 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00001507 /* XXX : not implemented */
j_mayera750fc02007-09-26 23:54:22 +00001508 spr_register(env, SPR_MSSCR0, "MSSCR0",
1509 SPR_NOACCESS, SPR_NOACCESS,
1510 &spr_read_generic, &spr_write_generic,
1511 0x00000000);
1512 /* Hardware implementation registers */
1513 /* XXX : not implemented */
1514 spr_register(env, SPR_HID0, "HID0",
1515 SPR_NOACCESS, SPR_NOACCESS,
1516 &spr_read_generic, &spr_write_generic,
1517 0x00000000);
1518 /* XXX : not implemented */
1519 spr_register(env, SPR_HID1, "HID1",
1520 SPR_NOACCESS, SPR_NOACCESS,
1521 &spr_read_generic, &spr_write_generic,
1522 0x00000000);
1523 /* Altivec */
1524 spr_register(env, SPR_VRSAVE, "VRSAVE",
1525 &spr_read_generic, &spr_write_generic,
1526 &spr_read_generic, &spr_write_generic,
1527 0x00000000);
j_mayerbd928eb2007-11-21 13:08:23 +00001528 /* XXX : not implemented */
1529 spr_register(env, SPR_L2CR, "L2CR",
1530 SPR_NOACCESS, SPR_NOACCESS,
Alexander Graf9633fcc2013-09-25 15:41:12 +02001531 &spr_read_generic, spr_access_nop,
j_mayerbd928eb2007-11-21 13:08:23 +00001532 0x00000000);
aurel32cf8358c2009-02-03 19:55:59 +00001533 /* Not strictly an SPR */
1534 vscr_init(env, 0x00010000);
j_mayera750fc02007-09-26 23:54:22 +00001535}
1536
j_mayera750fc02007-09-26 23:54:22 +00001537static void gen_l3_ctrl (CPUPPCState *env)
1538{
1539 /* L3CR */
1540 /* XXX : not implemented */
1541 spr_register(env, SPR_L3CR, "L3CR",
1542 SPR_NOACCESS, SPR_NOACCESS,
1543 &spr_read_generic, &spr_write_generic,
1544 0x00000000);
1545 /* L3ITCR0 */
j_mayer578bb252007-10-01 04:48:45 +00001546 /* XXX : not implemented */
j_mayera750fc02007-09-26 23:54:22 +00001547 spr_register(env, SPR_L3ITCR0, "L3ITCR0",
1548 SPR_NOACCESS, SPR_NOACCESS,
1549 &spr_read_generic, &spr_write_generic,
1550 0x00000000);
j_mayera750fc02007-09-26 23:54:22 +00001551 /* L3PM */
j_mayer578bb252007-10-01 04:48:45 +00001552 /* XXX : not implemented */
j_mayera750fc02007-09-26 23:54:22 +00001553 spr_register(env, SPR_L3PM, "L3PM",
1554 SPR_NOACCESS, SPR_NOACCESS,
1555 &spr_read_generic, &spr_write_generic,
1556 0x00000000);
1557}
j_mayera750fc02007-09-26 23:54:22 +00001558
j_mayer578bb252007-10-01 04:48:45 +00001559static void gen_74xx_soft_tlb (CPUPPCState *env, int nb_tlbs, int nb_ways)
j_mayera750fc02007-09-26 23:54:22 +00001560{
j_mayerf2e63a42007-10-07 15:43:50 +00001561#if !defined(CONFIG_USER_ONLY)
j_mayer578bb252007-10-01 04:48:45 +00001562 env->nb_tlb = nb_tlbs;
1563 env->nb_ways = nb_ways;
1564 env->id_tlbs = 1;
Alexander Graf1c53acc2011-06-17 01:00:28 +02001565 env->tlb_type = TLB_6XX;
j_mayer578bb252007-10-01 04:48:45 +00001566 /* XXX : not implemented */
j_mayera750fc02007-09-26 23:54:22 +00001567 spr_register(env, SPR_PTEHI, "PTEHI",
1568 SPR_NOACCESS, SPR_NOACCESS,
1569 &spr_read_generic, &spr_write_generic,
1570 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00001571 /* XXX : not implemented */
j_mayera750fc02007-09-26 23:54:22 +00001572 spr_register(env, SPR_PTELO, "PTELO",
1573 SPR_NOACCESS, SPR_NOACCESS,
1574 &spr_read_generic, &spr_write_generic,
1575 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00001576 /* XXX : not implemented */
j_mayera750fc02007-09-26 23:54:22 +00001577 spr_register(env, SPR_TLBMISS, "TLBMISS",
1578 SPR_NOACCESS, SPR_NOACCESS,
1579 &spr_read_generic, &spr_write_generic,
1580 0x00000000);
j_mayerf2e63a42007-10-07 15:43:50 +00001581#endif
j_mayera750fc02007-09-26 23:54:22 +00001582}
j_mayera750fc02007-09-26 23:54:22 +00001583
Alexander Graf01662f32011-04-30 23:34:58 +02001584#if !defined(CONFIG_USER_ONLY)
Paolo Bonzini69b058c2014-11-26 13:39:48 +03001585static void spr_write_e500_l1csr0 (DisasContext *ctx, int sprn, int gprn)
Alexander Graf01662f32011-04-30 23:34:58 +02001586{
1587 TCGv t0 = tcg_temp_new();
1588
Alexander Grafea712582014-01-19 17:49:11 +01001589 tcg_gen_andi_tl(t0, cpu_gpr[gprn], L1CSR0_DCE | L1CSR0_CPE);
1590 gen_store_spr(sprn, t0);
1591 tcg_temp_free(t0);
1592}
1593
Paolo Bonzini69b058c2014-11-26 13:39:48 +03001594static void spr_write_e500_l1csr1(DisasContext *ctx, int sprn, int gprn)
Alexander Grafea712582014-01-19 17:49:11 +01001595{
1596 TCGv t0 = tcg_temp_new();
1597
1598 tcg_gen_andi_tl(t0, cpu_gpr[gprn], L1CSR1_ICE | L1CSR1_CPE);
Alexander Graf01662f32011-04-30 23:34:58 +02001599 gen_store_spr(sprn, t0);
1600 tcg_temp_free(t0);
1601}
1602
Paolo Bonzini69b058c2014-11-26 13:39:48 +03001603static void spr_write_booke206_mmucsr0 (DisasContext *ctx, int sprn, int gprn)
Alexander Graf01662f32011-04-30 23:34:58 +02001604{
Alex Zuepkea721d392014-05-28 19:25:36 +02001605 gen_helper_booke206_tlbflush(cpu_env, cpu_gpr[gprn]);
Alexander Graf01662f32011-04-30 23:34:58 +02001606}
1607
Paolo Bonzini69b058c2014-11-26 13:39:48 +03001608static void spr_write_booke_pid (DisasContext *ctx, int sprn, int gprn)
Alexander Graf01662f32011-04-30 23:34:58 +02001609{
Stefan Weil1ff78542011-05-20 22:30:19 +02001610 TCGv_i32 t0 = tcg_const_i32(sprn);
Blue Swirlc6c7cf02012-05-30 04:23:31 +00001611 gen_helper_booke_setpid(cpu_env, t0, cpu_gpr[gprn]);
Stefan Weil1ff78542011-05-20 22:30:19 +02001612 tcg_temp_free_i32(t0);
Alexander Graf01662f32011-04-30 23:34:58 +02001613}
1614#endif
1615
j_mayer80d11f42007-11-17 23:02:20 +00001616static void gen_spr_usprgh (CPUPPCState *env)
j_mayer76a66252007-03-07 08:32:30 +00001617{
j_mayer80d11f42007-11-17 23:02:20 +00001618 spr_register(env, SPR_USPRG4, "USPRG4",
1619 &spr_read_ureg, SPR_NOACCESS,
1620 &spr_read_ureg, SPR_NOACCESS,
j_mayer76a66252007-03-07 08:32:30 +00001621 0x00000000);
j_mayer80d11f42007-11-17 23:02:20 +00001622 spr_register(env, SPR_USPRG5, "USPRG5",
1623 &spr_read_ureg, SPR_NOACCESS,
1624 &spr_read_ureg, SPR_NOACCESS,
1625 0x00000000);
1626 spr_register(env, SPR_USPRG6, "USPRG6",
1627 &spr_read_ureg, SPR_NOACCESS,
1628 &spr_read_ureg, SPR_NOACCESS,
1629 0x00000000);
1630 spr_register(env, SPR_USPRG7, "USPRG7",
1631 &spr_read_ureg, SPR_NOACCESS,
1632 &spr_read_ureg, SPR_NOACCESS,
1633 0x00000000);
1634}
1635
1636/* PowerPC BookE SPR */
1637static void gen_spr_BookE (CPUPPCState *env, uint64_t ivor_mask)
1638{
blueswir1b55266b2008-09-20 08:07:15 +00001639 const char *ivor_names[64] = {
j_mayer80d11f42007-11-17 23:02:20 +00001640 "IVOR0", "IVOR1", "IVOR2", "IVOR3",
1641 "IVOR4", "IVOR5", "IVOR6", "IVOR7",
1642 "IVOR8", "IVOR9", "IVOR10", "IVOR11",
1643 "IVOR12", "IVOR13", "IVOR14", "IVOR15",
1644 "IVOR16", "IVOR17", "IVOR18", "IVOR19",
1645 "IVOR20", "IVOR21", "IVOR22", "IVOR23",
1646 "IVOR24", "IVOR25", "IVOR26", "IVOR27",
1647 "IVOR28", "IVOR29", "IVOR30", "IVOR31",
1648 "IVOR32", "IVOR33", "IVOR34", "IVOR35",
1649 "IVOR36", "IVOR37", "IVOR38", "IVOR39",
1650 "IVOR40", "IVOR41", "IVOR42", "IVOR43",
1651 "IVOR44", "IVOR45", "IVOR46", "IVOR47",
1652 "IVOR48", "IVOR49", "IVOR50", "IVOR51",
1653 "IVOR52", "IVOR53", "IVOR54", "IVOR55",
1654 "IVOR56", "IVOR57", "IVOR58", "IVOR59",
1655 "IVOR60", "IVOR61", "IVOR62", "IVOR63",
1656 };
1657#define SPR_BOOKE_IVORxx (-1)
1658 int ivor_sprn[64] = {
1659 SPR_BOOKE_IVOR0, SPR_BOOKE_IVOR1, SPR_BOOKE_IVOR2, SPR_BOOKE_IVOR3,
1660 SPR_BOOKE_IVOR4, SPR_BOOKE_IVOR5, SPR_BOOKE_IVOR6, SPR_BOOKE_IVOR7,
1661 SPR_BOOKE_IVOR8, SPR_BOOKE_IVOR9, SPR_BOOKE_IVOR10, SPR_BOOKE_IVOR11,
1662 SPR_BOOKE_IVOR12, SPR_BOOKE_IVOR13, SPR_BOOKE_IVOR14, SPR_BOOKE_IVOR15,
1663 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1664 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1665 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1666 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1667 SPR_BOOKE_IVOR32, SPR_BOOKE_IVOR33, SPR_BOOKE_IVOR34, SPR_BOOKE_IVOR35,
Alexander Grafe9205252012-01-19 19:31:51 +01001668 SPR_BOOKE_IVOR36, SPR_BOOKE_IVOR37, SPR_BOOKE_IVOR38, SPR_BOOKE_IVOR39,
1669 SPR_BOOKE_IVOR40, SPR_BOOKE_IVOR41, SPR_BOOKE_IVOR42, SPR_BOOKE_IVORxx,
j_mayer80d11f42007-11-17 23:02:20 +00001670 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1671 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1672 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1673 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1674 SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
1675 };
1676 int i;
1677
j_mayer76a66252007-03-07 08:32:30 +00001678 /* Interrupt processing */
j_mayer363be492007-03-30 10:07:33 +00001679 spr_register(env, SPR_BOOKE_CSRR0, "CSRR0",
j_mayer76a66252007-03-07 08:32:30 +00001680 SPR_NOACCESS, SPR_NOACCESS,
1681 &spr_read_generic, &spr_write_generic,
1682 0x00000000);
j_mayer363be492007-03-30 10:07:33 +00001683 spr_register(env, SPR_BOOKE_CSRR1, "CSRR1",
1684 SPR_NOACCESS, SPR_NOACCESS,
1685 &spr_read_generic, &spr_write_generic,
1686 0x00000000);
j_mayer76a66252007-03-07 08:32:30 +00001687 /* Debug */
1688 /* XXX : not implemented */
1689 spr_register(env, SPR_BOOKE_IAC1, "IAC1",
1690 SPR_NOACCESS, SPR_NOACCESS,
1691 &spr_read_generic, &spr_write_generic,
1692 0x00000000);
1693 /* XXX : not implemented */
1694 spr_register(env, SPR_BOOKE_IAC2, "IAC2",
1695 SPR_NOACCESS, SPR_NOACCESS,
1696 &spr_read_generic, &spr_write_generic,
1697 0x00000000);
1698 /* XXX : not implemented */
j_mayer76a66252007-03-07 08:32:30 +00001699 spr_register(env, SPR_BOOKE_DAC1, "DAC1",
1700 SPR_NOACCESS, SPR_NOACCESS,
1701 &spr_read_generic, &spr_write_generic,
1702 0x00000000);
1703 /* XXX : not implemented */
1704 spr_register(env, SPR_BOOKE_DAC2, "DAC2",
1705 SPR_NOACCESS, SPR_NOACCESS,
1706 &spr_read_generic, &spr_write_generic,
1707 0x00000000);
1708 /* XXX : not implemented */
j_mayer76a66252007-03-07 08:32:30 +00001709 spr_register(env, SPR_BOOKE_DBCR0, "DBCR0",
1710 SPR_NOACCESS, SPR_NOACCESS,
Alexander Grafe598a9c2012-10-06 22:54:25 +02001711 &spr_read_generic, &spr_write_40x_dbcr0,
j_mayer76a66252007-03-07 08:32:30 +00001712 0x00000000);
1713 /* XXX : not implemented */
1714 spr_register(env, SPR_BOOKE_DBCR1, "DBCR1",
1715 SPR_NOACCESS, SPR_NOACCESS,
1716 &spr_read_generic, &spr_write_generic,
1717 0x00000000);
1718 /* XXX : not implemented */
1719 spr_register(env, SPR_BOOKE_DBCR2, "DBCR2",
1720 SPR_NOACCESS, SPR_NOACCESS,
1721 &spr_read_generic, &spr_write_generic,
1722 0x00000000);
1723 /* XXX : not implemented */
1724 spr_register(env, SPR_BOOKE_DBSR, "DBSR",
1725 SPR_NOACCESS, SPR_NOACCESS,
j_mayer8ecc7912007-04-16 20:09:45 +00001726 &spr_read_generic, &spr_write_clear,
j_mayer76a66252007-03-07 08:32:30 +00001727 0x00000000);
1728 spr_register(env, SPR_BOOKE_DEAR, "DEAR",
1729 SPR_NOACCESS, SPR_NOACCESS,
1730 &spr_read_generic, &spr_write_generic,
1731 0x00000000);
1732 spr_register(env, SPR_BOOKE_ESR, "ESR",
1733 SPR_NOACCESS, SPR_NOACCESS,
1734 &spr_read_generic, &spr_write_generic,
1735 0x00000000);
j_mayer363be492007-03-30 10:07:33 +00001736 spr_register(env, SPR_BOOKE_IVPR, "IVPR",
1737 SPR_NOACCESS, SPR_NOACCESS,
j_mayer6f5d4272007-10-01 01:32:49 +00001738 &spr_read_generic, &spr_write_excp_prefix,
j_mayer363be492007-03-30 10:07:33 +00001739 0x00000000);
1740 /* Exception vectors */
j_mayer80d11f42007-11-17 23:02:20 +00001741 for (i = 0; i < 64; i++) {
1742 if (ivor_mask & (1ULL << i)) {
1743 if (ivor_sprn[i] == SPR_BOOKE_IVORxx) {
1744 fprintf(stderr, "ERROR: IVOR %d SPR is not defined\n", i);
1745 exit(1);
1746 }
1747 spr_register(env, ivor_sprn[i], ivor_names[i],
1748 SPR_NOACCESS, SPR_NOACCESS,
1749 &spr_read_generic, &spr_write_excp_vector,
1750 0x00000000);
1751 }
1752 }
j_mayer76a66252007-03-07 08:32:30 +00001753 spr_register(env, SPR_BOOKE_PID, "PID",
1754 SPR_NOACCESS, SPR_NOACCESS,
Alexander Graf01662f32011-04-30 23:34:58 +02001755 &spr_read_generic, &spr_write_booke_pid,
j_mayer76a66252007-03-07 08:32:30 +00001756 0x00000000);
1757 spr_register(env, SPR_BOOKE_TCR, "TCR",
1758 SPR_NOACCESS, SPR_NOACCESS,
1759 &spr_read_generic, &spr_write_booke_tcr,
1760 0x00000000);
1761 spr_register(env, SPR_BOOKE_TSR, "TSR",
1762 SPR_NOACCESS, SPR_NOACCESS,
1763 &spr_read_generic, &spr_write_booke_tsr,
1764 0x00000000);
1765 /* Timer */
1766 spr_register(env, SPR_DECR, "DECR",
1767 SPR_NOACCESS, SPR_NOACCESS,
1768 &spr_read_decr, &spr_write_decr,
1769 0x00000000);
1770 spr_register(env, SPR_BOOKE_DECAR, "DECAR",
1771 SPR_NOACCESS, SPR_NOACCESS,
1772 SPR_NOACCESS, &spr_write_generic,
1773 0x00000000);
1774 /* SPRGs */
1775 spr_register(env, SPR_USPRG0, "USPRG0",
1776 &spr_read_generic, &spr_write_generic,
1777 &spr_read_generic, &spr_write_generic,
1778 0x00000000);
1779 spr_register(env, SPR_SPRG4, "SPRG4",
1780 SPR_NOACCESS, SPR_NOACCESS,
1781 &spr_read_generic, &spr_write_generic,
1782 0x00000000);
j_mayer76a66252007-03-07 08:32:30 +00001783 spr_register(env, SPR_SPRG5, "SPRG5",
1784 SPR_NOACCESS, SPR_NOACCESS,
1785 &spr_read_generic, &spr_write_generic,
1786 0x00000000);
j_mayer76a66252007-03-07 08:32:30 +00001787 spr_register(env, SPR_SPRG6, "SPRG6",
1788 SPR_NOACCESS, SPR_NOACCESS,
1789 &spr_read_generic, &spr_write_generic,
1790 0x00000000);
j_mayer76a66252007-03-07 08:32:30 +00001791 spr_register(env, SPR_SPRG7, "SPRG7",
1792 SPR_NOACCESS, SPR_NOACCESS,
1793 &spr_read_generic, &spr_write_generic,
1794 0x00000000);
j_mayer76a66252007-03-07 08:32:30 +00001795}
1796
Alexander Graf01662f32011-04-30 23:34:58 +02001797static inline uint32_t gen_tlbncfg(uint32_t assoc, uint32_t minsize,
1798 uint32_t maxsize, uint32_t flags,
1799 uint32_t nentries)
1800{
1801 return (assoc << TLBnCFG_ASSOC_SHIFT) |
1802 (minsize << TLBnCFG_MINSIZE_SHIFT) |
1803 (maxsize << TLBnCFG_MAXSIZE_SHIFT) |
1804 flags | nentries;
1805}
1806
1807/* BookE 2.06 storage control registers */
1808static void gen_spr_BookE206(CPUPPCState *env, uint32_t mas_mask,
1809 uint32_t *tlbncfg)
j_mayer363be492007-03-30 10:07:33 +00001810{
j_mayerf2e63a42007-10-07 15:43:50 +00001811#if !defined(CONFIG_USER_ONLY)
blueswir1b55266b2008-09-20 08:07:15 +00001812 const char *mas_names[8] = {
j_mayer80d11f42007-11-17 23:02:20 +00001813 "MAS0", "MAS1", "MAS2", "MAS3", "MAS4", "MAS5", "MAS6", "MAS7",
1814 };
1815 int mas_sprn[8] = {
1816 SPR_BOOKE_MAS0, SPR_BOOKE_MAS1, SPR_BOOKE_MAS2, SPR_BOOKE_MAS3,
1817 SPR_BOOKE_MAS4, SPR_BOOKE_MAS5, SPR_BOOKE_MAS6, SPR_BOOKE_MAS7,
1818 };
1819 int i;
1820
j_mayer363be492007-03-30 10:07:33 +00001821 /* TLB assist registers */
j_mayer578bb252007-10-01 04:48:45 +00001822 /* XXX : not implemented */
j_mayer80d11f42007-11-17 23:02:20 +00001823 for (i = 0; i < 8; i++) {
Paolo Bonzini69b058c2014-11-26 13:39:48 +03001824 void (*uea_write)(DisasContext *ctx, int sprn, int gprn) = &spr_write_generic32;
Alexander Grafba38ab82012-06-21 14:01:06 +02001825 if (i == 2 && (mas_mask & (1 << i)) && (env->insns_flags & PPC_64B)) {
1826 uea_write = &spr_write_generic;
1827 }
j_mayer80d11f42007-11-17 23:02:20 +00001828 if (mas_mask & (1 << i)) {
1829 spr_register(env, mas_sprn[i], mas_names[i],
1830 SPR_NOACCESS, SPR_NOACCESS,
Alexander Grafba38ab82012-06-21 14:01:06 +02001831 &spr_read_generic, uea_write,
j_mayer80d11f42007-11-17 23:02:20 +00001832 0x00000000);
1833 }
1834 }
j_mayer363be492007-03-30 10:07:33 +00001835 if (env->nb_pids > 1) {
j_mayer578bb252007-10-01 04:48:45 +00001836 /* XXX : not implemented */
j_mayer363be492007-03-30 10:07:33 +00001837 spr_register(env, SPR_BOOKE_PID1, "PID1",
1838 SPR_NOACCESS, SPR_NOACCESS,
Alexander Graf01662f32011-04-30 23:34:58 +02001839 &spr_read_generic, &spr_write_booke_pid,
j_mayer363be492007-03-30 10:07:33 +00001840 0x00000000);
1841 }
1842 if (env->nb_pids > 2) {
j_mayer578bb252007-10-01 04:48:45 +00001843 /* XXX : not implemented */
j_mayer363be492007-03-30 10:07:33 +00001844 spr_register(env, SPR_BOOKE_PID2, "PID2",
1845 SPR_NOACCESS, SPR_NOACCESS,
Alexander Graf01662f32011-04-30 23:34:58 +02001846 &spr_read_generic, &spr_write_booke_pid,
j_mayer363be492007-03-30 10:07:33 +00001847 0x00000000);
1848 }
j_mayer578bb252007-10-01 04:48:45 +00001849 /* XXX : not implemented */
j_mayer65f9ee82007-10-05 13:11:25 +00001850 spr_register(env, SPR_MMUCFG, "MMUCFG",
j_mayer363be492007-03-30 10:07:33 +00001851 SPR_NOACCESS, SPR_NOACCESS,
1852 &spr_read_generic, SPR_NOACCESS,
1853 0x00000000); /* TOFIX */
j_mayer363be492007-03-30 10:07:33 +00001854 switch (env->nb_ways) {
1855 case 4:
1856 spr_register(env, SPR_BOOKE_TLB3CFG, "TLB3CFG",
1857 SPR_NOACCESS, SPR_NOACCESS,
1858 &spr_read_generic, SPR_NOACCESS,
Alexander Graf01662f32011-04-30 23:34:58 +02001859 tlbncfg[3]);
j_mayer363be492007-03-30 10:07:33 +00001860 /* Fallthru */
1861 case 3:
1862 spr_register(env, SPR_BOOKE_TLB2CFG, "TLB2CFG",
1863 SPR_NOACCESS, SPR_NOACCESS,
1864 &spr_read_generic, SPR_NOACCESS,
Alexander Graf01662f32011-04-30 23:34:58 +02001865 tlbncfg[2]);
j_mayer363be492007-03-30 10:07:33 +00001866 /* Fallthru */
1867 case 2:
1868 spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG",
1869 SPR_NOACCESS, SPR_NOACCESS,
1870 &spr_read_generic, SPR_NOACCESS,
Alexander Graf01662f32011-04-30 23:34:58 +02001871 tlbncfg[1]);
j_mayer363be492007-03-30 10:07:33 +00001872 /* Fallthru */
1873 case 1:
1874 spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG",
1875 SPR_NOACCESS, SPR_NOACCESS,
1876 &spr_read_generic, SPR_NOACCESS,
Alexander Graf01662f32011-04-30 23:34:58 +02001877 tlbncfg[0]);
j_mayer363be492007-03-30 10:07:33 +00001878 /* Fallthru */
1879 case 0:
1880 default:
1881 break;
1882 }
j_mayerf2e63a42007-10-07 15:43:50 +00001883#endif
Alexander Graf01662f32011-04-30 23:34:58 +02001884
1885 gen_spr_usprgh(env);
j_mayer363be492007-03-30 10:07:33 +00001886}
1887
j_mayer76a66252007-03-07 08:32:30 +00001888/* SPR specific to PowerPC 440 implementation */
1889static void gen_spr_440 (CPUPPCState *env)
1890{
1891 /* Cache control */
1892 /* XXX : not implemented */
1893 spr_register(env, SPR_440_DNV0, "DNV0",
1894 SPR_NOACCESS, SPR_NOACCESS,
1895 &spr_read_generic, &spr_write_generic,
1896 0x00000000);
1897 /* XXX : not implemented */
1898 spr_register(env, SPR_440_DNV1, "DNV1",
1899 SPR_NOACCESS, SPR_NOACCESS,
1900 &spr_read_generic, &spr_write_generic,
1901 0x00000000);
1902 /* XXX : not implemented */
1903 spr_register(env, SPR_440_DNV2, "DNV2",
1904 SPR_NOACCESS, SPR_NOACCESS,
1905 &spr_read_generic, &spr_write_generic,
1906 0x00000000);
1907 /* XXX : not implemented */
1908 spr_register(env, SPR_440_DNV3, "DNV3",
1909 SPR_NOACCESS, SPR_NOACCESS,
1910 &spr_read_generic, &spr_write_generic,
1911 0x00000000);
1912 /* XXX : not implemented */
j_mayer2662a052007-09-21 05:50:37 +00001913 spr_register(env, SPR_440_DTV0, "DTV0",
j_mayer76a66252007-03-07 08:32:30 +00001914 SPR_NOACCESS, SPR_NOACCESS,
1915 &spr_read_generic, &spr_write_generic,
1916 0x00000000);
1917 /* XXX : not implemented */
j_mayer2662a052007-09-21 05:50:37 +00001918 spr_register(env, SPR_440_DTV1, "DTV1",
j_mayer76a66252007-03-07 08:32:30 +00001919 SPR_NOACCESS, SPR_NOACCESS,
1920 &spr_read_generic, &spr_write_generic,
1921 0x00000000);
1922 /* XXX : not implemented */
j_mayer2662a052007-09-21 05:50:37 +00001923 spr_register(env, SPR_440_DTV2, "DTV2",
j_mayer76a66252007-03-07 08:32:30 +00001924 SPR_NOACCESS, SPR_NOACCESS,
1925 &spr_read_generic, &spr_write_generic,
1926 0x00000000);
1927 /* XXX : not implemented */
j_mayer2662a052007-09-21 05:50:37 +00001928 spr_register(env, SPR_440_DTV3, "DTV3",
j_mayer76a66252007-03-07 08:32:30 +00001929 SPR_NOACCESS, SPR_NOACCESS,
1930 &spr_read_generic, &spr_write_generic,
1931 0x00000000);
1932 /* XXX : not implemented */
1933 spr_register(env, SPR_440_DVLIM, "DVLIM",
1934 SPR_NOACCESS, SPR_NOACCESS,
1935 &spr_read_generic, &spr_write_generic,
1936 0x00000000);
1937 /* XXX : not implemented */
1938 spr_register(env, SPR_440_INV0, "INV0",
1939 SPR_NOACCESS, SPR_NOACCESS,
1940 &spr_read_generic, &spr_write_generic,
1941 0x00000000);
1942 /* XXX : not implemented */
1943 spr_register(env, SPR_440_INV1, "INV1",
1944 SPR_NOACCESS, SPR_NOACCESS,
1945 &spr_read_generic, &spr_write_generic,
1946 0x00000000);
1947 /* XXX : not implemented */
1948 spr_register(env, SPR_440_INV2, "INV2",
1949 SPR_NOACCESS, SPR_NOACCESS,
1950 &spr_read_generic, &spr_write_generic,
1951 0x00000000);
1952 /* XXX : not implemented */
1953 spr_register(env, SPR_440_INV3, "INV3",
1954 SPR_NOACCESS, SPR_NOACCESS,
1955 &spr_read_generic, &spr_write_generic,
1956 0x00000000);
1957 /* XXX : not implemented */
j_mayer2662a052007-09-21 05:50:37 +00001958 spr_register(env, SPR_440_ITV0, "ITV0",
j_mayer76a66252007-03-07 08:32:30 +00001959 SPR_NOACCESS, SPR_NOACCESS,
1960 &spr_read_generic, &spr_write_generic,
1961 0x00000000);
1962 /* XXX : not implemented */
j_mayer2662a052007-09-21 05:50:37 +00001963 spr_register(env, SPR_440_ITV1, "ITV1",
j_mayer76a66252007-03-07 08:32:30 +00001964 SPR_NOACCESS, SPR_NOACCESS,
1965 &spr_read_generic, &spr_write_generic,
1966 0x00000000);
1967 /* XXX : not implemented */
j_mayer2662a052007-09-21 05:50:37 +00001968 spr_register(env, SPR_440_ITV2, "ITV2",
j_mayer76a66252007-03-07 08:32:30 +00001969 SPR_NOACCESS, SPR_NOACCESS,
1970 &spr_read_generic, &spr_write_generic,
1971 0x00000000);
1972 /* XXX : not implemented */
j_mayer2662a052007-09-21 05:50:37 +00001973 spr_register(env, SPR_440_ITV3, "ITV3",
j_mayer76a66252007-03-07 08:32:30 +00001974 SPR_NOACCESS, SPR_NOACCESS,
1975 &spr_read_generic, &spr_write_generic,
1976 0x00000000);
1977 /* XXX : not implemented */
1978 spr_register(env, SPR_440_IVLIM, "IVLIM",
1979 SPR_NOACCESS, SPR_NOACCESS,
1980 &spr_read_generic, &spr_write_generic,
1981 0x00000000);
1982 /* Cache debug */
1983 /* XXX : not implemented */
j_mayer2662a052007-09-21 05:50:37 +00001984 spr_register(env, SPR_BOOKE_DCDBTRH, "DCDBTRH",
j_mayer76a66252007-03-07 08:32:30 +00001985 SPR_NOACCESS, SPR_NOACCESS,
1986 &spr_read_generic, SPR_NOACCESS,
1987 0x00000000);
1988 /* XXX : not implemented */
j_mayer2662a052007-09-21 05:50:37 +00001989 spr_register(env, SPR_BOOKE_DCDBTRL, "DCDBTRL",
j_mayer76a66252007-03-07 08:32:30 +00001990 SPR_NOACCESS, SPR_NOACCESS,
1991 &spr_read_generic, SPR_NOACCESS,
1992 0x00000000);
1993 /* XXX : not implemented */
j_mayer2662a052007-09-21 05:50:37 +00001994 spr_register(env, SPR_BOOKE_ICDBDR, "ICDBDR",
j_mayer76a66252007-03-07 08:32:30 +00001995 SPR_NOACCESS, SPR_NOACCESS,
1996 &spr_read_generic, SPR_NOACCESS,
1997 0x00000000);
1998 /* XXX : not implemented */
j_mayer2662a052007-09-21 05:50:37 +00001999 spr_register(env, SPR_BOOKE_ICDBTRH, "ICDBTRH",
j_mayer76a66252007-03-07 08:32:30 +00002000 SPR_NOACCESS, SPR_NOACCESS,
2001 &spr_read_generic, SPR_NOACCESS,
2002 0x00000000);
2003 /* XXX : not implemented */
j_mayer2662a052007-09-21 05:50:37 +00002004 spr_register(env, SPR_BOOKE_ICDBTRL, "ICDBTRL",
j_mayer76a66252007-03-07 08:32:30 +00002005 SPR_NOACCESS, SPR_NOACCESS,
2006 &spr_read_generic, SPR_NOACCESS,
2007 0x00000000);
2008 /* XXX : not implemented */
2009 spr_register(env, SPR_440_DBDR, "DBDR",
2010 SPR_NOACCESS, SPR_NOACCESS,
2011 &spr_read_generic, &spr_write_generic,
2012 0x00000000);
2013 /* Processor control */
2014 spr_register(env, SPR_4xx_CCR0, "CCR0",
2015 SPR_NOACCESS, SPR_NOACCESS,
2016 &spr_read_generic, &spr_write_generic,
2017 0x00000000);
2018 spr_register(env, SPR_440_RSTCFG, "RSTCFG",
2019 SPR_NOACCESS, SPR_NOACCESS,
2020 &spr_read_generic, SPR_NOACCESS,
2021 0x00000000);
2022 /* Storage control */
2023 spr_register(env, SPR_440_MMUCR, "MMUCR",
2024 SPR_NOACCESS, SPR_NOACCESS,
2025 &spr_read_generic, &spr_write_generic,
2026 0x00000000);
2027}
2028
2029/* SPR shared between PowerPC 40x implementations */
2030static void gen_spr_40x (CPUPPCState *env)
2031{
2032 /* Cache */
Stefan Weil5cbdb3a2012-04-07 09:23:39 +02002033 /* not emulated, as QEMU do not emulate caches */
j_mayer76a66252007-03-07 08:32:30 +00002034 spr_register(env, SPR_40x_DCCR, "DCCR",
2035 SPR_NOACCESS, SPR_NOACCESS,
2036 &spr_read_generic, &spr_write_generic,
2037 0x00000000);
Stefan Weil5cbdb3a2012-04-07 09:23:39 +02002038 /* not emulated, as QEMU do not emulate caches */
j_mayer76a66252007-03-07 08:32:30 +00002039 spr_register(env, SPR_40x_ICCR, "ICCR",
2040 SPR_NOACCESS, SPR_NOACCESS,
2041 &spr_read_generic, &spr_write_generic,
2042 0x00000000);
Stefan Weil5cbdb3a2012-04-07 09:23:39 +02002043 /* not emulated, as QEMU do not emulate caches */
j_mayer2662a052007-09-21 05:50:37 +00002044 spr_register(env, SPR_BOOKE_ICDBDR, "ICDBDR",
j_mayer76a66252007-03-07 08:32:30 +00002045 SPR_NOACCESS, SPR_NOACCESS,
2046 &spr_read_generic, SPR_NOACCESS,
2047 0x00000000);
j_mayer76a66252007-03-07 08:32:30 +00002048 /* Exception */
2049 spr_register(env, SPR_40x_DEAR, "DEAR",
2050 SPR_NOACCESS, SPR_NOACCESS,
2051 &spr_read_generic, &spr_write_generic,
2052 0x00000000);
2053 spr_register(env, SPR_40x_ESR, "ESR",
2054 SPR_NOACCESS, SPR_NOACCESS,
2055 &spr_read_generic, &spr_write_generic,
2056 0x00000000);
2057 spr_register(env, SPR_40x_EVPR, "EVPR",
2058 SPR_NOACCESS, SPR_NOACCESS,
j_mayer6f5d4272007-10-01 01:32:49 +00002059 &spr_read_generic, &spr_write_excp_prefix,
j_mayer76a66252007-03-07 08:32:30 +00002060 0x00000000);
2061 spr_register(env, SPR_40x_SRR2, "SRR2",
2062 &spr_read_generic, &spr_write_generic,
2063 &spr_read_generic, &spr_write_generic,
2064 0x00000000);
2065 spr_register(env, SPR_40x_SRR3, "SRR3",
2066 &spr_read_generic, &spr_write_generic,
2067 &spr_read_generic, &spr_write_generic,
2068 0x00000000);
2069 /* Timers */
2070 spr_register(env, SPR_40x_PIT, "PIT",
2071 SPR_NOACCESS, SPR_NOACCESS,
2072 &spr_read_40x_pit, &spr_write_40x_pit,
2073 0x00000000);
2074 spr_register(env, SPR_40x_TCR, "TCR",
2075 SPR_NOACCESS, SPR_NOACCESS,
2076 &spr_read_generic, &spr_write_booke_tcr,
2077 0x00000000);
2078 spr_register(env, SPR_40x_TSR, "TSR",
2079 SPR_NOACCESS, SPR_NOACCESS,
2080 &spr_read_generic, &spr_write_booke_tsr,
2081 0x00000000);
j_mayer2662a052007-09-21 05:50:37 +00002082}
2083
2084/* SPR specific to PowerPC 405 implementation */
2085static void gen_spr_405 (CPUPPCState *env)
2086{
2087 /* MMU */
2088 spr_register(env, SPR_40x_PID, "PID",
2089 SPR_NOACCESS, SPR_NOACCESS,
2090 &spr_read_generic, &spr_write_generic,
2091 0x00000000);
2092 spr_register(env, SPR_4xx_CCR0, "CCR0",
2093 SPR_NOACCESS, SPR_NOACCESS,
2094 &spr_read_generic, &spr_write_generic,
2095 0x00700000);
j_mayer76a66252007-03-07 08:32:30 +00002096 /* Debug interface */
2097 /* XXX : not implemented */
j_mayer2662a052007-09-21 05:50:37 +00002098 spr_register(env, SPR_40x_DBCR0, "DBCR0",
2099 SPR_NOACCESS, SPR_NOACCESS,
2100 &spr_read_generic, &spr_write_40x_dbcr0,
2101 0x00000000);
2102 /* XXX : not implemented */
2103 spr_register(env, SPR_405_DBCR1, "DBCR1",
2104 SPR_NOACCESS, SPR_NOACCESS,
2105 &spr_read_generic, &spr_write_generic,
2106 0x00000000);
2107 /* XXX : not implemented */
2108 spr_register(env, SPR_40x_DBSR, "DBSR",
2109 SPR_NOACCESS, SPR_NOACCESS,
2110 &spr_read_generic, &spr_write_clear,
2111 /* Last reset was system reset */
2112 0x00000300);
2113 /* XXX : not implemented */
j_mayer76a66252007-03-07 08:32:30 +00002114 spr_register(env, SPR_40x_DAC1, "DAC1",
2115 SPR_NOACCESS, SPR_NOACCESS,
2116 &spr_read_generic, &spr_write_generic,
2117 0x00000000);
2118 spr_register(env, SPR_40x_DAC2, "DAC2",
2119 SPR_NOACCESS, SPR_NOACCESS,
2120 &spr_read_generic, &spr_write_generic,
2121 0x00000000);
2122 /* XXX : not implemented */
j_mayer76a66252007-03-07 08:32:30 +00002123 spr_register(env, SPR_405_DVC1, "DVC1",
2124 SPR_NOACCESS, SPR_NOACCESS,
2125 &spr_read_generic, &spr_write_generic,
2126 0x00000000);
2127 /* XXX : not implemented */
2128 spr_register(env, SPR_405_DVC2, "DVC2",
2129 SPR_NOACCESS, SPR_NOACCESS,
2130 &spr_read_generic, &spr_write_generic,
2131 0x00000000);
2132 /* XXX : not implemented */
j_mayer2662a052007-09-21 05:50:37 +00002133 spr_register(env, SPR_40x_IAC1, "IAC1",
2134 SPR_NOACCESS, SPR_NOACCESS,
2135 &spr_read_generic, &spr_write_generic,
2136 0x00000000);
2137 spr_register(env, SPR_40x_IAC2, "IAC2",
2138 SPR_NOACCESS, SPR_NOACCESS,
2139 &spr_read_generic, &spr_write_generic,
2140 0x00000000);
2141 /* XXX : not implemented */
j_mayer76a66252007-03-07 08:32:30 +00002142 spr_register(env, SPR_405_IAC3, "IAC3",
2143 SPR_NOACCESS, SPR_NOACCESS,
2144 &spr_read_generic, &spr_write_generic,
2145 0x00000000);
2146 /* XXX : not implemented */
2147 spr_register(env, SPR_405_IAC4, "IAC4",
2148 SPR_NOACCESS, SPR_NOACCESS,
2149 &spr_read_generic, &spr_write_generic,
2150 0x00000000);
2151 /* Storage control */
j_mayer035feb82007-10-01 01:38:03 +00002152 /* XXX: TODO: not implemented */
j_mayer76a66252007-03-07 08:32:30 +00002153 spr_register(env, SPR_405_SLER, "SLER",
2154 SPR_NOACCESS, SPR_NOACCESS,
j_mayerc294fc52007-04-24 06:44:14 +00002155 &spr_read_generic, &spr_write_40x_sler,
j_mayer76a66252007-03-07 08:32:30 +00002156 0x00000000);
j_mayer2662a052007-09-21 05:50:37 +00002157 spr_register(env, SPR_40x_ZPR, "ZPR",
2158 SPR_NOACCESS, SPR_NOACCESS,
2159 &spr_read_generic, &spr_write_generic,
2160 0x00000000);
j_mayer76a66252007-03-07 08:32:30 +00002161 /* XXX : not implemented */
2162 spr_register(env, SPR_405_SU0R, "SU0R",
2163 SPR_NOACCESS, SPR_NOACCESS,
2164 &spr_read_generic, &spr_write_generic,
2165 0x00000000);
2166 /* SPRG */
2167 spr_register(env, SPR_USPRG0, "USPRG0",
2168 &spr_read_ureg, SPR_NOACCESS,
2169 &spr_read_ureg, SPR_NOACCESS,
2170 0x00000000);
2171 spr_register(env, SPR_SPRG4, "SPRG4",
2172 SPR_NOACCESS, SPR_NOACCESS,
j_mayer04f20792007-04-17 02:50:56 +00002173 &spr_read_generic, &spr_write_generic,
j_mayer76a66252007-03-07 08:32:30 +00002174 0x00000000);
j_mayer76a66252007-03-07 08:32:30 +00002175 spr_register(env, SPR_SPRG5, "SPRG5",
2176 SPR_NOACCESS, SPR_NOACCESS,
j_mayer04f20792007-04-17 02:50:56 +00002177 spr_read_generic, &spr_write_generic,
j_mayer76a66252007-03-07 08:32:30 +00002178 0x00000000);
j_mayer76a66252007-03-07 08:32:30 +00002179 spr_register(env, SPR_SPRG6, "SPRG6",
2180 SPR_NOACCESS, SPR_NOACCESS,
j_mayer04f20792007-04-17 02:50:56 +00002181 spr_read_generic, &spr_write_generic,
j_mayer76a66252007-03-07 08:32:30 +00002182 0x00000000);
j_mayer76a66252007-03-07 08:32:30 +00002183 spr_register(env, SPR_SPRG7, "SPRG7",
2184 SPR_NOACCESS, SPR_NOACCESS,
j_mayer04f20792007-04-17 02:50:56 +00002185 spr_read_generic, &spr_write_generic,
j_mayer76a66252007-03-07 08:32:30 +00002186 0x00000000);
j_mayer80d11f42007-11-17 23:02:20 +00002187 gen_spr_usprgh(env);
j_mayer76a66252007-03-07 08:32:30 +00002188}
2189
2190/* SPR shared between PowerPC 401 & 403 implementations */
2191static void gen_spr_401_403 (CPUPPCState *env)
2192{
2193 /* Time base */
2194 spr_register(env, SPR_403_VTBL, "TBL",
2195 &spr_read_tbl, SPR_NOACCESS,
2196 &spr_read_tbl, SPR_NOACCESS,
2197 0x00000000);
2198 spr_register(env, SPR_403_TBL, "TBL",
2199 SPR_NOACCESS, SPR_NOACCESS,
2200 SPR_NOACCESS, &spr_write_tbl,
2201 0x00000000);
2202 spr_register(env, SPR_403_VTBU, "TBU",
2203 &spr_read_tbu, SPR_NOACCESS,
2204 &spr_read_tbu, SPR_NOACCESS,
2205 0x00000000);
2206 spr_register(env, SPR_403_TBU, "TBU",
2207 SPR_NOACCESS, SPR_NOACCESS,
2208 SPR_NOACCESS, &spr_write_tbu,
2209 0x00000000);
2210 /* Debug */
Stefan Weil5cbdb3a2012-04-07 09:23:39 +02002211 /* not emulated, as QEMU do not emulate caches */
j_mayer76a66252007-03-07 08:32:30 +00002212 spr_register(env, SPR_403_CDBCR, "CDBCR",
2213 SPR_NOACCESS, SPR_NOACCESS,
2214 &spr_read_generic, &spr_write_generic,
2215 0x00000000);
2216}
2217
j_mayer2662a052007-09-21 05:50:37 +00002218/* SPR specific to PowerPC 401 implementation */
2219static void gen_spr_401 (CPUPPCState *env)
2220{
2221 /* Debug interface */
2222 /* XXX : not implemented */
2223 spr_register(env, SPR_40x_DBCR0, "DBCR",
2224 SPR_NOACCESS, SPR_NOACCESS,
2225 &spr_read_generic, &spr_write_40x_dbcr0,
2226 0x00000000);
2227 /* XXX : not implemented */
2228 spr_register(env, SPR_40x_DBSR, "DBSR",
2229 SPR_NOACCESS, SPR_NOACCESS,
2230 &spr_read_generic, &spr_write_clear,
2231 /* Last reset was system reset */
2232 0x00000300);
2233 /* XXX : not implemented */
2234 spr_register(env, SPR_40x_DAC1, "DAC",
2235 SPR_NOACCESS, SPR_NOACCESS,
2236 &spr_read_generic, &spr_write_generic,
2237 0x00000000);
2238 /* XXX : not implemented */
2239 spr_register(env, SPR_40x_IAC1, "IAC",
2240 SPR_NOACCESS, SPR_NOACCESS,
2241 &spr_read_generic, &spr_write_generic,
2242 0x00000000);
2243 /* Storage control */
j_mayer035feb82007-10-01 01:38:03 +00002244 /* XXX: TODO: not implemented */
j_mayer2662a052007-09-21 05:50:37 +00002245 spr_register(env, SPR_405_SLER, "SLER",
2246 SPR_NOACCESS, SPR_NOACCESS,
2247 &spr_read_generic, &spr_write_40x_sler,
2248 0x00000000);
Stefan Weil5cbdb3a2012-04-07 09:23:39 +02002249 /* not emulated, as QEMU never does speculative access */
j_mayer035feb82007-10-01 01:38:03 +00002250 spr_register(env, SPR_40x_SGR, "SGR",
2251 SPR_NOACCESS, SPR_NOACCESS,
2252 &spr_read_generic, &spr_write_generic,
2253 0xFFFFFFFF);
Stefan Weil5cbdb3a2012-04-07 09:23:39 +02002254 /* not emulated, as QEMU do not emulate caches */
j_mayer035feb82007-10-01 01:38:03 +00002255 spr_register(env, SPR_40x_DCWR, "DCWR",
2256 SPR_NOACCESS, SPR_NOACCESS,
2257 &spr_read_generic, &spr_write_generic,
2258 0x00000000);
j_mayer2662a052007-09-21 05:50:37 +00002259}
2260
j_mayera750fc02007-09-26 23:54:22 +00002261static void gen_spr_401x2 (CPUPPCState *env)
2262{
2263 gen_spr_401(env);
2264 spr_register(env, SPR_40x_PID, "PID",
2265 SPR_NOACCESS, SPR_NOACCESS,
2266 &spr_read_generic, &spr_write_generic,
2267 0x00000000);
2268 spr_register(env, SPR_40x_ZPR, "ZPR",
2269 SPR_NOACCESS, SPR_NOACCESS,
2270 &spr_read_generic, &spr_write_generic,
2271 0x00000000);
2272}
2273
j_mayer76a66252007-03-07 08:32:30 +00002274/* SPR specific to PowerPC 403 implementation */
2275static void gen_spr_403 (CPUPPCState *env)
2276{
j_mayer2662a052007-09-21 05:50:37 +00002277 /* Debug interface */
2278 /* XXX : not implemented */
2279 spr_register(env, SPR_40x_DBCR0, "DBCR0",
2280 SPR_NOACCESS, SPR_NOACCESS,
2281 &spr_read_generic, &spr_write_40x_dbcr0,
2282 0x00000000);
2283 /* XXX : not implemented */
2284 spr_register(env, SPR_40x_DBSR, "DBSR",
2285 SPR_NOACCESS, SPR_NOACCESS,
2286 &spr_read_generic, &spr_write_clear,
2287 /* Last reset was system reset */
2288 0x00000300);
2289 /* XXX : not implemented */
2290 spr_register(env, SPR_40x_DAC1, "DAC1",
2291 SPR_NOACCESS, SPR_NOACCESS,
2292 &spr_read_generic, &spr_write_generic,
2293 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00002294 /* XXX : not implemented */
j_mayer2662a052007-09-21 05:50:37 +00002295 spr_register(env, SPR_40x_DAC2, "DAC2",
2296 SPR_NOACCESS, SPR_NOACCESS,
2297 &spr_read_generic, &spr_write_generic,
2298 0x00000000);
2299 /* XXX : not implemented */
2300 spr_register(env, SPR_40x_IAC1, "IAC1",
2301 SPR_NOACCESS, SPR_NOACCESS,
2302 &spr_read_generic, &spr_write_generic,
2303 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00002304 /* XXX : not implemented */
j_mayer2662a052007-09-21 05:50:37 +00002305 spr_register(env, SPR_40x_IAC2, "IAC2",
2306 SPR_NOACCESS, SPR_NOACCESS,
2307 &spr_read_generic, &spr_write_generic,
2308 0x00000000);
j_mayera750fc02007-09-26 23:54:22 +00002309}
2310
2311static void gen_spr_403_real (CPUPPCState *env)
2312{
j_mayer76a66252007-03-07 08:32:30 +00002313 spr_register(env, SPR_403_PBL1, "PBL1",
2314 SPR_NOACCESS, SPR_NOACCESS,
2315 &spr_read_403_pbr, &spr_write_403_pbr,
2316 0x00000000);
2317 spr_register(env, SPR_403_PBU1, "PBU1",
2318 SPR_NOACCESS, SPR_NOACCESS,
2319 &spr_read_403_pbr, &spr_write_403_pbr,
2320 0x00000000);
2321 spr_register(env, SPR_403_PBL2, "PBL2",
2322 SPR_NOACCESS, SPR_NOACCESS,
2323 &spr_read_403_pbr, &spr_write_403_pbr,
2324 0x00000000);
2325 spr_register(env, SPR_403_PBU2, "PBU2",
2326 SPR_NOACCESS, SPR_NOACCESS,
2327 &spr_read_403_pbr, &spr_write_403_pbr,
2328 0x00000000);
j_mayera750fc02007-09-26 23:54:22 +00002329}
2330
2331static void gen_spr_403_mmu (CPUPPCState *env)
2332{
2333 /* MMU */
2334 spr_register(env, SPR_40x_PID, "PID",
2335 SPR_NOACCESS, SPR_NOACCESS,
2336 &spr_read_generic, &spr_write_generic,
2337 0x00000000);
j_mayer2662a052007-09-21 05:50:37 +00002338 spr_register(env, SPR_40x_ZPR, "ZPR",
j_mayer76a66252007-03-07 08:32:30 +00002339 SPR_NOACCESS, SPR_NOACCESS,
2340 &spr_read_generic, &spr_write_generic,
2341 0x00000000);
2342}
2343
2344/* SPR specific to PowerPC compression coprocessor extension */
j_mayer76a66252007-03-07 08:32:30 +00002345static void gen_spr_compress (CPUPPCState *env)
2346{
j_mayer578bb252007-10-01 04:48:45 +00002347 /* XXX : not implemented */
j_mayer76a66252007-03-07 08:32:30 +00002348 spr_register(env, SPR_401_SKR, "SKR",
2349 SPR_NOACCESS, SPR_NOACCESS,
2350 &spr_read_generic, &spr_write_generic,
2351 0x00000000);
2352}
j_mayera750fc02007-09-26 23:54:22 +00002353
j_mayer80d11f42007-11-17 23:02:20 +00002354static void gen_spr_5xx_8xx (CPUPPCState *env)
2355{
2356 /* Exception processing */
David Gibsond67d40e2013-02-20 16:41:50 +00002357 spr_register_kvm(env, SPR_DSISR, "DSISR",
2358 SPR_NOACCESS, SPR_NOACCESS,
2359 &spr_read_generic, &spr_write_generic,
2360 KVM_REG_PPC_DSISR, 0x00000000);
2361 spr_register_kvm(env, SPR_DAR, "DAR",
2362 SPR_NOACCESS, SPR_NOACCESS,
2363 &spr_read_generic, &spr_write_generic,
2364 KVM_REG_PPC_DAR, 0x00000000);
j_mayer80d11f42007-11-17 23:02:20 +00002365 /* Timer */
2366 spr_register(env, SPR_DECR, "DECR",
2367 SPR_NOACCESS, SPR_NOACCESS,
2368 &spr_read_decr, &spr_write_decr,
2369 0x00000000);
2370 /* XXX : not implemented */
2371 spr_register(env, SPR_MPC_EIE, "EIE",
2372 SPR_NOACCESS, SPR_NOACCESS,
2373 &spr_read_generic, &spr_write_generic,
2374 0x00000000);
2375 /* XXX : not implemented */
2376 spr_register(env, SPR_MPC_EID, "EID",
2377 SPR_NOACCESS, SPR_NOACCESS,
2378 &spr_read_generic, &spr_write_generic,
2379 0x00000000);
2380 /* XXX : not implemented */
2381 spr_register(env, SPR_MPC_NRI, "NRI",
2382 SPR_NOACCESS, SPR_NOACCESS,
2383 &spr_read_generic, &spr_write_generic,
2384 0x00000000);
2385 /* XXX : not implemented */
2386 spr_register(env, SPR_MPC_CMPA, "CMPA",
2387 SPR_NOACCESS, SPR_NOACCESS,
2388 &spr_read_generic, &spr_write_generic,
2389 0x00000000);
2390 /* XXX : not implemented */
2391 spr_register(env, SPR_MPC_CMPB, "CMPB",
2392 SPR_NOACCESS, SPR_NOACCESS,
2393 &spr_read_generic, &spr_write_generic,
2394 0x00000000);
2395 /* XXX : not implemented */
2396 spr_register(env, SPR_MPC_CMPC, "CMPC",
2397 SPR_NOACCESS, SPR_NOACCESS,
2398 &spr_read_generic, &spr_write_generic,
2399 0x00000000);
2400 /* XXX : not implemented */
2401 spr_register(env, SPR_MPC_CMPD, "CMPD",
2402 SPR_NOACCESS, SPR_NOACCESS,
2403 &spr_read_generic, &spr_write_generic,
2404 0x00000000);
2405 /* XXX : not implemented */
2406 spr_register(env, SPR_MPC_ECR, "ECR",
2407 SPR_NOACCESS, SPR_NOACCESS,
2408 &spr_read_generic, &spr_write_generic,
2409 0x00000000);
2410 /* XXX : not implemented */
2411 spr_register(env, SPR_MPC_DER, "DER",
2412 SPR_NOACCESS, SPR_NOACCESS,
2413 &spr_read_generic, &spr_write_generic,
2414 0x00000000);
2415 /* XXX : not implemented */
2416 spr_register(env, SPR_MPC_COUNTA, "COUNTA",
2417 SPR_NOACCESS, SPR_NOACCESS,
2418 &spr_read_generic, &spr_write_generic,
2419 0x00000000);
2420 /* XXX : not implemented */
2421 spr_register(env, SPR_MPC_COUNTB, "COUNTB",
2422 SPR_NOACCESS, SPR_NOACCESS,
2423 &spr_read_generic, &spr_write_generic,
2424 0x00000000);
2425 /* XXX : not implemented */
2426 spr_register(env, SPR_MPC_CMPE, "CMPE",
2427 SPR_NOACCESS, SPR_NOACCESS,
2428 &spr_read_generic, &spr_write_generic,
2429 0x00000000);
2430 /* XXX : not implemented */
2431 spr_register(env, SPR_MPC_CMPF, "CMPF",
2432 SPR_NOACCESS, SPR_NOACCESS,
2433 &spr_read_generic, &spr_write_generic,
2434 0x00000000);
2435 /* XXX : not implemented */
2436 spr_register(env, SPR_MPC_CMPG, "CMPG",
2437 SPR_NOACCESS, SPR_NOACCESS,
2438 &spr_read_generic, &spr_write_generic,
2439 0x00000000);
2440 /* XXX : not implemented */
2441 spr_register(env, SPR_MPC_CMPH, "CMPH",
2442 SPR_NOACCESS, SPR_NOACCESS,
2443 &spr_read_generic, &spr_write_generic,
2444 0x00000000);
2445 /* XXX : not implemented */
2446 spr_register(env, SPR_MPC_LCTRL1, "LCTRL1",
2447 SPR_NOACCESS, SPR_NOACCESS,
2448 &spr_read_generic, &spr_write_generic,
2449 0x00000000);
2450 /* XXX : not implemented */
2451 spr_register(env, SPR_MPC_LCTRL2, "LCTRL2",
2452 SPR_NOACCESS, SPR_NOACCESS,
2453 &spr_read_generic, &spr_write_generic,
2454 0x00000000);
2455 /* XXX : not implemented */
2456 spr_register(env, SPR_MPC_BAR, "BAR",
2457 SPR_NOACCESS, SPR_NOACCESS,
2458 &spr_read_generic, &spr_write_generic,
2459 0x00000000);
2460 /* XXX : not implemented */
2461 spr_register(env, SPR_MPC_DPDR, "DPDR",
2462 SPR_NOACCESS, SPR_NOACCESS,
2463 &spr_read_generic, &spr_write_generic,
2464 0x00000000);
2465 /* XXX : not implemented */
2466 spr_register(env, SPR_MPC_IMMR, "IMMR",
2467 SPR_NOACCESS, SPR_NOACCESS,
2468 &spr_read_generic, &spr_write_generic,
2469 0x00000000);
2470}
2471
2472static void gen_spr_5xx (CPUPPCState *env)
2473{
2474 /* XXX : not implemented */
2475 spr_register(env, SPR_RCPU_MI_GRA, "MI_GRA",
2476 SPR_NOACCESS, SPR_NOACCESS,
2477 &spr_read_generic, &spr_write_generic,
2478 0x00000000);
2479 /* XXX : not implemented */
2480 spr_register(env, SPR_RCPU_L2U_GRA, "L2U_GRA",
2481 SPR_NOACCESS, SPR_NOACCESS,
2482 &spr_read_generic, &spr_write_generic,
2483 0x00000000);
2484 /* XXX : not implemented */
2485 spr_register(env, SPR_RPCU_BBCMCR, "L2U_BBCMCR",
2486 SPR_NOACCESS, SPR_NOACCESS,
2487 &spr_read_generic, &spr_write_generic,
2488 0x00000000);
2489 /* XXX : not implemented */
2490 spr_register(env, SPR_RCPU_L2U_MCR, "L2U_MCR",
2491 SPR_NOACCESS, SPR_NOACCESS,
2492 &spr_read_generic, &spr_write_generic,
2493 0x00000000);
2494 /* XXX : not implemented */
2495 spr_register(env, SPR_RCPU_MI_RBA0, "MI_RBA0",
2496 SPR_NOACCESS, SPR_NOACCESS,
2497 &spr_read_generic, &spr_write_generic,
2498 0x00000000);
2499 /* XXX : not implemented */
2500 spr_register(env, SPR_RCPU_MI_RBA1, "MI_RBA1",
2501 SPR_NOACCESS, SPR_NOACCESS,
2502 &spr_read_generic, &spr_write_generic,
2503 0x00000000);
2504 /* XXX : not implemented */
2505 spr_register(env, SPR_RCPU_MI_RBA2, "MI_RBA2",
2506 SPR_NOACCESS, SPR_NOACCESS,
2507 &spr_read_generic, &spr_write_generic,
2508 0x00000000);
2509 /* XXX : not implemented */
2510 spr_register(env, SPR_RCPU_MI_RBA3, "MI_RBA3",
2511 SPR_NOACCESS, SPR_NOACCESS,
2512 &spr_read_generic, &spr_write_generic,
2513 0x00000000);
2514 /* XXX : not implemented */
2515 spr_register(env, SPR_RCPU_L2U_RBA0, "L2U_RBA0",
2516 SPR_NOACCESS, SPR_NOACCESS,
2517 &spr_read_generic, &spr_write_generic,
2518 0x00000000);
2519 /* XXX : not implemented */
2520 spr_register(env, SPR_RCPU_L2U_RBA1, "L2U_RBA1",
2521 SPR_NOACCESS, SPR_NOACCESS,
2522 &spr_read_generic, &spr_write_generic,
2523 0x00000000);
2524 /* XXX : not implemented */
2525 spr_register(env, SPR_RCPU_L2U_RBA2, "L2U_RBA2",
2526 SPR_NOACCESS, SPR_NOACCESS,
2527 &spr_read_generic, &spr_write_generic,
2528 0x00000000);
2529 /* XXX : not implemented */
2530 spr_register(env, SPR_RCPU_L2U_RBA3, "L2U_RBA3",
2531 SPR_NOACCESS, SPR_NOACCESS,
2532 &spr_read_generic, &spr_write_generic,
2533 0x00000000);
2534 /* XXX : not implemented */
2535 spr_register(env, SPR_RCPU_MI_RA0, "MI_RA0",
2536 SPR_NOACCESS, SPR_NOACCESS,
2537 &spr_read_generic, &spr_write_generic,
2538 0x00000000);
2539 /* XXX : not implemented */
2540 spr_register(env, SPR_RCPU_MI_RA1, "MI_RA1",
2541 SPR_NOACCESS, SPR_NOACCESS,
2542 &spr_read_generic, &spr_write_generic,
2543 0x00000000);
2544 /* XXX : not implemented */
2545 spr_register(env, SPR_RCPU_MI_RA2, "MI_RA2",
2546 SPR_NOACCESS, SPR_NOACCESS,
2547 &spr_read_generic, &spr_write_generic,
2548 0x00000000);
2549 /* XXX : not implemented */
2550 spr_register(env, SPR_RCPU_MI_RA3, "MI_RA3",
2551 SPR_NOACCESS, SPR_NOACCESS,
2552 &spr_read_generic, &spr_write_generic,
2553 0x00000000);
2554 /* XXX : not implemented */
2555 spr_register(env, SPR_RCPU_L2U_RA0, "L2U_RA0",
2556 SPR_NOACCESS, SPR_NOACCESS,
2557 &spr_read_generic, &spr_write_generic,
2558 0x00000000);
2559 /* XXX : not implemented */
2560 spr_register(env, SPR_RCPU_L2U_RA1, "L2U_RA1",
2561 SPR_NOACCESS, SPR_NOACCESS,
2562 &spr_read_generic, &spr_write_generic,
2563 0x00000000);
2564 /* XXX : not implemented */
2565 spr_register(env, SPR_RCPU_L2U_RA2, "L2U_RA2",
2566 SPR_NOACCESS, SPR_NOACCESS,
2567 &spr_read_generic, &spr_write_generic,
2568 0x00000000);
2569 /* XXX : not implemented */
2570 spr_register(env, SPR_RCPU_L2U_RA3, "L2U_RA3",
2571 SPR_NOACCESS, SPR_NOACCESS,
2572 &spr_read_generic, &spr_write_generic,
2573 0x00000000);
2574 /* XXX : not implemented */
2575 spr_register(env, SPR_RCPU_FPECR, "FPECR",
2576 SPR_NOACCESS, SPR_NOACCESS,
2577 &spr_read_generic, &spr_write_generic,
2578 0x00000000);
2579}
2580
2581static void gen_spr_8xx (CPUPPCState *env)
2582{
2583 /* XXX : not implemented */
2584 spr_register(env, SPR_MPC_IC_CST, "IC_CST",
2585 SPR_NOACCESS, SPR_NOACCESS,
2586 &spr_read_generic, &spr_write_generic,
2587 0x00000000);
2588 /* XXX : not implemented */
2589 spr_register(env, SPR_MPC_IC_ADR, "IC_ADR",
2590 SPR_NOACCESS, SPR_NOACCESS,
2591 &spr_read_generic, &spr_write_generic,
2592 0x00000000);
2593 /* XXX : not implemented */
2594 spr_register(env, SPR_MPC_IC_DAT, "IC_DAT",
2595 SPR_NOACCESS, SPR_NOACCESS,
2596 &spr_read_generic, &spr_write_generic,
2597 0x00000000);
2598 /* XXX : not implemented */
2599 spr_register(env, SPR_MPC_DC_CST, "DC_CST",
2600 SPR_NOACCESS, SPR_NOACCESS,
2601 &spr_read_generic, &spr_write_generic,
2602 0x00000000);
2603 /* XXX : not implemented */
2604 spr_register(env, SPR_MPC_DC_ADR, "DC_ADR",
2605 SPR_NOACCESS, SPR_NOACCESS,
2606 &spr_read_generic, &spr_write_generic,
2607 0x00000000);
2608 /* XXX : not implemented */
2609 spr_register(env, SPR_MPC_DC_DAT, "DC_DAT",
2610 SPR_NOACCESS, SPR_NOACCESS,
2611 &spr_read_generic, &spr_write_generic,
2612 0x00000000);
2613 /* XXX : not implemented */
2614 spr_register(env, SPR_MPC_MI_CTR, "MI_CTR",
2615 SPR_NOACCESS, SPR_NOACCESS,
2616 &spr_read_generic, &spr_write_generic,
2617 0x00000000);
2618 /* XXX : not implemented */
2619 spr_register(env, SPR_MPC_MI_AP, "MI_AP",
2620 SPR_NOACCESS, SPR_NOACCESS,
2621 &spr_read_generic, &spr_write_generic,
2622 0x00000000);
2623 /* XXX : not implemented */
2624 spr_register(env, SPR_MPC_MI_EPN, "MI_EPN",
2625 SPR_NOACCESS, SPR_NOACCESS,
2626 &spr_read_generic, &spr_write_generic,
2627 0x00000000);
2628 /* XXX : not implemented */
2629 spr_register(env, SPR_MPC_MI_TWC, "MI_TWC",
2630 SPR_NOACCESS, SPR_NOACCESS,
2631 &spr_read_generic, &spr_write_generic,
2632 0x00000000);
2633 /* XXX : not implemented */
2634 spr_register(env, SPR_MPC_MI_RPN, "MI_RPN",
2635 SPR_NOACCESS, SPR_NOACCESS,
2636 &spr_read_generic, &spr_write_generic,
2637 0x00000000);
2638 /* XXX : not implemented */
2639 spr_register(env, SPR_MPC_MI_DBCAM, "MI_DBCAM",
2640 SPR_NOACCESS, SPR_NOACCESS,
2641 &spr_read_generic, &spr_write_generic,
2642 0x00000000);
2643 /* XXX : not implemented */
2644 spr_register(env, SPR_MPC_MI_DBRAM0, "MI_DBRAM0",
2645 SPR_NOACCESS, SPR_NOACCESS,
2646 &spr_read_generic, &spr_write_generic,
2647 0x00000000);
2648 /* XXX : not implemented */
2649 spr_register(env, SPR_MPC_MI_DBRAM1, "MI_DBRAM1",
2650 SPR_NOACCESS, SPR_NOACCESS,
2651 &spr_read_generic, &spr_write_generic,
2652 0x00000000);
2653 /* XXX : not implemented */
2654 spr_register(env, SPR_MPC_MD_CTR, "MD_CTR",
2655 SPR_NOACCESS, SPR_NOACCESS,
2656 &spr_read_generic, &spr_write_generic,
2657 0x00000000);
2658 /* XXX : not implemented */
2659 spr_register(env, SPR_MPC_MD_CASID, "MD_CASID",
2660 SPR_NOACCESS, SPR_NOACCESS,
2661 &spr_read_generic, &spr_write_generic,
2662 0x00000000);
2663 /* XXX : not implemented */
2664 spr_register(env, SPR_MPC_MD_AP, "MD_AP",
2665 SPR_NOACCESS, SPR_NOACCESS,
2666 &spr_read_generic, &spr_write_generic,
2667 0x00000000);
2668 /* XXX : not implemented */
2669 spr_register(env, SPR_MPC_MD_EPN, "MD_EPN",
2670 SPR_NOACCESS, SPR_NOACCESS,
2671 &spr_read_generic, &spr_write_generic,
2672 0x00000000);
2673 /* XXX : not implemented */
2674 spr_register(env, SPR_MPC_MD_TWB, "MD_TWB",
2675 SPR_NOACCESS, SPR_NOACCESS,
2676 &spr_read_generic, &spr_write_generic,
2677 0x00000000);
2678 /* XXX : not implemented */
2679 spr_register(env, SPR_MPC_MD_TWC, "MD_TWC",
2680 SPR_NOACCESS, SPR_NOACCESS,
2681 &spr_read_generic, &spr_write_generic,
2682 0x00000000);
2683 /* XXX : not implemented */
2684 spr_register(env, SPR_MPC_MD_RPN, "MD_RPN",
2685 SPR_NOACCESS, SPR_NOACCESS,
2686 &spr_read_generic, &spr_write_generic,
2687 0x00000000);
2688 /* XXX : not implemented */
2689 spr_register(env, SPR_MPC_MD_TW, "MD_TW",
2690 SPR_NOACCESS, SPR_NOACCESS,
2691 &spr_read_generic, &spr_write_generic,
2692 0x00000000);
2693 /* XXX : not implemented */
2694 spr_register(env, SPR_MPC_MD_DBCAM, "MD_DBCAM",
2695 SPR_NOACCESS, SPR_NOACCESS,
2696 &spr_read_generic, &spr_write_generic,
2697 0x00000000);
2698 /* XXX : not implemented */
2699 spr_register(env, SPR_MPC_MD_DBRAM0, "MD_DBRAM0",
2700 SPR_NOACCESS, SPR_NOACCESS,
2701 &spr_read_generic, &spr_write_generic,
2702 0x00000000);
2703 /* XXX : not implemented */
2704 spr_register(env, SPR_MPC_MD_DBRAM1, "MD_DBRAM1",
2705 SPR_NOACCESS, SPR_NOACCESS,
2706 &spr_read_generic, &spr_write_generic,
2707 0x00000000);
2708}
2709
j_mayer2662a052007-09-21 05:50:37 +00002710// XXX: TODO
bellard3fc6c082005-07-02 20:59:34 +00002711/*
j_mayer2662a052007-09-21 05:50:37 +00002712 * AMR => SPR 29 (Power 2.04)
2713 * CTRL => SPR 136 (Power 2.04)
2714 * CTRL => SPR 152 (Power 2.04)
j_mayer2662a052007-09-21 05:50:37 +00002715 * SCOMC => SPR 276 (64 bits ?)
2716 * SCOMD => SPR 277 (64 bits ?)
j_mayer2662a052007-09-21 05:50:37 +00002717 * TBU40 => SPR 286 (Power 2.04 hypv)
2718 * HSPRG0 => SPR 304 (Power 2.04 hypv)
2719 * HSPRG1 => SPR 305 (Power 2.04 hypv)
2720 * HDSISR => SPR 306 (Power 2.04 hypv)
2721 * HDAR => SPR 307 (Power 2.04 hypv)
2722 * PURR => SPR 309 (Power 2.04 hypv)
2723 * HDEC => SPR 310 (Power 2.04 hypv)
2724 * HIOR => SPR 311 (hypv)
2725 * RMOR => SPR 312 (970)
2726 * HRMOR => SPR 313 (Power 2.04 hypv)
2727 * HSRR0 => SPR 314 (Power 2.04 hypv)
2728 * HSRR1 => SPR 315 (Power 2.04 hypv)
j_mayer2662a052007-09-21 05:50:37 +00002729 * LPIDR => SPR 317 (970)
j_mayer2662a052007-09-21 05:50:37 +00002730 * EPR => SPR 702 (Power 2.04 emb)
2731 * perf => 768-783 (Power 2.04)
2732 * perf => 784-799 (Power 2.04)
2733 * PPR => SPR 896 (Power 2.04)
2734 * EPLC => SPR 947 (Power 2.04 emb)
2735 * EPSC => SPR 948 (Power 2.04 emb)
2736 * DABRX => 1015 (Power 2.04 hypv)
2737 * FPECR => SPR 1022 (?)
bellard3fc6c082005-07-02 20:59:34 +00002738 * ... and more (thermal management, performance counters, ...)
2739 */
2740
j_mayera750fc02007-09-26 23:54:22 +00002741/*****************************************************************************/
j_mayere1833e12007-09-29 13:06:16 +00002742/* Exception vectors models */
2743static void init_excp_4xx_real (CPUPPCState *env)
2744{
2745#if !defined(CONFIG_USER_ONLY)
2746 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000100;
2747 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
2748 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
2749 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
2750 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
2751 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
2752 env->excp_vectors[POWERPC_EXCP_PIT] = 0x00001000;
2753 env->excp_vectors[POWERPC_EXCP_FIT] = 0x00001010;
2754 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001020;
2755 env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000;
j_mayerfaadf502007-11-03 13:37:12 +00002756 env->ivor_mask = 0x0000FFF0UL;
2757 env->ivpr_mask = 0xFFFF0000UL;
j_mayer1c27f8f2007-10-05 13:09:54 +00002758 /* Hardware reset vector */
2759 env->hreset_vector = 0xFFFFFFFCUL;
j_mayere1833e12007-09-29 13:06:16 +00002760#endif
2761}
2762
2763static void init_excp_4xx_softmmu (CPUPPCState *env)
2764{
2765#if !defined(CONFIG_USER_ONLY)
2766 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000100;
2767 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
2768 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
2769 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
2770 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
2771 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
2772 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
2773 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
2774 env->excp_vectors[POWERPC_EXCP_PIT] = 0x00001000;
2775 env->excp_vectors[POWERPC_EXCP_FIT] = 0x00001010;
2776 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001020;
2777 env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001100;
2778 env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001200;
2779 env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000;
j_mayerfaadf502007-11-03 13:37:12 +00002780 env->ivor_mask = 0x0000FFF0UL;
2781 env->ivpr_mask = 0xFFFF0000UL;
j_mayer1c27f8f2007-10-05 13:09:54 +00002782 /* Hardware reset vector */
2783 env->hreset_vector = 0xFFFFFFFCUL;
j_mayere1833e12007-09-29 13:06:16 +00002784#endif
2785}
2786
j_mayer80d11f42007-11-17 23:02:20 +00002787static void init_excp_MPC5xx (CPUPPCState *env)
2788{
2789#if !defined(CONFIG_USER_ONLY)
2790 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
2791 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
2792 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
2793 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
2794 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
2795 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000900;
2796 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
2797 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
2798 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
2799 env->excp_vectors[POWERPC_EXCP_FPA] = 0x00000E00;
2800 env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001000;
2801 env->excp_vectors[POWERPC_EXCP_DABR] = 0x00001C00;
2802 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001C00;
2803 env->excp_vectors[POWERPC_EXCP_MEXTBR] = 0x00001E00;
2804 env->excp_vectors[POWERPC_EXCP_NMEXTBR] = 0x00001F00;
j_mayer80d11f42007-11-17 23:02:20 +00002805 env->ivor_mask = 0x0000FFF0UL;
2806 env->ivpr_mask = 0xFFFF0000UL;
2807 /* Hardware reset vector */
Fabien Chouteau09d98282013-03-29 02:06:28 +00002808 env->hreset_vector = 0x00000100UL;
j_mayer80d11f42007-11-17 23:02:20 +00002809#endif
2810}
2811
2812static void init_excp_MPC8xx (CPUPPCState *env)
2813{
2814#if !defined(CONFIG_USER_ONLY)
2815 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
2816 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
2817 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
2818 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
2819 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
2820 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
2821 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
2822 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000900;
2823 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
2824 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
2825 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
2826 env->excp_vectors[POWERPC_EXCP_FPA] = 0x00000E00;
2827 env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001000;
2828 env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001100;
2829 env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001200;
2830 env->excp_vectors[POWERPC_EXCP_ITLBE] = 0x00001300;
2831 env->excp_vectors[POWERPC_EXCP_DTLBE] = 0x00001400;
2832 env->excp_vectors[POWERPC_EXCP_DABR] = 0x00001C00;
2833 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001C00;
2834 env->excp_vectors[POWERPC_EXCP_MEXTBR] = 0x00001E00;
2835 env->excp_vectors[POWERPC_EXCP_NMEXTBR] = 0x00001F00;
j_mayer80d11f42007-11-17 23:02:20 +00002836 env->ivor_mask = 0x0000FFF0UL;
2837 env->ivpr_mask = 0xFFFF0000UL;
2838 /* Hardware reset vector */
Fabien Chouteau09d98282013-03-29 02:06:28 +00002839 env->hreset_vector = 0x00000100UL;
j_mayer80d11f42007-11-17 23:02:20 +00002840#endif
2841}
2842
2843static void init_excp_G2 (CPUPPCState *env)
2844{
2845#if !defined(CONFIG_USER_ONLY)
2846 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
2847 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
2848 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
2849 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
2850 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
2851 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
2852 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
2853 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
2854 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
2855 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000A00;
2856 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
2857 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
2858 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
2859 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
2860 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
2861 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
2862 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
j_mayer80d11f42007-11-17 23:02:20 +00002863 /* Hardware reset vector */
Fabien Chouteau09d98282013-03-29 02:06:28 +00002864 env->hreset_vector = 0x00000100UL;
j_mayer80d11f42007-11-17 23:02:20 +00002865#endif
2866}
2867
Alexander Grafe9cd84b2012-06-21 15:17:59 +02002868static void init_excp_e200(CPUPPCState *env, target_ulong ivpr_mask)
j_mayer80d11f42007-11-17 23:02:20 +00002869{
2870#if !defined(CONFIG_USER_ONLY)
2871 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000FFC;
2872 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000000;
2873 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000000;
2874 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000000;
2875 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000000;
2876 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000000;
2877 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000000;
2878 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000000;
2879 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000000;
2880 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000000;
2881 env->excp_vectors[POWERPC_EXCP_APU] = 0x00000000;
2882 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000000;
2883 env->excp_vectors[POWERPC_EXCP_FIT] = 0x00000000;
2884 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00000000;
2885 env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00000000;
2886 env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00000000;
2887 env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00000000;
2888 env->excp_vectors[POWERPC_EXCP_SPEU] = 0x00000000;
2889 env->excp_vectors[POWERPC_EXCP_EFPDI] = 0x00000000;
2890 env->excp_vectors[POWERPC_EXCP_EFPRI] = 0x00000000;
j_mayer80d11f42007-11-17 23:02:20 +00002891 env->ivor_mask = 0x0000FFF7UL;
Alexander Grafe9cd84b2012-06-21 15:17:59 +02002892 env->ivpr_mask = ivpr_mask;
j_mayer80d11f42007-11-17 23:02:20 +00002893 /* Hardware reset vector */
2894 env->hreset_vector = 0xFFFFFFFCUL;
2895#endif
2896}
2897
j_mayere1833e12007-09-29 13:06:16 +00002898static void init_excp_BookE (CPUPPCState *env)
2899{
2900#if !defined(CONFIG_USER_ONLY)
2901 env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000000;
2902 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000000;
2903 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000000;
2904 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000000;
2905 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000000;
2906 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000000;
2907 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000000;
2908 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000000;
2909 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000000;
2910 env->excp_vectors[POWERPC_EXCP_APU] = 0x00000000;
2911 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000000;
2912 env->excp_vectors[POWERPC_EXCP_FIT] = 0x00000000;
2913 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00000000;
2914 env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00000000;
2915 env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00000000;
2916 env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00000000;
Tom Musta8412d112014-09-05 11:39:05 -05002917 env->ivor_mask = 0x0000FFF0UL;
j_mayerfaadf502007-11-03 13:37:12 +00002918 env->ivpr_mask = 0xFFFF0000UL;
j_mayer1c27f8f2007-10-05 13:09:54 +00002919 /* Hardware reset vector */
2920 env->hreset_vector = 0xFFFFFFFCUL;
j_mayere1833e12007-09-29 13:06:16 +00002921#endif
2922}
2923
2924static void init_excp_601 (CPUPPCState *env)
2925{
2926#if !defined(CONFIG_USER_ONLY)
2927 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
2928 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
2929 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
2930 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
2931 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
2932 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
2933 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
2934 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
2935 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
2936 env->excp_vectors[POWERPC_EXCP_IO] = 0x00000A00;
2937 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
2938 env->excp_vectors[POWERPC_EXCP_RUNM] = 0x00002000;
j_mayer1c27f8f2007-10-05 13:09:54 +00002939 /* Hardware reset vector */
j_mayer4e80eff2007-10-08 02:35:41 +00002940 env->hreset_vector = 0x00000100UL;
j_mayere1833e12007-09-29 13:06:16 +00002941#endif
2942}
2943
2944static void init_excp_602 (CPUPPCState *env)
2945{
2946#if !defined(CONFIG_USER_ONLY)
j_mayer082c6682007-11-19 13:22:47 +00002947 /* XXX: exception prefix has a special behavior on 602 */
j_mayere1833e12007-09-29 13:06:16 +00002948 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
2949 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
2950 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
2951 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
2952 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
2953 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
2954 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
2955 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
2956 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
2957 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
2958 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
j_mayere1833e12007-09-29 13:06:16 +00002959 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
2960 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
2961 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
2962 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
2963 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
2964 env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001500;
2965 env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001600;
j_mayer1c27f8f2007-10-05 13:09:54 +00002966 /* Hardware reset vector */
Fabien Chouteau09d98282013-03-29 02:06:28 +00002967 env->hreset_vector = 0x00000100UL;
j_mayere1833e12007-09-29 13:06:16 +00002968#endif
2969}
2970
2971static void init_excp_603 (CPUPPCState *env)
2972{
2973#if !defined(CONFIG_USER_ONLY)
2974 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
2975 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
2976 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
2977 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
2978 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
2979 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
2980 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
2981 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
2982 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
2983 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
2984 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
2985 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
2986 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
2987 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
2988 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
2989 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
j_mayer1c27f8f2007-10-05 13:09:54 +00002990 /* Hardware reset vector */
Fabien Chouteau09d98282013-03-29 02:06:28 +00002991 env->hreset_vector = 0x00000100UL;
j_mayere1833e12007-09-29 13:06:16 +00002992#endif
2993}
2994
j_mayere1833e12007-09-29 13:06:16 +00002995static void init_excp_604 (CPUPPCState *env)
2996{
2997#if !defined(CONFIG_USER_ONLY)
2998 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
2999 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3000 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3001 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3002 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3003 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3004 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3005 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3006 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3007 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3008 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3009 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3010 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3011 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
j_mayer1c27f8f2007-10-05 13:09:54 +00003012 /* Hardware reset vector */
Tristan Gingold2d3eb7b2009-04-28 18:07:01 +00003013 env->hreset_vector = 0x00000100UL;
j_mayere1833e12007-09-29 13:06:16 +00003014#endif
3015}
3016
j_mayere1833e12007-09-29 13:06:16 +00003017static void init_excp_7x0 (CPUPPCState *env)
3018{
3019#if !defined(CONFIG_USER_ONLY)
3020 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3021 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3022 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3023 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3024 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3025 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3026 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3027 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3028 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3029 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3030 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3031 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3032 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
j_mayerbd928eb2007-11-21 13:08:23 +00003033 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
j_mayere1833e12007-09-29 13:06:16 +00003034 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
j_mayer1c27f8f2007-10-05 13:09:54 +00003035 /* Hardware reset vector */
Fabien Chouteau09d98282013-03-29 02:06:28 +00003036 env->hreset_vector = 0x00000100UL;
j_mayere1833e12007-09-29 13:06:16 +00003037#endif
3038}
3039
j_mayerbd928eb2007-11-21 13:08:23 +00003040static void init_excp_750cl (CPUPPCState *env)
j_mayere1833e12007-09-29 13:06:16 +00003041{
3042#if !defined(CONFIG_USER_ONLY)
3043 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3044 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3045 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3046 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3047 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3048 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3049 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3050 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3051 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3052 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3053 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3054 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3055 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3056 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
j_mayerbd928eb2007-11-21 13:08:23 +00003057 /* Hardware reset vector */
Fabien Chouteau09d98282013-03-29 02:06:28 +00003058 env->hreset_vector = 0x00000100UL;
j_mayerbd928eb2007-11-21 13:08:23 +00003059#endif
3060}
3061
3062static void init_excp_750cx (CPUPPCState *env)
3063{
3064#if !defined(CONFIG_USER_ONLY)
3065 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3066 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3067 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3068 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3069 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3070 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3071 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3072 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3073 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3074 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3075 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3076 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3077 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
j_mayere1833e12007-09-29 13:06:16 +00003078 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
j_mayer1c27f8f2007-10-05 13:09:54 +00003079 /* Hardware reset vector */
Fabien Chouteau09d98282013-03-29 02:06:28 +00003080 env->hreset_vector = 0x00000100UL;
j_mayere1833e12007-09-29 13:06:16 +00003081#endif
3082}
3083
j_mayer7a3a6922007-10-08 02:23:00 +00003084/* XXX: Check if this is correct */
3085static void init_excp_7x5 (CPUPPCState *env)
3086{
3087#if !defined(CONFIG_USER_ONLY)
3088 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3089 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3090 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3091 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3092 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3093 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3094 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3095 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3096 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3097 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3098 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
j_mayerbd928eb2007-11-21 13:08:23 +00003099 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
j_mayer7a3a6922007-10-08 02:23:00 +00003100 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
3101 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
3102 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
j_mayer7a3a6922007-10-08 02:23:00 +00003103 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3104 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
j_mayerbd928eb2007-11-21 13:08:23 +00003105 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
j_mayer7a3a6922007-10-08 02:23:00 +00003106 /* Hardware reset vector */
Fabien Chouteau09d98282013-03-29 02:06:28 +00003107 env->hreset_vector = 0x00000100UL;
j_mayer7a3a6922007-10-08 02:23:00 +00003108#endif
3109}
3110
j_mayere1833e12007-09-29 13:06:16 +00003111static void init_excp_7400 (CPUPPCState *env)
3112{
3113#if !defined(CONFIG_USER_ONLY)
3114 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3115 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3116 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3117 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3118 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3119 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3120 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3121 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3122 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3123 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3124 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3125 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3126 env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
3127 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3128 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3129 env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600;
3130 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
j_mayer1c27f8f2007-10-05 13:09:54 +00003131 /* Hardware reset vector */
Fabien Chouteau09d98282013-03-29 02:06:28 +00003132 env->hreset_vector = 0x00000100UL;
j_mayere1833e12007-09-29 13:06:16 +00003133#endif
3134}
3135
j_mayere1833e12007-09-29 13:06:16 +00003136static void init_excp_7450 (CPUPPCState *env)
3137{
3138#if !defined(CONFIG_USER_ONLY)
3139 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3140 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3141 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3142 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3143 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3144 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3145 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3146 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3147 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3148 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3149 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3150 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3151 env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
3152 env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
3153 env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
3154 env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
3155 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3156 env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
3157 env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600;
j_mayer1c27f8f2007-10-05 13:09:54 +00003158 /* Hardware reset vector */
Fabien Chouteau09d98282013-03-29 02:06:28 +00003159 env->hreset_vector = 0x00000100UL;
j_mayere1833e12007-09-29 13:06:16 +00003160#endif
3161}
j_mayere1833e12007-09-29 13:06:16 +00003162
3163#if defined (TARGET_PPC64)
3164static void init_excp_970 (CPUPPCState *env)
3165{
3166#if !defined(CONFIG_USER_ONLY)
3167 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3168 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3169 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3170 env->excp_vectors[POWERPC_EXCP_DSEG] = 0x00000380;
3171 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3172 env->excp_vectors[POWERPC_EXCP_ISEG] = 0x00000480;
3173 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3174 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3175 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3176 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3177 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
j_mayere1833e12007-09-29 13:06:16 +00003178 env->excp_vectors[POWERPC_EXCP_HDECR] = 0x00000980;
j_mayere1833e12007-09-29 13:06:16 +00003179 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3180 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
3181 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3182 env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
3183 env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
3184 env->excp_vectors[POWERPC_EXCP_MAINT] = 0x00001600;
3185 env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001700;
3186 env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001800;
j_mayer1c27f8f2007-10-05 13:09:54 +00003187 /* Hardware reset vector */
3188 env->hreset_vector = 0x0000000000000100ULL;
j_mayere1833e12007-09-29 13:06:16 +00003189#endif
3190}
David Gibson9d52e902011-04-01 15:15:19 +11003191
3192static void init_excp_POWER7 (CPUPPCState *env)
3193{
3194#if !defined(CONFIG_USER_ONLY)
3195 env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
3196 env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
3197 env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
3198 env->excp_vectors[POWERPC_EXCP_DSEG] = 0x00000380;
3199 env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
3200 env->excp_vectors[POWERPC_EXCP_ISEG] = 0x00000480;
3201 env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
3202 env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
3203 env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
3204 env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
3205 env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
3206 env->excp_vectors[POWERPC_EXCP_HDECR] = 0x00000980;
3207 env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
3208 env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
Benjamin Herrenschmidtf03a1af2016-06-21 23:48:49 +02003209 env->excp_vectors[POWERPC_EXCP_HDSI] = 0x00000E00;
3210 env->excp_vectors[POWERPC_EXCP_HISI] = 0x00000E20;
3211 env->excp_vectors[POWERPC_EXCP_HV_EMU] = 0x00000E40;
3212 env->excp_vectors[POWERPC_EXCP_HV_MAINT] = 0x00000E60;
David Gibson9d52e902011-04-01 15:15:19 +11003213 env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
3214 env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
Tom Musta1f298712013-10-22 22:06:17 +11003215 env->excp_vectors[POWERPC_EXCP_VSXU] = 0x00000F40;
David Gibson9d52e902011-04-01 15:15:19 +11003216 /* Hardware reset vector */
3217 env->hreset_vector = 0x0000000000000100ULL;
3218#endif
3219}
Benjamin Herrenschmidtf03a1af2016-06-21 23:48:49 +02003220
3221static void init_excp_POWER8(CPUPPCState *env)
3222{
3223 init_excp_POWER7(env);
3224
3225#if !defined(CONFIG_USER_ONLY)
3226 env->excp_vectors[POWERPC_EXCP_SDOOR] = 0x00000A00;
3227 env->excp_vectors[POWERPC_EXCP_FU] = 0x00000F60;
3228 env->excp_vectors[POWERPC_EXCP_HV_FU] = 0x00000F80;
3229 env->excp_vectors[POWERPC_EXCP_SDOOR_HV] = 0x00000E80;
3230#endif
3231}
3232
j_mayere1833e12007-09-29 13:06:16 +00003233#endif
3234
3235/*****************************************************************************/
j_mayer2f462812007-10-25 23:14:50 +00003236/* Power management enable checks */
3237static int check_pow_none (CPUPPCState *env)
3238{
3239 return 0;
3240}
3241
3242static int check_pow_nocheck (CPUPPCState *env)
3243{
3244 return 1;
3245}
3246
3247static int check_pow_hid0 (CPUPPCState *env)
3248{
3249 if (env->spr[SPR_HID0] & 0x00E00000)
3250 return 1;
3251
3252 return 0;
3253}
3254
j_mayer4e777442007-12-10 07:40:16 +00003255static int check_pow_hid0_74xx (CPUPPCState *env)
3256{
3257 if (env->spr[SPR_HID0] & 0x00600000)
3258 return 1;
3259
3260 return 0;
3261}
3262
Greg Kurz382d2db2014-05-19 19:59:05 +02003263static bool ppc_cpu_interrupts_big_endian_always(PowerPCCPU *cpu)
3264{
3265 return true;
3266}
3267
3268#ifdef TARGET_PPC64
3269static bool ppc_cpu_interrupts_big_endian_lpcr(PowerPCCPU *cpu)
3270{
3271 return !(cpu->env.spr[SPR_LPCR] & LPCR_ILE);
3272}
3273#endif
3274
j_mayer2f462812007-10-25 23:14:50 +00003275/*****************************************************************************/
j_mayera750fc02007-09-26 23:54:22 +00003276/* PowerPC implementations definitions */
3277
Andreas Färber7856e3a2013-02-17 23:16:42 +00003278#define POWERPC_FAMILY(_name) \
3279 static void \
3280 glue(glue(ppc_, _name), _cpu_family_class_init)(ObjectClass *, void *); \
3281 \
3282 static const TypeInfo \
3283 glue(glue(ppc_, _name), _cpu_family_type_info) = { \
3284 .name = stringify(_name) "-family-" TYPE_POWERPC_CPU, \
3285 .parent = TYPE_POWERPC_CPU, \
3286 .abstract = true, \
3287 .class_init = glue(glue(ppc_, _name), _cpu_family_class_init), \
3288 }; \
3289 \
3290 static void glue(glue(ppc_, _name), _cpu_family_register_types)(void) \
3291 { \
3292 type_register_static( \
3293 &glue(glue(ppc_, _name), _cpu_family_type_info)); \
3294 } \
3295 \
3296 type_init(glue(glue(ppc_, _name), _cpu_family_register_types)) \
3297 \
3298 static void glue(glue(ppc_, _name), _cpu_family_class_init)
3299
j_mayera750fc02007-09-26 23:54:22 +00003300static void init_proc_401 (CPUPPCState *env)
3301{
3302 gen_spr_40x(env);
3303 gen_spr_401_403(env);
3304 gen_spr_401(env);
j_mayere1833e12007-09-29 13:06:16 +00003305 init_excp_4xx_real(env);
j_mayerd63001d2007-10-04 00:51:58 +00003306 env->dcache_line_size = 32;
3307 env->icache_line_size = 32;
j_mayer4e290a02007-10-01 01:27:10 +00003308 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01003309 ppc40x_irq_init(ppc_env_get_cpu(env));
Fabien Chouteauddd10552011-09-13 04:00:32 +00003310
3311 SET_FIT_PERIOD(12, 16, 20, 24);
3312 SET_WDT_PERIOD(16, 20, 24, 28);
j_mayera750fc02007-09-26 23:54:22 +00003313}
3314
Andreas Färber7856e3a2013-02-17 23:16:42 +00003315POWERPC_FAMILY(401)(ObjectClass *oc, void *data)
3316{
Andreas Färberca5dff02013-02-17 23:16:46 +00003317 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00003318 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3319
Andreas Färberca5dff02013-02-17 23:16:46 +00003320 dc->desc = "PowerPC 401";
Andreas Färber7856e3a2013-02-17 23:16:42 +00003321 pcc->init_proc = init_proc_401;
3322 pcc->check_pow = check_pow_nocheck;
Andreas Färber53116eb2013-02-17 23:16:43 +00003323 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3324 PPC_WRTEE | PPC_DCR |
3325 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3326 PPC_CACHE_DCBZ |
3327 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3328 PPC_4xx_COMMON | PPC_40x_EXCP;
Tom Musta9df5a462014-04-15 12:21:12 -05003329 pcc->msr_mask = (1ull << MSR_KEY) |
3330 (1ull << MSR_POW) |
3331 (1ull << MSR_CE) |
3332 (1ull << MSR_ILE) |
3333 (1ull << MSR_EE) |
3334 (1ull << MSR_PR) |
3335 (1ull << MSR_ME) |
3336 (1ull << MSR_DE) |
3337 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00003338 pcc->mmu_model = POWERPC_MMU_REAL;
3339 pcc->excp_model = POWERPC_EXCP_40x;
3340 pcc->bus_model = PPC_FLAGS_INPUT_401;
3341 pcc->bfd_mach = bfd_mach_ppc_403;
3342 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3343 POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00003344}
3345
j_mayera750fc02007-09-26 23:54:22 +00003346static void init_proc_401x2 (CPUPPCState *env)
3347{
3348 gen_spr_40x(env);
3349 gen_spr_401_403(env);
3350 gen_spr_401x2(env);
3351 gen_spr_compress(env);
j_mayera750fc02007-09-26 23:54:22 +00003352 /* Memory management */
j_mayerf2e63a42007-10-07 15:43:50 +00003353#if !defined(CONFIG_USER_ONLY)
j_mayera750fc02007-09-26 23:54:22 +00003354 env->nb_tlb = 64;
3355 env->nb_ways = 1;
3356 env->id_tlbs = 0;
Alexander Graf1c53acc2011-06-17 01:00:28 +02003357 env->tlb_type = TLB_EMB;
j_mayerf2e63a42007-10-07 15:43:50 +00003358#endif
j_mayere1833e12007-09-29 13:06:16 +00003359 init_excp_4xx_softmmu(env);
j_mayerd63001d2007-10-04 00:51:58 +00003360 env->dcache_line_size = 32;
3361 env->icache_line_size = 32;
j_mayer4e290a02007-10-01 01:27:10 +00003362 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01003363 ppc40x_irq_init(ppc_env_get_cpu(env));
Fabien Chouteauddd10552011-09-13 04:00:32 +00003364
3365 SET_FIT_PERIOD(12, 16, 20, 24);
3366 SET_WDT_PERIOD(16, 20, 24, 28);
j_mayera750fc02007-09-26 23:54:22 +00003367}
3368
Andreas Färber7856e3a2013-02-17 23:16:42 +00003369POWERPC_FAMILY(401x2)(ObjectClass *oc, void *data)
3370{
Andreas Färberca5dff02013-02-17 23:16:46 +00003371 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00003372 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3373
Andreas Färberca5dff02013-02-17 23:16:46 +00003374 dc->desc = "PowerPC 401x2";
Andreas Färber7856e3a2013-02-17 23:16:42 +00003375 pcc->init_proc = init_proc_401x2;
3376 pcc->check_pow = check_pow_nocheck;
Andreas Färber53116eb2013-02-17 23:16:43 +00003377 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
3378 PPC_DCR | PPC_WRTEE |
3379 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3380 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3381 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3382 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3383 PPC_4xx_COMMON | PPC_40x_EXCP;
Tom Musta9df5a462014-04-15 12:21:12 -05003384 pcc->msr_mask = (1ull << 20) |
3385 (1ull << MSR_KEY) |
3386 (1ull << MSR_POW) |
3387 (1ull << MSR_CE) |
3388 (1ull << MSR_ILE) |
3389 (1ull << MSR_EE) |
3390 (1ull << MSR_PR) |
3391 (1ull << MSR_ME) |
3392 (1ull << MSR_DE) |
3393 (1ull << MSR_IR) |
3394 (1ull << MSR_DR) |
3395 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00003396 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3397 pcc->excp_model = POWERPC_EXCP_40x;
3398 pcc->bus_model = PPC_FLAGS_INPUT_401;
3399 pcc->bfd_mach = bfd_mach_ppc_403;
3400 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3401 POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00003402}
3403
j_mayere1833e12007-09-29 13:06:16 +00003404static void init_proc_401x3 (CPUPPCState *env)
j_mayera750fc02007-09-26 23:54:22 +00003405{
j_mayer4e290a02007-10-01 01:27:10 +00003406 gen_spr_40x(env);
3407 gen_spr_401_403(env);
3408 gen_spr_401(env);
3409 gen_spr_401x2(env);
3410 gen_spr_compress(env);
j_mayere1833e12007-09-29 13:06:16 +00003411 init_excp_4xx_softmmu(env);
j_mayerd63001d2007-10-04 00:51:58 +00003412 env->dcache_line_size = 32;
3413 env->icache_line_size = 32;
j_mayer4e290a02007-10-01 01:27:10 +00003414 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01003415 ppc40x_irq_init(ppc_env_get_cpu(env));
Fabien Chouteauddd10552011-09-13 04:00:32 +00003416
3417 SET_FIT_PERIOD(12, 16, 20, 24);
3418 SET_WDT_PERIOD(16, 20, 24, 28);
j_mayera750fc02007-09-26 23:54:22 +00003419}
j_mayera750fc02007-09-26 23:54:22 +00003420
Andreas Färber7856e3a2013-02-17 23:16:42 +00003421POWERPC_FAMILY(401x3)(ObjectClass *oc, void *data)
3422{
Andreas Färberca5dff02013-02-17 23:16:46 +00003423 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00003424 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3425
Andreas Färberca5dff02013-02-17 23:16:46 +00003426 dc->desc = "PowerPC 401x3";
Andreas Färber7856e3a2013-02-17 23:16:42 +00003427 pcc->init_proc = init_proc_401x3;
3428 pcc->check_pow = check_pow_nocheck;
Andreas Färber53116eb2013-02-17 23:16:43 +00003429 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
3430 PPC_DCR | PPC_WRTEE |
3431 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3432 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3433 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3434 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3435 PPC_4xx_COMMON | PPC_40x_EXCP;
Tom Musta9df5a462014-04-15 12:21:12 -05003436 pcc->msr_mask = (1ull << 20) |
3437 (1ull << MSR_KEY) |
3438 (1ull << MSR_POW) |
3439 (1ull << MSR_CE) |
3440 (1ull << MSR_ILE) |
3441 (1ull << MSR_EE) |
3442 (1ull << MSR_PR) |
3443 (1ull << MSR_ME) |
3444 (1ull << MSR_DWE) |
3445 (1ull << MSR_DE) |
3446 (1ull << MSR_IR) |
3447 (1ull << MSR_DR) |
3448 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00003449 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3450 pcc->excp_model = POWERPC_EXCP_40x;
3451 pcc->bus_model = PPC_FLAGS_INPUT_401;
3452 pcc->bfd_mach = bfd_mach_ppc_403;
3453 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3454 POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00003455}
3456
j_mayera750fc02007-09-26 23:54:22 +00003457static void init_proc_IOP480 (CPUPPCState *env)
3458{
3459 gen_spr_40x(env);
3460 gen_spr_401_403(env);
3461 gen_spr_401x2(env);
3462 gen_spr_compress(env);
j_mayera750fc02007-09-26 23:54:22 +00003463 /* Memory management */
j_mayerf2e63a42007-10-07 15:43:50 +00003464#if !defined(CONFIG_USER_ONLY)
j_mayera750fc02007-09-26 23:54:22 +00003465 env->nb_tlb = 64;
3466 env->nb_ways = 1;
3467 env->id_tlbs = 0;
Alexander Graf1c53acc2011-06-17 01:00:28 +02003468 env->tlb_type = TLB_EMB;
j_mayerf2e63a42007-10-07 15:43:50 +00003469#endif
j_mayere1833e12007-09-29 13:06:16 +00003470 init_excp_4xx_softmmu(env);
j_mayerd63001d2007-10-04 00:51:58 +00003471 env->dcache_line_size = 32;
3472 env->icache_line_size = 32;
j_mayer4e290a02007-10-01 01:27:10 +00003473 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01003474 ppc40x_irq_init(ppc_env_get_cpu(env));
Fabien Chouteauddd10552011-09-13 04:00:32 +00003475
3476 SET_FIT_PERIOD(8, 12, 16, 20);
3477 SET_WDT_PERIOD(16, 20, 24, 28);
j_mayera750fc02007-09-26 23:54:22 +00003478}
3479
Andreas Färber7856e3a2013-02-17 23:16:42 +00003480POWERPC_FAMILY(IOP480)(ObjectClass *oc, void *data)
3481{
Andreas Färberca5dff02013-02-17 23:16:46 +00003482 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00003483 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3484
Andreas Färberca5dff02013-02-17 23:16:46 +00003485 dc->desc = "IOP480";
Andreas Färber7856e3a2013-02-17 23:16:42 +00003486 pcc->init_proc = init_proc_IOP480;
3487 pcc->check_pow = check_pow_nocheck;
Andreas Färber53116eb2013-02-17 23:16:43 +00003488 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3489 PPC_DCR | PPC_WRTEE |
3490 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3491 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3492 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3493 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3494 PPC_4xx_COMMON | PPC_40x_EXCP;
Tom Musta9df5a462014-04-15 12:21:12 -05003495 pcc->msr_mask = (1ull << 20) |
3496 (1ull << MSR_KEY) |
3497 (1ull << MSR_POW) |
3498 (1ull << MSR_CE) |
3499 (1ull << MSR_ILE) |
3500 (1ull << MSR_EE) |
3501 (1ull << MSR_PR) |
3502 (1ull << MSR_ME) |
3503 (1ull << MSR_DE) |
3504 (1ull << MSR_IR) |
3505 (1ull << MSR_DR) |
3506 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00003507 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3508 pcc->excp_model = POWERPC_EXCP_40x;
3509 pcc->bus_model = PPC_FLAGS_INPUT_401;
3510 pcc->bfd_mach = bfd_mach_ppc_403;
3511 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
3512 POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00003513}
3514
j_mayera750fc02007-09-26 23:54:22 +00003515static void init_proc_403 (CPUPPCState *env)
3516{
3517 gen_spr_40x(env);
3518 gen_spr_401_403(env);
3519 gen_spr_403(env);
3520 gen_spr_403_real(env);
j_mayere1833e12007-09-29 13:06:16 +00003521 init_excp_4xx_real(env);
j_mayerd63001d2007-10-04 00:51:58 +00003522 env->dcache_line_size = 32;
3523 env->icache_line_size = 32;
j_mayer4e290a02007-10-01 01:27:10 +00003524 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01003525 ppc40x_irq_init(ppc_env_get_cpu(env));
Fabien Chouteauddd10552011-09-13 04:00:32 +00003526
3527 SET_FIT_PERIOD(8, 12, 16, 20);
3528 SET_WDT_PERIOD(16, 20, 24, 28);
j_mayera750fc02007-09-26 23:54:22 +00003529}
3530
Andreas Färber7856e3a2013-02-17 23:16:42 +00003531POWERPC_FAMILY(403)(ObjectClass *oc, void *data)
3532{
Andreas Färberca5dff02013-02-17 23:16:46 +00003533 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00003534 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3535
Andreas Färberca5dff02013-02-17 23:16:46 +00003536 dc->desc = "PowerPC 403";
Andreas Färber7856e3a2013-02-17 23:16:42 +00003537 pcc->init_proc = init_proc_403;
3538 pcc->check_pow = check_pow_nocheck;
Andreas Färber53116eb2013-02-17 23:16:43 +00003539 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3540 PPC_DCR | PPC_WRTEE |
3541 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3542 PPC_CACHE_DCBZ |
3543 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3544 PPC_4xx_COMMON | PPC_40x_EXCP;
Tom Musta9df5a462014-04-15 12:21:12 -05003545 pcc->msr_mask = (1ull << MSR_POW) |
3546 (1ull << MSR_CE) |
3547 (1ull << MSR_ILE) |
3548 (1ull << MSR_EE) |
3549 (1ull << MSR_PR) |
3550 (1ull << MSR_ME) |
3551 (1ull << MSR_PE) |
3552 (1ull << MSR_PX) |
3553 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00003554 pcc->mmu_model = POWERPC_MMU_REAL;
3555 pcc->excp_model = POWERPC_EXCP_40x;
3556 pcc->bus_model = PPC_FLAGS_INPUT_401;
3557 pcc->bfd_mach = bfd_mach_ppc_403;
3558 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_PX |
3559 POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00003560}
3561
j_mayera750fc02007-09-26 23:54:22 +00003562static void init_proc_403GCX (CPUPPCState *env)
3563{
3564 gen_spr_40x(env);
3565 gen_spr_401_403(env);
3566 gen_spr_403(env);
3567 gen_spr_403_real(env);
3568 gen_spr_403_mmu(env);
3569 /* Bus access control */
Stefan Weil5cbdb3a2012-04-07 09:23:39 +02003570 /* not emulated, as QEMU never does speculative access */
j_mayera750fc02007-09-26 23:54:22 +00003571 spr_register(env, SPR_40x_SGR, "SGR",
3572 SPR_NOACCESS, SPR_NOACCESS,
3573 &spr_read_generic, &spr_write_generic,
3574 0xFFFFFFFF);
Stefan Weil5cbdb3a2012-04-07 09:23:39 +02003575 /* not emulated, as QEMU do not emulate caches */
j_mayera750fc02007-09-26 23:54:22 +00003576 spr_register(env, SPR_40x_DCWR, "DCWR",
3577 SPR_NOACCESS, SPR_NOACCESS,
3578 &spr_read_generic, &spr_write_generic,
3579 0x00000000);
3580 /* Memory management */
j_mayerf2e63a42007-10-07 15:43:50 +00003581#if !defined(CONFIG_USER_ONLY)
j_mayera750fc02007-09-26 23:54:22 +00003582 env->nb_tlb = 64;
3583 env->nb_ways = 1;
3584 env->id_tlbs = 0;
Alexander Graf1c53acc2011-06-17 01:00:28 +02003585 env->tlb_type = TLB_EMB;
j_mayerf2e63a42007-10-07 15:43:50 +00003586#endif
j_mayere1833e12007-09-29 13:06:16 +00003587 init_excp_4xx_softmmu(env);
j_mayerd63001d2007-10-04 00:51:58 +00003588 env->dcache_line_size = 32;
3589 env->icache_line_size = 32;
j_mayer4e290a02007-10-01 01:27:10 +00003590 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01003591 ppc40x_irq_init(ppc_env_get_cpu(env));
Fabien Chouteauddd10552011-09-13 04:00:32 +00003592
3593 SET_FIT_PERIOD(8, 12, 16, 20);
3594 SET_WDT_PERIOD(16, 20, 24, 28);
j_mayera750fc02007-09-26 23:54:22 +00003595}
3596
Andreas Färber7856e3a2013-02-17 23:16:42 +00003597POWERPC_FAMILY(403GCX)(ObjectClass *oc, void *data)
3598{
Andreas Färberca5dff02013-02-17 23:16:46 +00003599 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00003600 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3601
Andreas Färberca5dff02013-02-17 23:16:46 +00003602 dc->desc = "PowerPC 403 GCX";
Andreas Färber7856e3a2013-02-17 23:16:42 +00003603 pcc->init_proc = init_proc_403GCX;
3604 pcc->check_pow = check_pow_nocheck;
Andreas Färber53116eb2013-02-17 23:16:43 +00003605 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3606 PPC_DCR | PPC_WRTEE |
3607 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3608 PPC_CACHE_DCBZ |
3609 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3610 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3611 PPC_4xx_COMMON | PPC_40x_EXCP;
Tom Musta9df5a462014-04-15 12:21:12 -05003612 pcc->msr_mask = (1ull << MSR_POW) |
3613 (1ull << MSR_CE) |
3614 (1ull << MSR_ILE) |
3615 (1ull << MSR_EE) |
3616 (1ull << MSR_PR) |
3617 (1ull << MSR_ME) |
3618 (1ull << MSR_PE) |
3619 (1ull << MSR_PX) |
3620 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00003621 pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
3622 pcc->excp_model = POWERPC_EXCP_40x;
3623 pcc->bus_model = PPC_FLAGS_INPUT_401;
3624 pcc->bfd_mach = bfd_mach_ppc_403;
3625 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_PX |
3626 POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00003627}
3628
j_mayera750fc02007-09-26 23:54:22 +00003629static void init_proc_405 (CPUPPCState *env)
3630{
3631 /* Time base */
3632 gen_tbl(env);
3633 gen_spr_40x(env);
3634 gen_spr_405(env);
3635 /* Bus access control */
Stefan Weil5cbdb3a2012-04-07 09:23:39 +02003636 /* not emulated, as QEMU never does speculative access */
j_mayera750fc02007-09-26 23:54:22 +00003637 spr_register(env, SPR_40x_SGR, "SGR",
3638 SPR_NOACCESS, SPR_NOACCESS,
3639 &spr_read_generic, &spr_write_generic,
3640 0xFFFFFFFF);
Stefan Weil5cbdb3a2012-04-07 09:23:39 +02003641 /* not emulated, as QEMU do not emulate caches */
j_mayera750fc02007-09-26 23:54:22 +00003642 spr_register(env, SPR_40x_DCWR, "DCWR",
3643 SPR_NOACCESS, SPR_NOACCESS,
3644 &spr_read_generic, &spr_write_generic,
3645 0x00000000);
3646 /* Memory management */
j_mayerf2e63a42007-10-07 15:43:50 +00003647#if !defined(CONFIG_USER_ONLY)
j_mayera750fc02007-09-26 23:54:22 +00003648 env->nb_tlb = 64;
3649 env->nb_ways = 1;
3650 env->id_tlbs = 0;
Alexander Graf1c53acc2011-06-17 01:00:28 +02003651 env->tlb_type = TLB_EMB;
j_mayerf2e63a42007-10-07 15:43:50 +00003652#endif
j_mayere1833e12007-09-29 13:06:16 +00003653 init_excp_4xx_softmmu(env);
j_mayerd63001d2007-10-04 00:51:58 +00003654 env->dcache_line_size = 32;
3655 env->icache_line_size = 32;
j_mayera750fc02007-09-26 23:54:22 +00003656 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01003657 ppc40x_irq_init(ppc_env_get_cpu(env));
Fabien Chouteauddd10552011-09-13 04:00:32 +00003658
3659 SET_FIT_PERIOD(8, 12, 16, 20);
3660 SET_WDT_PERIOD(16, 20, 24, 28);
j_mayera750fc02007-09-26 23:54:22 +00003661}
3662
Andreas Färber7856e3a2013-02-17 23:16:42 +00003663POWERPC_FAMILY(405)(ObjectClass *oc, void *data)
3664{
Andreas Färberca5dff02013-02-17 23:16:46 +00003665 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00003666 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3667
Andreas Färberca5dff02013-02-17 23:16:46 +00003668 dc->desc = "PowerPC 405";
Andreas Färber7856e3a2013-02-17 23:16:42 +00003669 pcc->init_proc = init_proc_405;
3670 pcc->check_pow = check_pow_nocheck;
Andreas Färber53116eb2013-02-17 23:16:43 +00003671 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
3672 PPC_DCR | PPC_WRTEE |
3673 PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
3674 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3675 PPC_MEM_SYNC | PPC_MEM_EIEIO |
3676 PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
3677 PPC_4xx_COMMON | PPC_405_MAC | PPC_40x_EXCP;
Tom Musta9df5a462014-04-15 12:21:12 -05003678 pcc->msr_mask = (1ull << MSR_POW) |
3679 (1ull << MSR_CE) |
3680 (1ull << MSR_EE) |
3681 (1ull << MSR_PR) |
3682 (1ull << MSR_FP) |
3683 (1ull << MSR_DWE) |
3684 (1ull << MSR_DE) |
3685 (1ull << MSR_IR) |
3686 (1ull << MSR_DR);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00003687 pcc->mmu_model = POWERPC_MMU_SOFT_4xx;
3688 pcc->excp_model = POWERPC_EXCP_40x;
3689 pcc->bus_model = PPC_FLAGS_INPUT_405;
3690 pcc->bfd_mach = bfd_mach_ppc_403;
3691 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
3692 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00003693}
3694
j_mayera750fc02007-09-26 23:54:22 +00003695static void init_proc_440EP (CPUPPCState *env)
3696{
3697 /* Time base */
3698 gen_tbl(env);
j_mayer80d11f42007-11-17 23:02:20 +00003699 gen_spr_BookE(env, 0x000000000000FFFFULL);
j_mayera750fc02007-09-26 23:54:22 +00003700 gen_spr_440(env);
j_mayer80d11f42007-11-17 23:02:20 +00003701 gen_spr_usprgh(env);
3702 /* Processor identification */
3703 spr_register(env, SPR_BOOKE_PIR, "PIR",
3704 SPR_NOACCESS, SPR_NOACCESS,
3705 &spr_read_generic, &spr_write_pir,
3706 0x00000000);
3707 /* XXX : not implemented */
3708 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
3709 SPR_NOACCESS, SPR_NOACCESS,
3710 &spr_read_generic, &spr_write_generic,
3711 0x00000000);
3712 /* XXX : not implemented */
3713 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
3714 SPR_NOACCESS, SPR_NOACCESS,
3715 &spr_read_generic, &spr_write_generic,
3716 0x00000000);
3717 /* XXX : not implemented */
3718 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
3719 SPR_NOACCESS, SPR_NOACCESS,
3720 &spr_read_generic, &spr_write_generic,
3721 0x00000000);
3722 /* XXX : not implemented */
3723 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
3724 SPR_NOACCESS, SPR_NOACCESS,
3725 &spr_read_generic, &spr_write_generic,
3726 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00003727 /* XXX : not implemented */
j_mayera750fc02007-09-26 23:54:22 +00003728 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
3729 SPR_NOACCESS, SPR_NOACCESS,
3730 &spr_read_generic, &spr_write_generic,
3731 0x00000000);
3732 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
3733 SPR_NOACCESS, SPR_NOACCESS,
3734 &spr_read_generic, &spr_write_generic,
3735 0x00000000);
3736 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
3737 SPR_NOACCESS, SPR_NOACCESS,
3738 &spr_read_generic, &spr_write_generic,
3739 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00003740 /* XXX : not implemented */
j_mayera750fc02007-09-26 23:54:22 +00003741 spr_register(env, SPR_440_CCR1, "CCR1",
3742 SPR_NOACCESS, SPR_NOACCESS,
3743 &spr_read_generic, &spr_write_generic,
3744 0x00000000);
3745 /* Memory management */
j_mayerf2e63a42007-10-07 15:43:50 +00003746#if !defined(CONFIG_USER_ONLY)
j_mayera750fc02007-09-26 23:54:22 +00003747 env->nb_tlb = 64;
3748 env->nb_ways = 1;
3749 env->id_tlbs = 0;
Alexander Graf1c53acc2011-06-17 01:00:28 +02003750 env->tlb_type = TLB_EMB;
j_mayerf2e63a42007-10-07 15:43:50 +00003751#endif
j_mayere1833e12007-09-29 13:06:16 +00003752 init_excp_BookE(env);
j_mayerd63001d2007-10-04 00:51:58 +00003753 env->dcache_line_size = 32;
3754 env->icache_line_size = 32;
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01003755 ppc40x_irq_init(ppc_env_get_cpu(env));
Fabien Chouteauddd10552011-09-13 04:00:32 +00003756
3757 SET_FIT_PERIOD(12, 16, 20, 24);
3758 SET_WDT_PERIOD(20, 24, 28, 32);
j_mayera750fc02007-09-26 23:54:22 +00003759}
3760
Andreas Färber7856e3a2013-02-17 23:16:42 +00003761POWERPC_FAMILY(440EP)(ObjectClass *oc, void *data)
3762{
Andreas Färberca5dff02013-02-17 23:16:46 +00003763 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00003764 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3765
Andreas Färberca5dff02013-02-17 23:16:46 +00003766 dc->desc = "PowerPC 440 EP";
Andreas Färber7856e3a2013-02-17 23:16:42 +00003767 pcc->init_proc = init_proc_440EP;
3768 pcc->check_pow = check_pow_nocheck;
Andreas Färber53116eb2013-02-17 23:16:43 +00003769 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3770 PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL |
3771 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
3772 PPC_FLOAT_STFIWX |
3773 PPC_DCR | PPC_WRTEE | PPC_RFMCI |
3774 PPC_CACHE | PPC_CACHE_ICBI |
3775 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3776 PPC_MEM_TLBSYNC | PPC_MFTB |
3777 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
3778 PPC_440_SPEC;
Tom Musta9df5a462014-04-15 12:21:12 -05003779 pcc->msr_mask = (1ull << MSR_POW) |
3780 (1ull << MSR_CE) |
3781 (1ull << MSR_EE) |
3782 (1ull << MSR_PR) |
3783 (1ull << MSR_FP) |
3784 (1ull << MSR_ME) |
3785 (1ull << MSR_FE0) |
3786 (1ull << MSR_DWE) |
3787 (1ull << MSR_DE) |
3788 (1ull << MSR_FE1) |
3789 (1ull << MSR_IR) |
3790 (1ull << MSR_DR);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00003791 pcc->mmu_model = POWERPC_MMU_BOOKE;
3792 pcc->excp_model = POWERPC_EXCP_BOOKE;
3793 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
3794 pcc->bfd_mach = bfd_mach_ppc_403;
3795 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
3796 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00003797}
3798
j_mayera750fc02007-09-26 23:54:22 +00003799static void init_proc_440GP (CPUPPCState *env)
3800{
3801 /* Time base */
3802 gen_tbl(env);
j_mayer80d11f42007-11-17 23:02:20 +00003803 gen_spr_BookE(env, 0x000000000000FFFFULL);
j_mayera750fc02007-09-26 23:54:22 +00003804 gen_spr_440(env);
j_mayer80d11f42007-11-17 23:02:20 +00003805 gen_spr_usprgh(env);
3806 /* Processor identification */
3807 spr_register(env, SPR_BOOKE_PIR, "PIR",
3808 SPR_NOACCESS, SPR_NOACCESS,
3809 &spr_read_generic, &spr_write_pir,
3810 0x00000000);
3811 /* XXX : not implemented */
3812 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
3813 SPR_NOACCESS, SPR_NOACCESS,
3814 &spr_read_generic, &spr_write_generic,
3815 0x00000000);
3816 /* XXX : not implemented */
3817 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
3818 SPR_NOACCESS, SPR_NOACCESS,
3819 &spr_read_generic, &spr_write_generic,
3820 0x00000000);
3821 /* XXX : not implemented */
3822 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
3823 SPR_NOACCESS, SPR_NOACCESS,
3824 &spr_read_generic, &spr_write_generic,
3825 0x00000000);
3826 /* XXX : not implemented */
3827 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
3828 SPR_NOACCESS, SPR_NOACCESS,
3829 &spr_read_generic, &spr_write_generic,
3830 0x00000000);
j_mayera750fc02007-09-26 23:54:22 +00003831 /* Memory management */
j_mayerf2e63a42007-10-07 15:43:50 +00003832#if !defined(CONFIG_USER_ONLY)
j_mayera750fc02007-09-26 23:54:22 +00003833 env->nb_tlb = 64;
3834 env->nb_ways = 1;
3835 env->id_tlbs = 0;
Alexander Graf1c53acc2011-06-17 01:00:28 +02003836 env->tlb_type = TLB_EMB;
j_mayerf2e63a42007-10-07 15:43:50 +00003837#endif
j_mayere1833e12007-09-29 13:06:16 +00003838 init_excp_BookE(env);
j_mayerd63001d2007-10-04 00:51:58 +00003839 env->dcache_line_size = 32;
3840 env->icache_line_size = 32;
j_mayera750fc02007-09-26 23:54:22 +00003841 /* XXX: TODO: allocate internal IRQ controller */
Fabien Chouteauddd10552011-09-13 04:00:32 +00003842
3843 SET_FIT_PERIOD(12, 16, 20, 24);
3844 SET_WDT_PERIOD(20, 24, 28, 32);
j_mayera750fc02007-09-26 23:54:22 +00003845}
3846
Andreas Färber7856e3a2013-02-17 23:16:42 +00003847POWERPC_FAMILY(440GP)(ObjectClass *oc, void *data)
3848{
Andreas Färberca5dff02013-02-17 23:16:46 +00003849 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00003850 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3851
Andreas Färberca5dff02013-02-17 23:16:46 +00003852 dc->desc = "PowerPC 440 GP";
Andreas Färber7856e3a2013-02-17 23:16:42 +00003853 pcc->init_proc = init_proc_440GP;
3854 pcc->check_pow = check_pow_nocheck;
Andreas Färber53116eb2013-02-17 23:16:43 +00003855 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3856 PPC_DCR | PPC_DCRX | PPC_WRTEE | PPC_MFAPIDI |
3857 PPC_CACHE | PPC_CACHE_ICBI |
3858 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3859 PPC_MEM_TLBSYNC | PPC_TLBIVA | PPC_MFTB |
3860 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
3861 PPC_440_SPEC;
Tom Musta9df5a462014-04-15 12:21:12 -05003862 pcc->msr_mask = (1ull << MSR_POW) |
3863 (1ull << MSR_CE) |
3864 (1ull << MSR_EE) |
3865 (1ull << MSR_PR) |
3866 (1ull << MSR_FP) |
3867 (1ull << MSR_ME) |
3868 (1ull << MSR_FE0) |
3869 (1ull << MSR_DWE) |
3870 (1ull << MSR_DE) |
3871 (1ull << MSR_FE1) |
3872 (1ull << MSR_IR) |
3873 (1ull << MSR_DR);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00003874 pcc->mmu_model = POWERPC_MMU_BOOKE;
3875 pcc->excp_model = POWERPC_EXCP_BOOKE;
3876 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
3877 pcc->bfd_mach = bfd_mach_ppc_403;
3878 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
3879 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00003880}
3881
j_mayera750fc02007-09-26 23:54:22 +00003882static void init_proc_440x4 (CPUPPCState *env)
3883{
3884 /* Time base */
3885 gen_tbl(env);
j_mayer80d11f42007-11-17 23:02:20 +00003886 gen_spr_BookE(env, 0x000000000000FFFFULL);
j_mayera750fc02007-09-26 23:54:22 +00003887 gen_spr_440(env);
j_mayer80d11f42007-11-17 23:02:20 +00003888 gen_spr_usprgh(env);
3889 /* Processor identification */
3890 spr_register(env, SPR_BOOKE_PIR, "PIR",
3891 SPR_NOACCESS, SPR_NOACCESS,
3892 &spr_read_generic, &spr_write_pir,
3893 0x00000000);
3894 /* XXX : not implemented */
3895 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
3896 SPR_NOACCESS, SPR_NOACCESS,
3897 &spr_read_generic, &spr_write_generic,
3898 0x00000000);
3899 /* XXX : not implemented */
3900 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
3901 SPR_NOACCESS, SPR_NOACCESS,
3902 &spr_read_generic, &spr_write_generic,
3903 0x00000000);
3904 /* XXX : not implemented */
3905 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
3906 SPR_NOACCESS, SPR_NOACCESS,
3907 &spr_read_generic, &spr_write_generic,
3908 0x00000000);
3909 /* XXX : not implemented */
3910 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
3911 SPR_NOACCESS, SPR_NOACCESS,
3912 &spr_read_generic, &spr_write_generic,
3913 0x00000000);
j_mayera750fc02007-09-26 23:54:22 +00003914 /* Memory management */
j_mayerf2e63a42007-10-07 15:43:50 +00003915#if !defined(CONFIG_USER_ONLY)
j_mayera750fc02007-09-26 23:54:22 +00003916 env->nb_tlb = 64;
3917 env->nb_ways = 1;
3918 env->id_tlbs = 0;
Alexander Graf1c53acc2011-06-17 01:00:28 +02003919 env->tlb_type = TLB_EMB;
j_mayerf2e63a42007-10-07 15:43:50 +00003920#endif
j_mayere1833e12007-09-29 13:06:16 +00003921 init_excp_BookE(env);
j_mayerd63001d2007-10-04 00:51:58 +00003922 env->dcache_line_size = 32;
3923 env->icache_line_size = 32;
j_mayera750fc02007-09-26 23:54:22 +00003924 /* XXX: TODO: allocate internal IRQ controller */
Fabien Chouteauddd10552011-09-13 04:00:32 +00003925
3926 SET_FIT_PERIOD(12, 16, 20, 24);
3927 SET_WDT_PERIOD(20, 24, 28, 32);
j_mayera750fc02007-09-26 23:54:22 +00003928}
j_mayera750fc02007-09-26 23:54:22 +00003929
Andreas Färber7856e3a2013-02-17 23:16:42 +00003930POWERPC_FAMILY(440x4)(ObjectClass *oc, void *data)
3931{
Andreas Färberca5dff02013-02-17 23:16:46 +00003932 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00003933 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
3934
Andreas Färberca5dff02013-02-17 23:16:46 +00003935 dc->desc = "PowerPC 440x4";
Andreas Färber7856e3a2013-02-17 23:16:42 +00003936 pcc->init_proc = init_proc_440x4;
3937 pcc->check_pow = check_pow_nocheck;
Andreas Färber53116eb2013-02-17 23:16:43 +00003938 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
3939 PPC_DCR | PPC_WRTEE |
3940 PPC_CACHE | PPC_CACHE_ICBI |
3941 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
3942 PPC_MEM_TLBSYNC | PPC_MFTB |
3943 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
3944 PPC_440_SPEC;
Tom Musta9df5a462014-04-15 12:21:12 -05003945 pcc->msr_mask = (1ull << MSR_POW) |
3946 (1ull << MSR_CE) |
3947 (1ull << MSR_EE) |
3948 (1ull << MSR_PR) |
3949 (1ull << MSR_FP) |
3950 (1ull << MSR_ME) |
3951 (1ull << MSR_FE0) |
3952 (1ull << MSR_DWE) |
3953 (1ull << MSR_DE) |
3954 (1ull << MSR_FE1) |
3955 (1ull << MSR_IR) |
3956 (1ull << MSR_DR);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00003957 pcc->mmu_model = POWERPC_MMU_BOOKE;
3958 pcc->excp_model = POWERPC_EXCP_BOOKE;
3959 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
3960 pcc->bfd_mach = bfd_mach_ppc_403;
3961 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
3962 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00003963}
3964
j_mayera750fc02007-09-26 23:54:22 +00003965static void init_proc_440x5 (CPUPPCState *env)
3966{
3967 /* Time base */
3968 gen_tbl(env);
j_mayer80d11f42007-11-17 23:02:20 +00003969 gen_spr_BookE(env, 0x000000000000FFFFULL);
j_mayera750fc02007-09-26 23:54:22 +00003970 gen_spr_440(env);
j_mayer80d11f42007-11-17 23:02:20 +00003971 gen_spr_usprgh(env);
3972 /* Processor identification */
3973 spr_register(env, SPR_BOOKE_PIR, "PIR",
3974 SPR_NOACCESS, SPR_NOACCESS,
3975 &spr_read_generic, &spr_write_pir,
3976 0x00000000);
3977 /* XXX : not implemented */
3978 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
3979 SPR_NOACCESS, SPR_NOACCESS,
3980 &spr_read_generic, &spr_write_generic,
3981 0x00000000);
3982 /* XXX : not implemented */
3983 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
3984 SPR_NOACCESS, SPR_NOACCESS,
3985 &spr_read_generic, &spr_write_generic,
3986 0x00000000);
3987 /* XXX : not implemented */
3988 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
3989 SPR_NOACCESS, SPR_NOACCESS,
3990 &spr_read_generic, &spr_write_generic,
3991 0x00000000);
3992 /* XXX : not implemented */
3993 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
3994 SPR_NOACCESS, SPR_NOACCESS,
3995 &spr_read_generic, &spr_write_generic,
3996 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00003997 /* XXX : not implemented */
j_mayera750fc02007-09-26 23:54:22 +00003998 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
3999 SPR_NOACCESS, SPR_NOACCESS,
4000 &spr_read_generic, &spr_write_generic,
4001 0x00000000);
4002 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
4003 SPR_NOACCESS, SPR_NOACCESS,
4004 &spr_read_generic, &spr_write_generic,
4005 0x00000000);
4006 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
4007 SPR_NOACCESS, SPR_NOACCESS,
4008 &spr_read_generic, &spr_write_generic,
4009 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00004010 /* XXX : not implemented */
j_mayera750fc02007-09-26 23:54:22 +00004011 spr_register(env, SPR_440_CCR1, "CCR1",
4012 SPR_NOACCESS, SPR_NOACCESS,
4013 &spr_read_generic, &spr_write_generic,
4014 0x00000000);
4015 /* Memory management */
j_mayerf2e63a42007-10-07 15:43:50 +00004016#if !defined(CONFIG_USER_ONLY)
j_mayera750fc02007-09-26 23:54:22 +00004017 env->nb_tlb = 64;
4018 env->nb_ways = 1;
4019 env->id_tlbs = 0;
Alexander Graf1c53acc2011-06-17 01:00:28 +02004020 env->tlb_type = TLB_EMB;
j_mayerf2e63a42007-10-07 15:43:50 +00004021#endif
j_mayere1833e12007-09-29 13:06:16 +00004022 init_excp_BookE(env);
j_mayerd63001d2007-10-04 00:51:58 +00004023 env->dcache_line_size = 32;
4024 env->icache_line_size = 32;
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01004025 ppc40x_irq_init(ppc_env_get_cpu(env));
Fabien Chouteauddd10552011-09-13 04:00:32 +00004026
4027 SET_FIT_PERIOD(12, 16, 20, 24);
4028 SET_WDT_PERIOD(20, 24, 28, 32);
j_mayera750fc02007-09-26 23:54:22 +00004029}
4030
Andreas Färber7856e3a2013-02-17 23:16:42 +00004031POWERPC_FAMILY(440x5)(ObjectClass *oc, void *data)
4032{
Andreas Färberca5dff02013-02-17 23:16:46 +00004033 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00004034 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4035
Andreas Färberca5dff02013-02-17 23:16:46 +00004036 dc->desc = "PowerPC 440x5";
Andreas Färber7856e3a2013-02-17 23:16:42 +00004037 pcc->init_proc = init_proc_440x5;
4038 pcc->check_pow = check_pow_nocheck;
Andreas Färber53116eb2013-02-17 23:16:43 +00004039 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4040 PPC_DCR | PPC_WRTEE | PPC_RFMCI |
4041 PPC_CACHE | PPC_CACHE_ICBI |
4042 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4043 PPC_MEM_TLBSYNC | PPC_MFTB |
4044 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4045 PPC_440_SPEC;
Tom Musta9df5a462014-04-15 12:21:12 -05004046 pcc->msr_mask = (1ull << MSR_POW) |
4047 (1ull << MSR_CE) |
4048 (1ull << MSR_EE) |
4049 (1ull << MSR_PR) |
4050 (1ull << MSR_FP) |
4051 (1ull << MSR_ME) |
4052 (1ull << MSR_FE0) |
4053 (1ull << MSR_DWE) |
4054 (1ull << MSR_DE) |
4055 (1ull << MSR_FE1) |
4056 (1ull << MSR_IR) |
4057 (1ull << MSR_DR);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00004058 pcc->mmu_model = POWERPC_MMU_BOOKE;
4059 pcc->excp_model = POWERPC_EXCP_BOOKE;
4060 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4061 pcc->bfd_mach = bfd_mach_ppc_403;
4062 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4063 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00004064}
4065
Pierre Mallardb8c867e2014-09-12 21:31:33 +02004066POWERPC_FAMILY(440x5wDFPU)(ObjectClass *oc, void *data)
4067{
4068 DeviceClass *dc = DEVICE_CLASS(oc);
4069 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4070
4071 dc->desc = "PowerPC 440x5 with double precision FPU";
4072 pcc->init_proc = init_proc_440x5;
4073 pcc->check_pow = check_pow_nocheck;
4074 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4075 PPC_FLOAT | PPC_FLOAT_FSQRT |
4076 PPC_FLOAT_STFIWX |
4077 PPC_DCR | PPC_WRTEE | PPC_RFMCI |
4078 PPC_CACHE | PPC_CACHE_ICBI |
4079 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4080 PPC_MEM_TLBSYNC | PPC_MFTB |
4081 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4082 PPC_440_SPEC;
4083 pcc->insns_flags2 = PPC2_FP_CVT_S64;
4084 pcc->msr_mask = (1ull << MSR_POW) |
4085 (1ull << MSR_CE) |
4086 (1ull << MSR_EE) |
4087 (1ull << MSR_PR) |
4088 (1ull << MSR_FP) |
4089 (1ull << MSR_ME) |
4090 (1ull << MSR_FE0) |
4091 (1ull << MSR_DWE) |
4092 (1ull << MSR_DE) |
4093 (1ull << MSR_FE1) |
4094 (1ull << MSR_IR) |
4095 (1ull << MSR_DR);
4096 pcc->mmu_model = POWERPC_MMU_BOOKE;
4097 pcc->excp_model = POWERPC_EXCP_BOOKE;
4098 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4099 pcc->bfd_mach = bfd_mach_ppc_403;
4100 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4101 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
4102}
4103
j_mayera750fc02007-09-26 23:54:22 +00004104static void init_proc_460 (CPUPPCState *env)
4105{
j_mayera750fc02007-09-26 23:54:22 +00004106 /* Time base */
4107 gen_tbl(env);
j_mayer80d11f42007-11-17 23:02:20 +00004108 gen_spr_BookE(env, 0x000000000000FFFFULL);
j_mayera750fc02007-09-26 23:54:22 +00004109 gen_spr_440(env);
j_mayer80d11f42007-11-17 23:02:20 +00004110 gen_spr_usprgh(env);
4111 /* Processor identification */
4112 spr_register(env, SPR_BOOKE_PIR, "PIR",
4113 SPR_NOACCESS, SPR_NOACCESS,
4114 &spr_read_generic, &spr_write_pir,
4115 0x00000000);
4116 /* XXX : not implemented */
4117 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4118 SPR_NOACCESS, SPR_NOACCESS,
4119 &spr_read_generic, &spr_write_generic,
4120 0x00000000);
4121 /* XXX : not implemented */
4122 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4123 SPR_NOACCESS, SPR_NOACCESS,
4124 &spr_read_generic, &spr_write_generic,
4125 0x00000000);
4126 /* XXX : not implemented */
4127 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
4128 SPR_NOACCESS, SPR_NOACCESS,
4129 &spr_read_generic, &spr_write_generic,
4130 0x00000000);
4131 /* XXX : not implemented */
4132 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
4133 SPR_NOACCESS, SPR_NOACCESS,
4134 &spr_read_generic, &spr_write_generic,
4135 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00004136 /* XXX : not implemented */
j_mayera750fc02007-09-26 23:54:22 +00004137 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
4138 SPR_NOACCESS, SPR_NOACCESS,
4139 &spr_read_generic, &spr_write_generic,
4140 0x00000000);
4141 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
4142 SPR_NOACCESS, SPR_NOACCESS,
4143 &spr_read_generic, &spr_write_generic,
4144 0x00000000);
4145 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
4146 SPR_NOACCESS, SPR_NOACCESS,
4147 &spr_read_generic, &spr_write_generic,
4148 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00004149 /* XXX : not implemented */
j_mayera750fc02007-09-26 23:54:22 +00004150 spr_register(env, SPR_440_CCR1, "CCR1",
4151 SPR_NOACCESS, SPR_NOACCESS,
4152 &spr_read_generic, &spr_write_generic,
4153 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00004154 /* XXX : not implemented */
j_mayera750fc02007-09-26 23:54:22 +00004155 spr_register(env, SPR_DCRIPR, "SPR_DCRIPR",
4156 &spr_read_generic, &spr_write_generic,
4157 &spr_read_generic, &spr_write_generic,
4158 0x00000000);
4159 /* Memory management */
j_mayerf2e63a42007-10-07 15:43:50 +00004160#if !defined(CONFIG_USER_ONLY)
j_mayera750fc02007-09-26 23:54:22 +00004161 env->nb_tlb = 64;
4162 env->nb_ways = 1;
4163 env->id_tlbs = 0;
Alexander Graf1c53acc2011-06-17 01:00:28 +02004164 env->tlb_type = TLB_EMB;
j_mayerf2e63a42007-10-07 15:43:50 +00004165#endif
j_mayere1833e12007-09-29 13:06:16 +00004166 init_excp_BookE(env);
j_mayerd63001d2007-10-04 00:51:58 +00004167 env->dcache_line_size = 32;
4168 env->icache_line_size = 32;
j_mayere1833e12007-09-29 13:06:16 +00004169 /* XXX: TODO: allocate internal IRQ controller */
Fabien Chouteauddd10552011-09-13 04:00:32 +00004170
4171 SET_FIT_PERIOD(12, 16, 20, 24);
4172 SET_WDT_PERIOD(20, 24, 28, 32);
j_mayere1833e12007-09-29 13:06:16 +00004173}
j_mayere1833e12007-09-29 13:06:16 +00004174
Andreas Färber7856e3a2013-02-17 23:16:42 +00004175POWERPC_FAMILY(460)(ObjectClass *oc, void *data)
4176{
Andreas Färberca5dff02013-02-17 23:16:46 +00004177 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00004178 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4179
Andreas Färberca5dff02013-02-17 23:16:46 +00004180 dc->desc = "PowerPC 460 (guessed)";
Andreas Färber7856e3a2013-02-17 23:16:42 +00004181 pcc->init_proc = init_proc_460;
4182 pcc->check_pow = check_pow_nocheck;
Andreas Färber53116eb2013-02-17 23:16:43 +00004183 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4184 PPC_DCR | PPC_DCRX | PPC_DCRUX |
4185 PPC_WRTEE | PPC_MFAPIDI | PPC_MFTB |
4186 PPC_CACHE | PPC_CACHE_ICBI |
4187 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4188 PPC_MEM_TLBSYNC | PPC_TLBIVA |
4189 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4190 PPC_440_SPEC;
Tom Musta9df5a462014-04-15 12:21:12 -05004191 pcc->msr_mask = (1ull << MSR_POW) |
4192 (1ull << MSR_CE) |
4193 (1ull << MSR_EE) |
4194 (1ull << MSR_PR) |
4195 (1ull << MSR_FP) |
4196 (1ull << MSR_ME) |
4197 (1ull << MSR_FE0) |
4198 (1ull << MSR_DWE) |
4199 (1ull << MSR_DE) |
4200 (1ull << MSR_FE1) |
4201 (1ull << MSR_IR) |
4202 (1ull << MSR_DR);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00004203 pcc->mmu_model = POWERPC_MMU_BOOKE;
4204 pcc->excp_model = POWERPC_EXCP_BOOKE;
4205 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4206 pcc->bfd_mach = bfd_mach_ppc_403;
4207 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4208 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00004209}
4210
j_mayere1833e12007-09-29 13:06:16 +00004211static void init_proc_460F (CPUPPCState *env)
4212{
4213 /* Time base */
4214 gen_tbl(env);
j_mayer80d11f42007-11-17 23:02:20 +00004215 gen_spr_BookE(env, 0x000000000000FFFFULL);
j_mayere1833e12007-09-29 13:06:16 +00004216 gen_spr_440(env);
j_mayer80d11f42007-11-17 23:02:20 +00004217 gen_spr_usprgh(env);
4218 /* Processor identification */
4219 spr_register(env, SPR_BOOKE_PIR, "PIR",
4220 SPR_NOACCESS, SPR_NOACCESS,
4221 &spr_read_generic, &spr_write_pir,
4222 0x00000000);
4223 /* XXX : not implemented */
4224 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4225 SPR_NOACCESS, SPR_NOACCESS,
4226 &spr_read_generic, &spr_write_generic,
4227 0x00000000);
4228 /* XXX : not implemented */
4229 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4230 SPR_NOACCESS, SPR_NOACCESS,
4231 &spr_read_generic, &spr_write_generic,
4232 0x00000000);
4233 /* XXX : not implemented */
4234 spr_register(env, SPR_BOOKE_DVC1, "DVC1",
4235 SPR_NOACCESS, SPR_NOACCESS,
4236 &spr_read_generic, &spr_write_generic,
4237 0x00000000);
4238 /* XXX : not implemented */
4239 spr_register(env, SPR_BOOKE_DVC2, "DVC2",
4240 SPR_NOACCESS, SPR_NOACCESS,
4241 &spr_read_generic, &spr_write_generic,
4242 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00004243 /* XXX : not implemented */
j_mayere1833e12007-09-29 13:06:16 +00004244 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
4245 SPR_NOACCESS, SPR_NOACCESS,
4246 &spr_read_generic, &spr_write_generic,
4247 0x00000000);
4248 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
4249 SPR_NOACCESS, SPR_NOACCESS,
4250 &spr_read_generic, &spr_write_generic,
4251 0x00000000);
4252 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
4253 SPR_NOACCESS, SPR_NOACCESS,
4254 &spr_read_generic, &spr_write_generic,
4255 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00004256 /* XXX : not implemented */
j_mayere1833e12007-09-29 13:06:16 +00004257 spr_register(env, SPR_440_CCR1, "CCR1",
4258 SPR_NOACCESS, SPR_NOACCESS,
4259 &spr_read_generic, &spr_write_generic,
4260 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00004261 /* XXX : not implemented */
j_mayere1833e12007-09-29 13:06:16 +00004262 spr_register(env, SPR_DCRIPR, "SPR_DCRIPR",
4263 &spr_read_generic, &spr_write_generic,
4264 &spr_read_generic, &spr_write_generic,
4265 0x00000000);
4266 /* Memory management */
j_mayerf2e63a42007-10-07 15:43:50 +00004267#if !defined(CONFIG_USER_ONLY)
j_mayere1833e12007-09-29 13:06:16 +00004268 env->nb_tlb = 64;
4269 env->nb_ways = 1;
4270 env->id_tlbs = 0;
Alexander Graf1c53acc2011-06-17 01:00:28 +02004271 env->tlb_type = TLB_EMB;
j_mayerf2e63a42007-10-07 15:43:50 +00004272#endif
j_mayere1833e12007-09-29 13:06:16 +00004273 init_excp_BookE(env);
j_mayerd63001d2007-10-04 00:51:58 +00004274 env->dcache_line_size = 32;
4275 env->icache_line_size = 32;
j_mayera750fc02007-09-26 23:54:22 +00004276 /* XXX: TODO: allocate internal IRQ controller */
Fabien Chouteauddd10552011-09-13 04:00:32 +00004277
4278 SET_FIT_PERIOD(12, 16, 20, 24);
4279 SET_WDT_PERIOD(20, 24, 28, 32);
j_mayera750fc02007-09-26 23:54:22 +00004280}
j_mayera750fc02007-09-26 23:54:22 +00004281
Andreas Färber7856e3a2013-02-17 23:16:42 +00004282POWERPC_FAMILY(460F)(ObjectClass *oc, void *data)
4283{
Andreas Färberca5dff02013-02-17 23:16:46 +00004284 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00004285 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4286
Andreas Färberca5dff02013-02-17 23:16:46 +00004287 dc->desc = "PowerPC 460F (guessed)";
Andreas Färber7856e3a2013-02-17 23:16:42 +00004288 pcc->init_proc = init_proc_460F;
4289 pcc->check_pow = check_pow_nocheck;
Andreas Färber53116eb2013-02-17 23:16:43 +00004290 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4291 PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL |
4292 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
4293 PPC_FLOAT_STFIWX | PPC_MFTB |
4294 PPC_DCR | PPC_DCRX | PPC_DCRUX |
4295 PPC_WRTEE | PPC_MFAPIDI |
4296 PPC_CACHE | PPC_CACHE_ICBI |
4297 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4298 PPC_MEM_TLBSYNC | PPC_TLBIVA |
4299 PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
4300 PPC_440_SPEC;
Tom Musta9df5a462014-04-15 12:21:12 -05004301 pcc->msr_mask = (1ull << MSR_POW) |
4302 (1ull << MSR_CE) |
4303 (1ull << MSR_EE) |
4304 (1ull << MSR_PR) |
4305 (1ull << MSR_FP) |
4306 (1ull << MSR_ME) |
4307 (1ull << MSR_FE0) |
4308 (1ull << MSR_DWE) |
4309 (1ull << MSR_DE) |
4310 (1ull << MSR_FE1) |
4311 (1ull << MSR_IR) |
4312 (1ull << MSR_DR);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00004313 pcc->mmu_model = POWERPC_MMU_BOOKE;
4314 pcc->excp_model = POWERPC_EXCP_BOOKE;
4315 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4316 pcc->bfd_mach = bfd_mach_ppc_403;
4317 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
4318 POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00004319}
4320
j_mayer80d11f42007-11-17 23:02:20 +00004321static void init_proc_MPC5xx (CPUPPCState *env)
j_mayera750fc02007-09-26 23:54:22 +00004322{
j_mayer80d11f42007-11-17 23:02:20 +00004323 /* Time base */
4324 gen_tbl(env);
4325 gen_spr_5xx_8xx(env);
4326 gen_spr_5xx(env);
4327 init_excp_MPC5xx(env);
j_mayerd63001d2007-10-04 00:51:58 +00004328 env->dcache_line_size = 32;
4329 env->icache_line_size = 32;
j_mayer80d11f42007-11-17 23:02:20 +00004330 /* XXX: TODO: allocate internal IRQ controller */
4331}
4332
Andreas Färber7856e3a2013-02-17 23:16:42 +00004333POWERPC_FAMILY(MPC5xx)(ObjectClass *oc, void *data)
4334{
Andreas Färberca5dff02013-02-17 23:16:46 +00004335 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00004336 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4337
Andreas Färberca5dff02013-02-17 23:16:46 +00004338 dc->desc = "Freescale 5xx cores (aka RCPU)";
Andreas Färber7856e3a2013-02-17 23:16:42 +00004339 pcc->init_proc = init_proc_MPC5xx;
4340 pcc->check_pow = check_pow_none;
Andreas Färber53116eb2013-02-17 23:16:43 +00004341 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4342 PPC_MEM_EIEIO | PPC_MEM_SYNC |
4343 PPC_CACHE_ICBI | PPC_FLOAT | PPC_FLOAT_STFIWX |
4344 PPC_MFTB;
Tom Musta9df5a462014-04-15 12:21:12 -05004345 pcc->msr_mask = (1ull << MSR_ILE) |
4346 (1ull << MSR_EE) |
4347 (1ull << MSR_PR) |
4348 (1ull << MSR_FP) |
4349 (1ull << MSR_ME) |
4350 (1ull << MSR_FE0) |
4351 (1ull << MSR_SE) |
4352 (1ull << MSR_DE) |
4353 (1ull << MSR_FE1) |
4354 (1ull << MSR_EP) |
4355 (1ull << MSR_RI) |
4356 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00004357 pcc->mmu_model = POWERPC_MMU_REAL;
4358 pcc->excp_model = POWERPC_EXCP_603;
4359 pcc->bus_model = PPC_FLAGS_INPUT_RCPU;
4360 pcc->bfd_mach = bfd_mach_ppc_505;
4361 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
4362 POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00004363}
4364
j_mayer80d11f42007-11-17 23:02:20 +00004365static void init_proc_MPC8xx (CPUPPCState *env)
4366{
4367 /* Time base */
4368 gen_tbl(env);
4369 gen_spr_5xx_8xx(env);
4370 gen_spr_8xx(env);
4371 init_excp_MPC8xx(env);
4372 env->dcache_line_size = 32;
4373 env->icache_line_size = 32;
4374 /* XXX: TODO: allocate internal IRQ controller */
4375}
4376
Andreas Färber7856e3a2013-02-17 23:16:42 +00004377POWERPC_FAMILY(MPC8xx)(ObjectClass *oc, void *data)
4378{
Andreas Färberca5dff02013-02-17 23:16:46 +00004379 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00004380 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4381
Andreas Färberca5dff02013-02-17 23:16:46 +00004382 dc->desc = "Freescale 8xx cores (aka PowerQUICC)";
Andreas Färber7856e3a2013-02-17 23:16:42 +00004383 pcc->init_proc = init_proc_MPC8xx;
4384 pcc->check_pow = check_pow_none;
Andreas Färber53116eb2013-02-17 23:16:43 +00004385 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
4386 PPC_MEM_EIEIO | PPC_MEM_SYNC |
4387 PPC_CACHE_ICBI | PPC_MFTB;
Tom Musta9df5a462014-04-15 12:21:12 -05004388 pcc->msr_mask = (1ull << MSR_ILE) |
4389 (1ull << MSR_EE) |
4390 (1ull << MSR_PR) |
4391 (1ull << MSR_FP) |
4392 (1ull << MSR_ME) |
4393 (1ull << MSR_SE) |
4394 (1ull << MSR_DE) |
4395 (1ull << MSR_EP) |
4396 (1ull << MSR_IR) |
4397 (1ull << MSR_DR) |
4398 (1ull << MSR_RI) |
4399 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00004400 pcc->mmu_model = POWERPC_MMU_MPC8xx;
4401 pcc->excp_model = POWERPC_EXCP_603;
4402 pcc->bus_model = PPC_FLAGS_INPUT_RCPU;
4403 pcc->bfd_mach = bfd_mach_ppc_860;
4404 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
4405 POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00004406}
4407
j_mayer80d11f42007-11-17 23:02:20 +00004408/* Freescale 82xx cores (aka PowerQUICC-II) */
Andreas Färberca5dff02013-02-17 23:16:46 +00004409
j_mayer80d11f42007-11-17 23:02:20 +00004410static void init_proc_G2 (CPUPPCState *env)
4411{
4412 gen_spr_ne_601(env);
4413 gen_spr_G2_755(env);
4414 gen_spr_G2(env);
4415 /* Time base */
4416 gen_tbl(env);
j_mayerbd928eb2007-11-21 13:08:23 +00004417 /* External access control */
4418 /* XXX : not implemented */
4419 spr_register(env, SPR_EAR, "EAR",
4420 SPR_NOACCESS, SPR_NOACCESS,
4421 &spr_read_generic, &spr_write_generic,
4422 0x00000000);
j_mayer80d11f42007-11-17 23:02:20 +00004423 /* Hardware implementation register */
4424 /* XXX : not implemented */
4425 spr_register(env, SPR_HID0, "HID0",
4426 SPR_NOACCESS, SPR_NOACCESS,
4427 &spr_read_generic, &spr_write_generic,
4428 0x00000000);
4429 /* XXX : not implemented */
4430 spr_register(env, SPR_HID1, "HID1",
4431 SPR_NOACCESS, SPR_NOACCESS,
4432 &spr_read_generic, &spr_write_generic,
4433 0x00000000);
4434 /* XXX : not implemented */
4435 spr_register(env, SPR_HID2, "HID2",
4436 SPR_NOACCESS, SPR_NOACCESS,
4437 &spr_read_generic, &spr_write_generic,
4438 0x00000000);
4439 /* Memory management */
4440 gen_low_BATs(env);
4441 gen_high_BATs(env);
4442 gen_6xx_7xx_soft_tlb(env, 64, 2);
4443 init_excp_G2(env);
4444 env->dcache_line_size = 32;
4445 env->icache_line_size = 32;
4446 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01004447 ppc6xx_irq_init(ppc_env_get_cpu(env));
j_mayer80d11f42007-11-17 23:02:20 +00004448}
4449
Andreas Färber7856e3a2013-02-17 23:16:42 +00004450POWERPC_FAMILY(G2)(ObjectClass *oc, void *data)
4451{
Andreas Färberca5dff02013-02-17 23:16:46 +00004452 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00004453 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4454
Andreas Färberca5dff02013-02-17 23:16:46 +00004455 dc->desc = "PowerPC G2";
Andreas Färber7856e3a2013-02-17 23:16:42 +00004456 pcc->init_proc = init_proc_G2;
4457 pcc->check_pow = check_pow_hid0;
Andreas Färber53116eb2013-02-17 23:16:43 +00004458 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4459 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4460 PPC_FLOAT_STFIWX |
4461 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4462 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4463 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4464 PPC_SEGMENT | PPC_EXTERN;
Tom Musta9df5a462014-04-15 12:21:12 -05004465 pcc->msr_mask = (1ull << MSR_POW) |
4466 (1ull << MSR_TGPR) |
4467 (1ull << MSR_EE) |
4468 (1ull << MSR_PR) |
4469 (1ull << MSR_FP) |
4470 (1ull << MSR_ME) |
4471 (1ull << MSR_FE0) |
4472 (1ull << MSR_SE) |
4473 (1ull << MSR_DE) |
4474 (1ull << MSR_FE1) |
4475 (1ull << MSR_AL) |
4476 (1ull << MSR_EP) |
4477 (1ull << MSR_IR) |
4478 (1ull << MSR_DR) |
4479 (1ull << MSR_RI);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00004480 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4481 pcc->excp_model = POWERPC_EXCP_G2;
4482 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4483 pcc->bfd_mach = bfd_mach_ppc_ec603e;
4484 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4485 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00004486}
4487
j_mayer80d11f42007-11-17 23:02:20 +00004488static void init_proc_G2LE (CPUPPCState *env)
4489{
4490 gen_spr_ne_601(env);
4491 gen_spr_G2_755(env);
4492 gen_spr_G2(env);
4493 /* Time base */
4494 gen_tbl(env);
j_mayerbd928eb2007-11-21 13:08:23 +00004495 /* External access control */
4496 /* XXX : not implemented */
4497 spr_register(env, SPR_EAR, "EAR",
4498 SPR_NOACCESS, SPR_NOACCESS,
4499 &spr_read_generic, &spr_write_generic,
4500 0x00000000);
j_mayer80d11f42007-11-17 23:02:20 +00004501 /* Hardware implementation register */
4502 /* XXX : not implemented */
4503 spr_register(env, SPR_HID0, "HID0",
4504 SPR_NOACCESS, SPR_NOACCESS,
4505 &spr_read_generic, &spr_write_generic,
4506 0x00000000);
4507 /* XXX : not implemented */
4508 spr_register(env, SPR_HID1, "HID1",
4509 SPR_NOACCESS, SPR_NOACCESS,
4510 &spr_read_generic, &spr_write_generic,
4511 0x00000000);
4512 /* XXX : not implemented */
4513 spr_register(env, SPR_HID2, "HID2",
4514 SPR_NOACCESS, SPR_NOACCESS,
4515 &spr_read_generic, &spr_write_generic,
4516 0x00000000);
Fabien Chouteau2bc17322013-04-03 04:03:38 +00004517
j_mayer80d11f42007-11-17 23:02:20 +00004518 /* Memory management */
4519 gen_low_BATs(env);
4520 gen_high_BATs(env);
4521 gen_6xx_7xx_soft_tlb(env, 64, 2);
4522 init_excp_G2(env);
4523 env->dcache_line_size = 32;
4524 env->icache_line_size = 32;
4525 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01004526 ppc6xx_irq_init(ppc_env_get_cpu(env));
j_mayera750fc02007-09-26 23:54:22 +00004527}
j_mayera750fc02007-09-26 23:54:22 +00004528
Andreas Färber7856e3a2013-02-17 23:16:42 +00004529POWERPC_FAMILY(G2LE)(ObjectClass *oc, void *data)
4530{
Andreas Färberca5dff02013-02-17 23:16:46 +00004531 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00004532 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4533
Andreas Färberca5dff02013-02-17 23:16:46 +00004534 dc->desc = "PowerPC G2LE";
Andreas Färber7856e3a2013-02-17 23:16:42 +00004535 pcc->init_proc = init_proc_G2LE;
4536 pcc->check_pow = check_pow_hid0;
Andreas Färber53116eb2013-02-17 23:16:43 +00004537 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4538 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4539 PPC_FLOAT_STFIWX |
4540 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4541 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4542 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4543 PPC_SEGMENT | PPC_EXTERN;
Tom Musta9df5a462014-04-15 12:21:12 -05004544 pcc->msr_mask = (1ull << MSR_POW) |
4545 (1ull << MSR_TGPR) |
4546 (1ull << MSR_ILE) |
4547 (1ull << MSR_EE) |
4548 (1ull << MSR_PR) |
4549 (1ull << MSR_FP) |
4550 (1ull << MSR_ME) |
4551 (1ull << MSR_FE0) |
4552 (1ull << MSR_SE) |
4553 (1ull << MSR_DE) |
4554 (1ull << MSR_FE1) |
4555 (1ull << MSR_AL) |
4556 (1ull << MSR_EP) |
4557 (1ull << MSR_IR) |
4558 (1ull << MSR_DR) |
4559 (1ull << MSR_RI) |
4560 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00004561 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4562 pcc->excp_model = POWERPC_EXCP_G2;
4563 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4564 pcc->bfd_mach = bfd_mach_ppc_ec603e;
4565 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4566 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00004567}
4568
j_mayer80d11f42007-11-17 23:02:20 +00004569static void init_proc_e200 (CPUPPCState *env)
4570{
4571 /* Time base */
4572 gen_tbl(env);
4573 gen_spr_BookE(env, 0x000000070000FFFFULL);
4574 /* XXX : not implemented */
4575 spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
aurel32d34defb2009-03-09 06:27:14 +00004576 &spr_read_spefscr, &spr_write_spefscr,
4577 &spr_read_spefscr, &spr_write_spefscr,
j_mayer80d11f42007-11-17 23:02:20 +00004578 0x00000000);
4579 /* Memory management */
Alexander Graf01662f32011-04-30 23:34:58 +02004580 gen_spr_BookE206(env, 0x0000005D, NULL);
j_mayer80d11f42007-11-17 23:02:20 +00004581 /* XXX : not implemented */
4582 spr_register(env, SPR_HID0, "HID0",
4583 SPR_NOACCESS, SPR_NOACCESS,
4584 &spr_read_generic, &spr_write_generic,
4585 0x00000000);
4586 /* XXX : not implemented */
4587 spr_register(env, SPR_HID1, "HID1",
4588 SPR_NOACCESS, SPR_NOACCESS,
4589 &spr_read_generic, &spr_write_generic,
4590 0x00000000);
4591 /* XXX : not implemented */
4592 spr_register(env, SPR_Exxx_ALTCTXCR, "ALTCTXCR",
4593 SPR_NOACCESS, SPR_NOACCESS,
4594 &spr_read_generic, &spr_write_generic,
4595 0x00000000);
4596 /* XXX : not implemented */
4597 spr_register(env, SPR_Exxx_BUCSR, "BUCSR",
4598 SPR_NOACCESS, SPR_NOACCESS,
4599 &spr_read_generic, &spr_write_generic,
4600 0x00000000);
4601 /* XXX : not implemented */
4602 spr_register(env, SPR_Exxx_CTXCR, "CTXCR",
4603 SPR_NOACCESS, SPR_NOACCESS,
4604 &spr_read_generic, &spr_write_generic,
4605 0x00000000);
4606 /* XXX : not implemented */
4607 spr_register(env, SPR_Exxx_DBCNT, "DBCNT",
4608 SPR_NOACCESS, SPR_NOACCESS,
4609 &spr_read_generic, &spr_write_generic,
4610 0x00000000);
4611 /* XXX : not implemented */
4612 spr_register(env, SPR_Exxx_DBCR3, "DBCR3",
4613 SPR_NOACCESS, SPR_NOACCESS,
4614 &spr_read_generic, &spr_write_generic,
4615 0x00000000);
4616 /* XXX : not implemented */
4617 spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0",
Alexander Grafdeb05c42014-01-23 11:43:49 +01004618 &spr_read_generic, SPR_NOACCESS,
4619 &spr_read_generic, SPR_NOACCESS,
j_mayer80d11f42007-11-17 23:02:20 +00004620 0x00000000);
4621 /* XXX : not implemented */
4622 spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0",
4623 SPR_NOACCESS, SPR_NOACCESS,
4624 &spr_read_generic, &spr_write_generic,
4625 0x00000000);
4626 /* XXX : not implemented */
4627 spr_register(env, SPR_Exxx_L1FINV0, "L1FINV0",
4628 SPR_NOACCESS, SPR_NOACCESS,
4629 &spr_read_generic, &spr_write_generic,
4630 0x00000000);
4631 /* XXX : not implemented */
4632 spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG",
4633 SPR_NOACCESS, SPR_NOACCESS,
4634 &spr_read_generic, &spr_write_generic,
4635 0x00000000);
4636 /* XXX : not implemented */
4637 spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG",
4638 SPR_NOACCESS, SPR_NOACCESS,
4639 &spr_read_generic, &spr_write_generic,
4640 0x00000000);
4641 /* XXX : not implemented */
4642 spr_register(env, SPR_BOOKE_IAC3, "IAC3",
4643 SPR_NOACCESS, SPR_NOACCESS,
4644 &spr_read_generic, &spr_write_generic,
4645 0x00000000);
4646 /* XXX : not implemented */
4647 spr_register(env, SPR_BOOKE_IAC4, "IAC4",
4648 SPR_NOACCESS, SPR_NOACCESS,
4649 &spr_read_generic, &spr_write_generic,
4650 0x00000000);
Alexander Graf01662f32011-04-30 23:34:58 +02004651 /* XXX : not implemented */
4652 spr_register(env, SPR_MMUCSR0, "MMUCSR0",
4653 SPR_NOACCESS, SPR_NOACCESS,
4654 &spr_read_generic, &spr_write_generic,
4655 0x00000000); /* TOFIX */
j_mayer80d11f42007-11-17 23:02:20 +00004656 spr_register(env, SPR_BOOKE_DSRR0, "DSRR0",
4657 SPR_NOACCESS, SPR_NOACCESS,
4658 &spr_read_generic, &spr_write_generic,
4659 0x00000000);
4660 spr_register(env, SPR_BOOKE_DSRR1, "DSRR1",
4661 SPR_NOACCESS, SPR_NOACCESS,
4662 &spr_read_generic, &spr_write_generic,
4663 0x00000000);
4664#if !defined(CONFIG_USER_ONLY)
4665 env->nb_tlb = 64;
4666 env->nb_ways = 1;
4667 env->id_tlbs = 0;
Alexander Graf1c53acc2011-06-17 01:00:28 +02004668 env->tlb_type = TLB_EMB;
j_mayer80d11f42007-11-17 23:02:20 +00004669#endif
Alexander Grafe9cd84b2012-06-21 15:17:59 +02004670 init_excp_e200(env, 0xFFFF0000UL);
j_mayer80d11f42007-11-17 23:02:20 +00004671 env->dcache_line_size = 32;
4672 env->icache_line_size = 32;
4673 /* XXX: TODO: allocate internal IRQ controller */
4674}
j_mayera750fc02007-09-26 23:54:22 +00004675
Andreas Färber7856e3a2013-02-17 23:16:42 +00004676POWERPC_FAMILY(e200)(ObjectClass *oc, void *data)
4677{
Andreas Färberca5dff02013-02-17 23:16:46 +00004678 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00004679 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4680
Andreas Färberca5dff02013-02-17 23:16:46 +00004681 dc->desc = "e200 core";
Andreas Färber7856e3a2013-02-17 23:16:42 +00004682 pcc->init_proc = init_proc_e200;
4683 pcc->check_pow = check_pow_hid0;
Andreas Färber53116eb2013-02-17 23:16:43 +00004684 /* XXX: unimplemented instructions:
4685 * dcblc
4686 * dcbtlst
4687 * dcbtstls
4688 * icblc
4689 * icbtls
4690 * tlbivax
4691 * all SPE multiply-accumulate instructions
4692 */
4693 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
4694 PPC_SPE | PPC_SPE_SINGLE |
4695 PPC_WRTEE | PPC_RFDI |
4696 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
4697 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
4698 PPC_MEM_TLBSYNC | PPC_TLBIVAX |
4699 PPC_BOOKE;
Tom Musta9df5a462014-04-15 12:21:12 -05004700 pcc->msr_mask = (1ull << MSR_UCLE) |
4701 (1ull << MSR_SPE) |
4702 (1ull << MSR_POW) |
4703 (1ull << MSR_CE) |
4704 (1ull << MSR_EE) |
4705 (1ull << MSR_PR) |
4706 (1ull << MSR_FP) |
4707 (1ull << MSR_ME) |
4708 (1ull << MSR_FE0) |
4709 (1ull << MSR_DWE) |
4710 (1ull << MSR_DE) |
4711 (1ull << MSR_FE1) |
4712 (1ull << MSR_IR) |
4713 (1ull << MSR_DR);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00004714 pcc->mmu_model = POWERPC_MMU_BOOKE206;
4715 pcc->excp_model = POWERPC_EXCP_BOOKE;
4716 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
4717 pcc->bfd_mach = bfd_mach_ppc_860;
4718 pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
4719 POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
4720 POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00004721}
4722
j_mayer80d11f42007-11-17 23:02:20 +00004723static void init_proc_e300 (CPUPPCState *env)
4724{
4725 gen_spr_ne_601(env);
4726 gen_spr_603(env);
4727 /* Time base */
4728 gen_tbl(env);
4729 /* hardware implementation registers */
4730 /* XXX : not implemented */
4731 spr_register(env, SPR_HID0, "HID0",
4732 SPR_NOACCESS, SPR_NOACCESS,
4733 &spr_read_generic, &spr_write_generic,
4734 0x00000000);
4735 /* XXX : not implemented */
4736 spr_register(env, SPR_HID1, "HID1",
4737 SPR_NOACCESS, SPR_NOACCESS,
4738 &spr_read_generic, &spr_write_generic,
4739 0x00000000);
Thomas Monjalon8daf1782009-10-15 19:01:19 +02004740 /* XXX : not implemented */
4741 spr_register(env, SPR_HID2, "HID2",
4742 SPR_NOACCESS, SPR_NOACCESS,
4743 &spr_read_generic, &spr_write_generic,
4744 0x00000000);
Fabien Chouteau3ade1a02014-11-06 17:23:50 +01004745 /* Breakpoints */
4746 /* XXX : not implemented */
4747 spr_register(env, SPR_DABR, "DABR",
4748 SPR_NOACCESS, SPR_NOACCESS,
4749 &spr_read_generic, &spr_write_generic,
4750 0x00000000);
4751 /* XXX : not implemented */
4752 spr_register(env, SPR_DABR2, "DABR2",
4753 SPR_NOACCESS, SPR_NOACCESS,
4754 &spr_read_generic, &spr_write_generic,
4755 0x00000000);
4756 /* XXX : not implemented */
4757 spr_register(env, SPR_IABR2, "IABR2",
4758 SPR_NOACCESS, SPR_NOACCESS,
4759 &spr_read_generic, &spr_write_generic,
4760 0x00000000);
4761 /* XXX : not implemented */
4762 spr_register(env, SPR_IBCR, "IBCR",
4763 SPR_NOACCESS, SPR_NOACCESS,
4764 &spr_read_generic, &spr_write_generic,
4765 0x00000000);
4766 /* XXX : not implemented */
4767 spr_register(env, SPR_DBCR, "DBCR",
4768 SPR_NOACCESS, SPR_NOACCESS,
4769 &spr_read_generic, &spr_write_generic,
4770 0x00000000);
j_mayer80d11f42007-11-17 23:02:20 +00004771 /* Memory management */
4772 gen_low_BATs(env);
Thomas Monjalon8daf1782009-10-15 19:01:19 +02004773 gen_high_BATs(env);
j_mayer80d11f42007-11-17 23:02:20 +00004774 gen_6xx_7xx_soft_tlb(env, 64, 2);
4775 init_excp_603(env);
4776 env->dcache_line_size = 32;
4777 env->icache_line_size = 32;
4778 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01004779 ppc6xx_irq_init(ppc_env_get_cpu(env));
j_mayer80d11f42007-11-17 23:02:20 +00004780}
j_mayera750fc02007-09-26 23:54:22 +00004781
Andreas Färber7856e3a2013-02-17 23:16:42 +00004782POWERPC_FAMILY(e300)(ObjectClass *oc, void *data)
4783{
Andreas Färberca5dff02013-02-17 23:16:46 +00004784 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00004785 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
4786
Andreas Färberca5dff02013-02-17 23:16:46 +00004787 dc->desc = "e300 core";
Andreas Färber7856e3a2013-02-17 23:16:42 +00004788 pcc->init_proc = init_proc_e300;
4789 pcc->check_pow = check_pow_hid0;
Andreas Färber53116eb2013-02-17 23:16:43 +00004790 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
4791 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
4792 PPC_FLOAT_STFIWX |
4793 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
4794 PPC_MEM_SYNC | PPC_MEM_EIEIO |
4795 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
4796 PPC_SEGMENT | PPC_EXTERN;
Tom Musta9df5a462014-04-15 12:21:12 -05004797 pcc->msr_mask = (1ull << MSR_POW) |
4798 (1ull << MSR_TGPR) |
4799 (1ull << MSR_ILE) |
4800 (1ull << MSR_EE) |
4801 (1ull << MSR_PR) |
4802 (1ull << MSR_FP) |
4803 (1ull << MSR_ME) |
4804 (1ull << MSR_FE0) |
4805 (1ull << MSR_SE) |
4806 (1ull << MSR_DE) |
4807 (1ull << MSR_FE1) |
4808 (1ull << MSR_AL) |
4809 (1ull << MSR_EP) |
4810 (1ull << MSR_IR) |
4811 (1ull << MSR_DR) |
4812 (1ull << MSR_RI) |
4813 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00004814 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
4815 pcc->excp_model = POWERPC_EXCP_603;
4816 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
4817 pcc->bfd_mach = bfd_mach_ppc_603;
4818 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
4819 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00004820}
4821
Alexander Grafb81ccf82012-06-20 21:55:55 +02004822#if !defined(CONFIG_USER_ONLY)
Paolo Bonzini69b058c2014-11-26 13:39:48 +03004823static void spr_write_mas73(DisasContext *ctx, int sprn, int gprn)
Alexander Grafb81ccf82012-06-20 21:55:55 +02004824{
4825 TCGv val = tcg_temp_new();
4826 tcg_gen_ext32u_tl(val, cpu_gpr[gprn]);
4827 gen_store_spr(SPR_BOOKE_MAS3, val);
Stefan Weilcfee0212012-06-24 04:18:41 +00004828 tcg_gen_shri_tl(val, cpu_gpr[gprn], 32);
Alexander Grafb81ccf82012-06-20 21:55:55 +02004829 gen_store_spr(SPR_BOOKE_MAS7, val);
4830 tcg_temp_free(val);
4831}
4832
Paolo Bonzini69b058c2014-11-26 13:39:48 +03004833static void spr_read_mas73(DisasContext *ctx, int gprn, int sprn)
Alexander Grafb81ccf82012-06-20 21:55:55 +02004834{
4835 TCGv mas7 = tcg_temp_new();
4836 TCGv mas3 = tcg_temp_new();
4837 gen_load_spr(mas7, SPR_BOOKE_MAS7);
4838 tcg_gen_shli_tl(mas7, mas7, 32);
4839 gen_load_spr(mas3, SPR_BOOKE_MAS3);
4840 tcg_gen_or_tl(cpu_gpr[gprn], mas3, mas7);
4841 tcg_temp_free(mas3);
4842 tcg_temp_free(mas7);
4843}
4844
Alexander Grafb81ccf82012-06-20 21:55:55 +02004845#endif
4846
Varun Sethif7aa5582011-12-22 12:26:17 +00004847enum fsl_e500_version {
4848 fsl_e500v1,
4849 fsl_e500v2,
4850 fsl_e500mc,
Alexander Grafb81ccf82012-06-20 21:55:55 +02004851 fsl_e5500,
Varun Sethif7aa5582011-12-22 12:26:17 +00004852};
4853
Alexander Graf01662f32011-04-30 23:34:58 +02004854static void init_proc_e500 (CPUPPCState *env, int version)
j_mayera750fc02007-09-26 23:54:22 +00004855{
Andreas Färbera47dddd2013-09-03 17:38:47 +02004856 PowerPCCPU *cpu = ppc_env_get_cpu(env);
Alexander Graf01662f32011-04-30 23:34:58 +02004857 uint32_t tlbncfg[2];
Alexander Grafb81ccf82012-06-20 21:55:55 +02004858 uint64_t ivor_mask;
Alexander Grafe9cd84b2012-06-21 15:17:59 +02004859 uint64_t ivpr_mask = 0xFFFF0000ULL;
Alexander Grafa496e8e2012-01-31 03:46:55 +01004860 uint32_t l1cfg0 = 0x3800 /* 8 ways */
4861 | 0x0020; /* 32 kb */
Alexander Grafd2ea2bf2014-01-19 17:47:43 +01004862 uint32_t l1cfg1 = 0x3800 /* 8 ways */
4863 | 0x0020; /* 32 kb */
Alexander Graf01662f32011-04-30 23:34:58 +02004864#if !defined(CONFIG_USER_ONLY)
4865 int i;
4866#endif
4867
j_mayera750fc02007-09-26 23:54:22 +00004868 /* Time base */
4869 gen_tbl(env);
Alexander Graf01662f32011-04-30 23:34:58 +02004870 /*
4871 * XXX The e500 doesn't implement IVOR7 and IVOR9, but doesn't
4872 * complain when accessing them.
4873 * gen_spr_BookE(env, 0x0000000F0000FD7FULL);
4874 */
Alexander Grafb81ccf82012-06-20 21:55:55 +02004875 switch (version) {
4876 case fsl_e500v1:
4877 case fsl_e500v2:
4878 default:
4879 ivor_mask = 0x0000000F0000FFFFULL;
4880 break;
4881 case fsl_e500mc:
4882 case fsl_e5500:
4883 ivor_mask = 0x000003FE0000FFFFULL;
4884 break;
Alexander Graf2c9732d2012-01-19 18:57:26 +01004885 }
4886 gen_spr_BookE(env, ivor_mask);
j_mayer80d11f42007-11-17 23:02:20 +00004887 /* Processor identification */
4888 spr_register(env, SPR_BOOKE_PIR, "PIR",
4889 SPR_NOACCESS, SPR_NOACCESS,
4890 &spr_read_generic, &spr_write_pir,
4891 0x00000000);
4892 /* XXX : not implemented */
4893 spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
aurel32d34defb2009-03-09 06:27:14 +00004894 &spr_read_spefscr, &spr_write_spefscr,
4895 &spr_read_spefscr, &spr_write_spefscr,
j_mayer80d11f42007-11-17 23:02:20 +00004896 0x00000000);
Alexander Graf892c5872012-04-19 15:34:06 +02004897#if !defined(CONFIG_USER_ONLY)
j_mayera750fc02007-09-26 23:54:22 +00004898 /* Memory management */
j_mayer80d11f42007-11-17 23:02:20 +00004899 env->nb_pids = 3;
Alexander Graf01662f32011-04-30 23:34:58 +02004900 env->nb_ways = 2;
4901 env->id_tlbs = 0;
4902 switch (version) {
Varun Sethif7aa5582011-12-22 12:26:17 +00004903 case fsl_e500v1:
Alexander Graf01662f32011-04-30 23:34:58 +02004904 tlbncfg[0] = gen_tlbncfg(2, 1, 1, 0, 256);
4905 tlbncfg[1] = gen_tlbncfg(16, 1, 9, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16);
4906 break;
Varun Sethif7aa5582011-12-22 12:26:17 +00004907 case fsl_e500v2:
Alexander Graf01662f32011-04-30 23:34:58 +02004908 tlbncfg[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4909 tlbncfg[1] = gen_tlbncfg(16, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16);
Alexander Graf892c5872012-04-19 15:34:06 +02004910 break;
4911 case fsl_e500mc:
Alexander Grafb81ccf82012-06-20 21:55:55 +02004912 case fsl_e5500:
Alexander Graf892c5872012-04-19 15:34:06 +02004913 tlbncfg[0] = gen_tlbncfg(4, 1, 1, 0, 512);
4914 tlbncfg[1] = gen_tlbncfg(64, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 64);
4915 break;
4916 default:
Andreas Färbera47dddd2013-09-03 17:38:47 +02004917 cpu_abort(CPU(cpu), "Unknown CPU: " TARGET_FMT_lx "\n", env->spr[SPR_PVR]);
Alexander Graf892c5872012-04-19 15:34:06 +02004918 }
4919#endif
4920 /* Cache sizes */
4921 switch (version) {
4922 case fsl_e500v1:
4923 case fsl_e500v2:
Varun Sethif7aa5582011-12-22 12:26:17 +00004924 env->dcache_line_size = 32;
4925 env->icache_line_size = 32;
4926 break;
4927 case fsl_e500mc:
Alexander Grafb81ccf82012-06-20 21:55:55 +02004928 case fsl_e5500:
Varun Sethif7aa5582011-12-22 12:26:17 +00004929 env->dcache_line_size = 64;
4930 env->icache_line_size = 64;
Alexander Grafa496e8e2012-01-31 03:46:55 +01004931 l1cfg0 |= 0x1000000; /* 64 byte cache block size */
Alexander Grafd2ea2bf2014-01-19 17:47:43 +01004932 l1cfg1 |= 0x1000000; /* 64 byte cache block size */
Alexander Graf01662f32011-04-30 23:34:58 +02004933 break;
4934 default:
Andreas Färbera47dddd2013-09-03 17:38:47 +02004935 cpu_abort(CPU(cpu), "Unknown CPU: " TARGET_FMT_lx "\n", env->spr[SPR_PVR]);
Alexander Graf01662f32011-04-30 23:34:58 +02004936 }
Alexander Graf01662f32011-04-30 23:34:58 +02004937 gen_spr_BookE206(env, 0x000000DF, tlbncfg);
j_mayer80d11f42007-11-17 23:02:20 +00004938 /* XXX : not implemented */
4939 spr_register(env, SPR_HID0, "HID0",
4940 SPR_NOACCESS, SPR_NOACCESS,
4941 &spr_read_generic, &spr_write_generic,
4942 0x00000000);
4943 /* XXX : not implemented */
4944 spr_register(env, SPR_HID1, "HID1",
4945 SPR_NOACCESS, SPR_NOACCESS,
4946 &spr_read_generic, &spr_write_generic,
4947 0x00000000);
4948 /* XXX : not implemented */
4949 spr_register(env, SPR_Exxx_BBEAR, "BBEAR",
4950 SPR_NOACCESS, SPR_NOACCESS,
4951 &spr_read_generic, &spr_write_generic,
4952 0x00000000);
4953 /* XXX : not implemented */
4954 spr_register(env, SPR_Exxx_BBTAR, "BBTAR",
4955 SPR_NOACCESS, SPR_NOACCESS,
4956 &spr_read_generic, &spr_write_generic,
4957 0x00000000);
4958 /* XXX : not implemented */
4959 spr_register(env, SPR_Exxx_MCAR, "MCAR",
4960 SPR_NOACCESS, SPR_NOACCESS,
4961 &spr_read_generic, &spr_write_generic,
4962 0x00000000);
4963 /* XXX : not implemented */
4964 spr_register(env, SPR_BOOKE_MCSR, "MCSR",
4965 SPR_NOACCESS, SPR_NOACCESS,
4966 &spr_read_generic, &spr_write_generic,
4967 0x00000000);
4968 /* XXX : not implemented */
4969 spr_register(env, SPR_Exxx_NPIDR, "NPIDR",
4970 SPR_NOACCESS, SPR_NOACCESS,
4971 &spr_read_generic, &spr_write_generic,
4972 0x00000000);
4973 /* XXX : not implemented */
4974 spr_register(env, SPR_Exxx_BUCSR, "BUCSR",
4975 SPR_NOACCESS, SPR_NOACCESS,
4976 &spr_read_generic, &spr_write_generic,
4977 0x00000000);
4978 /* XXX : not implemented */
4979 spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0",
Alexander Grafdeb05c42014-01-23 11:43:49 +01004980 &spr_read_generic, SPR_NOACCESS,
4981 &spr_read_generic, SPR_NOACCESS,
Alexander Grafa496e8e2012-01-31 03:46:55 +01004982 l1cfg0);
Alexander Grafd2ea2bf2014-01-19 17:47:43 +01004983 spr_register(env, SPR_Exxx_L1CFG1, "L1CFG1",
4984 &spr_read_generic, SPR_NOACCESS,
4985 &spr_read_generic, SPR_NOACCESS,
4986 l1cfg1);
j_mayer80d11f42007-11-17 23:02:20 +00004987 spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0",
4988 SPR_NOACCESS, SPR_NOACCESS,
Alexander Graf01662f32011-04-30 23:34:58 +02004989 &spr_read_generic, &spr_write_e500_l1csr0,
j_mayer80d11f42007-11-17 23:02:20 +00004990 0x00000000);
j_mayer80d11f42007-11-17 23:02:20 +00004991 spr_register(env, SPR_Exxx_L1CSR1, "L1CSR1",
4992 SPR_NOACCESS, SPR_NOACCESS,
Alexander Grafea712582014-01-19 17:49:11 +01004993 &spr_read_generic, &spr_write_e500_l1csr1,
j_mayer80d11f42007-11-17 23:02:20 +00004994 0x00000000);
j_mayer80d11f42007-11-17 23:02:20 +00004995 spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
4996 SPR_NOACCESS, SPR_NOACCESS,
4997 &spr_read_generic, &spr_write_generic,
4998 0x00000000);
4999 spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
5000 SPR_NOACCESS, SPR_NOACCESS,
5001 &spr_read_generic, &spr_write_generic,
5002 0x00000000);
Alexander Graf01662f32011-04-30 23:34:58 +02005003 spr_register(env, SPR_MMUCSR0, "MMUCSR0",
5004 SPR_NOACCESS, SPR_NOACCESS,
5005 &spr_read_generic, &spr_write_booke206_mmucsr0,
5006 0x00000000);
Alexander Grafb81ccf82012-06-20 21:55:55 +02005007 spr_register(env, SPR_BOOKE_EPR, "EPR",
5008 SPR_NOACCESS, SPR_NOACCESS,
Alexander Graf68c2dd72013-01-04 11:21:04 +01005009 &spr_read_generic, SPR_NOACCESS,
Alexander Grafb81ccf82012-06-20 21:55:55 +02005010 0x00000000);
5011 /* XXX better abstract into Emb.xxx features */
5012 if (version == fsl_e5500) {
5013 spr_register(env, SPR_BOOKE_EPCR, "EPCR",
5014 SPR_NOACCESS, SPR_NOACCESS,
5015 &spr_read_generic, &spr_write_generic,
5016 0x00000000);
5017 spr_register(env, SPR_BOOKE_MAS7_MAS3, "MAS7_MAS3",
5018 SPR_NOACCESS, SPR_NOACCESS,
5019 &spr_read_mas73, &spr_write_mas73,
5020 0x00000000);
5021 ivpr_mask = (target_ulong)~0xFFFFULL;
5022 }
Alexander Graf01662f32011-04-30 23:34:58 +02005023
j_mayerf2e63a42007-10-07 15:43:50 +00005024#if !defined(CONFIG_USER_ONLY)
Alexander Graf01662f32011-04-30 23:34:58 +02005025 env->nb_tlb = 0;
Alexander Graf1c53acc2011-06-17 01:00:28 +02005026 env->tlb_type = TLB_MAS;
Alexander Graf01662f32011-04-30 23:34:58 +02005027 for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
5028 env->nb_tlb += booke206_tlb_size(env, i);
5029 }
j_mayerf2e63a42007-10-07 15:43:50 +00005030#endif
Alexander Graf01662f32011-04-30 23:34:58 +02005031
Alexander Grafe9cd84b2012-06-21 15:17:59 +02005032 init_excp_e200(env, ivpr_mask);
aurel329fdc60b2009-03-02 16:42:32 +00005033 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01005034 ppce500_irq_init(ppc_env_get_cpu(env));
j_mayera750fc02007-09-26 23:54:22 +00005035}
j_mayera750fc02007-09-26 23:54:22 +00005036
Alexander Graf01662f32011-04-30 23:34:58 +02005037static void init_proc_e500v1(CPUPPCState *env)
5038{
Varun Sethif7aa5582011-12-22 12:26:17 +00005039 init_proc_e500(env, fsl_e500v1);
Alexander Graf01662f32011-04-30 23:34:58 +02005040}
5041
Andreas Färber7856e3a2013-02-17 23:16:42 +00005042POWERPC_FAMILY(e500v1)(ObjectClass *oc, void *data)
5043{
Andreas Färberca5dff02013-02-17 23:16:46 +00005044 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00005045 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5046
Andreas Färberca5dff02013-02-17 23:16:46 +00005047 dc->desc = "e500v1 core";
Andreas Färber7856e3a2013-02-17 23:16:42 +00005048 pcc->init_proc = init_proc_e500v1;
5049 pcc->check_pow = check_pow_hid0;
Andreas Färber53116eb2013-02-17 23:16:43 +00005050 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
5051 PPC_SPE | PPC_SPE_SINGLE |
5052 PPC_WRTEE | PPC_RFDI |
5053 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5054 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5055 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
5056 pcc->insns_flags2 = PPC2_BOOKE206;
Tom Musta9df5a462014-04-15 12:21:12 -05005057 pcc->msr_mask = (1ull << MSR_UCLE) |
5058 (1ull << MSR_SPE) |
5059 (1ull << MSR_POW) |
5060 (1ull << MSR_CE) |
5061 (1ull << MSR_EE) |
5062 (1ull << MSR_PR) |
5063 (1ull << MSR_FP) |
5064 (1ull << MSR_ME) |
5065 (1ull << MSR_FE0) |
5066 (1ull << MSR_DWE) |
5067 (1ull << MSR_DE) |
5068 (1ull << MSR_FE1) |
5069 (1ull << MSR_IR) |
5070 (1ull << MSR_DR);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00005071 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5072 pcc->excp_model = POWERPC_EXCP_BOOKE;
5073 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5074 pcc->bfd_mach = bfd_mach_ppc_860;
5075 pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
5076 POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
5077 POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00005078}
5079
Alexander Graf01662f32011-04-30 23:34:58 +02005080static void init_proc_e500v2(CPUPPCState *env)
5081{
Varun Sethif7aa5582011-12-22 12:26:17 +00005082 init_proc_e500(env, fsl_e500v2);
5083}
5084
Andreas Färber7856e3a2013-02-17 23:16:42 +00005085POWERPC_FAMILY(e500v2)(ObjectClass *oc, void *data)
5086{
Andreas Färberca5dff02013-02-17 23:16:46 +00005087 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00005088 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5089
Andreas Färberca5dff02013-02-17 23:16:46 +00005090 dc->desc = "e500v2 core";
Andreas Färber7856e3a2013-02-17 23:16:42 +00005091 pcc->init_proc = init_proc_e500v2;
5092 pcc->check_pow = check_pow_hid0;
Andreas Färber53116eb2013-02-17 23:16:43 +00005093 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
5094 PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE |
5095 PPC_WRTEE | PPC_RFDI |
5096 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5097 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5098 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
5099 pcc->insns_flags2 = PPC2_BOOKE206;
Tom Musta9df5a462014-04-15 12:21:12 -05005100 pcc->msr_mask = (1ull << MSR_UCLE) |
5101 (1ull << MSR_SPE) |
5102 (1ull << MSR_POW) |
5103 (1ull << MSR_CE) |
5104 (1ull << MSR_EE) |
5105 (1ull << MSR_PR) |
5106 (1ull << MSR_FP) |
5107 (1ull << MSR_ME) |
5108 (1ull << MSR_FE0) |
5109 (1ull << MSR_DWE) |
5110 (1ull << MSR_DE) |
5111 (1ull << MSR_FE1) |
5112 (1ull << MSR_IR) |
5113 (1ull << MSR_DR);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00005114 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5115 pcc->excp_model = POWERPC_EXCP_BOOKE;
5116 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5117 pcc->bfd_mach = bfd_mach_ppc_860;
5118 pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
5119 POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
5120 POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00005121}
5122
Varun Sethif7aa5582011-12-22 12:26:17 +00005123static void init_proc_e500mc(CPUPPCState *env)
5124{
5125 init_proc_e500(env, fsl_e500mc);
Alexander Graf01662f32011-04-30 23:34:58 +02005126}
5127
Andreas Färber7856e3a2013-02-17 23:16:42 +00005128POWERPC_FAMILY(e500mc)(ObjectClass *oc, void *data)
5129{
Andreas Färberca5dff02013-02-17 23:16:46 +00005130 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00005131 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5132
Andreas Färberca5dff02013-02-17 23:16:46 +00005133 dc->desc = "e500mc core";
Andreas Färber7856e3a2013-02-17 23:16:42 +00005134 pcc->init_proc = init_proc_e500mc;
5135 pcc->check_pow = check_pow_none;
Michael Walle2fff4ba2016-07-22 18:53:51 +02005136 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
Andreas Färber53116eb2013-02-17 23:16:43 +00005137 PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
5138 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5139 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5140 PPC_FLOAT | PPC_FLOAT_FRES |
5141 PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
5142 PPC_FLOAT_STFIWX | PPC_WAIT |
5143 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
5144 pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL;
Tom Musta9df5a462014-04-15 12:21:12 -05005145 pcc->msr_mask = (1ull << MSR_GS) |
5146 (1ull << MSR_UCLE) |
5147 (1ull << MSR_CE) |
5148 (1ull << MSR_EE) |
5149 (1ull << MSR_PR) |
5150 (1ull << MSR_FP) |
5151 (1ull << MSR_ME) |
5152 (1ull << MSR_FE0) |
5153 (1ull << MSR_DE) |
5154 (1ull << MSR_FE1) |
5155 (1ull << MSR_IR) |
5156 (1ull << MSR_DR) |
5157 (1ull << MSR_PX) |
5158 (1ull << MSR_RI);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00005159 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5160 pcc->excp_model = POWERPC_EXCP_BOOKE;
5161 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5162 /* FIXME: figure out the correct flag for e500mc */
5163 pcc->bfd_mach = bfd_mach_ppc_e500;
5164 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
5165 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00005166}
5167
Alexander Grafb81ccf82012-06-20 21:55:55 +02005168#ifdef TARGET_PPC64
5169static void init_proc_e5500(CPUPPCState *env)
5170{
5171 init_proc_e500(env, fsl_e5500);
5172}
Andreas Färber7856e3a2013-02-17 23:16:42 +00005173
5174POWERPC_FAMILY(e5500)(ObjectClass *oc, void *data)
5175{
Andreas Färberca5dff02013-02-17 23:16:46 +00005176 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00005177 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5178
Andreas Färberca5dff02013-02-17 23:16:46 +00005179 dc->desc = "e5500 core";
Andreas Färber7856e3a2013-02-17 23:16:42 +00005180 pcc->init_proc = init_proc_e5500;
5181 pcc->check_pow = check_pow_none;
Michael Walle2fff4ba2016-07-22 18:53:51 +02005182 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
Andreas Färber53116eb2013-02-17 23:16:43 +00005183 PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
5184 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
5185 PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
5186 PPC_FLOAT | PPC_FLOAT_FRES |
5187 PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
5188 PPC_FLOAT_STFIWX | PPC_WAIT |
5189 PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC |
5190 PPC_64B | PPC_POPCNTB | PPC_POPCNTWD;
Pierre Mallard41718532014-09-12 21:31:32 +02005191 pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL | PPC2_PERM_ISA206 | \
5192 PPC2_FP_CVT_S64;
Tom Musta9df5a462014-04-15 12:21:12 -05005193 pcc->msr_mask = (1ull << MSR_CM) |
5194 (1ull << MSR_GS) |
5195 (1ull << MSR_UCLE) |
5196 (1ull << MSR_CE) |
5197 (1ull << MSR_EE) |
5198 (1ull << MSR_PR) |
5199 (1ull << MSR_FP) |
5200 (1ull << MSR_ME) |
5201 (1ull << MSR_FE0) |
5202 (1ull << MSR_DE) |
5203 (1ull << MSR_FE1) |
5204 (1ull << MSR_IR) |
5205 (1ull << MSR_DR) |
5206 (1ull << MSR_PX) |
5207 (1ull << MSR_RI);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00005208 pcc->mmu_model = POWERPC_MMU_BOOKE206;
5209 pcc->excp_model = POWERPC_EXCP_BOOKE;
5210 pcc->bus_model = PPC_FLAGS_INPUT_BookE;
5211 /* FIXME: figure out the correct flag for e5500 */
5212 pcc->bfd_mach = bfd_mach_ppc_e500;
5213 pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
5214 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00005215}
Alexander Grafb81ccf82012-06-20 21:55:55 +02005216#endif
5217
j_mayera750fc02007-09-26 23:54:22 +00005218/* Non-embedded PowerPC */
j_mayera750fc02007-09-26 23:54:22 +00005219
5220/* POWER : same as 601, without mfmsr, mfsr */
Andreas Färber53116eb2013-02-17 23:16:43 +00005221POWERPC_FAMILY(POWER)(ObjectClass *oc, void *data)
5222{
Andreas Färberca5dff02013-02-17 23:16:46 +00005223 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber53116eb2013-02-17 23:16:43 +00005224 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5225
Andreas Färberca5dff02013-02-17 23:16:46 +00005226 dc->desc = "POWER";
Andreas Färber953af182013-02-17 23:16:49 +00005227 /* pcc->insns_flags = XXX_TODO; */
Andreas Färberba9fd9f2013-02-17 23:16:45 +00005228 /* POWER RSC (from RAD6000) */
Tom Musta9df5a462014-04-15 12:21:12 -05005229 pcc->msr_mask = (1ull << MSR_EE) |
5230 (1ull << MSR_PR) |
5231 (1ull << MSR_FP) |
5232 (1ull << MSR_ME) |
5233 (1ull << MSR_FE0) |
5234 (1ull << MSR_SE) |
5235 (1ull << MSR_DE) |
5236 (1ull << MSR_AL) |
5237 (1ull << MSR_EP) |
5238 (1ull << MSR_IR) |
5239 (1ull << MSR_DR);
Andreas Färber53116eb2013-02-17 23:16:43 +00005240}
j_mayera750fc02007-09-26 23:54:22 +00005241
j_mayer082c6682007-11-19 13:22:47 +00005242#define POWERPC_MSRR_601 (0x0000000000001040ULL)
j_mayera750fc02007-09-26 23:54:22 +00005243
5244static void init_proc_601 (CPUPPCState *env)
5245{
5246 gen_spr_ne_601(env);
5247 gen_spr_601(env);
5248 /* Hardware implementation registers */
5249 /* XXX : not implemented */
5250 spr_register(env, SPR_HID0, "HID0",
5251 SPR_NOACCESS, SPR_NOACCESS,
j_mayer056401e2007-11-04 02:55:33 +00005252 &spr_read_generic, &spr_write_hid0_601,
j_mayerfaadf502007-11-03 13:37:12 +00005253 0x80010080);
j_mayera750fc02007-09-26 23:54:22 +00005254 /* XXX : not implemented */
5255 spr_register(env, SPR_HID1, "HID1",
5256 SPR_NOACCESS, SPR_NOACCESS,
5257 &spr_read_generic, &spr_write_generic,
5258 0x00000000);
5259 /* XXX : not implemented */
5260 spr_register(env, SPR_601_HID2, "HID2",
5261 SPR_NOACCESS, SPR_NOACCESS,
5262 &spr_read_generic, &spr_write_generic,
5263 0x00000000);
5264 /* XXX : not implemented */
5265 spr_register(env, SPR_601_HID5, "HID5",
5266 SPR_NOACCESS, SPR_NOACCESS,
5267 &spr_read_generic, &spr_write_generic,
5268 0x00000000);
j_mayera750fc02007-09-26 23:54:22 +00005269 /* Memory management */
j_mayere1833e12007-09-29 13:06:16 +00005270 init_excp_601(env);
j_mayer082c6682007-11-19 13:22:47 +00005271 /* XXX: beware that dcache line size is 64
5272 * but dcbz uses 32 bytes "sectors"
5273 * XXX: this breaks clcs instruction !
5274 */
5275 env->dcache_line_size = 32;
j_mayerd63001d2007-10-04 00:51:58 +00005276 env->icache_line_size = 64;
j_mayerfaadf502007-11-03 13:37:12 +00005277 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01005278 ppc6xx_irq_init(ppc_env_get_cpu(env));
j_mayera750fc02007-09-26 23:54:22 +00005279}
5280
Andreas Färber7856e3a2013-02-17 23:16:42 +00005281POWERPC_FAMILY(601)(ObjectClass *oc, void *data)
5282{
Andreas Färberca5dff02013-02-17 23:16:46 +00005283 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00005284 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5285
Andreas Färberca5dff02013-02-17 23:16:46 +00005286 dc->desc = "PowerPC 601";
Andreas Färber7856e3a2013-02-17 23:16:42 +00005287 pcc->init_proc = init_proc_601;
5288 pcc->check_pow = check_pow_none;
Andreas Färber53116eb2013-02-17 23:16:43 +00005289 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
5290 PPC_FLOAT |
5291 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5292 PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
5293 PPC_SEGMENT | PPC_EXTERN;
Tom Musta9df5a462014-04-15 12:21:12 -05005294 pcc->msr_mask = (1ull << MSR_EE) |
5295 (1ull << MSR_PR) |
5296 (1ull << MSR_FP) |
5297 (1ull << MSR_ME) |
5298 (1ull << MSR_FE0) |
5299 (1ull << MSR_SE) |
5300 (1ull << MSR_FE1) |
5301 (1ull << MSR_EP) |
5302 (1ull << MSR_IR) |
5303 (1ull << MSR_DR);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00005304 pcc->mmu_model = POWERPC_MMU_601;
David Gibsonb632a142013-03-13 11:40:33 +11005305#if defined(CONFIG_SOFTMMU)
5306 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5307#endif
Andreas Färberba9fd9f2013-02-17 23:16:45 +00005308 pcc->excp_model = POWERPC_EXCP_601;
5309 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5310 pcc->bfd_mach = bfd_mach_ppc_601;
5311 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00005312}
5313
j_mayer082c6682007-11-19 13:22:47 +00005314#define POWERPC_MSRR_601v (0x0000000000001040ULL)
j_mayer082c6682007-11-19 13:22:47 +00005315
5316static void init_proc_601v (CPUPPCState *env)
5317{
5318 init_proc_601(env);
5319 /* XXX : not implemented */
5320 spr_register(env, SPR_601_HID15, "HID15",
5321 SPR_NOACCESS, SPR_NOACCESS,
5322 &spr_read_generic, &spr_write_generic,
5323 0x00000000);
5324}
5325
Andreas Färber7856e3a2013-02-17 23:16:42 +00005326POWERPC_FAMILY(601v)(ObjectClass *oc, void *data)
5327{
Andreas Färberca5dff02013-02-17 23:16:46 +00005328 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00005329 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5330
Andreas Färberca5dff02013-02-17 23:16:46 +00005331 dc->desc = "PowerPC 601v";
Andreas Färber7856e3a2013-02-17 23:16:42 +00005332 pcc->init_proc = init_proc_601v;
5333 pcc->check_pow = check_pow_none;
Andreas Färber53116eb2013-02-17 23:16:43 +00005334 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
5335 PPC_FLOAT |
5336 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5337 PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
5338 PPC_SEGMENT | PPC_EXTERN;
Tom Musta9df5a462014-04-15 12:21:12 -05005339 pcc->msr_mask = (1ull << MSR_EE) |
5340 (1ull << MSR_PR) |
5341 (1ull << MSR_FP) |
5342 (1ull << MSR_ME) |
5343 (1ull << MSR_FE0) |
5344 (1ull << MSR_SE) |
5345 (1ull << MSR_FE1) |
5346 (1ull << MSR_EP) |
5347 (1ull << MSR_IR) |
5348 (1ull << MSR_DR);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00005349 pcc->mmu_model = POWERPC_MMU_601;
David Gibsonb632a142013-03-13 11:40:33 +11005350#if defined(CONFIG_SOFTMMU)
5351 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5352#endif
Andreas Färberba9fd9f2013-02-17 23:16:45 +00005353 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5354 pcc->bfd_mach = bfd_mach_ppc_601;
5355 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00005356}
5357
j_mayera750fc02007-09-26 23:54:22 +00005358static void init_proc_602 (CPUPPCState *env)
5359{
5360 gen_spr_ne_601(env);
5361 gen_spr_602(env);
5362 /* Time base */
5363 gen_tbl(env);
5364 /* hardware implementation registers */
5365 /* XXX : not implemented */
5366 spr_register(env, SPR_HID0, "HID0",
5367 SPR_NOACCESS, SPR_NOACCESS,
5368 &spr_read_generic, &spr_write_generic,
5369 0x00000000);
5370 /* XXX : not implemented */
5371 spr_register(env, SPR_HID1, "HID1",
5372 SPR_NOACCESS, SPR_NOACCESS,
5373 &spr_read_generic, &spr_write_generic,
5374 0x00000000);
5375 /* Memory management */
5376 gen_low_BATs(env);
5377 gen_6xx_7xx_soft_tlb(env, 64, 2);
j_mayere1833e12007-09-29 13:06:16 +00005378 init_excp_602(env);
j_mayerd63001d2007-10-04 00:51:58 +00005379 env->dcache_line_size = 32;
5380 env->icache_line_size = 32;
j_mayera750fc02007-09-26 23:54:22 +00005381 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01005382 ppc6xx_irq_init(ppc_env_get_cpu(env));
j_mayera750fc02007-09-26 23:54:22 +00005383}
5384
Andreas Färber7856e3a2013-02-17 23:16:42 +00005385POWERPC_FAMILY(602)(ObjectClass *oc, void *data)
5386{
Andreas Färberca5dff02013-02-17 23:16:46 +00005387 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00005388 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5389
Andreas Färberca5dff02013-02-17 23:16:46 +00005390 dc->desc = "PowerPC 602";
Andreas Färber7856e3a2013-02-17 23:16:42 +00005391 pcc->init_proc = init_proc_602;
5392 pcc->check_pow = check_pow_hid0;
Andreas Färber53116eb2013-02-17 23:16:43 +00005393 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5394 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5395 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5396 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5397 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5398 PPC_MEM_TLBIE | PPC_6xx_TLB | PPC_MEM_TLBSYNC |
5399 PPC_SEGMENT | PPC_602_SPEC;
Tom Musta9df5a462014-04-15 12:21:12 -05005400 pcc->msr_mask = (1ull << MSR_VSX) |
5401 (1ull << MSR_SA) |
5402 (1ull << MSR_POW) |
5403 (1ull << MSR_TGPR) |
5404 (1ull << MSR_ILE) |
5405 (1ull << MSR_EE) |
5406 (1ull << MSR_PR) |
5407 (1ull << MSR_FP) |
5408 (1ull << MSR_ME) |
5409 (1ull << MSR_FE0) |
5410 (1ull << MSR_SE) |
5411 (1ull << MSR_DE) |
5412 (1ull << MSR_FE1) |
5413 (1ull << MSR_EP) |
5414 (1ull << MSR_IR) |
5415 (1ull << MSR_DR) |
5416 (1ull << MSR_RI) |
5417 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00005418 /* XXX: 602 MMU is quite specific. Should add a special case */
5419 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
5420 pcc->excp_model = POWERPC_EXCP_602;
5421 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5422 pcc->bfd_mach = bfd_mach_ppc_602;
5423 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
5424 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00005425}
5426
j_mayera750fc02007-09-26 23:54:22 +00005427static void init_proc_603 (CPUPPCState *env)
5428{
5429 gen_spr_ne_601(env);
5430 gen_spr_603(env);
5431 /* Time base */
5432 gen_tbl(env);
5433 /* hardware implementation registers */
5434 /* XXX : not implemented */
5435 spr_register(env, SPR_HID0, "HID0",
5436 SPR_NOACCESS, SPR_NOACCESS,
5437 &spr_read_generic, &spr_write_generic,
5438 0x00000000);
5439 /* XXX : not implemented */
5440 spr_register(env, SPR_HID1, "HID1",
5441 SPR_NOACCESS, SPR_NOACCESS,
5442 &spr_read_generic, &spr_write_generic,
5443 0x00000000);
5444 /* Memory management */
5445 gen_low_BATs(env);
5446 gen_6xx_7xx_soft_tlb(env, 64, 2);
j_mayere1833e12007-09-29 13:06:16 +00005447 init_excp_603(env);
j_mayerd63001d2007-10-04 00:51:58 +00005448 env->dcache_line_size = 32;
5449 env->icache_line_size = 32;
j_mayera750fc02007-09-26 23:54:22 +00005450 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01005451 ppc6xx_irq_init(ppc_env_get_cpu(env));
j_mayera750fc02007-09-26 23:54:22 +00005452}
5453
Andreas Färber7856e3a2013-02-17 23:16:42 +00005454POWERPC_FAMILY(603)(ObjectClass *oc, void *data)
5455{
Andreas Färberca5dff02013-02-17 23:16:46 +00005456 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00005457 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5458
Andreas Färberca5dff02013-02-17 23:16:46 +00005459 dc->desc = "PowerPC 603";
Andreas Färber7856e3a2013-02-17 23:16:42 +00005460 pcc->init_proc = init_proc_603;
5461 pcc->check_pow = check_pow_hid0;
Andreas Färber53116eb2013-02-17 23:16:43 +00005462 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 | PPC_6xx_TLB |
5468 PPC_SEGMENT | PPC_EXTERN;
Tom Musta9df5a462014-04-15 12:21:12 -05005469 pcc->msr_mask = (1ull << MSR_POW) |
5470 (1ull << MSR_TGPR) |
5471 (1ull << MSR_ILE) |
5472 (1ull << MSR_EE) |
5473 (1ull << MSR_PR) |
5474 (1ull << MSR_FP) |
5475 (1ull << MSR_ME) |
5476 (1ull << MSR_FE0) |
5477 (1ull << MSR_SE) |
5478 (1ull << MSR_DE) |
5479 (1ull << MSR_FE1) |
5480 (1ull << MSR_EP) |
5481 (1ull << MSR_IR) |
5482 (1ull << MSR_DR) |
5483 (1ull << MSR_RI) |
5484 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00005485 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
5486 pcc->excp_model = POWERPC_EXCP_603;
5487 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5488 pcc->bfd_mach = bfd_mach_ppc_603;
5489 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
5490 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00005491}
5492
j_mayera750fc02007-09-26 23:54:22 +00005493static void init_proc_603E (CPUPPCState *env)
5494{
5495 gen_spr_ne_601(env);
5496 gen_spr_603(env);
5497 /* Time base */
5498 gen_tbl(env);
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);
j_mayera750fc02007-09-26 23:54:22 +00005510 /* Memory management */
5511 gen_low_BATs(env);
5512 gen_6xx_7xx_soft_tlb(env, 64, 2);
j_mayere1833e12007-09-29 13:06:16 +00005513 init_excp_603(env);
j_mayerd63001d2007-10-04 00:51:58 +00005514 env->dcache_line_size = 32;
5515 env->icache_line_size = 32;
j_mayera750fc02007-09-26 23:54:22 +00005516 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01005517 ppc6xx_irq_init(ppc_env_get_cpu(env));
j_mayera750fc02007-09-26 23:54:22 +00005518}
5519
Andreas Färber7856e3a2013-02-17 23:16:42 +00005520POWERPC_FAMILY(603E)(ObjectClass *oc, void *data)
5521{
Andreas Färberca5dff02013-02-17 23:16:46 +00005522 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00005523 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5524
Andreas Färberca5dff02013-02-17 23:16:46 +00005525 dc->desc = "PowerPC 603e";
Andreas Färber7856e3a2013-02-17 23:16:42 +00005526 pcc->init_proc = init_proc_603E;
5527 pcc->check_pow = check_pow_hid0;
Andreas Färber53116eb2013-02-17 23:16:43 +00005528 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5529 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5530 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5531 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5532 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5533 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
5534 PPC_SEGMENT | PPC_EXTERN;
Tom Musta9df5a462014-04-15 12:21:12 -05005535 pcc->msr_mask = (1ull << MSR_POW) |
5536 (1ull << MSR_TGPR) |
5537 (1ull << MSR_ILE) |
5538 (1ull << MSR_EE) |
5539 (1ull << MSR_PR) |
5540 (1ull << MSR_FP) |
5541 (1ull << MSR_ME) |
5542 (1ull << MSR_FE0) |
5543 (1ull << MSR_SE) |
5544 (1ull << MSR_DE) |
5545 (1ull << MSR_FE1) |
5546 (1ull << MSR_EP) |
5547 (1ull << MSR_IR) |
5548 (1ull << MSR_DR) |
5549 (1ull << MSR_RI) |
5550 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00005551 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
5552 pcc->excp_model = POWERPC_EXCP_603E;
5553 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5554 pcc->bfd_mach = bfd_mach_ppc_ec603e;
5555 pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
5556 POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00005557}
5558
j_mayera750fc02007-09-26 23:54:22 +00005559static void init_proc_604 (CPUPPCState *env)
5560{
5561 gen_spr_ne_601(env);
5562 gen_spr_604(env);
5563 /* Time base */
5564 gen_tbl(env);
5565 /* Hardware implementation registers */
5566 /* XXX : not implemented */
5567 spr_register(env, SPR_HID0, "HID0",
5568 SPR_NOACCESS, SPR_NOACCESS,
5569 &spr_read_generic, &spr_write_generic,
5570 0x00000000);
j_mayer082c6682007-11-19 13:22:47 +00005571 /* Memory management */
5572 gen_low_BATs(env);
5573 init_excp_604(env);
5574 env->dcache_line_size = 32;
5575 env->icache_line_size = 32;
5576 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01005577 ppc6xx_irq_init(ppc_env_get_cpu(env));
j_mayer082c6682007-11-19 13:22:47 +00005578}
5579
Andreas Färber7856e3a2013-02-17 23:16:42 +00005580POWERPC_FAMILY(604)(ObjectClass *oc, void *data)
5581{
Andreas Färberca5dff02013-02-17 23:16:46 +00005582 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00005583 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5584
Andreas Färberca5dff02013-02-17 23:16:46 +00005585 dc->desc = "PowerPC 604";
Andreas Färber7856e3a2013-02-17 23:16:42 +00005586 pcc->init_proc = init_proc_604;
5587 pcc->check_pow = check_pow_nocheck;
Andreas Färber53116eb2013-02-17 23:16:43 +00005588 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5589 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5590 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5591 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5592 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5593 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5594 PPC_SEGMENT | PPC_EXTERN;
Tom Musta9df5a462014-04-15 12:21:12 -05005595 pcc->msr_mask = (1ull << MSR_POW) |
5596 (1ull << MSR_ILE) |
5597 (1ull << MSR_EE) |
5598 (1ull << MSR_PR) |
5599 (1ull << MSR_FP) |
5600 (1ull << MSR_ME) |
5601 (1ull << MSR_FE0) |
5602 (1ull << MSR_SE) |
5603 (1ull << MSR_DE) |
5604 (1ull << MSR_FE1) |
5605 (1ull << MSR_EP) |
5606 (1ull << MSR_IR) |
5607 (1ull << MSR_DR) |
5608 (1ull << MSR_PMM) |
5609 (1ull << MSR_RI) |
5610 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00005611 pcc->mmu_model = POWERPC_MMU_32B;
David Gibsonb632a142013-03-13 11:40:33 +11005612#if defined(CONFIG_SOFTMMU)
5613 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5614#endif
Andreas Färberba9fd9f2013-02-17 23:16:45 +00005615 pcc->excp_model = POWERPC_EXCP_604;
5616 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5617 pcc->bfd_mach = bfd_mach_ppc_604;
5618 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5619 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00005620}
5621
j_mayer082c6682007-11-19 13:22:47 +00005622static void init_proc_604E (CPUPPCState *env)
5623{
5624 gen_spr_ne_601(env);
5625 gen_spr_604(env);
5626 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10005627 spr_register(env, SPR_7XX_MMCR1, "MMCR1",
j_mayer082c6682007-11-19 13:22:47 +00005628 SPR_NOACCESS, SPR_NOACCESS,
5629 &spr_read_generic, &spr_write_generic,
5630 0x00000000);
5631 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10005632 spr_register(env, SPR_7XX_PMC3, "PMC3",
j_mayer082c6682007-11-19 13:22:47 +00005633 SPR_NOACCESS, SPR_NOACCESS,
5634 &spr_read_generic, &spr_write_generic,
5635 0x00000000);
5636 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10005637 spr_register(env, SPR_7XX_PMC4, "PMC4",
j_mayer082c6682007-11-19 13:22:47 +00005638 SPR_NOACCESS, SPR_NOACCESS,
5639 &spr_read_generic, &spr_write_generic,
5640 0x00000000);
5641 /* Time base */
5642 gen_tbl(env);
5643 /* Hardware implementation registers */
5644 /* XXX : not implemented */
5645 spr_register(env, SPR_HID0, "HID0",
5646 SPR_NOACCESS, SPR_NOACCESS,
5647 &spr_read_generic, &spr_write_generic,
5648 0x00000000);
j_mayera750fc02007-09-26 23:54:22 +00005649 /* XXX : not implemented */
5650 spr_register(env, SPR_HID1, "HID1",
5651 SPR_NOACCESS, SPR_NOACCESS,
5652 &spr_read_generic, &spr_write_generic,
5653 0x00000000);
5654 /* Memory management */
5655 gen_low_BATs(env);
j_mayere1833e12007-09-29 13:06:16 +00005656 init_excp_604(env);
j_mayerd63001d2007-10-04 00:51:58 +00005657 env->dcache_line_size = 32;
5658 env->icache_line_size = 32;
j_mayera750fc02007-09-26 23:54:22 +00005659 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01005660 ppc6xx_irq_init(ppc_env_get_cpu(env));
j_mayera750fc02007-09-26 23:54:22 +00005661}
5662
Andreas Färber7856e3a2013-02-17 23:16:42 +00005663POWERPC_FAMILY(604E)(ObjectClass *oc, void *data)
5664{
Andreas Färberca5dff02013-02-17 23:16:46 +00005665 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00005666 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5667
Andreas Färberca5dff02013-02-17 23:16:46 +00005668 dc->desc = "PowerPC 604E";
Andreas Färber7856e3a2013-02-17 23:16:42 +00005669 pcc->init_proc = init_proc_604E;
5670 pcc->check_pow = check_pow_nocheck;
Andreas Färber53116eb2013-02-17 23:16:43 +00005671 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5672 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5673 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5674 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5675 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5676 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5677 PPC_SEGMENT | PPC_EXTERN;
Tom Musta9df5a462014-04-15 12:21:12 -05005678 pcc->msr_mask = (1ull << MSR_POW) |
5679 (1ull << MSR_ILE) |
5680 (1ull << MSR_EE) |
5681 (1ull << MSR_PR) |
5682 (1ull << MSR_FP) |
5683 (1ull << MSR_ME) |
5684 (1ull << MSR_FE0) |
5685 (1ull << MSR_SE) |
5686 (1ull << MSR_DE) |
5687 (1ull << MSR_FE1) |
5688 (1ull << MSR_EP) |
5689 (1ull << MSR_IR) |
5690 (1ull << MSR_DR) |
5691 (1ull << MSR_PMM) |
5692 (1ull << MSR_RI) |
5693 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00005694 pcc->mmu_model = POWERPC_MMU_32B;
David Gibsonb632a142013-03-13 11:40:33 +11005695#if defined(CONFIG_SOFTMMU)
5696 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5697#endif
Andreas Färberba9fd9f2013-02-17 23:16:45 +00005698 pcc->excp_model = POWERPC_EXCP_604;
5699 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5700 pcc->bfd_mach = bfd_mach_ppc_604;
5701 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5702 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00005703}
5704
j_mayerbd928eb2007-11-21 13:08:23 +00005705static void init_proc_740 (CPUPPCState *env)
j_mayera750fc02007-09-26 23:54:22 +00005706{
5707 gen_spr_ne_601(env);
5708 gen_spr_7xx(env);
5709 /* Time base */
5710 gen_tbl(env);
5711 /* Thermal management */
5712 gen_spr_thrm(env);
5713 /* Hardware implementation registers */
5714 /* XXX : not implemented */
5715 spr_register(env, SPR_HID0, "HID0",
5716 SPR_NOACCESS, SPR_NOACCESS,
5717 &spr_read_generic, &spr_write_generic,
5718 0x00000000);
5719 /* XXX : not implemented */
5720 spr_register(env, SPR_HID1, "HID1",
5721 SPR_NOACCESS, SPR_NOACCESS,
5722 &spr_read_generic, &spr_write_generic,
5723 0x00000000);
5724 /* Memory management */
5725 gen_low_BATs(env);
j_mayere1833e12007-09-29 13:06:16 +00005726 init_excp_7x0(env);
j_mayerd63001d2007-10-04 00:51:58 +00005727 env->dcache_line_size = 32;
5728 env->icache_line_size = 32;
j_mayera750fc02007-09-26 23:54:22 +00005729 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01005730 ppc6xx_irq_init(ppc_env_get_cpu(env));
j_mayera750fc02007-09-26 23:54:22 +00005731}
5732
Andreas Färber7856e3a2013-02-17 23:16:42 +00005733POWERPC_FAMILY(740)(ObjectClass *oc, void *data)
5734{
Andreas Färberca5dff02013-02-17 23:16:46 +00005735 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00005736 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5737
Andreas Färberca5dff02013-02-17 23:16:46 +00005738 dc->desc = "PowerPC 740";
Andreas Färber7856e3a2013-02-17 23:16:42 +00005739 pcc->init_proc = init_proc_740;
5740 pcc->check_pow = check_pow_hid0;
Andreas Färber53116eb2013-02-17 23:16:43 +00005741 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5742 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5743 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5744 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5745 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5746 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5747 PPC_SEGMENT | PPC_EXTERN;
Tom Musta9df5a462014-04-15 12:21:12 -05005748 pcc->msr_mask = (1ull << MSR_POW) |
5749 (1ull << MSR_ILE) |
5750 (1ull << MSR_EE) |
5751 (1ull << MSR_PR) |
5752 (1ull << MSR_FP) |
5753 (1ull << MSR_ME) |
5754 (1ull << MSR_FE0) |
5755 (1ull << MSR_SE) |
5756 (1ull << MSR_DE) |
5757 (1ull << MSR_FE1) |
5758 (1ull << MSR_EP) |
5759 (1ull << MSR_IR) |
5760 (1ull << MSR_DR) |
5761 (1ull << MSR_PMM) |
5762 (1ull << MSR_RI) |
5763 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00005764 pcc->mmu_model = POWERPC_MMU_32B;
David Gibsonb632a142013-03-13 11:40:33 +11005765#if defined(CONFIG_SOFTMMU)
5766 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5767#endif
Andreas Färberba9fd9f2013-02-17 23:16:45 +00005768 pcc->excp_model = POWERPC_EXCP_7x0;
5769 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5770 pcc->bfd_mach = bfd_mach_ppc_750;
5771 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5772 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00005773}
5774
j_mayerbd928eb2007-11-21 13:08:23 +00005775static void init_proc_750 (CPUPPCState *env)
5776{
5777 gen_spr_ne_601(env);
5778 gen_spr_7xx(env);
5779 /* XXX : not implemented */
5780 spr_register(env, SPR_L2CR, "L2CR",
5781 SPR_NOACCESS, SPR_NOACCESS,
Alexander Graf9633fcc2013-09-25 15:41:12 +02005782 &spr_read_generic, spr_access_nop,
j_mayerbd928eb2007-11-21 13:08:23 +00005783 0x00000000);
5784 /* Time base */
5785 gen_tbl(env);
5786 /* Thermal management */
5787 gen_spr_thrm(env);
5788 /* Hardware implementation registers */
5789 /* XXX : not implemented */
5790 spr_register(env, SPR_HID0, "HID0",
5791 SPR_NOACCESS, SPR_NOACCESS,
5792 &spr_read_generic, &spr_write_generic,
5793 0x00000000);
5794 /* XXX : not implemented */
5795 spr_register(env, SPR_HID1, "HID1",
5796 SPR_NOACCESS, SPR_NOACCESS,
5797 &spr_read_generic, &spr_write_generic,
5798 0x00000000);
5799 /* Memory management */
5800 gen_low_BATs(env);
5801 /* XXX: high BATs are also present but are known to be bugged on
5802 * die version 1.x
5803 */
5804 init_excp_7x0(env);
5805 env->dcache_line_size = 32;
5806 env->icache_line_size = 32;
5807 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01005808 ppc6xx_irq_init(ppc_env_get_cpu(env));
j_mayerbd928eb2007-11-21 13:08:23 +00005809}
5810
Andreas Färber7856e3a2013-02-17 23:16:42 +00005811POWERPC_FAMILY(750)(ObjectClass *oc, void *data)
5812{
Andreas Färberca5dff02013-02-17 23:16:46 +00005813 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00005814 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5815
Andreas Färberca5dff02013-02-17 23:16:46 +00005816 dc->desc = "PowerPC 750";
Andreas Färber7856e3a2013-02-17 23:16:42 +00005817 pcc->init_proc = init_proc_750;
5818 pcc->check_pow = check_pow_hid0;
Andreas Färber53116eb2013-02-17 23:16:43 +00005819 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
5820 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
5821 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
5822 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
5823 PPC_MEM_SYNC | PPC_MEM_EIEIO |
5824 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
5825 PPC_SEGMENT | PPC_EXTERN;
Tom Musta9df5a462014-04-15 12:21:12 -05005826 pcc->msr_mask = (1ull << MSR_POW) |
5827 (1ull << MSR_ILE) |
5828 (1ull << MSR_EE) |
5829 (1ull << MSR_PR) |
5830 (1ull << MSR_FP) |
5831 (1ull << MSR_ME) |
5832 (1ull << MSR_FE0) |
5833 (1ull << MSR_SE) |
5834 (1ull << MSR_DE) |
5835 (1ull << MSR_FE1) |
5836 (1ull << MSR_EP) |
5837 (1ull << MSR_IR) |
5838 (1ull << MSR_DR) |
5839 (1ull << MSR_PMM) |
5840 (1ull << MSR_RI) |
5841 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00005842 pcc->mmu_model = POWERPC_MMU_32B;
David Gibsonb632a142013-03-13 11:40:33 +11005843#if defined(CONFIG_SOFTMMU)
5844 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
5845#endif
Andreas Färberba9fd9f2013-02-17 23:16:45 +00005846 pcc->excp_model = POWERPC_EXCP_7x0;
5847 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
5848 pcc->bfd_mach = bfd_mach_ppc_750;
5849 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
5850 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00005851}
5852
j_mayerbd928eb2007-11-21 13:08:23 +00005853static void init_proc_750cl (CPUPPCState *env)
5854{
5855 gen_spr_ne_601(env);
5856 gen_spr_7xx(env);
5857 /* XXX : not implemented */
5858 spr_register(env, SPR_L2CR, "L2CR",
5859 SPR_NOACCESS, SPR_NOACCESS,
Alexander Graf9633fcc2013-09-25 15:41:12 +02005860 &spr_read_generic, spr_access_nop,
j_mayerbd928eb2007-11-21 13:08:23 +00005861 0x00000000);
5862 /* Time base */
5863 gen_tbl(env);
5864 /* Thermal management */
5865 /* Those registers are fake on 750CL */
5866 spr_register(env, SPR_THRM1, "THRM1",
5867 SPR_NOACCESS, SPR_NOACCESS,
5868 &spr_read_generic, &spr_write_generic,
5869 0x00000000);
5870 spr_register(env, SPR_THRM2, "THRM2",
5871 SPR_NOACCESS, SPR_NOACCESS,
5872 &spr_read_generic, &spr_write_generic,
5873 0x00000000);
5874 spr_register(env, SPR_THRM3, "THRM3",
5875 SPR_NOACCESS, SPR_NOACCESS,
5876 &spr_read_generic, &spr_write_generic,
5877 0x00000000);
5878 /* XXX: not implemented */
5879 spr_register(env, SPR_750_TDCL, "TDCL",
5880 SPR_NOACCESS, SPR_NOACCESS,
5881 &spr_read_generic, &spr_write_generic,
5882 0x00000000);
5883 spr_register(env, SPR_750_TDCH, "TDCH",
5884 SPR_NOACCESS, SPR_NOACCESS,
5885 &spr_read_generic, &spr_write_generic,
5886 0x00000000);
5887 /* DMA */
5888 /* XXX : not implemented */
5889 spr_register(env, SPR_750_WPAR, "WPAR",
5890 SPR_NOACCESS, SPR_NOACCESS,
5891 &spr_read_generic, &spr_write_generic,
5892 0x00000000);
5893 spr_register(env, SPR_750_DMAL, "DMAL",
5894 SPR_NOACCESS, SPR_NOACCESS,
5895 &spr_read_generic, &spr_write_generic,
5896 0x00000000);
5897 spr_register(env, SPR_750_DMAU, "DMAU",
5898 SPR_NOACCESS, SPR_NOACCESS,
5899 &spr_read_generic, &spr_write_generic,
5900 0x00000000);
5901 /* Hardware implementation registers */
5902 /* XXX : not implemented */
5903 spr_register(env, SPR_HID0, "HID0",
5904 SPR_NOACCESS, SPR_NOACCESS,
5905 &spr_read_generic, &spr_write_generic,
5906 0x00000000);
5907 /* XXX : not implemented */
5908 spr_register(env, SPR_HID1, "HID1",
5909 SPR_NOACCESS, SPR_NOACCESS,
5910 &spr_read_generic, &spr_write_generic,
5911 0x00000000);
5912 /* XXX : not implemented */
5913 spr_register(env, SPR_750CL_HID2, "HID2",
5914 SPR_NOACCESS, SPR_NOACCESS,
5915 &spr_read_generic, &spr_write_generic,
5916 0x00000000);
5917 /* XXX : not implemented */
5918 spr_register(env, SPR_750CL_HID4, "HID4",
5919 SPR_NOACCESS, SPR_NOACCESS,
5920 &spr_read_generic, &spr_write_generic,
5921 0x00000000);
5922 /* Quantization registers */
5923 /* XXX : not implemented */
5924 spr_register(env, SPR_750_GQR0, "GQR0",
5925 SPR_NOACCESS, SPR_NOACCESS,
5926 &spr_read_generic, &spr_write_generic,
5927 0x00000000);
5928 /* XXX : not implemented */
5929 spr_register(env, SPR_750_GQR1, "GQR1",
5930 SPR_NOACCESS, SPR_NOACCESS,
5931 &spr_read_generic, &spr_write_generic,
5932 0x00000000);
5933 /* XXX : not implemented */
5934 spr_register(env, SPR_750_GQR2, "GQR2",
5935 SPR_NOACCESS, SPR_NOACCESS,
5936 &spr_read_generic, &spr_write_generic,
5937 0x00000000);
5938 /* XXX : not implemented */
5939 spr_register(env, SPR_750_GQR3, "GQR3",
5940 SPR_NOACCESS, SPR_NOACCESS,
5941 &spr_read_generic, &spr_write_generic,
5942 0x00000000);
5943 /* XXX : not implemented */
5944 spr_register(env, SPR_750_GQR4, "GQR4",
5945 SPR_NOACCESS, SPR_NOACCESS,
5946 &spr_read_generic, &spr_write_generic,
5947 0x00000000);
5948 /* XXX : not implemented */
5949 spr_register(env, SPR_750_GQR5, "GQR5",
5950 SPR_NOACCESS, SPR_NOACCESS,
5951 &spr_read_generic, &spr_write_generic,
5952 0x00000000);
5953 /* XXX : not implemented */
5954 spr_register(env, SPR_750_GQR6, "GQR6",
5955 SPR_NOACCESS, SPR_NOACCESS,
5956 &spr_read_generic, &spr_write_generic,
5957 0x00000000);
5958 /* XXX : not implemented */
5959 spr_register(env, SPR_750_GQR7, "GQR7",
5960 SPR_NOACCESS, SPR_NOACCESS,
5961 &spr_read_generic, &spr_write_generic,
5962 0x00000000);
5963 /* Memory management */
5964 gen_low_BATs(env);
5965 /* PowerPC 750cl has 8 DBATs and 8 IBATs */
5966 gen_high_BATs(env);
5967 init_excp_750cl(env);
5968 env->dcache_line_size = 32;
5969 env->icache_line_size = 32;
5970 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01005971 ppc6xx_irq_init(ppc_env_get_cpu(env));
j_mayerbd928eb2007-11-21 13:08:23 +00005972}
5973
Andreas Färber7856e3a2013-02-17 23:16:42 +00005974POWERPC_FAMILY(750cl)(ObjectClass *oc, void *data)
5975{
Andreas Färberca5dff02013-02-17 23:16:46 +00005976 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00005977 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
5978
Andreas Färberca5dff02013-02-17 23:16:46 +00005979 dc->desc = "PowerPC 750 CL";
Andreas Färber7856e3a2013-02-17 23:16:42 +00005980 pcc->init_proc = init_proc_750cl;
5981 pcc->check_pow = check_pow_hid0;
Andreas Färber53116eb2013-02-17 23:16:43 +00005982 /* XXX: not implemented:
5983 * cache lock instructions:
5984 * dcbz_l
5985 * floating point paired instructions
5986 * psq_lux
5987 * psq_lx
5988 * psq_stux
5989 * psq_stx
5990 * ps_abs
5991 * ps_add
5992 * ps_cmpo0
5993 * ps_cmpo1
5994 * ps_cmpu0
5995 * ps_cmpu1
5996 * ps_div
5997 * ps_madd
5998 * ps_madds0
5999 * ps_madds1
6000 * ps_merge00
6001 * ps_merge01
6002 * ps_merge10
6003 * ps_merge11
6004 * ps_mr
6005 * ps_msub
6006 * ps_mul
6007 * ps_muls0
6008 * ps_muls1
6009 * ps_nabs
6010 * ps_neg
6011 * ps_nmadd
6012 * ps_nmsub
6013 * ps_res
6014 * ps_rsqrte
6015 * ps_sel
6016 * ps_sub
6017 * ps_sum0
6018 * ps_sum1
6019 */
6020 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6021 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6022 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6023 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6024 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6025 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6026 PPC_SEGMENT | PPC_EXTERN;
Tom Musta9df5a462014-04-15 12:21:12 -05006027 pcc->msr_mask = (1ull << MSR_POW) |
6028 (1ull << MSR_ILE) |
6029 (1ull << MSR_EE) |
6030 (1ull << MSR_PR) |
6031 (1ull << MSR_FP) |
6032 (1ull << MSR_ME) |
6033 (1ull << MSR_FE0) |
6034 (1ull << MSR_SE) |
6035 (1ull << MSR_DE) |
6036 (1ull << MSR_FE1) |
6037 (1ull << MSR_EP) |
6038 (1ull << MSR_IR) |
6039 (1ull << MSR_DR) |
6040 (1ull << MSR_PMM) |
6041 (1ull << MSR_RI) |
6042 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00006043 pcc->mmu_model = POWERPC_MMU_32B;
David Gibsonb632a142013-03-13 11:40:33 +11006044#if defined(CONFIG_SOFTMMU)
6045 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6046#endif
Andreas Färberba9fd9f2013-02-17 23:16:45 +00006047 pcc->excp_model = POWERPC_EXCP_7x0;
6048 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6049 pcc->bfd_mach = bfd_mach_ppc_750;
6050 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6051 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00006052}
6053
j_mayerbd928eb2007-11-21 13:08:23 +00006054static void init_proc_750cx (CPUPPCState *env)
6055{
6056 gen_spr_ne_601(env);
6057 gen_spr_7xx(env);
6058 /* XXX : not implemented */
6059 spr_register(env, SPR_L2CR, "L2CR",
6060 SPR_NOACCESS, SPR_NOACCESS,
Alexander Graf9633fcc2013-09-25 15:41:12 +02006061 &spr_read_generic, spr_access_nop,
j_mayerbd928eb2007-11-21 13:08:23 +00006062 0x00000000);
6063 /* Time base */
6064 gen_tbl(env);
6065 /* Thermal management */
6066 gen_spr_thrm(env);
6067 /* This register is not implemented but is present for compatibility */
6068 spr_register(env, SPR_SDA, "SDA",
6069 SPR_NOACCESS, SPR_NOACCESS,
6070 &spr_read_generic, &spr_write_generic,
6071 0x00000000);
6072 /* Hardware implementation registers */
6073 /* XXX : not implemented */
6074 spr_register(env, SPR_HID0, "HID0",
6075 SPR_NOACCESS, SPR_NOACCESS,
6076 &spr_read_generic, &spr_write_generic,
6077 0x00000000);
6078 /* XXX : not implemented */
6079 spr_register(env, SPR_HID1, "HID1",
6080 SPR_NOACCESS, SPR_NOACCESS,
6081 &spr_read_generic, &spr_write_generic,
6082 0x00000000);
6083 /* Memory management */
6084 gen_low_BATs(env);
j_mayer4e777442007-12-10 07:40:16 +00006085 /* PowerPC 750cx has 8 DBATs and 8 IBATs */
6086 gen_high_BATs(env);
j_mayerbd928eb2007-11-21 13:08:23 +00006087 init_excp_750cx(env);
6088 env->dcache_line_size = 32;
6089 env->icache_line_size = 32;
6090 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01006091 ppc6xx_irq_init(ppc_env_get_cpu(env));
j_mayerbd928eb2007-11-21 13:08:23 +00006092}
6093
Andreas Färber7856e3a2013-02-17 23:16:42 +00006094POWERPC_FAMILY(750cx)(ObjectClass *oc, void *data)
6095{
Andreas Färberca5dff02013-02-17 23:16:46 +00006096 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00006097 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6098
Andreas Färberca5dff02013-02-17 23:16:46 +00006099 dc->desc = "PowerPC 750CX";
Andreas Färber7856e3a2013-02-17 23:16:42 +00006100 pcc->init_proc = init_proc_750cx;
6101 pcc->check_pow = check_pow_hid0;
Andreas Färber53116eb2013-02-17 23:16:43 +00006102 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6103 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6104 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6105 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6106 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6107 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6108 PPC_SEGMENT | PPC_EXTERN;
Tom Musta9df5a462014-04-15 12:21:12 -05006109 pcc->msr_mask = (1ull << MSR_POW) |
6110 (1ull << MSR_ILE) |
6111 (1ull << MSR_EE) |
6112 (1ull << MSR_PR) |
6113 (1ull << MSR_FP) |
6114 (1ull << MSR_ME) |
6115 (1ull << MSR_FE0) |
6116 (1ull << MSR_SE) |
6117 (1ull << MSR_DE) |
6118 (1ull << MSR_FE1) |
6119 (1ull << MSR_EP) |
6120 (1ull << MSR_IR) |
6121 (1ull << MSR_DR) |
6122 (1ull << MSR_PMM) |
6123 (1ull << MSR_RI) |
6124 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00006125 pcc->mmu_model = POWERPC_MMU_32B;
David Gibsonb632a142013-03-13 11:40:33 +11006126#if defined(CONFIG_SOFTMMU)
6127 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6128#endif
Andreas Färberba9fd9f2013-02-17 23:16:45 +00006129 pcc->excp_model = POWERPC_EXCP_7x0;
6130 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6131 pcc->bfd_mach = bfd_mach_ppc_750;
6132 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6133 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00006134}
6135
j_mayera750fc02007-09-26 23:54:22 +00006136static void init_proc_750fx (CPUPPCState *env)
6137{
6138 gen_spr_ne_601(env);
6139 gen_spr_7xx(env);
j_mayerbd928eb2007-11-21 13:08:23 +00006140 /* XXX : not implemented */
6141 spr_register(env, SPR_L2CR, "L2CR",
6142 SPR_NOACCESS, SPR_NOACCESS,
Alexander Graf9633fcc2013-09-25 15:41:12 +02006143 &spr_read_generic, spr_access_nop,
j_mayerbd928eb2007-11-21 13:08:23 +00006144 0x00000000);
j_mayera750fc02007-09-26 23:54:22 +00006145 /* Time base */
6146 gen_tbl(env);
6147 /* Thermal management */
6148 gen_spr_thrm(env);
j_mayerbd928eb2007-11-21 13:08:23 +00006149 /* XXX : not implemented */
6150 spr_register(env, SPR_750_THRM4, "THRM4",
6151 SPR_NOACCESS, SPR_NOACCESS,
6152 &spr_read_generic, &spr_write_generic,
6153 0x00000000);
j_mayera750fc02007-09-26 23:54:22 +00006154 /* Hardware implementation registers */
6155 /* XXX : not implemented */
6156 spr_register(env, SPR_HID0, "HID0",
6157 SPR_NOACCESS, SPR_NOACCESS,
6158 &spr_read_generic, &spr_write_generic,
6159 0x00000000);
6160 /* XXX : not implemented */
6161 spr_register(env, SPR_HID1, "HID1",
6162 SPR_NOACCESS, SPR_NOACCESS,
6163 &spr_read_generic, &spr_write_generic,
6164 0x00000000);
6165 /* XXX : not implemented */
j_mayerbd928eb2007-11-21 13:08:23 +00006166 spr_register(env, SPR_750FX_HID2, "HID2",
j_mayera750fc02007-09-26 23:54:22 +00006167 SPR_NOACCESS, SPR_NOACCESS,
6168 &spr_read_generic, &spr_write_generic,
6169 0x00000000);
6170 /* Memory management */
6171 gen_low_BATs(env);
6172 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6173 gen_high_BATs(env);
j_mayerbd928eb2007-11-21 13:08:23 +00006174 init_excp_7x0(env);
j_mayerd63001d2007-10-04 00:51:58 +00006175 env->dcache_line_size = 32;
6176 env->icache_line_size = 32;
j_mayera750fc02007-09-26 23:54:22 +00006177 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01006178 ppc6xx_irq_init(ppc_env_get_cpu(env));
j_mayera750fc02007-09-26 23:54:22 +00006179}
6180
Andreas Färber7856e3a2013-02-17 23:16:42 +00006181POWERPC_FAMILY(750fx)(ObjectClass *oc, void *data)
6182{
Andreas Färberca5dff02013-02-17 23:16:46 +00006183 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00006184 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6185
Andreas Färberca5dff02013-02-17 23:16:46 +00006186 dc->desc = "PowerPC 750FX";
Andreas Färber7856e3a2013-02-17 23:16:42 +00006187 pcc->init_proc = init_proc_750fx;
6188 pcc->check_pow = check_pow_hid0;
Andreas Färber53116eb2013-02-17 23:16:43 +00006189 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6190 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6191 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6192 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6193 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6194 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6195 PPC_SEGMENT | PPC_EXTERN;
Tom Musta9df5a462014-04-15 12:21:12 -05006196 pcc->msr_mask = (1ull << MSR_POW) |
6197 (1ull << MSR_ILE) |
6198 (1ull << MSR_EE) |
6199 (1ull << MSR_PR) |
6200 (1ull << MSR_FP) |
6201 (1ull << MSR_ME) |
6202 (1ull << MSR_FE0) |
6203 (1ull << MSR_SE) |
6204 (1ull << MSR_DE) |
6205 (1ull << MSR_FE1) |
6206 (1ull << MSR_EP) |
6207 (1ull << MSR_IR) |
6208 (1ull << MSR_DR) |
6209 (1ull << MSR_PMM) |
6210 (1ull << MSR_RI) |
6211 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00006212 pcc->mmu_model = POWERPC_MMU_32B;
David Gibsonb632a142013-03-13 11:40:33 +11006213#if defined(CONFIG_SOFTMMU)
6214 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6215#endif
Andreas Färberba9fd9f2013-02-17 23:16:45 +00006216 pcc->excp_model = POWERPC_EXCP_7x0;
6217 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6218 pcc->bfd_mach = bfd_mach_ppc_750;
6219 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6220 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00006221}
6222
j_mayerbd928eb2007-11-21 13:08:23 +00006223static void init_proc_750gx (CPUPPCState *env)
6224{
6225 gen_spr_ne_601(env);
6226 gen_spr_7xx(env);
6227 /* XXX : not implemented (XXX: different from 750fx) */
6228 spr_register(env, SPR_L2CR, "L2CR",
6229 SPR_NOACCESS, SPR_NOACCESS,
Alexander Graf9633fcc2013-09-25 15:41:12 +02006230 &spr_read_generic, spr_access_nop,
j_mayerbd928eb2007-11-21 13:08:23 +00006231 0x00000000);
6232 /* Time base */
6233 gen_tbl(env);
6234 /* Thermal management */
6235 gen_spr_thrm(env);
6236 /* XXX : not implemented */
6237 spr_register(env, SPR_750_THRM4, "THRM4",
6238 SPR_NOACCESS, SPR_NOACCESS,
6239 &spr_read_generic, &spr_write_generic,
6240 0x00000000);
6241 /* Hardware implementation registers */
6242 /* XXX : not implemented (XXX: different from 750fx) */
6243 spr_register(env, SPR_HID0, "HID0",
6244 SPR_NOACCESS, SPR_NOACCESS,
6245 &spr_read_generic, &spr_write_generic,
6246 0x00000000);
6247 /* XXX : not implemented */
6248 spr_register(env, SPR_HID1, "HID1",
6249 SPR_NOACCESS, SPR_NOACCESS,
6250 &spr_read_generic, &spr_write_generic,
6251 0x00000000);
6252 /* XXX : not implemented (XXX: different from 750fx) */
6253 spr_register(env, SPR_750FX_HID2, "HID2",
6254 SPR_NOACCESS, SPR_NOACCESS,
6255 &spr_read_generic, &spr_write_generic,
6256 0x00000000);
6257 /* Memory management */
6258 gen_low_BATs(env);
6259 /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
6260 gen_high_BATs(env);
6261 init_excp_7x0(env);
6262 env->dcache_line_size = 32;
6263 env->icache_line_size = 32;
6264 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01006265 ppc6xx_irq_init(ppc_env_get_cpu(env));
j_mayerbd928eb2007-11-21 13:08:23 +00006266}
6267
Andreas Färber7856e3a2013-02-17 23:16:42 +00006268POWERPC_FAMILY(750gx)(ObjectClass *oc, void *data)
6269{
Andreas Färberca5dff02013-02-17 23:16:46 +00006270 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00006271 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6272
Andreas Färberca5dff02013-02-17 23:16:46 +00006273 dc->desc = "PowerPC 750GX";
Andreas Färber7856e3a2013-02-17 23:16:42 +00006274 pcc->init_proc = init_proc_750gx;
6275 pcc->check_pow = check_pow_hid0;
Andreas Färber53116eb2013-02-17 23:16:43 +00006276 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6277 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6278 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6279 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6280 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6281 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6282 PPC_SEGMENT | PPC_EXTERN;
Tom Musta9df5a462014-04-15 12:21:12 -05006283 pcc->msr_mask = (1ull << MSR_POW) |
6284 (1ull << MSR_ILE) |
6285 (1ull << MSR_EE) |
6286 (1ull << MSR_PR) |
6287 (1ull << MSR_FP) |
6288 (1ull << MSR_ME) |
6289 (1ull << MSR_FE0) |
6290 (1ull << MSR_SE) |
6291 (1ull << MSR_DE) |
6292 (1ull << MSR_FE1) |
6293 (1ull << MSR_EP) |
6294 (1ull << MSR_IR) |
6295 (1ull << MSR_DR) |
6296 (1ull << MSR_PMM) |
6297 (1ull << MSR_RI) |
6298 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00006299 pcc->mmu_model = POWERPC_MMU_32B;
David Gibsonb632a142013-03-13 11:40:33 +11006300#if defined(CONFIG_SOFTMMU)
6301 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6302#endif
Andreas Färberba9fd9f2013-02-17 23:16:45 +00006303 pcc->excp_model = POWERPC_EXCP_7x0;
6304 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6305 pcc->bfd_mach = bfd_mach_ppc_750;
6306 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6307 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00006308}
6309
j_mayerbd928eb2007-11-21 13:08:23 +00006310static void init_proc_745 (CPUPPCState *env)
j_mayera750fc02007-09-26 23:54:22 +00006311{
6312 gen_spr_ne_601(env);
j_mayerbd928eb2007-11-21 13:08:23 +00006313 gen_spr_7xx(env);
j_mayera750fc02007-09-26 23:54:22 +00006314 gen_spr_G2_755(env);
6315 /* Time base */
6316 gen_tbl(env);
j_mayerbd928eb2007-11-21 13:08:23 +00006317 /* Thermal management */
6318 gen_spr_thrm(env);
j_mayera750fc02007-09-26 23:54:22 +00006319 /* Hardware implementation registers */
6320 /* XXX : not implemented */
6321 spr_register(env, SPR_HID0, "HID0",
6322 SPR_NOACCESS, SPR_NOACCESS,
6323 &spr_read_generic, &spr_write_generic,
6324 0x00000000);
6325 /* XXX : not implemented */
6326 spr_register(env, SPR_HID1, "HID1",
6327 SPR_NOACCESS, SPR_NOACCESS,
6328 &spr_read_generic, &spr_write_generic,
6329 0x00000000);
6330 /* XXX : not implemented */
6331 spr_register(env, SPR_HID2, "HID2",
6332 SPR_NOACCESS, SPR_NOACCESS,
6333 &spr_read_generic, &spr_write_generic,
6334 0x00000000);
6335 /* Memory management */
6336 gen_low_BATs(env);
6337 gen_high_BATs(env);
6338 gen_6xx_7xx_soft_tlb(env, 64, 2);
j_mayer7a3a6922007-10-08 02:23:00 +00006339 init_excp_7x5(env);
j_mayerd63001d2007-10-04 00:51:58 +00006340 env->dcache_line_size = 32;
6341 env->icache_line_size = 32;
j_mayera750fc02007-09-26 23:54:22 +00006342 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01006343 ppc6xx_irq_init(ppc_env_get_cpu(env));
j_mayerbd928eb2007-11-21 13:08:23 +00006344}
6345
Andreas Färber7856e3a2013-02-17 23:16:42 +00006346POWERPC_FAMILY(745)(ObjectClass *oc, void *data)
6347{
Andreas Färberca5dff02013-02-17 23:16:46 +00006348 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00006349 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6350
Andreas Färberca5dff02013-02-17 23:16:46 +00006351 dc->desc = "PowerPC 745";
Andreas Färber7856e3a2013-02-17 23:16:42 +00006352 pcc->init_proc = init_proc_745;
6353 pcc->check_pow = check_pow_hid0;
Andreas Färber53116eb2013-02-17 23:16:43 +00006354 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6355 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6356 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6357 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6358 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6359 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
6360 PPC_SEGMENT | PPC_EXTERN;
Tom Musta9df5a462014-04-15 12:21:12 -05006361 pcc->msr_mask = (1ull << MSR_POW) |
6362 (1ull << MSR_ILE) |
6363 (1ull << MSR_EE) |
6364 (1ull << MSR_PR) |
6365 (1ull << MSR_FP) |
6366 (1ull << MSR_ME) |
6367 (1ull << MSR_FE0) |
6368 (1ull << MSR_SE) |
6369 (1ull << MSR_DE) |
6370 (1ull << MSR_FE1) |
6371 (1ull << MSR_EP) |
6372 (1ull << MSR_IR) |
6373 (1ull << MSR_DR) |
6374 (1ull << MSR_PMM) |
6375 (1ull << MSR_RI) |
6376 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00006377 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
6378 pcc->excp_model = POWERPC_EXCP_7x5;
6379 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6380 pcc->bfd_mach = bfd_mach_ppc_750;
6381 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6382 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00006383}
6384
j_mayerbd928eb2007-11-21 13:08:23 +00006385static void init_proc_755 (CPUPPCState *env)
6386{
6387 gen_spr_ne_601(env);
6388 gen_spr_7xx(env);
6389 gen_spr_G2_755(env);
6390 /* Time base */
6391 gen_tbl(env);
6392 /* L2 cache control */
6393 /* XXX : not implemented */
6394 spr_register(env, SPR_L2CR, "L2CR",
6395 SPR_NOACCESS, SPR_NOACCESS,
Alexander Graf9633fcc2013-09-25 15:41:12 +02006396 &spr_read_generic, spr_access_nop,
j_mayerbd928eb2007-11-21 13:08:23 +00006397 0x00000000);
6398 /* XXX : not implemented */
6399 spr_register(env, SPR_L2PMCR, "L2PMCR",
6400 SPR_NOACCESS, SPR_NOACCESS,
6401 &spr_read_generic, &spr_write_generic,
6402 0x00000000);
6403 /* Thermal management */
6404 gen_spr_thrm(env);
6405 /* Hardware implementation registers */
6406 /* XXX : not implemented */
6407 spr_register(env, SPR_HID0, "HID0",
6408 SPR_NOACCESS, SPR_NOACCESS,
6409 &spr_read_generic, &spr_write_generic,
6410 0x00000000);
6411 /* XXX : not implemented */
6412 spr_register(env, SPR_HID1, "HID1",
6413 SPR_NOACCESS, SPR_NOACCESS,
6414 &spr_read_generic, &spr_write_generic,
6415 0x00000000);
6416 /* XXX : not implemented */
6417 spr_register(env, SPR_HID2, "HID2",
6418 SPR_NOACCESS, SPR_NOACCESS,
6419 &spr_read_generic, &spr_write_generic,
6420 0x00000000);
6421 /* Memory management */
6422 gen_low_BATs(env);
6423 gen_high_BATs(env);
6424 gen_6xx_7xx_soft_tlb(env, 64, 2);
6425 init_excp_7x5(env);
6426 env->dcache_line_size = 32;
6427 env->icache_line_size = 32;
6428 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01006429 ppc6xx_irq_init(ppc_env_get_cpu(env));
j_mayera750fc02007-09-26 23:54:22 +00006430}
6431
Andreas Färber7856e3a2013-02-17 23:16:42 +00006432POWERPC_FAMILY(755)(ObjectClass *oc, void *data)
6433{
Andreas Färberca5dff02013-02-17 23:16:46 +00006434 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00006435 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6436
Andreas Färberca5dff02013-02-17 23:16:46 +00006437 dc->desc = "PowerPC 755";
Andreas Färber7856e3a2013-02-17 23:16:42 +00006438 pcc->init_proc = init_proc_755;
6439 pcc->check_pow = check_pow_hid0;
Andreas Färber53116eb2013-02-17 23:16:43 +00006440 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6441 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6442 PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
6443 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
6444 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6445 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
6446 PPC_SEGMENT | PPC_EXTERN;
Tom Musta9df5a462014-04-15 12:21:12 -05006447 pcc->msr_mask = (1ull << MSR_POW) |
6448 (1ull << MSR_ILE) |
6449 (1ull << MSR_EE) |
6450 (1ull << MSR_PR) |
6451 (1ull << MSR_FP) |
6452 (1ull << MSR_ME) |
6453 (1ull << MSR_FE0) |
6454 (1ull << MSR_SE) |
6455 (1ull << MSR_DE) |
6456 (1ull << MSR_FE1) |
6457 (1ull << MSR_EP) |
6458 (1ull << MSR_IR) |
6459 (1ull << MSR_DR) |
6460 (1ull << MSR_PMM) |
6461 (1ull << MSR_RI) |
6462 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00006463 pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
6464 pcc->excp_model = POWERPC_EXCP_7x5;
6465 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6466 pcc->bfd_mach = bfd_mach_ppc_750;
6467 pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
6468 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00006469}
6470
j_mayera750fc02007-09-26 23:54:22 +00006471static void init_proc_7400 (CPUPPCState *env)
6472{
6473 gen_spr_ne_601(env);
6474 gen_spr_7xx(env);
6475 /* Time base */
6476 gen_tbl(env);
6477 /* 74xx specific SPR */
6478 gen_spr_74xx(env);
j_mayer4e777442007-12-10 07:40:16 +00006479 /* XXX : not implemented */
6480 spr_register(env, SPR_UBAMR, "UBAMR",
6481 &spr_read_ureg, SPR_NOACCESS,
6482 &spr_read_ureg, SPR_NOACCESS,
6483 0x00000000);
6484 /* XXX: this seems not implemented on all revisions. */
6485 /* XXX : not implemented */
6486 spr_register(env, SPR_MSSCR1, "MSSCR1",
6487 SPR_NOACCESS, SPR_NOACCESS,
6488 &spr_read_generic, &spr_write_generic,
6489 0x00000000);
j_mayera750fc02007-09-26 23:54:22 +00006490 /* Thermal management */
6491 gen_spr_thrm(env);
6492 /* Memory management */
6493 gen_low_BATs(env);
j_mayere1833e12007-09-29 13:06:16 +00006494 init_excp_7400(env);
j_mayerd63001d2007-10-04 00:51:58 +00006495 env->dcache_line_size = 32;
6496 env->icache_line_size = 32;
j_mayera750fc02007-09-26 23:54:22 +00006497 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01006498 ppc6xx_irq_init(ppc_env_get_cpu(env));
j_mayera750fc02007-09-26 23:54:22 +00006499}
6500
Andreas Färber7856e3a2013-02-17 23:16:42 +00006501POWERPC_FAMILY(7400)(ObjectClass *oc, void *data)
6502{
Andreas Färberca5dff02013-02-17 23:16:46 +00006503 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00006504 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6505
Andreas Färberca5dff02013-02-17 23:16:46 +00006506 dc->desc = "PowerPC 7400 (aka G4)";
Andreas Färber7856e3a2013-02-17 23:16:42 +00006507 pcc->init_proc = init_proc_7400;
6508 pcc->check_pow = check_pow_hid0;
Andreas Färber53116eb2013-02-17 23:16:43 +00006509 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6510 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6511 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6512 PPC_FLOAT_STFIWX |
6513 PPC_CACHE | PPC_CACHE_ICBI |
6514 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6515 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6516 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6517 PPC_MEM_TLBIA |
6518 PPC_SEGMENT | PPC_EXTERN |
6519 PPC_ALTIVEC;
Tom Musta9df5a462014-04-15 12:21:12 -05006520 pcc->msr_mask = (1ull << MSR_VR) |
6521 (1ull << MSR_POW) |
6522 (1ull << MSR_ILE) |
6523 (1ull << MSR_EE) |
6524 (1ull << MSR_PR) |
6525 (1ull << MSR_FP) |
6526 (1ull << MSR_ME) |
6527 (1ull << MSR_FE0) |
6528 (1ull << MSR_SE) |
6529 (1ull << MSR_DE) |
6530 (1ull << MSR_FE1) |
6531 (1ull << MSR_EP) |
6532 (1ull << MSR_IR) |
6533 (1ull << MSR_DR) |
6534 (1ull << MSR_PMM) |
6535 (1ull << MSR_RI) |
6536 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00006537 pcc->mmu_model = POWERPC_MMU_32B;
David Gibsonb632a142013-03-13 11:40:33 +11006538#if defined(CONFIG_SOFTMMU)
6539 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6540#endif
Andreas Färberba9fd9f2013-02-17 23:16:45 +00006541 pcc->excp_model = POWERPC_EXCP_74xx;
6542 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6543 pcc->bfd_mach = bfd_mach_ppc_7400;
6544 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6545 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6546 POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00006547}
6548
j_mayera750fc02007-09-26 23:54:22 +00006549static void init_proc_7410 (CPUPPCState *env)
6550{
6551 gen_spr_ne_601(env);
6552 gen_spr_7xx(env);
6553 /* Time base */
6554 gen_tbl(env);
6555 /* 74xx specific SPR */
6556 gen_spr_74xx(env);
j_mayer4e777442007-12-10 07:40:16 +00006557 /* XXX : not implemented */
6558 spr_register(env, SPR_UBAMR, "UBAMR",
6559 &spr_read_ureg, SPR_NOACCESS,
6560 &spr_read_ureg, SPR_NOACCESS,
6561 0x00000000);
j_mayera750fc02007-09-26 23:54:22 +00006562 /* Thermal management */
6563 gen_spr_thrm(env);
6564 /* L2PMCR */
6565 /* XXX : not implemented */
6566 spr_register(env, SPR_L2PMCR, "L2PMCR",
6567 SPR_NOACCESS, SPR_NOACCESS,
6568 &spr_read_generic, &spr_write_generic,
6569 0x00000000);
6570 /* LDSTDB */
6571 /* XXX : not implemented */
6572 spr_register(env, SPR_LDSTDB, "LDSTDB",
6573 SPR_NOACCESS, SPR_NOACCESS,
6574 &spr_read_generic, &spr_write_generic,
6575 0x00000000);
6576 /* Memory management */
6577 gen_low_BATs(env);
j_mayere1833e12007-09-29 13:06:16 +00006578 init_excp_7400(env);
j_mayerd63001d2007-10-04 00:51:58 +00006579 env->dcache_line_size = 32;
6580 env->icache_line_size = 32;
j_mayera750fc02007-09-26 23:54:22 +00006581 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01006582 ppc6xx_irq_init(ppc_env_get_cpu(env));
j_mayera750fc02007-09-26 23:54:22 +00006583}
6584
Andreas Färber7856e3a2013-02-17 23:16:42 +00006585POWERPC_FAMILY(7410)(ObjectClass *oc, void *data)
6586{
Andreas Färberca5dff02013-02-17 23:16:46 +00006587 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00006588 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6589
Andreas Färberca5dff02013-02-17 23:16:46 +00006590 dc->desc = "PowerPC 7410 (aka G4)";
Andreas Färber7856e3a2013-02-17 23:16:42 +00006591 pcc->init_proc = init_proc_7410;
6592 pcc->check_pow = check_pow_hid0;
Andreas Färber53116eb2013-02-17 23:16:43 +00006593 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6594 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6595 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6596 PPC_FLOAT_STFIWX |
6597 PPC_CACHE | PPC_CACHE_ICBI |
6598 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6599 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6600 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6601 PPC_MEM_TLBIA |
6602 PPC_SEGMENT | PPC_EXTERN |
6603 PPC_ALTIVEC;
Tom Musta9df5a462014-04-15 12:21:12 -05006604 pcc->msr_mask = (1ull << MSR_VR) |
6605 (1ull << MSR_POW) |
6606 (1ull << MSR_ILE) |
6607 (1ull << MSR_EE) |
6608 (1ull << MSR_PR) |
6609 (1ull << MSR_FP) |
6610 (1ull << MSR_ME) |
6611 (1ull << MSR_FE0) |
6612 (1ull << MSR_SE) |
6613 (1ull << MSR_DE) |
6614 (1ull << MSR_FE1) |
6615 (1ull << MSR_EP) |
6616 (1ull << MSR_IR) |
6617 (1ull << MSR_DR) |
6618 (1ull << MSR_PMM) |
6619 (1ull << MSR_RI) |
6620 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00006621 pcc->mmu_model = POWERPC_MMU_32B;
David Gibsonb632a142013-03-13 11:40:33 +11006622#if defined(CONFIG_SOFTMMU)
6623 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
6624#endif
Andreas Färberba9fd9f2013-02-17 23:16:45 +00006625 pcc->excp_model = POWERPC_EXCP_74xx;
6626 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6627 pcc->bfd_mach = bfd_mach_ppc_7400;
6628 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6629 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6630 POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00006631}
6632
j_mayera750fc02007-09-26 23:54:22 +00006633static void init_proc_7440 (CPUPPCState *env)
6634{
6635 gen_spr_ne_601(env);
6636 gen_spr_7xx(env);
6637 /* Time base */
6638 gen_tbl(env);
6639 /* 74xx specific SPR */
6640 gen_spr_74xx(env);
j_mayer4e777442007-12-10 07:40:16 +00006641 /* XXX : not implemented */
6642 spr_register(env, SPR_UBAMR, "UBAMR",
6643 &spr_read_ureg, SPR_NOACCESS,
6644 &spr_read_ureg, SPR_NOACCESS,
6645 0x00000000);
j_mayera750fc02007-09-26 23:54:22 +00006646 /* LDSTCR */
6647 /* XXX : not implemented */
6648 spr_register(env, SPR_LDSTCR, "LDSTCR",
6649 SPR_NOACCESS, SPR_NOACCESS,
6650 &spr_read_generic, &spr_write_generic,
6651 0x00000000);
6652 /* ICTRL */
6653 /* XXX : not implemented */
6654 spr_register(env, SPR_ICTRL, "ICTRL",
6655 SPR_NOACCESS, SPR_NOACCESS,
6656 &spr_read_generic, &spr_write_generic,
6657 0x00000000);
6658 /* MSSSR0 */
j_mayer578bb252007-10-01 04:48:45 +00006659 /* XXX : not implemented */
j_mayera750fc02007-09-26 23:54:22 +00006660 spr_register(env, SPR_MSSSR0, "MSSSR0",
6661 SPR_NOACCESS, SPR_NOACCESS,
6662 &spr_read_generic, &spr_write_generic,
6663 0x00000000);
6664 /* PMC */
6665 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10006666 spr_register(env, SPR_7XX_PMC5, "PMC5",
j_mayera750fc02007-09-26 23:54:22 +00006667 SPR_NOACCESS, SPR_NOACCESS,
6668 &spr_read_generic, &spr_write_generic,
6669 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00006670 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10006671 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
j_mayera750fc02007-09-26 23:54:22 +00006672 &spr_read_ureg, SPR_NOACCESS,
6673 &spr_read_ureg, SPR_NOACCESS,
6674 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00006675 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10006676 spr_register(env, SPR_7XX_PMC6, "PMC6",
j_mayera750fc02007-09-26 23:54:22 +00006677 SPR_NOACCESS, SPR_NOACCESS,
6678 &spr_read_generic, &spr_write_generic,
6679 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00006680 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10006681 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
j_mayera750fc02007-09-26 23:54:22 +00006682 &spr_read_ureg, SPR_NOACCESS,
6683 &spr_read_ureg, SPR_NOACCESS,
6684 0x00000000);
6685 /* Memory management */
6686 gen_low_BATs(env);
j_mayer578bb252007-10-01 04:48:45 +00006687 gen_74xx_soft_tlb(env, 128, 2);
j_mayer1c27f8f2007-10-05 13:09:54 +00006688 init_excp_7450(env);
j_mayerd63001d2007-10-04 00:51:58 +00006689 env->dcache_line_size = 32;
6690 env->icache_line_size = 32;
j_mayera750fc02007-09-26 23:54:22 +00006691 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01006692 ppc6xx_irq_init(ppc_env_get_cpu(env));
j_mayera750fc02007-09-26 23:54:22 +00006693}
j_mayera750fc02007-09-26 23:54:22 +00006694
Andreas Färber7856e3a2013-02-17 23:16:42 +00006695POWERPC_FAMILY(7440)(ObjectClass *oc, void *data)
6696{
Andreas Färberca5dff02013-02-17 23:16:46 +00006697 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00006698 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6699
Andreas Färberca5dff02013-02-17 23:16:46 +00006700 dc->desc = "PowerPC 7440 (aka G4)";
Andreas Färber7856e3a2013-02-17 23:16:42 +00006701 pcc->init_proc = init_proc_7440;
6702 pcc->check_pow = check_pow_hid0_74xx;
Andreas Färber53116eb2013-02-17 23:16:43 +00006703 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6704 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6705 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6706 PPC_FLOAT_STFIWX |
6707 PPC_CACHE | PPC_CACHE_ICBI |
6708 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6709 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6710 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6711 PPC_MEM_TLBIA | PPC_74xx_TLB |
6712 PPC_SEGMENT | PPC_EXTERN |
6713 PPC_ALTIVEC;
Tom Musta9df5a462014-04-15 12:21:12 -05006714 pcc->msr_mask = (1ull << MSR_VR) |
6715 (1ull << MSR_POW) |
6716 (1ull << MSR_ILE) |
6717 (1ull << MSR_EE) |
6718 (1ull << MSR_PR) |
6719 (1ull << MSR_FP) |
6720 (1ull << MSR_ME) |
6721 (1ull << MSR_FE0) |
6722 (1ull << MSR_SE) |
6723 (1ull << MSR_DE) |
6724 (1ull << MSR_FE1) |
6725 (1ull << MSR_EP) |
6726 (1ull << MSR_IR) |
6727 (1ull << MSR_DR) |
6728 (1ull << MSR_PMM) |
6729 (1ull << MSR_RI) |
6730 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00006731 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
6732 pcc->excp_model = POWERPC_EXCP_74xx;
6733 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6734 pcc->bfd_mach = bfd_mach_ppc_7400;
6735 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6736 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6737 POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00006738}
6739
j_mayera750fc02007-09-26 23:54:22 +00006740static void init_proc_7450 (CPUPPCState *env)
6741{
6742 gen_spr_ne_601(env);
6743 gen_spr_7xx(env);
6744 /* Time base */
6745 gen_tbl(env);
6746 /* 74xx specific SPR */
6747 gen_spr_74xx(env);
6748 /* Level 3 cache control */
6749 gen_l3_ctrl(env);
j_mayer4e777442007-12-10 07:40:16 +00006750 /* L3ITCR1 */
6751 /* XXX : not implemented */
6752 spr_register(env, SPR_L3ITCR1, "L3ITCR1",
6753 SPR_NOACCESS, SPR_NOACCESS,
6754 &spr_read_generic, &spr_write_generic,
6755 0x00000000);
6756 /* L3ITCR2 */
6757 /* XXX : not implemented */
6758 spr_register(env, SPR_L3ITCR2, "L3ITCR2",
6759 SPR_NOACCESS, SPR_NOACCESS,
6760 &spr_read_generic, &spr_write_generic,
6761 0x00000000);
6762 /* L3ITCR3 */
6763 /* XXX : not implemented */
6764 spr_register(env, SPR_L3ITCR3, "L3ITCR3",
6765 SPR_NOACCESS, SPR_NOACCESS,
6766 &spr_read_generic, &spr_write_generic,
6767 0x00000000);
6768 /* L3OHCR */
6769 /* XXX : not implemented */
6770 spr_register(env, SPR_L3OHCR, "L3OHCR",
6771 SPR_NOACCESS, SPR_NOACCESS,
6772 &spr_read_generic, &spr_write_generic,
6773 0x00000000);
6774 /* XXX : not implemented */
6775 spr_register(env, SPR_UBAMR, "UBAMR",
6776 &spr_read_ureg, SPR_NOACCESS,
6777 &spr_read_ureg, SPR_NOACCESS,
6778 0x00000000);
j_mayera750fc02007-09-26 23:54:22 +00006779 /* LDSTCR */
6780 /* XXX : not implemented */
6781 spr_register(env, SPR_LDSTCR, "LDSTCR",
6782 SPR_NOACCESS, SPR_NOACCESS,
6783 &spr_read_generic, &spr_write_generic,
6784 0x00000000);
6785 /* ICTRL */
6786 /* XXX : not implemented */
6787 spr_register(env, SPR_ICTRL, "ICTRL",
6788 SPR_NOACCESS, SPR_NOACCESS,
6789 &spr_read_generic, &spr_write_generic,
6790 0x00000000);
6791 /* MSSSR0 */
j_mayer578bb252007-10-01 04:48:45 +00006792 /* XXX : not implemented */
j_mayera750fc02007-09-26 23:54:22 +00006793 spr_register(env, SPR_MSSSR0, "MSSSR0",
6794 SPR_NOACCESS, SPR_NOACCESS,
6795 &spr_read_generic, &spr_write_generic,
6796 0x00000000);
6797 /* PMC */
6798 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10006799 spr_register(env, SPR_7XX_PMC5, "PMC5",
j_mayera750fc02007-09-26 23:54:22 +00006800 SPR_NOACCESS, SPR_NOACCESS,
6801 &spr_read_generic, &spr_write_generic,
6802 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00006803 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10006804 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
j_mayera750fc02007-09-26 23:54:22 +00006805 &spr_read_ureg, SPR_NOACCESS,
6806 &spr_read_ureg, SPR_NOACCESS,
6807 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00006808 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10006809 spr_register(env, SPR_7XX_PMC6, "PMC6",
j_mayera750fc02007-09-26 23:54:22 +00006810 SPR_NOACCESS, SPR_NOACCESS,
6811 &spr_read_generic, &spr_write_generic,
6812 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00006813 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10006814 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
j_mayera750fc02007-09-26 23:54:22 +00006815 &spr_read_ureg, SPR_NOACCESS,
6816 &spr_read_ureg, SPR_NOACCESS,
6817 0x00000000);
6818 /* Memory management */
6819 gen_low_BATs(env);
j_mayer578bb252007-10-01 04:48:45 +00006820 gen_74xx_soft_tlb(env, 128, 2);
j_mayere1833e12007-09-29 13:06:16 +00006821 init_excp_7450(env);
j_mayerd63001d2007-10-04 00:51:58 +00006822 env->dcache_line_size = 32;
6823 env->icache_line_size = 32;
j_mayera750fc02007-09-26 23:54:22 +00006824 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01006825 ppc6xx_irq_init(ppc_env_get_cpu(env));
j_mayera750fc02007-09-26 23:54:22 +00006826}
j_mayera750fc02007-09-26 23:54:22 +00006827
Andreas Färber7856e3a2013-02-17 23:16:42 +00006828POWERPC_FAMILY(7450)(ObjectClass *oc, void *data)
6829{
Andreas Färberca5dff02013-02-17 23:16:46 +00006830 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00006831 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6832
Andreas Färberca5dff02013-02-17 23:16:46 +00006833 dc->desc = "PowerPC 7450 (aka G4)";
Andreas Färber7856e3a2013-02-17 23:16:42 +00006834 pcc->init_proc = init_proc_7450;
6835 pcc->check_pow = check_pow_hid0_74xx;
Andreas Färber53116eb2013-02-17 23:16:43 +00006836 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6837 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6838 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6839 PPC_FLOAT_STFIWX |
6840 PPC_CACHE | PPC_CACHE_ICBI |
6841 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6842 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6843 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6844 PPC_MEM_TLBIA | PPC_74xx_TLB |
6845 PPC_SEGMENT | PPC_EXTERN |
6846 PPC_ALTIVEC;
Tom Musta9df5a462014-04-15 12:21:12 -05006847 pcc->msr_mask = (1ull << MSR_VR) |
6848 (1ull << MSR_POW) |
6849 (1ull << MSR_ILE) |
6850 (1ull << MSR_EE) |
6851 (1ull << MSR_PR) |
6852 (1ull << MSR_FP) |
6853 (1ull << MSR_ME) |
6854 (1ull << MSR_FE0) |
6855 (1ull << MSR_SE) |
6856 (1ull << MSR_DE) |
6857 (1ull << MSR_FE1) |
6858 (1ull << MSR_EP) |
6859 (1ull << MSR_IR) |
6860 (1ull << MSR_DR) |
6861 (1ull << MSR_PMM) |
6862 (1ull << MSR_RI) |
6863 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00006864 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
6865 pcc->excp_model = POWERPC_EXCP_74xx;
6866 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
6867 pcc->bfd_mach = bfd_mach_ppc_7400;
6868 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
6869 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
6870 POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00006871}
6872
j_mayera750fc02007-09-26 23:54:22 +00006873static void init_proc_7445 (CPUPPCState *env)
6874{
6875 gen_spr_ne_601(env);
6876 gen_spr_7xx(env);
6877 /* Time base */
6878 gen_tbl(env);
6879 /* 74xx specific SPR */
6880 gen_spr_74xx(env);
6881 /* LDSTCR */
6882 /* XXX : not implemented */
6883 spr_register(env, SPR_LDSTCR, "LDSTCR",
6884 SPR_NOACCESS, SPR_NOACCESS,
6885 &spr_read_generic, &spr_write_generic,
6886 0x00000000);
6887 /* ICTRL */
6888 /* XXX : not implemented */
6889 spr_register(env, SPR_ICTRL, "ICTRL",
6890 SPR_NOACCESS, SPR_NOACCESS,
6891 &spr_read_generic, &spr_write_generic,
6892 0x00000000);
6893 /* MSSSR0 */
j_mayer578bb252007-10-01 04:48:45 +00006894 /* XXX : not implemented */
j_mayera750fc02007-09-26 23:54:22 +00006895 spr_register(env, SPR_MSSSR0, "MSSSR0",
6896 SPR_NOACCESS, SPR_NOACCESS,
6897 &spr_read_generic, &spr_write_generic,
6898 0x00000000);
6899 /* PMC */
6900 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10006901 spr_register(env, SPR_7XX_PMC5, "PMC5",
j_mayera750fc02007-09-26 23:54:22 +00006902 SPR_NOACCESS, SPR_NOACCESS,
6903 &spr_read_generic, &spr_write_generic,
6904 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00006905 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10006906 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
j_mayera750fc02007-09-26 23:54:22 +00006907 &spr_read_ureg, SPR_NOACCESS,
6908 &spr_read_ureg, SPR_NOACCESS,
6909 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00006910 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10006911 spr_register(env, SPR_7XX_PMC6, "PMC6",
j_mayera750fc02007-09-26 23:54:22 +00006912 SPR_NOACCESS, SPR_NOACCESS,
6913 &spr_read_generic, &spr_write_generic,
6914 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00006915 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10006916 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
j_mayera750fc02007-09-26 23:54:22 +00006917 &spr_read_ureg, SPR_NOACCESS,
6918 &spr_read_ureg, SPR_NOACCESS,
6919 0x00000000);
6920 /* SPRGs */
6921 spr_register(env, SPR_SPRG4, "SPRG4",
6922 SPR_NOACCESS, SPR_NOACCESS,
6923 &spr_read_generic, &spr_write_generic,
6924 0x00000000);
6925 spr_register(env, SPR_USPRG4, "USPRG4",
6926 &spr_read_ureg, SPR_NOACCESS,
6927 &spr_read_ureg, SPR_NOACCESS,
6928 0x00000000);
6929 spr_register(env, SPR_SPRG5, "SPRG5",
6930 SPR_NOACCESS, SPR_NOACCESS,
6931 &spr_read_generic, &spr_write_generic,
6932 0x00000000);
6933 spr_register(env, SPR_USPRG5, "USPRG5",
6934 &spr_read_ureg, SPR_NOACCESS,
6935 &spr_read_ureg, SPR_NOACCESS,
6936 0x00000000);
6937 spr_register(env, SPR_SPRG6, "SPRG6",
6938 SPR_NOACCESS, SPR_NOACCESS,
6939 &spr_read_generic, &spr_write_generic,
6940 0x00000000);
6941 spr_register(env, SPR_USPRG6, "USPRG6",
6942 &spr_read_ureg, SPR_NOACCESS,
6943 &spr_read_ureg, SPR_NOACCESS,
6944 0x00000000);
6945 spr_register(env, SPR_SPRG7, "SPRG7",
6946 SPR_NOACCESS, SPR_NOACCESS,
6947 &spr_read_generic, &spr_write_generic,
6948 0x00000000);
6949 spr_register(env, SPR_USPRG7, "USPRG7",
6950 &spr_read_ureg, SPR_NOACCESS,
6951 &spr_read_ureg, SPR_NOACCESS,
6952 0x00000000);
6953 /* Memory management */
6954 gen_low_BATs(env);
6955 gen_high_BATs(env);
j_mayer578bb252007-10-01 04:48:45 +00006956 gen_74xx_soft_tlb(env, 128, 2);
j_mayere1833e12007-09-29 13:06:16 +00006957 init_excp_7450(env);
j_mayerd63001d2007-10-04 00:51:58 +00006958 env->dcache_line_size = 32;
6959 env->icache_line_size = 32;
j_mayera750fc02007-09-26 23:54:22 +00006960 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01006961 ppc6xx_irq_init(ppc_env_get_cpu(env));
j_mayera750fc02007-09-26 23:54:22 +00006962}
j_mayera750fc02007-09-26 23:54:22 +00006963
Andreas Färber7856e3a2013-02-17 23:16:42 +00006964POWERPC_FAMILY(7445)(ObjectClass *oc, void *data)
6965{
Andreas Färberca5dff02013-02-17 23:16:46 +00006966 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00006967 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
6968
Andreas Färberca5dff02013-02-17 23:16:46 +00006969 dc->desc = "PowerPC 7445 (aka G4)";
Andreas Färber7856e3a2013-02-17 23:16:42 +00006970 pcc->init_proc = init_proc_7445;
6971 pcc->check_pow = check_pow_hid0_74xx;
Andreas Färber53116eb2013-02-17 23:16:43 +00006972 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
6973 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
6974 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
6975 PPC_FLOAT_STFIWX |
6976 PPC_CACHE | PPC_CACHE_ICBI |
6977 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
6978 PPC_MEM_SYNC | PPC_MEM_EIEIO |
6979 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
6980 PPC_MEM_TLBIA | PPC_74xx_TLB |
6981 PPC_SEGMENT | PPC_EXTERN |
6982 PPC_ALTIVEC;
Tom Musta9df5a462014-04-15 12:21:12 -05006983 pcc->msr_mask = (1ull << MSR_VR) |
6984 (1ull << MSR_POW) |
6985 (1ull << MSR_ILE) |
6986 (1ull << MSR_EE) |
6987 (1ull << MSR_PR) |
6988 (1ull << MSR_FP) |
6989 (1ull << MSR_ME) |
6990 (1ull << MSR_FE0) |
6991 (1ull << MSR_SE) |
6992 (1ull << MSR_DE) |
6993 (1ull << MSR_FE1) |
6994 (1ull << MSR_EP) |
6995 (1ull << MSR_IR) |
6996 (1ull << MSR_DR) |
6997 (1ull << MSR_PMM) |
6998 (1ull << MSR_RI) |
6999 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00007000 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
7001 pcc->excp_model = POWERPC_EXCP_74xx;
7002 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7003 pcc->bfd_mach = bfd_mach_ppc_7400;
7004 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7005 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7006 POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00007007}
7008
j_mayera750fc02007-09-26 23:54:22 +00007009static void init_proc_7455 (CPUPPCState *env)
7010{
7011 gen_spr_ne_601(env);
7012 gen_spr_7xx(env);
7013 /* Time base */
7014 gen_tbl(env);
7015 /* 74xx specific SPR */
7016 gen_spr_74xx(env);
7017 /* Level 3 cache control */
7018 gen_l3_ctrl(env);
7019 /* LDSTCR */
7020 /* XXX : not implemented */
7021 spr_register(env, SPR_LDSTCR, "LDSTCR",
7022 SPR_NOACCESS, SPR_NOACCESS,
7023 &spr_read_generic, &spr_write_generic,
7024 0x00000000);
7025 /* ICTRL */
7026 /* XXX : not implemented */
7027 spr_register(env, SPR_ICTRL, "ICTRL",
7028 SPR_NOACCESS, SPR_NOACCESS,
7029 &spr_read_generic, &spr_write_generic,
7030 0x00000000);
7031 /* MSSSR0 */
j_mayer578bb252007-10-01 04:48:45 +00007032 /* XXX : not implemented */
j_mayera750fc02007-09-26 23:54:22 +00007033 spr_register(env, SPR_MSSSR0, "MSSSR0",
7034 SPR_NOACCESS, SPR_NOACCESS,
7035 &spr_read_generic, &spr_write_generic,
7036 0x00000000);
7037 /* PMC */
7038 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10007039 spr_register(env, SPR_7XX_PMC5, "PMC5",
j_mayera750fc02007-09-26 23:54:22 +00007040 SPR_NOACCESS, SPR_NOACCESS,
7041 &spr_read_generic, &spr_write_generic,
7042 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00007043 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10007044 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
j_mayera750fc02007-09-26 23:54:22 +00007045 &spr_read_ureg, SPR_NOACCESS,
7046 &spr_read_ureg, SPR_NOACCESS,
7047 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00007048 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10007049 spr_register(env, SPR_7XX_PMC6, "PMC6",
j_mayera750fc02007-09-26 23:54:22 +00007050 SPR_NOACCESS, SPR_NOACCESS,
7051 &spr_read_generic, &spr_write_generic,
7052 0x00000000);
j_mayer578bb252007-10-01 04:48:45 +00007053 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10007054 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
j_mayera750fc02007-09-26 23:54:22 +00007055 &spr_read_ureg, SPR_NOACCESS,
7056 &spr_read_ureg, SPR_NOACCESS,
7057 0x00000000);
7058 /* SPRGs */
7059 spr_register(env, SPR_SPRG4, "SPRG4",
7060 SPR_NOACCESS, SPR_NOACCESS,
7061 &spr_read_generic, &spr_write_generic,
7062 0x00000000);
7063 spr_register(env, SPR_USPRG4, "USPRG4",
7064 &spr_read_ureg, SPR_NOACCESS,
7065 &spr_read_ureg, SPR_NOACCESS,
7066 0x00000000);
7067 spr_register(env, SPR_SPRG5, "SPRG5",
7068 SPR_NOACCESS, SPR_NOACCESS,
7069 &spr_read_generic, &spr_write_generic,
7070 0x00000000);
7071 spr_register(env, SPR_USPRG5, "USPRG5",
7072 &spr_read_ureg, SPR_NOACCESS,
7073 &spr_read_ureg, SPR_NOACCESS,
7074 0x00000000);
7075 spr_register(env, SPR_SPRG6, "SPRG6",
7076 SPR_NOACCESS, SPR_NOACCESS,
7077 &spr_read_generic, &spr_write_generic,
7078 0x00000000);
7079 spr_register(env, SPR_USPRG6, "USPRG6",
7080 &spr_read_ureg, SPR_NOACCESS,
7081 &spr_read_ureg, SPR_NOACCESS,
7082 0x00000000);
7083 spr_register(env, SPR_SPRG7, "SPRG7",
7084 SPR_NOACCESS, SPR_NOACCESS,
7085 &spr_read_generic, &spr_write_generic,
7086 0x00000000);
7087 spr_register(env, SPR_USPRG7, "USPRG7",
7088 &spr_read_ureg, SPR_NOACCESS,
7089 &spr_read_ureg, SPR_NOACCESS,
7090 0x00000000);
7091 /* Memory management */
7092 gen_low_BATs(env);
7093 gen_high_BATs(env);
j_mayer578bb252007-10-01 04:48:45 +00007094 gen_74xx_soft_tlb(env, 128, 2);
j_mayere1833e12007-09-29 13:06:16 +00007095 init_excp_7450(env);
j_mayerd63001d2007-10-04 00:51:58 +00007096 env->dcache_line_size = 32;
7097 env->icache_line_size = 32;
j_mayera750fc02007-09-26 23:54:22 +00007098 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01007099 ppc6xx_irq_init(ppc_env_get_cpu(env));
j_mayera750fc02007-09-26 23:54:22 +00007100}
j_mayera750fc02007-09-26 23:54:22 +00007101
Andreas Färber7856e3a2013-02-17 23:16:42 +00007102POWERPC_FAMILY(7455)(ObjectClass *oc, void *data)
7103{
Andreas Färberca5dff02013-02-17 23:16:46 +00007104 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00007105 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7106
Andreas Färberca5dff02013-02-17 23:16:46 +00007107 dc->desc = "PowerPC 7455 (aka G4)";
Andreas Färber7856e3a2013-02-17 23:16:42 +00007108 pcc->init_proc = init_proc_7455;
7109 pcc->check_pow = check_pow_hid0_74xx;
Andreas Färber53116eb2013-02-17 23:16:43 +00007110 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7111 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7112 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7113 PPC_FLOAT_STFIWX |
7114 PPC_CACHE | PPC_CACHE_ICBI |
7115 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
7116 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7117 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7118 PPC_MEM_TLBIA | PPC_74xx_TLB |
7119 PPC_SEGMENT | PPC_EXTERN |
7120 PPC_ALTIVEC;
Tom Musta9df5a462014-04-15 12:21:12 -05007121 pcc->msr_mask = (1ull << MSR_VR) |
7122 (1ull << MSR_POW) |
7123 (1ull << MSR_ILE) |
7124 (1ull << MSR_EE) |
7125 (1ull << MSR_PR) |
7126 (1ull << MSR_FP) |
7127 (1ull << MSR_ME) |
7128 (1ull << MSR_FE0) |
7129 (1ull << MSR_SE) |
7130 (1ull << MSR_DE) |
7131 (1ull << MSR_FE1) |
7132 (1ull << MSR_EP) |
7133 (1ull << MSR_IR) |
7134 (1ull << MSR_DR) |
7135 (1ull << MSR_PMM) |
7136 (1ull << MSR_RI) |
7137 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00007138 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
7139 pcc->excp_model = POWERPC_EXCP_74xx;
7140 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7141 pcc->bfd_mach = bfd_mach_ppc_7400;
7142 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7143 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7144 POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00007145}
7146
j_mayer4e777442007-12-10 07:40:16 +00007147static void init_proc_7457 (CPUPPCState *env)
7148{
7149 gen_spr_ne_601(env);
7150 gen_spr_7xx(env);
7151 /* Time base */
7152 gen_tbl(env);
7153 /* 74xx specific SPR */
7154 gen_spr_74xx(env);
7155 /* Level 3 cache control */
7156 gen_l3_ctrl(env);
7157 /* L3ITCR1 */
7158 /* XXX : not implemented */
7159 spr_register(env, SPR_L3ITCR1, "L3ITCR1",
7160 SPR_NOACCESS, SPR_NOACCESS,
7161 &spr_read_generic, &spr_write_generic,
7162 0x00000000);
7163 /* L3ITCR2 */
7164 /* XXX : not implemented */
7165 spr_register(env, SPR_L3ITCR2, "L3ITCR2",
7166 SPR_NOACCESS, SPR_NOACCESS,
7167 &spr_read_generic, &spr_write_generic,
7168 0x00000000);
7169 /* L3ITCR3 */
7170 /* XXX : not implemented */
7171 spr_register(env, SPR_L3ITCR3, "L3ITCR3",
7172 SPR_NOACCESS, SPR_NOACCESS,
7173 &spr_read_generic, &spr_write_generic,
7174 0x00000000);
7175 /* L3OHCR */
7176 /* XXX : not implemented */
7177 spr_register(env, SPR_L3OHCR, "L3OHCR",
7178 SPR_NOACCESS, SPR_NOACCESS,
7179 &spr_read_generic, &spr_write_generic,
7180 0x00000000);
7181 /* LDSTCR */
7182 /* XXX : not implemented */
7183 spr_register(env, SPR_LDSTCR, "LDSTCR",
7184 SPR_NOACCESS, SPR_NOACCESS,
7185 &spr_read_generic, &spr_write_generic,
7186 0x00000000);
7187 /* ICTRL */
7188 /* XXX : not implemented */
7189 spr_register(env, SPR_ICTRL, "ICTRL",
7190 SPR_NOACCESS, SPR_NOACCESS,
7191 &spr_read_generic, &spr_write_generic,
7192 0x00000000);
7193 /* MSSSR0 */
7194 /* XXX : not implemented */
7195 spr_register(env, SPR_MSSSR0, "MSSSR0",
7196 SPR_NOACCESS, SPR_NOACCESS,
7197 &spr_read_generic, &spr_write_generic,
7198 0x00000000);
7199 /* PMC */
7200 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10007201 spr_register(env, SPR_7XX_PMC5, "PMC5",
j_mayer4e777442007-12-10 07:40:16 +00007202 SPR_NOACCESS, SPR_NOACCESS,
7203 &spr_read_generic, &spr_write_generic,
7204 0x00000000);
7205 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10007206 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
j_mayer4e777442007-12-10 07:40:16 +00007207 &spr_read_ureg, SPR_NOACCESS,
7208 &spr_read_ureg, SPR_NOACCESS,
7209 0x00000000);
7210 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10007211 spr_register(env, SPR_7XX_PMC6, "PMC6",
j_mayer4e777442007-12-10 07:40:16 +00007212 SPR_NOACCESS, SPR_NOACCESS,
7213 &spr_read_generic, &spr_write_generic,
7214 0x00000000);
7215 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10007216 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
j_mayer4e777442007-12-10 07:40:16 +00007217 &spr_read_ureg, SPR_NOACCESS,
7218 &spr_read_ureg, SPR_NOACCESS,
7219 0x00000000);
7220 /* SPRGs */
7221 spr_register(env, SPR_SPRG4, "SPRG4",
7222 SPR_NOACCESS, SPR_NOACCESS,
7223 &spr_read_generic, &spr_write_generic,
7224 0x00000000);
7225 spr_register(env, SPR_USPRG4, "USPRG4",
7226 &spr_read_ureg, SPR_NOACCESS,
7227 &spr_read_ureg, SPR_NOACCESS,
7228 0x00000000);
7229 spr_register(env, SPR_SPRG5, "SPRG5",
7230 SPR_NOACCESS, SPR_NOACCESS,
7231 &spr_read_generic, &spr_write_generic,
7232 0x00000000);
7233 spr_register(env, SPR_USPRG5, "USPRG5",
7234 &spr_read_ureg, SPR_NOACCESS,
7235 &spr_read_ureg, SPR_NOACCESS,
7236 0x00000000);
7237 spr_register(env, SPR_SPRG6, "SPRG6",
7238 SPR_NOACCESS, SPR_NOACCESS,
7239 &spr_read_generic, &spr_write_generic,
7240 0x00000000);
7241 spr_register(env, SPR_USPRG6, "USPRG6",
7242 &spr_read_ureg, SPR_NOACCESS,
7243 &spr_read_ureg, SPR_NOACCESS,
7244 0x00000000);
7245 spr_register(env, SPR_SPRG7, "SPRG7",
7246 SPR_NOACCESS, SPR_NOACCESS,
7247 &spr_read_generic, &spr_write_generic,
7248 0x00000000);
7249 spr_register(env, SPR_USPRG7, "USPRG7",
7250 &spr_read_ureg, SPR_NOACCESS,
7251 &spr_read_ureg, SPR_NOACCESS,
7252 0x00000000);
7253 /* Memory management */
7254 gen_low_BATs(env);
7255 gen_high_BATs(env);
7256 gen_74xx_soft_tlb(env, 128, 2);
7257 init_excp_7450(env);
7258 env->dcache_line_size = 32;
7259 env->icache_line_size = 32;
7260 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01007261 ppc6xx_irq_init(ppc_env_get_cpu(env));
j_mayer4e777442007-12-10 07:40:16 +00007262}
7263
Andreas Färber7856e3a2013-02-17 23:16:42 +00007264POWERPC_FAMILY(7457)(ObjectClass *oc, void *data)
7265{
Andreas Färberca5dff02013-02-17 23:16:46 +00007266 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00007267 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7268
Andreas Färberca5dff02013-02-17 23:16:46 +00007269 dc->desc = "PowerPC 7457 (aka G4)";
Andreas Färber7856e3a2013-02-17 23:16:42 +00007270 pcc->init_proc = init_proc_7457;
7271 pcc->check_pow = check_pow_hid0_74xx;
Andreas Färber53116eb2013-02-17 23:16:43 +00007272 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7273 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7274 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7275 PPC_FLOAT_STFIWX |
7276 PPC_CACHE | PPC_CACHE_ICBI |
7277 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
7278 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7279 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7280 PPC_MEM_TLBIA | PPC_74xx_TLB |
7281 PPC_SEGMENT | PPC_EXTERN |
7282 PPC_ALTIVEC;
Tom Musta9df5a462014-04-15 12:21:12 -05007283 pcc->msr_mask = (1ull << MSR_VR) |
7284 (1ull << MSR_POW) |
7285 (1ull << MSR_ILE) |
7286 (1ull << MSR_EE) |
7287 (1ull << MSR_PR) |
7288 (1ull << MSR_FP) |
7289 (1ull << MSR_ME) |
7290 (1ull << MSR_FE0) |
7291 (1ull << MSR_SE) |
7292 (1ull << MSR_DE) |
7293 (1ull << MSR_FE1) |
7294 (1ull << MSR_EP) |
7295 (1ull << MSR_IR) |
7296 (1ull << MSR_DR) |
7297 (1ull << MSR_PMM) |
7298 (1ull << MSR_RI) |
7299 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00007300 pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
7301 pcc->excp_model = POWERPC_EXCP_74xx;
7302 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7303 pcc->bfd_mach = bfd_mach_ppc_7400;
7304 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7305 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7306 POWERPC_FLAG_BUS_CLK;
Andreas Färber7856e3a2013-02-17 23:16:42 +00007307}
7308
Julio Guerra7162bde2013-06-24 23:15:54 +02007309static void init_proc_e600 (CPUPPCState *env)
7310{
7311 gen_spr_ne_601(env);
7312 gen_spr_7xx(env);
7313 /* Time base */
7314 gen_tbl(env);
7315 /* 74xx specific SPR */
7316 gen_spr_74xx(env);
7317 /* XXX : not implemented */
7318 spr_register(env, SPR_UBAMR, "UBAMR",
7319 &spr_read_ureg, SPR_NOACCESS,
7320 &spr_read_ureg, SPR_NOACCESS,
7321 0x00000000);
7322 /* XXX : not implemented */
7323 spr_register(env, SPR_LDSTCR, "LDSTCR",
7324 SPR_NOACCESS, SPR_NOACCESS,
7325 &spr_read_generic, &spr_write_generic,
7326 0x00000000);
7327 /* XXX : not implemented */
7328 spr_register(env, SPR_ICTRL, "ICTRL",
7329 SPR_NOACCESS, SPR_NOACCESS,
7330 &spr_read_generic, &spr_write_generic,
7331 0x00000000);
7332 /* XXX : not implemented */
7333 spr_register(env, SPR_MSSSR0, "MSSSR0",
7334 SPR_NOACCESS, SPR_NOACCESS,
7335 &spr_read_generic, &spr_write_generic,
7336 0x00000000);
7337 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10007338 spr_register(env, SPR_7XX_PMC5, "PMC5",
Julio Guerra7162bde2013-06-24 23:15:54 +02007339 SPR_NOACCESS, SPR_NOACCESS,
7340 &spr_read_generic, &spr_write_generic,
7341 0x00000000);
7342 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10007343 spr_register(env, SPR_7XX_UPMC5, "UPMC5",
Julio Guerra7162bde2013-06-24 23:15:54 +02007344 &spr_read_ureg, SPR_NOACCESS,
7345 &spr_read_ureg, SPR_NOACCESS,
7346 0x00000000);
7347 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10007348 spr_register(env, SPR_7XX_PMC6, "PMC6",
Julio Guerra7162bde2013-06-24 23:15:54 +02007349 SPR_NOACCESS, SPR_NOACCESS,
7350 &spr_read_generic, &spr_write_generic,
7351 0x00000000);
7352 /* XXX : not implemented */
Alexey Kardashevskiycb8b8bf2014-06-04 22:50:36 +10007353 spr_register(env, SPR_7XX_UPMC6, "UPMC6",
Julio Guerra7162bde2013-06-24 23:15:54 +02007354 &spr_read_ureg, SPR_NOACCESS,
7355 &spr_read_ureg, SPR_NOACCESS,
7356 0x00000000);
7357 /* SPRGs */
7358 spr_register(env, SPR_SPRG4, "SPRG4",
7359 SPR_NOACCESS, SPR_NOACCESS,
7360 &spr_read_generic, &spr_write_generic,
7361 0x00000000);
7362 spr_register(env, SPR_USPRG4, "USPRG4",
7363 &spr_read_ureg, SPR_NOACCESS,
7364 &spr_read_ureg, SPR_NOACCESS,
7365 0x00000000);
7366 spr_register(env, SPR_SPRG5, "SPRG5",
7367 SPR_NOACCESS, SPR_NOACCESS,
7368 &spr_read_generic, &spr_write_generic,
7369 0x00000000);
7370 spr_register(env, SPR_USPRG5, "USPRG5",
7371 &spr_read_ureg, SPR_NOACCESS,
7372 &spr_read_ureg, SPR_NOACCESS,
7373 0x00000000);
7374 spr_register(env, SPR_SPRG6, "SPRG6",
7375 SPR_NOACCESS, SPR_NOACCESS,
7376 &spr_read_generic, &spr_write_generic,
7377 0x00000000);
7378 spr_register(env, SPR_USPRG6, "USPRG6",
7379 &spr_read_ureg, SPR_NOACCESS,
7380 &spr_read_ureg, SPR_NOACCESS,
7381 0x00000000);
7382 spr_register(env, SPR_SPRG7, "SPRG7",
7383 SPR_NOACCESS, SPR_NOACCESS,
7384 &spr_read_generic, &spr_write_generic,
7385 0x00000000);
7386 spr_register(env, SPR_USPRG7, "USPRG7",
7387 &spr_read_ureg, SPR_NOACCESS,
7388 &spr_read_ureg, SPR_NOACCESS,
7389 0x00000000);
7390 /* Memory management */
7391 gen_low_BATs(env);
7392 gen_high_BATs(env);
7393 gen_74xx_soft_tlb(env, 128, 2);
7394 init_excp_7450(env);
7395 env->dcache_line_size = 32;
7396 env->icache_line_size = 32;
7397 /* Allocate hardware IRQ controller */
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01007398 ppc6xx_irq_init(ppc_env_get_cpu(env));
Julio Guerra7162bde2013-06-24 23:15:54 +02007399}
7400
7401POWERPC_FAMILY(e600)(ObjectClass *oc, void *data)
7402{
7403 DeviceClass *dc = DEVICE_CLASS(oc);
7404 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
7405
7406 dc->desc = "PowerPC e600";
7407 pcc->init_proc = init_proc_e600;
7408 pcc->check_pow = check_pow_hid0_74xx;
7409 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
7410 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
7411 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
7412 PPC_FLOAT_STFIWX |
7413 PPC_CACHE | PPC_CACHE_ICBI |
7414 PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
7415 PPC_MEM_SYNC | PPC_MEM_EIEIO |
7416 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
7417 PPC_MEM_TLBIA | PPC_74xx_TLB |
7418 PPC_SEGMENT | PPC_EXTERN |
7419 PPC_ALTIVEC;
7420 pcc->insns_flags2 = PPC_NONE;
Tom Musta9df5a462014-04-15 12:21:12 -05007421 pcc->msr_mask = (1ull << MSR_VR) |
7422 (1ull << MSR_POW) |
7423 (1ull << MSR_ILE) |
7424 (1ull << MSR_EE) |
7425 (1ull << MSR_PR) |
7426 (1ull << MSR_FP) |
7427 (1ull << MSR_ME) |
7428 (1ull << MSR_FE0) |
7429 (1ull << MSR_SE) |
7430 (1ull << MSR_DE) |
7431 (1ull << MSR_FE1) |
7432 (1ull << MSR_EP) |
7433 (1ull << MSR_IR) |
7434 (1ull << MSR_DR) |
7435 (1ull << MSR_PMM) |
7436 (1ull << MSR_RI) |
7437 (1ull << MSR_LE);
Julio Guerra7162bde2013-06-24 23:15:54 +02007438 pcc->mmu_model = POWERPC_MMU_32B;
7439#if defined(CONFIG_SOFTMMU)
7440 pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
7441#endif
7442 pcc->excp_model = POWERPC_EXCP_74xx;
7443 pcc->bus_model = PPC_FLAGS_INPUT_6xx;
7444 pcc->bfd_mach = bfd_mach_ppc_7400;
7445 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
7446 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
7447 POWERPC_FLAG_BUS_CLK;
7448}
7449
j_mayera750fc02007-09-26 23:54:22 +00007450#if defined (TARGET_PPC64)
j_mayer417bf012007-10-07 23:10:08 +00007451#if defined(CONFIG_USER_ONLY)
7452#define POWERPC970_HID5_INIT 0x00000080
7453#else
7454#define POWERPC970_HID5_INIT 0x00000000
7455#endif
7456
Alexey Kardashevskiy7488d482014-06-04 22:50:45 +10007457enum BOOK3S_CPU_TYPE {
7458 BOOK3S_CPU_970,
7459 BOOK3S_CPU_POWER5PLUS,
Alexey Kardashevskiya2428812014-06-04 22:50:54 +10007460 BOOK3S_CPU_POWER6,
7461 BOOK3S_CPU_POWER7,
Aneesh Kumar K.V706d6462016-07-26 17:28:24 +05307462 BOOK3S_CPU_POWER8,
7463 BOOK3S_CPU_POWER9
Alexey Kardashevskiy7488d482014-06-04 22:50:45 +10007464};
7465
Paolo Bonzini69b058c2014-11-26 13:39:48 +03007466static void gen_fscr_facility_check(DisasContext *ctx, int facility_sprn,
7467 int bit, int sprn, int cause)
Alexey Kardashevskiy45ed0be2014-06-04 22:50:57 +10007468{
7469 TCGv_i32 t1 = tcg_const_i32(bit);
7470 TCGv_i32 t2 = tcg_const_i32(sprn);
7471 TCGv_i32 t3 = tcg_const_i32(cause);
7472
Alexey Kardashevskiy45ed0be2014-06-04 22:50:57 +10007473 gen_helper_fscr_facility_check(cpu_env, t1, t2, t3);
7474
7475 tcg_temp_free_i32(t3);
7476 tcg_temp_free_i32(t2);
7477 tcg_temp_free_i32(t1);
7478}
7479
Paolo Bonzini69b058c2014-11-26 13:39:48 +03007480static void gen_msr_facility_check(DisasContext *ctx, int facility_sprn,
7481 int bit, int sprn, int cause)
Alexey Kardashevskiycdcdda22014-06-04 22:50:59 +10007482{
7483 TCGv_i32 t1 = tcg_const_i32(bit);
7484 TCGv_i32 t2 = tcg_const_i32(sprn);
7485 TCGv_i32 t3 = tcg_const_i32(cause);
7486
Alexey Kardashevskiycdcdda22014-06-04 22:50:59 +10007487 gen_helper_msr_facility_check(cpu_env, t1, t2, t3);
7488
7489 tcg_temp_free_i32(t3);
7490 tcg_temp_free_i32(t2);
7491 tcg_temp_free_i32(t1);
7492}
7493
Paolo Bonzini69b058c2014-11-26 13:39:48 +03007494static void spr_read_prev_upper32(DisasContext *ctx, int gprn, int sprn)
Alexey Kardashevskiycdcdda22014-06-04 22:50:59 +10007495{
7496 TCGv spr_up = tcg_temp_new();
7497 TCGv spr = tcg_temp_new();
7498
7499 gen_load_spr(spr, sprn - 1);
7500 tcg_gen_shri_tl(spr_up, spr, 32);
7501 tcg_gen_ext32u_tl(cpu_gpr[gprn], spr_up);
7502
7503 tcg_temp_free(spr);
7504 tcg_temp_free(spr_up);
7505}
7506
Paolo Bonzini69b058c2014-11-26 13:39:48 +03007507static void spr_write_prev_upper32(DisasContext *ctx, int sprn, int gprn)
Alexey Kardashevskiycdcdda22014-06-04 22:50:59 +10007508{
7509 TCGv spr = tcg_temp_new();
7510
7511 gen_load_spr(spr, sprn - 1);
7512 tcg_gen_deposit_tl(spr, spr, cpu_gpr[gprn], 32, 32);
7513 gen_store_spr(sprn - 1, spr);
7514
7515 tcg_temp_free(spr);
7516}
7517
j_mayer2f462812007-10-25 23:14:50 +00007518static int check_pow_970 (CPUPPCState *env)
7519{
Alexey Kardashevskiybbc01ca2014-06-04 22:50:37 +10007520 if (env->spr[SPR_HID0] & (HID0_DEEPNAP | HID0_DOZE | HID0_NAP)) {
j_mayer2f462812007-10-25 23:14:50 +00007521 return 1;
Alexey Kardashevskiybbc01ca2014-06-04 22:50:37 +10007522 }
j_mayer2f462812007-10-25 23:14:50 +00007523
7524 return 0;
7525}
7526
Alexey Kardashevskiy42382f62014-06-04 22:50:38 +10007527static void gen_spr_970_hid(CPUPPCState *env)
j_mayera750fc02007-09-26 23:54:22 +00007528{
j_mayera750fc02007-09-26 23:54:22 +00007529 /* Hardware implementation registers */
7530 /* XXX : not implemented */
7531 spr_register(env, SPR_HID0, "HID0",
7532 SPR_NOACCESS, SPR_NOACCESS,
j_mayer06403422007-10-03 20:27:44 +00007533 &spr_read_generic, &spr_write_clear,
j_mayerd63001d2007-10-04 00:51:58 +00007534 0x60000000);
j_mayera750fc02007-09-26 23:54:22 +00007535 spr_register(env, SPR_HID1, "HID1",
7536 SPR_NOACCESS, SPR_NOACCESS,
7537 &spr_read_generic, &spr_write_generic,
7538 0x00000000);
j_mayere57448f2007-10-04 01:50:03 +00007539 spr_register(env, SPR_970_HID5, "HID5",
7540 SPR_NOACCESS, SPR_NOACCESS,
7541 &spr_read_generic, &spr_write_generic,
j_mayer417bf012007-10-07 23:10:08 +00007542 POWERPC970_HID5_INIT);
Alexey Kardashevskiy42382f62014-06-04 22:50:38 +10007543}
7544
7545static void gen_spr_970_hior(CPUPPCState *env)
7546{
j_mayer12de9a32007-10-05 22:06:02 +00007547 spr_register(env, SPR_HIOR, "SPR_HIOR",
7548 SPR_NOACCESS, SPR_NOACCESS,
blueswir12adab7d2009-02-28 18:39:42 +00007549 &spr_read_hior, &spr_write_hior,
7550 0x00000000);
Alexey Kardashevskiy42382f62014-06-04 22:50:38 +10007551}
Alexey Kardashevskiybbc01ca2014-06-04 22:50:37 +10007552
Alexey Kardashevskiy42382f62014-06-04 22:50:38 +10007553static void gen_spr_book3s_common(CPUPPCState *env)
7554{
Alexey Kardashevskiybbc01ca2014-06-04 22:50:37 +10007555 spr_register(env, SPR_CTRL, "SPR_CTRL",
7556 SPR_NOACCESS, SPR_NOACCESS,
7557 SPR_NOACCESS, &spr_write_generic,
7558 0x00000000);
7559 spr_register(env, SPR_UCTRL, "SPR_UCTRL",
Alexey Kardashevskiyeb16dd92014-06-04 22:50:39 +10007560 &spr_read_ureg, SPR_NOACCESS,
7561 &spr_read_ureg, SPR_NOACCESS,
Alexey Kardashevskiybbc01ca2014-06-04 22:50:37 +10007562 0x00000000);
Alexey Kardashevskiy42382f62014-06-04 22:50:38 +10007563}
7564
7565static void gen_spr_book3s_altivec(CPUPPCState *env)
7566{
7567 if (!(env->insns_flags & PPC_ALTIVEC)) {
7568 return;
7569 }
7570
Alexey Kardashevskiy7303f832014-06-04 22:51:02 +10007571 spr_register_kvm(env, SPR_VRSAVE, "VRSAVE",
7572 &spr_read_generic, &spr_write_generic,
7573 &spr_read_generic, &spr_write_generic,
7574 KVM_REG_PPC_VRSAVE, 0x00000000);
Alexey Kardashevskiy42382f62014-06-04 22:50:38 +10007575
7576 /* Can't find information on what this should be on reset. This
7577 * value is the one used by 74xx processors. */
7578 vscr_init(env, 0x00010000);
7579}
7580
Alexey Kardashevskiyfd51ff62014-06-04 22:50:40 +10007581static void gen_spr_book3s_dbg(CPUPPCState *env)
7582{
Alexey Kardashevskiycd9adfd2014-06-04 22:51:03 +10007583 /*
7584 * TODO: different specs define different scopes for these,
7585 * will have to address this:
7586 * 970: super/write and super/read
7587 * powerisa 2.03..2.04: hypv/write and super/read.
7588 * powerisa 2.05 and newer: hypv/write and hypv/read.
7589 */
Alexey Kardashevskiyfd51ff62014-06-04 22:50:40 +10007590 spr_register_kvm(env, SPR_DABR, "DABR",
7591 SPR_NOACCESS, SPR_NOACCESS,
7592 &spr_read_generic, &spr_write_generic,
7593 KVM_REG_PPC_DABR, 0x00000000);
Alexey Kardashevskiycd9adfd2014-06-04 22:51:03 +10007594 spr_register_kvm(env, SPR_DABRX, "DABRX",
7595 SPR_NOACCESS, SPR_NOACCESS,
7596 &spr_read_generic, &spr_write_generic,
7597 KVM_REG_PPC_DABRX, 0x00000000);
Alexey Kardashevskiyfd51ff62014-06-04 22:50:40 +10007598}
7599
Benjamin Herrenschmidtf401dd32016-03-21 13:52:33 +01007600static void gen_spr_book3s_207_dbg(CPUPPCState *env)
7601{
7602 spr_register_kvm_hv(env, SPR_DAWR, "DAWR",
7603 SPR_NOACCESS, SPR_NOACCESS,
7604 SPR_NOACCESS, SPR_NOACCESS,
7605 &spr_read_generic, &spr_write_generic,
7606 KVM_REG_PPC_DAWR, 0x00000000);
7607 spr_register_kvm_hv(env, SPR_DAWRX, "DAWRX",
7608 SPR_NOACCESS, SPR_NOACCESS,
7609 SPR_NOACCESS, SPR_NOACCESS,
7610 &spr_read_generic, &spr_write_generic,
7611 KVM_REG_PPC_DAWRX, 0x00000000);
Benjamin Herrenschmidteb5ceb42016-03-21 13:52:39 +01007612 spr_register_kvm_hv(env, SPR_CIABR, "CIABR",
7613 SPR_NOACCESS, SPR_NOACCESS,
7614 SPR_NOACCESS, SPR_NOACCESS,
7615 &spr_read_generic, &spr_write_generic,
7616 KVM_REG_PPC_CIABR, 0x00000000);
Benjamin Herrenschmidtf401dd32016-03-21 13:52:33 +01007617}
7618
Alexey Kardashevskiyfd51ff62014-06-04 22:50:40 +10007619static void gen_spr_970_dbg(CPUPPCState *env)
7620{
7621 /* Breakpoints */
7622 spr_register(env, SPR_IABR, "IABR",
7623 SPR_NOACCESS, SPR_NOACCESS,
7624 &spr_read_generic, &spr_write_generic,
7625 0x00000000);
7626}
7627
7628static void gen_spr_book3s_pmu_sup(CPUPPCState *env)
7629{
Alexey Kardashevskiy83cc6f82014-06-04 22:50:47 +10007630 spr_register_kvm(env, SPR_POWER_MMCR0, "MMCR0",
7631 SPR_NOACCESS, SPR_NOACCESS,
7632 &spr_read_generic, &spr_write_generic,
7633 KVM_REG_PPC_MMCR0, 0x00000000);
7634 spr_register_kvm(env, SPR_POWER_MMCR1, "MMCR1",
7635 SPR_NOACCESS, SPR_NOACCESS,
7636 &spr_read_generic, &spr_write_generic,
7637 KVM_REG_PPC_MMCR1, 0x00000000);
7638 spr_register_kvm(env, SPR_POWER_MMCRA, "MMCRA",
7639 SPR_NOACCESS, SPR_NOACCESS,
7640 &spr_read_generic, &spr_write_generic,
7641 KVM_REG_PPC_MMCRA, 0x00000000);
7642 spr_register_kvm(env, SPR_POWER_PMC1, "PMC1",
7643 SPR_NOACCESS, SPR_NOACCESS,
7644 &spr_read_generic, &spr_write_generic,
7645 KVM_REG_PPC_PMC1, 0x00000000);
7646 spr_register_kvm(env, SPR_POWER_PMC2, "PMC2",
7647 SPR_NOACCESS, SPR_NOACCESS,
7648 &spr_read_generic, &spr_write_generic,
7649 KVM_REG_PPC_PMC2, 0x00000000);
7650 spr_register_kvm(env, SPR_POWER_PMC3, "PMC3",
7651 SPR_NOACCESS, SPR_NOACCESS,
7652 &spr_read_generic, &spr_write_generic,
7653 KVM_REG_PPC_PMC3, 0x00000000);
7654 spr_register_kvm(env, SPR_POWER_PMC4, "PMC4",
7655 SPR_NOACCESS, SPR_NOACCESS,
7656 &spr_read_generic, &spr_write_generic,
7657 KVM_REG_PPC_PMC4, 0x00000000);
7658 spr_register_kvm(env, SPR_POWER_PMC5, "PMC5",
7659 SPR_NOACCESS, SPR_NOACCESS,
7660 &spr_read_generic, &spr_write_generic,
7661 KVM_REG_PPC_PMC5, 0x00000000);
7662 spr_register_kvm(env, SPR_POWER_PMC6, "PMC6",
7663 SPR_NOACCESS, SPR_NOACCESS,
7664 &spr_read_generic, &spr_write_generic,
7665 KVM_REG_PPC_PMC6, 0x00000000);
7666 spr_register_kvm(env, SPR_POWER_SIAR, "SIAR",
7667 SPR_NOACCESS, SPR_NOACCESS,
7668 &spr_read_generic, &spr_write_generic,
7669 KVM_REG_PPC_SIAR, 0x00000000);
7670 spr_register_kvm(env, SPR_POWER_SDAR, "SDAR",
7671 SPR_NOACCESS, SPR_NOACCESS,
7672 &spr_read_generic, &spr_write_generic,
7673 KVM_REG_PPC_SDAR, 0x00000000);
Alexey Kardashevskiyfd51ff62014-06-04 22:50:40 +10007674}
7675
7676static void gen_spr_book3s_pmu_user(CPUPPCState *env)
7677{
7678 spr_register(env, SPR_POWER_UMMCR0, "UMMCR0",
7679 &spr_read_ureg, SPR_NOACCESS,
7680 &spr_read_ureg, &spr_write_ureg,
7681 0x00000000);
7682 spr_register(env, SPR_POWER_UMMCR1, "UMMCR1",
7683 &spr_read_ureg, SPR_NOACCESS,
7684 &spr_read_ureg, &spr_write_ureg,
7685 0x00000000);
Alexey Kardashevskiy077850b2014-06-04 22:50:42 +10007686 spr_register(env, SPR_POWER_UMMCRA, "UMMCRA",
7687 &spr_read_ureg, SPR_NOACCESS,
7688 &spr_read_ureg, &spr_write_ureg,
7689 0x00000000);
Alexey Kardashevskiyfd51ff62014-06-04 22:50:40 +10007690 spr_register(env, SPR_POWER_UPMC1, "UPMC1",
7691 &spr_read_ureg, SPR_NOACCESS,
7692 &spr_read_ureg, &spr_write_ureg,
7693 0x00000000);
7694 spr_register(env, SPR_POWER_UPMC2, "UPMC2",
7695 &spr_read_ureg, SPR_NOACCESS,
7696 &spr_read_ureg, &spr_write_ureg,
7697 0x00000000);
7698 spr_register(env, SPR_POWER_UPMC3, "UPMC3",
7699 &spr_read_ureg, SPR_NOACCESS,
7700 &spr_read_ureg, &spr_write_ureg,
7701 0x00000000);
7702 spr_register(env, SPR_POWER_UPMC4, "UPMC4",
7703 &spr_read_ureg, SPR_NOACCESS,
7704 &spr_read_ureg, &spr_write_ureg,
7705 0x00000000);
Alexey Kardashevskiy077850b2014-06-04 22:50:42 +10007706 spr_register(env, SPR_POWER_UPMC5, "UPMC5",
7707 &spr_read_ureg, SPR_NOACCESS,
7708 &spr_read_ureg, &spr_write_ureg,
7709 0x00000000);
7710 spr_register(env, SPR_POWER_UPMC6, "UPMC6",
7711 &spr_read_ureg, SPR_NOACCESS,
7712 &spr_read_ureg, &spr_write_ureg,
7713 0x00000000);
Alexey Kardashevskiyfd51ff62014-06-04 22:50:40 +10007714 spr_register(env, SPR_POWER_USIAR, "USIAR",
7715 &spr_read_ureg, SPR_NOACCESS,
7716 &spr_read_ureg, &spr_write_ureg,
7717 0x00000000);
Alexey Kardashevskiy077850b2014-06-04 22:50:42 +10007718 spr_register(env, SPR_POWER_USDAR, "USDAR",
7719 &spr_read_ureg, SPR_NOACCESS,
7720 &spr_read_ureg, &spr_write_ureg,
7721 0x00000000);
Alexey Kardashevskiyfd51ff62014-06-04 22:50:40 +10007722}
7723
Alexey Kardashevskiyc36c97f2014-06-04 22:50:43 +10007724static void gen_spr_970_pmu_sup(CPUPPCState *env)
7725{
Alexey Kardashevskiy83cc6f82014-06-04 22:50:47 +10007726 spr_register_kvm(env, SPR_970_PMC7, "PMC7",
7727 SPR_NOACCESS, SPR_NOACCESS,
7728 &spr_read_generic, &spr_write_generic,
7729 KVM_REG_PPC_PMC7, 0x00000000);
7730 spr_register_kvm(env, SPR_970_PMC8, "PMC8",
7731 SPR_NOACCESS, SPR_NOACCESS,
7732 &spr_read_generic, &spr_write_generic,
7733 KVM_REG_PPC_PMC8, 0x00000000);
Alexey Kardashevskiyc36c97f2014-06-04 22:50:43 +10007734}
7735
7736static void gen_spr_970_pmu_user(CPUPPCState *env)
7737{
7738 spr_register(env, SPR_970_UPMC7, "UPMC7",
7739 &spr_read_ureg, SPR_NOACCESS,
7740 &spr_read_ureg, &spr_write_ureg,
7741 0x00000000);
7742 spr_register(env, SPR_970_UPMC8, "UPMC8",
7743 &spr_read_ureg, SPR_NOACCESS,
7744 &spr_read_ureg, &spr_write_ureg,
7745 0x00000000);
7746}
7747
Alexey Kardashevskiy70c53402014-06-04 22:50:58 +10007748static void gen_spr_power8_pmu_sup(CPUPPCState *env)
7749{
7750 spr_register_kvm(env, SPR_POWER_MMCR2, "MMCR2",
7751 SPR_NOACCESS, SPR_NOACCESS,
7752 &spr_read_generic, &spr_write_generic,
7753 KVM_REG_PPC_MMCR2, 0x00000000);
7754 spr_register_kvm(env, SPR_POWER_MMCRS, "MMCRS",
7755 SPR_NOACCESS, SPR_NOACCESS,
7756 &spr_read_generic, &spr_write_generic,
7757 KVM_REG_PPC_MMCRS, 0x00000000);
Benjamin Herrenschmidt14646452016-03-02 21:19:22 +01007758 spr_register_kvm(env, SPR_POWER_SIER, "SIER",
7759 SPR_NOACCESS, SPR_NOACCESS,
7760 &spr_read_generic, &spr_write_generic,
7761 KVM_REG_PPC_SIER, 0x00000000);
7762 spr_register_kvm(env, SPR_POWER_SPMC1, "SPMC1",
7763 SPR_NOACCESS, SPR_NOACCESS,
7764 &spr_read_generic, &spr_write_generic,
7765 KVM_REG_PPC_SPMC1, 0x00000000);
7766 spr_register_kvm(env, SPR_POWER_SPMC2, "SPMC2",
7767 SPR_NOACCESS, SPR_NOACCESS,
7768 &spr_read_generic, &spr_write_generic,
7769 KVM_REG_PPC_SPMC2, 0x00000000);
7770 spr_register_kvm(env, SPR_TACR, "TACR",
7771 SPR_NOACCESS, SPR_NOACCESS,
7772 &spr_read_generic, &spr_write_generic,
7773 KVM_REG_PPC_TACR, 0x00000000);
7774 spr_register_kvm(env, SPR_TCSCR, "TCSCR",
7775 SPR_NOACCESS, SPR_NOACCESS,
7776 &spr_read_generic, &spr_write_generic,
7777 KVM_REG_PPC_TCSCR, 0x00000000);
7778 spr_register_kvm(env, SPR_CSIGR, "CSIGR",
7779 SPR_NOACCESS, SPR_NOACCESS,
7780 &spr_read_generic, &spr_write_generic,
7781 KVM_REG_PPC_CSIGR, 0x00000000);
Alexey Kardashevskiy70c53402014-06-04 22:50:58 +10007782}
7783
7784static void gen_spr_power8_pmu_user(CPUPPCState *env)
7785{
7786 spr_register(env, SPR_POWER_UMMCR2, "UMMCR2",
7787 &spr_read_ureg, SPR_NOACCESS,
7788 &spr_read_ureg, &spr_write_ureg,
7789 0x00000000);
Benjamin Herrenschmidt14646452016-03-02 21:19:22 +01007790 spr_register(env, SPR_POWER_USIER, "USIER",
7791 &spr_read_generic, SPR_NOACCESS,
7792 &spr_read_generic, &spr_write_generic,
7793 0x00000000);
Alexey Kardashevskiy70c53402014-06-04 22:50:58 +10007794}
7795
Alexey Kardashevskiyfd51ff62014-06-04 22:50:40 +10007796static void gen_spr_power5p_ear(CPUPPCState *env)
7797{
7798 /* External access control */
7799 spr_register(env, SPR_EAR, "EAR",
7800 SPR_NOACCESS, SPR_NOACCESS,
7801 &spr_read_generic, &spr_write_generic,
7802 0x00000000);
7803}
7804
Benjamin Herrenschmidt8eeb3302016-06-27 08:55:14 +02007805#if !defined(CONFIG_USER_ONLY)
7806static void spr_write_hmer(DisasContext *ctx, int sprn, int gprn)
7807{
7808 TCGv hmer = tcg_temp_new();
7809
7810 gen_load_spr(hmer, sprn);
7811 tcg_gen_and_tl(hmer, cpu_gpr[gprn], hmer);
7812 gen_store_spr(sprn, hmer);
7813 spr_store_dump_spr(sprn);
7814 tcg_temp_free(hmer);
7815}
Benjamin Herrenschmidt4b3fc372016-06-27 08:55:16 +02007816
7817static void spr_write_lpcr(DisasContext *ctx, int sprn, int gprn)
7818{
7819 gen_helper_store_lpcr(cpu_env, cpu_gpr[gprn]);
7820}
7821
7822static void spr_write_970_hid4(DisasContext *ctx, int sprn, int gprn)
7823{
7824#if defined(TARGET_PPC64)
7825 spr_write_generic(ctx, sprn, gprn);
7826 gen_helper_store_lpcr(cpu_env, cpu_gpr[gprn]);
Benjamin Herrenschmidt8eeb3302016-06-27 08:55:14 +02007827#endif
Benjamin Herrenschmidt4b3fc372016-06-27 08:55:16 +02007828}
7829
7830#endif /* !defined(CONFIG_USER_ONLY) */
7831
7832static void gen_spr_970_lpar(CPUPPCState *env)
7833{
7834#if !defined(CONFIG_USER_ONLY)
7835 /* Logical partitionning */
7836 /* PPC970: HID4 is effectively the LPCR */
7837 spr_register(env, SPR_970_HID4, "HID4",
7838 SPR_NOACCESS, SPR_NOACCESS,
7839 &spr_read_generic, &spr_write_970_hid4,
7840 0x00000000);
7841#endif
7842}
7843
7844static void gen_spr_power5p_lpar(CPUPPCState *env)
7845{
7846#if !defined(CONFIG_USER_ONLY)
7847 /* Logical partitionning */
Benjamin Herrenschmidt635dff22016-06-27 08:55:20 +02007848 spr_register_kvm_hv(env, SPR_LPCR, "LPCR",
7849 SPR_NOACCESS, SPR_NOACCESS,
7850 SPR_NOACCESS, SPR_NOACCESS,
7851 &spr_read_generic, &spr_write_lpcr,
7852 KVM_REG_PPC_LPCR, LPCR_LPES0 | LPCR_LPES1);
Benjamin Herrenschmidt4b236b62016-06-27 08:55:19 +02007853 spr_register_hv(env, SPR_HDEC, "HDEC",
7854 SPR_NOACCESS, SPR_NOACCESS,
7855 SPR_NOACCESS, SPR_NOACCESS,
7856 &spr_read_hdecr, &spr_write_hdecr, 0);
Benjamin Herrenschmidt4b3fc372016-06-27 08:55:16 +02007857#endif
7858}
Benjamin Herrenschmidt8eeb3302016-06-27 08:55:14 +02007859
Alexey Kardashevskiye61716a2014-06-04 22:50:48 +10007860static void gen_spr_book3s_ids(CPUPPCState *env)
7861{
Benjamin Herrenschmidt8eeb3302016-06-27 08:55:14 +02007862 /* FIXME: Will need to deal with thread vs core only SPRs */
7863
Alexey Kardashevskiye61716a2014-06-04 22:50:48 +10007864 /* Processor identification */
Benjamin Herrenschmidt8eeb3302016-06-27 08:55:14 +02007865 spr_register_hv(env, SPR_PIR, "PIR",
Alexey Kardashevskiye61716a2014-06-04 22:50:48 +10007866 SPR_NOACCESS, SPR_NOACCESS,
Benjamin Herrenschmidt8eeb3302016-06-27 08:55:14 +02007867 SPR_NOACCESS, SPR_NOACCESS,
7868 &spr_read_generic, NULL,
7869 0x00000000);
7870 spr_register_hv(env, SPR_HID0, "HID0",
7871 SPR_NOACCESS, SPR_NOACCESS,
7872 SPR_NOACCESS, SPR_NOACCESS,
7873 &spr_read_generic, &spr_write_generic,
7874 0x00000000);
7875 spr_register_hv(env, SPR_TSCR, "TSCR",
7876 SPR_NOACCESS, SPR_NOACCESS,
7877 SPR_NOACCESS, SPR_NOACCESS,
7878 &spr_read_generic, &spr_write_generic,
7879 0x00000000);
7880 spr_register_hv(env, SPR_HMER, "HMER",
7881 SPR_NOACCESS, SPR_NOACCESS,
7882 SPR_NOACCESS, SPR_NOACCESS,
7883 &spr_read_generic, &spr_write_hmer,
7884 0x00000000);
7885 spr_register_hv(env, SPR_HMEER, "HMEER",
7886 SPR_NOACCESS, SPR_NOACCESS,
7887 SPR_NOACCESS, SPR_NOACCESS,
7888 &spr_read_generic, &spr_write_generic,
7889 0x00000000);
7890 spr_register_hv(env, SPR_TFMR, "TFMR",
7891 SPR_NOACCESS, SPR_NOACCESS,
7892 SPR_NOACCESS, SPR_NOACCESS,
7893 &spr_read_generic, &spr_write_generic,
7894 0x00000000);
7895 spr_register_hv(env, SPR_LPIDR, "LPIDR",
7896 SPR_NOACCESS, SPR_NOACCESS,
7897 SPR_NOACCESS, SPR_NOACCESS,
7898 &spr_read_generic, &spr_write_generic,
7899 0x00000000);
7900 spr_register_hv(env, SPR_HFSCR, "HFSCR",
7901 SPR_NOACCESS, SPR_NOACCESS,
7902 SPR_NOACCESS, SPR_NOACCESS,
7903 &spr_read_generic, &spr_write_generic,
7904 0x00000000);
7905 spr_register_hv(env, SPR_MMCRC, "MMCRC",
7906 SPR_NOACCESS, SPR_NOACCESS,
7907 SPR_NOACCESS, SPR_NOACCESS,
7908 &spr_read_generic, &spr_write_generic,
7909 0x00000000);
7910 spr_register_hv(env, SPR_MMCRH, "MMCRH",
7911 SPR_NOACCESS, SPR_NOACCESS,
7912 SPR_NOACCESS, SPR_NOACCESS,
7913 &spr_read_generic, &spr_write_generic,
7914 0x00000000);
7915 spr_register_hv(env, SPR_HSPRG0, "HSPRG0",
7916 SPR_NOACCESS, SPR_NOACCESS,
7917 SPR_NOACCESS, SPR_NOACCESS,
7918 &spr_read_generic, &spr_write_generic,
7919 0x00000000);
7920 spr_register_hv(env, SPR_HSPRG1, "HSPRG1",
7921 SPR_NOACCESS, SPR_NOACCESS,
7922 SPR_NOACCESS, SPR_NOACCESS,
7923 &spr_read_generic, &spr_write_generic,
7924 0x00000000);
7925 spr_register_hv(env, SPR_HSRR0, "HSRR0",
7926 SPR_NOACCESS, SPR_NOACCESS,
7927 SPR_NOACCESS, SPR_NOACCESS,
7928 &spr_read_generic, &spr_write_generic,
7929 0x00000000);
7930 spr_register_hv(env, SPR_HSRR1, "HSRR1",
7931 SPR_NOACCESS, SPR_NOACCESS,
7932 SPR_NOACCESS, SPR_NOACCESS,
7933 &spr_read_generic, &spr_write_generic,
7934 0x00000000);
7935 spr_register_hv(env, SPR_HDAR, "HDAR",
7936 SPR_NOACCESS, SPR_NOACCESS,
7937 SPR_NOACCESS, SPR_NOACCESS,
7938 &spr_read_generic, &spr_write_generic,
7939 0x00000000);
7940 spr_register_hv(env, SPR_HDSISR, "HDSISR",
7941 SPR_NOACCESS, SPR_NOACCESS,
7942 SPR_NOACCESS, SPR_NOACCESS,
7943 &spr_read_generic, &spr_write_generic,
7944 0x00000000);
7945 spr_register_hv(env, SPR_RMOR, "RMOR",
7946 SPR_NOACCESS, SPR_NOACCESS,
7947 SPR_NOACCESS, SPR_NOACCESS,
7948 &spr_read_generic, &spr_write_generic,
7949 0x00000000);
7950 spr_register_hv(env, SPR_HRMOR, "HRMOR",
7951 SPR_NOACCESS, SPR_NOACCESS,
7952 SPR_NOACCESS, SPR_NOACCESS,
7953 &spr_read_generic, &spr_write_generic,
Alexey Kardashevskiye61716a2014-06-04 22:50:48 +10007954 0x00000000);
7955}
7956
Alexey Kardashevskiyd1a721a2014-06-04 22:50:55 +10007957static void gen_spr_power8_ids(CPUPPCState *env)
7958{
7959 /* Thread identification */
7960 spr_register(env, SPR_TIR, "TIR",
7961 SPR_NOACCESS, SPR_NOACCESS,
7962 &spr_read_generic, SPR_NOACCESS,
7963 0x00000000);
7964}
7965
Alexey Kardashevskiye61716a2014-06-04 22:50:48 +10007966static void gen_spr_book3s_purr(CPUPPCState *env)
7967{
7968#if !defined(CONFIG_USER_ONLY)
7969 /* PURR & SPURR: Hack - treat these as aliases for the TB for now */
7970 spr_register_kvm(env, SPR_PURR, "PURR",
7971 &spr_read_purr, SPR_NOACCESS,
7972 &spr_read_purr, SPR_NOACCESS,
7973 KVM_REG_PPC_PURR, 0x00000000);
7974 spr_register_kvm(env, SPR_SPURR, "SPURR",
7975 &spr_read_purr, SPR_NOACCESS,
7976 &spr_read_purr, SPR_NOACCESS,
7977 KVM_REG_PPC_SPURR, 0x00000000);
7978#endif
7979}
7980
Alexey Kardashevskiy5db7d4f2014-06-04 22:50:50 +10007981static void gen_spr_power6_dbg(CPUPPCState *env)
7982{
7983#if !defined(CONFIG_USER_ONLY)
7984 spr_register(env, SPR_CFAR, "SPR_CFAR",
7985 SPR_NOACCESS, SPR_NOACCESS,
7986 &spr_read_cfar, &spr_write_cfar,
7987 0x00000000);
7988#endif
7989}
7990
7991static void gen_spr_power5p_common(CPUPPCState *env)
7992{
Alexey Kardashevskiy7303f832014-06-04 22:51:02 +10007993 spr_register_kvm(env, SPR_PPR, "PPR",
7994 &spr_read_generic, &spr_write_generic,
7995 &spr_read_generic, &spr_write_generic,
7996 KVM_REG_PPC_PPR, 0x00000000);
Alexey Kardashevskiy5db7d4f2014-06-04 22:50:50 +10007997}
7998
7999static void gen_spr_power6_common(CPUPPCState *env)
8000{
8001#if !defined(CONFIG_USER_ONLY)
8002 spr_register_kvm(env, SPR_DSCR, "SPR_DSCR",
8003 SPR_NOACCESS, SPR_NOACCESS,
8004 &spr_read_generic, &spr_write_generic,
8005 KVM_REG_PPC_DSCR, 0x00000000);
8006#endif
8007 /*
8008 * Register PCR to report POWERPC_EXCP_PRIV_REG instead of
8009 * POWERPC_EXCP_INVAL_SPR.
8010 */
8011 spr_register(env, SPR_PCR, "PCR",
8012 SPR_NOACCESS, SPR_NOACCESS,
8013 SPR_NOACCESS, SPR_NOACCESS,
8014 0x00000000);
8015}
8016
Paolo Bonzini69b058c2014-11-26 13:39:48 +03008017static void spr_read_tar(DisasContext *ctx, int gprn, int sprn)
Alexey Kardashevskiy45ed0be2014-06-04 22:50:57 +10008018{
Paolo Bonzini69b058c2014-11-26 13:39:48 +03008019 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_TAR, sprn, FSCR_IC_TAR);
8020 spr_read_generic(ctx, gprn, sprn);
Alexey Kardashevskiy45ed0be2014-06-04 22:50:57 +10008021}
8022
Paolo Bonzini69b058c2014-11-26 13:39:48 +03008023static void spr_write_tar(DisasContext *ctx, int sprn, int gprn)
Alexey Kardashevskiy45ed0be2014-06-04 22:50:57 +10008024{
Paolo Bonzini69b058c2014-11-26 13:39:48 +03008025 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_TAR, sprn, FSCR_IC_TAR);
8026 spr_write_generic(ctx, sprn, gprn);
Alexey Kardashevskiy45ed0be2014-06-04 22:50:57 +10008027}
8028
Alexey Kardashevskiy768167a2014-06-04 22:50:49 +10008029static void gen_spr_power8_tce_address_control(CPUPPCState *env)
8030{
Thomas Huth1e440cb2016-03-02 21:19:21 +01008031 spr_register_kvm(env, SPR_TAR, "TAR",
8032 &spr_read_tar, &spr_write_tar,
8033 &spr_read_generic, &spr_write_generic,
8034 KVM_REG_PPC_TAR, 0x00000000);
Alexey Kardashevskiy768167a2014-06-04 22:50:49 +10008035}
8036
Paolo Bonzini69b058c2014-11-26 13:39:48 +03008037static void spr_read_tm(DisasContext *ctx, int gprn, int sprn)
Alexey Kardashevskiycdcdda22014-06-04 22:50:59 +10008038{
Paolo Bonzini69b058c2014-11-26 13:39:48 +03008039 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8040 spr_read_generic(ctx, gprn, sprn);
Alexey Kardashevskiycdcdda22014-06-04 22:50:59 +10008041}
8042
Paolo Bonzini69b058c2014-11-26 13:39:48 +03008043static void spr_write_tm(DisasContext *ctx, int sprn, int gprn)
Alexey Kardashevskiycdcdda22014-06-04 22:50:59 +10008044{
Paolo Bonzini69b058c2014-11-26 13:39:48 +03008045 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8046 spr_write_generic(ctx, sprn, gprn);
Alexey Kardashevskiycdcdda22014-06-04 22:50:59 +10008047}
8048
Paolo Bonzini69b058c2014-11-26 13:39:48 +03008049static void spr_read_tm_upper32(DisasContext *ctx, int gprn, int sprn)
Alexey Kardashevskiycdcdda22014-06-04 22:50:59 +10008050{
Paolo Bonzini69b058c2014-11-26 13:39:48 +03008051 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8052 spr_read_prev_upper32(ctx, gprn, sprn);
Alexey Kardashevskiycdcdda22014-06-04 22:50:59 +10008053}
8054
Paolo Bonzini69b058c2014-11-26 13:39:48 +03008055static void spr_write_tm_upper32(DisasContext *ctx, int sprn, int gprn)
Alexey Kardashevskiycdcdda22014-06-04 22:50:59 +10008056{
Paolo Bonzini69b058c2014-11-26 13:39:48 +03008057 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
8058 spr_write_prev_upper32(ctx, sprn, gprn);
Alexey Kardashevskiycdcdda22014-06-04 22:50:59 +10008059}
8060
8061static void gen_spr_power8_tm(CPUPPCState *env)
8062{
8063 spr_register_kvm(env, SPR_TFHAR, "TFHAR",
8064 &spr_read_tm, &spr_write_tm,
8065 &spr_read_tm, &spr_write_tm,
8066 KVM_REG_PPC_TFHAR, 0x00000000);
8067 spr_register_kvm(env, SPR_TFIAR, "TFIAR",
8068 &spr_read_tm, &spr_write_tm,
8069 &spr_read_tm, &spr_write_tm,
8070 KVM_REG_PPC_TFIAR, 0x00000000);
8071 spr_register_kvm(env, SPR_TEXASR, "TEXASR",
8072 &spr_read_tm, &spr_write_tm,
8073 &spr_read_tm, &spr_write_tm,
8074 KVM_REG_PPC_TEXASR, 0x00000000);
8075 spr_register(env, SPR_TEXASRU, "TEXASRU",
8076 &spr_read_tm_upper32, &spr_write_tm_upper32,
8077 &spr_read_tm_upper32, &spr_write_tm_upper32,
8078 0x00000000);
8079}
8080
Paolo Bonzini69b058c2014-11-26 13:39:48 +03008081static void spr_read_ebb(DisasContext *ctx, int gprn, int sprn)
Alexey Kardashevskiy4ee4a032014-06-04 22:51:01 +10008082{
Paolo Bonzini69b058c2014-11-26 13:39:48 +03008083 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8084 spr_read_generic(ctx, gprn, sprn);
Alexey Kardashevskiy4ee4a032014-06-04 22:51:01 +10008085}
8086
Paolo Bonzini69b058c2014-11-26 13:39:48 +03008087static void spr_write_ebb(DisasContext *ctx, int sprn, int gprn)
Alexey Kardashevskiy4ee4a032014-06-04 22:51:01 +10008088{
Paolo Bonzini69b058c2014-11-26 13:39:48 +03008089 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8090 spr_write_generic(ctx, sprn, gprn);
Alexey Kardashevskiy4ee4a032014-06-04 22:51:01 +10008091}
8092
Paolo Bonzini69b058c2014-11-26 13:39:48 +03008093static void spr_read_ebb_upper32(DisasContext *ctx, int gprn, int sprn)
Alexey Kardashevskiy4ee4a032014-06-04 22:51:01 +10008094{
Paolo Bonzini69b058c2014-11-26 13:39:48 +03008095 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8096 spr_read_prev_upper32(ctx, gprn, sprn);
Alexey Kardashevskiy4ee4a032014-06-04 22:51:01 +10008097}
8098
Paolo Bonzini69b058c2014-11-26 13:39:48 +03008099static void spr_write_ebb_upper32(DisasContext *ctx, int sprn, int gprn)
Alexey Kardashevskiy4ee4a032014-06-04 22:51:01 +10008100{
Paolo Bonzini69b058c2014-11-26 13:39:48 +03008101 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
8102 spr_write_prev_upper32(ctx, sprn, gprn);
Alexey Kardashevskiy4ee4a032014-06-04 22:51:01 +10008103}
8104
8105static void gen_spr_power8_ebb(CPUPPCState *env)
8106{
8107 spr_register(env, SPR_BESCRS, "BESCRS",
8108 &spr_read_ebb, &spr_write_ebb,
8109 &spr_read_generic, &spr_write_generic,
8110 0x00000000);
8111 spr_register(env, SPR_BESCRSU, "BESCRSU",
8112 &spr_read_ebb_upper32, &spr_write_ebb_upper32,
8113 &spr_read_prev_upper32, &spr_write_prev_upper32,
8114 0x00000000);
8115 spr_register(env, SPR_BESCRR, "BESCRR",
8116 &spr_read_ebb, &spr_write_ebb,
8117 &spr_read_generic, &spr_write_generic,
8118 0x00000000);
8119 spr_register(env, SPR_BESCRRU, "BESCRRU",
8120 &spr_read_ebb_upper32, &spr_write_ebb_upper32,
8121 &spr_read_prev_upper32, &spr_write_prev_upper32,
8122 0x00000000);
8123 spr_register_kvm(env, SPR_EBBHR, "EBBHR",
8124 &spr_read_ebb, &spr_write_ebb,
8125 &spr_read_generic, &spr_write_generic,
8126 KVM_REG_PPC_EBBHR, 0x00000000);
8127 spr_register_kvm(env, SPR_EBBRR, "EBBRR",
8128 &spr_read_ebb, &spr_write_ebb,
8129 &spr_read_generic, &spr_write_generic,
8130 KVM_REG_PPC_EBBRR, 0x00000000);
8131 spr_register_kvm(env, SPR_BESCR, "BESCR",
8132 &spr_read_ebb, &spr_write_ebb,
8133 &spr_read_generic, &spr_write_generic,
8134 KVM_REG_PPC_BESCR, 0x00000000);
8135}
8136
Cyril Bur3ba55e32015-03-02 17:55:38 +11008137/* Virtual Time Base */
8138static void gen_spr_vtb(CPUPPCState *env)
8139{
8140 spr_register(env, SPR_VTB, "VTB",
8141 SPR_NOACCESS, SPR_NOACCESS,
8142 &spr_read_tbl, SPR_NOACCESS,
8143 0x00000000);
8144}
8145
Alexey Kardashevskiy7019cb32014-06-04 22:50:56 +10008146static void gen_spr_power8_fscr(CPUPPCState *env)
8147{
Alexey Kardashevskiy45ed0be2014-06-04 22:50:57 +10008148#if defined(CONFIG_USER_ONLY)
8149 target_ulong initval = 1ULL << FSCR_TAR;
8150#else
8151 target_ulong initval = 0;
8152#endif
Alexey Kardashevskiy7019cb32014-06-04 22:50:56 +10008153 spr_register_kvm(env, SPR_FSCR, "FSCR",
8154 SPR_NOACCESS, SPR_NOACCESS,
8155 &spr_read_generic, &spr_write_generic,
Alexey Kardashevskiy45ed0be2014-06-04 22:50:57 +10008156 KVM_REG_PPC_FSCR, initval);
Alexey Kardashevskiy7019cb32014-06-04 22:50:56 +10008157}
8158
Thomas Huthd6f14452016-03-02 21:19:20 +01008159static void gen_spr_power8_pspb(CPUPPCState *env)
8160{
8161 spr_register_kvm(env, SPR_PSPB, "PSPB",
8162 SPR_NOACCESS, SPR_NOACCESS,
8163 &spr_read_generic, &spr_write_generic32,
8164 KVM_REG_PPC_PSPB, 0);
8165}
8166
Benjamin Herrenschmidt21a558b2016-03-21 13:52:35 +01008167static void gen_spr_power8_ic(CPUPPCState *env)
8168{
8169#if !defined(CONFIG_USER_ONLY)
8170 spr_register_hv(env, SPR_IC, "IC",
8171 SPR_NOACCESS, SPR_NOACCESS,
8172 &spr_read_generic, SPR_NOACCESS,
8173 &spr_read_generic, &spr_write_generic,
8174 0);
Cédric Le Goater9d0e5c82016-03-22 15:23:13 +01008175#endif
8176}
8177
8178static void gen_spr_power8_book4(CPUPPCState *env)
8179{
8180 /* Add a number of P8 book4 registers */
8181#if !defined(CONFIG_USER_ONLY)
Benjamin Herrenschmidt9c1cf382016-03-21 13:52:40 +01008182 spr_register_kvm(env, SPR_ACOP, "ACOP",
8183 SPR_NOACCESS, SPR_NOACCESS,
8184 &spr_read_generic, &spr_write_generic,
8185 KVM_REG_PPC_ACOP, 0);
8186 spr_register_kvm(env, SPR_BOOKS_PID, "PID",
8187 SPR_NOACCESS, SPR_NOACCESS,
8188 &spr_read_generic, &spr_write_generic,
8189 KVM_REG_PPC_PID, 0);
8190 spr_register_kvm(env, SPR_WORT, "WORT",
8191 SPR_NOACCESS, SPR_NOACCESS,
8192 &spr_read_generic, &spr_write_generic,
8193 KVM_REG_PPC_WORT, 0);
Benjamin Herrenschmidt21a558b2016-03-21 13:52:35 +01008194#endif
8195}
8196
Benjamin Herrenschmidt8eb0f562016-06-07 12:50:23 +10008197static void gen_spr_power7_book4(CPUPPCState *env)
8198{
8199 /* Add a number of P7 book4 registers */
8200#if !defined(CONFIG_USER_ONLY)
8201 spr_register_kvm(env, SPR_ACOP, "ACOP",
8202 SPR_NOACCESS, SPR_NOACCESS,
8203 &spr_read_generic, &spr_write_generic,
8204 KVM_REG_PPC_ACOP, 0);
8205 spr_register_kvm(env, SPR_BOOKS_PID, "PID",
8206 SPR_NOACCESS, SPR_NOACCESS,
8207 &spr_read_generic, &spr_write_generic,
8208 KVM_REG_PPC_PID, 0);
8209#endif
8210}
8211
Benjamin Herrenschmidt8eeb3302016-06-27 08:55:14 +02008212static void gen_spr_power8_rpr(CPUPPCState *env)
8213{
8214#if !defined(CONFIG_USER_ONLY)
8215 spr_register_hv(env, SPR_RPR, "RPR",
8216 SPR_NOACCESS, SPR_NOACCESS,
8217 SPR_NOACCESS, SPR_NOACCESS,
8218 &spr_read_generic, &spr_write_generic,
8219 0x00000103070F1F3F);
8220#endif
8221}
8222
Alexey Kardashevskiy7488d482014-06-04 22:50:45 +10008223static void init_proc_book3s_64(CPUPPCState *env, int version)
Alexey Kardashevskiy42382f62014-06-04 22:50:38 +10008224{
8225 gen_spr_ne_601(env);
Alexey Kardashevskiy42382f62014-06-04 22:50:38 +10008226 gen_tbl(env);
8227 gen_spr_book3s_altivec(env);
Alexey Kardashevskiyfd51ff62014-06-04 22:50:40 +10008228 gen_spr_book3s_pmu_sup(env);
8229 gen_spr_book3s_pmu_user(env);
Alexey Kardashevskiy42382f62014-06-04 22:50:38 +10008230 gen_spr_book3s_common(env);
Alexey Kardashevskiyfd51ff62014-06-04 22:50:40 +10008231
Alexey Kardashevskiya2428812014-06-04 22:50:54 +10008232 switch (version) {
8233 case BOOK3S_CPU_970:
8234 case BOOK3S_CPU_POWER5PLUS:
8235 gen_spr_970_hid(env);
8236 gen_spr_970_hior(env);
8237 gen_low_BATs(env);
8238 gen_spr_970_pmu_sup(env);
8239 gen_spr_970_pmu_user(env);
8240 break;
8241 case BOOK3S_CPU_POWER7:
8242 case BOOK3S_CPU_POWER8:
Aneesh Kumar K.V706d6462016-07-26 17:28:24 +05308243 case BOOK3S_CPU_POWER9:
Alexey Kardashevskiya2428812014-06-04 22:50:54 +10008244 gen_spr_book3s_ids(env);
Benjamin Herrenschmidta6eabb92016-03-21 13:52:38 +01008245 gen_spr_amr(env, version >= BOOK3S_CPU_POWER8);
Alexey Kardashevskiya2428812014-06-04 22:50:54 +10008246 gen_spr_book3s_purr(env);
Benjamin Herrenschmidt90da0d52015-10-22 18:30:59 +11008247 env->ci_large_pages = true;
Alexey Kardashevskiya2428812014-06-04 22:50:54 +10008248 break;
8249 default:
8250 g_assert_not_reached();
8251 }
Alexey Kardashevskiy7488d482014-06-04 22:50:45 +10008252 if (version >= BOOK3S_CPU_POWER5PLUS) {
Alexey Kardashevskiya2428812014-06-04 22:50:54 +10008253 gen_spr_power5p_common(env);
Alexey Kardashevskiy7488d482014-06-04 22:50:45 +10008254 gen_spr_power5p_lpar(env);
8255 gen_spr_power5p_ear(env);
8256 } else {
8257 gen_spr_970_lpar(env);
8258 }
Alexey Kardashevskiya2428812014-06-04 22:50:54 +10008259 if (version == BOOK3S_CPU_970) {
8260 gen_spr_970_dbg(env);
8261 }
8262 if (version >= BOOK3S_CPU_POWER6) {
8263 gen_spr_power6_common(env);
8264 gen_spr_power6_dbg(env);
8265 }
Benjamin Herrenschmidt8eb0f562016-06-07 12:50:23 +10008266 if (version == BOOK3S_CPU_POWER7) {
8267 gen_spr_power7_book4(env);
8268 }
Alexey Kardashevskiya2428812014-06-04 22:50:54 +10008269 if (version >= BOOK3S_CPU_POWER8) {
8270 gen_spr_power8_tce_address_control(env);
Alexey Kardashevskiyd1a721a2014-06-04 22:50:55 +10008271 gen_spr_power8_ids(env);
Alexey Kardashevskiy4ee4a032014-06-04 22:51:01 +10008272 gen_spr_power8_ebb(env);
Alexey Kardashevskiy7019cb32014-06-04 22:50:56 +10008273 gen_spr_power8_fscr(env);
Alexey Kardashevskiy70c53402014-06-04 22:50:58 +10008274 gen_spr_power8_pmu_sup(env);
8275 gen_spr_power8_pmu_user(env);
Alexey Kardashevskiycdcdda22014-06-04 22:50:59 +10008276 gen_spr_power8_tm(env);
Thomas Huthd6f14452016-03-02 21:19:20 +01008277 gen_spr_power8_pspb(env);
Cyril Bur3ba55e32015-03-02 17:55:38 +11008278 gen_spr_vtb(env);
Benjamin Herrenschmidt21a558b2016-03-21 13:52:35 +01008279 gen_spr_power8_ic(env);
Cédric Le Goater9d0e5c82016-03-22 15:23:13 +01008280 gen_spr_power8_book4(env);
Benjamin Herrenschmidt8eeb3302016-06-27 08:55:14 +02008281 gen_spr_power8_rpr(env);
Alexey Kardashevskiya2428812014-06-04 22:50:54 +10008282 }
Alexey Kardashevskiycd9adfd2014-06-04 22:51:03 +10008283 if (version < BOOK3S_CPU_POWER8) {
8284 gen_spr_book3s_dbg(env);
Benjamin Herrenschmidtf401dd32016-03-21 13:52:33 +01008285 } else {
8286 gen_spr_book3s_207_dbg(env);
Alexey Kardashevskiycd9adfd2014-06-04 22:51:03 +10008287 }
j_mayer12de9a32007-10-05 22:06:02 +00008288#if !defined(CONFIG_USER_ONLY)
Alexey Kardashevskiya2428812014-06-04 22:50:54 +10008289 switch (version) {
8290 case BOOK3S_CPU_970:
8291 case BOOK3S_CPU_POWER5PLUS:
8292 env->slb_nr = 64;
8293 break;
8294 case BOOK3S_CPU_POWER7:
8295 case BOOK3S_CPU_POWER8:
Aneesh Kumar K.V706d6462016-07-26 17:28:24 +05308296 case BOOK3S_CPU_POWER9:
Alexey Kardashevskiya2428812014-06-04 22:50:54 +10008297 default:
8298 env->slb_nr = 32;
8299 break;
8300 }
j_mayerf2e63a42007-10-07 15:43:50 +00008301#endif
Alexey Kardashevskiya2428812014-06-04 22:50:54 +10008302 /* Allocate hardware IRQ controller */
8303 switch (version) {
8304 case BOOK3S_CPU_970:
8305 case BOOK3S_CPU_POWER5PLUS:
8306 init_excp_970(env);
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01008307 ppc970_irq_init(ppc_env_get_cpu(env));
Alexey Kardashevskiya2428812014-06-04 22:50:54 +10008308 break;
8309 case BOOK3S_CPU_POWER7:
Alexey Kardashevskiya2428812014-06-04 22:50:54 +10008310 init_excp_POWER7(env);
Paolo Bonziniaa5a9e22016-03-15 14:32:19 +01008311 ppcPOWER7_irq_init(ppc_env_get_cpu(env));
Alexey Kardashevskiya2428812014-06-04 22:50:54 +10008312 break;
Benjamin Herrenschmidtf03a1af2016-06-21 23:48:49 +02008313 case BOOK3S_CPU_POWER8:
Aneesh Kumar K.V706d6462016-07-26 17:28:24 +05308314 case BOOK3S_CPU_POWER9:
Benjamin Herrenschmidtf03a1af2016-06-21 23:48:49 +02008315 init_excp_POWER8(env);
8316 ppcPOWER7_irq_init(ppc_env_get_cpu(env));
8317 break;
Alexey Kardashevskiya2428812014-06-04 22:50:54 +10008318 default:
8319 g_assert_not_reached();
8320 }
8321
j_mayerd63001d2007-10-04 00:51:58 +00008322 env->dcache_line_size = 128;
8323 env->icache_line_size = 128;
j_mayera750fc02007-09-26 23:54:22 +00008324}
j_mayera750fc02007-09-26 23:54:22 +00008325
Alexey Kardashevskiy7488d482014-06-04 22:50:45 +10008326static void init_proc_970(CPUPPCState *env)
8327{
8328 init_proc_book3s_64(env, BOOK3S_CPU_970);
8329}
8330
Andreas Färber7856e3a2013-02-17 23:16:42 +00008331POWERPC_FAMILY(970)(ObjectClass *oc, void *data)
8332{
Andreas Färberca5dff02013-02-17 23:16:46 +00008333 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00008334 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8335
Andreas Färberca5dff02013-02-17 23:16:46 +00008336 dc->desc = "PowerPC 970";
Andreas Färber7856e3a2013-02-17 23:16:42 +00008337 pcc->init_proc = init_proc_970;
8338 pcc->check_pow = check_pow_970;
Andreas Färber53116eb2013-02-17 23:16:43 +00008339 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
8340 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8341 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
8342 PPC_FLOAT_STFIWX |
8343 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8344 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8345 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
8346 PPC_64B | PPC_ALTIVEC |
8347 PPC_SEGMENT_64B | PPC_SLBI;
Pierre Mallard41718532014-09-12 21:31:32 +02008348 pcc->insns_flags2 = PPC2_FP_CVT_S64;
Tom Musta9df5a462014-04-15 12:21:12 -05008349 pcc->msr_mask = (1ull << MSR_SF) |
Tom Musta9df5a462014-04-15 12:21:12 -05008350 (1ull << MSR_VR) |
8351 (1ull << MSR_POW) |
8352 (1ull << MSR_EE) |
8353 (1ull << MSR_PR) |
8354 (1ull << MSR_FP) |
8355 (1ull << MSR_ME) |
8356 (1ull << MSR_FE0) |
8357 (1ull << MSR_SE) |
8358 (1ull << MSR_DE) |
8359 (1ull << MSR_FE1) |
8360 (1ull << MSR_IR) |
8361 (1ull << MSR_DR) |
8362 (1ull << MSR_PMM) |
8363 (1ull << MSR_RI);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00008364 pcc->mmu_model = POWERPC_MMU_64B;
David Gibsonb632a142013-03-13 11:40:33 +11008365#if defined(CONFIG_SOFTMMU)
8366 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
8367#endif
Andreas Färberba9fd9f2013-02-17 23:16:45 +00008368 pcc->excp_model = POWERPC_EXCP_970;
8369 pcc->bus_model = PPC_FLAGS_INPUT_970;
8370 pcc->bfd_mach = bfd_mach_ppc64;
8371 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8372 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8373 POWERPC_FLAG_BUS_CLK;
Alexander Graf06f6e122014-04-08 01:42:53 +02008374 pcc->l1_dcache_size = 0x8000;
8375 pcc->l1_icache_size = 0x10000;
Andreas Färber7856e3a2013-02-17 23:16:42 +00008376}
8377
Andreas Färber35ebcb22013-08-01 03:42:02 +02008378static void init_proc_power5plus(CPUPPCState *env)
8379{
Alexey Kardashevskiy7488d482014-06-04 22:50:45 +10008380 init_proc_book3s_64(env, BOOK3S_CPU_POWER5PLUS);
Andreas Färber35ebcb22013-08-01 03:42:02 +02008381}
8382
8383POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data)
8384{
8385 DeviceClass *dc = DEVICE_CLASS(oc);
8386 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8387
Andreas Färber793826c2013-10-15 18:33:36 +02008388 dc->fw_name = "PowerPC,POWER5";
Andreas Färber35ebcb22013-08-01 03:42:02 +02008389 dc->desc = "POWER5+";
8390 pcc->init_proc = init_proc_power5plus;
Alexey Kardashevskiy90618f42014-06-04 22:50:46 +10008391 pcc->check_pow = check_pow_970;
Andreas Färber35ebcb22013-08-01 03:42:02 +02008392 pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
8393 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8394 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
8395 PPC_FLOAT_STFIWX |
8396 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8397 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8398 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
8399 PPC_64B |
8400 PPC_SEGMENT_64B | PPC_SLBI;
Pierre Mallard41718532014-09-12 21:31:32 +02008401 pcc->insns_flags2 = PPC2_FP_CVT_S64;
Tom Musta9df5a462014-04-15 12:21:12 -05008402 pcc->msr_mask = (1ull << MSR_SF) |
8403 (1ull << MSR_VR) |
8404 (1ull << MSR_POW) |
8405 (1ull << MSR_EE) |
8406 (1ull << MSR_PR) |
8407 (1ull << MSR_FP) |
8408 (1ull << MSR_ME) |
8409 (1ull << MSR_FE0) |
8410 (1ull << MSR_SE) |
8411 (1ull << MSR_DE) |
8412 (1ull << MSR_FE1) |
8413 (1ull << MSR_IR) |
8414 (1ull << MSR_DR) |
8415 (1ull << MSR_PMM) |
8416 (1ull << MSR_RI);
Benjamin Herrenschmidtaa4bb582015-10-22 18:30:58 +11008417 pcc->mmu_model = POWERPC_MMU_2_03;
Andreas Färber35ebcb22013-08-01 03:42:02 +02008418#if defined(CONFIG_SOFTMMU)
8419 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
8420#endif
8421 pcc->excp_model = POWERPC_EXCP_970;
8422 pcc->bus_model = PPC_FLAGS_INPUT_970;
8423 pcc->bfd_mach = bfd_mach_ppc64;
8424 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8425 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8426 POWERPC_FLAG_BUS_CLK;
Alexander Graf06f6e122014-04-08 01:42:53 +02008427 pcc->l1_dcache_size = 0x8000;
8428 pcc->l1_icache_size = 0x10000;
Andreas Färber35ebcb22013-08-01 03:42:02 +02008429}
8430
Eric Blaked7bce992016-01-29 06:48:55 -07008431static void powerpc_get_compat(Object *obj, Visitor *v, const char *name,
8432 void *opaque, Error **errp)
Alexey Kardashevskiy8dfa3a52014-05-23 12:26:50 +10008433{
8434 char *value = (char *)"";
8435 Property *prop = opaque;
8436 uint32_t *max_compat = qdev_get_prop_ptr(DEVICE(obj), prop);
8437
8438 switch (*max_compat) {
8439 case CPU_POWERPC_LOGICAL_2_05:
8440 value = (char *)"power6";
8441 break;
8442 case CPU_POWERPC_LOGICAL_2_06:
8443 value = (char *)"power7";
8444 break;
8445 case CPU_POWERPC_LOGICAL_2_07:
8446 value = (char *)"power8";
8447 break;
8448 case 0:
8449 break;
8450 default:
Greg Kurzc4dfc142016-07-13 12:00:17 +02008451 error_report("Internal error: compat is set to %x", *max_compat);
8452 abort();
Alexey Kardashevskiy8dfa3a52014-05-23 12:26:50 +10008453 break;
8454 }
8455
Eric Blake51e72bc2016-01-29 06:48:54 -07008456 visit_type_str(v, name, &value, errp);
Alexey Kardashevskiy8dfa3a52014-05-23 12:26:50 +10008457}
8458
Eric Blaked7bce992016-01-29 06:48:55 -07008459static void powerpc_set_compat(Object *obj, Visitor *v, const char *name,
8460 void *opaque, Error **errp)
Alexey Kardashevskiy8dfa3a52014-05-23 12:26:50 +10008461{
8462 Error *error = NULL;
8463 char *value = NULL;
8464 Property *prop = opaque;
8465 uint32_t *max_compat = qdev_get_prop_ptr(DEVICE(obj), prop);
8466
Eric Blake51e72bc2016-01-29 06:48:54 -07008467 visit_type_str(v, name, &value, &error);
Alexey Kardashevskiy8dfa3a52014-05-23 12:26:50 +10008468 if (error) {
8469 error_propagate(errp, error);
8470 return;
8471 }
8472
8473 if (strcmp(value, "power6") == 0) {
8474 *max_compat = CPU_POWERPC_LOGICAL_2_05;
8475 } else if (strcmp(value, "power7") == 0) {
8476 *max_compat = CPU_POWERPC_LOGICAL_2_06;
8477 } else if (strcmp(value, "power8") == 0) {
8478 *max_compat = CPU_POWERPC_LOGICAL_2_07;
8479 } else {
8480 error_setg(errp, "Invalid compatibility mode \"%s\"", value);
8481 }
8482
8483 g_free(value);
8484}
8485
8486static PropertyInfo powerpc_compat_propinfo = {
8487 .name = "str",
Gonglei51b2e8c2014-10-07 14:33:20 +08008488 .description = "compatibility mode, power6/power7/power8",
Alexey Kardashevskiy8dfa3a52014-05-23 12:26:50 +10008489 .get = powerpc_get_compat,
8490 .set = powerpc_set_compat,
8491};
8492
8493#define DEFINE_PROP_POWERPC_COMPAT(_n, _s, _f) \
8494 DEFINE_PROP(_n, _s, _f, powerpc_compat_propinfo, uint32_t)
8495
8496static Property powerpc_servercpu_properties[] = {
8497 DEFINE_PROP_POWERPC_COMPAT("compat", PowerPCCPU, max_compat),
8498 DEFINE_PROP_END_OF_LIST(),
8499};
8500
David Gibsona8891fb2016-01-15 17:54:42 +11008501#ifdef CONFIG_SOFTMMU
8502static const struct ppc_segment_page_sizes POWER7_POWER8_sps = {
8503 .sps = {
8504 {
8505 .page_shift = 12, /* 4K */
8506 .slb_enc = 0,
8507 .enc = { { .page_shift = 12, .pte_enc = 0 },
8508 { .page_shift = 16, .pte_enc = 0x7 },
8509 { .page_shift = 24, .pte_enc = 0x38 }, },
8510 },
8511 {
8512 .page_shift = 16, /* 64K */
8513 .slb_enc = SLB_VSID_64K,
8514 .enc = { { .page_shift = 16, .pte_enc = 0x1 },
8515 { .page_shift = 24, .pte_enc = 0x8 }, },
8516 },
8517 {
8518 .page_shift = 24, /* 16M */
8519 .slb_enc = SLB_VSID_16M,
8520 .enc = { { .page_shift = 24, .pte_enc = 0 }, },
8521 },
8522 {
8523 .page_shift = 34, /* 16G */
8524 .slb_enc = SLB_VSID_16G,
8525 .enc = { { .page_shift = 34, .pte_enc = 0x3 }, },
8526 },
8527 }
8528};
8529#endif /* CONFIG_SOFTMMU */
8530
David Gibson9d52e902011-04-01 15:15:19 +11008531static void init_proc_POWER7 (CPUPPCState *env)
8532{
Alexey Kardashevskiya2428812014-06-04 22:50:54 +10008533 init_proc_book3s_64(env, BOOK3S_CPU_POWER7);
David Gibson9d52e902011-04-01 15:15:19 +11008534}
David Gibson9d52e902011-04-01 15:15:19 +11008535
Alexey Kardashevskiy03ae4132014-07-04 00:48:55 +10008536static bool ppc_pvr_match_power7(PowerPCCPUClass *pcc, uint32_t pvr)
8537{
8538 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7P_BASE) {
8539 return true;
8540 }
8541 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7_BASE) {
8542 return true;
8543 }
8544 return false;
8545}
8546
Benjamin Herrenschmidt7778a572016-06-21 23:48:55 +02008547static bool cpu_has_work_POWER7(CPUState *cs)
8548{
8549 PowerPCCPU *cpu = POWERPC_CPU(cs);
8550 CPUPPCState *env = &cpu->env;
8551
8552 if (cs->halted) {
8553 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
8554 return false;
8555 }
8556 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
8557 (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) {
8558 return true;
8559 }
8560 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
8561 (env->spr[SPR_LPCR] & LPCR_P7_PECE1)) {
8562 return true;
8563 }
8564 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
8565 (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
8566 return true;
8567 }
8568 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
8569 (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
8570 return true;
8571 }
8572 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
8573 return true;
8574 }
8575 return false;
8576 } else {
8577 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
8578 }
8579}
8580
Andreas Färber7856e3a2013-02-17 23:16:42 +00008581POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
8582{
Andreas Färberca5dff02013-02-17 23:16:46 +00008583 DeviceClass *dc = DEVICE_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00008584 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
Benjamin Herrenschmidt7778a572016-06-21 23:48:55 +02008585 CPUClass *cc = CPU_CLASS(oc);
Andreas Färber7856e3a2013-02-17 23:16:42 +00008586
Andreas Färber793826c2013-10-15 18:33:36 +02008587 dc->fw_name = "PowerPC,POWER7";
Andreas Färberca5dff02013-02-17 23:16:46 +00008588 dc->desc = "POWER7";
Alexey Kardashevskiy8dfa3a52014-05-23 12:26:50 +10008589 dc->props = powerpc_servercpu_properties;
Alexey Kardashevskiy03ae4132014-07-04 00:48:55 +10008590 pcc->pvr_match = ppc_pvr_match_power7;
Thomas Huth8cd2ce72016-06-07 17:39:37 +02008591 pcc->pcr_mask = PCR_VEC_DIS | PCR_VSX_DIS | PCR_COMPAT_2_05;
8592 pcc->pcr_supported = PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
Andreas Färber7856e3a2013-02-17 23:16:42 +00008593 pcc->init_proc = init_proc_POWER7;
8594 pcc->check_pow = check_pow_nocheck;
Benjamin Herrenschmidt7778a572016-06-21 23:48:55 +02008595 cc->has_work = cpu_has_work_POWER7;
Aurelien Jarnoe71ec2e2013-04-01 05:06:23 +00008596 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
Andreas Färber53116eb2013-02-17 23:16:43 +00008597 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8598 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
Tom Mustace8ca302014-01-07 10:06:09 -06008599 PPC_FLOAT_FRSQRTES |
Andreas Färber53116eb2013-02-17 23:16:43 +00008600 PPC_FLOAT_STFIWX |
Tom Mustac7386082014-01-07 10:06:05 -06008601 PPC_FLOAT_EXT |
Andreas Färber53116eb2013-02-17 23:16:43 +00008602 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8603 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8604 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
Benjamin Herrenschmidtdfdd3e42016-06-07 12:50:24 +10008605 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
Andreas Färber53116eb2013-02-17 23:16:43 +00008606 PPC_SEGMENT_64B | PPC_SLBI |
Benjamin Herrenschmidtb7815372016-06-21 23:48:52 +02008607 PPC_POPCNTB | PPC_POPCNTWD |
8608 PPC_CILDST;
Tom Musta86ba37e2014-01-07 10:05:49 -06008609 pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
Tom Musta1fa6c532014-01-07 10:05:55 -06008610 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
Tom Musta29a0e4e2014-01-07 10:06:06 -06008611 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
Benjamin Herrenschmidt7778a572016-06-21 23:48:55 +02008612 PPC2_FP_TST_ISA206 | PPC2_FP_CVT_S64 |
8613 PPC2_PM_ISA206;
Tom Musta9df5a462014-04-15 12:21:12 -05008614 pcc->msr_mask = (1ull << MSR_SF) |
8615 (1ull << MSR_VR) |
8616 (1ull << MSR_VSX) |
8617 (1ull << MSR_EE) |
8618 (1ull << MSR_PR) |
8619 (1ull << MSR_FP) |
8620 (1ull << MSR_ME) |
8621 (1ull << MSR_FE0) |
8622 (1ull << MSR_SE) |
8623 (1ull << MSR_DE) |
8624 (1ull << MSR_FE1) |
8625 (1ull << MSR_IR) |
8626 (1ull << MSR_DR) |
8627 (1ull << MSR_PMM) |
8628 (1ull << MSR_RI) |
8629 (1ull << MSR_LE);
Andreas Färberba9fd9f2013-02-17 23:16:45 +00008630 pcc->mmu_model = POWERPC_MMU_2_06;
David Gibsonb632a142013-03-13 11:40:33 +11008631#if defined(CONFIG_SOFTMMU)
8632 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
David Gibsona8891fb2016-01-15 17:54:42 +11008633 pcc->sps = &POWER7_POWER8_sps;
David Gibsonb632a142013-03-13 11:40:33 +11008634#endif
Andreas Färberba9fd9f2013-02-17 23:16:45 +00008635 pcc->excp_model = POWERPC_EXCP_POWER7;
8636 pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
8637 pcc->bfd_mach = bfd_mach_ppc64;
8638 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8639 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
Tom Musta74f23992013-10-22 22:05:46 +11008640 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
8641 POWERPC_FLAG_VSX;
David Gibson0cbad812013-04-07 19:08:19 +00008642 pcc->l1_dcache_size = 0x8000;
8643 pcc->l1_icache_size = 0x8000;
Greg Kurz382d2db2014-05-19 19:59:05 +02008644 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
Andreas Färber7856e3a2013-02-17 23:16:42 +00008645}
Prerna Saxena8d43ea12013-07-04 12:12:32 +05308646
Tom Musta60511042014-02-10 11:26:54 -06008647static void init_proc_POWER8(CPUPPCState *env)
8648{
Alexey Kardashevskiya2428812014-06-04 22:50:54 +10008649 init_proc_book3s_64(env, BOOK3S_CPU_POWER8);
Tom Musta60511042014-02-10 11:26:54 -06008650}
8651
Alexey Kardashevskiy03ae4132014-07-04 00:48:55 +10008652static bool ppc_pvr_match_power8(PowerPCCPUClass *pcc, uint32_t pvr)
8653{
Alexey Kardashevskiya88dced2016-03-03 11:08:19 +11008654 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8NVL_BASE) {
8655 return true;
8656 }
Alexey Kardashevskiy03ae4132014-07-04 00:48:55 +10008657 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8E_BASE) {
8658 return true;
8659 }
8660 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8_BASE) {
8661 return true;
8662 }
8663 return false;
8664}
8665
Benjamin Herrenschmidt7778a572016-06-21 23:48:55 +02008666static bool cpu_has_work_POWER8(CPUState *cs)
8667{
8668 PowerPCCPU *cpu = POWERPC_CPU(cs);
8669 CPUPPCState *env = &cpu->env;
8670
8671 if (cs->halted) {
8672 if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
8673 return false;
8674 }
8675 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
8676 (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) {
8677 return true;
8678 }
8679 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
8680 (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) {
8681 return true;
8682 }
8683 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
8684 (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
8685 return true;
8686 }
8687 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
8688 (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
8689 return true;
8690 }
8691 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
8692 (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) {
8693 return true;
8694 }
8695 if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
8696 (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) {
8697 return true;
8698 }
8699 if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
8700 return true;
8701 }
8702 return false;
8703 } else {
8704 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
8705 }
8706}
8707
Alexey Kardashevskiyb60c6002014-07-01 00:30:18 +10008708POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
Prerna Saxena8d43ea12013-07-04 12:12:32 +05308709{
8710 DeviceClass *dc = DEVICE_CLASS(oc);
8711 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
Benjamin Herrenschmidt7778a572016-06-21 23:48:55 +02008712 CPUClass *cc = CPU_CLASS(oc);
Prerna Saxena8d43ea12013-07-04 12:12:32 +05308713
Andreas Färber793826c2013-10-15 18:33:36 +02008714 dc->fw_name = "PowerPC,POWER8";
Alexey Kardashevskiyb60c6002014-07-01 00:30:18 +10008715 dc->desc = "POWER8";
Alexey Kardashevskiy8dfa3a52014-05-23 12:26:50 +10008716 dc->props = powerpc_servercpu_properties;
Alexey Kardashevskiy03ae4132014-07-04 00:48:55 +10008717 pcc->pvr_match = ppc_pvr_match_power8;
Thomas Huth8cd2ce72016-06-07 17:39:37 +02008718 pcc->pcr_mask = PCR_TM_DIS | PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
8719 pcc->pcr_supported = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
Tom Musta60511042014-02-10 11:26:54 -06008720 pcc->init_proc = init_proc_POWER8;
Prerna Saxena8d43ea12013-07-04 12:12:32 +05308721 pcc->check_pow = check_pow_nocheck;
Benjamin Herrenschmidt7778a572016-06-21 23:48:55 +02008722 cc->has_work = cpu_has_work_POWER8;
Anton Blanchard536492e2014-03-25 13:40:27 +11008723 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
Prerna Saxena8d43ea12013-07-04 12:12:32 +05308724 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8725 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
Tom Mustace8ca302014-01-07 10:06:09 -06008726 PPC_FLOAT_FRSQRTES |
Prerna Saxena8d43ea12013-07-04 12:12:32 +05308727 PPC_FLOAT_STFIWX |
Tom Mustac7386082014-01-07 10:06:05 -06008728 PPC_FLOAT_EXT |
Prerna Saxena8d43ea12013-07-04 12:12:32 +05308729 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8730 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8731 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
Benjamin Herrenschmidt4e080612016-05-03 18:03:34 +02008732 PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
Prerna Saxena8d43ea12013-07-04 12:12:32 +05308733 PPC_SEGMENT_64B | PPC_SLBI |
Benjamin Herrenschmidtb7815372016-06-21 23:48:52 +02008734 PPC_POPCNTB | PPC_POPCNTWD |
8735 PPC_CILDST;
Tom Musta86ba37e2014-01-07 10:05:49 -06008736 pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
Tom Musta1fa6c532014-01-07 10:05:55 -06008737 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
Tom Musta29a0e4e2014-01-07 10:06:06 -06008738 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
Tom Musta38a85332014-02-10 11:26:56 -06008739 PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
Alexey Kardashevskiydf99d302014-03-07 15:37:39 +11008740 PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
Tom Musta3e28c5e2014-12-18 10:34:32 -06008741 PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
Benjamin Herrenschmidt7778a572016-06-21 23:48:55 +02008742 PPC2_TM | PPC2_PM_ISA206;
Tom Musta9df5a462014-04-15 12:21:12 -05008743 pcc->msr_mask = (1ull << MSR_SF) |
Benjamin Herrenschmidt932ccbd2016-06-03 14:11:19 +02008744 (1ull << MSR_SHV) |
Alexey Kardashevskiycdcdda22014-06-04 22:50:59 +10008745 (1ull << MSR_TM) |
Tom Musta9df5a462014-04-15 12:21:12 -05008746 (1ull << MSR_VR) |
8747 (1ull << MSR_VSX) |
8748 (1ull << MSR_EE) |
8749 (1ull << MSR_PR) |
8750 (1ull << MSR_FP) |
8751 (1ull << MSR_ME) |
8752 (1ull << MSR_FE0) |
8753 (1ull << MSR_SE) |
8754 (1ull << MSR_DE) |
8755 (1ull << MSR_FE1) |
8756 (1ull << MSR_IR) |
8757 (1ull << MSR_DR) |
8758 (1ull << MSR_PMM) |
8759 (1ull << MSR_RI) |
8760 (1ull << MSR_LE);
Benjamin Herrenschmidtaa4bb582015-10-22 18:30:58 +11008761 pcc->mmu_model = POWERPC_MMU_2_07;
Prerna Saxena8d43ea12013-07-04 12:12:32 +05308762#if defined(CONFIG_SOFTMMU)
8763 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
David Gibsona8891fb2016-01-15 17:54:42 +11008764 pcc->sps = &POWER7_POWER8_sps;
Prerna Saxena8d43ea12013-07-04 12:12:32 +05308765#endif
Cédric Le Goater5c94b2a2016-04-03 19:57:50 +02008766 pcc->excp_model = POWERPC_EXCP_POWER8;
Prerna Saxena8d43ea12013-07-04 12:12:32 +05308767 pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
8768 pcc->bfd_mach = bfd_mach_ppc64;
8769 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8770 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
Tom Musta74f23992013-10-22 22:05:46 +11008771 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
Tom Musta3e28c5e2014-12-18 10:34:32 -06008772 POWERPC_FLAG_VSX | POWERPC_FLAG_TM;
Prerna Saxena8d43ea12013-07-04 12:12:32 +05308773 pcc->l1_dcache_size = 0x8000;
8774 pcc->l1_icache_size = 0x8000;
Greg Kurz382d2db2014-05-19 19:59:05 +02008775 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
Prerna Saxena8d43ea12013-07-04 12:12:32 +05308776}
Aneesh Kumar K.V706d6462016-07-26 17:28:24 +05308777static void init_proc_POWER9(CPUPPCState *env)
8778{
8779 init_proc_book3s_64(env, BOOK3S_CPU_POWER9);
8780}
8781
8782static bool ppc_pvr_match_power9(PowerPCCPUClass *pcc, uint32_t pvr)
8783{
8784 if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER9_BASE) {
8785 return true;
8786 }
8787 return false;
8788}
8789
8790POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
8791{
8792 DeviceClass *dc = DEVICE_CLASS(oc);
8793 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
8794
8795 dc->fw_name = "PowerPC,POWER9";
8796 dc->desc = "POWER9";
8797 dc->props = powerpc_servercpu_properties;
8798 pcc->pvr_match = ppc_pvr_match_power9;
8799 pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07;
8800 pcc->init_proc = init_proc_POWER9;
8801 pcc->check_pow = check_pow_nocheck;
8802 pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
8803 PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
8804 PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
8805 PPC_FLOAT_FRSQRTES |
8806 PPC_FLOAT_STFIWX |
8807 PPC_FLOAT_EXT |
8808 PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
8809 PPC_MEM_SYNC | PPC_MEM_EIEIO |
8810 PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
8811 PPC_64B | PPC_64BX | PPC_ALTIVEC |
8812 PPC_SEGMENT_64B | PPC_SLBI |
8813 PPC_POPCNTB | PPC_POPCNTWD |
8814 PPC_CILDST;
8815 pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
8816 PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
8817 PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
8818 PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
8819 PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
8820 PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |
Nikunj A Dadhaniaeb640b12016-07-26 17:28:25 +05308821 PPC2_TM | PPC2_PM_ISA206 | PPC2_ISA300;
Aneesh Kumar K.V706d6462016-07-26 17:28:24 +05308822 pcc->msr_mask = (1ull << MSR_SF) |
8823 (1ull << MSR_TM) |
8824 (1ull << MSR_VR) |
8825 (1ull << MSR_VSX) |
8826 (1ull << MSR_EE) |
8827 (1ull << MSR_PR) |
8828 (1ull << MSR_FP) |
8829 (1ull << MSR_ME) |
8830 (1ull << MSR_FE0) |
8831 (1ull << MSR_SE) |
8832 (1ull << MSR_DE) |
8833 (1ull << MSR_FE1) |
8834 (1ull << MSR_IR) |
8835 (1ull << MSR_DR) |
8836 (1ull << MSR_PMM) |
8837 (1ull << MSR_RI) |
8838 (1ull << MSR_LE);
8839 /* Using 2.07 defines until new radix model is added. */
8840 pcc->mmu_model = POWERPC_MMU_2_07;
8841#if defined(CONFIG_SOFTMMU)
8842 pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
8843 /* segment page size remain the same */
8844 pcc->sps = &POWER7_POWER8_sps;
8845#endif
8846 pcc->excp_model = POWERPC_EXCP_POWER8;
8847 pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
8848 pcc->bfd_mach = bfd_mach_ppc64;
8849 pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
8850 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
8851 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
8852 POWERPC_FLAG_VSX | POWERPC_FLAG_TM;
8853 pcc->l1_dcache_size = 0x8000;
8854 pcc->l1_icache_size = 0x8000;
8855 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
8856}
j_mayera750fc02007-09-26 23:54:22 +00008857
Benjamin Herrenschmidt26a7f122016-03-21 13:52:34 +01008858#if !defined(CONFIG_USER_ONLY)
8859
8860void cpu_ppc_set_papr(PowerPCCPU *cpu)
8861{
8862 CPUPPCState *env = &cpu->env;
Benjamin Herrenschmidt61687db2016-06-21 23:48:47 +02008863 ppc_spr_t *lpcr = &env->spr_cb[SPR_LPCR];
Benjamin Herrenschmidt6a9c4ef2016-03-21 13:52:36 +01008864 ppc_spr_t *amor = &env->spr_cb[SPR_AMOR];
Benjamin Herrenschmidt26a7f122016-03-21 13:52:34 +01008865
8866 /* PAPR always has exception vectors in RAM not ROM. To ensure this,
8867 * MSR[IP] should never be set.
8868 *
8869 * We also disallow setting of MSR_HV
8870 */
8871 env->msr_mask &= ~((1ull << MSR_EP) | MSR_HVB);
8872
Benjamin Herrenschmidt61687db2016-06-21 23:48:47 +02008873 /* Set emulated LPCR to not send interrupts to hypervisor. Note that
8874 * under KVM, the actual HW LPCR will be set differently by KVM itself,
8875 * the settings below ensure proper operations with TCG in absence of
Benjamin Herrenschmidt912acdf2016-07-05 07:37:08 +10008876 * a real hypervisor.
8877 *
8878 * Clearing VPM0 will also cause us to use RMOR in mmu-hash64.c for
8879 * real mode accesses, which thankfully defaults to 0 and isn't
8880 * accessible in guest mode.
Benjamin Herrenschmidt61687db2016-06-21 23:48:47 +02008881 */
8882 lpcr->default_value &= ~(LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV);
8883 lpcr->default_value |= LPCR_LPES0 | LPCR_LPES1;
8884
Benjamin Herrenschmidt912acdf2016-07-05 07:37:08 +10008885 /* Set RMLS to the max (ie, 16G) */
8886 lpcr->default_value &= ~LPCR_RMLS;
8887 lpcr->default_value |= 1ull << LPCR_RMLS_SHIFT;
8888
Benjamin Herrenschmidt7778a572016-06-21 23:48:55 +02008889 /* P7 and P8 has slightly different PECE bits, mostly because P8 adds
8890 * bit 47 and 48 which are reserved on P7. Here we set them all, which
8891 * will work as expected for both implementations
8892 */
8893 lpcr->default_value |= LPCR_P8_PECE0 | LPCR_P8_PECE1 | LPCR_P8_PECE2 |
8894 LPCR_P8_PECE3 | LPCR_P8_PECE4;
8895
Benjamin Herrenschmidt61687db2016-06-21 23:48:47 +02008896 /* We should be followed by a CPU reset but update the active value
8897 * just in case...
8898 */
8899 env->spr[SPR_LPCR] = lpcr->default_value;
8900
Benjamin Herrenschmidt6a9c4ef2016-03-21 13:52:36 +01008901 /* Set a full AMOR so guest can use the AMR as it sees fit */
8902 env->spr[SPR_AMOR] = amor->default_value = 0xffffffffffffffffull;
8903
Benjamin Herrenschmidt912acdf2016-07-05 07:37:08 +10008904 /* Update some env bits based on new LPCR value */
8905 ppc_hash64_update_rmls(env);
8906 ppc_hash64_update_vrma(env);
8907
Benjamin Herrenschmidt26a7f122016-03-21 13:52:34 +01008908 /* Tell KVM that we're in PAPR mode */
8909 if (kvm_enabled()) {
8910 kvmppc_set_papr(cpu);
8911 }
8912}
8913
8914#endif /* !defined(CONFIG_USER_ONLY) */
8915
8916#endif /* defined (TARGET_PPC64) */
Andreas Färberfd5ed412013-02-17 23:16:04 +00008917
j_mayera750fc02007-09-26 23:54:22 +00008918/*****************************************************************************/
Stefan Weil60b14d92011-04-28 17:20:36 +02008919/* Generic CPU instantiation routine */
Andreas Färbercfe34f42013-02-17 23:16:41 +00008920static void init_ppc_proc(PowerPCCPU *cpu)
bellard3fc6c082005-07-02 20:59:34 +00008921{
Andreas Färbercfe34f42013-02-17 23:16:41 +00008922 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
8923 CPUPPCState *env = &cpu->env;
j_mayera750fc02007-09-26 23:54:22 +00008924#if !defined(CONFIG_USER_ONLY)
j_mayere1833e12007-09-29 13:06:16 +00008925 int i;
8926
j_mayera750fc02007-09-26 23:54:22 +00008927 env->irq_inputs = NULL;
j_mayere1833e12007-09-29 13:06:16 +00008928 /* Set all exception vectors to an invalid address */
8929 for (i = 0; i < POWERPC_EXCP_NB; i++)
8930 env->excp_vectors[i] = (target_ulong)(-1ULL);
j_mayere1833e12007-09-29 13:06:16 +00008931 env->ivor_mask = 0x00000000;
8932 env->ivpr_mask = 0x00000000;
bellard3fc6c082005-07-02 20:59:34 +00008933 /* Default MMU definitions */
j_mayera750fc02007-09-26 23:54:22 +00008934 env->nb_BATs = 0;
bellard3fc6c082005-07-02 20:59:34 +00008935 env->nb_tlb = 0;
8936 env->nb_ways = 0;
Alexander Graf1c53acc2011-06-17 01:00:28 +02008937 env->tlb_type = TLB_NONE;
j_mayerf2e63a42007-10-07 15:43:50 +00008938#endif
j_mayera750fc02007-09-26 23:54:22 +00008939 /* Register SPR common to all PowerPC implementations */
8940 gen_spr_generic(env);
bellard3fc6c082005-07-02 20:59:34 +00008941 spr_register(env, SPR_PVR, "PVR",
Nathan Froyda139aa12009-06-04 18:45:03 -07008942 /* Linux permits userspace to read PVR */
8943#if defined(CONFIG_LINUX_USER)
8944 &spr_read_generic,
8945#else
8946 SPR_NOACCESS,
8947#endif
8948 SPR_NOACCESS,
bellard3fc6c082005-07-02 20:59:34 +00008949 &spr_read_generic, SPR_NOACCESS,
Andreas Färbercfe34f42013-02-17 23:16:41 +00008950 pcc->pvr);
j_mayer80d11f42007-11-17 23:02:20 +00008951 /* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
Andreas Färbercfe34f42013-02-17 23:16:41 +00008952 if (pcc->svr != POWERPC_SVR_NONE) {
8953 if (pcc->svr & POWERPC_SVR_E500) {
j_mayer80d11f42007-11-17 23:02:20 +00008954 spr_register(env, SPR_E500_SVR, "SVR",
8955 SPR_NOACCESS, SPR_NOACCESS,
8956 &spr_read_generic, SPR_NOACCESS,
Andreas Färbercfe34f42013-02-17 23:16:41 +00008957 pcc->svr & ~POWERPC_SVR_E500);
j_mayer80d11f42007-11-17 23:02:20 +00008958 } else {
8959 spr_register(env, SPR_SVR, "SVR",
8960 SPR_NOACCESS, SPR_NOACCESS,
8961 &spr_read_generic, SPR_NOACCESS,
Andreas Färbercfe34f42013-02-17 23:16:41 +00008962 pcc->svr);
j_mayer80d11f42007-11-17 23:02:20 +00008963 }
8964 }
j_mayera750fc02007-09-26 23:54:22 +00008965 /* PowerPC implementation specific initialisations (SPRs, timers, ...) */
Andreas Färbercfe34f42013-02-17 23:16:41 +00008966 (*pcc->init_proc)(env);
Fabien Chouteau2cf3eb62013-03-29 02:06:27 +00008967
j_mayer25ba3a62007-10-08 02:58:07 +00008968 /* MSR bits & flags consistency checks */
8969 if (env->msr_mask & (1 << 25)) {
8970 switch (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
8971 case POWERPC_FLAG_SPE:
8972 case POWERPC_FLAG_VRE:
8973 break;
8974 default:
8975 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
8976 "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n");
8977 exit(1);
8978 }
8979 } else if (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
8980 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
8981 "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n");
8982 exit(1);
8983 }
8984 if (env->msr_mask & (1 << 17)) {
8985 switch (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
8986 case POWERPC_FLAG_TGPR:
8987 case POWERPC_FLAG_CE:
8988 break;
8989 default:
8990 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
8991 "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n");
8992 exit(1);
8993 }
8994 } else if (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
8995 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
8996 "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n");
8997 exit(1);
8998 }
8999 if (env->msr_mask & (1 << 10)) {
9000 switch (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
9001 POWERPC_FLAG_UBLE)) {
9002 case POWERPC_FLAG_SE:
9003 case POWERPC_FLAG_DWE:
9004 case POWERPC_FLAG_UBLE:
9005 break;
9006 default:
9007 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9008 "Should define POWERPC_FLAG_SE or POWERPC_FLAG_DWE or "
9009 "POWERPC_FLAG_UBLE\n");
9010 exit(1);
9011 }
9012 } else if (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
9013 POWERPC_FLAG_UBLE)) {
9014 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9015 "Should not define POWERPC_FLAG_SE nor POWERPC_FLAG_DWE nor "
9016 "POWERPC_FLAG_UBLE\n");
9017 exit(1);
9018 }
9019 if (env->msr_mask & (1 << 9)) {
9020 switch (env->flags & (POWERPC_FLAG_BE | POWERPC_FLAG_DE)) {
9021 case POWERPC_FLAG_BE:
9022 case POWERPC_FLAG_DE:
9023 break;
9024 default:
9025 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9026 "Should define POWERPC_FLAG_BE or POWERPC_FLAG_DE\n");
9027 exit(1);
9028 }
9029 } else if (env->flags & (POWERPC_FLAG_BE | POWERPC_FLAG_DE)) {
9030 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9031 "Should not define POWERPC_FLAG_BE nor POWERPC_FLAG_DE\n");
9032 exit(1);
9033 }
9034 if (env->msr_mask & (1 << 2)) {
9035 switch (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
9036 case POWERPC_FLAG_PX:
9037 case POWERPC_FLAG_PMM:
9038 break;
9039 default:
9040 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9041 "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n");
9042 exit(1);
9043 }
9044 } else if (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
9045 fprintf(stderr, "PowerPC MSR definition inconsistency\n"
9046 "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n");
9047 exit(1);
9048 }
j_mayer4018bae2007-11-19 01:48:12 +00009049 if ((env->flags & (POWERPC_FLAG_RTC_CLK | POWERPC_FLAG_BUS_CLK)) == 0) {
9050 fprintf(stderr, "PowerPC flags inconsistency\n"
9051 "Should define the time-base and decrementer clock source\n");
9052 exit(1);
9053 }
j_mayer76a66252007-03-07 08:32:30 +00009054 /* Allocate TLBs buffer when needed */
j_mayerf2e63a42007-10-07 15:43:50 +00009055#if !defined(CONFIG_USER_ONLY)
j_mayer76a66252007-03-07 08:32:30 +00009056 if (env->nb_tlb != 0) {
9057 int nb_tlb = env->nb_tlb;
9058 if (env->id_tlbs != 0)
9059 nb_tlb *= 2;
Alexander Graf1c53acc2011-06-17 01:00:28 +02009060 switch (env->tlb_type) {
9061 case TLB_6XX:
Anthony Liguori7267c092011-08-20 22:09:37 -05009062 env->tlb.tlb6 = g_malloc0(nb_tlb * sizeof(ppc6xx_tlb_t));
Alexander Graf1c53acc2011-06-17 01:00:28 +02009063 break;
9064 case TLB_EMB:
Anthony Liguori7267c092011-08-20 22:09:37 -05009065 env->tlb.tlbe = g_malloc0(nb_tlb * sizeof(ppcemb_tlb_t));
Alexander Graf1c53acc2011-06-17 01:00:28 +02009066 break;
9067 case TLB_MAS:
Anthony Liguori7267c092011-08-20 22:09:37 -05009068 env->tlb.tlbm = g_malloc0(nb_tlb * sizeof(ppcmas_tlb_t));
Alexander Graf1c53acc2011-06-17 01:00:28 +02009069 break;
9070 }
j_mayer76a66252007-03-07 08:32:30 +00009071 /* Pre-compute some useful values */
9072 env->tlb_per_way = env->nb_tlb / env->nb_ways;
9073 }
j_mayera750fc02007-09-26 23:54:22 +00009074 if (env->irq_inputs == NULL) {
9075 fprintf(stderr, "WARNING: no internal IRQ controller registered.\n"
Stefan Weil5cbdb3a2012-04-07 09:23:39 +02009076 " Attempt QEMU to crash very soon !\n");
j_mayera750fc02007-09-26 23:54:22 +00009077 }
9078#endif
j_mayer2f462812007-10-25 23:14:50 +00009079 if (env->check_pow == NULL) {
9080 fprintf(stderr, "WARNING: no power management check handler "
9081 "registered.\n"
Stefan Weil5cbdb3a2012-04-07 09:23:39 +02009082 " Attempt QEMU to crash very soon !\n");
j_mayer2f462812007-10-25 23:14:50 +00009083 }
bellard3fc6c082005-07-02 20:59:34 +00009084}
9085
9086#if defined(PPC_DUMP_CPU)
j_mayera750fc02007-09-26 23:54:22 +00009087static void dump_ppc_sprs (CPUPPCState *env)
bellard3fc6c082005-07-02 20:59:34 +00009088{
9089 ppc_spr_t *spr;
j_mayera750fc02007-09-26 23:54:22 +00009090#if !defined(CONFIG_USER_ONLY)
9091 uint32_t sr, sw;
9092#endif
9093 uint32_t ur, uw;
bellard3fc6c082005-07-02 20:59:34 +00009094 int i, j, n;
9095
j_mayera750fc02007-09-26 23:54:22 +00009096 printf("Special purpose registers:\n");
bellard3fc6c082005-07-02 20:59:34 +00009097 for (i = 0; i < 32; i++) {
9098 for (j = 0; j < 32; j++) {
9099 n = (i << 5) | j;
9100 spr = &env->spr_cb[n];
j_mayera750fc02007-09-26 23:54:22 +00009101 uw = spr->uea_write != NULL && spr->uea_write != SPR_NOACCESS;
9102 ur = spr->uea_read != NULL && spr->uea_read != SPR_NOACCESS;
j_mayer76a66252007-03-07 08:32:30 +00009103#if !defined(CONFIG_USER_ONLY)
bellard3fc6c082005-07-02 20:59:34 +00009104 sw = spr->oea_write != NULL && spr->oea_write != SPR_NOACCESS;
9105 sr = spr->oea_read != NULL && spr->oea_read != SPR_NOACCESS;
bellard3fc6c082005-07-02 20:59:34 +00009106 if (sw || sr || uw || ur) {
j_mayer2662a052007-09-21 05:50:37 +00009107 printf("SPR: %4d (%03x) %-8s s%c%c u%c%c\n",
bellard3fc6c082005-07-02 20:59:34 +00009108 (i << 5) | j, (i << 5) | j, spr->name,
9109 sw ? 'w' : '-', sr ? 'r' : '-',
9110 uw ? 'w' : '-', ur ? 'r' : '-');
9111 }
j_mayera750fc02007-09-26 23:54:22 +00009112#else
9113 if (uw || ur) {
9114 printf("SPR: %4d (%03x) %-8s u%c%c\n",
9115 (i << 5) | j, (i << 5) | j, spr->name,
9116 uw ? 'w' : '-', ur ? 'r' : '-');
9117 }
9118#endif
bellard3fc6c082005-07-02 20:59:34 +00009119 }
9120 }
9121 fflush(stdout);
9122 fflush(stderr);
9123}
9124#endif
9125
9126/*****************************************************************************/
bellard3fc6c082005-07-02 20:59:34 +00009127
bellard3fc6c082005-07-02 20:59:34 +00009128/* Opcode types */
9129enum {
9130 PPC_DIRECT = 0, /* Opcode routine */
9131 PPC_INDIRECT = 1, /* Indirect opcode table */
9132};
9133
Bharata B Rao54ff58b2014-09-26 14:37:37 +05309134#define PPC_OPCODE_MASK 0x3
9135
bellard3fc6c082005-07-02 20:59:34 +00009136static inline int is_indirect_opcode (void *handler)
9137{
Bharata B Rao54ff58b2014-09-26 14:37:37 +05309138 return ((uintptr_t)handler & PPC_OPCODE_MASK) == PPC_INDIRECT;
bellard3fc6c082005-07-02 20:59:34 +00009139}
9140
Anthony Liguoric227f092009-10-01 16:12:16 -05009141static inline opc_handler_t **ind_table(void *handler)
bellard3fc6c082005-07-02 20:59:34 +00009142{
Bharata B Rao54ff58b2014-09-26 14:37:37 +05309143 return (opc_handler_t **)((uintptr_t)handler & ~PPC_OPCODE_MASK);
bellard3fc6c082005-07-02 20:59:34 +00009144}
9145
9146/* Instruction table creation */
9147/* Opcodes tables creation */
Anthony Liguoric227f092009-10-01 16:12:16 -05009148static void fill_new_table (opc_handler_t **table, int len)
bellard3fc6c082005-07-02 20:59:34 +00009149{
9150 int i;
9151
9152 for (i = 0; i < len; i++)
9153 table[i] = &invalid_handler;
9154}
9155
Anthony Liguoric227f092009-10-01 16:12:16 -05009156static int create_new_table (opc_handler_t **table, unsigned char idx)
bellard3fc6c082005-07-02 20:59:34 +00009157{
Anthony Liguoric227f092009-10-01 16:12:16 -05009158 opc_handler_t **tmp;
bellard3fc6c082005-07-02 20:59:34 +00009159
Bharata B Rao54ff58b2014-09-26 14:37:37 +05309160 tmp = g_new(opc_handler_t *, PPC_CPU_INDIRECT_OPCODES_LEN);
9161 fill_new_table(tmp, PPC_CPU_INDIRECT_OPCODES_LEN);
Stefan Weil57247532012-04-15 16:13:48 +02009162 table[idx] = (opc_handler_t *)((uintptr_t)tmp | PPC_INDIRECT);
bellard3fc6c082005-07-02 20:59:34 +00009163
9164 return 0;
9165}
9166
Anthony Liguoric227f092009-10-01 16:12:16 -05009167static int insert_in_table (opc_handler_t **table, unsigned char idx,
9168 opc_handler_t *handler)
bellard3fc6c082005-07-02 20:59:34 +00009169{
9170 if (table[idx] != &invalid_handler)
9171 return -1;
9172 table[idx] = handler;
9173
9174 return 0;
9175}
9176
Anthony Liguoric227f092009-10-01 16:12:16 -05009177static int register_direct_insn (opc_handler_t **ppc_opcodes,
9178 unsigned char idx, opc_handler_t *handler)
bellard3fc6c082005-07-02 20:59:34 +00009179{
9180 if (insert_in_table(ppc_opcodes, idx, handler) < 0) {
9181 printf("*** ERROR: opcode %02x already assigned in main "
j_mayer76a66252007-03-07 08:32:30 +00009182 "opcode table\n", idx);
j_mayer4c1b1bf2007-11-17 23:14:53 +00009183#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9184 printf(" Registered handler '%s' - new handler '%s'\n",
9185 ppc_opcodes[idx]->oname, handler->oname);
9186#endif
bellard3fc6c082005-07-02 20:59:34 +00009187 return -1;
9188 }
9189
9190 return 0;
9191}
9192
Anthony Liguoric227f092009-10-01 16:12:16 -05009193static int register_ind_in_table (opc_handler_t **table,
bellard3fc6c082005-07-02 20:59:34 +00009194 unsigned char idx1, unsigned char idx2,
Anthony Liguoric227f092009-10-01 16:12:16 -05009195 opc_handler_t *handler)
bellard3fc6c082005-07-02 20:59:34 +00009196{
9197 if (table[idx1] == &invalid_handler) {
9198 if (create_new_table(table, idx1) < 0) {
9199 printf("*** ERROR: unable to create indirect table "
j_mayer76a66252007-03-07 08:32:30 +00009200 "idx=%02x\n", idx1);
bellard3fc6c082005-07-02 20:59:34 +00009201 return -1;
9202 }
9203 } else {
9204 if (!is_indirect_opcode(table[idx1])) {
9205 printf("*** ERROR: idx %02x already assigned to a direct "
j_mayer76a66252007-03-07 08:32:30 +00009206 "opcode\n", idx1);
j_mayer4c1b1bf2007-11-17 23:14:53 +00009207#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9208 printf(" Registered handler '%s' - new handler '%s'\n",
9209 ind_table(table[idx1])[idx2]->oname, handler->oname);
9210#endif
bellard3fc6c082005-07-02 20:59:34 +00009211 return -1;
9212 }
9213 }
9214 if (handler != NULL &&
9215 insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) {
9216 printf("*** ERROR: opcode %02x already assigned in "
j_mayer76a66252007-03-07 08:32:30 +00009217 "opcode table %02x\n", idx2, idx1);
j_mayer4c1b1bf2007-11-17 23:14:53 +00009218#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
9219 printf(" Registered handler '%s' - new handler '%s'\n",
9220 ind_table(table[idx1])[idx2]->oname, handler->oname);
9221#endif
bellard3fc6c082005-07-02 20:59:34 +00009222 return -1;
9223 }
9224
9225 return 0;
9226}
9227
Anthony Liguoric227f092009-10-01 16:12:16 -05009228static int register_ind_insn (opc_handler_t **ppc_opcodes,
bellard3fc6c082005-07-02 20:59:34 +00009229 unsigned char idx1, unsigned char idx2,
Anthony Liguoric227f092009-10-01 16:12:16 -05009230 opc_handler_t *handler)
bellard3fc6c082005-07-02 20:59:34 +00009231{
Shraddha Barke74c373e2015-09-05 00:50:28 +05309232 return register_ind_in_table(ppc_opcodes, idx1, idx2, handler);
bellard3fc6c082005-07-02 20:59:34 +00009233}
9234
Anthony Liguoric227f092009-10-01 16:12:16 -05009235static int register_dblind_insn (opc_handler_t **ppc_opcodes,
bellard3fc6c082005-07-02 20:59:34 +00009236 unsigned char idx1, unsigned char idx2,
Anthony Liguoric227f092009-10-01 16:12:16 -05009237 unsigned char idx3, opc_handler_t *handler)
bellard3fc6c082005-07-02 20:59:34 +00009238{
9239 if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
9240 printf("*** ERROR: unable to join indirect table idx "
j_mayer76a66252007-03-07 08:32:30 +00009241 "[%02x-%02x]\n", idx1, idx2);
bellard3fc6c082005-07-02 20:59:34 +00009242 return -1;
9243 }
9244 if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3,
9245 handler) < 0) {
9246 printf("*** ERROR: unable to insert opcode "
j_mayer76a66252007-03-07 08:32:30 +00009247 "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
bellard3fc6c082005-07-02 20:59:34 +00009248 return -1;
9249 }
9250
9251 return 0;
9252}
9253
Nikunj A Dadhania323ad192016-07-26 17:28:38 +05309254static int register_trplind_insn(opc_handler_t **ppc_opcodes,
9255 unsigned char idx1, unsigned char idx2,
9256 unsigned char idx3, unsigned char idx4,
9257 opc_handler_t *handler)
9258{
9259 opc_handler_t **table;
9260
9261 if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
9262 printf("*** ERROR: unable to join indirect table idx "
9263 "[%02x-%02x]\n", idx1, idx2);
9264 return -1;
9265 }
9266 table = ind_table(ppc_opcodes[idx1]);
9267 if (register_ind_in_table(table, idx2, idx3, NULL) < 0) {
9268 printf("*** ERROR: unable to join 2nd-level indirect table idx "
9269 "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
9270 return -1;
9271 }
9272 table = ind_table(table[idx2]);
9273 if (register_ind_in_table(table, idx3, idx4, handler) < 0) {
9274 printf("*** ERROR: unable to insert opcode "
9275 "[%02x-%02x-%02x-%02x]\n", idx1, idx2, idx3, idx4);
9276 return -1;
9277 }
9278 return 0;
9279}
Anthony Liguoric227f092009-10-01 16:12:16 -05009280static int register_insn (opc_handler_t **ppc_opcodes, opcode_t *insn)
bellard3fc6c082005-07-02 20:59:34 +00009281{
9282 if (insn->opc2 != 0xFF) {
9283 if (insn->opc3 != 0xFF) {
Nikunj A Dadhania323ad192016-07-26 17:28:38 +05309284 if (insn->opc4 != 0xFF) {
9285 if (register_trplind_insn(ppc_opcodes, insn->opc1, insn->opc2,
9286 insn->opc3, insn->opc4,
9287 &insn->handler) < 0) {
9288 return -1;
9289 }
9290 } else {
9291 if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2,
9292 insn->opc3, &insn->handler) < 0)
9293 return -1;
9294 }
bellard3fc6c082005-07-02 20:59:34 +00009295 } else {
9296 if (register_ind_insn(ppc_opcodes, insn->opc1,
9297 insn->opc2, &insn->handler) < 0)
9298 return -1;
9299 }
9300 } else {
9301 if (register_direct_insn(ppc_opcodes, insn->opc1, &insn->handler) < 0)
9302 return -1;
9303 }
9304
9305 return 0;
9306}
9307
Anthony Liguoric227f092009-10-01 16:12:16 -05009308static int test_opcode_table (opc_handler_t **table, int len)
bellard3fc6c082005-07-02 20:59:34 +00009309{
9310 int i, count, tmp;
9311
9312 for (i = 0, count = 0; i < len; i++) {
9313 /* Consistency fixup */
9314 if (table[i] == NULL)
9315 table[i] = &invalid_handler;
9316 if (table[i] != &invalid_handler) {
9317 if (is_indirect_opcode(table[i])) {
Bharata B Rao54ff58b2014-09-26 14:37:37 +05309318 tmp = test_opcode_table(ind_table(table[i]),
9319 PPC_CPU_INDIRECT_OPCODES_LEN);
bellard3fc6c082005-07-02 20:59:34 +00009320 if (tmp == 0) {
9321 free(table[i]);
9322 table[i] = &invalid_handler;
9323 } else {
9324 count++;
9325 }
9326 } else {
9327 count++;
9328 }
9329 }
9330 }
9331
9332 return count;
9333}
9334
Anthony Liguoric227f092009-10-01 16:12:16 -05009335static void fix_opcode_tables (opc_handler_t **ppc_opcodes)
bellard3fc6c082005-07-02 20:59:34 +00009336{
Bharata B Rao54ff58b2014-09-26 14:37:37 +05309337 if (test_opcode_table(ppc_opcodes, PPC_CPU_OPCODES_LEN) == 0)
bellard3fc6c082005-07-02 20:59:34 +00009338 printf("*** WARNING: no opcode defined !\n");
9339}
9340
9341/*****************************************************************************/
Andreas Färber2985b862013-01-06 08:31:30 +00009342static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp)
bellard3fc6c082005-07-02 20:59:34 +00009343{
Andreas Färber2985b862013-01-06 08:31:30 +00009344 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
9345 CPUPPCState *env = &cpu->env;
Anthony Liguoric227f092009-10-01 16:12:16 -05009346 opcode_t *opc;
bellard3fc6c082005-07-02 20:59:34 +00009347
Bharata B Rao54ff58b2014-09-26 14:37:37 +05309348 fill_new_table(env->opcodes, PPC_CPU_OPCODES_LEN);
Blue Swirl5c55ff92009-06-17 15:22:31 +00009349 for (opc = opcodes; opc < &opcodes[ARRAY_SIZE(opcodes)]; opc++) {
Andreas Färbercfe34f42013-02-17 23:16:41 +00009350 if (((opc->handler.type & pcc->insns_flags) != 0) ||
9351 ((opc->handler.type2 & pcc->insns_flags2) != 0)) {
bellard3fc6c082005-07-02 20:59:34 +00009352 if (register_insn(env->opcodes, opc) < 0) {
Andreas Färber2985b862013-01-06 08:31:30 +00009353 error_setg(errp, "ERROR initializing PowerPC instruction "
Markus Armbruster312fd5f2013-02-08 21:22:16 +01009354 "0x%02x 0x%02x 0x%02x", opc->opc1, opc->opc2,
Andreas Färber2985b862013-01-06 08:31:30 +00009355 opc->opc3);
9356 return;
bellard3fc6c082005-07-02 20:59:34 +00009357 }
bellard3fc6c082005-07-02 20:59:34 +00009358 }
9359 }
Anthony Liguoric227f092009-10-01 16:12:16 -05009360 fix_opcode_tables(env->opcodes);
bellard3fc6c082005-07-02 20:59:34 +00009361 fflush(stdout);
9362 fflush(stderr);
bellard3fc6c082005-07-02 20:59:34 +00009363}
9364
j_mayera750fc02007-09-26 23:54:22 +00009365#if defined(PPC_DUMP_CPU)
j_mayer25ba3a62007-10-08 02:58:07 +00009366static void dump_ppc_insns (CPUPPCState *env)
j_mayera750fc02007-09-26 23:54:22 +00009367{
Anthony Liguoric227f092009-10-01 16:12:16 -05009368 opc_handler_t **table, *handler;
blueswir1b55266b2008-09-20 08:07:15 +00009369 const char *p, *q;
Nikunj A Dadhania323ad192016-07-26 17:28:38 +05309370 uint8_t opc1, opc2, opc3, opc4;
j_mayera750fc02007-09-26 23:54:22 +00009371
9372 printf("Instructions set:\n");
9373 /* opc1 is 6 bits long */
Bharata B Rao54ff58b2014-09-26 14:37:37 +05309374 for (opc1 = 0x00; opc1 < PPC_CPU_OPCODES_LEN; opc1++) {
j_mayera750fc02007-09-26 23:54:22 +00009375 table = env->opcodes;
9376 handler = table[opc1];
9377 if (is_indirect_opcode(handler)) {
9378 /* opc2 is 5 bits long */
Bharata B Rao54ff58b2014-09-26 14:37:37 +05309379 for (opc2 = 0; opc2 < PPC_CPU_INDIRECT_OPCODES_LEN; opc2++) {
j_mayera750fc02007-09-26 23:54:22 +00009380 table = env->opcodes;
9381 handler = env->opcodes[opc1];
9382 table = ind_table(handler);
9383 handler = table[opc2];
9384 if (is_indirect_opcode(handler)) {
9385 table = ind_table(handler);
9386 /* opc3 is 5 bits long */
Bharata B Rao54ff58b2014-09-26 14:37:37 +05309387 for (opc3 = 0; opc3 < PPC_CPU_INDIRECT_OPCODES_LEN;
9388 opc3++) {
j_mayera750fc02007-09-26 23:54:22 +00009389 handler = table[opc3];
Nikunj A Dadhania323ad192016-07-26 17:28:38 +05309390 if (is_indirect_opcode(handler)) {
9391 table = ind_table(handler);
9392 /* opc4 is 5 bits long */
9393 for (opc4 = 0; opc4 < PPC_CPU_INDIRECT_OPCODES_LEN;
9394 opc4++) {
9395 handler = table[opc4];
9396 if (handler->handler != &gen_invalid) {
9397 printf("INSN: %02x %02x %02x %02x -- "
9398 "(%02d %04d %02d) : %s\n",
9399 opc1, opc2, opc3, opc4,
9400 opc1, (opc3 << 5) | opc2, opc4,
j_mayer4c1b1bf2007-11-17 23:14:53 +00009401 handler->oname);
9402 }
Nikunj A Dadhania323ad192016-07-26 17:28:38 +05309403 }
9404 } else {
9405 if (handler->handler != &gen_invalid) {
9406 /* Special hack to properly dump SPE insns */
9407 p = strchr(handler->oname, '_');
9408 if (p == NULL) {
j_mayer4c1b1bf2007-11-17 23:14:53 +00009409 printf("INSN: %02x %02x %02x (%02d %04d) : "
9410 "%s\n",
Nikunj A Dadhania323ad192016-07-26 17:28:38 +05309411 opc1, opc2, opc3, opc1,
9412 (opc3 << 5) | opc2,
9413 handler->oname);
9414 } else {
9415 q = "speundef";
9416 if ((p - handler->oname) != strlen(q)
9417 || (memcmp(handler->oname, q, strlen(q))
9418 != 0)) {
9419 /* First instruction */
9420 printf("INSN: %02x %02x %02x"
9421 "(%02d %04d) : %.*s\n",
9422 opc1, opc2 << 1, opc3, opc1,
9423 (opc3 << 6) | (opc2 << 1),
9424 (int)(p - handler->oname),
9425 handler->oname);
9426 }
9427 if (strcmp(p + 1, q) != 0) {
9428 /* Second instruction */
9429 printf("INSN: %02x %02x %02x "
9430 "(%02d %04d) : %s\n", opc1,
9431 (opc2 << 1) | 1, opc3, opc1,
9432 (opc3 << 6) | (opc2 << 1) | 1,
9433 p + 1);
9434 }
j_mayer4c1b1bf2007-11-17 23:14:53 +00009435 }
9436 }
j_mayera750fc02007-09-26 23:54:22 +00009437 }
9438 }
9439 } else {
9440 if (handler->handler != &gen_invalid) {
9441 printf("INSN: %02x %02x -- (%02d %04d) : %s\n",
9442 opc1, opc2, opc1, opc2, handler->oname);
9443 }
9444 }
9445 }
9446 } else {
9447 if (handler->handler != &gen_invalid) {
9448 printf("INSN: %02x -- -- (%02d ----) : %s\n",
9449 opc1, opc1, handler->oname);
9450 }
9451 }
9452 }
9453}
9454#endif
9455
Greg Kurz87601e22016-01-15 16:00:31 +01009456static bool avr_need_swap(CPUPPCState *env)
9457{
9458#ifdef HOST_WORDS_BIGENDIAN
Greg Kurzea499e72016-01-15 16:00:38 +01009459 return msr_le;
Greg Kurz87601e22016-01-15 16:00:31 +01009460#else
Greg Kurzea499e72016-01-15 16:00:38 +01009461 return !msr_le;
Greg Kurz87601e22016-01-15 16:00:31 +01009462#endif
9463}
9464
Andreas Färber1328c2b2012-03-14 01:38:22 +01009465static int gdb_get_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
aurel3224951522009-01-24 15:08:00 +00009466{
9467 if (n < 32) {
9468 stfq_p(mem_buf, env->fpr[n]);
Greg Kurz385abeb2016-01-15 16:00:25 +01009469 ppc_maybe_bswap_register(env, mem_buf, 8);
aurel3224951522009-01-24 15:08:00 +00009470 return 8;
9471 }
9472 if (n == 32) {
Fabien Chouteau5a576fb2011-09-01 04:56:00 +00009473 stl_p(mem_buf, env->fpscr);
Greg Kurz385abeb2016-01-15 16:00:25 +01009474 ppc_maybe_bswap_register(env, mem_buf, 4);
aurel3224951522009-01-24 15:08:00 +00009475 return 4;
9476 }
9477 return 0;
9478}
9479
Andreas Färber1328c2b2012-03-14 01:38:22 +01009480static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
aurel3224951522009-01-24 15:08:00 +00009481{
9482 if (n < 32) {
Greg Kurz385abeb2016-01-15 16:00:25 +01009483 ppc_maybe_bswap_register(env, mem_buf, 8);
aurel3224951522009-01-24 15:08:00 +00009484 env->fpr[n] = ldfq_p(mem_buf);
9485 return 8;
9486 }
9487 if (n == 32) {
Greg Kurz385abeb2016-01-15 16:00:25 +01009488 ppc_maybe_bswap_register(env, mem_buf, 4);
Fabien Chouteaud6478bc2013-03-19 07:41:53 +00009489 helper_store_fpscr(env, ldl_p(mem_buf), 0xffffffff);
aurel3224951522009-01-24 15:08:00 +00009490 return 4;
9491 }
9492 return 0;
9493}
9494
Andreas Färber1328c2b2012-03-14 01:38:22 +01009495static int gdb_get_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
aurel32b4f8d822009-01-24 15:08:09 +00009496{
9497 if (n < 32) {
Greg Kurz87601e22016-01-15 16:00:31 +01009498 if (!avr_need_swap(env)) {
9499 stq_p(mem_buf, env->avr[n].u64[0]);
9500 stq_p(mem_buf+8, env->avr[n].u64[1]);
9501 } else {
9502 stq_p(mem_buf, env->avr[n].u64[1]);
9503 stq_p(mem_buf+8, env->avr[n].u64[0]);
9504 }
Greg Kurzea499e72016-01-15 16:00:38 +01009505 ppc_maybe_bswap_register(env, mem_buf, 8);
9506 ppc_maybe_bswap_register(env, mem_buf + 8, 8);
aurel32b4f8d822009-01-24 15:08:09 +00009507 return 16;
9508 }
aurel3270976a72009-03-07 22:00:49 +00009509 if (n == 32) {
aurel32b4f8d822009-01-24 15:08:09 +00009510 stl_p(mem_buf, env->vscr);
Greg Kurzea499e72016-01-15 16:00:38 +01009511 ppc_maybe_bswap_register(env, mem_buf, 4);
aurel32b4f8d822009-01-24 15:08:09 +00009512 return 4;
9513 }
aurel3270976a72009-03-07 22:00:49 +00009514 if (n == 33) {
aurel32b4f8d822009-01-24 15:08:09 +00009515 stl_p(mem_buf, (uint32_t)env->spr[SPR_VRSAVE]);
Greg Kurzea499e72016-01-15 16:00:38 +01009516 ppc_maybe_bswap_register(env, mem_buf, 4);
aurel32b4f8d822009-01-24 15:08:09 +00009517 return 4;
9518 }
9519 return 0;
9520}
9521
Andreas Färber1328c2b2012-03-14 01:38:22 +01009522static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
aurel32b4f8d822009-01-24 15:08:09 +00009523{
9524 if (n < 32) {
Greg Kurzea499e72016-01-15 16:00:38 +01009525 ppc_maybe_bswap_register(env, mem_buf, 8);
9526 ppc_maybe_bswap_register(env, mem_buf + 8, 8);
Greg Kurz87601e22016-01-15 16:00:31 +01009527 if (!avr_need_swap(env)) {
9528 env->avr[n].u64[0] = ldq_p(mem_buf);
9529 env->avr[n].u64[1] = ldq_p(mem_buf+8);
9530 } else {
9531 env->avr[n].u64[1] = ldq_p(mem_buf);
9532 env->avr[n].u64[0] = ldq_p(mem_buf+8);
9533 }
aurel32b4f8d822009-01-24 15:08:09 +00009534 return 16;
9535 }
aurel3270976a72009-03-07 22:00:49 +00009536 if (n == 32) {
Greg Kurzea499e72016-01-15 16:00:38 +01009537 ppc_maybe_bswap_register(env, mem_buf, 4);
aurel32b4f8d822009-01-24 15:08:09 +00009538 env->vscr = ldl_p(mem_buf);
9539 return 4;
9540 }
aurel3270976a72009-03-07 22:00:49 +00009541 if (n == 33) {
Greg Kurzea499e72016-01-15 16:00:38 +01009542 ppc_maybe_bswap_register(env, mem_buf, 4);
aurel32b4f8d822009-01-24 15:08:09 +00009543 env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf);
9544 return 4;
9545 }
9546 return 0;
9547}
9548
Andreas Färber1328c2b2012-03-14 01:38:22 +01009549static int gdb_get_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
aurel32688890f2009-01-24 15:08:17 +00009550{
9551 if (n < 32) {
9552#if defined(TARGET_PPC64)
9553 stl_p(mem_buf, env->gpr[n] >> 32);
Greg Kurz95f5b542016-01-15 16:00:44 +01009554 ppc_maybe_bswap_register(env, mem_buf, 4);
aurel32688890f2009-01-24 15:08:17 +00009555#else
9556 stl_p(mem_buf, env->gprh[n]);
9557#endif
9558 return 4;
9559 }
aurel3270976a72009-03-07 22:00:49 +00009560 if (n == 32) {
aurel32688890f2009-01-24 15:08:17 +00009561 stq_p(mem_buf, env->spe_acc);
Greg Kurz95f5b542016-01-15 16:00:44 +01009562 ppc_maybe_bswap_register(env, mem_buf, 8);
aurel32688890f2009-01-24 15:08:17 +00009563 return 8;
9564 }
aurel3270976a72009-03-07 22:00:49 +00009565 if (n == 33) {
aurel32d34defb2009-03-09 06:27:14 +00009566 stl_p(mem_buf, env->spe_fscr);
Greg Kurz95f5b542016-01-15 16:00:44 +01009567 ppc_maybe_bswap_register(env, mem_buf, 4);
aurel32688890f2009-01-24 15:08:17 +00009568 return 4;
9569 }
9570 return 0;
9571}
9572
Andreas Färber1328c2b2012-03-14 01:38:22 +01009573static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
aurel32688890f2009-01-24 15:08:17 +00009574{
9575 if (n < 32) {
9576#if defined(TARGET_PPC64)
9577 target_ulong lo = (uint32_t)env->gpr[n];
Greg Kurz95f5b542016-01-15 16:00:44 +01009578 target_ulong hi;
9579
9580 ppc_maybe_bswap_register(env, mem_buf, 4);
9581
9582 hi = (target_ulong)ldl_p(mem_buf) << 32;
aurel32688890f2009-01-24 15:08:17 +00009583 env->gpr[n] = lo | hi;
9584#else
9585 env->gprh[n] = ldl_p(mem_buf);
9586#endif
9587 return 4;
9588 }
aurel3270976a72009-03-07 22:00:49 +00009589 if (n == 32) {
Greg Kurz95f5b542016-01-15 16:00:44 +01009590 ppc_maybe_bswap_register(env, mem_buf, 8);
aurel32688890f2009-01-24 15:08:17 +00009591 env->spe_acc = ldq_p(mem_buf);
9592 return 8;
9593 }
aurel3270976a72009-03-07 22:00:49 +00009594 if (n == 33) {
Greg Kurz95f5b542016-01-15 16:00:44 +01009595 ppc_maybe_bswap_register(env, mem_buf, 4);
aurel32d34defb2009-03-09 06:27:14 +00009596 env->spe_fscr = ldl_p(mem_buf);
aurel32688890f2009-01-24 15:08:17 +00009597 return 4;
9598 }
9599 return 0;
9600}
9601
Anton Blanchard1438eff2016-01-15 16:00:51 +01009602static int gdb_get_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
9603{
9604 if (n < 32) {
9605 stq_p(mem_buf, env->vsr[n]);
9606 ppc_maybe_bswap_register(env, mem_buf, 8);
9607 return 8;
9608 }
9609 return 0;
9610}
9611
9612static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
9613{
9614 if (n < 32) {
9615 ppc_maybe_bswap_register(env, mem_buf, 8);
9616 env->vsr[n] = ldq_p(mem_buf);
9617 return 8;
9618 }
9619 return 0;
9620}
9621
Andreas Färber55e5c282012-12-17 06:18:02 +01009622static int ppc_fixup_cpu(PowerPCCPU *cpu)
David Gibson12b11432012-04-04 15:02:05 +10009623{
Andreas Färber55e5c282012-12-17 06:18:02 +01009624 CPUPPCState *env = &cpu->env;
9625
David Gibson12b11432012-04-04 15:02:05 +10009626 /* TCG doesn't (yet) emulate some groups of instructions that
9627 * are implemented on some otherwise supported CPUs (e.g. VSX
9628 * and decimal floating point instructions on POWER7). We
9629 * remove unsupported instruction groups from the cpu state's
9630 * instruction masks and hope the guest can cope. For at
9631 * least the pseries machine, the unavailability of these
9632 * instructions can be advertised to the guest via the device
9633 * tree. */
9634 if ((env->insns_flags & ~PPC_TCG_INSNS)
9635 || (env->insns_flags2 & ~PPC_TCG_INSNS2)) {
9636 fprintf(stderr, "Warning: Disabling some instructions which are not "
9637 "emulated by TCG (0x%" PRIx64 ", 0x%" PRIx64 ")\n",
9638 env->insns_flags & ~PPC_TCG_INSNS,
9639 env->insns_flags2 & ~PPC_TCG_INSNS2);
9640 }
9641 env->insns_flags &= PPC_TCG_INSNS;
9642 env->insns_flags2 &= PPC_TCG_INSNS2;
9643 return 0;
9644}
9645
Andreas Färber292363e2014-01-23 17:47:44 +01009646static inline bool ppc_cpu_is_valid(PowerPCCPUClass *pcc)
9647{
9648#ifdef TARGET_PPCEMB
9649 return pcc->mmu_model == POWERPC_MMU_BOOKE ||
9650 pcc->mmu_model == POWERPC_MMU_SOFT_4xx ||
9651 pcc->mmu_model == POWERPC_MMU_SOFT_4xx_Z;
9652#else
9653 return true;
9654#endif
9655}
9656
Andreas Färber4776ce62013-01-16 03:55:14 +01009657static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
bellard3fc6c082005-07-02 20:59:34 +00009658{
Andreas Färber22169d42013-06-28 21:27:39 +02009659 CPUState *cs = CPU(dev);
Andreas Färber4776ce62013-01-16 03:55:14 +01009660 PowerPCCPU *cpu = POWERPC_CPU(dev);
Andreas Färber2985b862013-01-06 08:31:30 +00009661 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
Andreas Färber2985b862013-01-06 08:31:30 +00009662 Error *local_err = NULL;
Mike Qiufe828a42013-01-23 17:20:38 +00009663#if !defined(CONFIG_USER_ONLY)
Greg Kurzc4e6c422016-07-02 00:41:32 +02009664 int max_smt = kvmppc_smt_threads();
Mike Qiufe828a42013-01-23 17:20:38 +00009665#endif
9666
9667#if !defined(CONFIG_USER_ONLY)
9668 if (smp_threads > max_smt) {
Andreas Färber5e95acc2013-02-17 23:16:01 +00009669 error_setg(errp, "Cannot support more than %d threads on PPC with %s",
9670 max_smt, kvm_enabled() ? "KVM" : "TCG");
9671 return;
Mike Qiufe828a42013-01-23 17:20:38 +00009672 }
Bharata B Rao5ec83c72014-03-05 14:02:36 +05309673 if (!is_power_of_2(smp_threads)) {
9674 error_setg(errp, "Cannot support %d threads on PPC with %s, "
9675 "threads count must be a power of 2.",
9676 smp_threads, kvm_enabled() ? "KVM" : "TCG");
9677 return;
9678 }
Bharata B Rao6dd0f832015-06-23 19:31:14 -07009679#endif
Alexey Kardashevskiy0ce470c2014-02-02 01:45:51 +11009680
Laurent Vivierce5b1bb2016-10-20 13:26:03 +02009681 cpu_exec_realizefn(cs, &local_err);
Bharata B Rao6dd0f832015-06-23 19:31:14 -07009682 if (local_err != NULL) {
9683 error_propagate(errp, local_err);
9684 return;
9685 }
9686
9687#if !defined(CONFIG_USER_ONLY)
Alexey Kardashevskiy0ce470c2014-02-02 01:45:51 +11009688 cpu->cpu_dt_id = (cs->cpu_index / smp_threads) * max_smt
9689 + (cs->cpu_index % smp_threads);
Greg Kurz41264b32016-04-26 15:41:04 +02009690
9691 if (kvm_enabled() && !kvm_vcpu_id_is_valid(cpu->cpu_dt_id)) {
9692 error_setg(errp, "Can't create CPU with id %d in KVM", cpu->cpu_dt_id);
9693 error_append_hint(errp, "Adjust the number of cpus to %d "
9694 "or try to raise the number of threads per core\n",
9695 cpu->cpu_dt_id * smp_threads / max_smt);
9696 return;
9697 }
Mike Qiufe828a42013-01-23 17:20:38 +00009698#endif
Benjamin Herrenschmidt4656e1f2012-06-18 19:56:25 +00009699
Alexey Kardashevskiy0ce470c2014-02-02 01:45:51 +11009700 if (tcg_enabled()) {
Andreas Färber55e5c282012-12-17 06:18:02 +01009701 if (ppc_fixup_cpu(cpu) != 0) {
Andreas Färber2985b862013-01-06 08:31:30 +00009702 error_setg(errp, "Unable to emulate selected CPU with TCG");
9703 return;
David Gibson12b11432012-04-04 15:02:05 +10009704 }
9705 }
9706
Andreas Färber4d7fb182013-02-17 23:16:44 +00009707#if defined(TARGET_PPCEMB)
Andreas Färber292363e2014-01-23 17:47:44 +01009708 if (!ppc_cpu_is_valid(pcc)) {
9709 error_setg(errp, "CPU does not possess a BookE or 4xx MMU. "
Andreas Färber4d7fb182013-02-17 23:16:44 +00009710 "Please use qemu-system-ppc or qemu-system-ppc64 instead "
9711 "or choose another CPU model.");
9712 return;
9713 }
9714#endif
9715
Andreas Färber2985b862013-01-06 08:31:30 +00009716 create_ppc_opcodes(cpu, &local_err);
9717 if (local_err != NULL) {
9718 error_propagate(errp, local_err);
9719 return;
9720 }
Andreas Färbercfe34f42013-02-17 23:16:41 +00009721 init_ppc_proc(cpu);
aurel3224951522009-01-24 15:08:00 +00009722
Andreas Färbercfe34f42013-02-17 23:16:41 +00009723 if (pcc->insns_flags & PPC_FLOAT) {
Andreas Färber22169d42013-06-28 21:27:39 +02009724 gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
aurel3224951522009-01-24 15:08:00 +00009725 33, "power-fpu.xml", 0);
9726 }
Andreas Färbercfe34f42013-02-17 23:16:41 +00009727 if (pcc->insns_flags & PPC_ALTIVEC) {
Andreas Färber22169d42013-06-28 21:27:39 +02009728 gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg,
aurel32b4f8d822009-01-24 15:08:09 +00009729 34, "power-altivec.xml", 0);
9730 }
Andreas Färbercfe34f42013-02-17 23:16:41 +00009731 if (pcc->insns_flags & PPC_SPE) {
Andreas Färber22169d42013-06-28 21:27:39 +02009732 gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
aurel32688890f2009-01-24 15:08:17 +00009733 34, "power-spe.xml", 0);
9734 }
Anton Blanchard1438eff2016-01-15 16:00:51 +01009735 if (pcc->insns_flags2 & PPC2_VSX) {
9736 gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg,
9737 32, "power-vsx.xml", 0);
9738 }
aurel32688890f2009-01-24 15:08:17 +00009739
Andreas Färber14a10fc2013-07-27 02:53:25 +02009740 qemu_init_vcpu(cs);
9741
Andreas Färber4776ce62013-01-16 03:55:14 +01009742 pcc->parent_realize(dev, errp);
9743
bellard3fc6c082005-07-02 20:59:34 +00009744#if defined(PPC_DUMP_CPU)
j_mayera750fc02007-09-26 23:54:22 +00009745 {
Andreas Färber22169d42013-06-28 21:27:39 +02009746 CPUPPCState *env = &cpu->env;
blueswir1b55266b2008-09-20 08:07:15 +00009747 const char *mmu_model, *excp_model, *bus_model;
j_mayera750fc02007-09-26 23:54:22 +00009748 switch (env->mmu_model) {
9749 case POWERPC_MMU_32B:
9750 mmu_model = "PowerPC 32";
9751 break;
j_mayera750fc02007-09-26 23:54:22 +00009752 case POWERPC_MMU_SOFT_6xx:
9753 mmu_model = "PowerPC 6xx/7xx with software driven TLBs";
9754 break;
9755 case POWERPC_MMU_SOFT_74xx:
9756 mmu_model = "PowerPC 74xx with software driven TLBs";
9757 break;
9758 case POWERPC_MMU_SOFT_4xx:
9759 mmu_model = "PowerPC 4xx with software driven TLBs";
9760 break;
9761 case POWERPC_MMU_SOFT_4xx_Z:
9762 mmu_model = "PowerPC 4xx with software driven TLBs "
9763 "and zones protections";
9764 break;
j_mayerb4095fe2007-11-17 22:42:36 +00009765 case POWERPC_MMU_REAL:
9766 mmu_model = "PowerPC real mode only";
9767 break;
9768 case POWERPC_MMU_MPC8xx:
9769 mmu_model = "PowerPC MPC8xx";
j_mayera750fc02007-09-26 23:54:22 +00009770 break;
9771 case POWERPC_MMU_BOOKE:
9772 mmu_model = "PowerPC BookE";
9773 break;
Alexander Graf01662f32011-04-30 23:34:58 +02009774 case POWERPC_MMU_BOOKE206:
9775 mmu_model = "PowerPC BookE 2.06";
j_mayera750fc02007-09-26 23:54:22 +00009776 break;
j_mayerb4095fe2007-11-17 22:42:36 +00009777 case POWERPC_MMU_601:
9778 mmu_model = "PowerPC 601";
9779 break;
j_mayer00af6852007-10-03 01:05:39 +00009780#if defined (TARGET_PPC64)
9781 case POWERPC_MMU_64B:
9782 mmu_model = "PowerPC 64";
9783 break;
j_mayer00af6852007-10-03 01:05:39 +00009784#endif
j_mayera750fc02007-09-26 23:54:22 +00009785 default:
9786 mmu_model = "Unknown or invalid";
9787 break;
9788 }
9789 switch (env->excp_model) {
9790 case POWERPC_EXCP_STD:
9791 excp_model = "PowerPC";
9792 break;
9793 case POWERPC_EXCP_40x:
9794 excp_model = "PowerPC 40x";
9795 break;
9796 case POWERPC_EXCP_601:
9797 excp_model = "PowerPC 601";
9798 break;
9799 case POWERPC_EXCP_602:
9800 excp_model = "PowerPC 602";
9801 break;
9802 case POWERPC_EXCP_603:
9803 excp_model = "PowerPC 603";
9804 break;
9805 case POWERPC_EXCP_603E:
9806 excp_model = "PowerPC 603e";
9807 break;
9808 case POWERPC_EXCP_604:
9809 excp_model = "PowerPC 604";
9810 break;
9811 case POWERPC_EXCP_7x0:
9812 excp_model = "PowerPC 740/750";
9813 break;
9814 case POWERPC_EXCP_7x5:
9815 excp_model = "PowerPC 745/755";
9816 break;
9817 case POWERPC_EXCP_74xx:
9818 excp_model = "PowerPC 74xx";
9819 break;
j_mayera750fc02007-09-26 23:54:22 +00009820 case POWERPC_EXCP_BOOKE:
9821 excp_model = "PowerPC BookE";
9822 break;
j_mayer00af6852007-10-03 01:05:39 +00009823#if defined (TARGET_PPC64)
9824 case POWERPC_EXCP_970:
9825 excp_model = "PowerPC 970";
9826 break;
9827#endif
j_mayera750fc02007-09-26 23:54:22 +00009828 default:
9829 excp_model = "Unknown or invalid";
9830 break;
9831 }
9832 switch (env->bus_model) {
9833 case PPC_FLAGS_INPUT_6xx:
9834 bus_model = "PowerPC 6xx";
9835 break;
9836 case PPC_FLAGS_INPUT_BookE:
9837 bus_model = "PowerPC BookE";
9838 break;
9839 case PPC_FLAGS_INPUT_405:
9840 bus_model = "PowerPC 405";
9841 break;
j_mayera750fc02007-09-26 23:54:22 +00009842 case PPC_FLAGS_INPUT_401:
9843 bus_model = "PowerPC 401/403";
9844 break;
j_mayerb4095fe2007-11-17 22:42:36 +00009845 case PPC_FLAGS_INPUT_RCPU:
9846 bus_model = "RCPU / MPC8xx";
9847 break;
j_mayer00af6852007-10-03 01:05:39 +00009848#if defined (TARGET_PPC64)
9849 case PPC_FLAGS_INPUT_970:
9850 bus_model = "PowerPC 970";
9851 break;
9852#endif
j_mayera750fc02007-09-26 23:54:22 +00009853 default:
9854 bus_model = "Unknown or invalid";
9855 break;
9856 }
9857 printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64 "\n"
9858 " MMU model : %s\n",
Alexey Kardashevskiya5100e72013-12-20 13:14:57 +11009859 object_class_get_name(OBJECT_CLASS(pcc)),
9860 pcc->pvr, pcc->msr_mask, mmu_model);
j_mayerf2e63a42007-10-07 15:43:50 +00009861#if !defined(CONFIG_USER_ONLY)
Alexey Kardashevskiya5100e72013-12-20 13:14:57 +11009862 if (env->tlb.tlb6) {
j_mayera750fc02007-09-26 23:54:22 +00009863 printf(" %d %s TLB in %d ways\n",
9864 env->nb_tlb, env->id_tlbs ? "splitted" : "merged",
9865 env->nb_ways);
9866 }
j_mayerf2e63a42007-10-07 15:43:50 +00009867#endif
j_mayera750fc02007-09-26 23:54:22 +00009868 printf(" Exceptions model : %s\n"
9869 " Bus model : %s\n",
9870 excp_model, bus_model);
j_mayer25ba3a62007-10-08 02:58:07 +00009871 printf(" MSR features :\n");
9872 if (env->flags & POWERPC_FLAG_SPE)
9873 printf(" signal processing engine enable"
9874 "\n");
9875 else if (env->flags & POWERPC_FLAG_VRE)
9876 printf(" vector processor enable\n");
9877 if (env->flags & POWERPC_FLAG_TGPR)
9878 printf(" temporary GPRs\n");
9879 else if (env->flags & POWERPC_FLAG_CE)
9880 printf(" critical input enable\n");
9881 if (env->flags & POWERPC_FLAG_SE)
9882 printf(" single-step trace mode\n");
9883 else if (env->flags & POWERPC_FLAG_DWE)
9884 printf(" debug wait enable\n");
9885 else if (env->flags & POWERPC_FLAG_UBLE)
9886 printf(" user BTB lock enable\n");
9887 if (env->flags & POWERPC_FLAG_BE)
9888 printf(" branch-step trace mode\n");
9889 else if (env->flags & POWERPC_FLAG_DE)
9890 printf(" debug interrupt enable\n");
9891 if (env->flags & POWERPC_FLAG_PX)
9892 printf(" inclusive protection\n");
9893 else if (env->flags & POWERPC_FLAG_PMM)
9894 printf(" performance monitor mark\n");
9895 if (env->flags == POWERPC_FLAG_NONE)
9896 printf(" none\n");
j_mayer4018bae2007-11-19 01:48:12 +00009897 printf(" Time-base/decrementer clock source: %s\n",
9898 env->flags & POWERPC_FLAG_RTC_CLK ? "RTC clock" : "bus clock");
Andreas Färber22169d42013-06-28 21:27:39 +02009899 dump_ppc_insns(env);
9900 dump_ppc_sprs(env);
9901 fflush(stdout);
j_mayer76a66252007-03-07 08:32:30 +00009902 }
bellard3fc6c082005-07-02 20:59:34 +00009903#endif
bellard3fc6c082005-07-02 20:59:34 +00009904}
9905
Andreas Färberb0489602013-06-09 22:11:49 +02009906static void ppc_cpu_unrealizefn(DeviceState *dev, Error **errp)
9907{
9908 PowerPCCPU *cpu = POWERPC_CPU(dev);
Laurent Vivier7bbc1242016-10-20 13:26:04 +02009909 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
Andreas Färberb0489602013-06-09 22:11:49 +02009910 CPUPPCState *env = &cpu->env;
Laurent Vivier7bbc1242016-10-20 13:26:04 +02009911 Error *local_err = NULL;
Nikunj A Dadhania323ad192016-07-26 17:28:38 +05309912 opc_handler_t **table, **table_2;
9913 int i, j, k;
Andreas Färberb0489602013-06-09 22:11:49 +02009914
Laurent Vivier7bbc1242016-10-20 13:26:04 +02009915 pcc->parent_unrealize(dev, &local_err);
9916 if (local_err != NULL) {
9917 error_propagate(errp, local_err);
9918 return;
9919 }
Bharata B Rao6dd0f832015-06-23 19:31:14 -07009920
Andreas Färberb0489602013-06-09 22:11:49 +02009921 for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) {
Bharata B Rao81f194d2014-09-26 14:37:38 +05309922 if (env->opcodes[i] == &invalid_handler) {
9923 continue;
9924 }
9925 if (is_indirect_opcode(env->opcodes[i])) {
9926 table = ind_table(env->opcodes[i]);
9927 for (j = 0; j < PPC_CPU_INDIRECT_OPCODES_LEN; j++) {
Nikunj A Dadhania323ad192016-07-26 17:28:38 +05309928 if (table[j] == &invalid_handler) {
9929 continue;
9930 }
9931 if (is_indirect_opcode(table[j])) {
9932 table_2 = ind_table(table[j]);
9933 for (k = 0; k < PPC_CPU_INDIRECT_OPCODES_LEN; k++) {
9934 if (table_2[k] != &invalid_handler &&
9935 is_indirect_opcode(table_2[k])) {
9936 g_free((opc_handler_t *)((uintptr_t)table_2[k] &
9937 ~PPC_INDIRECT));
9938 }
9939 }
Bharata B Rao81f194d2014-09-26 14:37:38 +05309940 g_free((opc_handler_t *)((uintptr_t)table[j] &
Nikunj A Dadhania323ad192016-07-26 17:28:38 +05309941 ~PPC_INDIRECT));
Bharata B Rao81f194d2014-09-26 14:37:38 +05309942 }
9943 }
9944 g_free((opc_handler_t *)((uintptr_t)env->opcodes[i] &
9945 ~PPC_INDIRECT));
Andreas Färberb0489602013-06-09 22:11:49 +02009946 }
9947 }
9948}
9949
Alexey Kardashevskiy2a48d992014-05-23 12:26:56 +10009950int ppc_get_compat_smt_threads(PowerPCCPU *cpu)
9951{
Marc-André Lureaueab60fb2016-09-16 19:50:24 +04009952 CPUState *cs = CPU(cpu);
9953 int ret = MIN(cs->nr_threads, kvmppc_smt_threads());
Alexey Kardashevskiy2a48d992014-05-23 12:26:56 +10009954
9955 switch (cpu->cpu_version) {
9956 case CPU_POWERPC_LOGICAL_2_05:
Alexey Kardashevskiy063cac52014-07-10 00:40:56 +10009957 ret = MIN(ret, 2);
Alexey Kardashevskiy2a48d992014-05-23 12:26:56 +10009958 break;
9959 case CPU_POWERPC_LOGICAL_2_06:
Alexey Kardashevskiy063cac52014-07-10 00:40:56 +10009960 ret = MIN(ret, 4);
Alexey Kardashevskiy2a48d992014-05-23 12:26:56 +10009961 break;
9962 case CPU_POWERPC_LOGICAL_2_07:
Alexey Kardashevskiy063cac52014-07-10 00:40:56 +10009963 ret = MIN(ret, 8);
Alexey Kardashevskiy2a48d992014-05-23 12:26:56 +10009964 break;
9965 }
9966
Alexey Kardashevskiy063cac52014-07-10 00:40:56 +10009967 return ret;
Alexey Kardashevskiy2a48d992014-05-23 12:26:56 +10009968}
9969
Thomas Hutheac4fba2016-06-07 17:39:39 +02009970#ifdef TARGET_PPC64
David Gibsonf9ab1e82016-01-20 12:58:07 +11009971void ppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version, Error **errp)
Alexey Kardashevskiy6d9412e2014-05-23 12:26:52 +10009972{
9973 int ret = 0;
9974 CPUPPCState *env = &cpu->env;
Thomas Hutheac4fba2016-06-07 17:39:39 +02009975 PowerPCCPUClass *host_pcc;
Alexey Kardashevskiy6d9412e2014-05-23 12:26:52 +10009976
9977 cpu->cpu_version = cpu_version;
9978
9979 switch (cpu_version) {
9980 case CPU_POWERPC_LOGICAL_2_05:
Thomas Hutheac4fba2016-06-07 17:39:39 +02009981 env->spr[SPR_PCR] = PCR_TM_DIS | PCR_VSX_DIS | PCR_COMPAT_2_07 |
9982 PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
Alexey Kardashevskiy6d9412e2014-05-23 12:26:52 +10009983 break;
9984 case CPU_POWERPC_LOGICAL_2_06:
Alexey Kardashevskiy6d9412e2014-05-23 12:26:52 +10009985 case CPU_POWERPC_LOGICAL_2_06_PLUS:
Thomas Hutheac4fba2016-06-07 17:39:39 +02009986 env->spr[SPR_PCR] = PCR_TM_DIS | PCR_COMPAT_2_07 | PCR_COMPAT_2_06;
Alexey Kardashevskiy6d9412e2014-05-23 12:26:52 +10009987 break;
Thomas Huthb30ff222016-06-07 17:39:40 +02009988 case CPU_POWERPC_LOGICAL_2_07:
9989 env->spr[SPR_PCR] = PCR_COMPAT_2_07;
9990 break;
Alexey Kardashevskiy6d9412e2014-05-23 12:26:52 +10009991 default:
9992 env->spr[SPR_PCR] = 0;
9993 break;
9994 }
9995
Thomas Hutheac4fba2016-06-07 17:39:39 +02009996 host_pcc = kvm_ppc_get_host_cpu_class();
9997 if (host_pcc) {
9998 env->spr[SPR_PCR] &= host_pcc->pcr_mask;
9999 }
10000
David Gibsonf9ab1e82016-01-20 12:58:07 +110010001 if (kvm_enabled()) {
10002 ret = kvmppc_set_compat(cpu, cpu->cpu_version);
10003 if (ret < 0) {
10004 error_setg_errno(errp, -ret,
10005 "Unable to set CPU compatibility mode in KVM");
10006 }
Alexey Kardashevskiy6db5bb02014-05-23 12:26:58 +100010007 }
Alexey Kardashevskiy6d9412e2014-05-23 12:26:52 +100010008}
Thomas Hutheac4fba2016-06-07 17:39:39 +020010009#endif
Alexey Kardashevskiy6d9412e2014-05-23 12:26:52 +100010010
Andreas Färber2985b862013-01-06 08:31:30 +000010011static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b)
Alexander Graff0ad8c32011-10-18 02:00:51 +020010012{
Andreas Färber2985b862013-01-06 08:31:30 +000010013 ObjectClass *oc = (ObjectClass *)a;
10014 uint32_t pvr = *(uint32_t *)b;
10015 PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
Alexander Graff0ad8c32011-10-18 02:00:51 +020010016
Andreas Färber2985b862013-01-06 08:31:30 +000010017 /* -cpu host does a PVR lookup during construction */
10018 if (unlikely(strcmp(object_class_get_name(oc),
10019 TYPE_HOST_POWERPC_CPU) == 0)) {
10020 return -1;
10021 }
10022
Andreas Färber292363e2014-01-23 17:47:44 +010010023 if (!ppc_cpu_is_valid(pcc)) {
Andreas Färber4d7fb182013-02-17 23:16:44 +000010024 return -1;
10025 }
Andreas Färber4d7fb182013-02-17 23:16:44 +000010026
Andreas Färbercfe34f42013-02-17 23:16:41 +000010027 return pcc->pvr == pvr ? 0 : -1;
Alexander Graff0ad8c32011-10-18 02:00:51 +020010028}
10029
Andreas Färber2985b862013-01-06 08:31:30 +000010030PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr)
j_mayeree4e83e2007-11-10 23:51:02 +000010031{
Andreas Färber2985b862013-01-06 08:31:30 +000010032 GSList *list, *item;
10033 PowerPCCPUClass *pcc = NULL;
j_mayeree4e83e2007-11-10 23:51:02 +000010034
Andreas Färber2985b862013-01-06 08:31:30 +000010035 list = object_class_get_list(TYPE_POWERPC_CPU, false);
10036 item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr);
10037 if (item != NULL) {
10038 pcc = POWERPC_CPU_CLASS(item->data);
j_mayeree4e83e2007-11-10 23:51:02 +000010039 }
Andreas Färber2985b862013-01-06 08:31:30 +000010040 g_slist_free(list);
j_mayeree4e83e2007-11-10 23:51:02 +000010041
Andreas Färber2985b862013-01-06 08:31:30 +000010042 return pcc;
10043}
10044
Alexey Kardashevskiy3bc9ccc2013-09-27 18:05:03 +100010045static gint ppc_cpu_compare_class_pvr_mask(gconstpointer a, gconstpointer b)
10046{
10047 ObjectClass *oc = (ObjectClass *)a;
10048 uint32_t pvr = *(uint32_t *)b;
10049 PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
Alexey Kardashevskiy3bc9ccc2013-09-27 18:05:03 +100010050
10051 /* -cpu host does a PVR lookup during construction */
10052 if (unlikely(strcmp(object_class_get_name(oc),
10053 TYPE_HOST_POWERPC_CPU) == 0)) {
10054 return -1;
10055 }
10056
Andreas Färber292363e2014-01-23 17:47:44 +010010057 if (!ppc_cpu_is_valid(pcc)) {
Alexey Kardashevskiy3bc9ccc2013-09-27 18:05:03 +100010058 return -1;
10059 }
Andreas Färber292363e2014-01-23 17:47:44 +010010060
Alexey Kardashevskiy03ae4132014-07-04 00:48:55 +100010061 if (pcc->pvr_match(pcc, pvr)) {
10062 return 0;
10063 }
Alexey Kardashevskiy3bc9ccc2013-09-27 18:05:03 +100010064
Alexey Kardashevskiy03ae4132014-07-04 00:48:55 +100010065 return -1;
Alexey Kardashevskiy3bc9ccc2013-09-27 18:05:03 +100010066}
10067
10068PowerPCCPUClass *ppc_cpu_class_by_pvr_mask(uint32_t pvr)
10069{
10070 GSList *list, *item;
10071 PowerPCCPUClass *pcc = NULL;
10072
10073 list = object_class_get_list(TYPE_POWERPC_CPU, true);
10074 item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr_mask);
10075 if (item != NULL) {
10076 pcc = POWERPC_CPU_CLASS(item->data);
10077 }
10078 g_slist_free(list);
10079
10080 return pcc;
10081}
10082
Andreas Färber2985b862013-01-06 08:31:30 +000010083static gint ppc_cpu_compare_class_name(gconstpointer a, gconstpointer b)
10084{
10085 ObjectClass *oc = (ObjectClass *)a;
10086 const char *name = b;
Andreas Färber4d7fb182013-02-17 23:16:44 +000010087 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
Andreas Färber2985b862013-01-06 08:31:30 +000010088
10089 if (strncasecmp(name, object_class_get_name(oc), strlen(name)) == 0 &&
Andreas Färber292363e2014-01-23 17:47:44 +010010090 ppc_cpu_is_valid(pcc) &&
Andreas Färber2985b862013-01-06 08:31:30 +000010091 strcmp(object_class_get_name(oc) + strlen(name),
10092 "-" TYPE_POWERPC_CPU) == 0) {
10093 return 0;
10094 }
10095 return -1;
j_mayeree4e83e2007-11-10 23:51:02 +000010096}
10097
j_mayeree4e83e2007-11-10 23:51:02 +000010098
Alexander Graf9761ad72013-06-22 03:53:35 +020010099static ObjectClass *ppc_cpu_class_by_name(const char *name);
10100
10101static ObjectClass *ppc_cpu_class_by_alias(PowerPCCPUAlias *alias)
10102{
10103 ObjectClass *invalid_class = (void*)ppc_cpu_class_by_alias;
10104
10105 /* Cache target class lookups in the alias table */
10106 if (!alias->oc) {
10107 alias->oc = ppc_cpu_class_by_name(alias->model);
10108 if (!alias->oc) {
10109 /* Fast check for non-existing aliases */
10110 alias->oc = invalid_class;
10111 }
10112 }
10113
10114 if (alias->oc == invalid_class) {
10115 return NULL;
10116 } else {
10117 return alias->oc;
10118 }
10119}
10120
Andreas Färber2985b862013-01-06 08:31:30 +000010121static ObjectClass *ppc_cpu_class_by_name(const char *name)
bellard3fc6c082005-07-02 20:59:34 +000010122{
Andreas Färber2985b862013-01-06 08:31:30 +000010123 GSList *list, *item;
10124 ObjectClass *ret = NULL;
blueswir1b55266b2008-09-20 08:07:15 +000010125 const char *p;
Andreas Färber2985b862013-01-06 08:31:30 +000010126 int i, len;
bellard3fc6c082005-07-02 20:59:34 +000010127
j_mayeree4e83e2007-11-10 23:51:02 +000010128 /* Check if the given name is a PVR */
10129 len = strlen(name);
10130 if (len == 10 && name[0] == '0' && name[1] == 'x') {
10131 p = name + 2;
10132 goto check_pvr;
10133 } else if (len == 8) {
10134 p = name;
10135 check_pvr:
10136 for (i = 0; i < 8; i++) {
blueswir1cd390082008-11-16 13:53:32 +000010137 if (!qemu_isxdigit(*p++))
j_mayeree4e83e2007-11-10 23:51:02 +000010138 break;
10139 }
Andreas Färber2985b862013-01-06 08:31:30 +000010140 if (i == 8) {
Shraddha Barke74c373e2015-09-05 00:50:28 +053010141 return OBJECT_CLASS(ppc_cpu_class_by_pvr(strtoul(name, NULL, 16)));
Alexander Graff0ad8c32011-10-18 02:00:51 +020010142 }
Andreas Färber2985b862013-01-06 08:31:30 +000010143 }
Alexander Graff0ad8c32011-10-18 02:00:51 +020010144
Andreas Färber2985b862013-01-06 08:31:30 +000010145 list = object_class_get_list(TYPE_POWERPC_CPU, false);
10146 item = g_slist_find_custom(list, name, ppc_cpu_compare_class_name);
10147 if (item != NULL) {
10148 ret = OBJECT_CLASS(item->data);
bellard3fc6c082005-07-02 20:59:34 +000010149 }
Andreas Färber2985b862013-01-06 08:31:30 +000010150 g_slist_free(list);
bellard3fc6c082005-07-02 20:59:34 +000010151
Alexey Kardashevskiyfdf8a962014-04-12 03:34:26 +100010152 if (ret) {
10153 return ret;
10154 }
10155
10156 for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
10157 if (strcmp(ppc_cpu_aliases[i].alias, name) == 0) {
10158 return ppc_cpu_class_by_alias(&ppc_cpu_aliases[i]);
10159 }
10160 }
10161
10162 return NULL;
bellard3fc6c082005-07-02 20:59:34 +000010163}
10164
Thomas Huthcaf63162016-08-09 18:59:58 +020010165const char *ppc_cpu_lookup_alias(const char *alias)
10166{
10167 int ai;
10168
10169 for (ai = 0; ppc_cpu_aliases[ai].alias != NULL; ai++) {
10170 if (strcmp(ppc_cpu_aliases[ai].alias, alias) == 0) {
10171 return ppc_cpu_aliases[ai].model;
10172 }
10173 }
10174
10175 return NULL;
10176}
10177
Andreas Färber2985b862013-01-06 08:31:30 +000010178PowerPCCPU *cpu_ppc_init(const char *cpu_model)
bellard3fc6c082005-07-02 20:59:34 +000010179{
Andreas Färber92626852014-03-04 03:17:10 +010010180 return POWERPC_CPU(cpu_generic_init(TYPE_POWERPC_CPU, cpu_model));
Andreas Färber2985b862013-01-06 08:31:30 +000010181}
10182
10183/* Sort by PVR, ordering special case "host" last. */
10184static gint ppc_cpu_list_compare(gconstpointer a, gconstpointer b)
10185{
10186 ObjectClass *oc_a = (ObjectClass *)a;
10187 ObjectClass *oc_b = (ObjectClass *)b;
10188 PowerPCCPUClass *pcc_a = POWERPC_CPU_CLASS(oc_a);
10189 PowerPCCPUClass *pcc_b = POWERPC_CPU_CLASS(oc_b);
10190 const char *name_a = object_class_get_name(oc_a);
10191 const char *name_b = object_class_get_name(oc_b);
10192
10193 if (strcmp(name_a, TYPE_HOST_POWERPC_CPU) == 0) {
10194 return 1;
10195 } else if (strcmp(name_b, TYPE_HOST_POWERPC_CPU) == 0) {
10196 return -1;
10197 } else {
10198 /* Avoid an integer overflow during subtraction */
Andreas Färbercfe34f42013-02-17 23:16:41 +000010199 if (pcc_a->pvr < pcc_b->pvr) {
Andreas Färber2985b862013-01-06 08:31:30 +000010200 return -1;
Andreas Färbercfe34f42013-02-17 23:16:41 +000010201 } else if (pcc_a->pvr > pcc_b->pvr) {
Andreas Färber2985b862013-01-06 08:31:30 +000010202 return 1;
10203 } else {
10204 return 0;
10205 }
10206 }
10207}
10208
10209static void ppc_cpu_list_entry(gpointer data, gpointer user_data)
10210{
10211 ObjectClass *oc = data;
10212 CPUListState *s = user_data;
10213 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
Andreas Färberde400122013-02-17 23:16:40 +000010214 const char *typename = object_class_get_name(oc);
10215 char *name;
Andreas Färber55d3d1a2013-02-23 07:34:28 +000010216 int i;
Andreas Färber2985b862013-01-06 08:31:30 +000010217
Andreas Färber292363e2014-01-23 17:47:44 +010010218 if (!ppc_cpu_is_valid(pcc)) {
Andreas Färber4d7fb182013-02-17 23:16:44 +000010219 return;
10220 }
Andreas Färber5ba45762013-02-23 11:22:12 +000010221 if (unlikely(strcmp(typename, TYPE_HOST_POWERPC_CPU) == 0)) {
10222 return;
10223 }
Andreas Färber4d7fb182013-02-17 23:16:44 +000010224
Andreas Färberde400122013-02-17 23:16:40 +000010225 name = g_strndup(typename,
10226 strlen(typename) - strlen("-" TYPE_POWERPC_CPU));
Andreas Färber2985b862013-01-06 08:31:30 +000010227 (*s->cpu_fprintf)(s->file, "PowerPC %-16s PVR %08x\n",
Andreas Färbercfe34f42013-02-17 23:16:41 +000010228 name, pcc->pvr);
Andreas Färbere9a96072013-02-25 03:43:17 +000010229 for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
Alexander Graf9761ad72013-06-22 03:53:35 +020010230 PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
10231 ObjectClass *alias_oc = ppc_cpu_class_by_alias(alias);
Andreas Färber55d3d1a2013-02-23 07:34:28 +000010232
10233 if (alias_oc != oc) {
10234 continue;
10235 }
10236 (*s->cpu_fprintf)(s->file, "PowerPC %-16s (alias for %s)\n",
10237 alias->alias, name);
10238 }
Andreas Färberde400122013-02-17 23:16:40 +000010239 g_free(name);
Andreas Färber2985b862013-01-06 08:31:30 +000010240}
10241
10242void ppc_cpu_list(FILE *f, fprintf_function cpu_fprintf)
10243{
10244 CPUListState s = {
10245 .file = f,
10246 .cpu_fprintf = cpu_fprintf,
10247 };
10248 GSList *list;
10249
10250 list = object_class_get_list(TYPE_POWERPC_CPU, false);
10251 list = g_slist_sort(list, ppc_cpu_list_compare);
10252 g_slist_foreach(list, ppc_cpu_list_entry, &s);
10253 g_slist_free(list);
Andreas Färberfd5ed412013-02-17 23:16:04 +000010254
Andreas Färber5ba45762013-02-23 11:22:12 +000010255#ifdef CONFIG_KVM
10256 cpu_fprintf(f, "\n");
10257 cpu_fprintf(f, "PowerPC %-16s\n", "host");
10258#endif
Andreas Färber2985b862013-01-06 08:31:30 +000010259}
10260
10261static void ppc_cpu_defs_entry(gpointer data, gpointer user_data)
10262{
10263 ObjectClass *oc = data;
10264 CpuDefinitionInfoList **first = user_data;
Andreas Färberde400122013-02-17 23:16:40 +000010265 const char *typename;
Andreas Färber2985b862013-01-06 08:31:30 +000010266 CpuDefinitionInfoList *entry;
10267 CpuDefinitionInfo *info;
Andreas Färber4d7fb182013-02-17 23:16:44 +000010268 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
10269
Andreas Färber292363e2014-01-23 17:47:44 +010010270 if (!ppc_cpu_is_valid(pcc)) {
Andreas Färber4d7fb182013-02-17 23:16:44 +000010271 return;
10272 }
Andreas Färber2985b862013-01-06 08:31:30 +000010273
Andreas Färberde400122013-02-17 23:16:40 +000010274 typename = object_class_get_name(oc);
Andreas Färber2985b862013-01-06 08:31:30 +000010275 info = g_malloc0(sizeof(*info));
Andreas Färberde400122013-02-17 23:16:40 +000010276 info->name = g_strndup(typename,
10277 strlen(typename) - strlen("-" TYPE_POWERPC_CPU));
Andreas Färber2985b862013-01-06 08:31:30 +000010278
10279 entry = g_malloc0(sizeof(*entry));
10280 entry->value = info;
10281 entry->next = *first;
10282 *first = entry;
bellard3fc6c082005-07-02 20:59:34 +000010283}
Andreas Färber1d0cb672012-04-06 14:39:03 +020010284
Anthony Liguori76b64a72012-08-14 22:17:36 -050010285CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
Anthony Liguori70b76602012-08-10 11:04:15 -050010286{
10287 CpuDefinitionInfoList *cpu_list = NULL;
Andreas Färber2985b862013-01-06 08:31:30 +000010288 GSList *list;
Andreas Färber35e21d32013-02-23 07:52:24 +000010289 int i;
Anthony Liguori70b76602012-08-10 11:04:15 -050010290
Andreas Färber2985b862013-01-06 08:31:30 +000010291 list = object_class_get_list(TYPE_POWERPC_CPU, false);
10292 g_slist_foreach(list, ppc_cpu_defs_entry, &cpu_list);
10293 g_slist_free(list);
Anthony Liguori70b76602012-08-10 11:04:15 -050010294
Andreas Färbere9a96072013-02-25 03:43:17 +000010295 for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
Alexander Graf9761ad72013-06-22 03:53:35 +020010296 PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
Andreas Färber35e21d32013-02-23 07:52:24 +000010297 ObjectClass *oc;
10298 CpuDefinitionInfoList *entry;
10299 CpuDefinitionInfo *info;
10300
Alexander Graf9761ad72013-06-22 03:53:35 +020010301 oc = ppc_cpu_class_by_alias(alias);
Andreas Färber35e21d32013-02-23 07:52:24 +000010302 if (oc == NULL) {
10303 continue;
10304 }
10305
10306 info = g_malloc0(sizeof(*info));
10307 info->name = g_strdup(alias->alias);
10308
10309 entry = g_malloc0(sizeof(*entry));
10310 entry->value = info;
10311 entry->next = cpu_list;
10312 cpu_list = entry;
10313 }
10314
Anthony Liguori70b76602012-08-10 11:04:15 -050010315 return cpu_list;
10316}
10317
Andreas Färberf45748f2013-06-21 19:09:18 +020010318static void ppc_cpu_set_pc(CPUState *cs, vaddr value)
10319{
10320 PowerPCCPU *cpu = POWERPC_CPU(cs);
10321
10322 cpu->env.nip = value;
10323}
10324
Andreas Färber8c2e1b02013-08-25 18:53:55 +020010325static bool ppc_cpu_has_work(CPUState *cs)
10326{
10327 PowerPCCPU *cpu = POWERPC_CPU(cs);
10328 CPUPPCState *env = &cpu->env;
10329
10330 return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
10331}
10332
Richard Henderson774f0ab2014-09-13 09:45:16 -070010333static void ppc_cpu_exec_enter(CPUState *cs)
10334{
10335 PowerPCCPU *cpu = POWERPC_CPU(cs);
10336 CPUPPCState *env = &cpu->env;
10337
10338 env->reserve_addr = -1;
10339}
10340
Andreas Färber1d0cb672012-04-06 14:39:03 +020010341/* CPUClass::reset() */
10342static void ppc_cpu_reset(CPUState *s)
10343{
10344 PowerPCCPU *cpu = POWERPC_CPU(s);
10345 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
10346 CPUPPCState *env = &cpu->env;
Andreas Färbera1389542012-04-06 15:35:34 +020010347 target_ulong msr;
Alexey Kardashevskiyd197fdb2014-03-20 00:03:57 +110010348 int i;
Andreas Färbera1389542012-04-06 15:35:34 +020010349
Andreas Färber1d0cb672012-04-06 14:39:03 +020010350 pcc->parent_reset(s);
10351
Andreas Färbera1389542012-04-06 15:35:34 +020010352 msr = (target_ulong)0;
Benjamin Herrenschmidt932ccbd2016-06-03 14:11:19 +020010353 msr |= (target_ulong)MSR_HVB;
Andreas Färbera1389542012-04-06 15:35:34 +020010354 msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */
10355 msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */
10356 msr |= (target_ulong)1 << MSR_EP;
10357#if defined(DO_SINGLE_STEP) && 0
10358 /* Single step trace mode */
10359 msr |= (target_ulong)1 << MSR_SE;
10360 msr |= (target_ulong)1 << MSR_BE;
10361#endif
10362#if defined(CONFIG_USER_ONLY)
10363 msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
10364 msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
Tom Musta5b274ed2014-05-29 09:12:22 -050010365 msr |= (target_ulong)1 << MSR_VSX; /* Allow VSX usage */
Andreas Färbera1389542012-04-06 15:35:34 +020010366 msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
10367 msr |= (target_ulong)1 << MSR_PR;
Alexey Kardashevskiycdcdda22014-06-04 22:50:59 +100010368#if defined(TARGET_PPC64)
10369 msr |= (target_ulong)1 << MSR_TM; /* Transactional memory */
10370#endif
Doug Kwane22c3572014-05-29 09:12:20 -050010371#if !defined(TARGET_WORDS_BIGENDIAN)
10372 msr |= (target_ulong)1 << MSR_LE; /* Little-endian user mode */
Richard Hendersona74029f2014-06-28 09:45:27 -070010373 if (!((env->msr_mask >> MSR_LE) & 1)) {
10374 fprintf(stderr, "Selected CPU does not support little-endian.\n");
10375 exit(1);
10376 }
Doug Kwane22c3572014-05-29 09:12:20 -050010377#endif
Andreas Färbera1389542012-04-06 15:35:34 +020010378#endif
Fabien Chouteau2cf3eb62013-03-29 02:06:27 +000010379
Andreas Färbera1389542012-04-06 15:35:34 +020010380#if defined(TARGET_PPC64)
10381 if (env->mmu_model & POWERPC_MMU_64) {
Laurent Vivier8b9f2112016-03-16 10:43:52 +010010382 msr |= (1ULL << MSR_SF);
Andreas Färbera1389542012-04-06 15:35:34 +020010383 }
10384#endif
Fabien Chouteau2cf3eb62013-03-29 02:06:27 +000010385
10386 hreg_store_msr(env, msr, 1);
10387
10388#if !defined(CONFIG_USER_ONLY)
10389 env->nip = env->hreset_vector | env->excp_prefix;
10390 if (env->mmu_model != POWERPC_MMU_REAL) {
10391 ppc_tlb_invalidate_all(env);
10392 }
10393#endif
10394
Andreas Färbera1389542012-04-06 15:35:34 +020010395 hreg_compute_hflags(env);
10396 env->reserve_addr = (target_ulong)-1ULL;
10397 /* Be sure no exception or interrupt is pending */
10398 env->pending_interrupts = 0;
Andreas Färber27103422013-08-26 08:31:06 +020010399 s->exception_index = POWERPC_EXCP_NONE;
Andreas Färbera1389542012-04-06 15:35:34 +020010400 env->error_code = 0;
David Gibson2b158112012-09-25 17:12:21 +000010401
10402#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
David Gibson1bfb37d2012-10-08 18:17:38 +000010403 env->vpa_addr = 0;
10404 env->slb_shadow_addr = 0;
10405 env->slb_shadow_size = 0;
10406 env->dtl_addr = 0;
David Gibson2b158112012-09-25 17:12:21 +000010407 env->dtl_size = 0;
10408#endif /* TARGET_PPC64 */
10409
Alexey Kardashevskiyd197fdb2014-03-20 00:03:57 +110010410 for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
10411 ppc_spr_t *spr = &env->spr_cb[i];
10412
10413 if (!spr->name) {
10414 continue;
10415 }
10416 env->spr[i] = spr->default_value;
10417 }
10418
Andreas Färbera1389542012-04-06 15:35:34 +020010419 /* Flush all TLBs */
Andreas Färber00c8cb02013-09-04 02:19:44 +020010420 tlb_flush(s, 1);
Andreas Färber1d0cb672012-04-06 14:39:03 +020010421}
10422
Greg Kurz7826c2b2014-06-24 19:51:19 +020010423#ifndef CONFIG_USER_ONLY
10424static bool ppc_cpu_is_big_endian(CPUState *cs)
10425{
10426 PowerPCCPU *cpu = POWERPC_CPU(cs);
10427 CPUPPCState *env = &cpu->env;
10428
10429 cpu_synchronize_state(cs);
10430
10431 return !msr_le;
10432}
10433#endif
10434
Andreas Färber6cca7ad2012-04-06 15:09:01 +020010435static void ppc_cpu_initfn(Object *obj)
10436{
Andreas Färberc05efcb2013-01-17 12:13:41 +010010437 CPUState *cs = CPU(obj);
Andreas Färber6cca7ad2012-04-06 15:09:01 +020010438 PowerPCCPU *cpu = POWERPC_CPU(obj);
Andreas Färber2985b862013-01-06 08:31:30 +000010439 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
Andreas Färber6cca7ad2012-04-06 15:09:01 +020010440 CPUPPCState *env = &cpu->env;
10441
Andreas Färberc05efcb2013-01-17 12:13:41 +010010442 cs->env_ptr = env;
Andreas Färber2985b862013-01-06 08:31:30 +000010443
Andreas Färbercfe34f42013-02-17 23:16:41 +000010444 env->msr_mask = pcc->msr_mask;
10445 env->mmu_model = pcc->mmu_model;
10446 env->excp_model = pcc->excp_model;
10447 env->bus_model = pcc->bus_model;
10448 env->insns_flags = pcc->insns_flags;
10449 env->insns_flags2 = pcc->insns_flags2;
10450 env->flags = pcc->flags;
10451 env->bfd_mach = pcc->bfd_mach;
10452 env->check_pow = pcc->check_pow;
Andreas Färber2985b862013-01-06 08:31:30 +000010453
Benjamin Herrenschmidt932ccbd2016-06-03 14:11:19 +020010454 /* Mark HV mode as supported if the CPU has an MSR_HV bit
10455 * in the msr_mask. The mask can later be cleared by PAPR
10456 * mode but the hv mode support will remain, thus enforcing
10457 * that we cannot use priv. instructions in guest in PAPR
10458 * mode. For 970 we currently simply don't set HV in msr_mask
10459 * thus simulating an "Apple mode" 970. If we ever want to
10460 * support 970 HV mode, we'll have to add a processor attribute
10461 * of some sort.
10462 */
10463#if !defined(CONFIG_USER_ONLY)
10464 env->has_hv_mode = !!(env->msr_mask & MSR_HVB);
10465#endif
10466
Andreas Färber2985b862013-01-06 08:31:30 +000010467#if defined(TARGET_PPC64)
Andreas Färbercfe34f42013-02-17 23:16:41 +000010468 if (pcc->sps) {
10469 env->sps = *pcc->sps;
Andreas Färber2985b862013-01-06 08:31:30 +000010470 } else if (env->mmu_model & POWERPC_MMU_64) {
Benjamin Herrenschmidt4322e8c2016-06-28 08:48:34 +020010471 /* Use default sets of page sizes. We don't support MPSS */
10472 static const struct ppc_segment_page_sizes defsps_4k = {
Andreas Färber2985b862013-01-06 08:31:30 +000010473 .sps = {
10474 { .page_shift = 12, /* 4K */
10475 .slb_enc = 0,
10476 .enc = { { .page_shift = 12, .pte_enc = 0 } }
10477 },
10478 { .page_shift = 24, /* 16M */
10479 .slb_enc = 0x100,
10480 .enc = { { .page_shift = 24, .pte_enc = 0 } }
10481 },
10482 },
10483 };
Benjamin Herrenschmidt4322e8c2016-06-28 08:48:34 +020010484 static const struct ppc_segment_page_sizes defsps_64k = {
10485 .sps = {
10486 { .page_shift = 12, /* 4K */
10487 .slb_enc = 0,
10488 .enc = { { .page_shift = 12, .pte_enc = 0 } }
10489 },
10490 { .page_shift = 16, /* 64K */
10491 .slb_enc = 0x110,
10492 .enc = { { .page_shift = 16, .pte_enc = 1 } }
10493 },
10494 { .page_shift = 24, /* 16M */
10495 .slb_enc = 0x100,
10496 .enc = { { .page_shift = 24, .pte_enc = 0 } }
10497 },
10498 },
10499 };
10500 env->sps = (env->mmu_model & POWERPC_MMU_64K) ? defsps_64k : defsps_4k;
Andreas Färber2985b862013-01-06 08:31:30 +000010501 }
10502#endif /* defined(TARGET_PPC64) */
Andreas Färber60925d22013-01-20 01:26:37 +010010503
10504 if (tcg_enabled()) {
10505 ppc_translate_init();
10506 }
Andreas Färber6cca7ad2012-04-06 15:09:01 +020010507}
10508
Alexey Kardashevskiy03ae4132014-07-04 00:48:55 +100010509static bool ppc_pvr_match_default(PowerPCCPUClass *pcc, uint32_t pvr)
10510{
10511 return pcc->pvr == pvr;
10512}
10513
David Hildenbrandb3820e62015-12-03 13:14:41 +010010514static gchar *ppc_gdb_arch_name(CPUState *cs)
10515{
10516#if defined(TARGET_PPC64)
10517 return g_strdup("powerpc:common64");
10518#else
10519 return g_strdup("powerpc:common");
10520#endif
10521}
10522
Andreas Färber1d0cb672012-04-06 14:39:03 +020010523static void ppc_cpu_class_init(ObjectClass *oc, void *data)
10524{
10525 PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
10526 CPUClass *cc = CPU_CLASS(oc);
Andreas Färber4776ce62013-01-16 03:55:14 +010010527 DeviceClass *dc = DEVICE_CLASS(oc);
10528
10529 pcc->parent_realize = dc->realize;
Laurent Vivier7bbc1242016-10-20 13:26:04 +020010530 pcc->parent_unrealize = dc->unrealize;
Alexey Kardashevskiy03ae4132014-07-04 00:48:55 +100010531 pcc->pvr_match = ppc_pvr_match_default;
Greg Kurz382d2db2014-05-19 19:59:05 +020010532 pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_always;
Andreas Färber4776ce62013-01-16 03:55:14 +010010533 dc->realize = ppc_cpu_realizefn;
Andreas Färberb0489602013-06-09 22:11:49 +020010534 dc->unrealize = ppc_cpu_unrealizefn;
Andreas Färber1d0cb672012-04-06 14:39:03 +020010535
10536 pcc->parent_reset = cc->reset;
10537 cc->reset = ppc_cpu_reset;
Andreas Färber2b8c2752013-01-21 18:26:21 +010010538
10539 cc->class_by_name = ppc_cpu_class_by_name;
Andreas Färber8c2e1b02013-08-25 18:53:55 +020010540 cc->has_work = ppc_cpu_has_work;
Andreas Färber97a8ea52013-02-02 10:57:51 +010010541 cc->do_interrupt = ppc_cpu_do_interrupt;
Richard Henderson458dd762014-09-13 09:45:32 -070010542 cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt;
Andreas Färber878096e2013-05-27 01:33:50 +020010543 cc->dump_state = ppc_cpu_dump_state;
10544 cc->dump_statistics = ppc_cpu_dump_statistics;
Andreas Färberf45748f2013-06-21 19:09:18 +020010545 cc->set_pc = ppc_cpu_set_pc;
Andreas Färber5b50e792013-06-29 04:18:45 +020010546 cc->gdb_read_register = ppc_cpu_gdb_read_register;
10547 cc->gdb_write_register = ppc_cpu_gdb_write_register;
Andreas Färber75104542013-08-26 03:01:33 +020010548#ifdef CONFIG_USER_ONLY
10549 cc->handle_mmu_fault = ppc_cpu_handle_mmu_fault;
10550#else
Andreas Färber00b941e2013-06-29 18:55:54 +020010551 cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
Alexey Kardashevskiya90db152013-07-18 14:32:54 -050010552 cc->vmsd = &vmstate_ppc_cpu;
Aneesh Kumar K.Ve62fbc52013-10-01 21:49:33 +053010553#if defined(TARGET_PPC64)
10554 cc->write_elf64_note = ppc64_cpu_write_elf64_note;
Aneesh Kumar K.Ve62fbc52013-10-01 21:49:33 +053010555#endif
Andreas Färber00b941e2013-06-29 18:55:54 +020010556#endif
Richard Henderson774f0ab2014-09-13 09:45:16 -070010557 cc->cpu_exec_enter = ppc_cpu_exec_enter;
Andreas Färbera0e372f2013-06-28 23:18:47 +020010558
10559 cc->gdb_num_core_regs = 71;
Alexander Grafb3cad3a2014-06-23 15:23:08 +020010560
10561#ifdef USE_APPLE_GDB
10562 cc->gdb_read_register = ppc_cpu_gdb_read_register_apple;
10563 cc->gdb_write_register = ppc_cpu_gdb_write_register_apple;
10564 cc->gdb_num_core_regs = 71 + 32;
10565#endif
10566
David Hildenbrandb3820e62015-12-03 13:14:41 +010010567 cc->gdb_arch_name = ppc_gdb_arch_name;
Andreas Färber5b24c642013-07-07 15:08:22 +020010568#if defined(TARGET_PPC64)
10569 cc->gdb_core_xml_file = "power64-core.xml";
10570#else
10571 cc->gdb_core_xml_file = "power-core.xml";
10572#endif
Greg Kurz7826c2b2014-06-24 19:51:19 +020010573#ifndef CONFIG_USER_ONLY
10574 cc->virtio_is_big_endian = ppc_cpu_is_big_endian;
10575#endif
Andreas Färber3bbf37f2013-10-15 18:33:37 +020010576
10577 dc->fw_name = "PowerPC,UNKNOWN";
Andreas Färber1d0cb672012-04-06 14:39:03 +020010578}
10579
10580static const TypeInfo ppc_cpu_type_info = {
10581 .name = TYPE_POWERPC_CPU,
10582 .parent = TYPE_CPU,
10583 .instance_size = sizeof(PowerPCCPU),
Andreas Färber6cca7ad2012-04-06 15:09:01 +020010584 .instance_init = ppc_cpu_initfn,
Andreas Färber2985b862013-01-06 08:31:30 +000010585 .abstract = true,
Andreas Färber1d0cb672012-04-06 14:39:03 +020010586 .class_size = sizeof(PowerPCCPUClass),
10587 .class_init = ppc_cpu_class_init,
10588};
10589
10590static void ppc_cpu_register_types(void)
10591{
10592 type_register_static(&ppc_cpu_type_info);
10593}
10594
10595type_init(ppc_cpu_register_types)