summaryrefslogtreecommitdiff
path: root/target-ppc
diff options
context:
space:
mode:
authorJunfeng Dong <junfeng.dong@intel.com>2013-11-19 17:45:23 +0800
committerJunfeng Dong <junfeng.dong@intel.com>2013-11-19 17:45:23 +0800
commit340f06c9eaee097e626c251bf7a013350649c091 (patch)
tree107e5705050a12da68fc80a56ae37afd50a2cc94 /target-ppc
parent42bf3037d458a330856a0be584200c1e41c3f417 (diff)
downloadqemu-340f06c9eaee097e626c251bf7a013350649c091.tar.gz
qemu-340f06c9eaee097e626c251bf7a013350649c091.tar.bz2
qemu-340f06c9eaee097e626c251bf7a013350649c091.zip
Import upstream 1.6.0.upstream/1.6.0
Change-Id: Icf52b556470cac8677297f2ef14ded16684f7887 Signed-off-by: Junfeng Dong <junfeng.dong@intel.com>
Diffstat (limited to 'target-ppc')
-rw-r--r--target-ppc/Makefile.objs14
-rw-r--r--target-ppc/cpu-models.c1421
-rw-r--r--target-ppc/cpu-models.h741
-rw-r--r--target-ppc/cpu-qom.h43
-rw-r--r--target-ppc/cpu.h213
-rw-r--r--target-ppc/excp_helper.c76
-rw-r--r--target-ppc/fpu_helper.c76
-rw-r--r--target-ppc/gdbstub.c131
-rw-r--r--target-ppc/helper.h15
-rw-r--r--target-ppc/helper_regs.h11
-rw-r--r--target-ppc/int_helper.c73
-rw-r--r--target-ppc/kvm-stub.c18
-rw-r--r--target-ppc/kvm.c846
-rw-r--r--target-ppc/kvm_ppc.c4
-rw-r--r--target-ppc/kvm_ppc.h77
-rw-r--r--target-ppc/machine.c539
-rw-r--r--target-ppc/mem_helper.c69
-rw-r--r--target-ppc/misc_helper.c6
-rw-r--r--target-ppc/mmu-hash32.c560
-rw-r--r--target-ppc/mmu-hash32.h102
-rw-r--r--target-ppc/mmu-hash64.c546
-rw-r--r--target-ppc/mmu-hash64.h124
-rw-r--r--target-ppc/mmu_helper.c940
-rw-r--r--target-ppc/mpic_helper.c35
-rw-r--r--target-ppc/translate.c1282
-rw-r--r--target-ppc/translate_init.c6254
-rw-r--r--target-ppc/user_only_helper.c (renamed from target-ppc/helper.c)46
27 files changed, 8322 insertions, 5940 deletions
diff --git a/target-ppc/Makefile.objs b/target-ppc/Makefile.objs
index 237a0ed4f..f72e3993f 100644
--- a/target-ppc/Makefile.objs
+++ b/target-ppc/Makefile.objs
@@ -1,12 +1,16 @@
-obj-y += translate.o helper.o
-obj-$(CONFIG_SOFTMMU) += machine.o
+obj-y += cpu-models.o
+obj-y += translate.o
+ifeq ($(CONFIG_SOFTMMU),y)
+obj-y += machine.o mmu_helper.o mmu-hash32.o
+obj-$(TARGET_PPC64) += mmu-hash64.o
+endif
obj-$(CONFIG_KVM) += kvm.o kvm_ppc.o
-obj-y += helper.o
+obj-$(CONFIG_NO_KVM) += kvm-stub.o
obj-y += excp_helper.o
obj-y += fpu_helper.o
obj-y += int_helper.o
-obj-y += mmu_helper.o
obj-y += timebase_helper.o
obj-y += misc_helper.o
obj-y += mem_helper.o
-obj-y += mpic_helper.o
+obj-$(CONFIG_USER_ONLY) += user_only_helper.o
+obj-y += gdbstub.o
diff --git a/target-ppc/cpu-models.c b/target-ppc/cpu-models.c
new file mode 100644
index 000000000..8dea56038
--- /dev/null
+++ b/target-ppc/cpu-models.c
@@ -0,0 +1,1421 @@
+/*
+ * PowerPC CPU initialization for qemu.
+ *
+ * Copyright (c) 2003-2007 Jocelyn Mayer
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2013 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* A lot of PowerPC definition have been included here.
+ * Most of them are not usable for now but have been kept
+ * inside "#if defined(TODO) ... #endif" statements to make tests easier.
+ */
+
+#include "cpu.h"
+#include "cpu-models.h"
+
+#if defined(CONFIG_USER_ONLY)
+#define TODO_USER_ONLY 1
+#endif
+
+/***************************************************************************/
+/* PowerPC CPU definitions */
+#define POWERPC_DEF_PREFIX(pvr, svr, type) \
+ glue(glue(glue(glue(pvr, _), svr), _), type)
+#define POWERPC_DEF_SVR(_name, _desc, _pvr, _svr, _type) \
+ static void \
+ glue(POWERPC_DEF_PREFIX(_pvr, _svr, _type), _cpu_class_init) \
+ (ObjectClass *oc, void *data) \
+ { \
+ DeviceClass *dc = DEVICE_CLASS(oc); \
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); \
+ \
+ pcc->pvr = _pvr; \
+ pcc->svr = _svr; \
+ dc->desc = _desc; \
+ } \
+ \
+ static const TypeInfo \
+ glue(POWERPC_DEF_PREFIX(_pvr, _svr, _type), _cpu_type_info) = { \
+ .name = _name "-" TYPE_POWERPC_CPU, \
+ .parent = stringify(_type) "-family-" TYPE_POWERPC_CPU, \
+ .class_init = \
+ glue(POWERPC_DEF_PREFIX(_pvr, _svr, _type), _cpu_class_init), \
+ }; \
+ \
+ static void \
+ glue(POWERPC_DEF_PREFIX(_pvr, _svr, _type), _cpu_register_types)(void) \
+ { \
+ type_register_static( \
+ &glue(POWERPC_DEF_PREFIX(_pvr, _svr, _type), _cpu_type_info)); \
+ } \
+ \
+ type_init( \
+ glue(POWERPC_DEF_PREFIX(_pvr, _svr, _type), _cpu_register_types))
+
+#define POWERPC_DEF(_name, _pvr, _type, _desc) \
+ POWERPC_DEF_SVR(_name, _desc, _pvr, POWERPC_SVR_NONE, _type)
+
+ /* Embedded PowerPC */
+ /* PowerPC 401 family */
+ POWERPC_DEF("401", CPU_POWERPC_401, 401,
+ "Generic PowerPC 401")
+ /* PowerPC 401 cores */
+ POWERPC_DEF("401A1", CPU_POWERPC_401A1, 401,
+ "PowerPC 401A1")
+ POWERPC_DEF("401B2", CPU_POWERPC_401B2, 401x2,
+ "PowerPC 401B2")
+#if defined(TODO)
+ POWERPC_DEF("401B3", CPU_POWERPC_401B3, 401x3,
+ "PowerPC 401B3")
+#endif
+ POWERPC_DEF("401C2", CPU_POWERPC_401C2, 401x2,
+ "PowerPC 401C2")
+ POWERPC_DEF("401D2", CPU_POWERPC_401D2, 401x2,
+ "PowerPC 401D2")
+ POWERPC_DEF("401E2", CPU_POWERPC_401E2, 401x2,
+ "PowerPC 401E2")
+ POWERPC_DEF("401F2", CPU_POWERPC_401F2, 401x2,
+ "PowerPC 401F2")
+ /* XXX: to be checked */
+ POWERPC_DEF("401G2", CPU_POWERPC_401G2, 401x2,
+ "PowerPC 401G2")
+ /* PowerPC 401 microcontrollers */
+#if defined(TODO)
+ POWERPC_DEF("401GF", CPU_POWERPC_401GF, 401,
+ "PowerPC 401GF")
+#endif
+ POWERPC_DEF("IOP480", CPU_POWERPC_IOP480, IOP480,
+ "IOP480 (401 microcontroller)")
+ POWERPC_DEF("Cobra", CPU_POWERPC_COBRA, 401,
+ "IBM Processor for Network Resources")
+#if defined(TODO)
+ POWERPC_DEF("Xipchip", CPU_POWERPC_XIPCHIP, 401,
+ NULL)
+#endif
+ /* PowerPC 403 family */
+ /* PowerPC 403 microcontrollers */
+ POWERPC_DEF("403GA", CPU_POWERPC_403GA, 403,
+ "PowerPC 403 GA")
+ POWERPC_DEF("403GB", CPU_POWERPC_403GB, 403,
+ "PowerPC 403 GB")
+ POWERPC_DEF("403GC", CPU_POWERPC_403GC, 403,
+ "PowerPC 403 GC")
+ POWERPC_DEF("403GCX", CPU_POWERPC_403GCX, 403GCX,
+ "PowerPC 403 GCX")
+#if defined(TODO)
+ POWERPC_DEF("403GP", CPU_POWERPC_403GP, 403,
+ "PowerPC 403 GP")
+#endif
+ /* PowerPC 405 family */
+ /* PowerPC 405 cores */
+#if defined(TODO)
+ POWERPC_DEF("405A3", CPU_POWERPC_405A3, 405,
+ "PowerPC 405 A3")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("405A4", CPU_POWERPC_405A4, 405,
+ "PowerPC 405 A4")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("405B3", CPU_POWERPC_405B3, 405,
+ "PowerPC 405 B3")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("405B4", CPU_POWERPC_405B4, 405,
+ "PowerPC 405 B4")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("405C3", CPU_POWERPC_405C3, 405,
+ "PowerPC 405 C3")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("405C4", CPU_POWERPC_405C4, 405,
+ "PowerPC 405 C4")
+#endif
+ POWERPC_DEF("405D2", CPU_POWERPC_405D2, 405,
+ "PowerPC 405 D2")
+#if defined(TODO)
+ POWERPC_DEF("405D3", CPU_POWERPC_405D3, 405,
+ "PowerPC 405 D3")
+#endif
+ POWERPC_DEF("405D4", CPU_POWERPC_405D4, 405,
+ "PowerPC 405 D4")
+#if defined(TODO)
+ POWERPC_DEF("405D5", CPU_POWERPC_405D5, 405,
+ "PowerPC 405 D5")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("405E4", CPU_POWERPC_405E4, 405,
+ "PowerPC 405 E4")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("405F4", CPU_POWERPC_405F4, 405,
+ "PowerPC 405 F4")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("405F5", CPU_POWERPC_405F5, 405,
+ "PowerPC 405 F5")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("405F6", CPU_POWERPC_405F6, 405,
+ "PowerPC 405 F6")
+#endif
+ /* PowerPC 405 microcontrollers */
+ POWERPC_DEF("405CRa", CPU_POWERPC_405CRa, 405,
+ "PowerPC 405 CRa")
+ POWERPC_DEF("405CRb", CPU_POWERPC_405CRb, 405,
+ "PowerPC 405 CRb")
+ POWERPC_DEF("405CRc", CPU_POWERPC_405CRc, 405,
+ "PowerPC 405 CRc")
+ POWERPC_DEF("405EP", CPU_POWERPC_405EP, 405,
+ "PowerPC 405 EP")
+#if defined(TODO)
+ POWERPC_DEF("405EXr", CPU_POWERPC_405EXr, 405,
+ "PowerPC 405 EXr")
+#endif
+ POWERPC_DEF("405EZ", CPU_POWERPC_405EZ, 405,
+ "PowerPC 405 EZ")
+#if defined(TODO)
+ POWERPC_DEF("405FX", CPU_POWERPC_405FX, 405,
+ "PowerPC 405 FX")
+#endif
+ POWERPC_DEF("405GPa", CPU_POWERPC_405GPa, 405,
+ "PowerPC 405 GPa")
+ POWERPC_DEF("405GPb", CPU_POWERPC_405GPb, 405,
+ "PowerPC 405 GPb")
+ POWERPC_DEF("405GPc", CPU_POWERPC_405GPc, 405,
+ "PowerPC 405 GPc")
+ POWERPC_DEF("405GPd", CPU_POWERPC_405GPd, 405,
+ "PowerPC 405 GPd")
+ POWERPC_DEF("405GPR", CPU_POWERPC_405GPR, 405,
+ "PowerPC 405 GPR")
+#if defined(TODO)
+ POWERPC_DEF("405H", CPU_POWERPC_405H, 405,
+ "PowerPC 405 H")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("405L", CPU_POWERPC_405L, 405,
+ "PowerPC 405 L")
+#endif
+ POWERPC_DEF("405LP", CPU_POWERPC_405LP, 405,
+ "PowerPC 405 LP")
+#if defined(TODO)
+ POWERPC_DEF("405PM", CPU_POWERPC_405PM, 405,
+ "PowerPC 405 PM")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("405PS", CPU_POWERPC_405PS, 405,
+ "PowerPC 405 PS")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("405S", CPU_POWERPC_405S, 405,
+ "PowerPC 405 S")
+#endif
+ POWERPC_DEF("Npe405H", CPU_POWERPC_NPE405H, 405,
+ "Npe405 H")
+ POWERPC_DEF("Npe405H2", CPU_POWERPC_NPE405H2, 405,
+ "Npe405 H2")
+ POWERPC_DEF("Npe405L", CPU_POWERPC_NPE405L, 405,
+ "Npe405 L")
+ POWERPC_DEF("Npe4GS3", CPU_POWERPC_NPE4GS3, 405,
+ "Npe4GS3")
+#if defined(TODO)
+ POWERPC_DEF("Npcxx1", CPU_POWERPC_NPCxx1, 405,
+ NULL)
+#endif
+#if defined(TODO)
+ POWERPC_DEF("Npr161", CPU_POWERPC_NPR161, 405,
+ NULL)
+#endif
+#if defined(TODO)
+ POWERPC_DEF("LC77700", CPU_POWERPC_LC77700, 405,
+ "PowerPC LC77700 (Sanyo)")
+#endif
+ /* PowerPC 401/403/405 based set-top-box microcontrollers */
+#if defined(TODO)
+ POWERPC_DEF("STB01000", CPU_POWERPC_STB01000, 401x2,
+ "STB010000")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("STB01010", CPU_POWERPC_STB01010, 401x2,
+ "STB01010")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("STB0210", CPU_POWERPC_STB0210, 401x3,
+ "STB0210")
+#endif
+ POWERPC_DEF("STB03", CPU_POWERPC_STB03, 405,
+ "STB03xx")
+#if defined(TODO)
+ POWERPC_DEF("STB043", CPU_POWERPC_STB043, 405,
+ "STB043x")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("STB045", CPU_POWERPC_STB045, 405,
+ "STB045x")
+#endif
+ POWERPC_DEF("STB04", CPU_POWERPC_STB04, 405,
+ "STB04xx")
+ POWERPC_DEF("STB25", CPU_POWERPC_STB25, 405,
+ "STB25xx")
+#if defined(TODO)
+ POWERPC_DEF("STB130", CPU_POWERPC_STB130, 405,
+ "STB130")
+#endif
+ /* Xilinx PowerPC 405 cores */
+ POWERPC_DEF("x2vp4", CPU_POWERPC_X2VP4, 405,
+ NULL)
+ POWERPC_DEF("x2vp20", CPU_POWERPC_X2VP20, 405,
+ NULL)
+#if defined(TODO)
+ POWERPC_DEF("zl10310", CPU_POWERPC_ZL10310, 405,
+ "Zarlink ZL10310")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("zl10311", CPU_POWERPC_ZL10311, 405,
+ "Zarlink ZL10311")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("zl10320", CPU_POWERPC_ZL10320, 405,
+ "Zarlink ZL10320")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("zl10321", CPU_POWERPC_ZL10321, 405,
+ "Zarlink ZL10321")
+#endif
+ /* PowerPC 440 family */
+#if defined(TODO_USER_ONLY)
+ POWERPC_DEF("440", CPU_POWERPC_440, 440GP,
+ "Generic PowerPC 440")
+#endif
+ /* PowerPC 440 cores */
+#if defined(TODO)
+ POWERPC_DEF("440A4", CPU_POWERPC_440A4, 440x4,
+ "PowerPC 440 A4")
+#endif
+ POWERPC_DEF("440-Xilinx", CPU_POWERPC_440_XILINX, 440x5,
+ "PowerPC 440 Xilinx 5")
+#if defined(TODO)
+ POWERPC_DEF("440A5", CPU_POWERPC_440A5, 440x5,
+ "PowerPC 440 A5")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("440B4", CPU_POWERPC_440B4, 440x4,
+ "PowerPC 440 B4")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("440G4", CPU_POWERPC_440G4, 440x4,
+ "PowerPC 440 G4")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("440F5", CPU_POWERPC_440F5, 440x5,
+ "PowerPC 440 F5")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("440G5", CPU_POWERPC_440G5, 440x5,
+ "PowerPC 440 G5")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("440H4", CPU_POWERPC_440H4, 440x4,
+ "PowerPC 440H4")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("440H6", CPU_POWERPC_440H6, 440Gx5,
+ "PowerPC 440H6")
+#endif
+ /* PowerPC 440 microcontrollers */
+ POWERPC_DEF("440EPa", CPU_POWERPC_440EPa, 440EP,
+ "PowerPC 440 EPa")
+ POWERPC_DEF("440EPb", CPU_POWERPC_440EPb, 440EP,
+ "PowerPC 440 EPb")
+ POWERPC_DEF("440EPX", CPU_POWERPC_440EPX, 440EP,
+ "PowerPC 440 EPX")
+#if defined(TODO_USER_ONLY)
+ POWERPC_DEF("440GPb", CPU_POWERPC_440GPb, 440GP,
+ "PowerPC 440 GPb")
+#endif
+#if defined(TODO_USER_ONLY)
+ POWERPC_DEF("440GPc", CPU_POWERPC_440GPc, 440GP,
+ "PowerPC 440 GPc")
+#endif
+#if defined(TODO_USER_ONLY)
+ POWERPC_DEF("440GRa", CPU_POWERPC_440GRa, 440x5,
+ "PowerPC 440 GRa")
+#endif
+#if defined(TODO_USER_ONLY)
+ POWERPC_DEF("440GRX", CPU_POWERPC_440GRX, 440x5,
+ "PowerPC 440 GRX")
+#endif
+#if defined(TODO_USER_ONLY)
+ POWERPC_DEF("440GXa", CPU_POWERPC_440GXa, 440EP,
+ "PowerPC 440 GXa")
+#endif
+#if defined(TODO_USER_ONLY)
+ POWERPC_DEF("440GXb", CPU_POWERPC_440GXb, 440EP,
+ "PowerPC 440 GXb")
+#endif
+#if defined(TODO_USER_ONLY)
+ POWERPC_DEF("440GXc", CPU_POWERPC_440GXc, 440EP,
+ "PowerPC 440 GXc")
+#endif
+#if defined(TODO_USER_ONLY)
+ POWERPC_DEF("440GXf", CPU_POWERPC_440GXf, 440EP,
+ "PowerPC 440 GXf")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("440S", CPU_POWERPC_440S, 440,
+ "PowerPC 440 S")
+#endif
+#if defined(TODO_USER_ONLY)
+ POWERPC_DEF("440SP", CPU_POWERPC_440SP, 440EP,
+ "PowerPC 440 SP")
+#endif
+#if defined(TODO_USER_ONLY)
+ POWERPC_DEF("440SP2", CPU_POWERPC_440SP2, 440EP,
+ "PowerPC 440 SP2")
+#endif
+#if defined(TODO_USER_ONLY)
+ POWERPC_DEF("440SPE", CPU_POWERPC_440SPE, 440EP,
+ "PowerPC 440 SPE")
+#endif
+ /* PowerPC 460 family */
+#if defined(TODO)
+ POWERPC_DEF("464", CPU_POWERPC_464, 460,
+ "Generic PowerPC 464")
+#endif
+ /* PowerPC 464 microcontrollers */
+#if defined(TODO)
+ POWERPC_DEF("464H90", CPU_POWERPC_464H90, 460,
+ "PowerPC 464H90")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("464H90F", CPU_POWERPC_464H90F, 460F,
+ "PowerPC 464H90F")
+#endif
+ /* Freescale embedded PowerPC cores */
+ /* MPC5xx family (aka RCPU) */
+#if defined(TODO_USER_ONLY)
+ POWERPC_DEF("MPC5xx", CPU_POWERPC_MPC5xx, MPC5xx,
+ "Generic MPC5xx core")
+#endif
+ /* MPC8xx family (aka PowerQUICC) */
+#if defined(TODO_USER_ONLY)
+ POWERPC_DEF("MPC8xx", CPU_POWERPC_MPC8xx, MPC8xx,
+ "Generic MPC8xx core")
+#endif
+ /* MPC82xx family (aka PowerQUICC-II) */
+ POWERPC_DEF("G2", CPU_POWERPC_G2, G2,
+ "PowerPC G2 core")
+ POWERPC_DEF("G2H4", CPU_POWERPC_G2H4, G2,
+ "PowerPC G2 H4 core")
+ POWERPC_DEF("G2GP", CPU_POWERPC_G2gp, G2,
+ "PowerPC G2 GP core")
+ POWERPC_DEF("G2LS", CPU_POWERPC_G2ls, G2,
+ "PowerPC G2 LS core")
+ POWERPC_DEF("G2HiP3", CPU_POWERPC_G2_HIP3, G2,
+ "PowerPC G2 HiP3 core")
+ POWERPC_DEF("G2HiP4", CPU_POWERPC_G2_HIP4, G2,
+ "PowerPC G2 HiP4 core")
+ POWERPC_DEF("MPC603", CPU_POWERPC_MPC603, 603E,
+ "PowerPC MPC603 core")
+ POWERPC_DEF("G2le", CPU_POWERPC_G2LE, G2LE,
+ "PowerPC G2le core (same as G2 plus little-endian mode support)")
+ POWERPC_DEF("G2leGP", CPU_POWERPC_G2LEgp, G2LE,
+ "PowerPC G2LE GP core")
+ POWERPC_DEF("G2leLS", CPU_POWERPC_G2LEls, G2LE,
+ "PowerPC G2LE LS core")
+ POWERPC_DEF("G2leGP1", CPU_POWERPC_G2LEgp1, G2LE,
+ "PowerPC G2LE GP1 core")
+ POWERPC_DEF("G2leGP3", CPU_POWERPC_G2LEgp3, G2LE,
+ "PowerPC G2LE GP3 core")
+ /* PowerPC G2 microcontrollers */
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC5121", "MPC5121",
+ CPU_POWERPC_MPC5121, POWERPC_SVR_5121, G2LE)
+#endif
+ POWERPC_DEF_SVR("MPC5200_v10", "MPC5200 v1.0",
+ CPU_POWERPC_MPC5200_v10, POWERPC_SVR_5200_v10, G2LE)
+ POWERPC_DEF_SVR("MPC5200_v11", "MPC5200 v1.1",
+ CPU_POWERPC_MPC5200_v11, POWERPC_SVR_5200_v11, G2LE)
+ POWERPC_DEF_SVR("MPC5200_v12", "MPC5200 v1.2",
+ CPU_POWERPC_MPC5200_v12, POWERPC_SVR_5200_v12, G2LE)
+ POWERPC_DEF_SVR("MPC5200B_v20", "MPC5200B v2.0",
+ CPU_POWERPC_MPC5200B_v20, POWERPC_SVR_5200B_v20, G2LE)
+ POWERPC_DEF_SVR("MPC5200B_v21", "MPC5200B v2.1",
+ CPU_POWERPC_MPC5200B_v21, POWERPC_SVR_5200B_v21, G2LE)
+ /* e200 family */
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC55xx", "Generic MPC55xx core",
+ CPU_POWERPC_MPC55xx, POWERPC_SVR_55xx, e200)
+#endif
+#if defined(TODO)
+ POWERPC_DEF("e200z0", CPU_POWERPC_e200z0, e200,
+ "PowerPC e200z0 core")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("e200z1", CPU_POWERPC_e200z1, e200,
+ "PowerPC e200z1 core")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("e200z3", CPU_POWERPC_e200z3, e200,
+ "PowerPC e200z3 core")
+#endif
+ POWERPC_DEF("e200z5", CPU_POWERPC_e200z5, e200,
+ "PowerPC e200z5 core")
+ POWERPC_DEF("e200z6", CPU_POWERPC_e200z6, e200,
+ "PowerPC e200z6 core")
+ /* PowerPC e200 microcontrollers */
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC5514E", "MPC5514E",
+ CPU_POWERPC_MPC5514E, POWERPC_SVR_5514E, e200)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC5514E_v0", "MPC5514E v0",
+ CPU_POWERPC_MPC5514E_v0, POWERPC_SVR_5514E_v0, e200)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC5514E_v1", "MPC5514E v1",
+ CPU_POWERPC_MPC5514E_v1, POWERPC_SVR_5514E_v1, e200)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC5514G", "MPC5514G",
+ CPU_POWERPC_MPC5514G, POWERPC_SVR_5514G, e200)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC5514G_v0", "MPC5514G v0",
+ CPU_POWERPC_MPC5514G_v0, POWERPC_SVR_5514G_v0, e200)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC5514G_v1", "MPC5514G v1",
+ CPU_POWERPC_MPC5514G_v1, POWERPC_SVR_5514G_v1, e200)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC5515S", "MPC5515S",
+ CPU_POWERPC_MPC5515S, POWERPC_SVR_5515S, e200)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC5516E", "MPC5516E",
+ CPU_POWERPC_MPC5516E, POWERPC_SVR_5516E, e200)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC5516E_v0", "MPC5516E v0",
+ CPU_POWERPC_MPC5516E_v0, POWERPC_SVR_5516E_v0, e200)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC5516E_v1", "MPC5516E v1",
+ CPU_POWERPC_MPC5516E_v1, POWERPC_SVR_5516E_v1, e200)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC5516G", "MPC5516G",
+ CPU_POWERPC_MPC5516G, POWERPC_SVR_5516G, e200)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC5516G_v0", "MPC5516G v0",
+ CPU_POWERPC_MPC5516G_v0, POWERPC_SVR_5516G_v0, e200)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC5516G_v1", "MPC5516G v1",
+ CPU_POWERPC_MPC5516G_v1, POWERPC_SVR_5516G_v1, e200)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC5516S", "MPC5516S",
+ CPU_POWERPC_MPC5516S, POWERPC_SVR_5516S, e200)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC5533", "MPC5533",
+ CPU_POWERPC_MPC5533, POWERPC_SVR_5533, e200)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC5534", "MPC5534",
+ CPU_POWERPC_MPC5534, POWERPC_SVR_5534, e200)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC5553", "MPC5553",
+ CPU_POWERPC_MPC5553, POWERPC_SVR_5553, e200)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC5554", "MPC5554",
+ CPU_POWERPC_MPC5554, POWERPC_SVR_5554, e200)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC5561", "MPC5561",
+ CPU_POWERPC_MPC5561, POWERPC_SVR_5561, e200)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC5565", "MPC5565",
+ CPU_POWERPC_MPC5565, POWERPC_SVR_5565, e200)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC5566", "MPC5566",
+ CPU_POWERPC_MPC5566, POWERPC_SVR_5566, e200)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC5567", "MPC5567",
+ CPU_POWERPC_MPC5567, POWERPC_SVR_5567, e200)
+#endif
+ /* e300 family */
+ POWERPC_DEF("e300c1", CPU_POWERPC_e300c1, e300,
+ "PowerPC e300c1 core")
+ POWERPC_DEF("e300c2", CPU_POWERPC_e300c2, e300,
+ "PowerPC e300c2 core")
+ POWERPC_DEF("e300c3", CPU_POWERPC_e300c3, e300,
+ "PowerPC e300c3 core")
+ POWERPC_DEF("e300c4", CPU_POWERPC_e300c4, e300,
+ "PowerPC e300c4 core")
+ /* PowerPC e300 microcontrollers */
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC8313", "MPC8313",
+ CPU_POWERPC_MPC831x, POWERPC_SVR_8313, e300)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC8313E", "MPC8313E",
+ CPU_POWERPC_MPC831x, POWERPC_SVR_8313E, e300)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC8314", "MPC8314",
+ CPU_POWERPC_MPC831x, POWERPC_SVR_8314, e300)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC8314E", "MPC8314E",
+ CPU_POWERPC_MPC831x, POWERPC_SVR_8314E, e300)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC8315", "MPC8315",
+ CPU_POWERPC_MPC831x, POWERPC_SVR_8315, e300)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC8315E", "MPC8315E",
+ CPU_POWERPC_MPC831x, POWERPC_SVR_8315E, e300)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC8321", "MPC8321",
+ CPU_POWERPC_MPC832x, POWERPC_SVR_8321, e300)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC8321E", "MPC8321E",
+ CPU_POWERPC_MPC832x, POWERPC_SVR_8321E, e300)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC8323", "MPC8323",
+ CPU_POWERPC_MPC832x, POWERPC_SVR_8323, e300)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC8323E", "MPC8323E",
+ CPU_POWERPC_MPC832x, POWERPC_SVR_8323E, e300)
+#endif
+ POWERPC_DEF_SVR("MPC8343", "MPC8343",
+ CPU_POWERPC_MPC834x, POWERPC_SVR_8343, e300)
+ POWERPC_DEF_SVR("MPC8343A", "MPC8343A",
+ CPU_POWERPC_MPC834x, POWERPC_SVR_8343A, e300)
+ POWERPC_DEF_SVR("MPC8343E", "MPC8343E",
+ CPU_POWERPC_MPC834x, POWERPC_SVR_8343E, e300)
+ POWERPC_DEF_SVR("MPC8343EA", "MPC8343EA",
+ CPU_POWERPC_MPC834x, POWERPC_SVR_8343EA, e300)
+ POWERPC_DEF_SVR("MPC8347T", "MPC8347T",
+ CPU_POWERPC_MPC834x, POWERPC_SVR_8347T, e300)
+ POWERPC_DEF_SVR("MPC8347P", "MPC8347P",
+ CPU_POWERPC_MPC834x, POWERPC_SVR_8347P, e300)
+ POWERPC_DEF_SVR("MPC8347AT", "MPC8347AT",
+ CPU_POWERPC_MPC834x, POWERPC_SVR_8347AT, e300)
+ POWERPC_DEF_SVR("MPC8347AP", "MPC8347AP",
+ CPU_POWERPC_MPC834x, POWERPC_SVR_8347AP, e300)
+ POWERPC_DEF_SVR("MPC8347ET", "MPC8347ET",
+ CPU_POWERPC_MPC834x, POWERPC_SVR_8347ET, e300)
+ POWERPC_DEF_SVR("MPC8347EP", "MPC8343EP",
+ CPU_POWERPC_MPC834x, POWERPC_SVR_8347EP, e300)
+ POWERPC_DEF_SVR("MPC8347EAT", "MPC8347EAT",
+ CPU_POWERPC_MPC834x, POWERPC_SVR_8347EAT, e300)
+ POWERPC_DEF_SVR("MPC8347EAP", "MPC8343EAP",
+ CPU_POWERPC_MPC834x, POWERPC_SVR_8347EAP, e300)
+ POWERPC_DEF_SVR("MPC8349", "MPC8349",
+ CPU_POWERPC_MPC834x, POWERPC_SVR_8349, e300)
+ POWERPC_DEF_SVR("MPC8349A", "MPC8349A",
+ CPU_POWERPC_MPC834x, POWERPC_SVR_8349A, e300)
+ POWERPC_DEF_SVR("MPC8349E", "MPC8349E",
+ CPU_POWERPC_MPC834x, POWERPC_SVR_8349E, e300)
+ POWERPC_DEF_SVR("MPC8349EA", "MPC8349EA",
+ CPU_POWERPC_MPC834x, POWERPC_SVR_8349EA, e300)
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC8358E", "MPC8358E",
+ CPU_POWERPC_MPC835x, POWERPC_SVR_8358E, e300)
+#endif
+#if defined(TODO)
+ POWERPC_DEF_SVR("MPC8360E", "MPC8360E",
+ CPU_POWERPC_MPC836x, POWERPC_SVR_8360E, e300)
+#endif
+ POWERPC_DEF_SVR("MPC8377", "MPC8377",
+ CPU_POWERPC_MPC837x, POWERPC_SVR_8377, e300)
+ POWERPC_DEF_SVR("MPC8377E", "MPC8377E",
+ CPU_POWERPC_MPC837x, POWERPC_SVR_8377E, e300)
+ POWERPC_DEF_SVR("MPC8378", "MPC8378",
+ CPU_POWERPC_MPC837x, POWERPC_SVR_8378, e300)
+ POWERPC_DEF_SVR("MPC8378E", "MPC8378E",
+ CPU_POWERPC_MPC837x, POWERPC_SVR_8378E, e300)
+ POWERPC_DEF_SVR("MPC8379", "MPC8379",
+ CPU_POWERPC_MPC837x, POWERPC_SVR_8379, e300)
+ POWERPC_DEF_SVR("MPC8379E", "MPC8379E",
+ CPU_POWERPC_MPC837x, POWERPC_SVR_8379E, e300)
+ /* e500 family */
+ POWERPC_DEF("e500_v10", CPU_POWERPC_e500v1_v10, e500v1,
+ "PowerPC e500 v1.0 core")
+ POWERPC_DEF("e500_v20", CPU_POWERPC_e500v1_v20, e500v1,
+ "PowerPC e500 v2.0 core")
+ POWERPC_DEF("e500v2_v10", CPU_POWERPC_e500v2_v10, e500v2,
+ "PowerPC e500v2 v1.0 core")
+ POWERPC_DEF("e500v2_v20", CPU_POWERPC_e500v2_v20, e500v2,
+ "PowerPC e500v2 v2.0 core")
+ POWERPC_DEF("e500v2_v21", CPU_POWERPC_e500v2_v21, e500v2,
+ "PowerPC e500v2 v2.1 core")
+ POWERPC_DEF("e500v2_v22", CPU_POWERPC_e500v2_v22, e500v2,
+ "PowerPC e500v2 v2.2 core")
+ POWERPC_DEF("e500v2_v30", CPU_POWERPC_e500v2_v30, e500v2,
+ "PowerPC e500v2 v3.0 core")
+ POWERPC_DEF_SVR("e500mc", "e500mc",
+ CPU_POWERPC_e500mc, POWERPC_SVR_E500, e500mc)
+#ifdef TARGET_PPC64
+ POWERPC_DEF_SVR("e5500", "e5500",
+ CPU_POWERPC_e5500, POWERPC_SVR_E500, e5500)
+#endif
+ /* PowerPC e500 microcontrollers */
+ POWERPC_DEF_SVR("MPC8533_v10", "MPC8533 v1.0",
+ CPU_POWERPC_MPC8533_v10, POWERPC_SVR_8533_v10, e500v2)
+ POWERPC_DEF_SVR("MPC8533_v11", "MPC8533 v1.1",
+ CPU_POWERPC_MPC8533_v11, POWERPC_SVR_8533_v11, e500v2)
+ POWERPC_DEF_SVR("MPC8533E_v10", "MPC8533E v1.0",
+ CPU_POWERPC_MPC8533E_v10, POWERPC_SVR_8533E_v10, e500v2)
+ POWERPC_DEF_SVR("MPC8533E_v11", "MPC8533E v1.1",
+ CPU_POWERPC_MPC8533E_v11, POWERPC_SVR_8533E_v11, e500v2)
+ POWERPC_DEF_SVR("MPC8540_v10", "MPC8540 v1.0",
+ CPU_POWERPC_MPC8540_v10, POWERPC_SVR_8540_v10, e500v1)
+ POWERPC_DEF_SVR("MPC8540_v20", "MPC8540 v2.0",
+ CPU_POWERPC_MPC8540_v20, POWERPC_SVR_8540_v20, e500v1)
+ POWERPC_DEF_SVR("MPC8540_v21", "MPC8540 v2.1",
+ CPU_POWERPC_MPC8540_v21, POWERPC_SVR_8540_v21, e500v1)
+ POWERPC_DEF_SVR("MPC8541_v10", "MPC8541 v1.0",
+ CPU_POWERPC_MPC8541_v10, POWERPC_SVR_8541_v10, e500v1)
+ POWERPC_DEF_SVR("MPC8541_v11", "MPC8541 v1.1",
+ CPU_POWERPC_MPC8541_v11, POWERPC_SVR_8541_v11, e500v1)
+ POWERPC_DEF_SVR("MPC8541E_v10", "MPC8541E v1.0",
+ CPU_POWERPC_MPC8541E_v10, POWERPC_SVR_8541E_v10, e500v1)
+ POWERPC_DEF_SVR("MPC8541E_v11", "MPC8541E v1.1",
+ CPU_POWERPC_MPC8541E_v11, POWERPC_SVR_8541E_v11, e500v1)
+ POWERPC_DEF_SVR("MPC8543_v10", "MPC8543 v1.0",
+ CPU_POWERPC_MPC8543_v10, POWERPC_SVR_8543_v10, e500v2)
+ POWERPC_DEF_SVR("MPC8543_v11", "MPC8543 v1.1",
+ CPU_POWERPC_MPC8543_v11, POWERPC_SVR_8543_v11, e500v2)
+ POWERPC_DEF_SVR("MPC8543_v20", "MPC8543 v2.0",
+ CPU_POWERPC_MPC8543_v20, POWERPC_SVR_8543_v20, e500v2)
+ POWERPC_DEF_SVR("MPC8543_v21", "MPC8543 v2.1",
+ CPU_POWERPC_MPC8543_v21, POWERPC_SVR_8543_v21, e500v2)
+ POWERPC_DEF_SVR("MPC8543E_v10", "MPC8543E v1.0",
+ CPU_POWERPC_MPC8543E_v10, POWERPC_SVR_8543E_v10, e500v2)
+ POWERPC_DEF_SVR("MPC8543E_v11", "MPC8543E v1.1",
+ CPU_POWERPC_MPC8543E_v11, POWERPC_SVR_8543E_v11, e500v2)
+ POWERPC_DEF_SVR("MPC8543E_v20", "MPC8543E v2.0",
+ CPU_POWERPC_MPC8543E_v20, POWERPC_SVR_8543E_v20, e500v2)
+ POWERPC_DEF_SVR("MPC8543E_v21", "MPC8543E v2.1",
+ CPU_POWERPC_MPC8543E_v21, POWERPC_SVR_8543E_v21, e500v2)
+ POWERPC_DEF_SVR("MPC8544_v10", "MPC8544 v1.0",
+ CPU_POWERPC_MPC8544_v10, POWERPC_SVR_8544_v10, e500v2)
+ POWERPC_DEF_SVR("MPC8544_v11", "MPC8544 v1.1",
+ CPU_POWERPC_MPC8544_v11, POWERPC_SVR_8544_v11, e500v2)
+ POWERPC_DEF_SVR("MPC8544E_v10", "MPC8544E v1.0",
+ CPU_POWERPC_MPC8544E_v10, POWERPC_SVR_8544E_v10, e500v2)
+ POWERPC_DEF_SVR("MPC8544E_v11", "MPC8544E v1.1",
+ CPU_POWERPC_MPC8544E_v11, POWERPC_SVR_8544E_v11, e500v2)
+ POWERPC_DEF_SVR("MPC8545_v20", "MPC8545 v2.0",
+ CPU_POWERPC_MPC8545_v20, POWERPC_SVR_8545_v20, e500v2)
+ POWERPC_DEF_SVR("MPC8545_v21", "MPC8545 v2.1",
+ CPU_POWERPC_MPC8545_v21, POWERPC_SVR_8545_v21, e500v2)
+ POWERPC_DEF_SVR("MPC8545E_v20", "MPC8545E v2.0",
+ CPU_POWERPC_MPC8545E_v20, POWERPC_SVR_8545E_v20, e500v2)
+ POWERPC_DEF_SVR("MPC8545E_v21", "MPC8545E v2.1",
+ CPU_POWERPC_MPC8545E_v21, POWERPC_SVR_8545E_v21, e500v2)
+ POWERPC_DEF_SVR("MPC8547E_v20", "MPC8547E v2.0",
+ CPU_POWERPC_MPC8547E_v20, POWERPC_SVR_8547E_v20, e500v2)
+ POWERPC_DEF_SVR("MPC8547E_v21", "MPC8547E v2.1",
+ CPU_POWERPC_MPC8547E_v21, POWERPC_SVR_8547E_v21, e500v2)
+ POWERPC_DEF_SVR("MPC8548_v10", "MPC8548 v1.0",
+ CPU_POWERPC_MPC8548_v10, POWERPC_SVR_8548_v10, e500v2)
+ POWERPC_DEF_SVR("MPC8548_v11", "MPC8548 v1.1",
+ CPU_POWERPC_MPC8548_v11, POWERPC_SVR_8548_v11, e500v2)
+ POWERPC_DEF_SVR("MPC8548_v20", "MPC8548 v2.0",
+ CPU_POWERPC_MPC8548_v20, POWERPC_SVR_8548_v20, e500v2)
+ POWERPC_DEF_SVR("MPC8548_v21", "MPC8548 v2.1",
+ CPU_POWERPC_MPC8548_v21, POWERPC_SVR_8548_v21, e500v2)
+ POWERPC_DEF_SVR("MPC8548E_v10", "MPC8548E v1.0",
+ CPU_POWERPC_MPC8548E_v10, POWERPC_SVR_8548E_v10, e500v2)
+ POWERPC_DEF_SVR("MPC8548E_v11", "MPC8548E v1.1",
+ CPU_POWERPC_MPC8548E_v11, POWERPC_SVR_8548E_v11, e500v2)
+ POWERPC_DEF_SVR("MPC8548E_v20", "MPC8548E v2.0",
+ CPU_POWERPC_MPC8548E_v20, POWERPC_SVR_8548E_v20, e500v2)
+ POWERPC_DEF_SVR("MPC8548E_v21", "MPC8548E v2.1",
+ CPU_POWERPC_MPC8548E_v21, POWERPC_SVR_8548E_v21, e500v2)
+ POWERPC_DEF_SVR("MPC8555_v10", "MPC8555 v1.0",
+ CPU_POWERPC_MPC8555_v10, POWERPC_SVR_8555_v10, e500v2)
+ POWERPC_DEF_SVR("MPC8555_v11", "MPC8555 v1.1",
+ CPU_POWERPC_MPC8555_v11, POWERPC_SVR_8555_v11, e500v2)
+ POWERPC_DEF_SVR("MPC8555E_v10", "MPC8555E v1.0",
+ CPU_POWERPC_MPC8555E_v10, POWERPC_SVR_8555E_v10, e500v2)
+ POWERPC_DEF_SVR("MPC8555E_v11", "MPC8555E v1.1",
+ CPU_POWERPC_MPC8555E_v11, POWERPC_SVR_8555E_v11, e500v2)
+ POWERPC_DEF_SVR("MPC8560_v10", "MPC8560 v1.0",
+ CPU_POWERPC_MPC8560_v10, POWERPC_SVR_8560_v10, e500v2)
+ POWERPC_DEF_SVR("MPC8560_v20", "MPC8560 v2.0",
+ CPU_POWERPC_MPC8560_v20, POWERPC_SVR_8560_v20, e500v2)
+ POWERPC_DEF_SVR("MPC8560_v21", "MPC8560 v2.1",
+ CPU_POWERPC_MPC8560_v21, POWERPC_SVR_8560_v21, e500v2)
+ POWERPC_DEF_SVR("MPC8567", "MPC8567",
+ CPU_POWERPC_MPC8567, POWERPC_SVR_8567, e500v2)
+ POWERPC_DEF_SVR("MPC8567E", "MPC8567E",
+ CPU_POWERPC_MPC8567E, POWERPC_SVR_8567E, e500v2)
+ POWERPC_DEF_SVR("MPC8568", "MPC8568",
+ CPU_POWERPC_MPC8568, POWERPC_SVR_8568, e500v2)
+ POWERPC_DEF_SVR("MPC8568E", "MPC8568E",
+ CPU_POWERPC_MPC8568E, POWERPC_SVR_8568E, e500v2)
+ POWERPC_DEF_SVR("MPC8572", "MPC8572",
+ CPU_POWERPC_MPC8572, POWERPC_SVR_8572, e500v2)
+ POWERPC_DEF_SVR("MPC8572E", "MPC8572E",
+ CPU_POWERPC_MPC8572E, POWERPC_SVR_8572E, e500v2)
+ /* e600 family */
+ POWERPC_DEF("e600", CPU_POWERPC_e600, e600,
+ "PowerPC e600 core")
+ /* PowerPC e600 microcontrollers */
+ POWERPC_DEF_SVR("MPC8610", "MPC8610",
+ CPU_POWERPC_MPC8610, POWERPC_SVR_8610, e600)
+ POWERPC_DEF_SVR("MPC8641", "MPC8641",
+ CPU_POWERPC_MPC8641, POWERPC_SVR_8641, e600)
+ POWERPC_DEF_SVR("MPC8641D", "MPC8641D",
+ CPU_POWERPC_MPC8641D, POWERPC_SVR_8641D, e600)
+ /* 32 bits "classic" PowerPC */
+ /* PowerPC 6xx family */
+ POWERPC_DEF("601_v0", CPU_POWERPC_601_v0, 601,
+ "PowerPC 601v0")
+ POWERPC_DEF("601_v1", CPU_POWERPC_601_v1, 601,
+ "PowerPC 601v1")
+ POWERPC_DEF("601_v2", CPU_POWERPC_601_v2, 601v,
+ "PowerPC 601v2")
+ POWERPC_DEF("602", CPU_POWERPC_602, 602,
+ "PowerPC 602")
+ POWERPC_DEF("603", CPU_POWERPC_603, 603,
+ "PowerPC 603")
+ POWERPC_DEF("603e_v1.1", CPU_POWERPC_603E_v11, 603E,
+ "PowerPC 603e v1.1")
+ POWERPC_DEF("603e_v1.2", CPU_POWERPC_603E_v12, 603E,
+ "PowerPC 603e v1.2")
+ POWERPC_DEF("603e_v1.3", CPU_POWERPC_603E_v13, 603E,
+ "PowerPC 603e v1.3")
+ POWERPC_DEF("603e_v1.4", CPU_POWERPC_603E_v14, 603E,
+ "PowerPC 603e v1.4")
+ POWERPC_DEF("603e_v2.2", CPU_POWERPC_603E_v22, 603E,
+ "PowerPC 603e v2.2")
+ POWERPC_DEF("603e_v3", CPU_POWERPC_603E_v3, 603E,
+ "PowerPC 603e v3")
+ POWERPC_DEF("603e_v4", CPU_POWERPC_603E_v4, 603E,
+ "PowerPC 603e v4")
+ POWERPC_DEF("603e_v4.1", CPU_POWERPC_603E_v41, 603E,
+ "PowerPC 603e v4.1")
+ POWERPC_DEF("603e7", CPU_POWERPC_603E7, 603E,
+ "PowerPC 603e (aka PID7)")
+ POWERPC_DEF("603e7t", CPU_POWERPC_603E7t, 603E,
+ "PowerPC 603e7t")
+ POWERPC_DEF("603e7v", CPU_POWERPC_603E7v, 603E,
+ "PowerPC 603e7v")
+ POWERPC_DEF("603e7v1", CPU_POWERPC_603E7v1, 603E,
+ "PowerPC 603e7v1")
+ POWERPC_DEF("603e7v2", CPU_POWERPC_603E7v2, 603E,
+ "PowerPC 603e7v2")
+ POWERPC_DEF("603p", CPU_POWERPC_603P, 603E,
+ "PowerPC 603p (aka PID7v)")
+ POWERPC_DEF("604", CPU_POWERPC_604, 604,
+ "PowerPC 604")
+ POWERPC_DEF("604e_v1.0", CPU_POWERPC_604E_v10, 604E,
+ "PowerPC 604e v1.0")
+ POWERPC_DEF("604e_v2.2", CPU_POWERPC_604E_v22, 604E,
+ "PowerPC 604e v2.2")
+ POWERPC_DEF("604e_v2.4", CPU_POWERPC_604E_v24, 604E,
+ "PowerPC 604e v2.4")
+ POWERPC_DEF("604r", CPU_POWERPC_604R, 604E,
+ "PowerPC 604r (aka PIDA)")
+#if defined(TODO)
+ POWERPC_DEF("604ev", CPU_POWERPC_604EV, 604E,
+ "PowerPC 604ev")
+#endif
+ /* PowerPC 7xx family */
+ POWERPC_DEF("740_v1.0", CPU_POWERPC_7x0_v10, 740,
+ "PowerPC 740 v1.0 (G3)")
+ POWERPC_DEF("750_v1.0", CPU_POWERPC_7x0_v10, 750,
+ "PowerPC 750 v1.0 (G3)")
+ POWERPC_DEF("740_v2.0", CPU_POWERPC_7x0_v20, 740,
+ "PowerPC 740 v2.0 (G3)")
+ POWERPC_DEF("750_v2.0", CPU_POWERPC_7x0_v20, 750,
+ "PowerPC 750 v2.0 (G3)")
+ POWERPC_DEF("740_v2.1", CPU_POWERPC_7x0_v21, 740,
+ "PowerPC 740 v2.1 (G3)")
+ POWERPC_DEF("750_v2.1", CPU_POWERPC_7x0_v21, 750,
+ "PowerPC 750 v2.1 (G3)")
+ POWERPC_DEF("740_v2.2", CPU_POWERPC_7x0_v22, 740,
+ "PowerPC 740 v2.2 (G3)")
+ POWERPC_DEF("750_v2.2", CPU_POWERPC_7x0_v22, 750,
+ "PowerPC 750 v2.2 (G3)")
+ POWERPC_DEF("740_v3.0", CPU_POWERPC_7x0_v30, 740,
+ "PowerPC 740 v3.0 (G3)")
+ POWERPC_DEF("750_v3.0", CPU_POWERPC_7x0_v30, 750,
+ "PowerPC 750 v3.0 (G3)")
+ POWERPC_DEF("740_v3.1", CPU_POWERPC_7x0_v31, 740,
+ "PowerPC 740 v3.1 (G3)")
+ POWERPC_DEF("750_v3.1", CPU_POWERPC_7x0_v31, 750,
+ "PowerPC 750 v3.1 (G3)")
+ POWERPC_DEF("740e", CPU_POWERPC_740E, 740,
+ "PowerPC 740E (G3)")
+ POWERPC_DEF("750e", CPU_POWERPC_750E, 750,
+ "PowerPC 750E (G3)")
+ POWERPC_DEF("740p", CPU_POWERPC_7x0P, 740,
+ "PowerPC 740P (G3)")
+ POWERPC_DEF("750p", CPU_POWERPC_7x0P, 750,
+ "PowerPC 750P (G3)")
+ POWERPC_DEF("750cl_v1.0", CPU_POWERPC_750CL_v10, 750cl,
+ "PowerPC 750CL v1.0")
+ POWERPC_DEF("750cl_v2.0", CPU_POWERPC_750CL_v20, 750cl,
+ "PowerPC 750CL v2.0")
+ POWERPC_DEF("750cx_v1.0", CPU_POWERPC_750CX_v10, 750cx,
+ "PowerPC 750CX v1.0 (G3 embedded)")
+ POWERPC_DEF("750cx_v2.0", CPU_POWERPC_750CX_v20, 750cx,
+ "PowerPC 750CX v2.1 (G3 embedded)")
+ POWERPC_DEF("750cx_v2.1", CPU_POWERPC_750CX_v21, 750cx,
+ "PowerPC 750CX v2.1 (G3 embedded)")
+ POWERPC_DEF("750cx_v2.2", CPU_POWERPC_750CX_v22, 750cx,
+ "PowerPC 750CX v2.2 (G3 embedded)")
+ POWERPC_DEF("750cxe_v2.1", CPU_POWERPC_750CXE_v21, 750cx,
+ "PowerPC 750CXe v2.1 (G3 embedded)")
+ POWERPC_DEF("750cxe_v2.2", CPU_POWERPC_750CXE_v22, 750cx,
+ "PowerPC 750CXe v2.2 (G3 embedded)")
+ POWERPC_DEF("750cxe_v2.3", CPU_POWERPC_750CXE_v23, 750cx,
+ "PowerPC 750CXe v2.3 (G3 embedded)")
+ POWERPC_DEF("750cxe_v2.4", CPU_POWERPC_750CXE_v24, 750cx,
+ "PowerPC 750CXe v2.4 (G3 embedded)")
+ POWERPC_DEF("750cxe_v2.4b", CPU_POWERPC_750CXE_v24b, 750cx,
+ "PowerPC 750CXe v2.4b (G3 embedded)")
+ POWERPC_DEF("750cxe_v3.0", CPU_POWERPC_750CXE_v30, 750cx,
+ "PowerPC 750CXe v3.0 (G3 embedded)")
+ POWERPC_DEF("750cxe_v3.1", CPU_POWERPC_750CXE_v31, 750cx,
+ "PowerPC 750CXe v3.1 (G3 embedded)")
+ POWERPC_DEF("750cxe_v3.1b", CPU_POWERPC_750CXE_v31b, 750cx,
+ "PowerPC 750CXe v3.1b (G3 embedded)")
+ POWERPC_DEF("750cxr", CPU_POWERPC_750CXR, 750cx,
+ "PowerPC 750CXr (G3 embedded)")
+ POWERPC_DEF("750fl", CPU_POWERPC_750FL, 750fx,
+ "PowerPC 750FL (G3 embedded)")
+ POWERPC_DEF("750fx_v1.0", CPU_POWERPC_750FX_v10, 750fx,
+ "PowerPC 750FX v1.0 (G3 embedded)")
+ POWERPC_DEF("750fx_v2.0", CPU_POWERPC_750FX_v20, 750fx,
+ "PowerPC 750FX v2.0 (G3 embedded)")
+ POWERPC_DEF("750fx_v2.1", CPU_POWERPC_750FX_v21, 750fx,
+ "PowerPC 750FX v2.1 (G3 embedded)")
+ POWERPC_DEF("750fx_v2.2", CPU_POWERPC_750FX_v22, 750fx,
+ "PowerPC 750FX v2.2 (G3 embedded)")
+ POWERPC_DEF("750fx_v2.3", CPU_POWERPC_750FX_v23, 750fx,
+ "PowerPC 750FX v2.3 (G3 embedded)")
+ POWERPC_DEF("750gl", CPU_POWERPC_750GL, 750gx,
+ "PowerPC 750GL (G3 embedded)")
+ POWERPC_DEF("750gx_v1.0", CPU_POWERPC_750GX_v10, 750gx,
+ "PowerPC 750GX v1.0 (G3 embedded)")
+ POWERPC_DEF("750gx_v1.1", CPU_POWERPC_750GX_v11, 750gx,
+ "PowerPC 750GX v1.1 (G3 embedded)")
+ POWERPC_DEF("750gx_v1.2", CPU_POWERPC_750GX_v12, 750gx,
+ "PowerPC 750GX v1.2 (G3 embedded)")
+ POWERPC_DEF("750l_v2.0", CPU_POWERPC_750L_v20, 750,
+ "PowerPC 750L v2.0 (G3 embedded)")
+ POWERPC_DEF("750l_v2.1", CPU_POWERPC_750L_v21, 750,
+ "PowerPC 750L v2.1 (G3 embedded)")
+ POWERPC_DEF("750l_v2.2", CPU_POWERPC_750L_v22, 750,
+ "PowerPC 750L v2.2 (G3 embedded)")
+ POWERPC_DEF("750l_v3.0", CPU_POWERPC_750L_v30, 750,
+ "PowerPC 750L v3.0 (G3 embedded)")
+ POWERPC_DEF("750l_v3.2", CPU_POWERPC_750L_v32, 750,
+ "PowerPC 750L v3.2 (G3 embedded)")
+ POWERPC_DEF("745_v1.0", CPU_POWERPC_7x5_v10, 745,
+ "PowerPC 745 v1.0")
+ POWERPC_DEF("755_v1.0", CPU_POWERPC_7x5_v10, 755,
+ "PowerPC 755 v1.0")
+ POWERPC_DEF("745_v1.1", CPU_POWERPC_7x5_v11, 745,
+ "PowerPC 745 v1.1")
+ POWERPC_DEF("755_v1.1", CPU_POWERPC_7x5_v11, 755,
+ "PowerPC 755 v1.1")
+ POWERPC_DEF("745_v2.0", CPU_POWERPC_7x5_v20, 745,
+ "PowerPC 745 v2.0")
+ POWERPC_DEF("755_v2.0", CPU_POWERPC_7x5_v20, 755,
+ "PowerPC 755 v2.0")
+ POWERPC_DEF("745_v2.1", CPU_POWERPC_7x5_v21, 745,
+ "PowerPC 745 v2.1")
+ POWERPC_DEF("755_v2.1", CPU_POWERPC_7x5_v21, 755,
+ "PowerPC 755 v2.1")
+ POWERPC_DEF("745_v2.2", CPU_POWERPC_7x5_v22, 745,
+ "PowerPC 745 v2.2")
+ POWERPC_DEF("755_v2.2", CPU_POWERPC_7x5_v22, 755,
+ "PowerPC 755 v2.2")
+ POWERPC_DEF("745_v2.3", CPU_POWERPC_7x5_v23, 745,
+ "PowerPC 745 v2.3")
+ POWERPC_DEF("755_v2.3", CPU_POWERPC_7x5_v23, 755,
+ "PowerPC 755 v2.3")
+ POWERPC_DEF("745_v2.4", CPU_POWERPC_7x5_v24, 745,
+ "PowerPC 745 v2.4")
+ POWERPC_DEF("755_v2.4", CPU_POWERPC_7x5_v24, 755,
+ "PowerPC 755 v2.4")
+ POWERPC_DEF("745_v2.5", CPU_POWERPC_7x5_v25, 745,
+ "PowerPC 745 v2.5")
+ POWERPC_DEF("755_v2.5", CPU_POWERPC_7x5_v25, 755,
+ "PowerPC 755 v2.5")
+ POWERPC_DEF("745_v2.6", CPU_POWERPC_7x5_v26, 745,
+ "PowerPC 745 v2.6")
+ POWERPC_DEF("755_v2.6", CPU_POWERPC_7x5_v26, 755,
+ "PowerPC 755 v2.6")
+ POWERPC_DEF("745_v2.7", CPU_POWERPC_7x5_v27, 745,
+ "PowerPC 745 v2.7")
+ POWERPC_DEF("755_v2.7", CPU_POWERPC_7x5_v27, 755,
+ "PowerPC 755 v2.7")
+ POWERPC_DEF("745_v2.8", CPU_POWERPC_7x5_v28, 745,
+ "PowerPC 745 v2.8")
+ POWERPC_DEF("755_v2.8", CPU_POWERPC_7x5_v28, 755,
+ "PowerPC 755 v2.8")
+#if defined(TODO)
+ POWERPC_DEF("745p", CPU_POWERPC_7x5P, 745,
+ "PowerPC 745P (G3)")
+ POWERPC_DEF("755p", CPU_POWERPC_7x5P, 755,
+ "PowerPC 755P (G3)")
+#endif
+ /* PowerPC 74xx family */
+ POWERPC_DEF("7400_v1.0", CPU_POWERPC_7400_v10, 7400,
+ "PowerPC 7400 v1.0 (G4)")
+ POWERPC_DEF("7400_v1.1", CPU_POWERPC_7400_v11, 7400,
+ "PowerPC 7400 v1.1 (G4)")
+ POWERPC_DEF("7400_v2.0", CPU_POWERPC_7400_v20, 7400,
+ "PowerPC 7400 v2.0 (G4)")
+ POWERPC_DEF("7400_v2.1", CPU_POWERPC_7400_v21, 7400,
+ "PowerPC 7400 v2.1 (G4)")
+ POWERPC_DEF("7400_v2.2", CPU_POWERPC_7400_v22, 7400,
+ "PowerPC 7400 v2.2 (G4)")
+ POWERPC_DEF("7400_v2.6", CPU_POWERPC_7400_v26, 7400,
+ "PowerPC 7400 v2.6 (G4)")
+ POWERPC_DEF("7400_v2.7", CPU_POWERPC_7400_v27, 7400,
+ "PowerPC 7400 v2.7 (G4)")
+ POWERPC_DEF("7400_v2.8", CPU_POWERPC_7400_v28, 7400,
+ "PowerPC 7400 v2.8 (G4)")
+ POWERPC_DEF("7400_v2.9", CPU_POWERPC_7400_v29, 7400,
+ "PowerPC 7400 v2.9 (G4)")
+ POWERPC_DEF("7410_v1.0", CPU_POWERPC_7410_v10, 7410,
+ "PowerPC 7410 v1.0 (G4)")
+ POWERPC_DEF("7410_v1.1", CPU_POWERPC_7410_v11, 7410,
+ "PowerPC 7410 v1.1 (G4)")
+ POWERPC_DEF("7410_v1.2", CPU_POWERPC_7410_v12, 7410,
+ "PowerPC 7410 v1.2 (G4)")
+ POWERPC_DEF("7410_v1.3", CPU_POWERPC_7410_v13, 7410,
+ "PowerPC 7410 v1.3 (G4)")
+ POWERPC_DEF("7410_v1.4", CPU_POWERPC_7410_v14, 7410,
+ "PowerPC 7410 v1.4 (G4)")
+ POWERPC_DEF("7448_v1.0", CPU_POWERPC_7448_v10, 7400,
+ "PowerPC 7448 v1.0 (G4)")
+ POWERPC_DEF("7448_v1.1", CPU_POWERPC_7448_v11, 7400,
+ "PowerPC 7448 v1.1 (G4)")
+ POWERPC_DEF("7448_v2.0", CPU_POWERPC_7448_v20, 7400,
+ "PowerPC 7448 v2.0 (G4)")
+ POWERPC_DEF("7448_v2.1", CPU_POWERPC_7448_v21, 7400,
+ "PowerPC 7448 v2.1 (G4)")
+ POWERPC_DEF("7450_v1.0", CPU_POWERPC_7450_v10, 7450,
+ "PowerPC 7450 v1.0 (G4)")
+ POWERPC_DEF("7450_v1.1", CPU_POWERPC_7450_v11, 7450,
+ "PowerPC 7450 v1.1 (G4)")
+ POWERPC_DEF("7450_v1.2", CPU_POWERPC_7450_v12, 7450,
+ "PowerPC 7450 v1.2 (G4)")
+ POWERPC_DEF("7450_v2.0", CPU_POWERPC_7450_v20, 7450,
+ "PowerPC 7450 v2.0 (G4)")
+ POWERPC_DEF("7450_v2.1", CPU_POWERPC_7450_v21, 7450,
+ "PowerPC 7450 v2.1 (G4)")
+ POWERPC_DEF("7441_v2.1", CPU_POWERPC_7450_v21, 7440,
+ "PowerPC 7441 v2.1 (G4)")
+ POWERPC_DEF("7441_v2.3", CPU_POWERPC_74x1_v23, 7440,
+ "PowerPC 7441 v2.3 (G4)")
+ POWERPC_DEF("7451_v2.3", CPU_POWERPC_74x1_v23, 7450,
+ "PowerPC 7451 v2.3 (G4)")
+ POWERPC_DEF("7441_v2.10", CPU_POWERPC_74x1_v210, 7440,
+ "PowerPC 7441 v2.10 (G4)")
+ POWERPC_DEF("7451_v2.10", CPU_POWERPC_74x1_v210, 7450,
+ "PowerPC 7451 v2.10 (G4)")
+ POWERPC_DEF("7445_v1.0", CPU_POWERPC_74x5_v10, 7445,
+ "PowerPC 7445 v1.0 (G4)")
+ POWERPC_DEF("7455_v1.0", CPU_POWERPC_74x5_v10, 7455,
+ "PowerPC 7455 v1.0 (G4)")
+ POWERPC_DEF("7445_v2.1", CPU_POWERPC_74x5_v21, 7445,
+ "PowerPC 7445 v2.1 (G4)")
+ POWERPC_DEF("7455_v2.1", CPU_POWERPC_74x5_v21, 7455,
+ "PowerPC 7455 v2.1 (G4)")
+ POWERPC_DEF("7445_v3.2", CPU_POWERPC_74x5_v32, 7445,
+ "PowerPC 7445 v3.2 (G4)")
+ POWERPC_DEF("7455_v3.2", CPU_POWERPC_74x5_v32, 7455,
+ "PowerPC 7455 v3.2 (G4)")
+ POWERPC_DEF("7445_v3.3", CPU_POWERPC_74x5_v33, 7445,
+ "PowerPC 7445 v3.3 (G4)")
+ POWERPC_DEF("7455_v3.3", CPU_POWERPC_74x5_v33, 7455,
+ "PowerPC 7455 v3.3 (G4)")
+ POWERPC_DEF("7445_v3.4", CPU_POWERPC_74x5_v34, 7445,
+ "PowerPC 7445 v3.4 (G4)")
+ POWERPC_DEF("7455_v3.4", CPU_POWERPC_74x5_v34, 7455,
+ "PowerPC 7455 v3.4 (G4)")
+ POWERPC_DEF("7447_v1.0", CPU_POWERPC_74x7_v10, 7445,
+ "PowerPC 7447 v1.0 (G4)")
+ POWERPC_DEF("7457_v1.0", CPU_POWERPC_74x7_v10, 7455,
+ "PowerPC 7457 v1.0 (G4)")
+ POWERPC_DEF("7447_v1.1", CPU_POWERPC_74x7_v11, 7445,
+ "PowerPC 7447 v1.1 (G4)")
+ POWERPC_DEF("7457_v1.1", CPU_POWERPC_74x7_v11, 7455,
+ "PowerPC 7457 v1.1 (G4)")
+ POWERPC_DEF("7457_v1.2", CPU_POWERPC_74x7_v12, 7455,
+ "PowerPC 7457 v1.2 (G4)")
+ POWERPC_DEF("7447A_v1.0", CPU_POWERPC_74x7A_v10, 7445,
+ "PowerPC 7447A v1.0 (G4)")
+ POWERPC_DEF("7457A_v1.0", CPU_POWERPC_74x7A_v10, 7455,
+ "PowerPC 7457A v1.0 (G4)")
+ POWERPC_DEF("7447A_v1.1", CPU_POWERPC_74x7A_v11, 7445,
+ "PowerPC 7447A v1.1 (G4)")
+ POWERPC_DEF("7457A_v1.1", CPU_POWERPC_74x7A_v11, 7455,
+ "PowerPC 7457A v1.1 (G4)")
+ POWERPC_DEF("7447A_v1.2", CPU_POWERPC_74x7A_v12, 7445,
+ "PowerPC 7447A v1.2 (G4)")
+ POWERPC_DEF("7457A_v1.2", CPU_POWERPC_74x7A_v12, 7455,
+ "PowerPC 7457A v1.2 (G4)")
+ /* 64 bits PowerPC */
+#if defined (TARGET_PPC64)
+#if defined(TODO)
+ POWERPC_DEF("620", CPU_POWERPC_620, 620,
+ "PowerPC 620")
+ POWERPC_DEF("630", CPU_POWERPC_630, 630,
+ "PowerPC 630 (POWER3)")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("631", CPU_POWERPC_631, 631,
+ "PowerPC 631 (Power 3+)")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("POWER4", CPU_POWERPC_POWER4, POWER4,
+ "POWER4")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("POWER4+", CPU_POWERPC_POWER4P, POWER4P,
+ "POWER4p")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("POWER5", CPU_POWERPC_POWER5, POWER5,
+ "POWER5")
+#endif
+ POWERPC_DEF("POWER5+", CPU_POWERPC_POWER5P, POWER5P,
+ "POWER5+")
+ POWERPC_DEF("POWER5+_v2.1", CPU_POWERPC_POWER5P_v21, POWER5P,
+ "POWER5+ v2.1")
+#if defined(TODO)
+ POWERPC_DEF("POWER6", CPU_POWERPC_POWER6, POWER6,
+ "POWER6")
+ POWERPC_DEF("POWER6_5", CPU_POWERPC_POWER6_5, POWER5,
+ "POWER6 running in POWER5 mode")
+ POWERPC_DEF("POWER6A", CPU_POWERPC_POWER6A, POWER6,
+ "POWER6A")
+#endif
+ POWERPC_DEF("POWER7_v2.0", CPU_POWERPC_POWER7_v20, POWER7,
+ "POWER7 v2.0")
+ POWERPC_DEF("POWER7_v2.1", CPU_POWERPC_POWER7_v21, POWER7,
+ "POWER7 v2.1")
+ POWERPC_DEF("POWER7_v2.3", CPU_POWERPC_POWER7_v23, POWER7,
+ "POWER7 v2.3")
+ POWERPC_DEF("POWER7+_v2.1", CPU_POWERPC_POWER7P_v21, POWER7,
+ "POWER7+ v2.1")
+ POWERPC_DEF("POWER8_v1.0", CPU_POWERPC_POWER8_v10, POWER8,
+ "POWER8 v1.0")
+ POWERPC_DEF("970", CPU_POWERPC_970, 970,
+ "PowerPC 970")
+ POWERPC_DEF("970fx_v1.0", CPU_POWERPC_970FX_v10, 970FX,
+ "PowerPC 970FX v1.0 (G5)")
+ POWERPC_DEF("970fx_v2.0", CPU_POWERPC_970FX_v20, 970FX,
+ "PowerPC 970FX v2.0 (G5)")
+ POWERPC_DEF("970fx_v2.1", CPU_POWERPC_970FX_v21, 970FX,
+ "PowerPC 970FX v2.1 (G5)")
+ POWERPC_DEF("970fx_v3.0", CPU_POWERPC_970FX_v30, 970FX,
+ "PowerPC 970FX v3.0 (G5)")
+ POWERPC_DEF("970fx_v3.1", CPU_POWERPC_970FX_v31, 970FX,
+ "PowerPC 970FX v3.1 (G5)")
+ POWERPC_DEF("970gx", CPU_POWERPC_970GX, 970GX,
+ "PowerPC 970GX (G5)")
+ POWERPC_DEF("970mp_v1.0", CPU_POWERPC_970MP_v10, 970MP,
+ "PowerPC 970MP v1.0")
+ POWERPC_DEF("970mp_v1.1", CPU_POWERPC_970MP_v11, 970MP,
+ "PowerPC 970MP v1.1")
+#if defined(TODO)
+ POWERPC_DEF("Cell", CPU_POWERPC_CELL, 970,
+ "PowerPC Cell")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("Cell_v1.0", CPU_POWERPC_CELL_v10, 970,
+ "PowerPC Cell v1.0")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("Cell_v2.0", CPU_POWERPC_CELL_v20, 970,
+ "PowerPC Cell v2.0")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("Cell_v3.0", CPU_POWERPC_CELL_v30, 970,
+ "PowerPC Cell v3.0")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("Cell_v3.1", CPU_POWERPC_CELL_v31, 970,
+ "PowerPC Cell v3.1")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("Cell_v3.2", CPU_POWERPC_CELL_v32, 970,
+ "PowerPC Cell v3.2")
+#endif
+#if defined(TODO)
+ /* This one seems to support the whole POWER2 instruction set
+ * and the PowerPC 64 one.
+ */
+ /* What about A10 & A30 ? */
+ POWERPC_DEF("RS64", CPU_POWERPC_RS64, RS64,
+ "RS64 (Apache/A35)")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("RS64-II", CPU_POWERPC_RS64II, RS64,
+ "RS64-II (NorthStar/A50)")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("RS64-III", CPU_POWERPC_RS64III, RS64,
+ "RS64-III (Pulsar)")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("RS64-IV", CPU_POWERPC_RS64IV, RS64,
+ "RS64-IV (IceStar/IStar/SStar)")
+#endif
+#endif /* defined (TARGET_PPC64) */
+ /* POWER */
+#if defined(TODO)
+ POWERPC_DEF("POWER", CPU_POWERPC_POWER, POWER,
+ "Original POWER")
+#endif
+#if defined(TODO)
+ POWERPC_DEF("POWER2", CPU_POWERPC_POWER2, POWER,
+ "POWER2")
+#endif
+ /* PA semi cores */
+#if defined(TODO)
+ POWERPC_DEF("PA6T", CPU_POWERPC_PA6T, PA6T,
+ "PA PA6T")
+#endif
+
+
+/***************************************************************************/
+/* PowerPC CPU aliases */
+
+PowerPCCPUAlias ppc_cpu_aliases[] = {
+ { "403", "403GC" },
+ { "405", "405D4" },
+ { "405CR", "405CRc" },
+ { "405GP", "405GPd" },
+ { "405GPe", "405CRc" },
+ { "x2vp7", "x2vp4" },
+ { "x2vp50", "x2vp20" },
+
+ { "440EP", "440EPb" },
+ { "440GP", "440GPc" },
+ { "440GR", "440GRa" },
+ { "440GX", "440GXf" },
+
+ { "RCPU", "MPC5xx" },
+ /* MPC5xx microcontrollers */
+ { "MGT560", "MPC5xx" },
+ { "MPC509", "MPC5xx" },
+ { "MPC533", "MPC5xx" },
+ { "MPC534", "MPC5xx" },
+ { "MPC555", "MPC5xx" },
+ { "MPC556", "MPC5xx" },
+ { "MPC560", "MPC5xx" },
+ { "MPC561", "MPC5xx" },
+ { "MPC562", "MPC5xx" },
+ { "MPC563", "MPC5xx" },
+ { "MPC564", "MPC5xx" },
+ { "MPC565", "MPC5xx" },
+ { "MPC566", "MPC5xx" },
+
+ { "PowerQUICC", "MPC8xx" },
+ /* MPC8xx microcontrollers */
+ { "MGT823", "MPC8xx" },
+ { "MPC821", "MPC8xx" },
+ { "MPC823", "MPC8xx" },
+ { "MPC850", "MPC8xx" },
+ { "MPC852T", "MPC8xx" },
+ { "MPC855T", "MPC8xx" },
+ { "MPC857", "MPC8xx" },
+ { "MPC859", "MPC8xx" },
+ { "MPC860", "MPC8xx" },
+ { "MPC862", "MPC8xx" },
+ { "MPC866", "MPC8xx" },
+ { "MPC870", "MPC8xx" },
+ { "MPC875", "MPC8xx" },
+ { "MPC880", "MPC8xx" },
+ { "MPC885", "MPC8xx" },
+
+ /* PowerPC MPC603 microcontrollers */
+ { "MPC8240", "603" },
+
+ { "MPC52xx", "MPC5200" },
+ { "MPC5200", "MPC5200_v12" },
+ { "MPC5200B", "MPC5200B_v21" },
+
+ { "MPC82xx", "MPC8280" },
+ { "PowerQUICC-II", "MPC82xx" },
+ { "MPC8241", "G2HiP4" },
+ { "MPC8245", "G2HiP4" },
+ { "MPC8247", "G2leGP3" },
+ { "MPC8248", "G2leGP3" },
+ { "MPC8250", "MPC8250_HiP4" },
+ { "MPC8250_HiP3", "G2HiP3" },
+ { "MPC8250_HiP4", "G2HiP4" },
+ { "MPC8255", "MPC8255_HiP4" },
+ { "MPC8255_HiP3", "G2HiP3" },
+ { "MPC8255_HiP4", "G2HiP4" },
+ { "MPC8260", "MPC8260_HiP4" },
+ { "MPC8260_HiP3", "G2HiP3" },
+ { "MPC8260_HiP4", "G2HiP4" },
+ { "MPC8264", "MPC8264_HiP4" },
+ { "MPC8264_HiP3", "G2HiP3" },
+ { "MPC8264_HiP4", "G2HiP4" },
+ { "MPC8265", "MPC8265_HiP4" },
+ { "MPC8265_HiP3", "G2HiP3" },
+ { "MPC8265_HiP4", "G2HiP4" },
+ { "MPC8266", "MPC8266_HiP4" },
+ { "MPC8266_HiP3", "G2HiP3" },
+ { "MPC8266_HiP4", "G2HiP4" },
+ { "MPC8270", "G2leGP3" },
+ { "MPC8271", "G2leGP3" },
+ { "MPC8272", "G2leGP3" },
+ { "MPC8275", "G2leGP3" },
+ { "MPC8280", "G2leGP3" },
+ { "e200", "e200z6" },
+ { "e300", "e300c3" },
+ { "MPC8347", "MPC8347T" },
+ { "MPC8347A", "MPC8347AT" },
+ { "MPC8347E", "MPC8347ET" },
+ { "MPC8347EA", "MPC8347EAT" },
+ { "e500", "e500v2_v22" },
+ { "e500v1", "e500_v20" },
+ { "e500v2", "e500v2_v22" },
+ { "MPC8533", "MPC8533_v11" },
+ { "MPC8533E", "MPC8533E_v11" },
+ { "MPC8540", "MPC8540_v21" },
+ { "MPC8541", "MPC8541_v11" },
+ { "MPC8541E", "MPC8541E_v11" },
+ { "MPC8543", "MPC8543_v21" },
+ { "MPC8543E", "MPC8543E_v21" },
+ { "MPC8544", "MPC8544_v11" },
+ { "MPC8544E", "MPC8544E_v11" },
+ { "MPC8545", "MPC8545_v21" },
+ { "MPC8545E", "MPC8545E_v21" },
+ { "MPC8547E", "MPC8547E_v21" },
+ { "MPC8548", "MPC8548_v21" },
+ { "MPC8548E", "MPC8548E_v21" },
+ { "MPC8555", "MPC8555_v11" },
+ { "MPC8555E", "MPC8555E_v11" },
+ { "MPC8560", "MPC8560_v21" },
+ { "601", "601_v2" },
+ { "601v", "601_v2" },
+ { "Vanilla", "603" },
+ { "603e", "603e_v4.1" },
+ { "Stretch", "603e" },
+ { "Vaillant", "603e7v" },
+ { "603r", "603e7t" },
+ { "Goldeneye", "603r" },
+ { "604e", "604e_v2.4" },
+ { "Sirocco", "604e" },
+ { "Mach5", "604r" },
+ { "740", "740_v3.1" },
+ { "Arthur", "740" },
+ { "750", "750_v3.1" },
+ { "Typhoon", "750" },
+ { "G3", "750" },
+ { "Conan/Doyle", "750p" },
+ { "750cl", "750cl_v2.0" },
+ { "750cx", "750cx_v2.2" },
+ { "750cxe", "750cxe_v3.1b" },
+ { "750fx", "750fx_v2.3" },
+ { "750gx", "750gx_v1.2" },
+ { "750l", "750l_v3.2" },
+ { "LoneStar", "750l" },
+ { "745", "745_v2.8" },
+ { "755", "755_v2.8" },
+ { "Goldfinger", "755" },
+ { "7400", "7400_v2.9" },
+ { "Max", "7400" },
+ { "G4", "7400" },
+ { "7410", "7410_v1.4" },
+ { "Nitro", "7410" },
+ { "7448", "7448_v2.1" },
+ { "7450", "7450_v2.1" },
+ { "Vger", "7450" },
+ { "7441", "7441_v2.3" },
+ { "7451", "7451_v2.3" },
+ { "7445", "7445_v3.2" },
+ { "7455", "7455_v3.2" },
+ { "Apollo6", "7455" },
+ { "7447", "7447_v1.2" },
+ { "7457", "7457_v1.2" },
+ { "Apollo7", "7457" },
+ { "7447A", "7447A_v1.2" },
+ { "7457A", "7457A_v1.2" },
+ { "Apollo7PM", "7457A_v1.0" },
+#if defined(TARGET_PPC64)
+ { "Trident", "620" },
+ { "POWER3", "630" },
+ { "Boxer", "POWER3" },
+ { "Dino", "POWER3" },
+ { "POWER3+", "631" },
+ { "POWER5gr", "POWER5" },
+ { "POWER5gs", "POWER5+" },
+ { "POWER7", "POWER7_v2.3" },
+ { "POWER7+", "POWER7+_v2.1" },
+ { "POWER8", "POWER8_v1.0" },
+ { "970fx", "970fx_v3.1" },
+ { "970mp", "970mp_v1.1" },
+ { "Apache", "RS64" },
+ { "A35", "RS64" },
+ { "NorthStar", "RS64-II" },
+ { "A50", "RS64-II" },
+ { "Pulsar", "RS64-III" },
+ { "IceStar", "RS64-IV" },
+ { "IStar", "RS64-IV" },
+ { "SStar", "RS64-IV" },
+#endif
+ { "RIOS", "POWER" },
+ { "RSC", "POWER" },
+ { "RSC3308", "POWER" },
+ { "RSC4608", "POWER" },
+ { "RSC2", "POWER2" },
+ { "P2SC", "POWER2" },
+
+ /* Generic PowerPCs */
+#if defined(TARGET_PPC64)
+ { "ppc64", "970fx" },
+#endif
+ { "ppc32", "604" },
+ { "ppc", "ppc32" },
+ { "default", "ppc" },
+ { NULL, NULL }
+};
diff --git a/target-ppc/cpu-models.h b/target-ppc/cpu-models.h
new file mode 100644
index 000000000..d9145d147
--- /dev/null
+++ b/target-ppc/cpu-models.h
@@ -0,0 +1,741 @@
+/*
+ * PowerPC CPU initialization for qemu.
+ *
+ * Copyright (c) 2003-2007 Jocelyn Mayer
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2013 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_PPC_CPU_MODELS_H
+#define TARGET_PPC_CPU_MODELS_H
+
+/**
+ * PowerPCCPUAlias:
+ * @alias: The alias name.
+ * @model: The CPU model @alias refers to.
+ *
+ * A mapping entry from CPU @alias to CPU @model.
+ */
+typedef struct PowerPCCPUAlias {
+ const char *alias;
+ const char *model;
+ ObjectClass *oc;
+} PowerPCCPUAlias;
+
+extern PowerPCCPUAlias ppc_cpu_aliases[];
+
+/*****************************************************************************/
+/* PVR definitions for most known PowerPC */
+enum {
+ /* PowerPC 401 family */
+ /* Generic PowerPC 401 */
+#define CPU_POWERPC_401 CPU_POWERPC_401G2
+ /* PowerPC 401 cores */
+ CPU_POWERPC_401A1 = 0x00210000,
+ CPU_POWERPC_401B2 = 0x00220000,
+#if 0
+ CPU_POWERPC_401B3 = xxx,
+#endif
+ CPU_POWERPC_401C2 = 0x00230000,
+ CPU_POWERPC_401D2 = 0x00240000,
+ CPU_POWERPC_401E2 = 0x00250000,
+ CPU_POWERPC_401F2 = 0x00260000,
+ CPU_POWERPC_401G2 = 0x00270000,
+ /* PowerPC 401 microcontrolers */
+#if 0
+ CPU_POWERPC_401GF = xxx,
+#endif
+#define CPU_POWERPC_IOP480 CPU_POWERPC_401B2
+ /* IBM Processor for Network Resources */
+ CPU_POWERPC_COBRA = 0x10100000, /* XXX: 405 ? */
+#if 0
+ CPU_POWERPC_XIPCHIP = xxx,
+#endif
+ /* PowerPC 403 family */
+ /* PowerPC 403 microcontrollers */
+ CPU_POWERPC_403GA = 0x00200011,
+ CPU_POWERPC_403GB = 0x00200100,
+ CPU_POWERPC_403GC = 0x00200200,
+ CPU_POWERPC_403GCX = 0x00201400,
+#if 0
+ CPU_POWERPC_403GP = xxx,
+#endif
+ /* PowerPC 405 family */
+ /* PowerPC 405 cores */
+#if 0
+ CPU_POWERPC_405A3 = xxx,
+#endif
+#if 0
+ CPU_POWERPC_405A4 = xxx,
+#endif
+#if 0
+ CPU_POWERPC_405B3 = xxx,
+#endif
+#if 0
+ CPU_POWERPC_405B4 = xxx,
+#endif
+#if 0
+ CPU_POWERPC_405C3 = xxx,
+#endif
+#if 0
+ CPU_POWERPC_405C4 = xxx,
+#endif
+ CPU_POWERPC_405D2 = 0x20010000,
+#if 0
+ CPU_POWERPC_405D3 = xxx,
+#endif
+ CPU_POWERPC_405D4 = 0x41810000,
+#if 0
+ CPU_POWERPC_405D5 = xxx,
+#endif
+#if 0
+ CPU_POWERPC_405E4 = xxx,
+#endif
+#if 0
+ CPU_POWERPC_405F4 = xxx,
+#endif
+#if 0
+ CPU_POWERPC_405F5 = xxx,
+#endif
+#if 0
+ CPU_POWERPC_405F6 = xxx,
+#endif
+ /* PowerPC 405 microcontrolers */
+ /* XXX: missing 0x200108a0 */
+ CPU_POWERPC_405CRa = 0x40110041,
+ CPU_POWERPC_405CRb = 0x401100C5,
+ CPU_POWERPC_405CRc = 0x40110145,
+ CPU_POWERPC_405EP = 0x51210950,
+#if 0
+ CPU_POWERPC_405EXr = xxx,
+#endif
+ CPU_POWERPC_405EZ = 0x41511460, /* 0x51210950 ? */
+#if 0
+ CPU_POWERPC_405FX = xxx,
+#endif
+ CPU_POWERPC_405GPa = 0x40110000,
+ CPU_POWERPC_405GPb = 0x40110040,
+ CPU_POWERPC_405GPc = 0x40110082,
+ CPU_POWERPC_405GPd = 0x401100C4,
+ CPU_POWERPC_405GPR = 0x50910951,
+#if 0
+ CPU_POWERPC_405H = xxx,
+#endif
+#if 0
+ CPU_POWERPC_405L = xxx,
+#endif
+ CPU_POWERPC_405LP = 0x41F10000,
+#if 0
+ CPU_POWERPC_405PM = xxx,
+#endif
+#if 0
+ CPU_POWERPC_405PS = xxx,
+#endif
+#if 0
+ CPU_POWERPC_405S = xxx,
+#endif
+ /* IBM network processors */
+ CPU_POWERPC_NPE405H = 0x414100C0,
+ CPU_POWERPC_NPE405H2 = 0x41410140,
+ CPU_POWERPC_NPE405L = 0x416100C0,
+ CPU_POWERPC_NPE4GS3 = 0x40B10000,
+#if 0
+ CPU_POWERPC_NPCxx1 = xxx,
+#endif
+#if 0
+ CPU_POWERPC_NPR161 = xxx,
+#endif
+#if 0
+ CPU_POWERPC_LC77700 = xxx,
+#endif
+ /* IBM STBxxx (PowerPC 401/403/405 core based microcontrollers) */
+#if 0
+ CPU_POWERPC_STB01000 = xxx,
+#endif
+#if 0
+ CPU_POWERPC_STB01010 = xxx,
+#endif
+#if 0
+ CPU_POWERPC_STB0210 = xxx, /* 401B3 */
+#endif
+ CPU_POWERPC_STB03 = 0x40310000, /* 0x40130000 ? */
+#if 0
+ CPU_POWERPC_STB043 = xxx,
+#endif
+#if 0
+ CPU_POWERPC_STB045 = xxx,
+#endif
+ CPU_POWERPC_STB04 = 0x41810000,
+ CPU_POWERPC_STB25 = 0x51510950,
+#if 0
+ CPU_POWERPC_STB130 = xxx,
+#endif
+ /* Xilinx cores */
+ CPU_POWERPC_X2VP4 = 0x20010820,
+ CPU_POWERPC_X2VP20 = 0x20010860,
+#if 0
+ CPU_POWERPC_ZL10310 = xxx,
+#endif
+#if 0
+ CPU_POWERPC_ZL10311 = xxx,
+#endif
+#if 0
+ CPU_POWERPC_ZL10320 = xxx,
+#endif
+#if 0
+ CPU_POWERPC_ZL10321 = xxx,
+#endif
+ /* PowerPC 440 family */
+ /* Generic PowerPC 440 */
+#define CPU_POWERPC_440 CPU_POWERPC_440GXf
+ /* PowerPC 440 cores */
+#if 0
+ CPU_POWERPC_440A4 = xxx,
+#endif
+ CPU_POWERPC_440_XILINX = 0x7ff21910,
+#if 0
+ CPU_POWERPC_440A5 = xxx,
+#endif
+#if 0
+ CPU_POWERPC_440B4 = xxx,
+#endif
+#if 0
+ CPU_POWERPC_440F5 = xxx,
+#endif
+#if 0
+ CPU_POWERPC_440G5 = xxx,
+#endif
+#if 0
+ CPU_POWERPC_440H4 = xxx,
+#endif
+#if 0
+ CPU_POWERPC_440H6 = xxx,
+#endif
+ /* PowerPC 440 microcontrolers */
+ CPU_POWERPC_440EPa = 0x42221850,
+ CPU_POWERPC_440EPb = 0x422218D3,
+ CPU_POWERPC_440GPb = 0x40120440,
+ CPU_POWERPC_440GPc = 0x40120481,
+#define CPU_POWERPC_440GRa CPU_POWERPC_440EPb
+ CPU_POWERPC_440GRX = 0x200008D0,
+#define CPU_POWERPC_440EPX CPU_POWERPC_440GRX
+ CPU_POWERPC_440GXa = 0x51B21850,
+ CPU_POWERPC_440GXb = 0x51B21851,
+ CPU_POWERPC_440GXc = 0x51B21892,
+ CPU_POWERPC_440GXf = 0x51B21894,
+#if 0
+ CPU_POWERPC_440S = xxx,
+#endif
+ CPU_POWERPC_440SP = 0x53221850,
+ CPU_POWERPC_440SP2 = 0x53221891,
+ CPU_POWERPC_440SPE = 0x53421890,
+ /* PowerPC 460 family */
+#if 0
+ /* Generic PowerPC 464 */
+#define CPU_POWERPC_464 CPU_POWERPC_464H90
+#endif
+ /* PowerPC 464 microcontrolers */
+#if 0
+ CPU_POWERPC_464H90 = xxx,
+#endif
+#if 0
+ CPU_POWERPC_464H90FP = xxx,
+#endif
+ /* Freescale embedded PowerPC cores */
+ /* PowerPC MPC 5xx cores (aka RCPU) */
+ CPU_POWERPC_MPC5xx = 0x00020020,
+ /* PowerPC MPC 8xx cores (aka PowerQUICC) */
+ CPU_POWERPC_MPC8xx = 0x00500000,
+ /* G2 cores (aka PowerQUICC-II) */
+ CPU_POWERPC_G2 = 0x00810011,
+ CPU_POWERPC_G2H4 = 0x80811010,
+ CPU_POWERPC_G2gp = 0x80821010,
+ CPU_POWERPC_G2ls = 0x90810010,
+ CPU_POWERPC_MPC603 = 0x00810100,
+ CPU_POWERPC_G2_HIP3 = 0x00810101,
+ CPU_POWERPC_G2_HIP4 = 0x80811014,
+ /* G2_LE core (aka PowerQUICC-II) */
+ CPU_POWERPC_G2LE = 0x80820010,
+ CPU_POWERPC_G2LEgp = 0x80822010,
+ CPU_POWERPC_G2LEls = 0xA0822010,
+ CPU_POWERPC_G2LEgp1 = 0x80822011,
+ CPU_POWERPC_G2LEgp3 = 0x80822013,
+ /* MPC52xx microcontrollers */
+ /* XXX: MPC 5121 ? */
+#define CPU_POWERPC_MPC5200_v10 CPU_POWERPC_G2LEgp1
+#define CPU_POWERPC_MPC5200_v11 CPU_POWERPC_G2LEgp1
+#define CPU_POWERPC_MPC5200_v12 CPU_POWERPC_G2LEgp1
+#define CPU_POWERPC_MPC5200B_v20 CPU_POWERPC_G2LEgp1
+#define CPU_POWERPC_MPC5200B_v21 CPU_POWERPC_G2LEgp1
+ /* e200 family */
+ /* e200 cores */
+#if 0
+ CPU_POWERPC_e200z0 = xxx,
+#endif
+#if 0
+ CPU_POWERPC_e200z1 = xxx,
+#endif
+#if 0 /* ? */
+ CPU_POWERPC_e200z3 = 0x81120000,
+#endif
+ CPU_POWERPC_e200z5 = 0x81000000,
+ CPU_POWERPC_e200z6 = 0x81120000,
+ /* MPC55xx microcontrollers */
+#define CPU_POWERPC_MPC55xx CPU_POWERPC_MPC5567
+#if 0
+#define CPU_POWERPC_MPC5514E CPU_POWERPC_MPC5514E_v1
+#define CPU_POWERPC_MPC5514E_v0 CPU_POWERPC_e200z0
+#define CPU_POWERPC_MPC5514E_v1 CPU_POWERPC_e200z1
+#define CPU_POWERPC_MPC5514G CPU_POWERPC_MPC5514G_v1
+#define CPU_POWERPC_MPC5514G_v0 CPU_POWERPC_e200z0
+#define CPU_POWERPC_MPC5514G_v1 CPU_POWERPC_e200z1
+#define CPU_POWERPC_MPC5515S CPU_POWERPC_e200z1
+#define CPU_POWERPC_MPC5516E CPU_POWERPC_MPC5516E_v1
+#define CPU_POWERPC_MPC5516E_v0 CPU_POWERPC_e200z0
+#define CPU_POWERPC_MPC5516E_v1 CPU_POWERPC_e200z1
+#define CPU_POWERPC_MPC5516G CPU_POWERPC_MPC5516G_v1
+#define CPU_POWERPC_MPC5516G_v0 CPU_POWERPC_e200z0
+#define CPU_POWERPC_MPC5516G_v1 CPU_POWERPC_e200z1
+#define CPU_POWERPC_MPC5516S CPU_POWERPC_e200z1
+#endif
+#if 0
+#define CPU_POWERPC_MPC5533 CPU_POWERPC_e200z3
+#define CPU_POWERPC_MPC5534 CPU_POWERPC_e200z3
+#endif
+#define CPU_POWERPC_MPC5553 CPU_POWERPC_e200z6
+#define CPU_POWERPC_MPC5554 CPU_POWERPC_e200z6
+#define CPU_POWERPC_MPC5561 CPU_POWERPC_e200z6
+#define CPU_POWERPC_MPC5565 CPU_POWERPC_e200z6
+#define CPU_POWERPC_MPC5566 CPU_POWERPC_e200z6
+#define CPU_POWERPC_MPC5567 CPU_POWERPC_e200z6
+ /* e300 family */
+ /* e300 cores */
+ CPU_POWERPC_e300c1 = 0x00830010,
+ CPU_POWERPC_e300c2 = 0x00840010,
+ CPU_POWERPC_e300c3 = 0x00850010,
+ CPU_POWERPC_e300c4 = 0x00860010,
+ /* MPC83xx microcontrollers */
+#define CPU_POWERPC_MPC831x CPU_POWERPC_e300c3
+#define CPU_POWERPC_MPC832x CPU_POWERPC_e300c2
+#define CPU_POWERPC_MPC834x CPU_POWERPC_e300c1
+#define CPU_POWERPC_MPC835x CPU_POWERPC_e300c1
+#define CPU_POWERPC_MPC836x CPU_POWERPC_e300c1
+#define CPU_POWERPC_MPC837x CPU_POWERPC_e300c4
+ /* e500 family */
+ /* e500 cores */
+#define CPU_POWERPC_e500 CPU_POWERPC_e500v2_v22
+ CPU_POWERPC_e500v1_v10 = 0x80200010,
+ CPU_POWERPC_e500v1_v20 = 0x80200020,
+ CPU_POWERPC_e500v2_v10 = 0x80210010,
+ CPU_POWERPC_e500v2_v11 = 0x80210011,
+ CPU_POWERPC_e500v2_v20 = 0x80210020,
+ CPU_POWERPC_e500v2_v21 = 0x80210021,
+ CPU_POWERPC_e500v2_v22 = 0x80210022,
+ CPU_POWERPC_e500v2_v30 = 0x80210030,
+ CPU_POWERPC_e500mc = 0x80230020,
+ CPU_POWERPC_e5500 = 0x80240020,
+ /* MPC85xx microcontrollers */
+#define CPU_POWERPC_MPC8533_v10 CPU_POWERPC_e500v2_v21
+#define CPU_POWERPC_MPC8533_v11 CPU_POWERPC_e500v2_v22
+#define CPU_POWERPC_MPC8533E_v10 CPU_POWERPC_e500v2_v21
+#define CPU_POWERPC_MPC8533E_v11 CPU_POWERPC_e500v2_v22
+#define CPU_POWERPC_MPC8540_v10 CPU_POWERPC_e500v1_v10
+#define CPU_POWERPC_MPC8540_v20 CPU_POWERPC_e500v1_v20
+#define CPU_POWERPC_MPC8540_v21 CPU_POWERPC_e500v1_v20
+#define CPU_POWERPC_MPC8541_v10 CPU_POWERPC_e500v1_v20
+#define CPU_POWERPC_MPC8541_v11 CPU_POWERPC_e500v1_v20
+#define CPU_POWERPC_MPC8541E_v10 CPU_POWERPC_e500v1_v20
+#define CPU_POWERPC_MPC8541E_v11 CPU_POWERPC_e500v1_v20
+#define CPU_POWERPC_MPC8543_v10 CPU_POWERPC_e500v2_v10
+#define CPU_POWERPC_MPC8543_v11 CPU_POWERPC_e500v2_v11
+#define CPU_POWERPC_MPC8543_v20 CPU_POWERPC_e500v2_v20
+#define CPU_POWERPC_MPC8543_v21 CPU_POWERPC_e500v2_v21
+#define CPU_POWERPC_MPC8543E_v10 CPU_POWERPC_e500v2_v10
+#define CPU_POWERPC_MPC8543E_v11 CPU_POWERPC_e500v2_v11
+#define CPU_POWERPC_MPC8543E_v20 CPU_POWERPC_e500v2_v20
+#define CPU_POWERPC_MPC8543E_v21 CPU_POWERPC_e500v2_v21
+#define CPU_POWERPC_MPC8544_v10 CPU_POWERPC_e500v2_v21
+#define CPU_POWERPC_MPC8544_v11 CPU_POWERPC_e500v2_v22
+#define CPU_POWERPC_MPC8544E_v11 CPU_POWERPC_e500v2_v22
+#define CPU_POWERPC_MPC8544E_v10 CPU_POWERPC_e500v2_v21
+#define CPU_POWERPC_MPC8545_v10 CPU_POWERPC_e500v2_v10
+#define CPU_POWERPC_MPC8545_v20 CPU_POWERPC_e500v2_v20
+#define CPU_POWERPC_MPC8545_v21 CPU_POWERPC_e500v2_v21
+#define CPU_POWERPC_MPC8545E_v10 CPU_POWERPC_e500v2_v10
+#define CPU_POWERPC_MPC8545E_v20 CPU_POWERPC_e500v2_v20
+#define CPU_POWERPC_MPC8545E_v21 CPU_POWERPC_e500v2_v21
+#define CPU_POWERPC_MPC8547E_v10 CPU_POWERPC_e500v2_v10
+#define CPU_POWERPC_MPC8547E_v20 CPU_POWERPC_e500v2_v20
+#define CPU_POWERPC_MPC8547E_v21 CPU_POWERPC_e500v2_v21
+#define CPU_POWERPC_MPC8548_v10 CPU_POWERPC_e500v2_v10
+#define CPU_POWERPC_MPC8548_v11 CPU_POWERPC_e500v2_v11
+#define CPU_POWERPC_MPC8548_v20 CPU_POWERPC_e500v2_v20
+#define CPU_POWERPC_MPC8548_v21 CPU_POWERPC_e500v2_v21
+#define CPU_POWERPC_MPC8548E_v10 CPU_POWERPC_e500v2_v10
+#define CPU_POWERPC_MPC8548E_v11 CPU_POWERPC_e500v2_v11
+#define CPU_POWERPC_MPC8548E_v20 CPU_POWERPC_e500v2_v20
+#define CPU_POWERPC_MPC8548E_v21 CPU_POWERPC_e500v2_v21
+#define CPU_POWERPC_MPC8555_v10 CPU_POWERPC_e500v2_v10
+#define CPU_POWERPC_MPC8555_v11 CPU_POWERPC_e500v2_v11
+#define CPU_POWERPC_MPC8555E_v10 CPU_POWERPC_e500v2_v10
+#define CPU_POWERPC_MPC8555E_v11 CPU_POWERPC_e500v2_v11
+#define CPU_POWERPC_MPC8560_v10 CPU_POWERPC_e500v2_v10
+#define CPU_POWERPC_MPC8560_v20 CPU_POWERPC_e500v2_v20
+#define CPU_POWERPC_MPC8560_v21 CPU_POWERPC_e500v2_v21
+#define CPU_POWERPC_MPC8567 CPU_POWERPC_e500v2_v22
+#define CPU_POWERPC_MPC8567E CPU_POWERPC_e500v2_v22
+#define CPU_POWERPC_MPC8568 CPU_POWERPC_e500v2_v22
+#define CPU_POWERPC_MPC8568E CPU_POWERPC_e500v2_v22
+#define CPU_POWERPC_MPC8572 CPU_POWERPC_e500v2_v30
+#define CPU_POWERPC_MPC8572E CPU_POWERPC_e500v2_v30
+ /* e600 family */
+ /* e600 cores */
+ CPU_POWERPC_e600 = 0x80040010,
+ /* MPC86xx microcontrollers */
+#define CPU_POWERPC_MPC8610 CPU_POWERPC_e600
+#define CPU_POWERPC_MPC8641 CPU_POWERPC_e600
+#define CPU_POWERPC_MPC8641D CPU_POWERPC_e600
+ /* PowerPC 6xx cores */
+ CPU_POWERPC_601_v0 = 0x00010001,
+ CPU_POWERPC_601_v1 = 0x00010001,
+ CPU_POWERPC_601_v2 = 0x00010002,
+ CPU_POWERPC_602 = 0x00050100,
+ CPU_POWERPC_603 = 0x00030100,
+ CPU_POWERPC_603E_v11 = 0x00060101,
+ CPU_POWERPC_603E_v12 = 0x00060102,
+ CPU_POWERPC_603E_v13 = 0x00060103,
+ CPU_POWERPC_603E_v14 = 0x00060104,
+ CPU_POWERPC_603E_v22 = 0x00060202,
+ CPU_POWERPC_603E_v3 = 0x00060300,
+ CPU_POWERPC_603E_v4 = 0x00060400,
+ CPU_POWERPC_603E_v41 = 0x00060401,
+ CPU_POWERPC_603E7t = 0x00071201,
+ CPU_POWERPC_603E7v = 0x00070100,
+ CPU_POWERPC_603E7v1 = 0x00070101,
+ CPU_POWERPC_603E7v2 = 0x00070201,
+ CPU_POWERPC_603E7 = 0x00070200,
+ CPU_POWERPC_603P = 0x00070000,
+ /* XXX: missing 0x00040303 (604) */
+ CPU_POWERPC_604 = 0x00040103,
+ /* XXX: missing 0x00091203 */
+ /* XXX: missing 0x00092110 */
+ /* XXX: missing 0x00092120 */
+ CPU_POWERPC_604E_v10 = 0x00090100,
+ CPU_POWERPC_604E_v22 = 0x00090202,
+ CPU_POWERPC_604E_v24 = 0x00090204,
+ /* XXX: missing 0x000a0100 */
+ /* XXX: missing 0x00093102 */
+ CPU_POWERPC_604R = 0x000a0101,
+#if 0
+ CPU_POWERPC_604EV = xxx, /* XXX: same as 604R ? */
+#endif
+ /* PowerPC 740/750 cores (aka G3) */
+ /* XXX: missing 0x00084202 */
+ CPU_POWERPC_7x0_v10 = 0x00080100,
+ CPU_POWERPC_7x0_v20 = 0x00080200,
+ CPU_POWERPC_7x0_v21 = 0x00080201,
+ CPU_POWERPC_7x0_v22 = 0x00080202,
+ CPU_POWERPC_7x0_v30 = 0x00080300,
+ CPU_POWERPC_7x0_v31 = 0x00080301,
+ CPU_POWERPC_740E = 0x00080100,
+ CPU_POWERPC_750E = 0x00080200,
+ CPU_POWERPC_7x0P = 0x10080000,
+ /* XXX: missing 0x00087010 (CL ?) */
+ CPU_POWERPC_750CL_v10 = 0x00087200,
+ CPU_POWERPC_750CL_v20 = 0x00087210, /* aka rev E */
+ CPU_POWERPC_750CX_v10 = 0x00082100,
+ CPU_POWERPC_750CX_v20 = 0x00082200,
+ CPU_POWERPC_750CX_v21 = 0x00082201,
+ CPU_POWERPC_750CX_v22 = 0x00082202,
+ CPU_POWERPC_750CXE_v21 = 0x00082211,
+ CPU_POWERPC_750CXE_v22 = 0x00082212,
+ CPU_POWERPC_750CXE_v23 = 0x00082213,
+ CPU_POWERPC_750CXE_v24 = 0x00082214,
+ CPU_POWERPC_750CXE_v24b = 0x00083214,
+ CPU_POWERPC_750CXE_v30 = 0x00082310,
+ CPU_POWERPC_750CXE_v31 = 0x00082311,
+ CPU_POWERPC_750CXE_v31b = 0x00083311,
+ CPU_POWERPC_750CXR = 0x00083410,
+ CPU_POWERPC_750FL = 0x70000203,
+ CPU_POWERPC_750FX_v10 = 0x70000100,
+ CPU_POWERPC_750FX_v20 = 0x70000200,
+ CPU_POWERPC_750FX_v21 = 0x70000201,
+ CPU_POWERPC_750FX_v22 = 0x70000202,
+ CPU_POWERPC_750FX_v23 = 0x70000203,
+ CPU_POWERPC_750GL = 0x70020102,
+ CPU_POWERPC_750GX_v10 = 0x70020100,
+ CPU_POWERPC_750GX_v11 = 0x70020101,
+ CPU_POWERPC_750GX_v12 = 0x70020102,
+ CPU_POWERPC_750L_v20 = 0x00088200,
+ CPU_POWERPC_750L_v21 = 0x00088201,
+ CPU_POWERPC_750L_v22 = 0x00088202,
+ CPU_POWERPC_750L_v30 = 0x00088300,
+ CPU_POWERPC_750L_v32 = 0x00088302,
+ /* PowerPC 745/755 cores */
+ CPU_POWERPC_7x5_v10 = 0x00083100,
+ CPU_POWERPC_7x5_v11 = 0x00083101,
+ CPU_POWERPC_7x5_v20 = 0x00083200,
+ CPU_POWERPC_7x5_v21 = 0x00083201,
+ CPU_POWERPC_7x5_v22 = 0x00083202, /* aka D */
+ CPU_POWERPC_7x5_v23 = 0x00083203, /* aka E */
+ CPU_POWERPC_7x5_v24 = 0x00083204,
+ CPU_POWERPC_7x5_v25 = 0x00083205,
+ CPU_POWERPC_7x5_v26 = 0x00083206,
+ CPU_POWERPC_7x5_v27 = 0x00083207,
+ CPU_POWERPC_7x5_v28 = 0x00083208,
+#if 0
+ CPU_POWERPC_7x5P = xxx,
+#endif
+ /* PowerPC 74xx cores (aka G4) */
+ /* XXX: missing 0x000C1101 */
+ CPU_POWERPC_7400_v10 = 0x000C0100,
+ CPU_POWERPC_7400_v11 = 0x000C0101,
+ CPU_POWERPC_7400_v20 = 0x000C0200,
+ CPU_POWERPC_7400_v21 = 0x000C0201,
+ CPU_POWERPC_7400_v22 = 0x000C0202,
+ CPU_POWERPC_7400_v26 = 0x000C0206,
+ CPU_POWERPC_7400_v27 = 0x000C0207,
+ CPU_POWERPC_7400_v28 = 0x000C0208,
+ CPU_POWERPC_7400_v29 = 0x000C0209,
+ CPU_POWERPC_7410_v10 = 0x800C1100,
+ CPU_POWERPC_7410_v11 = 0x800C1101,
+ CPU_POWERPC_7410_v12 = 0x800C1102, /* aka C */
+ CPU_POWERPC_7410_v13 = 0x800C1103, /* aka D */
+ CPU_POWERPC_7410_v14 = 0x800C1104, /* aka E */
+ CPU_POWERPC_7448_v10 = 0x80040100,
+ CPU_POWERPC_7448_v11 = 0x80040101,
+ CPU_POWERPC_7448_v20 = 0x80040200,
+ CPU_POWERPC_7448_v21 = 0x80040201,
+ CPU_POWERPC_7450_v10 = 0x80000100,
+ CPU_POWERPC_7450_v11 = 0x80000101,
+ CPU_POWERPC_7450_v12 = 0x80000102,
+ CPU_POWERPC_7450_v20 = 0x80000200, /* aka A, B, C, D: 2.04 */
+ CPU_POWERPC_7450_v21 = 0x80000201, /* aka E */
+ CPU_POWERPC_74x1_v23 = 0x80000203, /* aka G: 2.3 */
+ /* XXX: this entry might be a bug in some documentation */
+ CPU_POWERPC_74x1_v210 = 0x80000210, /* aka G: 2.3 ? */
+ CPU_POWERPC_74x5_v10 = 0x80010100,
+ /* XXX: missing 0x80010200 */
+ CPU_POWERPC_74x5_v21 = 0x80010201, /* aka C: 2.1 */
+ CPU_POWERPC_74x5_v32 = 0x80010302,
+ CPU_POWERPC_74x5_v33 = 0x80010303, /* aka F: 3.3 */
+ CPU_POWERPC_74x5_v34 = 0x80010304, /* aka G: 3.4 */
+ CPU_POWERPC_74x7_v10 = 0x80020100, /* aka A: 1.0 */
+ CPU_POWERPC_74x7_v11 = 0x80020101, /* aka B: 1.1 */
+ CPU_POWERPC_74x7_v12 = 0x80020102, /* aka C: 1.2 */
+ CPU_POWERPC_74x7A_v10 = 0x80030100, /* aka A: 1.0 */
+ CPU_POWERPC_74x7A_v11 = 0x80030101, /* aka B: 1.1 */
+ CPU_POWERPC_74x7A_v12 = 0x80030102, /* aka C: 1.2 */
+ /* 64 bits PowerPC */
+#if defined(TARGET_PPC64)
+ CPU_POWERPC_620 = 0x00140000,
+ CPU_POWERPC_630 = 0x00400000,
+ CPU_POWERPC_631 = 0x00410104,
+ CPU_POWERPC_POWER4 = 0x00350000,
+ CPU_POWERPC_POWER4P = 0x00380000,
+ /* XXX: missing 0x003A0201 */
+ CPU_POWERPC_POWER5 = 0x003A0203,
+ CPU_POWERPC_POWER5P = 0x003B0000,
+ CPU_POWERPC_POWER5P_v21 = 0x003B0201,
+ CPU_POWERPC_POWER6 = 0x003E0000,
+ CPU_POWERPC_POWER6_5 = 0x0F000001, /* POWER6 in POWER5 mode */
+ CPU_POWERPC_POWER6A = 0x0F000002,
+ CPU_POWERPC_POWER7_v20 = 0x003F0200,
+ CPU_POWERPC_POWER7_v21 = 0x003F0201,
+ CPU_POWERPC_POWER7_v23 = 0x003F0203,
+ CPU_POWERPC_POWER7P_v21 = 0x004A0201,
+ CPU_POWERPC_POWER8_v10 = 0x004B0100,
+ CPU_POWERPC_970 = 0x00390202,
+ CPU_POWERPC_970FX_v10 = 0x00391100,
+ CPU_POWERPC_970FX_v20 = 0x003C0200,
+ CPU_POWERPC_970FX_v21 = 0x003C0201,
+ CPU_POWERPC_970FX_v30 = 0x003C0300,
+ CPU_POWERPC_970FX_v31 = 0x003C0301,
+ CPU_POWERPC_970GX = 0x00450000,
+ CPU_POWERPC_970MP_v10 = 0x00440100,
+ CPU_POWERPC_970MP_v11 = 0x00440101,
+#define CPU_POWERPC_CELL CPU_POWERPC_CELL_v32
+ CPU_POWERPC_CELL_v10 = 0x00700100,
+ CPU_POWERPC_CELL_v20 = 0x00700400,
+ CPU_POWERPC_CELL_v30 = 0x00700500,
+ CPU_POWERPC_CELL_v31 = 0x00700501,
+#define CPU_POWERPC_CELL_v32 CPU_POWERPC_CELL_v31
+ CPU_POWERPC_RS64 = 0x00330000,
+ CPU_POWERPC_RS64II = 0x00340000,
+ CPU_POWERPC_RS64III = 0x00360000,
+ CPU_POWERPC_RS64IV = 0x00370000,
+#endif /* defined(TARGET_PPC64) */
+ /* Original POWER */
+ /* XXX: should be POWER (RIOS), RSC3308, RSC4608,
+ * POWER2 (RIOS2) & RSC2 (P2SC) here
+ */
+#if 0
+ CPU_POWER = xxx, /* 0x20000 ? 0x30000 for RSC ? */
+#endif
+#if 0
+ CPU_POWER2 = xxx, /* 0x40000 ? */
+#endif
+ /* PA Semi core */
+ CPU_POWERPC_PA6T = 0x00900000,
+};
+
+/* System version register (used on MPC 8xxx) */
+enum {
+ POWERPC_SVR_NONE = 0x00000000,
+ POWERPC_SVR_5200_v10 = 0x80110010,
+ POWERPC_SVR_5200_v11 = 0x80110011,
+ POWERPC_SVR_5200_v12 = 0x80110012,
+ POWERPC_SVR_5200B_v20 = 0x80110020,
+ POWERPC_SVR_5200B_v21 = 0x80110021,
+#define POWERPC_SVR_55xx POWERPC_SVR_5567
+#if 0
+ POWERPC_SVR_5533 = xxx,
+#endif
+#if 0
+ POWERPC_SVR_5534 = xxx,
+#endif
+#if 0
+ POWERPC_SVR_5553 = xxx,
+#endif
+#if 0
+ POWERPC_SVR_5554 = xxx,
+#endif
+#if 0
+ POWERPC_SVR_5561 = xxx,
+#endif
+#if 0
+ POWERPC_SVR_5565 = xxx,
+#endif
+#if 0
+ POWERPC_SVR_5566 = xxx,
+#endif
+#if 0
+ POWERPC_SVR_5567 = xxx,
+#endif
+#if 0
+ POWERPC_SVR_8313 = xxx,
+#endif
+#if 0
+ POWERPC_SVR_8313E = xxx,
+#endif
+#if 0
+ POWERPC_SVR_8314 = xxx,
+#endif
+#if 0
+ POWERPC_SVR_8314E = xxx,
+#endif
+#if 0
+ POWERPC_SVR_8315 = xxx,
+#endif
+#if 0
+ POWERPC_SVR_8315E = xxx,
+#endif
+#if 0
+ POWERPC_SVR_8321 = xxx,
+#endif
+#if 0
+ POWERPC_SVR_8321E = xxx,
+#endif
+#if 0
+ POWERPC_SVR_8323 = xxx,
+#endif
+#if 0
+ POWERPC_SVR_8323E = xxx,
+#endif
+ POWERPC_SVR_8343 = 0x80570010,
+ POWERPC_SVR_8343A = 0x80570030,
+ POWERPC_SVR_8343E = 0x80560010,
+ POWERPC_SVR_8343EA = 0x80560030,
+ POWERPC_SVR_8347P = 0x80550010, /* PBGA package */
+ POWERPC_SVR_8347T = 0x80530010, /* TBGA package */
+ POWERPC_SVR_8347AP = 0x80550030, /* PBGA package */
+ POWERPC_SVR_8347AT = 0x80530030, /* TBGA package */
+ POWERPC_SVR_8347EP = 0x80540010, /* PBGA package */
+ POWERPC_SVR_8347ET = 0x80520010, /* TBGA package */
+ POWERPC_SVR_8347EAP = 0x80540030, /* PBGA package */
+ POWERPC_SVR_8347EAT = 0x80520030, /* TBGA package */
+ POWERPC_SVR_8349 = 0x80510010,
+ POWERPC_SVR_8349A = 0x80510030,
+ POWERPC_SVR_8349E = 0x80500010,
+ POWERPC_SVR_8349EA = 0x80500030,
+#if 0
+ POWERPC_SVR_8358E = xxx,
+#endif
+#if 0
+ POWERPC_SVR_8360E = xxx,
+#endif
+#define POWERPC_SVR_E500 0x40000000
+ POWERPC_SVR_8377 = 0x80C70010 | POWERPC_SVR_E500,
+ POWERPC_SVR_8377E = 0x80C60010 | POWERPC_SVR_E500,
+ POWERPC_SVR_8378 = 0x80C50010 | POWERPC_SVR_E500,
+ POWERPC_SVR_8378E = 0x80C40010 | POWERPC_SVR_E500,
+ POWERPC_SVR_8379 = 0x80C30010 | POWERPC_SVR_E500,
+ POWERPC_SVR_8379E = 0x80C00010 | POWERPC_SVR_E500,
+ POWERPC_SVR_8533_v10 = 0x80340010 | POWERPC_SVR_E500,
+ POWERPC_SVR_8533_v11 = 0x80340011 | POWERPC_SVR_E500,
+ POWERPC_SVR_8533E_v10 = 0x803C0010 | POWERPC_SVR_E500,
+ POWERPC_SVR_8533E_v11 = 0x803C0011 | POWERPC_SVR_E500,
+ POWERPC_SVR_8540_v10 = 0x80300010 | POWERPC_SVR_E500,
+ POWERPC_SVR_8540_v20 = 0x80300020 | POWERPC_SVR_E500,
+ POWERPC_SVR_8540_v21 = 0x80300021 | POWERPC_SVR_E500,
+ POWERPC_SVR_8541_v10 = 0x80720010 | POWERPC_SVR_E500,
+ POWERPC_SVR_8541_v11 = 0x80720011 | POWERPC_SVR_E500,
+ POWERPC_SVR_8541E_v10 = 0x807A0010 | POWERPC_SVR_E500,
+ POWERPC_SVR_8541E_v11 = 0x807A0011 | POWERPC_SVR_E500,
+ POWERPC_SVR_8543_v10 = 0x80320010 | POWERPC_SVR_E500,
+ POWERPC_SVR_8543_v11 = 0x80320011 | POWERPC_SVR_E500,
+ POWERPC_SVR_8543_v20 = 0x80320020 | POWERPC_SVR_E500,
+ POWERPC_SVR_8543_v21 = 0x80320021 | POWERPC_SVR_E500,
+ POWERPC_SVR_8543E_v10 = 0x803A0010 | POWERPC_SVR_E500,
+ POWERPC_SVR_8543E_v11 = 0x803A0011 | POWERPC_SVR_E500,
+ POWERPC_SVR_8543E_v20 = 0x803A0020 | POWERPC_SVR_E500,
+ POWERPC_SVR_8543E_v21 = 0x803A0021 | POWERPC_SVR_E500,
+ POWERPC_SVR_8544_v10 = 0x80340110 | POWERPC_SVR_E500,
+ POWERPC_SVR_8544_v11 = 0x80340111 | POWERPC_SVR_E500,
+ POWERPC_SVR_8544E_v10 = 0x803C0110 | POWERPC_SVR_E500,
+ POWERPC_SVR_8544E_v11 = 0x803C0111 | POWERPC_SVR_E500,
+ POWERPC_SVR_8545_v20 = 0x80310220 | POWERPC_SVR_E500,
+ POWERPC_SVR_8545_v21 = 0x80310221 | POWERPC_SVR_E500,
+ POWERPC_SVR_8545E_v20 = 0x80390220 | POWERPC_SVR_E500,
+ POWERPC_SVR_8545E_v21 = 0x80390221 | POWERPC_SVR_E500,
+ POWERPC_SVR_8547E_v20 = 0x80390120 | POWERPC_SVR_E500,
+ POWERPC_SVR_8547E_v21 = 0x80390121 | POWERPC_SVR_E500,
+ POWERPC_SVR_8548_v10 = 0x80310010 | POWERPC_SVR_E500,
+ POWERPC_SVR_8548_v11 = 0x80310011 | POWERPC_SVR_E500,
+ POWERPC_SVR_8548_v20 = 0x80310020 | POWERPC_SVR_E500,
+ POWERPC_SVR_8548_v21 = 0x80310021 | POWERPC_SVR_E500,
+ POWERPC_SVR_8548E_v10 = 0x80390010 | POWERPC_SVR_E500,
+ POWERPC_SVR_8548E_v11 = 0x80390011 | POWERPC_SVR_E500,
+ POWERPC_SVR_8548E_v20 = 0x80390020 | POWERPC_SVR_E500,
+ POWERPC_SVR_8548E_v21 = 0x80390021 | POWERPC_SVR_E500,
+ POWERPC_SVR_8555_v10 = 0x80710010 | POWERPC_SVR_E500,
+ POWERPC_SVR_8555_v11 = 0x80710011 | POWERPC_SVR_E500,
+ POWERPC_SVR_8555E_v10 = 0x80790010 | POWERPC_SVR_E500,
+ POWERPC_SVR_8555E_v11 = 0x80790011 | POWERPC_SVR_E500,
+ POWERPC_SVR_8560_v10 = 0x80700010 | POWERPC_SVR_E500,
+ POWERPC_SVR_8560_v20 = 0x80700020 | POWERPC_SVR_E500,
+ POWERPC_SVR_8560_v21 = 0x80700021 | POWERPC_SVR_E500,
+ POWERPC_SVR_8567 = 0x80750111 | POWERPC_SVR_E500,
+ POWERPC_SVR_8567E = 0x807D0111 | POWERPC_SVR_E500,
+ POWERPC_SVR_8568 = 0x80750011 | POWERPC_SVR_E500,
+ POWERPC_SVR_8568E = 0x807D0011 | POWERPC_SVR_E500,
+ POWERPC_SVR_8572 = 0x80E00010 | POWERPC_SVR_E500,
+ POWERPC_SVR_8572E = 0x80E80010 | POWERPC_SVR_E500,
+ POWERPC_SVR_8610 = 0x80A00011,
+ POWERPC_SVR_8641 = 0x80900021,
+ POWERPC_SVR_8641D = 0x80900121,
+};
+
+#endif
diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
index fef6f95a0..f3c710a9e 100644
--- a/target-ppc/cpu-qom.h
+++ b/target-ppc/cpu-qom.h
@@ -20,7 +20,7 @@
#ifndef QEMU_PPC_CPU_QOM_H
#define QEMU_PPC_CPU_QOM_H
-#include "qemu/cpu.h"
+#include "qom/cpu.h"
#include "cpu.h"
#ifdef TARGET_PPC64
@@ -40,6 +40,7 @@
/**
* PowerPCCPUClass:
+ * @parent_realize: The parent class' realize handler.
* @parent_reset: The parent class' reset handler.
*
* A PowerPC CPU model.
@@ -49,7 +50,29 @@ typedef struct PowerPCCPUClass {
CPUClass parent_class;
/*< public >*/
+ DeviceRealize parent_realize;
void (*parent_reset)(CPUState *cpu);
+
+ uint32_t pvr;
+ uint32_t svr;
+ uint64_t insns_flags;
+ uint64_t insns_flags2;
+ uint64_t msr_mask;
+ powerpc_mmu_t mmu_model;
+ powerpc_excp_t excp_model;
+ powerpc_input_t bus_model;
+ uint32_t flags;
+ int bfd_mach;
+ uint32_t l1_dcache_size, l1_icache_size;
+#if defined(TARGET_PPC64)
+ const struct ppc_segment_page_sizes *sps;
+#endif
+ void (*init_proc)(CPUPPCState *env);
+ int (*check_pow)(CPUPPCState *env);
+#if defined(CONFIG_SOFTMMU)
+ int (*handle_mmu_fault)(CPUPPCState *env, target_ulong eaddr, int rwx,
+ int mmu_idx);
+#endif
} PowerPCCPUClass;
/**
@@ -68,10 +91,26 @@ typedef struct PowerPCCPU {
static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env)
{
- return POWERPC_CPU(container_of(env, PowerPCCPU, env));
+ return container_of(env, PowerPCCPU, env);
}
#define ENV_GET_CPU(e) CPU(ppc_env_get_cpu(e))
+#define ENV_OFFSET offsetof(PowerPCCPU, env)
+
+PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr);
+
+void ppc_cpu_do_interrupt(CPUState *cpu);
+void ppc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+ int flags);
+void ppc_cpu_dump_statistics(CPUState *cpu, FILE *f,
+ fprintf_function cpu_fprintf, int flags);
+hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+int ppc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int ppc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+
+#ifndef CONFIG_USER_ONLY
+extern const struct VMStateDescription vmstate_ppc_cpu;
+#endif
#endif
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 5f1dc8b7d..711db083e 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -73,9 +73,9 @@
#define CPUArchState struct CPUPPCState
-#include "cpu-defs.h"
+#include "exec/cpu-defs.h"
-#include "softfloat.h"
+#include "fpu/softfloat.h"
#define TARGET_HAS_ICE 1
@@ -113,13 +113,16 @@ enum powerpc_mmu_t {
#if defined(TARGET_PPC64)
#define POWERPC_MMU_64 0x00010000
#define POWERPC_MMU_1TSEG 0x00020000
+#define POWERPC_MMU_AMR 0x00040000
/* 64 bits PowerPC MMU */
POWERPC_MMU_64B = POWERPC_MMU_64 | 0x00000001,
- /* 620 variant (no segment exceptions) */
- POWERPC_MMU_620 = POWERPC_MMU_64 | 0x00000002,
/* Architecture 2.06 variant */
- POWERPC_MMU_2_06 = POWERPC_MMU_64 | POWERPC_MMU_1TSEG | 0x00000003,
+ POWERPC_MMU_2_06 = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
+ | POWERPC_MMU_AMR | 0x00000003,
/* Architecture 2.06 "degraded" (no 1T segments) */
+ POWERPC_MMU_2_06a = POWERPC_MMU_64 | POWERPC_MMU_AMR
+ | 0x00000003,
+ /* Architecture 2.06 "degraded" (no 1T segments or AMR) */
POWERPC_MMU_2_06d = POWERPC_MMU_64 | 0x00000003,
#endif /* defined(TARGET_PPC64) */
};
@@ -307,7 +310,6 @@ enum powerpc_input_t {
#define PPC_INPUT(env) (env->bus_model)
/*****************************************************************************/
-typedef struct ppc_def_t ppc_def_t;
typedef struct opc_handler_t opc_handler_t;
/*****************************************************************************/
@@ -330,6 +332,12 @@ struct ppc_spr_t {
void (*hea_write)(void *opaque, int spr_num, int gpr_num);
#endif
const char *name;
+#ifdef CONFIG_KVM
+ /* We (ab)use the fact that all the SPRs will have ids for the
+ * ONE_REG interface will have KVM_REG_PPC to use 0 as meaning,
+ * don't sync this */
+ uint64_t one_reg_id;
+#endif
};
/* Altivec registers (128 bits) */
@@ -355,7 +363,7 @@ struct ppc6xx_tlb_t {
typedef struct ppcemb_tlb_t ppcemb_tlb_t;
struct ppcemb_tlb_t {
- hwaddr RPN;
+ uint64_t RPN;
target_ulong EPN;
target_ulong PID;
target_ulong size;
@@ -391,36 +399,12 @@ union ppc_tlb_t {
#define SDR_64_HTABSIZE 0x000000000000001FULL
#endif /* defined(TARGET_PPC64 */
-#define HASH_PTE_SIZE_32 8
-#define HASH_PTE_SIZE_64 16
-
typedef struct ppc_slb_t ppc_slb_t;
struct ppc_slb_t {
uint64_t esid;
uint64_t vsid;
};
-/* Bits in the SLB ESID word */
-#define SLB_ESID_ESID 0xFFFFFFFFF0000000ULL
-#define SLB_ESID_V 0x0000000008000000ULL /* valid */
-
-/* Bits in the SLB VSID word */
-#define SLB_VSID_SHIFT 12
-#define SLB_VSID_SHIFT_1T 24
-#define SLB_VSID_SSIZE_SHIFT 62
-#define SLB_VSID_B 0xc000000000000000ULL
-#define SLB_VSID_B_256M 0x0000000000000000ULL
-#define SLB_VSID_B_1T 0x4000000000000000ULL
-#define SLB_VSID_VSID 0x3FFFFFFFFFFFF000ULL
-#define SLB_VSID_PTEM (SLB_VSID_B | SLB_VSID_VSID)
-#define SLB_VSID_KS 0x0000000000000800ULL
-#define SLB_VSID_KP 0x0000000000000400ULL
-#define SLB_VSID_N 0x0000000000000200ULL /* no-execute */
-#define SLB_VSID_L 0x0000000000000100ULL
-#define SLB_VSID_C 0x0000000000000080ULL /* class */
-#define SLB_VSID_LP 0x0000000000000030ULL
-#define SLB_VSID_ATTR 0x0000000000000FFFULL
-
#define SEGMENT_SHIFT_256M 28
#define SEGMENT_MASK_256M (~((1ULL << SEGMENT_SHIFT_256M) - 1))
@@ -902,24 +886,7 @@ struct ppc_segment_page_sizes {
/* The whole PowerPC CPU context */
#define NB_MMU_MODES 3
-struct ppc_def_t {
- const char *name;
- uint32_t pvr;
- uint32_t svr;
- uint64_t insns_flags;
- uint64_t insns_flags2;
- uint64_t msr_mask;
- powerpc_mmu_t mmu_model;
- powerpc_excp_t excp_model;
- powerpc_input_t bus_model;
- uint32_t flags;
- int bfd_mach;
-#if defined(TARGET_PPC64)
- const struct ppc_segment_page_sizes *sps;
-#endif
- void (*init_proc)(CPUPPCState *env);
- int (*check_pow)(CPUPPCState *env);
-};
+#define PPC_CPU_OPCODES_LEN 0x40
struct CPUPPCState {
/* First are the most commonly used resources
@@ -941,8 +908,11 @@ struct CPUPPCState {
/* CFAR */
target_ulong cfar;
#endif
- /* XER */
+ /* XER (with SO, OV, CA split out) */
target_ulong xer;
+ target_ulong so;
+ target_ulong ov;
+ target_ulong ca;
/* Reservation address */
target_ulong reserve_addr;
/* Reservation value */
@@ -976,11 +946,9 @@ struct CPUPPCState {
/* MMU context - only relevant for full system emulation */
#if !defined(CONFIG_USER_ONLY)
#if defined(TARGET_PPC64)
- /* Address space register */
- target_ulong asr;
/* PowerPC 64 SLB area */
ppc_slb_t slb[64];
- int slb_nr;
+ int32_t slb_nr;
#endif
/* segment registers */
hwaddr htab_base;
@@ -989,11 +957,11 @@ struct CPUPPCState {
/* externally stored hash table */
uint8_t *external_htab;
/* BATs */
- int nb_BATs;
+ uint32_t nb_BATs;
target_ulong DBAT[2][8];
target_ulong IBAT[2][8];
/* PowerPC TLB registers (for 4xx, e500 and 60x software driven TLBs) */
- int nb_tlb; /* Total number of TLB */
+ int32_t nb_tlb; /* Total number of TLB */
int tlb_per_way; /* Speed-up helper: used to avoid divisions at run time */
int nb_ways; /* Number of ways in the TLB set */
int last_way; /* Last used way used to allocate TLB in a LRU way */
@@ -1063,16 +1031,17 @@ struct CPUPPCState {
/* Exception vectors */
target_ulong excp_vectors[POWERPC_EXCP_NB];
target_ulong excp_prefix;
- target_ulong hreset_excp_prefix;
target_ulong ivor_mask;
target_ulong ivpr_mask;
target_ulong hreset_vector;
- hwaddr mpic_cpu_base;
+ hwaddr mpic_iack;
+ /* true when the external proxy facility mode is enabled */
+ bool mpic_proxy;
#endif
/* Those resources are used only during code translation */
/* opcode handlers */
- opc_handler_t *opcodes[0x40];
+ opc_handler_t *opcodes[PPC_CPU_OPCODES_LEN];
/* Those resources are used only in QEMU core */
target_ulong hflags; /* hflags is a MSR & HFLAGS_MASK */
@@ -1114,20 +1083,6 @@ do { \
env->wdt_period[3] = (d_); \
} while (0)
-#if !defined(CONFIG_USER_ONLY)
-/* Context used internally during MMU translations */
-typedef struct mmu_ctx_t mmu_ctx_t;
-struct mmu_ctx_t {
- hwaddr raddr; /* Real address */
- hwaddr eaddr; /* Effective address */
- int prot; /* Protection bits */
- hwaddr hash[2]; /* Pagetable hash values */
- target_ulong ptem; /* Virtual segment ID | API */
- int key; /* Access key */
- int nx; /* Non-execute area */
-};
-#endif
-
#include "cpu-qom.h"
/*****************************************************************************/
@@ -1139,27 +1094,19 @@ int cpu_ppc_exec (CPUPPCState *s);
is returned if the signal was handled by the virtual CPU. */
int cpu_ppc_signal_handler (int host_signum, void *pinfo,
void *puc);
-int cpu_ppc_handle_mmu_fault (CPUPPCState *env, target_ulong address, int rw,
- int mmu_idx);
-#define cpu_handle_mmu_fault cpu_ppc_handle_mmu_fault
-void do_interrupt (CPUPPCState *env);
void ppc_hw_interrupt (CPUPPCState *env);
+#if defined(CONFIG_USER_ONLY)
+int cpu_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
+ int mmu_idx);
+#endif
#if !defined(CONFIG_USER_ONLY)
void ppc_store_sdr1 (CPUPPCState *env, target_ulong value);
-#if defined(TARGET_PPC64)
-void ppc_store_asr (CPUPPCState *env, target_ulong value);
-int ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs);
-#endif /* defined(TARGET_PPC64) */
#endif /* !defined(CONFIG_USER_ONLY) */
void ppc_store_msr (CPUPPCState *env, target_ulong value);
void ppc_cpu_list (FILE *f, fprintf_function cpu_fprintf);
-const ppc_def_t *ppc_find_by_pvr(uint32_t pvr);
-const ppc_def_t *cpu_ppc_find_by_name (const char *name);
-int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def);
-
/* Time-base and decrementer management */
#ifndef NO_CPU_IO_DEFS
uint64_t cpu_ppc_load_tbl (CPUPPCState *env);
@@ -1186,14 +1133,13 @@ void store_40x_dbcr0 (CPUPPCState *env, uint32_t val);
void store_40x_sler (CPUPPCState *env, uint32_t val);
void store_booke_tcr (CPUPPCState *env, target_ulong val);
void store_booke_tsr (CPUPPCState *env, target_ulong val);
-int ppcmas_tlb_check(CPUPPCState *env, ppcmas_tlb_t *tlb,
- hwaddr *raddrp, target_ulong address,
- uint32_t pid);
void ppc_tlb_invalidate_all (CPUPPCState *env);
void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr);
#endif
#endif
+void store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask);
+
static inline uint64_t ppc_dump_gpr(CPUPPCState *env, int gprn)
{
uint64_t gprv;
@@ -1230,8 +1176,6 @@ static inline CPUPPCState *cpu_init(const char *cpu_model)
#define cpu_signal_handler cpu_ppc_signal_handler
#define cpu_list ppc_cpu_list
-#define CPU_SAVE_VERSION 4
-
/* MMU modes definitions */
#define MMU_MODE0_SUFFIX _user
#define MMU_MODE1_SUFFIX _kernel
@@ -1242,16 +1186,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
return env->mmu_idx;
}
-#if defined(CONFIG_USER_ONLY)
-static inline void cpu_clone_regs(CPUPPCState *env, target_ulong newsp)
-{
- if (newsp)
- env->gpr[1] = newsp;
- env->gpr[3] = 0;
-}
-#endif
-
-#include "cpu-all.h"
+#include "exec/cpu-all.h"
/*****************************************************************************/
/* CRF definitions */
@@ -1270,9 +1205,9 @@ static inline void cpu_clone_regs(CPUPPCState *env, target_ulong newsp)
#define XER_CA 29
#define XER_CMP 8
#define XER_BC 0
-#define xer_so ((env->xer >> XER_SO) & 1)
-#define xer_ov ((env->xer >> XER_OV) & 1)
-#define xer_ca ((env->xer >> XER_CA) & 1)
+#define xer_so (env->so)
+#define xer_ov (env->ov)
+#define xer_ca (env->ca)
#define xer_cmp ((env->xer >> XER_CMP) & 0xFF)
#define xer_bc ((env->xer >> XER_BC) & 0x7F)
@@ -1284,6 +1219,7 @@ static inline void cpu_clone_regs(CPUPPCState *env, target_ulong newsp)
#define SPR_601_UDECR (0x006)
#define SPR_LR (0x008)
#define SPR_CTR (0x009)
+#define SPR_UAMR (0x00C)
#define SPR_DSCR (0x011)
#define SPR_DSISR (0x012)
#define SPR_DAR (0x013) /* DAE for PowerPC 601 */
@@ -1321,6 +1257,7 @@ static inline void cpu_clone_regs(CPUPPCState *env, target_ulong newsp)
#define SPR_MPC_CMPH (0x09B)
#define SPR_MPC_LCTRL1 (0x09C)
#define SPR_MPC_LCTRL2 (0x09D)
+#define SPR_UAMOR (0x09D)
#define SPR_MPC_ICTRL (0x09E)
#define SPR_MPC_BAR (0x09F)
#define SPR_VRSAVE (0x100)
@@ -1502,12 +1439,11 @@ static inline void cpu_clone_regs(CPUPPCState *env, target_ulong newsp)
#define SPR_PERF2 (0x302)
#define SPR_RCPU_MI_RBA2 (0x302)
#define SPR_MPC_MI_AP (0x302)
+#define SPR_MMCRA (0x302)
#define SPR_PERF3 (0x303)
-#define SPR_620_PMC1R (0x303)
#define SPR_RCPU_MI_RBA3 (0x303)
#define SPR_MPC_MI_EPN (0x303)
#define SPR_PERF4 (0x304)
-#define SPR_620_PMC2R (0x304)
#define SPR_PERF5 (0x305)
#define SPR_MPC_MI_TWC (0x305)
#define SPR_PERF6 (0x306)
@@ -1523,7 +1459,6 @@ static inline void cpu_clone_regs(CPUPPCState *env, target_ulong newsp)
#define SPR_RCPU_L2U_RBA2 (0x30A)
#define SPR_MPC_MD_AP (0x30A)
#define SPR_PERFB (0x30B)
-#define SPR_620_MMCR0R (0x30B)
#define SPR_RCPU_L2U_RBA3 (0x30B)
#define SPR_MPC_MD_EPN (0x30B)
#define SPR_PERFC (0x30C)
@@ -1538,9 +1473,7 @@ static inline void cpu_clone_regs(CPUPPCState *env, target_ulong newsp)
#define SPR_UPERF1 (0x311)
#define SPR_UPERF2 (0x312)
#define SPR_UPERF3 (0x313)
-#define SPR_620_PMC1W (0x313)
#define SPR_UPERF4 (0x314)
-#define SPR_620_PMC2W (0x314)
#define SPR_UPERF5 (0x315)
#define SPR_UPERF6 (0x316)
#define SPR_UPERF7 (0x317)
@@ -1548,7 +1481,6 @@ static inline void cpu_clone_regs(CPUPPCState *env, target_ulong newsp)
#define SPR_UPERF9 (0x319)
#define SPR_UPERFA (0x31A)
#define SPR_UPERFB (0x31B)
-#define SPR_620_MMCR0W (0x31B)
#define SPR_UPERFC (0x31C)
#define SPR_UPERFD (0x31D)
#define SPR_UPERFE (0x31E)
@@ -1620,49 +1552,33 @@ static inline void cpu_clone_regs(CPUPPCState *env, target_ulong newsp)
#define SPR_USDA (0x3AF)
#define SPR_40x_ZPR (0x3B0)
#define SPR_BOOKE_MAS7 (0x3B0)
-#define SPR_620_PMR0 (0x3B0)
#define SPR_MMCR2 (0x3B0)
#define SPR_PMC5 (0x3B1)
#define SPR_40x_PID (0x3B1)
-#define SPR_620_PMR1 (0x3B1)
#define SPR_PMC6 (0x3B2)
#define SPR_440_MMUCR (0x3B2)
-#define SPR_620_PMR2 (0x3B2)
#define SPR_4xx_CCR0 (0x3B3)
#define SPR_BOOKE_EPLC (0x3B3)
-#define SPR_620_PMR3 (0x3B3)
#define SPR_405_IAC3 (0x3B4)
#define SPR_BOOKE_EPSC (0x3B4)
-#define SPR_620_PMR4 (0x3B4)
#define SPR_405_IAC4 (0x3B5)
-#define SPR_620_PMR5 (0x3B5)
#define SPR_405_DVC1 (0x3B6)
-#define SPR_620_PMR6 (0x3B6)
#define SPR_405_DVC2 (0x3B7)
-#define SPR_620_PMR7 (0x3B7)
#define SPR_BAMR (0x3B7)
#define SPR_MMCR0 (0x3B8)
-#define SPR_620_PMR8 (0x3B8)
#define SPR_PMC1 (0x3B9)
#define SPR_40x_SGR (0x3B9)
-#define SPR_620_PMR9 (0x3B9)
#define SPR_PMC2 (0x3BA)
#define SPR_40x_DCWR (0x3BA)
-#define SPR_620_PMRA (0x3BA)
#define SPR_SIAR (0x3BB)
#define SPR_405_SLER (0x3BB)
-#define SPR_620_PMRB (0x3BB)
#define SPR_MMCR1 (0x3BC)
#define SPR_405_SU0R (0x3BC)
-#define SPR_620_PMRC (0x3BC)
#define SPR_401_SKR (0x3BC)
#define SPR_PMC3 (0x3BD)
#define SPR_405_DBCR1 (0x3BD)
-#define SPR_620_PMRD (0x3BD)
#define SPR_PMC4 (0x3BE)
-#define SPR_620_PMRE (0x3BE)
#define SPR_SDA (0x3BF)
-#define SPR_620_PMRF (0x3BF)
#define SPR_403_VTBL (0x3CC)
#define SPR_403_VTBU (0x3CD)
#define SPR_DMISS (0x3D0)
@@ -1730,15 +1646,12 @@ static inline void cpu_clone_regs(CPUPPCState *env, target_ulong newsp)
#define SPR_LDSTCR (0x3F8)
#define SPR_L2PMCR (0x3F8)
#define SPR_750FX_HID2 (0x3F8)
-#define SPR_620_BUSCSR (0x3F8)
#define SPR_Exxx_L1FINV0 (0x3F8)
#define SPR_L2CR (0x3F9)
-#define SPR_620_L2CR (0x3F9)
#define SPR_L3CR (0x3FA)
#define SPR_750_TDCH (0x3FA)
#define SPR_IABR2 (0x3FA)
#define SPR_40x_DCCR (0x3FA)
-#define SPR_620_L2SR (0x3FA)
#define SPR_ICTC (0x3FB)
#define SPR_40x_ICCR (0x3FB)
#define SPR_THRM1 (0x3FC)
@@ -1859,10 +1772,8 @@ enum {
PPC_CACHE = 0x0000000200000000ULL,
/* icbi instruction */
PPC_CACHE_ICBI = 0x0000000400000000ULL,
- /* dcbz instruction with fixed cache line size */
+ /* dcbz instruction */
PPC_CACHE_DCBZ = 0x0000000800000000ULL,
- /* dcbz instruction with tunable cache line size */
- PPC_CACHE_DCBZT = 0x0000001000000000ULL,
/* dcba instruction */
PPC_CACHE_DCBA = 0x0000002000000000ULL,
/* Freescale cache locking instructions */
@@ -1930,7 +1841,7 @@ enum {
| PPC_MEM_TLBIE | PPC_MEM_TLBSYNC \
| PPC_MEM_SYNC | PPC_MEM_EIEIO \
| PPC_CACHE | PPC_CACHE_ICBI \
- | PPC_CACHE_DCBZ | PPC_CACHE_DCBZT \
+ | PPC_CACHE_DCBZ \
| PPC_CACHE_DCBA | PPC_CACHE_LOCK \
| PPC_EXTERN | PPC_SEGMENT | PPC_6xx_TLB \
| PPC_74xx_TLB | PPC_40x_TLB | PPC_SEGMENT_64B \
@@ -1953,8 +1864,10 @@ enum {
PPC2_PRCNTL = 0x0000000000000008ULL,
/* Byte-reversed, indexed, double-word load and store */
PPC2_DBRX = 0x0000000000000010ULL,
+ /* Book I 2.05 PowerPC specification */
+ PPC2_ISA205 = 0x0000000000000020ULL,
-#define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_PRCNTL | PPC2_DBRX)
+#define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_PRCNTL | PPC2_DBRX | PPC2_ISA205)
};
/*****************************************************************************/
@@ -2091,6 +2004,19 @@ enum {
/*****************************************************************************/
+static inline target_ulong cpu_read_xer(CPUPPCState *env)
+{
+ return env->xer | (env->so << XER_SO) | (env->ov << XER_OV) | (env->ca << XER_CA);
+}
+
+static inline void cpu_write_xer(CPUPPCState *env, target_ulong xer)
+{
+ env->so = (xer >> XER_SO) & 1;
+ env->ov = (xer >> XER_OV) & 1;
+ env->ca = (xer >> XER_CA) & 1;
+ env->xer = xer & ~((1u << XER_SO) | (1u << XER_OV) | (1u << XER_CA));
+}
+
static inline void cpu_get_tb_cpu_state(CPUPPCState *env, target_ulong *pc,
target_ulong *cs_base, int *flags)
{
@@ -2099,17 +2025,6 @@ static inline void cpu_get_tb_cpu_state(CPUPPCState *env, target_ulong *pc,
*flags = env->hflags;
}
-static inline void cpu_set_tls(CPUPPCState *env, target_ulong newtls)
-{
-#if defined(TARGET_PPC64)
- /* The kernel checks TIF_32BIT here; we don't support loading 32-bit
- binaries on PPC64 yet. */
- env->gpr[13] = newtls;
-#else
- env->gpr[2] = newtls;
-#endif
-}
-
#if !defined(CONFIG_USER_ONLY)
static inline int booke206_tlbm_id(CPUPPCState *env, ppcmas_tlb_t *tlbm)
{
@@ -2219,17 +2134,13 @@ extern void (*cpu_ppc_hypercall)(PowerPCCPU *);
static inline bool cpu_has_work(CPUState *cpu)
{
- CPUPPCState *env = &POWERPC_CPU(cpu)->env;
+ PowerPCCPU *ppc_cpu = POWERPC_CPU(cpu);
+ CPUPPCState *env = &ppc_cpu->env;
- return msr_ee && (env->interrupt_request & CPU_INTERRUPT_HARD);
+ return msr_ee && (cpu->interrupt_request & CPU_INTERRUPT_HARD);
}
-#include "exec-all.h"
-
-static inline void cpu_pc_from_tb(CPUPPCState *env, TranslationBlock *tb)
-{
- env->nip = tb->pc;
-}
+#include "exec/exec-all.h"
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env);
diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index 5e34ad08a..e9fcad8ef 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -38,8 +38,11 @@ void (*cpu_ppc_hypercall)(PowerPCCPU *);
/*****************************************************************************/
/* Exception processing */
#if defined(CONFIG_USER_ONLY)
-void do_interrupt(CPUPPCState *env)
+void ppc_cpu_do_interrupt(CPUState *cs)
{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+
env->exception_index = POWERPC_EXCP_NONE;
env->error_code = 0;
}
@@ -66,6 +69,7 @@ static inline void dump_syscall(CPUPPCState *env)
static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
{
CPUPPCState *env = &cpu->env;
+ CPUState *cs;
target_ulong msr, new_msr, vector;
int srr0, srr1, asrr0, asrr1;
int lpes0, lpes1, lev;
@@ -84,7 +88,11 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
" => %08x (%02x)\n", env->nip, excp, env->error_code);
/* new srr1 value excluding must-be-zero bits */
- msr = env->msr & ~0x783f0000ULL;
+ if (excp_model == POWERPC_EXCP_BOOKE) {
+ msr = env->msr;
+ } else {
+ msr = env->msr & ~0x783f0000ULL;
+ }
/* new interrupt handler msr */
new_msr = env->msr & ((target_ulong)1 << MSR_ME);
@@ -127,8 +135,9 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
fprintf(stderr, "Machine check while not allowed. "
"Entering checkstop state\n");
}
- env->halted = 1;
- env->interrupt_request |= CPU_INTERRUPT_EXITTB;
+ cs = CPU(cpu);
+ cs->halted = 1;
+ cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
}
if (0) {
/* XXX: find a suitable condition to enable the hypervisor mode */
@@ -145,6 +154,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
srr1 = SPR_40x_SRR3;
break;
case POWERPC_EXCP_BOOKE:
+ /* FIXME: choose one or the other based on CPU type */
srr0 = SPR_BOOKE_MCSRR0;
srr1 = SPR_BOOKE_MCSRR1;
asrr0 = SPR_BOOKE_CSRR0;
@@ -173,6 +183,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
if (lpes0 == 1) {
new_msr |= (target_ulong)MSR_HVB;
}
+ if (env->mpic_proxy) {
+ /* IACK the IRQ on delivery */
+ env->spr[SPR_BOOKE_EPR] = ldl_phys(env->mpic_iack);
+ }
goto store_next;
case POWERPC_EXCP_ALIGN: /* Alignment exception */
if (lpes1 == 0) {
@@ -275,6 +289,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
case POWERPC_EXCP_DEBUG: /* Debug interrupt */
switch (excp_model) {
case POWERPC_EXCP_BOOKE:
+ /* FIXME: choose one or the other based on CPU type */
srr0 = SPR_BOOKE_DSRR0;
srr1 = SPR_BOOKE_DSRR1;
asrr0 = SPR_BOOKE_CSRR0;
@@ -642,9 +657,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
}
}
-void do_interrupt(CPUPPCState *env)
+void ppc_cpu_do_interrupt(CPUState *cs)
{
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
powerpc_excp(cpu, env->excp_model, env->exception_index);
}
@@ -653,11 +669,12 @@ void ppc_hw_interrupt(CPUPPCState *env)
{
PowerPCCPU *cpu = ppc_env_get_cpu(env);
int hdice;
-
#if 0
+ CPUState *cs = CPU(cpu);
+
qemu_log_mask(CPU_LOG_INT, "%s: %p pending %08x req %08x me %d ee %d\n",
- __func__, env, env->pending_interrupts,
- env->interrupt_request, (int)msr_me, (int)msr_ee);
+ __func__, env, env->pending_interrupts,
+ cs->interrupt_request, (int)msr_me, (int)msr_ee);
#endif
/* External reset */
if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
@@ -797,9 +814,12 @@ void helper_raise_exception(CPUPPCState *env, uint32_t exception)
#if !defined(CONFIG_USER_ONLY)
void helper_store_msr(CPUPPCState *env, target_ulong val)
{
+ CPUState *cs;
+
val = hreg_store_msr(env, val, 0);
if (val != 0) {
- env->interrupt_request |= CPU_INTERRUPT_EXITTB;
+ cs = CPU(ppc_env_get_cpu(env));
+ cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
helper_raise_exception(env, val);
}
}
@@ -807,6 +827,8 @@ void helper_store_msr(CPUPPCState *env, target_ulong val)
static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr,
target_ulong msrm, int keep_msrh)
{
+ CPUState *cs = CPU(ppc_env_get_cpu(env));
+
#if defined(TARGET_PPC64)
if (msr_is_64bit(env, msr)) {
nip = (uint64_t)nip;
@@ -831,13 +853,18 @@ static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr,
/* No need to raise an exception here,
* as rfi is always the last insn of a TB
*/
- env->interrupt_request |= CPU_INTERRUPT_EXITTB;
+ cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
}
void helper_rfi(CPUPPCState *env)
{
- do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
- ~((target_ulong)0x783F0000), 1);
+ if (env->excp_model == POWERPC_EXCP_BOOKE) {
+ do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
+ ~((target_ulong)0), 0);
+ } else {
+ do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1],
+ ~((target_ulong)0x783F0000), 1);
+ }
}
#if defined(TARGET_PPC64)
@@ -864,20 +891,22 @@ void helper_40x_rfci(CPUPPCState *env)
void helper_rfci(CPUPPCState *env)
{
- do_rfi(env, env->spr[SPR_BOOKE_CSRR0], SPR_BOOKE_CSRR1,
- ~((target_ulong)0x3FFF0000), 0);
+ do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1],
+ ~((target_ulong)0), 0);
}
void helper_rfdi(CPUPPCState *env)
{
- do_rfi(env, env->spr[SPR_BOOKE_DSRR0], SPR_BOOKE_DSRR1,
- ~((target_ulong)0x3FFF0000), 0);
+ /* FIXME: choose CSRR1 or DSRR1 based on cpu type */
+ do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1],
+ ~((target_ulong)0), 0);
}
void helper_rfmci(CPUPPCState *env)
{
- do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], SPR_BOOKE_MCSRR1,
- ~((target_ulong)0x3FFF0000), 0);
+ /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */
+ do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1],
+ ~((target_ulong)0), 0);
}
#endif
@@ -957,16 +986,19 @@ void helper_msgsnd(target_ulong rb)
{
int irq = dbell2irq(rb);
int pir = rb & DBELL_PIRTAG_MASK;
- CPUPPCState *cenv;
+ CPUState *cs;
if (irq < 0) {
return;
}
- for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) {
+ for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *cenv = &cpu->env;
+
if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) {
cenv->pending_interrupts |= 1 << irq;
- cpu_interrupt(cenv, CPU_INTERRUPT_HARD);
+ cpu_interrupt(cs, CPU_INTERRUPT_HARD);
}
}
}
diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index 9d6792620..4f6021835 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -430,20 +430,17 @@ void helper_fpscr_setbit(CPUPPCState *env, uint32_t bit)
void helper_store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask)
{
- /*
- * We use only the 32 LSB of the incoming fpr
- */
- uint32_t prev, new;
+ target_ulong prev, new;
int i;
prev = env->fpscr;
- new = (uint32_t)arg;
- new &= ~0x60000000;
- new |= prev & 0x60000000;
- for (i = 0; i < 8; i++) {
+ new = (target_ulong)arg;
+ new &= ~0x60000000LL;
+ new |= prev & 0x60000000LL;
+ for (i = 0; i < sizeof(target_ulong) * 2; i++) {
if (mask & (1 << i)) {
- env->fpscr &= ~(0xF << (4 * i));
- env->fpscr |= new & (0xF << (4 * i));
+ env->fpscr &= ~(0xFLL << (4 * i));
+ env->fpscr |= new & (0xFLL << (4 * i));
}
}
/* Update VX and FEX */
@@ -463,8 +460,25 @@ void helper_store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask)
fpscr_set_rounding_mode(env);
}
+void store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask)
+{
+ helper_store_fpscr(env, arg, mask);
+}
+
void helper_float_check_status(CPUPPCState *env)
{
+ int status = get_float_exception_flags(&env->fp_status);
+
+ if (status & float_flag_divbyzero) {
+ float_zero_divide_excp(env);
+ } else if (status & float_flag_overflow) {
+ float_overflow_excp(env);
+ } else if (status & float_flag_underflow) {
+ float_underflow_excp(env);
+ } else if (status & float_flag_inexact) {
+ float_inexact_excp(env);
+ }
+
if (env->exception_index == POWERPC_EXCP_PROGRAM &&
(env->error_code & POWERPC_EXCP_FP)) {
/* Differred floating-point exception after target FPR update */
@@ -472,17 +486,6 @@ void helper_float_check_status(CPUPPCState *env)
helper_raise_exception_err(env, env->exception_index,
env->error_code);
}
- } else {
- int status = get_float_exception_flags(&env->fp_status);
- if (status & float_flag_divbyzero) {
- float_zero_divide_excp(env);
- } else if (status & float_flag_overflow) {
- float_overflow_excp(env);
- } else if (status & float_flag_underflow) {
- float_underflow_excp(env);
- } else if (status & float_flag_inexact) {
- float_inexact_excp(env);
- }
}
}
@@ -590,37 +593,6 @@ uint64_t helper_fdiv(CPUPPCState *env, uint64_t arg1, uint64_t arg2)
return farg1.ll;
}
-/* fabs */
-uint64_t helper_fabs(CPUPPCState *env, uint64_t arg)
-{
- CPU_DoubleU farg;
-
- farg.ll = arg;
- farg.d = float64_abs(farg.d);
- return farg.ll;
-}
-
-/* fnabs */
-uint64_t helper_fnabs(CPUPPCState *env, uint64_t arg)
-{
- CPU_DoubleU farg;
-
- farg.ll = arg;
- farg.d = float64_abs(farg.d);
- farg.d = float64_chs(farg.d);
- return farg.ll;
-}
-
-/* fneg */
-uint64_t helper_fneg(CPUPPCState *env, uint64_t arg)
-{
- CPU_DoubleU farg;
-
- farg.ll = arg;
- farg.d = float64_chs(farg.d);
- return farg.ll;
-}
-
/* fctiw - fctiw. */
uint64_t helper_fctiw(CPUPPCState *env, uint64_t arg)
{
diff --git a/target-ppc/gdbstub.c b/target-ppc/gdbstub.c
new file mode 100644
index 000000000..1c910902e
--- /dev/null
+++ b/target-ppc/gdbstub.c
@@ -0,0 +1,131 @@
+/*
+ * PowerPC gdb server stub
+ *
+ * Copyright (c) 2003-2005 Fabrice Bellard
+ * Copyright (c) 2013 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include "config.h"
+#include "qemu-common.h"
+#include "exec/gdbstub.h"
+
+/* Old gdb always expects FP registers. Newer (xml-aware) gdb only
+ * expects whatever the target description contains. Due to a
+ * historical mishap the FP registers appear in between core integer
+ * regs and PC, MSR, CR, and so forth. We hack round this by giving the
+ * FP regs zero size when talking to a newer gdb.
+ */
+
+int ppc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+
+ if (n < 32) {
+ /* gprs */
+ return gdb_get_regl(mem_buf, env->gpr[n]);
+ } else if (n < 64) {
+ /* fprs */
+ if (gdb_has_xml) {
+ return 0;
+ }
+ stfq_p(mem_buf, env->fpr[n-32]);
+ return 8;
+ } else {
+ switch (n) {
+ case 64:
+ return gdb_get_regl(mem_buf, env->nip);
+ case 65:
+ return gdb_get_regl(mem_buf, env->msr);
+ case 66:
+ {
+ uint32_t cr = 0;
+ int i;
+ for (i = 0; i < 8; i++) {
+ cr |= env->crf[i] << (32 - ((i + 1) * 4));
+ }
+ return gdb_get_reg32(mem_buf, cr);
+ }
+ case 67:
+ return gdb_get_regl(mem_buf, env->lr);
+ case 68:
+ return gdb_get_regl(mem_buf, env->ctr);
+ case 69:
+ return gdb_get_regl(mem_buf, env->xer);
+ case 70:
+ {
+ if (gdb_has_xml) {
+ return 0;
+ }
+ return gdb_get_reg32(mem_buf, env->fpscr);
+ }
+ }
+ }
+ return 0;
+}
+
+int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+
+ if (n < 32) {
+ /* gprs */
+ env->gpr[n] = ldtul_p(mem_buf);
+ return sizeof(target_ulong);
+ } else if (n < 64) {
+ /* fprs */
+ if (gdb_has_xml) {
+ return 0;
+ }
+ env->fpr[n-32] = ldfq_p(mem_buf);
+ return 8;
+ } else {
+ switch (n) {
+ case 64:
+ env->nip = ldtul_p(mem_buf);
+ return sizeof(target_ulong);
+ case 65:
+ ppc_store_msr(env, ldtul_p(mem_buf));
+ return sizeof(target_ulong);
+ case 66:
+ {
+ uint32_t cr = ldl_p(mem_buf);
+ int i;
+ for (i = 0; i < 8; i++) {
+ env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF;
+ }
+ return 4;
+ }
+ case 67:
+ env->lr = ldtul_p(mem_buf);
+ return sizeof(target_ulong);
+ case 68:
+ env->ctr = ldtul_p(mem_buf);
+ return sizeof(target_ulong);
+ case 69:
+ env->xer = ldtul_p(mem_buf);
+ return sizeof(target_ulong);
+ case 70:
+ /* fpscr */
+ if (gdb_has_xml) {
+ return 0;
+ }
+ store_fpscr(env, ldtul_p(mem_buf), 0xffffffff);
+ return sizeof(target_ulong);
+ }
+ }
+ return 0;
+}
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index e588370e2..56814b501 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -1,4 +1,4 @@
-#include "def-helper.h"
+#include "exec/def-helper.h"
DEF_HELPER_3(raise_exception_err, void, env, i32, i32)
DEF_HELPER_2(raise_exception, void, env, i32)
@@ -25,20 +25,18 @@ DEF_HELPER_3(stmw, void, env, tl, i32)
DEF_HELPER_4(lsw, void, env, tl, i32, i32)
DEF_HELPER_5(lswx, void, env, tl, i32, i32, i32)
DEF_HELPER_4(stsw, void, env, tl, i32, i32)
-DEF_HELPER_2(dcbz, void, env, tl)
-DEF_HELPER_2(dcbz_970, void, env, tl)
+DEF_HELPER_3(dcbz, void, env, tl, i32)
DEF_HELPER_2(icbi, void, env, tl)
DEF_HELPER_5(lscbx, tl, env, tl, i32, i32, i32)
#if defined(TARGET_PPC64)
-DEF_HELPER_FLAGS_2(mulhd, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(mulhdu, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_3(mulldo, i64, env, i64, i64)
#endif
DEF_HELPER_FLAGS_1(cntlzw, TCG_CALL_NO_RWG_SE, tl, tl)
DEF_HELPER_FLAGS_1(popcntb, TCG_CALL_NO_RWG_SE, tl, tl)
DEF_HELPER_FLAGS_1(popcntw, TCG_CALL_NO_RWG_SE, tl, tl)
+DEF_HELPER_FLAGS_2(cmpb, TCG_CALL_NO_RWG_SE, tl, tl, tl)
DEF_HELPER_3(sraw, tl, env, tl, tl)
#if defined(TARGET_PPC64)
DEF_HELPER_FLAGS_1(cntlzd, TCG_CALL_NO_RWG_SE, tl, tl)
@@ -83,9 +81,6 @@ DEF_HELPER_4(fmadd, i64, env, i64, i64, i64)
DEF_HELPER_4(fmsub, i64, env, i64, i64, i64)
DEF_HELPER_4(fnmadd, i64, env, i64, i64, i64)
DEF_HELPER_4(fnmsub, i64, env, i64, i64, i64)
-DEF_HELPER_2(fabs, i64, env, i64)
-DEF_HELPER_2(fnabs, i64, env, i64)
-DEF_HELPER_2(fneg, i64, env, i64)
DEF_HELPER_2(fsqrt, i64, env, i64)
DEF_HELPER_2(fre, i64, env, i64)
DEF_HELPER_2(fres, i64, env, i64)
@@ -385,7 +380,6 @@ DEF_HELPER_1(load_601_rtcl, tl, env)
DEF_HELPER_1(load_601_rtcu, tl, env)
#if !defined(CONFIG_USER_ONLY)
#if defined(TARGET_PPC64)
-DEF_HELPER_2(store_asr, void, env, tl)
DEF_HELPER_1(load_purr, tl, env)
#endif
DEF_HELPER_2(store_sdr1, void, env, tl)
@@ -405,7 +399,6 @@ DEF_HELPER_2(store_40x_dbcr0, void, env, tl)
DEF_HELPER_2(store_40x_sler, void, env, tl)
DEF_HELPER_2(store_booke_tcr, void, env, tl)
DEF_HELPER_2(store_booke_tsr, void, env, tl)
-DEF_HELPER_1(load_epr, tl, env)
DEF_HELPER_3(store_ibatl, void, env, i32, tl)
DEF_HELPER_3(store_ibatu, void, env, i32, tl)
DEF_HELPER_3(store_dbatl, void, env, i32, tl)
@@ -414,4 +407,4 @@ DEF_HELPER_3(store_601_batl, void, env, i32, tl)
DEF_HELPER_3(store_601_batu, void, env, i32, tl)
#endif
-#include "def-helper.h"
+#include "exec/def-helper.h"
diff --git a/target-ppc/helper_regs.h b/target-ppc/helper_regs.h
index 3c988502e..a6d5e2fe2 100644
--- a/target-ppc/helper_regs.h
+++ b/target-ppc/helper_regs.h
@@ -68,10 +68,13 @@ static inline int hreg_store_msr(CPUPPCState *env, target_ulong value,
int alter_hv)
{
int excp;
+#if !defined(CONFIG_USER_ONLY)
+ CPUState *cs = CPU(ppc_env_get_cpu(env));
+#endif
excp = 0;
value &= env->msr_mask;
-#if !defined (CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY)
if (!alter_hv) {
/* mtmsr cannot alter the hypervisor state */
value &= ~MSR_HVB;
@@ -82,7 +85,7 @@ static inline int hreg_store_msr(CPUPPCState *env, target_ulong value,
/* Flush all tlb when changing translation mode */
tlb_flush(env, 1);
excp = POWERPC_EXCP_NONE;
- env->interrupt_request |= CPU_INTERRUPT_EXITTB;
+ cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
}
if (unlikely((env->flags & POWERPC_FLAG_TGPR) &&
((value ^ env->msr) & (1 << MSR_TGPR)))) {
@@ -96,10 +99,10 @@ static inline int hreg_store_msr(CPUPPCState *env, target_ulong value,
#endif
env->msr = value;
hreg_compute_hflags(env);
-#if !defined (CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY)
if (unlikely(msr_pow == 1)) {
if ((*env->check_pow)(env)) {
- env->halted = 1;
+ cs->halted = 1;
excp = EXCP_HALTED;
}
}
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index f39b4f682..e50bdd20e 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -17,7 +17,7 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "cpu.h"
-#include "host-utils.h"
+#include "qemu/host-utils.h"
#include "helper.h"
#include "helper_regs.h"
@@ -25,24 +25,6 @@
/* Fixed point operations helpers */
#if defined(TARGET_PPC64)
-/* multiply high word */
-uint64_t helper_mulhd(uint64_t arg1, uint64_t arg2)
-{
- uint64_t tl, th;
-
- muls64(&tl, &th, arg1, arg2);
- return th;
-}
-
-/* multiply high word unsigned */
-uint64_t helper_mulhdu(uint64_t arg1, uint64_t arg2)
-{
- uint64_t tl, th;
-
- mulu64(&tl, &th, arg1, arg2);
- return th;
-}
-
uint64_t helper_mulldo(CPUPPCState *env, uint64_t arg1, uint64_t arg2)
{
int64_t th;
@@ -51,9 +33,9 @@ uint64_t helper_mulldo(CPUPPCState *env, uint64_t arg1, uint64_t arg2)
muls64(&tl, (uint64_t *)&th, arg1, arg2);
/* If th != 0 && th != -1, then we had an overflow */
if (likely((uint64_t)(th + 1) <= 1)) {
- env->xer &= ~(1 << XER_OV);
+ env->ov = 0;
} else {
- env->xer |= (1 << XER_OV) | (1 << XER_SO);
+ env->so = env->ov = 1;
}
return (int64_t)tl;
}
@@ -71,6 +53,21 @@ target_ulong helper_cntlzd(target_ulong t)
}
#endif
+target_ulong helper_cmpb(target_ulong rs, target_ulong rb)
+{
+ target_ulong mask = 0xff;
+ target_ulong ra = 0;
+ int i;
+
+ for (i = 0; i < sizeof(target_ulong); i++) {
+ if ((rs & mask) == (rb & mask)) {
+ ra |= mask;
+ }
+ mask <<= 8;
+ }
+ return ra;
+}
+
/* shift right arithmetic helper */
target_ulong helper_sraw(CPUPPCState *env, target_ulong value,
target_ulong shift)
@@ -82,21 +79,17 @@ target_ulong helper_sraw(CPUPPCState *env, target_ulong value,
shift &= 0x1f;
ret = (int32_t)value >> shift;
if (likely(ret >= 0 || (value & ((1 << shift) - 1)) == 0)) {
- env->xer &= ~(1 << XER_CA);
+ env->ca = 0;
} else {
- env->xer |= (1 << XER_CA);
+ env->ca = 1;
}
} else {
ret = (int32_t)value;
- env->xer &= ~(1 << XER_CA);
+ env->ca = 0;
}
} else {
ret = (int32_t)value >> 31;
- if (ret) {
- env->xer |= (1 << XER_CA);
- } else {
- env->xer &= ~(1 << XER_CA);
- }
+ env->ca = (ret != 0);
}
return (target_long)ret;
}
@@ -112,21 +105,17 @@ target_ulong helper_srad(CPUPPCState *env, target_ulong value,
shift &= 0x3f;
ret = (int64_t)value >> shift;
if (likely(ret >= 0 || (value & ((1 << shift) - 1)) == 0)) {
- env->xer &= ~(1 << XER_CA);
+ env->ca = 0;
} else {
- env->xer |= (1 << XER_CA);
+ env->ca = 1;
}
} else {
ret = (int64_t)value;
- env->xer &= ~(1 << XER_CA);
+ env->ca = 0;
}
} else {
ret = (int64_t)value >> 63;
- if (ret) {
- env->xer |= (1 << XER_CA);
- } else {
- env->xer &= ~(1 << XER_CA);
- }
+ env->ca = (ret != 0);
}
return ret;
}
@@ -206,16 +195,16 @@ target_ulong helper_divo(CPUPPCState *env, target_ulong arg1,
if (((int32_t)tmp == INT32_MIN && (int32_t)arg2 == (int32_t)-1) ||
(int32_t)arg2 == 0) {
- env->xer |= (1 << XER_OV) | (1 << XER_SO);
+ env->so = env->ov = 1;
env->spr[SPR_MQ] = 0;
return INT32_MIN;
} else {
env->spr[SPR_MQ] = tmp % arg2;
tmp /= (int32_t)arg2;
if ((int32_t)tmp != tmp) {
- env->xer |= (1 << XER_OV) | (1 << XER_SO);
+ env->so = env->ov = 1;
} else {
- env->xer &= ~(1 << XER_OV);
+ env->ov = 0;
}
return tmp;
}
@@ -239,11 +228,11 @@ target_ulong helper_divso(CPUPPCState *env, target_ulong arg1,
{
if (((int32_t)arg1 == INT32_MIN && (int32_t)arg2 == (int32_t)-1) ||
(int32_t)arg2 == 0) {
- env->xer |= (1 << XER_OV) | (1 << XER_SO);
+ env->so = env->ov = 1;
env->spr[SPR_MQ] = 0;
return INT32_MIN;
} else {
- env->xer &= ~(1 << XER_OV);
+ env->ov = 0;
env->spr[SPR_MQ] = (int32_t)arg1 % (int32_t)arg2;
return (int32_t)arg1 / (int32_t)arg2;
}
diff --git a/target-ppc/kvm-stub.c b/target-ppc/kvm-stub.c
new file mode 100644
index 000000000..ee3f5d2f7
--- /dev/null
+++ b/target-ppc/kvm-stub.c
@@ -0,0 +1,18 @@
+/*
+ * QEMU KVM PPC specific function stubs
+ *
+ * Copyright Freescale Inc. 2013
+ *
+ * Author: Alexander Graf <agraf@suse.de>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+#include "qemu-common.h"
+#include "hw/ppc/openpic.h"
+
+int kvm_openpic_connect_vcpu(DeviceState *d, CPUState *cs)
+{
+ return -EINVAL;
+}
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 3f5df5772..30a870ecb 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -23,27 +23,27 @@
#include <linux/kvm.h>
#include "qemu-common.h"
-#include "qemu-timer.h"
-#include "sysemu.h"
-#include "kvm.h"
+#include "qemu/timer.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/kvm.h"
#include "kvm_ppc.h"
#include "cpu.h"
-#include "cpus.h"
-#include "device_tree.h"
-#include "hw/sysbus.h"
-#include "hw/spapr.h"
+#include "sysemu/cpus.h"
+#include "sysemu/device_tree.h"
+#include "mmu-hash64.h"
#include "hw/sysbus.h"
-#include "hw/spapr.h"
-#include "hw/spapr_vio.h"
+#include "hw/ppc/spapr.h"
+#include "hw/ppc/spapr_vio.h"
+#include "sysemu/watchdog.h"
//#define DEBUG_KVM
#ifdef DEBUG_KVM
-#define dprintf(fmt, ...) \
+#define DPRINTF(fmt, ...) \
do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
#else
-#define dprintf(fmt, ...) \
+#define DPRINTF(fmt, ...) \
do { } while (0)
#endif
@@ -61,6 +61,11 @@ static int cap_ppc_smt;
static int cap_ppc_rma;
static int cap_spapr_tce;
static int cap_hior;
+static int cap_one_reg;
+static int cap_epr;
+static int cap_ppc_watchdog;
+static int cap_papr;
+static int cap_htab_fd;
/* XXX We have a race condition where we actually have a level triggered
* interrupt, but the infrastructure can't expose that yet, so the guest
@@ -80,6 +85,8 @@ static void kvm_kick_cpu(void *opaque)
qemu_cpu_kick(CPU(cpu));
}
+static int kvm_ppc_register_host_cpu_type(void);
+
int kvm_arch_init(KVMState *s)
{
cap_interrupt_unset = kvm_check_extension(s, KVM_CAP_PPC_UNSET_IRQ);
@@ -89,18 +96,28 @@ int kvm_arch_init(KVMState *s)
cap_ppc_smt = kvm_check_extension(s, KVM_CAP_PPC_SMT);
cap_ppc_rma = kvm_check_extension(s, KVM_CAP_PPC_RMA);
cap_spapr_tce = kvm_check_extension(s, KVM_CAP_SPAPR_TCE);
+ cap_one_reg = kvm_check_extension(s, KVM_CAP_ONE_REG);
cap_hior = kvm_check_extension(s, KVM_CAP_PPC_HIOR);
+ cap_epr = kvm_check_extension(s, KVM_CAP_PPC_EPR);
+ cap_ppc_watchdog = kvm_check_extension(s, KVM_CAP_PPC_BOOKE_WATCHDOG);
+ /* Note: we don't set cap_papr here, because this capability is
+ * only activated after this by kvmppc_set_papr() */
+ cap_htab_fd = kvm_check_extension(s, KVM_CAP_PPC_HTAB_FD);
if (!cap_interrupt_level) {
fprintf(stderr, "KVM: Couldn't find level irq capability. Expect the "
"VM to stall at times!\n");
}
+ kvm_ppc_register_host_cpu_type();
+
return 0;
}
-static int kvm_arch_sync_sregs(CPUPPCState *cenv)
+static int kvm_arch_sync_sregs(PowerPCCPU *cpu)
{
+ CPUPPCState *cenv = &cpu->env;
+ CPUState *cs = CPU(cpu);
struct kvm_sregs sregs;
int ret;
@@ -117,18 +134,20 @@ static int kvm_arch_sync_sregs(CPUPPCState *cenv)
}
}
- ret = kvm_vcpu_ioctl(cenv, KVM_GET_SREGS, &sregs);
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_SREGS, &sregs);
if (ret) {
return ret;
}
sregs.pvr = cenv->spr[SPR_PVR];
- return kvm_vcpu_ioctl(cenv, KVM_SET_SREGS, &sregs);
+ return kvm_vcpu_ioctl(cs, KVM_SET_SREGS, &sregs);
}
/* Set up a shared TLB array with KVM */
-static int kvm_booke206_tlb_init(CPUPPCState *env)
+static int kvm_booke206_tlb_init(PowerPCCPU *cpu)
{
+ CPUPPCState *env = &cpu->env;
+ CPUState *cs = CPU(cpu);
struct kvm_book3e_206_tlb_params params = {};
struct kvm_config_tlb cfg = {};
struct kvm_enable_cap encap = {};
@@ -136,7 +155,7 @@ static int kvm_booke206_tlb_init(CPUPPCState *env)
int ret, i;
if (!kvm_enabled() ||
- !kvm_check_extension(env->kvm_state, KVM_CAP_SW_TLB)) {
+ !kvm_check_extension(cs->kvm_state, KVM_CAP_SW_TLB)) {
return 0;
}
@@ -161,7 +180,7 @@ static int kvm_booke206_tlb_init(CPUPPCState *env)
encap.cap = KVM_CAP_SW_TLB;
encap.args[0] = (uintptr_t)&cfg;
- ret = kvm_vcpu_ioctl(env, KVM_ENABLE_CAP, &encap);
+ ret = kvm_vcpu_ioctl(cs, KVM_ENABLE_CAP, &encap);
if (ret < 0) {
fprintf(stderr, "%s: couldn't enable KVM_CAP_SW_TLB: %s\n",
__func__, strerror(-ret));
@@ -174,9 +193,12 @@ static int kvm_booke206_tlb_init(CPUPPCState *env)
#if defined(TARGET_PPC64)
-static void kvm_get_fallback_smmu_info(CPUPPCState *env,
+static void kvm_get_fallback_smmu_info(PowerPCCPU *cpu,
struct kvm_ppc_smmu_info *info)
{
+ CPUPPCState *env = &cpu->env;
+ CPUState *cs = CPU(cpu);
+
memset(info, 0, sizeof(*info));
/* We don't have the new KVM_PPC_GET_SMMU_INFO ioctl, so
@@ -202,7 +224,7 @@ static void kvm_get_fallback_smmu_info(CPUPPCState *env,
* implements KVM_CAP_PPC_GET_SMMU_INFO and thus doesn't hit
* this fallback.
*/
- if (kvm_check_extension(env->kvm_state, KVM_CAP_PPC_GET_PVINFO)) {
+ if (kvm_check_extension(cs->kvm_state, KVM_CAP_PPC_GET_PVINFO)) {
/* No flags */
info->flags = 0;
info->slb_size = 64;
@@ -258,18 +280,19 @@ static void kvm_get_fallback_smmu_info(CPUPPCState *env,
}
}
-static void kvm_get_smmu_info(CPUPPCState *env, struct kvm_ppc_smmu_info *info)
+static void kvm_get_smmu_info(PowerPCCPU *cpu, struct kvm_ppc_smmu_info *info)
{
+ CPUState *cs = CPU(cpu);
int ret;
- if (kvm_check_extension(env->kvm_state, KVM_CAP_PPC_GET_SMMU_INFO)) {
- ret = kvm_vm_ioctl(env->kvm_state, KVM_PPC_GET_SMMU_INFO, info);
+ if (kvm_check_extension(cs->kvm_state, KVM_CAP_PPC_GET_SMMU_INFO)) {
+ ret = kvm_vm_ioctl(cs->kvm_state, KVM_PPC_GET_SMMU_INFO, info);
if (ret == 0) {
return;
}
}
- kvm_get_fallback_smmu_info(env, info);
+ kvm_get_fallback_smmu_info(cpu, info);
}
static long getrampagesize(void)
@@ -312,10 +335,11 @@ static bool kvm_valid_page_size(uint32_t flags, long rampgsize, uint32_t shift)
return (1ul << shift) <= rampgsize;
}
-static void kvm_fixup_page_sizes(CPUPPCState *env)
+static void kvm_fixup_page_sizes(PowerPCCPU *cpu)
{
static struct kvm_ppc_smmu_info smmu_info;
static bool has_smmu_info;
+ CPUPPCState *env = &cpu->env;
long rampagesize;
int iq, ik, jq, jk;
@@ -326,7 +350,7 @@ static void kvm_fixup_page_sizes(CPUPPCState *env)
/* Collect MMU info from kernel if not already */
if (!has_smmu_info) {
- kvm_get_smmu_info(env, &smmu_info);
+ kvm_get_smmu_info(cpu, &smmu_info);
has_smmu_info = true;
}
@@ -369,22 +393,28 @@ static void kvm_fixup_page_sizes(CPUPPCState *env)
}
#else /* defined (TARGET_PPC64) */
-static inline void kvm_fixup_page_sizes(CPUPPCState *env)
+static inline void kvm_fixup_page_sizes(PowerPCCPU *cpu)
{
}
#endif /* !defined (TARGET_PPC64) */
-int kvm_arch_init_vcpu(CPUPPCState *cenv)
+unsigned long kvm_arch_vcpu_id(CPUState *cpu)
+{
+ return cpu->cpu_index;
+}
+
+int kvm_arch_init_vcpu(CPUState *cs)
{
- PowerPCCPU *cpu = ppc_env_get_cpu(cenv);
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *cenv = &cpu->env;
int ret;
/* Gather server mmu info from KVM and update the CPU state */
- kvm_fixup_page_sizes(cenv);
+ kvm_fixup_page_sizes(cpu);
/* Synchronize sregs with kvm */
- ret = kvm_arch_sync_sregs(cenv);
+ ret = kvm_arch_sync_sregs(cpu);
if (ret) {
return ret;
}
@@ -394,7 +424,7 @@ int kvm_arch_init_vcpu(CPUPPCState *cenv)
/* Some targets support access to KVM's guest TLB. */
switch (cenv->mmu_model) {
case POWERPC_MMU_BOOKE206:
- ret = kvm_booke206_tlb_init(cenv);
+ ret = kvm_booke206_tlb_init(cpu);
break;
default:
break;
@@ -403,12 +433,14 @@ int kvm_arch_init_vcpu(CPUPPCState *cenv)
return ret;
}
-void kvm_arch_reset_vcpu(CPUPPCState *env)
+void kvm_arch_reset_vcpu(CPUState *cpu)
{
}
-static void kvm_sw_tlb_put(CPUPPCState *env)
+static void kvm_sw_tlb_put(PowerPCCPU *cpu)
{
+ CPUPPCState *env = &cpu->env;
+ CPUState *cs = CPU(cpu);
struct kvm_dirty_tlb dirty_tlb;
unsigned char *bitmap;
int ret;
@@ -423,7 +455,7 @@ static void kvm_sw_tlb_put(CPUPPCState *env)
dirty_tlb.bitmap = (uintptr_t)bitmap;
dirty_tlb.num_dirty = env->nb_tlb;
- ret = kvm_vcpu_ioctl(env, KVM_DIRTY_TLB, &dirty_tlb);
+ ret = kvm_vcpu_ioctl(cs, KVM_DIRTY_TLB, &dirty_tlb);
if (ret) {
fprintf(stderr, "%s: KVM_DIRTY_TLB: %s\n",
__func__, strerror(-ret));
@@ -432,19 +464,315 @@ static void kvm_sw_tlb_put(CPUPPCState *env)
g_free(bitmap);
}
-int kvm_arch_put_registers(CPUPPCState *env, int level)
+static void kvm_get_one_spr(CPUState *cs, uint64_t id, int spr)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+ union {
+ uint32_t u32;
+ uint64_t u64;
+ } val;
+ struct kvm_one_reg reg = {
+ .id = id,
+ .addr = (uintptr_t) &val,
+ };
+ int ret;
+
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
+ if (ret != 0) {
+ fprintf(stderr, "Warning: Unable to retrieve SPR %d from KVM: %s\n",
+ spr, strerror(errno));
+ } else {
+ switch (id & KVM_REG_SIZE_MASK) {
+ case KVM_REG_SIZE_U32:
+ env->spr[spr] = val.u32;
+ break;
+
+ case KVM_REG_SIZE_U64:
+ env->spr[spr] = val.u64;
+ break;
+
+ default:
+ /* Don't handle this size yet */
+ abort();
+ }
+ }
+}
+
+static void kvm_put_one_spr(CPUState *cs, uint64_t id, int spr)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+ union {
+ uint32_t u32;
+ uint64_t u64;
+ } val;
+ struct kvm_one_reg reg = {
+ .id = id,
+ .addr = (uintptr_t) &val,
+ };
+ int ret;
+
+ switch (id & KVM_REG_SIZE_MASK) {
+ case KVM_REG_SIZE_U32:
+ val.u32 = env->spr[spr];
+ break;
+
+ case KVM_REG_SIZE_U64:
+ val.u64 = env->spr[spr];
+ break;
+
+ default:
+ /* Don't handle this size yet */
+ abort();
+ }
+
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
+ if (ret != 0) {
+ fprintf(stderr, "Warning: Unable to set SPR %d to KVM: %s\n",
+ spr, strerror(errno));
+ }
+}
+
+static int kvm_put_fp(CPUState *cs)
{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+ struct kvm_one_reg reg;
+ int i;
+ int ret;
+
+ if (env->insns_flags & PPC_FLOAT) {
+ uint64_t fpscr = env->fpscr;
+ bool vsx = !!(env->insns_flags2 & PPC2_VSX);
+
+ reg.id = KVM_REG_PPC_FPSCR;
+ reg.addr = (uintptr_t)&fpscr;
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
+ if (ret < 0) {
+ DPRINTF("Unable to set FPSCR to KVM: %s\n", strerror(errno));
+ return ret;
+ }
+
+ for (i = 0; i < 32; i++) {
+ uint64_t vsr[2];
+
+ vsr[0] = float64_val(env->fpr[i]);
+ vsr[1] = env->vsr[i];
+ reg.addr = (uintptr_t) &vsr;
+ reg.id = vsx ? KVM_REG_PPC_VSR(i) : KVM_REG_PPC_FPR(i);
+
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
+ if (ret < 0) {
+ DPRINTF("Unable to set %s%d to KVM: %s\n", vsx ? "VSR" : "FPR",
+ i, strerror(errno));
+ return ret;
+ }
+ }
+ }
+
+ if (env->insns_flags & PPC_ALTIVEC) {
+ reg.id = KVM_REG_PPC_VSCR;
+ reg.addr = (uintptr_t)&env->vscr;
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
+ if (ret < 0) {
+ DPRINTF("Unable to set VSCR to KVM: %s\n", strerror(errno));
+ return ret;
+ }
+
+ for (i = 0; i < 32; i++) {
+ reg.id = KVM_REG_PPC_VR(i);
+ reg.addr = (uintptr_t)&env->avr[i];
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
+ if (ret < 0) {
+ DPRINTF("Unable to set VR%d to KVM: %s\n", i, strerror(errno));
+ return ret;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int kvm_get_fp(CPUState *cs)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+ struct kvm_one_reg reg;
+ int i;
+ int ret;
+
+ if (env->insns_flags & PPC_FLOAT) {
+ uint64_t fpscr;
+ bool vsx = !!(env->insns_flags2 & PPC2_VSX);
+
+ reg.id = KVM_REG_PPC_FPSCR;
+ reg.addr = (uintptr_t)&fpscr;
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
+ if (ret < 0) {
+ DPRINTF("Unable to get FPSCR from KVM: %s\n", strerror(errno));
+ return ret;
+ } else {
+ env->fpscr = fpscr;
+ }
+
+ for (i = 0; i < 32; i++) {
+ uint64_t vsr[2];
+
+ reg.addr = (uintptr_t) &vsr;
+ reg.id = vsx ? KVM_REG_PPC_VSR(i) : KVM_REG_PPC_FPR(i);
+
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
+ if (ret < 0) {
+ DPRINTF("Unable to get %s%d from KVM: %s\n",
+ vsx ? "VSR" : "FPR", i, strerror(errno));
+ return ret;
+ } else {
+ env->fpr[i] = vsr[0];
+ if (vsx) {
+ env->vsr[i] = vsr[1];
+ }
+ }
+ }
+ }
+
+ if (env->insns_flags & PPC_ALTIVEC) {
+ reg.id = KVM_REG_PPC_VSCR;
+ reg.addr = (uintptr_t)&env->vscr;
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
+ if (ret < 0) {
+ DPRINTF("Unable to get VSCR from KVM: %s\n", strerror(errno));
+ return ret;
+ }
+
+ for (i = 0; i < 32; i++) {
+ reg.id = KVM_REG_PPC_VR(i);
+ reg.addr = (uintptr_t)&env->avr[i];
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
+ if (ret < 0) {
+ DPRINTF("Unable to get VR%d from KVM: %s\n",
+ i, strerror(errno));
+ return ret;
+ }
+ }
+ }
+
+ return 0;
+}
+
+#if defined(TARGET_PPC64)
+static int kvm_get_vpa(CPUState *cs)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+ struct kvm_one_reg reg;
+ int ret;
+
+ reg.id = KVM_REG_PPC_VPA_ADDR;
+ reg.addr = (uintptr_t)&env->vpa_addr;
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
+ if (ret < 0) {
+ DPRINTF("Unable to get VPA address from KVM: %s\n", strerror(errno));
+ return ret;
+ }
+
+ assert((uintptr_t)&env->slb_shadow_size
+ == ((uintptr_t)&env->slb_shadow_addr + 8));
+ reg.id = KVM_REG_PPC_VPA_SLB;
+ reg.addr = (uintptr_t)&env->slb_shadow_addr;
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
+ if (ret < 0) {
+ DPRINTF("Unable to get SLB shadow state from KVM: %s\n",
+ strerror(errno));
+ return ret;
+ }
+
+ assert((uintptr_t)&env->dtl_size == ((uintptr_t)&env->dtl_addr + 8));
+ reg.id = KVM_REG_PPC_VPA_DTL;
+ reg.addr = (uintptr_t)&env->dtl_addr;
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
+ if (ret < 0) {
+ DPRINTF("Unable to get dispatch trace log state from KVM: %s\n",
+ strerror(errno));
+ return ret;
+ }
+
+ return 0;
+}
+
+static int kvm_put_vpa(CPUState *cs)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
+ struct kvm_one_reg reg;
+ int ret;
+
+ /* SLB shadow or DTL can't be registered unless a master VPA is
+ * registered. That means when restoring state, if a VPA *is*
+ * registered, we need to set that up first. If not, we need to
+ * deregister the others before deregistering the master VPA */
+ assert(env->vpa_addr || !(env->slb_shadow_addr || env->dtl_addr));
+
+ if (env->vpa_addr) {
+ reg.id = KVM_REG_PPC_VPA_ADDR;
+ reg.addr = (uintptr_t)&env->vpa_addr;
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
+ if (ret < 0) {
+ DPRINTF("Unable to set VPA address to KVM: %s\n", strerror(errno));
+ return ret;
+ }
+ }
+
+ assert((uintptr_t)&env->slb_shadow_size
+ == ((uintptr_t)&env->slb_shadow_addr + 8));
+ reg.id = KVM_REG_PPC_VPA_SLB;
+ reg.addr = (uintptr_t)&env->slb_shadow_addr;
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
+ if (ret < 0) {
+ DPRINTF("Unable to set SLB shadow state to KVM: %s\n", strerror(errno));
+ return ret;
+ }
+
+ assert((uintptr_t)&env->dtl_size == ((uintptr_t)&env->dtl_addr + 8));
+ reg.id = KVM_REG_PPC_VPA_DTL;
+ reg.addr = (uintptr_t)&env->dtl_addr;
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
+ if (ret < 0) {
+ DPRINTF("Unable to set dispatch trace log state to KVM: %s\n",
+ strerror(errno));
+ return ret;
+ }
+
+ if (!env->vpa_addr) {
+ reg.id = KVM_REG_PPC_VPA_ADDR;
+ reg.addr = (uintptr_t)&env->vpa_addr;
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
+ if (ret < 0) {
+ DPRINTF("Unable to set VPA address to KVM: %s\n", strerror(errno));
+ return ret;
+ }
+ }
+
+ return 0;
+}
+#endif /* TARGET_PPC64 */
+
+int kvm_arch_put_registers(CPUState *cs, int level)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
struct kvm_regs regs;
int ret;
int i;
- ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, &regs);
- if (ret < 0)
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_REGS, &regs);
+ if (ret < 0) {
return ret;
+ }
regs.ctr = env->ctr;
regs.lr = env->lr;
- regs.xer = env->xer;
+ regs.xer = cpu_read_xer(env);
regs.msr = env->msr;
regs.pc = env->nip;
@@ -465,12 +793,19 @@ int kvm_arch_put_registers(CPUPPCState *env, int level)
for (i = 0;i < 32; i++)
regs.gpr[i] = env->gpr[i];
- ret = kvm_vcpu_ioctl(env, KVM_SET_REGS, &regs);
+ regs.cr = 0;
+ for (i = 0; i < 8; i++) {
+ regs.cr |= (env->crf[i] & 15) << (4 * (7 - i));
+ }
+
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, &regs);
if (ret < 0)
return ret;
+ kvm_put_fp(cs);
+
if (env->tlb_dirty) {
- kvm_sw_tlb_put(env);
+ kvm_sw_tlb_put(cpu);
env->tlb_dirty = false;
}
@@ -503,36 +838,53 @@ int kvm_arch_put_registers(CPUPPCState *env, int level)
| env->IBAT[1][i];
}
- ret = kvm_vcpu_ioctl(env, KVM_SET_SREGS, &sregs);
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_SREGS, &sregs);
if (ret) {
return ret;
}
}
if (cap_hior && (level >= KVM_PUT_RESET_STATE)) {
- uint64_t hior = env->spr[SPR_HIOR];
- struct kvm_one_reg reg = {
- .id = KVM_REG_PPC_HIOR,
- .addr = (uintptr_t) &hior,
- };
+ kvm_put_one_spr(cs, KVM_REG_PPC_HIOR, SPR_HIOR);
+ }
- ret = kvm_vcpu_ioctl(env, KVM_SET_ONE_REG, &reg);
- if (ret) {
- return ret;
+ if (cap_one_reg) {
+ int i;
+
+ /* We deliberately ignore errors here, for kernels which have
+ * the ONE_REG calls, but don't support the specific
+ * registers, there's a reasonable chance things will still
+ * work, at least until we try to migrate. */
+ for (i = 0; i < 1024; i++) {
+ uint64_t id = env->spr_cb[i].one_reg_id;
+
+ if (id != 0) {
+ kvm_put_one_spr(cs, id, i);
+ }
+ }
+
+#ifdef TARGET_PPC64
+ if (cap_papr) {
+ if (kvm_put_vpa(cs) < 0) {
+ DPRINTF("Warning: Unable to set VPA information to KVM\n");
+ }
}
+#endif /* TARGET_PPC64 */
}
return ret;
}
-int kvm_arch_get_registers(CPUPPCState *env)
+int kvm_arch_get_registers(CPUState *cs)
{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
struct kvm_regs regs;
struct kvm_sregs sregs;
uint32_t cr;
int i, ret;
- ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, &regs);
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_REGS, &regs);
if (ret < 0)
return ret;
@@ -544,7 +896,7 @@ int kvm_arch_get_registers(CPUPPCState *env)
env->ctr = regs.ctr;
env->lr = regs.lr;
- env->xer = regs.xer;
+ cpu_write_xer(env, regs.xer);
env->msr = regs.msr;
env->nip = regs.pc;
@@ -565,8 +917,10 @@ int kvm_arch_get_registers(CPUPPCState *env)
for (i = 0;i < 32; i++)
env->gpr[i] = regs.gpr[i];
+ kvm_get_fp(cs);
+
if (cap_booke_sregs) {
- ret = kvm_vcpu_ioctl(env, KVM_GET_SREGS, &sregs);
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_SREGS, &sregs);
if (ret < 0) {
return ret;
}
@@ -670,7 +1024,7 @@ int kvm_arch_get_registers(CPUPPCState *env)
}
if (cap_segstate) {
- ret = kvm_vcpu_ioctl(env, KVM_GET_SREGS, &sregs);
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_SREGS, &sregs);
if (ret < 0) {
return ret;
}
@@ -699,10 +1053,38 @@ int kvm_arch_get_registers(CPUPPCState *env)
}
}
+ if (cap_hior) {
+ kvm_get_one_spr(cs, KVM_REG_PPC_HIOR, SPR_HIOR);
+ }
+
+ if (cap_one_reg) {
+ int i;
+
+ /* We deliberately ignore errors here, for kernels which have
+ * the ONE_REG calls, but don't support the specific
+ * registers, there's a reasonable chance things will still
+ * work, at least until we try to migrate. */
+ for (i = 0; i < 1024; i++) {
+ uint64_t id = env->spr_cb[i].one_reg_id;
+
+ if (id != 0) {
+ kvm_get_one_spr(cs, id, i);
+ }
+ }
+
+#ifdef TARGET_PPC64
+ if (cap_papr) {
+ if (kvm_get_vpa(cs) < 0) {
+ DPRINTF("Warning: Unable to get VPA information from KVM\n");
+ }
+ }
+#endif
+ }
+
return 0;
}
-int kvmppc_set_interrupt(CPUPPCState *env, int irq, int level)
+int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level)
{
unsigned virq = level ? KVM_INTERRUPT_SET_LEVEL : KVM_INTERRUPT_UNSET;
@@ -714,7 +1096,7 @@ int kvmppc_set_interrupt(CPUPPCState *env, int irq, int level)
return 0;
}
- kvm_vcpu_ioctl(env, KVM_INTERRUPT, &virq);
+ kvm_vcpu_ioctl(CPU(cpu), KVM_INTERRUPT, &virq);
return 0;
}
@@ -727,8 +1109,10 @@ int kvmppc_set_interrupt(CPUPPCState *env, int irq, int level)
#define PPC_INPUT_INT PPC6xx_INPUT_INT
#endif
-void kvm_arch_pre_run(CPUPPCState *env, struct kvm_run *run)
+void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
int r;
unsigned irq;
@@ -736,7 +1120,7 @@ void kvm_arch_pre_run(CPUPPCState *env, struct kvm_run *run)
* interrupt, reset, etc) in PPC-specific env->irq_input_state. */
if (!cap_interrupt_level &&
run->ready_for_interrupt_injection &&
- (env->interrupt_request & CPU_INTERRUPT_HARD) &&
+ (cs->interrupt_request & CPU_INTERRUPT_HARD) &&
(env->irq_input_state & (1<<PPC_INPUT_INT)))
{
/* For now KVM disregards the 'irq' argument. However, in the
@@ -745,10 +1129,11 @@ void kvm_arch_pre_run(CPUPPCState *env, struct kvm_run *run)
*/
irq = KVM_INTERRUPT_SET;
- dprintf("injected interrupt %d\n", irq);
- r = kvm_vcpu_ioctl(env, KVM_INTERRUPT, &irq);
- if (r < 0)
- printf("cpu %d fail inject %x\n", env->cpu_index, irq);
+ DPRINTF("injected interrupt %d\n", irq);
+ r = kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &irq);
+ if (r < 0) {
+ printf("cpu %d fail inject %x\n", cs->cpu_index, irq);
+ }
/* Always wake up soon in case the interrupt was level based */
qemu_mod_timer(idle_timer, qemu_get_clock_ns(vm_clock) +
@@ -760,19 +1145,22 @@ void kvm_arch_pre_run(CPUPPCState *env, struct kvm_run *run)
* anyways, so we will get a chance to deliver the rest. */
}
-void kvm_arch_post_run(CPUPPCState *env, struct kvm_run *run)
+void kvm_arch_post_run(CPUState *cpu, struct kvm_run *run)
{
}
-int kvm_arch_process_async_events(CPUPPCState *env)
+int kvm_arch_process_async_events(CPUState *cs)
{
- return env->halted;
+ return cs->halted;
}
-static int kvmppc_handle_halt(CPUPPCState *env)
+static int kvmppc_handle_halt(PowerPCCPU *cpu)
{
- if (!(env->interrupt_request & CPU_INTERRUPT_HARD) && (msr_ee)) {
- env->halted = 1;
+ CPUState *cs = CPU(cpu);
+ CPUPPCState *env = &cpu->env;
+
+ if (!(cs->interrupt_request & CPU_INTERRUPT_HARD) && (msr_ee)) {
+ cs->halted = 1;
env->exception_index = EXCP_HLT;
}
@@ -796,33 +1184,46 @@ static int kvmppc_handle_dcr_write(CPUPPCState *env, uint32_t dcrn, uint32_t dat
return 0;
}
-int kvm_arch_handle_exit(CPUPPCState *env, struct kvm_run *run)
+int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
int ret;
switch (run->exit_reason) {
case KVM_EXIT_DCR:
if (run->dcr.is_write) {
- dprintf("handle dcr write\n");
+ DPRINTF("handle dcr write\n");
ret = kvmppc_handle_dcr_write(env, run->dcr.dcrn, run->dcr.data);
} else {
- dprintf("handle dcr read\n");
+ DPRINTF("handle dcr read\n");
ret = kvmppc_handle_dcr_read(env, run->dcr.dcrn, &run->dcr.data);
}
break;
case KVM_EXIT_HLT:
- dprintf("handle halt\n");
- ret = kvmppc_handle_halt(env);
+ DPRINTF("handle halt\n");
+ ret = kvmppc_handle_halt(cpu);
break;
-#ifdef CONFIG_PSERIES
+#if defined(TARGET_PPC64)
case KVM_EXIT_PAPR_HCALL:
- dprintf("handle PAPR hypercall\n");
- run->papr_hcall.ret = spapr_hypercall(ppc_env_get_cpu(env),
+ DPRINTF("handle PAPR hypercall\n");
+ run->papr_hcall.ret = spapr_hypercall(cpu,
run->papr_hcall.nr,
run->papr_hcall.args);
ret = 0;
break;
#endif
+ case KVM_EXIT_EPR:
+ DPRINTF("handle epr\n");
+ run->epr.epr = ldl_phys(env->mpic_iack);
+ ret = 0;
+ break;
+ case KVM_EXIT_WATCHDOG:
+ DPRINTF("handle watchdog expiry\n");
+ watchdog_perform_action();
+ ret = 0;
+ break;
+
default:
fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
ret = -1;
@@ -832,6 +1233,71 @@ int kvm_arch_handle_exit(CPUPPCState *env, struct kvm_run *run)
return ret;
}
+int kvmppc_or_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits)
+{
+ CPUState *cs = CPU(cpu);
+ uint32_t bits = tsr_bits;
+ struct kvm_one_reg reg = {
+ .id = KVM_REG_PPC_OR_TSR,
+ .addr = (uintptr_t) &bits,
+ };
+
+ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
+}
+
+int kvmppc_clear_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits)
+{
+
+ CPUState *cs = CPU(cpu);
+ uint32_t bits = tsr_bits;
+ struct kvm_one_reg reg = {
+ .id = KVM_REG_PPC_CLEAR_TSR,
+ .addr = (uintptr_t) &bits,
+ };
+
+ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
+}
+
+int kvmppc_set_tcr(PowerPCCPU *cpu)
+{
+ CPUState *cs = CPU(cpu);
+ CPUPPCState *env = &cpu->env;
+ uint32_t tcr = env->spr[SPR_BOOKE_TCR];
+
+ struct kvm_one_reg reg = {
+ .id = KVM_REG_PPC_TCR,
+ .addr = (uintptr_t) &tcr,
+ };
+
+ return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
+}
+
+int kvmppc_booke_watchdog_enable(PowerPCCPU *cpu)
+{
+ CPUState *cs = CPU(cpu);
+ struct kvm_enable_cap encap = {};
+ int ret;
+
+ if (!kvm_enabled()) {
+ return -1;
+ }
+
+ if (!cap_ppc_watchdog) {
+ printf("warning: KVM does not support watchdog");
+ return -1;
+ }
+
+ encap.cap = KVM_CAP_PPC_BOOKE_WATCHDOG;
+ ret = kvm_vcpu_ioctl(cs, KVM_ENABLE_CAP, &encap);
+ if (ret < 0) {
+ fprintf(stderr, "%s: couldn't enable KVM_CAP_PPC_BOOKE_WATCHDOG: %s\n",
+ __func__, strerror(-ret));
+ return ret;
+ }
+
+ return ret;
+}
+
static int read_cpuinfo(const char *field, char *value, int len)
{
FILE *f;
@@ -967,16 +1433,38 @@ uint32_t kvmppc_get_dfp(void)
return kvmppc_read_int_cpu_dt("ibm,dfp");
}
+static int kvmppc_get_pvinfo(CPUPPCState *env, struct kvm_ppc_pvinfo *pvinfo)
+ {
+ PowerPCCPU *cpu = ppc_env_get_cpu(env);
+ CPUState *cs = CPU(cpu);
+
+ if (kvm_check_extension(cs->kvm_state, KVM_CAP_PPC_GET_PVINFO) &&
+ !kvm_vm_ioctl(cs->kvm_state, KVM_PPC_GET_PVINFO, pvinfo)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+int kvmppc_get_hasidle(CPUPPCState *env)
+{
+ struct kvm_ppc_pvinfo pvinfo;
+
+ if (!kvmppc_get_pvinfo(env, &pvinfo) &&
+ (pvinfo.flags & KVM_PPC_PVINFO_FLAGS_EV_IDLE)) {
+ return 1;
+ }
+
+ return 0;
+}
+
int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len)
{
uint32_t *hc = (uint32_t*)buf;
-
struct kvm_ppc_pvinfo pvinfo;
- if (kvm_check_extension(env->kvm_state, KVM_CAP_PPC_GET_PVINFO) &&
- !kvm_vm_ioctl(env->kvm_state, KVM_PPC_GET_PVINFO, &pvinfo)) {
+ if (!kvmppc_get_pvinfo(env, &pvinfo)) {
memcpy(buf, pvinfo.hcall, buf_len);
-
return 0;
}
@@ -997,17 +1485,39 @@ int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len)
return 0;
}
-void kvmppc_set_papr(CPUPPCState *env)
+void kvmppc_set_papr(PowerPCCPU *cpu)
{
+ CPUPPCState *env = &cpu->env;
+ CPUState *cs = CPU(cpu);
struct kvm_enable_cap cap = {};
int ret;
cap.cap = KVM_CAP_PPC_PAPR;
- ret = kvm_vcpu_ioctl(env, KVM_ENABLE_CAP, &cap);
+ ret = kvm_vcpu_ioctl(cs, KVM_ENABLE_CAP, &cap);
if (ret) {
cpu_abort(env, "This KVM version does not support PAPR\n");
}
+
+ /* Update the capability flag so we sync the right information
+ * with kvm */
+ cap_papr = 1;
+}
+
+void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy)
+{
+ CPUPPCState *env = &cpu->env;
+ CPUState *cs = CPU(cpu);
+ struct kvm_enable_cap cap = {};
+ int ret;
+
+ cap.cap = KVM_CAP_PPC_EPR;
+ cap.args[0] = mpic_proxy;
+ ret = kvm_vcpu_ioctl(cs, KVM_ENABLE_CAP, &cap);
+
+ if (ret && mpic_proxy) {
+ cpu_abort(env, "This KVM version does not support EPR\n");
+ }
}
int kvmppc_smt_threads(void)
@@ -1052,7 +1562,7 @@ off_t kvmppc_alloc_rma(const char *name, MemoryRegion *sysmem)
};
rma_region = g_new(MemoryRegion, 1);
- memory_region_init_ram_ptr(rma_region, name, size, rma);
+ memory_region_init_ram_ptr(rma_region, NULL, name, size, rma);
vmstate_register_ram_global(rma_region);
memory_region_add_subregion(sysmem, 0, rma_region);
@@ -1061,11 +1571,35 @@ off_t kvmppc_alloc_rma(const char *name, MemoryRegion *sysmem)
uint64_t kvmppc_rma_size(uint64_t current_size, unsigned int hash_shift)
{
+ struct kvm_ppc_smmu_info info;
+ long rampagesize, best_page_shift;
+ int i;
+
if (cap_ppc_rma >= 2) {
return current_size;
}
+
+ /* Find the largest hardware supported page size that's less than
+ * or equal to the (logical) backing page size of guest RAM */
+ kvm_get_smmu_info(POWERPC_CPU(first_cpu), &info);
+ rampagesize = getrampagesize();
+ best_page_shift = 0;
+
+ for (i = 0; i < KVM_PPC_PAGE_SIZES_MAX_SZ; i++) {
+ struct kvm_ppc_one_seg_page_size *sps = &info.sps[i];
+
+ if (!sps->page_shift) {
+ continue;
+ }
+
+ if ((sps->page_shift > best_page_shift)
+ && ((1UL << sps->page_shift) <= rampagesize)) {
+ best_page_shift = sps->page_shift;
+ }
+ }
+
return MIN(current_size,
- getrampagesize() << (hash_shift - 7));
+ 1ULL << (best_page_shift + hash_shift - 7));
}
#endif
@@ -1094,7 +1628,7 @@ void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd)
return NULL;
}
- len = (window_size / SPAPR_TCE_PAGE_SIZE) * sizeof(sPAPRTCE);
+ len = (window_size / SPAPR_TCE_PAGE_SIZE) * sizeof(uint64_t);
/* FIXME: round this up to page size */
table = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
@@ -1117,7 +1651,7 @@ int kvmppc_remove_spapr_tce(void *table, int fd, uint32_t window_size)
return -1;
}
- len = (window_size / SPAPR_TCE_PAGE_SIZE)*sizeof(sPAPRTCE);
+ len = (window_size / SPAPR_TCE_PAGE_SIZE)*sizeof(uint64_t);
if ((munmap(table, len) < 0) ||
(close(fd) < 0)) {
fprintf(stderr, "KVM: Unexpected error removing TCE table: %s",
@@ -1184,53 +1718,151 @@ static void alter_insns(uint64_t *word, uint64_t flags, bool on)
}
}
-const ppc_def_t *kvmppc_host_cpu_def(void)
+static void kvmppc_host_cpu_initfn(Object *obj)
{
- uint32_t host_pvr = mfpvr();
- const ppc_def_t *base_spec;
- ppc_def_t *spec;
+ assert(kvm_enabled());
+}
+
+static void kvmppc_host_cpu_class_init(ObjectClass *oc, void *data)
+{
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
uint32_t vmx = kvmppc_get_vmx();
uint32_t dfp = kvmppc_get_dfp();
+ uint32_t dcache_size = kvmppc_read_int_cpu_dt("d-cache-size");
+ uint32_t icache_size = kvmppc_read_int_cpu_dt("i-cache-size");
- base_spec = ppc_find_by_pvr(host_pvr);
-
- spec = g_malloc0(sizeof(*spec));
- memcpy(spec, base_spec, sizeof(*spec));
-
- /* Now fix up the spec with information we can query from the host */
+ /* Now fix up the class with information we can query from the host */
if (vmx != -1) {
/* Only override when we know what the host supports */
- alter_insns(&spec->insns_flags, PPC_ALTIVEC, vmx > 0);
- alter_insns(&spec->insns_flags2, PPC2_VSX, vmx > 1);
+ alter_insns(&pcc->insns_flags, PPC_ALTIVEC, vmx > 0);
+ alter_insns(&pcc->insns_flags2, PPC2_VSX, vmx > 1);
}
if (dfp != -1) {
/* Only override when we know what the host supports */
- alter_insns(&spec->insns_flags2, PPC2_DFP, dfp);
+ alter_insns(&pcc->insns_flags2, PPC2_DFP, dfp);
}
- return spec;
+ if (dcache_size != -1) {
+ pcc->l1_dcache_size = dcache_size;
+ }
+
+ if (icache_size != -1) {
+ pcc->l1_icache_size = icache_size;
+ }
}
-int kvmppc_fixup_cpu(CPUPPCState *env)
+int kvmppc_fixup_cpu(PowerPCCPU *cpu)
{
+ CPUState *cs = CPU(cpu);
int smt;
/* Adjust cpu index for SMT */
smt = kvmppc_smt_threads();
- env->cpu_index = (env->cpu_index / smp_threads) * smt
- + (env->cpu_index % smp_threads);
+ cs->cpu_index = (cs->cpu_index / smp_threads) * smt
+ + (cs->cpu_index % smp_threads);
+
+ return 0;
+}
+
+bool kvmppc_has_cap_epr(void)
+{
+ return cap_epr;
+}
+
+static int kvm_ppc_register_host_cpu_type(void)
+{
+ TypeInfo type_info = {
+ .name = TYPE_HOST_POWERPC_CPU,
+ .instance_init = kvmppc_host_cpu_initfn,
+ .class_init = kvmppc_host_cpu_class_init,
+ };
+ uint32_t host_pvr = mfpvr();
+ PowerPCCPUClass *pvr_pcc;
+ pvr_pcc = ppc_cpu_class_by_pvr(host_pvr);
+ if (pvr_pcc == NULL) {
+ return -1;
+ }
+ type_info.parent = object_class_get_name(OBJECT_CLASS(pvr_pcc));
+ type_register(&type_info);
return 0;
}
-bool kvm_arch_stop_on_emulation_error(CPUPPCState *env)
+int kvmppc_get_htab_fd(bool write)
+{
+ struct kvm_get_htab_fd s = {
+ .flags = write ? KVM_GET_HTAB_WRITE : 0,
+ .start_index = 0,
+ };
+
+ if (!cap_htab_fd) {
+ fprintf(stderr, "KVM version doesn't support saving the hash table\n");
+ return -1;
+ }
+
+ return kvm_vm_ioctl(kvm_state, KVM_PPC_GET_HTAB_FD, &s);
+}
+
+int kvmppc_save_htab(QEMUFile *f, int fd, size_t bufsize, int64_t max_ns)
+{
+ int64_t starttime = qemu_get_clock_ns(rt_clock);
+ uint8_t buf[bufsize];
+ ssize_t rc;
+
+ do {
+ rc = read(fd, buf, bufsize);
+ if (rc < 0) {
+ fprintf(stderr, "Error reading data from KVM HTAB fd: %s\n",
+ strerror(errno));
+ return rc;
+ } else if (rc) {
+ /* Kernel already retuns data in BE format for the file */
+ qemu_put_buffer(f, buf, rc);
+ }
+ } while ((rc != 0)
+ && ((max_ns < 0)
+ || ((qemu_get_clock_ns(rt_clock) - starttime) < max_ns)));
+
+ return (rc == 0) ? 1 : 0;
+}
+
+int kvmppc_load_htab_chunk(QEMUFile *f, int fd, uint32_t index,
+ uint16_t n_valid, uint16_t n_invalid)
+{
+ struct kvm_get_htab_header *buf;
+ size_t chunksize = sizeof(*buf) + n_valid*HASH_PTE_SIZE_64;
+ ssize_t rc;
+
+ buf = alloca(chunksize);
+ /* This is KVM on ppc, so this is all big-endian */
+ buf->index = index;
+ buf->n_valid = n_valid;
+ buf->n_invalid = n_invalid;
+
+ qemu_get_buffer(f, (void *)(buf + 1), HASH_PTE_SIZE_64*n_valid);
+
+ rc = write(fd, buf, chunksize);
+ if (rc < 0) {
+ fprintf(stderr, "Error writing KVM hash table: %s\n",
+ strerror(errno));
+ return rc;
+ }
+ if (rc != chunksize) {
+ /* We should never get a short write on a single chunk */
+ fprintf(stderr, "Short write, restoring KVM hash table\n");
+ return -1;
+ }
+ return 0;
+}
+
+bool kvm_arch_stop_on_emulation_error(CPUState *cpu)
{
return true;
}
-int kvm_arch_on_sigbus_vcpu(CPUPPCState *env, int code, void *addr)
+int kvm_arch_on_sigbus_vcpu(CPUState *cpu, int code, void *addr)
{
return 1;
}
@@ -1239,3 +1871,7 @@ int kvm_arch_on_sigbus(int code, void *addr)
{
return 1;
}
+
+void kvm_arch_init_irq_routing(KVMState *s)
+{
+}
diff --git a/target-ppc/kvm_ppc.c b/target-ppc/kvm_ppc.c
index a2e49cd42..1b192a803 100644
--- a/target-ppc/kvm_ppc.c
+++ b/target-ppc/kvm_ppc.c
@@ -12,9 +12,9 @@
*/
#include "qemu-common.h"
-#include "qemu-timer.h"
+#include "qemu/timer.h"
#include "kvm_ppc.h"
-#include "device_tree.h"
+#include "sysemu/device_tree.h"
#define PROC_DEVTREE_PATH "/proc/device-tree"
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index baad6eb75..4ae7bf2c3 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -9,7 +9,7 @@
#ifndef __KVM_PPC_H__
#define __KVM_PPC_H__
-#include "memory.h"
+#define TYPE_HOST_POWERPC_CPU "host-" TYPE_POWERPC_CPU
void kvmppc_init(void);
@@ -19,10 +19,16 @@ uint32_t kvmppc_get_tbfreq(void);
uint64_t kvmppc_get_clockfreq(void);
uint32_t kvmppc_get_vmx(void);
uint32_t kvmppc_get_dfp(void);
+int kvmppc_get_hasidle(CPUPPCState *env);
int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len);
-int kvmppc_set_interrupt(CPUPPCState *env, int irq, int level);
-void kvmppc_set_papr(CPUPPCState *env);
+int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level);
+void kvmppc_set_papr(PowerPCCPU *cpu);
+void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy);
int kvmppc_smt_threads(void);
+int kvmppc_clear_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits);
+int kvmppc_or_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits);
+int kvmppc_set_tcr(PowerPCCPU *cpu);
+int kvmppc_booke_watchdog_enable(PowerPCCPU *cpu);
#ifndef CONFIG_USER_ONLY
off_t kvmppc_alloc_rma(const char *name, MemoryRegion *sysmem);
void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd);
@@ -30,8 +36,12 @@ int kvmppc_remove_spapr_tce(void *table, int pfd, uint32_t window_size);
int kvmppc_reset_htab(int shift_hint);
uint64_t kvmppc_rma_size(uint64_t current_size, unsigned int hash_shift);
#endif /* !CONFIG_USER_ONLY */
-const ppc_def_t *kvmppc_host_cpu_def(void);
-int kvmppc_fixup_cpu(CPUPPCState *env);
+int kvmppc_fixup_cpu(PowerPCCPU *cpu);
+bool kvmppc_has_cap_epr(void);
+int kvmppc_get_htab_fd(bool write);
+int kvmppc_save_htab(QEMUFile *f, int fd, size_t bufsize, int64_t max_ns);
+int kvmppc_load_htab_chunk(QEMUFile *f, int fd, uint32_t index,
+ uint16_t n_valid, uint16_t n_invalid);
#else
@@ -55,6 +65,11 @@ static inline uint32_t kvmppc_get_dfp(void)
return 0;
}
+static inline int kvmppc_get_hasidle(CPUPPCState *env)
+{
+ return 0;
+}
+
static inline int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len)
{
return -1;
@@ -65,12 +80,16 @@ static inline int kvmppc_read_segment_page_sizes(uint32_t *prop, int maxcells)
return -1;
}
-static inline int kvmppc_set_interrupt(CPUPPCState *env, int irq, int level)
+static inline int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level)
{
return -1;
}
-static inline void kvmppc_set_papr(CPUPPCState *env)
+static inline void kvmppc_set_papr(PowerPCCPU *cpu)
+{
+}
+
+static inline void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy)
{
}
@@ -79,6 +98,26 @@ static inline int kvmppc_smt_threads(void)
return 1;
}
+static inline int kvmppc_or_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits)
+{
+ return 0;
+}
+
+static inline int kvmppc_clear_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits)
+{
+ return 0;
+}
+
+static inline int kvmppc_set_tcr(PowerPCCPU *cpu)
+{
+ return 0;
+}
+
+static inline int kvmppc_booke_watchdog_enable(PowerPCCPU *cpu)
+{
+ return -1;
+}
+
#ifndef CONFIG_USER_ONLY
static inline off_t kvmppc_alloc_rma(const char *name, MemoryRegion *sysmem)
{
@@ -115,15 +154,33 @@ static inline int kvmppc_update_sdr1(CPUPPCState *env)
#endif /* !CONFIG_USER_ONLY */
-static inline const ppc_def_t *kvmppc_host_cpu_def(void)
+static inline int kvmppc_fixup_cpu(PowerPCCPU *cpu)
{
- return NULL;
+ return -1;
}
-static inline int kvmppc_fixup_cpu(CPUPPCState *env)
+static inline bool kvmppc_has_cap_epr(void)
+{
+ return false;
+}
+
+static inline int kvmppc_get_htab_fd(bool write)
{
return -1;
}
+
+static inline int kvmppc_save_htab(QEMUFile *f, int fd, size_t bufsize,
+ int64_t max_ns)
+{
+ abort();
+}
+
+static inline int kvmppc_load_htab_chunk(QEMUFile *f, int fd, uint32_t index,
+ uint16_t n_valid, uint16_t n_invalid)
+{
+ abort();
+}
+
#endif
#ifndef CONFIG_KVM
diff --git a/target-ppc/machine.c b/target-ppc/machine.c
index 5e7bc00e2..12e151299 100644
--- a/target-ppc/machine.c
+++ b/target-ppc/machine.c
@@ -1,98 +1,16 @@
#include "hw/hw.h"
#include "hw/boards.h"
-#include "kvm.h"
+#include "sysemu/kvm.h"
+#include "helper_regs.h"
-void cpu_save(QEMUFile *f, void *opaque)
+static int cpu_load_old(QEMUFile *f, void *opaque, int version_id)
{
- CPUPPCState *env = (CPUPPCState *)opaque;
- unsigned int i, j;
- uint32_t fpscr;
-
- for (i = 0; i < 32; i++)
- qemu_put_betls(f, &env->gpr[i]);
-#if !defined(TARGET_PPC64)
- for (i = 0; i < 32; i++)
- qemu_put_betls(f, &env->gprh[i]);
-#endif
- qemu_put_betls(f, &env->lr);
- qemu_put_betls(f, &env->ctr);
- for (i = 0; i < 8; i++)
- qemu_put_be32s(f, &env->crf[i]);
- qemu_put_betls(f, &env->xer);
- qemu_put_betls(f, &env->reserve_addr);
- qemu_put_betls(f, &env->msr);
- for (i = 0; i < 4; i++)
- qemu_put_betls(f, &env->tgpr[i]);
- for (i = 0; i < 32; i++) {
- union {
- float64 d;
- uint64_t l;
- } u;
- u.d = env->fpr[i];
- qemu_put_be64(f, u.l);
- }
- fpscr = env->fpscr;
- qemu_put_be32s(f, &fpscr);
- qemu_put_sbe32s(f, &env->access_type);
-#if defined(TARGET_PPC64)
- qemu_put_betls(f, &env->asr);
- qemu_put_sbe32s(f, &env->slb_nr);
-#endif
- qemu_put_betls(f, &env->spr[SPR_SDR1]);
- for (i = 0; i < 32; i++)
- qemu_put_betls(f, &env->sr[i]);
- for (i = 0; i < 2; i++)
- for (j = 0; j < 8; j++)
- qemu_put_betls(f, &env->DBAT[i][j]);
- for (i = 0; i < 2; i++)
- for (j = 0; j < 8; j++)
- qemu_put_betls(f, &env->IBAT[i][j]);
- qemu_put_sbe32s(f, &env->nb_tlb);
- qemu_put_sbe32s(f, &env->tlb_per_way);
- qemu_put_sbe32s(f, &env->nb_ways);
- qemu_put_sbe32s(f, &env->last_way);
- qemu_put_sbe32s(f, &env->id_tlbs);
- qemu_put_sbe32s(f, &env->nb_pids);
- if (env->tlb.tlb6) {
- // XXX assumes 6xx
- for (i = 0; i < env->nb_tlb; i++) {
- qemu_put_betls(f, &env->tlb.tlb6[i].pte0);
- qemu_put_betls(f, &env->tlb.tlb6[i].pte1);
- qemu_put_betls(f, &env->tlb.tlb6[i].EPN);
- }
- }
- for (i = 0; i < 4; i++)
- qemu_put_betls(f, &env->pb[i]);
- for (i = 0; i < 1024; i++)
- qemu_put_betls(f, &env->spr[i]);
- qemu_put_be32s(f, &env->vscr);
- qemu_put_be64s(f, &env->spe_acc);
- qemu_put_be32s(f, &env->spe_fscr);
- qemu_put_betls(f, &env->msr_mask);
- qemu_put_be32s(f, &env->flags);
- qemu_put_sbe32s(f, &env->error_code);
- qemu_put_be32s(f, &env->pending_interrupts);
- qemu_put_be32s(f, &env->irq_input_state);
- for (i = 0; i < POWERPC_EXCP_NB; i++)
- qemu_put_betls(f, &env->excp_vectors[i]);
- qemu_put_betls(f, &env->excp_prefix);
- qemu_put_betls(f, &env->hreset_excp_prefix);
- qemu_put_betls(f, &env->ivor_mask);
- qemu_put_betls(f, &env->ivpr_mask);
- qemu_put_betls(f, &env->hreset_vector);
- qemu_put_betls(f, &env->nip);
- qemu_put_betls(f, &env->hflags);
- qemu_put_betls(f, &env->hflags_nmsr);
- qemu_put_sbe32s(f, &env->mmu_idx);
- qemu_put_sbe32(f, 0);
-}
-
-int cpu_load(QEMUFile *f, void *opaque, int version_id)
-{
- CPUPPCState *env = (CPUPPCState *)opaque;
+ PowerPCCPU *cpu = opaque;
+ CPUPPCState *env = &cpu->env;
unsigned int i, j;
target_ulong sdr1;
uint32_t fpscr;
+ target_ulong xer;
for (i = 0; i < 32; i++)
qemu_get_betls(f, &env->gpr[i]);
@@ -104,7 +22,8 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
qemu_get_betls(f, &env->ctr);
for (i = 0; i < 8; i++)
qemu_get_be32s(f, &env->crf[i]);
- qemu_get_betls(f, &env->xer);
+ qemu_get_betls(f, &xer);
+ cpu_write_xer(env, xer);
qemu_get_betls(f, &env->reserve_addr);
qemu_get_betls(f, &env->msr);
for (i = 0; i < 4; i++)
@@ -121,7 +40,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
env->fpscr = fpscr;
qemu_get_sbe32s(f, &env->access_type);
#if defined(TARGET_PPC64)
- qemu_get_betls(f, &env->asr);
+ qemu_get_betls(f, &env->spr[SPR_ASR]);
qemu_get_sbe32s(f, &env->slb_nr);
#endif
qemu_get_betls(f, &sdr1);
@@ -163,7 +82,6 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
for (i = 0; i < POWERPC_EXCP_NB; i++)
qemu_get_betls(f, &env->excp_vectors[i]);
qemu_get_betls(f, &env->excp_prefix);
- qemu_get_betls(f, &env->hreset_excp_prefix);
qemu_get_betls(f, &env->ivor_mask);
qemu_get_betls(f, &env->ivpr_mask);
qemu_get_betls(f, &env->hreset_vector);
@@ -175,3 +93,442 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
return 0;
}
+
+static int get_avr(QEMUFile *f, void *pv, size_t size)
+{
+ ppc_avr_t *v = pv;
+
+ v->u64[0] = qemu_get_be64(f);
+ v->u64[1] = qemu_get_be64(f);
+
+ return 0;
+}
+
+static void put_avr(QEMUFile *f, void *pv, size_t size)
+{
+ ppc_avr_t *v = pv;
+
+ qemu_put_be64(f, v->u64[0]);
+ qemu_put_be64(f, v->u64[1]);
+}
+
+const VMStateInfo vmstate_info_avr = {
+ .name = "avr",
+ .get = get_avr,
+ .put = put_avr,
+};
+
+#define VMSTATE_AVR_ARRAY_V(_f, _s, _n, _v) \
+ VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_avr, ppc_avr_t)
+
+#define VMSTATE_AVR_ARRAY(_f, _s, _n) \
+ VMSTATE_AVR_ARRAY_V(_f, _s, _n, 0)
+
+static void cpu_pre_save(void *opaque)
+{
+ PowerPCCPU *cpu = opaque;
+ CPUPPCState *env = &cpu->env;
+ int i;
+
+ env->spr[SPR_LR] = env->lr;
+ env->spr[SPR_CTR] = env->ctr;
+ env->spr[SPR_XER] = env->xer;
+#if defined(TARGET_PPC64)
+ env->spr[SPR_CFAR] = env->cfar;
+#endif
+ env->spr[SPR_BOOKE_SPEFSCR] = env->spe_fscr;
+
+ for (i = 0; (i < 4) && (i < env->nb_BATs); i++) {
+ env->spr[SPR_DBAT0U + 2*i] = env->DBAT[0][i];
+ env->spr[SPR_DBAT0U + 2*i + 1] = env->DBAT[1][i];
+ env->spr[SPR_IBAT0U + 2*i] = env->IBAT[0][i];
+ env->spr[SPR_IBAT0U + 2*i + 1] = env->IBAT[1][i];
+ }
+ for (i = 0; (i < 4) && ((i+4) < env->nb_BATs); i++) {
+ env->spr[SPR_DBAT4U + 2*i] = env->DBAT[0][i+4];
+ env->spr[SPR_DBAT4U + 2*i + 1] = env->DBAT[1][i+4];
+ env->spr[SPR_IBAT4U + 2*i] = env->IBAT[0][i+4];
+ env->spr[SPR_IBAT4U + 2*i + 1] = env->IBAT[1][i+4];
+ }
+}
+
+static int cpu_post_load(void *opaque, int version_id)
+{
+ PowerPCCPU *cpu = opaque;
+ CPUPPCState *env = &cpu->env;
+ int i;
+
+ env->lr = env->spr[SPR_LR];
+ env->ctr = env->spr[SPR_CTR];
+ env->xer = env->spr[SPR_XER];
+#if defined(TARGET_PPC64)
+ env->cfar = env->spr[SPR_CFAR];
+#endif
+ env->spe_fscr = env->spr[SPR_BOOKE_SPEFSCR];
+
+ for (i = 0; (i < 4) && (i < env->nb_BATs); i++) {
+ env->DBAT[0][i] = env->spr[SPR_DBAT0U + 2*i];
+ env->DBAT[1][i] = env->spr[SPR_DBAT0U + 2*i + 1];
+ env->IBAT[0][i] = env->spr[SPR_IBAT0U + 2*i];
+ env->IBAT[1][i] = env->spr[SPR_IBAT0U + 2*i + 1];
+ }
+ for (i = 0; (i < 4) && ((i+4) < env->nb_BATs); i++) {
+ env->DBAT[0][i+4] = env->spr[SPR_DBAT4U + 2*i];
+ env->DBAT[1][i+4] = env->spr[SPR_DBAT4U + 2*i + 1];
+ env->IBAT[0][i+4] = env->spr[SPR_IBAT4U + 2*i];
+ env->IBAT[1][i+4] = env->spr[SPR_IBAT4U + 2*i + 1];
+ }
+
+ /* Restore htab_base and htab_mask variables */
+ ppc_store_sdr1(env, env->spr[SPR_SDR1]);
+
+ hreg_compute_hflags(env);
+ hreg_compute_mem_idx(env);
+
+ return 0;
+}
+
+static bool fpu_needed(void *opaque)
+{
+ PowerPCCPU *cpu = opaque;
+
+ return (cpu->env.insns_flags & PPC_FLOAT);
+}
+
+static const VMStateDescription vmstate_fpu = {
+ .name = "cpu/fpu",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField []) {
+ VMSTATE_FLOAT64_ARRAY(env.fpr, PowerPCCPU, 32),
+ VMSTATE_UINTTL(env.fpscr, PowerPCCPU),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
+static bool altivec_needed(void *opaque)
+{
+ PowerPCCPU *cpu = opaque;
+
+ return (cpu->env.insns_flags & PPC_ALTIVEC);
+}
+
+static const VMStateDescription vmstate_altivec = {
+ .name = "cpu/altivec",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField []) {
+ VMSTATE_AVR_ARRAY(env.avr, PowerPCCPU, 32),
+ VMSTATE_UINT32(env.vscr, PowerPCCPU),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
+static bool vsx_needed(void *opaque)
+{
+ PowerPCCPU *cpu = opaque;
+
+ return (cpu->env.insns_flags2 & PPC2_VSX);
+}
+
+static const VMStateDescription vmstate_vsx = {
+ .name = "cpu/vsx",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField []) {
+ VMSTATE_UINT64_ARRAY(env.vsr, PowerPCCPU, 32),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
+static bool sr_needed(void *opaque)
+{
+#ifdef TARGET_PPC64
+ PowerPCCPU *cpu = opaque;
+
+ return !(cpu->env.mmu_model & POWERPC_MMU_64);
+#else
+ return true;
+#endif
+}
+
+static const VMStateDescription vmstate_sr = {
+ .name = "cpu/sr",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField []) {
+ VMSTATE_UINTTL_ARRAY(env.sr, PowerPCCPU, 32),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
+#ifdef TARGET_PPC64
+static int get_slbe(QEMUFile *f, void *pv, size_t size)
+{
+ ppc_slb_t *v = pv;
+
+ v->esid = qemu_get_be64(f);
+ v->vsid = qemu_get_be64(f);
+
+ return 0;
+}
+
+static void put_slbe(QEMUFile *f, void *pv, size_t size)
+{
+ ppc_slb_t *v = pv;
+
+ qemu_put_be64(f, v->esid);
+ qemu_put_be64(f, v->vsid);
+}
+
+const VMStateInfo vmstate_info_slbe = {
+ .name = "slbe",
+ .get = get_slbe,
+ .put = put_slbe,
+};
+
+#define VMSTATE_SLB_ARRAY_V(_f, _s, _n, _v) \
+ VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_slbe, ppc_slb_t)
+
+#define VMSTATE_SLB_ARRAY(_f, _s, _n) \
+ VMSTATE_SLB_ARRAY_V(_f, _s, _n, 0)
+
+static bool slb_needed(void *opaque)
+{
+ PowerPCCPU *cpu = opaque;
+
+ /* We don't support any of the old segment table based 64-bit CPUs */
+ return (cpu->env.mmu_model & POWERPC_MMU_64);
+}
+
+static const VMStateDescription vmstate_slb = {
+ .name = "cpu/slb",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField []) {
+ VMSTATE_INT32_EQUAL(env.slb_nr, PowerPCCPU),
+ VMSTATE_SLB_ARRAY(env.slb, PowerPCCPU, 64),
+ VMSTATE_END_OF_LIST()
+ }
+};
+#endif /* TARGET_PPC64 */
+
+static const VMStateDescription vmstate_tlb6xx_entry = {
+ .name = "cpu/tlb6xx_entry",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField []) {
+ VMSTATE_UINTTL(pte0, ppc6xx_tlb_t),
+ VMSTATE_UINTTL(pte1, ppc6xx_tlb_t),
+ VMSTATE_UINTTL(EPN, ppc6xx_tlb_t),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
+static bool tlb6xx_needed(void *opaque)
+{
+ PowerPCCPU *cpu = opaque;
+ CPUPPCState *env = &cpu->env;
+
+ return env->nb_tlb && (env->tlb_type == TLB_6XX);
+}
+
+static const VMStateDescription vmstate_tlb6xx = {
+ .name = "cpu/tlb6xx",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField []) {
+ VMSTATE_INT32_EQUAL(env.nb_tlb, PowerPCCPU),
+ VMSTATE_STRUCT_VARRAY_POINTER_INT32(env.tlb.tlb6, PowerPCCPU,
+ env.nb_tlb,
+ vmstate_tlb6xx_entry,
+ ppc6xx_tlb_t),
+ VMSTATE_UINTTL_ARRAY(env.tgpr, PowerPCCPU, 4),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static const VMStateDescription vmstate_tlbemb_entry = {
+ .name = "cpu/tlbemb_entry",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField []) {
+ VMSTATE_UINT64(RPN, ppcemb_tlb_t),
+ VMSTATE_UINTTL(EPN, ppcemb_tlb_t),
+ VMSTATE_UINTTL(PID, ppcemb_tlb_t),
+ VMSTATE_UINTTL(size, ppcemb_tlb_t),
+ VMSTATE_UINT32(prot, ppcemb_tlb_t),
+ VMSTATE_UINT32(attr, ppcemb_tlb_t),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
+static bool tlbemb_needed(void *opaque)
+{
+ PowerPCCPU *cpu = opaque;
+ CPUPPCState *env = &cpu->env;
+
+ return env->nb_tlb && (env->tlb_type == TLB_EMB);
+}
+
+static bool pbr403_needed(void *opaque)
+{
+ PowerPCCPU *cpu = opaque;
+ uint32_t pvr = cpu->env.spr[SPR_PVR];
+
+ return (pvr & 0xffff0000) == 0x00200000;
+}
+
+static const VMStateDescription vmstate_pbr403 = {
+ .name = "cpu/pbr403",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField []) {
+ VMSTATE_UINTTL_ARRAY(env.pb, PowerPCCPU, 4),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
+static const VMStateDescription vmstate_tlbemb = {
+ .name = "cpu/tlb6xx",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField []) {
+ VMSTATE_INT32_EQUAL(env.nb_tlb, PowerPCCPU),
+ VMSTATE_STRUCT_VARRAY_POINTER_INT32(env.tlb.tlbe, PowerPCCPU,
+ env.nb_tlb,
+ vmstate_tlbemb_entry,
+ ppcemb_tlb_t),
+ /* 403 protection registers */
+ VMSTATE_END_OF_LIST()
+ },
+ .subsections = (VMStateSubsection []) {
+ {
+ .vmsd = &vmstate_pbr403,
+ .needed = pbr403_needed,
+ } , {
+ /* empty */
+ }
+ }
+};
+
+static const VMStateDescription vmstate_tlbmas_entry = {
+ .name = "cpu/tlbmas_entry",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField []) {
+ VMSTATE_UINT32(mas8, ppcmas_tlb_t),
+ VMSTATE_UINT32(mas1, ppcmas_tlb_t),
+ VMSTATE_UINT64(mas2, ppcmas_tlb_t),
+ VMSTATE_UINT64(mas7_3, ppcmas_tlb_t),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
+static bool tlbmas_needed(void *opaque)
+{
+ PowerPCCPU *cpu = opaque;
+ CPUPPCState *env = &cpu->env;
+
+ return env->nb_tlb && (env->tlb_type == TLB_MAS);
+}
+
+static const VMStateDescription vmstate_tlbmas = {
+ .name = "cpu/tlbmas",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField []) {
+ VMSTATE_INT32_EQUAL(env.nb_tlb, PowerPCCPU),
+ VMSTATE_STRUCT_VARRAY_POINTER_INT32(env.tlb.tlbm, PowerPCCPU,
+ env.nb_tlb,
+ vmstate_tlbmas_entry,
+ ppcmas_tlb_t),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+const VMStateDescription vmstate_ppc_cpu = {
+ .name = "cpu",
+ .version_id = 5,
+ .minimum_version_id = 5,
+ .minimum_version_id_old = 4,
+ .load_state_old = cpu_load_old,
+ .pre_save = cpu_pre_save,
+ .post_load = cpu_post_load,
+ .fields = (VMStateField []) {
+ /* Verify we haven't changed the pvr */
+ VMSTATE_UINTTL_EQUAL(env.spr[SPR_PVR], PowerPCCPU),
+
+ /* User mode architected state */
+ VMSTATE_UINTTL_ARRAY(env.gpr, PowerPCCPU, 32),
+#if !defined(TARGET_PPC64)
+ VMSTATE_UINTTL_ARRAY(env.gprh, PowerPCCPU, 32),
+#endif
+ VMSTATE_UINT32_ARRAY(env.crf, PowerPCCPU, 8),
+ VMSTATE_UINTTL(env.nip, PowerPCCPU),
+
+ /* SPRs */
+ VMSTATE_UINTTL_ARRAY(env.spr, PowerPCCPU, 1024),
+ VMSTATE_UINT64(env.spe_acc, PowerPCCPU),
+
+ /* Reservation */
+ VMSTATE_UINTTL(env.reserve_addr, PowerPCCPU),
+
+ /* Supervisor mode architected state */
+ VMSTATE_UINTTL(env.msr, PowerPCCPU),
+
+ /* Internal state */
+ VMSTATE_UINTTL(env.hflags_nmsr, PowerPCCPU),
+ /* FIXME: access_type? */
+
+ /* Sanity checking */
+ VMSTATE_UINTTL_EQUAL(env.msr_mask, PowerPCCPU),
+ VMSTATE_UINT64_EQUAL(env.insns_flags, PowerPCCPU),
+ VMSTATE_UINT64_EQUAL(env.insns_flags2, PowerPCCPU),
+ VMSTATE_UINT32_EQUAL(env.nb_BATs, PowerPCCPU),
+ VMSTATE_END_OF_LIST()
+ },
+ .subsections = (VMStateSubsection []) {
+ {
+ .vmsd = &vmstate_fpu,
+ .needed = fpu_needed,
+ } , {
+ .vmsd = &vmstate_altivec,
+ .needed = altivec_needed,
+ } , {
+ .vmsd = &vmstate_vsx,
+ .needed = vsx_needed,
+ } , {
+ .vmsd = &vmstate_sr,
+ .needed = sr_needed,
+ } , {
+#ifdef TARGET_PPC64
+ .vmsd = &vmstate_slb,
+ .needed = slb_needed,
+ } , {
+#endif /* TARGET_PPC64 */
+ .vmsd = &vmstate_tlb6xx,
+ .needed = tlb6xx_needed,
+ } , {
+ .vmsd = &vmstate_tlbemb,
+ .needed = tlbemb_needed,
+ } , {
+ .vmsd = &vmstate_tlbmas,
+ .needed = tlbmas_needed,
+ } , {
+ /* empty */
+ }
+ }
+};
diff --git a/target-ppc/mem_helper.c b/target-ppc/mem_helper.c
index 5b5f1bdd2..d8e63ca7d 100644
--- a/target-ppc/mem_helper.c
+++ b/target-ppc/mem_helper.c
@@ -17,13 +17,13 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "cpu.h"
-#include "host-utils.h"
+#include "qemu/host-utils.h"
#include "helper.h"
#include "helper_regs.h"
#if !defined(CONFIG_USER_ONLY)
-#include "softmmu_exec.h"
+#include "exec/softmmu_exec.h"
#endif /* !defined(CONFIG_USER_ONLY) */
//#define DEBUG_OP
@@ -136,18 +136,21 @@ static void do_dcbz(CPUPPCState *env, target_ulong addr, int dcache_line_size)
}
}
-void helper_dcbz(CPUPPCState *env, target_ulong addr)
+void helper_dcbz(CPUPPCState *env, target_ulong addr, uint32_t is_dcbzl)
{
- do_dcbz(env, addr, env->dcache_line_size);
-}
+ int dcbz_size = env->dcache_line_size;
-void helper_dcbz_970(CPUPPCState *env, target_ulong addr)
-{
- if (((env->spr[SPR_970_HID5] >> 7) & 0x3) == 1) {
- do_dcbz(env, addr, 32);
- } else {
- do_dcbz(env, addr, env->dcache_line_size);
+#if defined(TARGET_PPC64)
+ if (!is_dcbzl &&
+ (env->excp_model == POWERPC_EXCP_970) &&
+ ((env->spr[SPR_970_HID5] >> 7) & 0x3) == 1) {
+ dcbz_size = 32;
}
+#endif
+
+ /* XXX add e500mc support */
+
+ do_dcbz(env, addr, dcbz_size);
}
void helper_icbi(CPUPPCState *env, target_ulong addr)
@@ -249,47 +252,3 @@ STVE(stvewx, cpu_stl_data, bswap32, u32)
#undef HI_IDX
#undef LO_IDX
-
-/*****************************************************************************/
-/* Softmmu support */
-#if !defined(CONFIG_USER_ONLY)
-
-#define MMUSUFFIX _mmu
-
-#define SHIFT 0
-#include "softmmu_template.h"
-
-#define SHIFT 1
-#include "softmmu_template.h"
-
-#define SHIFT 2
-#include "softmmu_template.h"
-
-#define SHIFT 3
-#include "softmmu_template.h"
-
-/* try to fill the TLB and return an exception if error. If retaddr is
- NULL, it means that the function was called in C code (i.e. not
- from generated code or from helper.c) */
-/* XXX: fix it to restore all registers */
-void tlb_fill(CPUPPCState *env, target_ulong addr, int is_write, int mmu_idx,
- uintptr_t retaddr)
-{
- TranslationBlock *tb;
- int ret;
-
- ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, mmu_idx);
- if (unlikely(ret != 0)) {
- if (likely(retaddr)) {
- /* now we have a real cpu fault */
- tb = tb_find_pc(retaddr);
- if (likely(tb)) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, retaddr);
- }
- }
- helper_raise_exception_err(env, env->exception_index, env->error_code);
- }
-}
-#endif /* !CONFIG_USER_ONLY */
diff --git a/target-ppc/misc_helper.c b/target-ppc/misc_helper.c
index 26edcca2d..616aab6fb 100644
--- a/target-ppc/misc_helper.c
+++ b/target-ppc/misc_helper.c
@@ -35,12 +35,6 @@ void helper_store_dump_spr(CPUPPCState *env, uint32_t sprn)
env->spr[sprn]);
}
#if !defined(CONFIG_USER_ONLY)
-#if defined(TARGET_PPC64)
-void helper_store_asr(CPUPPCState *env, target_ulong val)
-{
- ppc_store_asr(env, val);
-}
-#endif
void helper_store_sdr1(CPUPPCState *env, target_ulong val)
{
diff --git a/target-ppc/mmu-hash32.c b/target-ppc/mmu-hash32.c
new file mode 100644
index 000000000..6a77dc4f9
--- /dev/null
+++ b/target-ppc/mmu-hash32.c
@@ -0,0 +1,560 @@
+/*
+ * PowerPC MMU, TLB and BAT emulation helpers for QEMU.
+ *
+ * Copyright (c) 2003-2007 Jocelyn Mayer
+ * Copyright (c) 2013 David Gibson, IBM Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cpu.h"
+#include "helper.h"
+#include "sysemu/kvm.h"
+#include "kvm_ppc.h"
+#include "mmu-hash32.h"
+
+//#define DEBUG_MMU
+//#define DEBUG_BAT
+
+#ifdef DEBUG_MMU
+# define LOG_MMU(...) qemu_log(__VA_ARGS__)
+# define LOG_MMU_STATE(cpu) log_cpu_state((cpu), 0)
+#else
+# define LOG_MMU(...) do { } while (0)
+# define LOG_MMU_STATE(cpu) do { } while (0)
+#endif
+
+#ifdef DEBUG_BATS
+# define LOG_BATS(...) qemu_log(__VA_ARGS__)
+#else
+# define LOG_BATS(...) do { } while (0)
+#endif
+
+struct mmu_ctx_hash32 {
+ hwaddr raddr; /* Real address */
+ int prot; /* Protection bits */
+ int key; /* Access key */
+};
+
+static int ppc_hash32_pp_prot(int key, int pp, int nx)
+{
+ int prot;
+
+ if (key == 0) {
+ switch (pp) {
+ case 0x0:
+ case 0x1:
+ case 0x2:
+ prot = PAGE_READ | PAGE_WRITE;
+ break;
+
+ case 0x3:
+ prot = PAGE_READ;
+ break;
+
+ default:
+ abort();
+ }
+ } else {
+ switch (pp) {
+ case 0x0:
+ prot = 0;
+ break;
+
+ case 0x1:
+ case 0x3:
+ prot = PAGE_READ;
+ break;
+
+ case 0x2:
+ prot = PAGE_READ | PAGE_WRITE;
+ break;
+
+ default:
+ abort();
+ }
+ }
+ if (nx == 0) {
+ prot |= PAGE_EXEC;
+ }
+
+ return prot;
+}
+
+static int ppc_hash32_pte_prot(CPUPPCState *env,
+ target_ulong sr, ppc_hash_pte32_t pte)
+{
+ unsigned pp, key;
+
+ key = !!(msr_pr ? (sr & SR32_KP) : (sr & SR32_KS));
+ pp = pte.pte1 & HPTE32_R_PP;
+
+ return ppc_hash32_pp_prot(key, pp, !!(sr & SR32_NX));
+}
+
+static target_ulong hash32_bat_size(CPUPPCState *env,
+ target_ulong batu, target_ulong batl)
+{
+ if ((msr_pr && !(batu & BATU32_VP))
+ || (!msr_pr && !(batu & BATU32_VS))) {
+ return 0;
+ }
+
+ return BATU32_BEPI & ~((batu & BATU32_BL) << 15);
+}
+
+static int hash32_bat_prot(CPUPPCState *env,
+ target_ulong batu, target_ulong batl)
+{
+ int pp, prot;
+
+ prot = 0;
+ pp = batl & BATL32_PP;
+ if (pp != 0) {
+ prot = PAGE_READ | PAGE_EXEC;
+ if (pp == 0x2) {
+ prot |= PAGE_WRITE;
+ }
+ }
+ return prot;
+}
+
+static target_ulong hash32_bat_601_size(CPUPPCState *env,
+ target_ulong batu, target_ulong batl)
+{
+ if (!(batl & BATL32_601_V)) {
+ return 0;
+ }
+
+ return BATU32_BEPI & ~((batl & BATL32_601_BL) << 17);
+}
+
+static int hash32_bat_601_prot(CPUPPCState *env,
+ target_ulong batu, target_ulong batl)
+{
+ int key, pp;
+
+ pp = batu & BATU32_601_PP;
+ if (msr_pr == 0) {
+ key = !!(batu & BATU32_601_KS);
+ } else {
+ key = !!(batu & BATU32_601_KP);
+ }
+ return ppc_hash32_pp_prot(key, pp, 0);
+}
+
+static hwaddr ppc_hash32_bat_lookup(CPUPPCState *env, target_ulong ea, int rwx,
+ int *prot)
+{
+ target_ulong *BATlt, *BATut;
+ int i;
+
+ LOG_BATS("%s: %cBAT v " TARGET_FMT_lx "\n", __func__,
+ rwx == 2 ? 'I' : 'D', ea);
+ if (rwx == 2) {
+ BATlt = env->IBAT[1];
+ BATut = env->IBAT[0];
+ } else {
+ BATlt = env->DBAT[1];
+ BATut = env->DBAT[0];
+ }
+ for (i = 0; i < env->nb_BATs; i++) {
+ target_ulong batu = BATut[i];
+ target_ulong batl = BATlt[i];
+ target_ulong mask;
+
+ if (unlikely(env->mmu_model == POWERPC_MMU_601)) {
+ mask = hash32_bat_601_size(env, batu, batl);
+ } else {
+ mask = hash32_bat_size(env, batu, batl);
+ }
+ LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
+ " BATl " TARGET_FMT_lx "\n", __func__,
+ type == ACCESS_CODE ? 'I' : 'D', i, ea, batu, batl);
+
+ if (mask && ((ea & mask) == (batu & BATU32_BEPI))) {
+ hwaddr raddr = (batl & mask) | (ea & ~mask);
+
+ if (unlikely(env->mmu_model == POWERPC_MMU_601)) {
+ *prot = hash32_bat_601_prot(env, batu, batl);
+ } else {
+ *prot = hash32_bat_prot(env, batu, batl);
+ }
+
+ return raddr & TARGET_PAGE_MASK;
+ }
+ }
+
+ /* No hit */
+#if defined(DEBUG_BATS)
+ if (qemu_log_enabled()) {
+ LOG_BATS("no BAT match for " TARGET_FMT_lx ":\n", ea);
+ for (i = 0; i < 4; i++) {
+ BATu = &BATut[i];
+ BATl = &BATlt[i];
+ BEPIu = *BATu & BATU32_BEPIU;
+ BEPIl = *BATu & BATU32_BEPIL;
+ bl = (*BATu & 0x00001FFC) << 15;
+ LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
+ " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " "
+ TARGET_FMT_lx " " TARGET_FMT_lx "\n",
+ __func__, type == ACCESS_CODE ? 'I' : 'D', i, ea,
+ *BATu, *BATl, BEPIu, BEPIl, bl);
+ }
+ }
+#endif
+
+ return -1;
+}
+
+static int ppc_hash32_direct_store(CPUPPCState *env, target_ulong sr,
+ target_ulong eaddr, int rwx,
+ hwaddr *raddr, int *prot)
+{
+ int key = !!(msr_pr ? (sr & SR32_KP) : (sr & SR32_KS));
+
+ LOG_MMU("direct store...\n");
+
+ if ((sr & 0x1FF00000) >> 20 == 0x07f) {
+ /* Memory-forced I/O controller interface access */
+ /* If T=1 and BUID=x'07F', the 601 performs a memory access
+ * to SR[28-31] LA[4-31], bypassing all protection mechanisms.
+ */
+ *raddr = ((sr & 0xF) << 28) | (eaddr & 0x0FFFFFFF);
+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ return 0;
+ }
+
+ if (rwx == 2) {
+ /* No code fetch is allowed in direct-store areas */
+ env->exception_index = POWERPC_EXCP_ISI;
+ env->error_code = 0x10000000;
+ return 1;
+ }
+
+ switch (env->access_type) {
+ case ACCESS_INT:
+ /* Integer load/store : only access allowed */
+ break;
+ case ACCESS_FLOAT:
+ /* Floating point load/store */
+ env->exception_index = POWERPC_EXCP_ALIGN;
+ env->error_code = POWERPC_EXCP_ALIGN_FP;
+ env->spr[SPR_DAR] = eaddr;
+ return 1;
+ case ACCESS_RES:
+ /* lwarx, ldarx or srwcx. */
+ env->error_code = 0;
+ env->spr[SPR_DAR] = eaddr;
+ if (rwx == 1) {
+ env->spr[SPR_DSISR] = 0x06000000;
+ } else {
+ env->spr[SPR_DSISR] = 0x04000000;
+ }
+ return 1;
+ case ACCESS_CACHE:
+ /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */
+ /* Should make the instruction do no-op.
+ * As it already do no-op, it's quite easy :-)
+ */
+ *raddr = eaddr;
+ return 0;
+ case ACCESS_EXT:
+ /* eciwx or ecowx */
+ env->exception_index = POWERPC_EXCP_DSI;
+ env->error_code = 0;
+ env->spr[SPR_DAR] = eaddr;
+ if (rwx == 1) {
+ env->spr[SPR_DSISR] = 0x06100000;
+ } else {
+ env->spr[SPR_DSISR] = 0x04100000;
+ }
+ return 1;
+ default:
+ qemu_log("ERROR: instruction should not need "
+ "address translation\n");
+ abort();
+ }
+ if ((rwx == 1 || key != 1) && (rwx == 0 || key != 0)) {
+ *raddr = eaddr;
+ return 0;
+ } else {
+ env->exception_index = POWERPC_EXCP_DSI;
+ env->error_code = 0;
+ env->spr[SPR_DAR] = eaddr;
+ if (rwx == 1) {
+ env->spr[SPR_DSISR] = 0x0a000000;
+ } else {
+ env->spr[SPR_DSISR] = 0x08000000;
+ }
+ return 1;
+ }
+}
+
+hwaddr get_pteg_offset32(CPUPPCState *env, hwaddr hash)
+{
+ return (hash * HASH_PTEG_SIZE_32) & env->htab_mask;
+}
+
+static hwaddr ppc_hash32_pteg_search(CPUPPCState *env, hwaddr pteg_off,
+ bool secondary, target_ulong ptem,
+ ppc_hash_pte32_t *pte)
+{
+ hwaddr pte_offset = pteg_off;
+ target_ulong pte0, pte1;
+ int i;
+
+ for (i = 0; i < HPTES_PER_GROUP; i++) {
+ pte0 = ppc_hash32_load_hpte0(env, pte_offset);
+ pte1 = ppc_hash32_load_hpte1(env, pte_offset);
+
+ if ((pte0 & HPTE32_V_VALID)
+ && (secondary == !!(pte0 & HPTE32_V_SECONDARY))
+ && HPTE32_V_COMPARE(pte0, ptem)) {
+ pte->pte0 = pte0;
+ pte->pte1 = pte1;
+ return pte_offset;
+ }
+
+ pte_offset += HASH_PTE_SIZE_32;
+ }
+
+ return -1;
+}
+
+static hwaddr ppc_hash32_htab_lookup(CPUPPCState *env,
+ target_ulong sr, target_ulong eaddr,
+ ppc_hash_pte32_t *pte)
+{
+ hwaddr pteg_off, pte_offset;
+ hwaddr hash;
+ uint32_t vsid, pgidx, ptem;
+
+ vsid = sr & SR32_VSID;
+ pgidx = (eaddr & ~SEGMENT_MASK_256M) >> TARGET_PAGE_BITS;
+ hash = vsid ^ pgidx;
+ ptem = (vsid << 7) | (pgidx >> 10);
+
+ /* Page address translation */
+ LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx
+ " hash " TARGET_FMT_plx "\n",
+ env->htab_base, env->htab_mask, hash);
+
+ /* Primary PTEG lookup */
+ LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
+ " vsid=%" PRIx32 " ptem=%" PRIx32
+ " hash=" TARGET_FMT_plx "\n",
+ env->htab_base, env->htab_mask, vsid, ptem, hash);
+ pteg_off = get_pteg_offset32(env, hash);
+ pte_offset = ppc_hash32_pteg_search(env, pteg_off, 0, ptem, pte);
+ if (pte_offset == -1) {
+ /* Secondary PTEG lookup */
+ LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
+ " vsid=%" PRIx32 " api=%" PRIx32
+ " hash=" TARGET_FMT_plx "\n", env->htab_base,
+ env->htab_mask, vsid, ptem, ~hash);
+ pteg_off = get_pteg_offset32(env, ~hash);
+ pte_offset = ppc_hash32_pteg_search(env, pteg_off, 1, ptem, pte);
+ }
+
+ return pte_offset;
+}
+
+static hwaddr ppc_hash32_pte_raddr(target_ulong sr, ppc_hash_pte32_t pte,
+ target_ulong eaddr)
+{
+ hwaddr rpn = pte.pte1 & HPTE32_R_RPN;
+ hwaddr mask = ~TARGET_PAGE_MASK;
+
+ return (rpn & ~mask) | (eaddr & mask);
+}
+
+int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, int rwx,
+ int mmu_idx)
+{
+ target_ulong sr;
+ hwaddr pte_offset;
+ ppc_hash_pte32_t pte;
+ int prot;
+ uint32_t new_pte1;
+ const int need_prot[] = {PAGE_READ, PAGE_WRITE, PAGE_EXEC};
+ hwaddr raddr;
+
+ assert((rwx == 0) || (rwx == 1) || (rwx == 2));
+
+ /* 1. Handle real mode accesses */
+ if (((rwx == 2) && (msr_ir == 0)) || ((rwx != 2) && (msr_dr == 0))) {
+ /* Translation is off */
+ raddr = eaddr;
+ tlb_set_page(env, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
+ PAGE_READ | PAGE_WRITE | PAGE_EXEC, mmu_idx,
+ TARGET_PAGE_SIZE);
+ return 0;
+ }
+
+ /* 2. Check Block Address Translation entries (BATs) */
+ if (env->nb_BATs != 0) {
+ raddr = ppc_hash32_bat_lookup(env, eaddr, rwx, &prot);
+ if (raddr != -1) {
+ if (need_prot[rwx] & ~prot) {
+ if (rwx == 2) {
+ env->exception_index = POWERPC_EXCP_ISI;
+ env->error_code = 0x08000000;
+ } else {
+ env->exception_index = POWERPC_EXCP_DSI;
+ env->error_code = 0;
+ env->spr[SPR_DAR] = eaddr;
+ if (rwx == 1) {
+ env->spr[SPR_DSISR] = 0x0a000000;
+ } else {
+ env->spr[SPR_DSISR] = 0x08000000;
+ }
+ }
+ return 1;
+ }
+
+ tlb_set_page(env, eaddr & TARGET_PAGE_MASK,
+ raddr & TARGET_PAGE_MASK, prot, mmu_idx,
+ TARGET_PAGE_SIZE);
+ return 0;
+ }
+ }
+
+ /* 3. Look up the Segment Register */
+ sr = env->sr[eaddr >> 28];
+
+ /* 4. Handle direct store segments */
+ if (sr & SR32_T) {
+ if (ppc_hash32_direct_store(env, sr, eaddr, rwx,
+ &raddr, &prot) == 0) {
+ tlb_set_page(env, eaddr & TARGET_PAGE_MASK,
+ raddr & TARGET_PAGE_MASK, prot, mmu_idx,
+ TARGET_PAGE_SIZE);
+ return 0;
+ } else {
+ return 1;
+ }
+ }
+
+ /* 5. Check for segment level no-execute violation */
+ if ((rwx == 2) && (sr & SR32_NX)) {
+ env->exception_index = POWERPC_EXCP_ISI;
+ env->error_code = 0x10000000;
+ return 1;
+ }
+
+ /* 6. Locate the PTE in the hash table */
+ pte_offset = ppc_hash32_htab_lookup(env, sr, eaddr, &pte);
+ if (pte_offset == -1) {
+ if (rwx == 2) {
+ env->exception_index = POWERPC_EXCP_ISI;
+ env->error_code = 0x40000000;
+ } else {
+ env->exception_index = POWERPC_EXCP_DSI;
+ env->error_code = 0;
+ env->spr[SPR_DAR] = eaddr;
+ if (rwx == 1) {
+ env->spr[SPR_DSISR] = 0x42000000;
+ } else {
+ env->spr[SPR_DSISR] = 0x40000000;
+ }
+ }
+
+ return 1;
+ }
+ LOG_MMU("found PTE at offset %08" HWADDR_PRIx "\n", pte_offset);
+
+ /* 7. Check access permissions */
+
+ prot = ppc_hash32_pte_prot(env, sr, pte);
+
+ if (need_prot[rwx] & ~prot) {
+ /* Access right violation */
+ LOG_MMU("PTE access rejected\n");
+ if (rwx == 2) {
+ env->exception_index = POWERPC_EXCP_ISI;
+ env->error_code = 0x08000000;
+ } else {
+ env->exception_index = POWERPC_EXCP_DSI;
+ env->error_code = 0;
+ env->spr[SPR_DAR] = eaddr;
+ if (rwx == 1) {
+ env->spr[SPR_DSISR] = 0x0a000000;
+ } else {
+ env->spr[SPR_DSISR] = 0x08000000;
+ }
+ }
+ return 1;
+ }
+
+ LOG_MMU("PTE access granted !\n");
+
+ /* 8. Update PTE referenced and changed bits if necessary */
+
+ new_pte1 = pte.pte1 | HPTE32_R_R; /* set referenced bit */
+ if (rwx == 1) {
+ new_pte1 |= HPTE32_R_C; /* set changed (dirty) bit */
+ } else {
+ /* Treat the page as read-only for now, so that a later write
+ * will pass through this function again to set the C bit */
+ prot &= ~PAGE_WRITE;
+ }
+
+ if (new_pte1 != pte.pte1) {
+ ppc_hash32_store_hpte1(env, pte_offset, new_pte1);
+ }
+
+ /* 9. Determine the real address from the PTE */
+
+ raddr = ppc_hash32_pte_raddr(sr, pte, eaddr);
+
+ tlb_set_page(env, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
+ prot, mmu_idx, TARGET_PAGE_SIZE);
+
+ return 0;
+}
+
+hwaddr ppc_hash32_get_phys_page_debug(CPUPPCState *env, target_ulong eaddr)
+{
+ target_ulong sr;
+ hwaddr pte_offset;
+ ppc_hash_pte32_t pte;
+ int prot;
+
+ if (msr_dr == 0) {
+ /* Translation is off */
+ return eaddr;
+ }
+
+ if (env->nb_BATs != 0) {
+ hwaddr raddr = ppc_hash32_bat_lookup(env, eaddr, 0, &prot);
+ if (raddr != -1) {
+ return raddr;
+ }
+ }
+
+ sr = env->sr[eaddr >> 28];
+
+ if (sr & SR32_T) {
+ /* FIXME: Add suitable debug support for Direct Store segments */
+ return -1;
+ }
+
+ pte_offset = ppc_hash32_htab_lookup(env, sr, eaddr, &pte);
+ if (pte_offset == -1) {
+ return -1;
+ }
+
+ return ppc_hash32_pte_raddr(sr, pte, eaddr) & TARGET_PAGE_MASK;
+}
diff --git a/target-ppc/mmu-hash32.h b/target-ppc/mmu-hash32.h
new file mode 100644
index 000000000..884786b97
--- /dev/null
+++ b/target-ppc/mmu-hash32.h
@@ -0,0 +1,102 @@
+#if !defined (__MMU_HASH32_H__)
+#define __MMU_HASH32_H__
+
+#ifndef CONFIG_USER_ONLY
+
+hwaddr get_pteg_offset32(CPUPPCState *env, hwaddr hash);
+hwaddr ppc_hash32_get_phys_page_debug(CPUPPCState *env, target_ulong addr);
+int ppc_hash32_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
+ int mmu_idx);
+
+/*
+ * Segment register definitions
+ */
+
+#define SR32_T 0x80000000
+#define SR32_KS 0x40000000
+#define SR32_KP 0x20000000
+#define SR32_NX 0x10000000
+#define SR32_VSID 0x00ffffff
+
+/*
+ * Block Address Translation (BAT) definitions
+ */
+
+#define BATU32_BEPI 0xfffe0000
+#define BATU32_BL 0x00001ffc
+#define BATU32_VS 0x00000002
+#define BATU32_VP 0x00000001
+
+
+#define BATL32_BRPN 0xfffe0000
+#define BATL32_WIMG 0x00000078
+#define BATL32_PP 0x00000003
+
+/* PowerPC 601 has slightly different BAT registers */
+
+#define BATU32_601_KS 0x00000008
+#define BATU32_601_KP 0x00000004
+#define BATU32_601_PP 0x00000003
+
+#define BATL32_601_V 0x00000040
+#define BATL32_601_BL 0x0000003f
+
+/*
+ * Hash page table definitions
+ */
+
+#define HPTES_PER_GROUP 8
+#define HASH_PTE_SIZE_32 8
+#define HASH_PTEG_SIZE_32 (HASH_PTE_SIZE_32 * HPTES_PER_GROUP)
+
+#define HPTE32_V_VALID 0x80000000
+#define HPTE32_V_VSID 0x7fffff80
+#define HPTE32_V_SECONDARY 0x00000040
+#define HPTE32_V_API 0x0000003f
+#define HPTE32_V_COMPARE(x, y) (!(((x) ^ (y)) & 0x7fffffbf))
+
+#define HPTE32_R_RPN 0xfffff000
+#define HPTE32_R_R 0x00000100
+#define HPTE32_R_C 0x00000080
+#define HPTE32_R_W 0x00000040
+#define HPTE32_R_I 0x00000020
+#define HPTE32_R_M 0x00000010
+#define HPTE32_R_G 0x00000008
+#define HPTE32_R_WIMG 0x00000078
+#define HPTE32_R_PP 0x00000003
+
+static inline target_ulong ppc_hash32_load_hpte0(CPUPPCState *env,
+ hwaddr pte_offset)
+{
+ assert(!env->external_htab); /* Not supported on 32-bit for now */
+ return ldl_phys(env->htab_base + pte_offset);
+}
+
+static inline target_ulong ppc_hash32_load_hpte1(CPUPPCState *env,
+ hwaddr pte_offset)
+{
+ assert(!env->external_htab); /* Not supported on 32-bit for now */
+ return ldl_phys(env->htab_base + pte_offset + HASH_PTE_SIZE_32/2);
+}
+
+static inline void ppc_hash32_store_hpte0(CPUPPCState *env,
+ hwaddr pte_offset, target_ulong pte0)
+{
+ assert(!env->external_htab); /* Not supported on 32-bit for now */
+ stl_phys(env->htab_base + pte_offset, pte0);
+}
+
+static inline void ppc_hash32_store_hpte1(CPUPPCState *env,
+ hwaddr pte_offset, target_ulong pte1)
+{
+ assert(!env->external_htab); /* Not supported on 32-bit for now */
+ stl_phys(env->htab_base + pte_offset + HASH_PTE_SIZE_32/2, pte1);
+}
+
+typedef struct {
+ uint32_t pte0, pte1;
+} ppc_hash_pte32_t;
+
+#endif /* CONFIG_USER_ONLY */
+
+#endif /* __MMU_HASH32_H__ */
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
new file mode 100644
index 000000000..67fc1b5de
--- /dev/null
+++ b/target-ppc/mmu-hash64.c
@@ -0,0 +1,546 @@
+/*
+ * PowerPC MMU, TLB, SLB and BAT emulation helpers for QEMU.
+ *
+ * Copyright (c) 2003-2007 Jocelyn Mayer
+ * Copyright (c) 2013 David Gibson, IBM Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include "cpu.h"
+#include "helper.h"
+#include "sysemu/kvm.h"
+#include "kvm_ppc.h"
+#include "mmu-hash64.h"
+
+//#define DEBUG_MMU
+//#define DEBUG_SLB
+
+#ifdef DEBUG_MMU
+# define LOG_MMU(...) qemu_log(__VA_ARGS__)
+# define LOG_MMU_STATE(cpu) log_cpu_state((cpu), 0)
+#else
+# define LOG_MMU(...) do { } while (0)
+# define LOG_MMU_STATE(cpu) do { } while (0)
+#endif
+
+#ifdef DEBUG_SLB
+# define LOG_SLB(...) qemu_log(__VA_ARGS__)
+#else
+# define LOG_SLB(...) do { } while (0)
+#endif
+
+/*
+ * SLB handling
+ */
+
+static ppc_slb_t *slb_lookup(CPUPPCState *env, target_ulong eaddr)
+{
+ uint64_t esid_256M, esid_1T;
+ int n;
+
+ LOG_SLB("%s: eaddr " TARGET_FMT_lx "\n", __func__, eaddr);
+
+ esid_256M = (eaddr & SEGMENT_MASK_256M) | SLB_ESID_V;
+ esid_1T = (eaddr & SEGMENT_MASK_1T) | SLB_ESID_V;
+
+ for (n = 0; n < env->slb_nr; n++) {
+ ppc_slb_t *slb = &env->slb[n];
+
+ LOG_SLB("%s: slot %d %016" PRIx64 " %016"
+ PRIx64 "\n", __func__, n, slb->esid, slb->vsid);
+ /* We check for 1T matches on all MMUs here - if the MMU
+ * doesn't have 1T segment support, we will have prevented 1T
+ * entries from being inserted in the slbmte code. */
+ if (((slb->esid == esid_256M) &&
+ ((slb->vsid & SLB_VSID_B) == SLB_VSID_B_256M))
+ || ((slb->esid == esid_1T) &&
+ ((slb->vsid & SLB_VSID_B) == SLB_VSID_B_1T))) {
+ return slb;
+ }
+ }
+
+ return NULL;
+}
+
+void dump_slb(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env)
+{
+ int i;
+ uint64_t slbe, slbv;
+
+ cpu_synchronize_state(CPU(ppc_env_get_cpu(env)));
+
+ cpu_fprintf(f, "SLB\tESID\t\t\tVSID\n");
+ for (i = 0; i < env->slb_nr; i++) {
+ slbe = env->slb[i].esid;
+ slbv = env->slb[i].vsid;
+ if (slbe == 0 && slbv == 0) {
+ continue;
+ }
+ cpu_fprintf(f, "%d\t0x%016" PRIx64 "\t0x%016" PRIx64 "\n",
+ i, slbe, slbv);
+ }
+}
+
+void helper_slbia(CPUPPCState *env)
+{
+ int n, do_invalidate;
+
+ do_invalidate = 0;
+ /* XXX: Warning: slbia never invalidates the first segment */
+ for (n = 1; n < env->slb_nr; n++) {
+ ppc_slb_t *slb = &env->slb[n];
+
+ if (slb->esid & SLB_ESID_V) {
+ slb->esid &= ~SLB_ESID_V;
+ /* XXX: given the fact that segment size is 256 MB or 1TB,
+ * and we still don't have a tlb_flush_mask(env, n, mask)
+ * in QEMU, we just invalidate all TLBs
+ */
+ do_invalidate = 1;
+ }
+ }
+ if (do_invalidate) {
+ tlb_flush(env, 1);
+ }
+}
+
+void helper_slbie(CPUPPCState *env, target_ulong addr)
+{
+ ppc_slb_t *slb;
+
+ slb = slb_lookup(env, addr);
+ if (!slb) {
+ return;
+ }
+
+ if (slb->esid & SLB_ESID_V) {
+ slb->esid &= ~SLB_ESID_V;
+
+ /* XXX: given the fact that segment size is 256 MB or 1TB,
+ * and we still don't have a tlb_flush_mask(env, n, mask)
+ * in QEMU, we just invalidate all TLBs
+ */
+ tlb_flush(env, 1);
+ }
+}
+
+int ppc_store_slb(CPUPPCState *env, target_ulong rb, target_ulong rs)
+{
+ int slot = rb & 0xfff;
+ ppc_slb_t *slb = &env->slb[slot];
+
+ if (rb & (0x1000 - env->slb_nr)) {
+ return -1; /* Reserved bits set or slot too high */
+ }
+ if (rs & (SLB_VSID_B & ~SLB_VSID_B_1T)) {
+ return -1; /* Bad segment size */
+ }
+ if ((rs & SLB_VSID_B) && !(env->mmu_model & POWERPC_MMU_1TSEG)) {
+ return -1; /* 1T segment on MMU that doesn't support it */
+ }
+
+ /* Mask out the slot number as we store the entry */
+ slb->esid = rb & (SLB_ESID_ESID | SLB_ESID_V);
+ slb->vsid = rs;
+
+ LOG_SLB("%s: %d " TARGET_FMT_lx " - " TARGET_FMT_lx " => %016" PRIx64
+ " %016" PRIx64 "\n", __func__, slot, rb, rs,
+ slb->esid, slb->vsid);
+
+ return 0;
+}
+
+static int ppc_load_slb_esid(CPUPPCState *env, target_ulong rb,
+ target_ulong *rt)
+{
+ int slot = rb & 0xfff;
+ ppc_slb_t *slb = &env->slb[slot];
+
+ if (slot >= env->slb_nr) {
+ return -1;
+ }
+
+ *rt = slb->esid;
+ return 0;
+}
+
+static int ppc_load_slb_vsid(CPUPPCState *env, target_ulong rb,
+ target_ulong *rt)
+{
+ int slot = rb & 0xfff;
+ ppc_slb_t *slb = &env->slb[slot];
+
+ if (slot >= env->slb_nr) {
+ return -1;
+ }
+
+ *rt = slb->vsid;
+ return 0;
+}
+
+void helper_store_slb(CPUPPCState *env, target_ulong rb, target_ulong rs)
+{
+ if (ppc_store_slb(env, rb, rs) < 0) {
+ helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
+ POWERPC_EXCP_INVAL);
+ }
+}
+
+target_ulong helper_load_slb_esid(CPUPPCState *env, target_ulong rb)
+{
+ target_ulong rt = 0;
+
+ if (ppc_load_slb_esid(env, rb, &rt) < 0) {
+ helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
+ POWERPC_EXCP_INVAL);
+ }
+ return rt;
+}
+
+target_ulong helper_load_slb_vsid(CPUPPCState *env, target_ulong rb)
+{
+ target_ulong rt = 0;
+
+ if (ppc_load_slb_vsid(env, rb, &rt) < 0) {
+ helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
+ POWERPC_EXCP_INVAL);
+ }
+ return rt;
+}
+
+/*
+ * 64-bit hash table MMU handling
+ */
+
+static int ppc_hash64_pte_prot(CPUPPCState *env,
+ ppc_slb_t *slb, ppc_hash_pte64_t pte)
+{
+ unsigned pp, key;
+ /* Some pp bit combinations have undefined behaviour, so default
+ * to no access in those cases */
+ int prot = 0;
+
+ key = !!(msr_pr ? (slb->vsid & SLB_VSID_KP)
+ : (slb->vsid & SLB_VSID_KS));
+ pp = (pte.pte1 & HPTE64_R_PP) | ((pte.pte1 & HPTE64_R_PP0) >> 61);
+
+ if (key == 0) {
+ switch (pp) {
+ case 0x0:
+ case 0x1:
+ case 0x2:
+ prot = PAGE_READ | PAGE_WRITE;
+ break;
+
+ case 0x3:
+ case 0x6:
+ prot = PAGE_READ;
+ break;
+ }
+ } else {
+ switch (pp) {
+ case 0x0:
+ case 0x6:
+ prot = 0;
+ break;
+
+ case 0x1:
+ case 0x3:
+ prot = PAGE_READ;
+ break;
+
+ case 0x2:
+ prot = PAGE_READ | PAGE_WRITE;
+ break;
+ }
+ }
+
+ /* No execute if either noexec or guarded bits set */
+ if (!(pte.pte1 & HPTE64_R_N) || (pte.pte1 & HPTE64_R_G)
+ || (slb->vsid & SLB_VSID_N)) {
+ prot |= PAGE_EXEC;
+ }
+
+ return prot;
+}
+
+static int ppc_hash64_amr_prot(CPUPPCState *env, ppc_hash_pte64_t pte)
+{
+ int key, amrbits;
+ int prot = PAGE_EXEC;
+
+
+ /* Only recent MMUs implement Virtual Page Class Key Protection */
+ if (!(env->mmu_model & POWERPC_MMU_AMR)) {
+ return PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ }
+
+ key = HPTE64_R_KEY(pte.pte1);
+ amrbits = (env->spr[SPR_AMR] >> 2*(31 - key)) & 0x3;
+
+ /* fprintf(stderr, "AMR protection: key=%d AMR=0x%" PRIx64 "\n", key, */
+ /* env->spr[SPR_AMR]); */
+
+ if (amrbits & 0x2) {
+ prot |= PAGE_WRITE;
+ }
+ if (amrbits & 0x1) {
+ prot |= PAGE_READ;
+ }
+
+ return prot;
+}
+
+static hwaddr ppc_hash64_pteg_search(CPUPPCState *env, hwaddr pteg_off,
+ bool secondary, target_ulong ptem,
+ ppc_hash_pte64_t *pte)
+{
+ hwaddr pte_offset = pteg_off;
+ target_ulong pte0, pte1;
+ int i;
+
+ for (i = 0; i < HPTES_PER_GROUP; i++) {
+ pte0 = ppc_hash64_load_hpte0(env, pte_offset);
+ pte1 = ppc_hash64_load_hpte1(env, pte_offset);
+
+ if ((pte0 & HPTE64_V_VALID)
+ && (secondary == !!(pte0 & HPTE64_V_SECONDARY))
+ && HPTE64_V_COMPARE(pte0, ptem)) {
+ pte->pte0 = pte0;
+ pte->pte1 = pte1;
+ return pte_offset;
+ }
+
+ pte_offset += HASH_PTE_SIZE_64;
+ }
+
+ return -1;
+}
+
+static hwaddr ppc_hash64_htab_lookup(CPUPPCState *env,
+ ppc_slb_t *slb, target_ulong eaddr,
+ ppc_hash_pte64_t *pte)
+{
+ hwaddr pteg_off, pte_offset;
+ hwaddr hash;
+ uint64_t vsid, epnshift, epnmask, epn, ptem;
+
+ /* Page size according to the SLB, which we use to generate the
+ * EPN for hash table lookup.. When we implement more recent MMU
+ * extensions this might be different from the actual page size
+ * encoded in the PTE */
+ epnshift = (slb->vsid & SLB_VSID_L)
+ ? TARGET_PAGE_BITS_16M : TARGET_PAGE_BITS;
+ epnmask = ~((1ULL << epnshift) - 1);
+
+ if (slb->vsid & SLB_VSID_B) {
+ /* 1TB segment */
+ vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT_1T;
+ epn = (eaddr & ~SEGMENT_MASK_1T) & epnmask;
+ hash = vsid ^ (vsid << 25) ^ (epn >> epnshift);
+ } else {
+ /* 256M segment */
+ vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT;
+ epn = (eaddr & ~SEGMENT_MASK_256M) & epnmask;
+ hash = vsid ^ (epn >> epnshift);
+ }
+ ptem = (slb->vsid & SLB_VSID_PTEM) | ((epn >> 16) & HPTE64_V_AVPN);
+
+ /* Page address translation */
+ LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx
+ " hash " TARGET_FMT_plx "\n",
+ env->htab_base, env->htab_mask, hash);
+
+ /* Primary PTEG lookup */
+ LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
+ " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx
+ " hash=" TARGET_FMT_plx "\n",
+ env->htab_base, env->htab_mask, vsid, ptem, hash);
+ pteg_off = (hash * HASH_PTEG_SIZE_64) & env->htab_mask;
+ pte_offset = ppc_hash64_pteg_search(env, pteg_off, 0, ptem, pte);
+
+ if (pte_offset == -1) {
+ /* Secondary PTEG lookup */
+ LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
+ " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx
+ " hash=" TARGET_FMT_plx "\n", env->htab_base,
+ env->htab_mask, vsid, ptem, ~hash);
+
+ pteg_off = (~hash * HASH_PTEG_SIZE_64) & env->htab_mask;
+ pte_offset = ppc_hash64_pteg_search(env, pteg_off, 1, ptem, pte);
+ }
+
+ return pte_offset;
+}
+
+static hwaddr ppc_hash64_pte_raddr(ppc_slb_t *slb, ppc_hash_pte64_t pte,
+ target_ulong eaddr)
+{
+ hwaddr rpn = pte.pte1 & HPTE64_R_RPN;
+ /* FIXME: Add support for SLLP extended page sizes */
+ int target_page_bits = (slb->vsid & SLB_VSID_L)
+ ? TARGET_PAGE_BITS_16M : TARGET_PAGE_BITS;
+ hwaddr mask = (1ULL << target_page_bits) - 1;
+
+ return (rpn & ~mask) | (eaddr & mask);
+}
+
+int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr,
+ int rwx, int mmu_idx)
+{
+ ppc_slb_t *slb;
+ hwaddr pte_offset;
+ ppc_hash_pte64_t pte;
+ int pp_prot, amr_prot, prot;
+ uint64_t new_pte1;
+ const int need_prot[] = {PAGE_READ, PAGE_WRITE, PAGE_EXEC};
+ hwaddr raddr;
+
+ assert((rwx == 0) || (rwx == 1) || (rwx == 2));
+
+ /* 1. Handle real mode accesses */
+ if (((rwx == 2) && (msr_ir == 0)) || ((rwx != 2) && (msr_dr == 0))) {
+ /* Translation is off */
+ /* In real mode the top 4 effective address bits are ignored */
+ raddr = eaddr & 0x0FFFFFFFFFFFFFFFULL;
+ tlb_set_page(env, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
+ PAGE_READ | PAGE_WRITE | PAGE_EXEC, mmu_idx,
+ TARGET_PAGE_SIZE);
+ return 0;
+ }
+
+ /* 2. Translation is on, so look up the SLB */
+ slb = slb_lookup(env, eaddr);
+
+ if (!slb) {
+ if (rwx == 2) {
+ env->exception_index = POWERPC_EXCP_ISEG;
+ env->error_code = 0;
+ } else {
+ env->exception_index = POWERPC_EXCP_DSEG;
+ env->error_code = 0;
+ env->spr[SPR_DAR] = eaddr;
+ }
+ return 1;
+ }
+
+ /* 3. Check for segment level no-execute violation */
+ if ((rwx == 2) && (slb->vsid & SLB_VSID_N)) {
+ env->exception_index = POWERPC_EXCP_ISI;
+ env->error_code = 0x10000000;
+ return 1;
+ }
+
+ /* 4. Locate the PTE in the hash table */
+ pte_offset = ppc_hash64_htab_lookup(env, slb, eaddr, &pte);
+ if (pte_offset == -1) {
+ if (rwx == 2) {
+ env->exception_index = POWERPC_EXCP_ISI;
+ env->error_code = 0x40000000;
+ } else {
+ env->exception_index = POWERPC_EXCP_DSI;
+ env->error_code = 0;
+ env->spr[SPR_DAR] = eaddr;
+ if (rwx == 1) {
+ env->spr[SPR_DSISR] = 0x42000000;
+ } else {
+ env->spr[SPR_DSISR] = 0x40000000;
+ }
+ }
+ return 1;
+ }
+ LOG_MMU("found PTE at offset %08" HWADDR_PRIx "\n", pte_offset);
+
+ /* 5. Check access permissions */
+
+ pp_prot = ppc_hash64_pte_prot(env, slb, pte);
+ amr_prot = ppc_hash64_amr_prot(env, pte);
+ prot = pp_prot & amr_prot;
+
+ if ((need_prot[rwx] & ~prot) != 0) {
+ /* Access right violation */
+ LOG_MMU("PTE access rejected\n");
+ if (rwx == 2) {
+ env->exception_index = POWERPC_EXCP_ISI;
+ env->error_code = 0x08000000;
+ } else {
+ target_ulong dsisr = 0;
+
+ env->exception_index = POWERPC_EXCP_DSI;
+ env->error_code = 0;
+ env->spr[SPR_DAR] = eaddr;
+ if (need_prot[rwx] & ~pp_prot) {
+ dsisr |= 0x08000000;
+ }
+ if (rwx == 1) {
+ dsisr |= 0x02000000;
+ }
+ if (need_prot[rwx] & ~amr_prot) {
+ dsisr |= 0x00200000;
+ }
+ env->spr[SPR_DSISR] = dsisr;
+ }
+ return 1;
+ }
+
+ LOG_MMU("PTE access granted !\n");
+
+ /* 6. Update PTE referenced and changed bits if necessary */
+
+ new_pte1 = pte.pte1 | HPTE64_R_R; /* set referenced bit */
+ if (rwx == 1) {
+ new_pte1 |= HPTE64_R_C; /* set changed (dirty) bit */
+ } else {
+ /* Treat the page as read-only for now, so that a later write
+ * will pass through this function again to set the C bit */
+ prot &= ~PAGE_WRITE;
+ }
+
+ if (new_pte1 != pte.pte1) {
+ ppc_hash64_store_hpte1(env, pte_offset, new_pte1);
+ }
+
+ /* 7. Determine the real address from the PTE */
+
+ raddr = ppc_hash64_pte_raddr(slb, pte, eaddr);
+
+ tlb_set_page(env, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
+ prot, mmu_idx, TARGET_PAGE_SIZE);
+
+ return 0;
+}
+
+hwaddr ppc_hash64_get_phys_page_debug(CPUPPCState *env, target_ulong addr)
+{
+ ppc_slb_t *slb;
+ hwaddr pte_offset;
+ ppc_hash_pte64_t pte;
+
+ if (msr_dr == 0) {
+ /* In real mode the top 4 effective address bits are ignored */
+ return addr & 0x0FFFFFFFFFFFFFFFULL;
+ }
+
+ slb = slb_lookup(env, addr);
+ if (!slb) {
+ return -1;
+ }
+
+ pte_offset = ppc_hash64_htab_lookup(env, slb, addr, &pte);
+ if (pte_offset == -1) {
+ return -1;
+ }
+
+ return ppc_hash64_pte_raddr(slb, pte, addr) & TARGET_PAGE_MASK;
+}
diff --git a/target-ppc/mmu-hash64.h b/target-ppc/mmu-hash64.h
new file mode 100644
index 000000000..55f5a230f
--- /dev/null
+++ b/target-ppc/mmu-hash64.h
@@ -0,0 +1,124 @@
+#if !defined (__MMU_HASH64_H__)
+#define __MMU_HASH64_H__
+
+#ifndef CONFIG_USER_ONLY
+
+#ifdef TARGET_PPC64
+void dump_slb(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env);
+int ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs);
+hwaddr ppc_hash64_get_phys_page_debug(CPUPPCState *env, target_ulong addr);
+int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
+ int mmu_idx);
+#endif
+
+/*
+ * SLB definitions
+ */
+
+/* Bits in the SLB ESID word */
+#define SLB_ESID_ESID 0xFFFFFFFFF0000000ULL
+#define SLB_ESID_V 0x0000000008000000ULL /* valid */
+
+/* Bits in the SLB VSID word */
+#define SLB_VSID_SHIFT 12
+#define SLB_VSID_SHIFT_1T 24
+#define SLB_VSID_SSIZE_SHIFT 62
+#define SLB_VSID_B 0xc000000000000000ULL
+#define SLB_VSID_B_256M 0x0000000000000000ULL
+#define SLB_VSID_B_1T 0x4000000000000000ULL
+#define SLB_VSID_VSID 0x3FFFFFFFFFFFF000ULL
+#define SLB_VSID_PTEM (SLB_VSID_B | SLB_VSID_VSID)
+#define SLB_VSID_KS 0x0000000000000800ULL
+#define SLB_VSID_KP 0x0000000000000400ULL
+#define SLB_VSID_N 0x0000000000000200ULL /* no-execute */
+#define SLB_VSID_L 0x0000000000000100ULL
+#define SLB_VSID_C 0x0000000000000080ULL /* class */
+#define SLB_VSID_LP 0x0000000000000030ULL
+#define SLB_VSID_ATTR 0x0000000000000FFFULL
+
+/*
+ * Hash page table definitions
+ */
+
+#define HPTES_PER_GROUP 8
+#define HASH_PTE_SIZE_64 16
+#define HASH_PTEG_SIZE_64 (HASH_PTE_SIZE_64 * HPTES_PER_GROUP)
+
+#define HPTE64_V_SSIZE_SHIFT 62
+#define HPTE64_V_AVPN_SHIFT 7
+#define HPTE64_V_AVPN 0x3fffffffffffff80ULL
+#define HPTE64_V_AVPN_VAL(x) (((x) & HPTE64_V_AVPN) >> HPTE64_V_AVPN_SHIFT)
+#define HPTE64_V_COMPARE(x, y) (!(((x) ^ (y)) & 0xffffffffffffff80ULL))
+#define HPTE64_V_LARGE 0x0000000000000004ULL
+#define HPTE64_V_SECONDARY 0x0000000000000002ULL
+#define HPTE64_V_VALID 0x0000000000000001ULL
+
+#define HPTE64_R_PP0 0x8000000000000000ULL
+#define HPTE64_R_TS 0x4000000000000000ULL
+#define HPTE64_R_KEY_HI 0x3000000000000000ULL
+#define HPTE64_R_RPN_SHIFT 12
+#define HPTE64_R_RPN 0x0ffffffffffff000ULL
+#define HPTE64_R_FLAGS 0x00000000000003ffULL
+#define HPTE64_R_PP 0x0000000000000003ULL
+#define HPTE64_R_N 0x0000000000000004ULL
+#define HPTE64_R_G 0x0000000000000008ULL
+#define HPTE64_R_M 0x0000000000000010ULL
+#define HPTE64_R_I 0x0000000000000020ULL
+#define HPTE64_R_W 0x0000000000000040ULL
+#define HPTE64_R_WIMG 0x0000000000000078ULL
+#define HPTE64_R_C 0x0000000000000080ULL
+#define HPTE64_R_R 0x0000000000000100ULL
+#define HPTE64_R_KEY_LO 0x0000000000000e00ULL
+#define HPTE64_R_KEY(x) ((((x) & HPTE64_R_KEY_HI) >> 60) | \
+ (((x) & HPTE64_R_KEY_LO) >> 9))
+
+#define HPTE64_V_1TB_SEG 0x4000000000000000ULL
+#define HPTE64_V_VRMA_MASK 0x4001ffffff000000ULL
+
+static inline target_ulong ppc_hash64_load_hpte0(CPUPPCState *env,
+ hwaddr pte_offset)
+{
+ if (env->external_htab) {
+ return ldq_p(env->external_htab + pte_offset);
+ } else {
+ return ldq_phys(env->htab_base + pte_offset);
+ }
+}
+
+static inline target_ulong ppc_hash64_load_hpte1(CPUPPCState *env,
+ hwaddr pte_offset)
+{
+ if (env->external_htab) {
+ return ldq_p(env->external_htab + pte_offset + HASH_PTE_SIZE_64/2);
+ } else {
+ return ldq_phys(env->htab_base + pte_offset + HASH_PTE_SIZE_64/2);
+ }
+}
+
+static inline void ppc_hash64_store_hpte0(CPUPPCState *env,
+ hwaddr pte_offset, target_ulong pte0)
+{
+ if (env->external_htab) {
+ stq_p(env->external_htab + pte_offset, pte0);
+ } else {
+ stq_phys(env->htab_base + pte_offset, pte0);
+ }
+}
+
+static inline void ppc_hash64_store_hpte1(CPUPPCState *env,
+ hwaddr pte_offset, target_ulong pte1)
+{
+ if (env->external_htab) {
+ stq_p(env->external_htab + pte_offset + HASH_PTE_SIZE_64/2, pte1);
+ } else {
+ stq_phys(env->htab_base + pte_offset + HASH_PTE_SIZE_64/2, pte1);
+ }
+}
+
+typedef struct {
+ uint64_t pte0, pte1;
+} ppc_hash_pte64_t;
+
+#endif /* CONFIG_USER_ONLY */
+
+#endif /* !defined (__MMU_HASH64_H__) */
diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
index 318ce92ad..5dd4e05f7 100644
--- a/target-ppc/mmu_helper.c
+++ b/target-ppc/mmu_helper.c
@@ -18,12 +18,13 @@
*/
#include "cpu.h"
#include "helper.h"
-#include "kvm.h"
+#include "sysemu/kvm.h"
#include "kvm_ppc.h"
+#include "mmu-hash64.h"
+#include "mmu-hash32.h"
//#define DEBUG_MMU
//#define DEBUG_BATS
-//#define DEBUG_SLB
//#define DEBUG_SOFTWARE_TLB
//#define DUMP_PAGE_TABLES
//#define DEBUG_SOFTWARE_TLB
@@ -31,10 +32,10 @@
#ifdef DEBUG_MMU
# define LOG_MMU(...) qemu_log(__VA_ARGS__)
-# define LOG_MMU_STATE(env) log_cpu_state((env), 0)
+# define LOG_MMU_STATE(cpu) log_cpu_state((cpu), 0)
#else
# define LOG_MMU(...) do { } while (0)
-# define LOG_MMU_STATE(...) do { } while (0)
+# define LOG_MMU_STATE(cpu) do { } while (0)
#endif
#ifdef DEBUG_SOFTWARE_TLB
@@ -49,39 +50,21 @@
# define LOG_BATS(...) do { } while (0)
#endif
-#ifdef DEBUG_SLB
-# define LOG_SLB(...) qemu_log(__VA_ARGS__)
-#else
-# define LOG_SLB(...) do { } while (0)
-#endif
-
/*****************************************************************************/
/* PowerPC MMU emulation */
-#if defined(CONFIG_USER_ONLY)
-int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
- int mmu_idx)
-{
- int exception, error_code;
- if (rw == 2) {
- exception = POWERPC_EXCP_ISI;
- error_code = 0x40000000;
- } else {
- exception = POWERPC_EXCP_DSI;
- error_code = 0x40000000;
- if (rw) {
- error_code |= 0x02000000;
- }
- env->spr[SPR_DAR] = address;
- env->spr[SPR_DSISR] = error_code;
- }
- env->exception_index = exception;
- env->error_code = error_code;
-
- return 1;
-}
+/* Context used internally during MMU translations */
+typedef struct mmu_ctx_t mmu_ctx_t;
+struct mmu_ctx_t {
+ hwaddr raddr; /* Real address */
+ hwaddr eaddr; /* Effective address */
+ int prot; /* Protection bits */
+ hwaddr hash[2]; /* Pagetable hash values */
+ target_ulong ptem; /* Virtual segment ID | API */
+ int key; /* Access key */
+ int nx; /* Non-execute area */
+};
-#else
/* Common routines used by software and hardware TLBs emulation */
static inline int pte_is_valid(target_ulong pte0)
{
@@ -93,31 +76,14 @@ static inline void pte_invalidate(target_ulong *pte0)
*pte0 &= ~0x80000000;
}
-#if defined(TARGET_PPC64)
-static inline int pte64_is_valid(target_ulong pte0)
-{
- return pte0 & 0x0000000000000001ULL ? 1 : 0;
-}
-
-static inline void pte64_invalidate(target_ulong *pte0)
-{
- *pte0 &= ~0x0000000000000001ULL;
-}
-#endif
-
#define PTE_PTEM_MASK 0x7FFFFFBF
#define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
-#if defined(TARGET_PPC64)
-#define PTE64_PTEM_MASK 0xFFFFFFFFFFFFFF80ULL
-#define PTE64_CHECK_MASK (TARGET_PAGE_MASK | 0x7F)
-#endif
-static inline int pp_check(int key, int pp, int nx)
+static int pp_check(int key, int pp, int nx)
{
int access;
/* Compute access rights */
- /* When pp is 3/7, the result is undefined. Set it to noaccess */
access = 0;
if (key == 0) {
switch (pp) {
@@ -127,14 +93,12 @@ static inline int pp_check(int key, int pp, int nx)
access |= PAGE_WRITE;
/* No break here */
case 0x3:
- case 0x6:
access |= PAGE_READ;
break;
}
} else {
switch (pp) {
case 0x0:
- case 0x6:
access = 0;
break;
case 0x1:
@@ -153,7 +117,7 @@ static inline int pp_check(int key, int pp, int nx)
return access;
}
-static inline int check_prot(int prot, int rw, int access_type)
+static int check_prot(int prot, int rw, int access_type)
{
int ret;
@@ -180,40 +144,21 @@ static inline int check_prot(int prot, int rw, int access_type)
return ret;
}
-static inline int pte_check(mmu_ctx_t *ctx, int is_64b, target_ulong pte0,
- target_ulong pte1, int h, int rw, int type)
+static inline int ppc6xx_tlb_pte_check(mmu_ctx_t *ctx, target_ulong pte0,
+ target_ulong pte1, int h, int rw, int type)
{
target_ulong ptem, mmask;
int access, ret, pteh, ptev, pp;
ret = -1;
/* Check validity and table match */
-#if defined(TARGET_PPC64)
- if (is_64b) {
- ptev = pte64_is_valid(pte0);
- pteh = (pte0 >> 1) & 1;
- } else
-#endif
- {
- ptev = pte_is_valid(pte0);
- pteh = (pte0 >> 6) & 1;
- }
+ ptev = pte_is_valid(pte0);
+ pteh = (pte0 >> 6) & 1;
if (ptev && h == pteh) {
/* Check vsid & api */
-#if defined(TARGET_PPC64)
- if (is_64b) {
- ptem = pte0 & PTE64_PTEM_MASK;
- mmask = PTE64_CHECK_MASK;
- pp = (pte1 & 0x00000003) | ((pte1 >> 61) & 0x00000004);
- ctx->nx = (pte1 >> 2) & 1; /* No execute bit */
- ctx->nx |= (pte1 >> 3) & 1; /* Guarded bit */
- } else
-#endif
- {
- ptem = pte0 & PTE_PTEM_MASK;
- mmask = PTE_CHECK_MASK;
- pp = pte1 & 0x00000003;
- }
+ ptem = pte0 & PTE_PTEM_MASK;
+ mmask = PTE_CHECK_MASK;
+ pp = pte1 & 0x00000003;
if (ptem == ctx->ptem) {
if (ctx->raddr != (hwaddr)-1ULL) {
/* all matches should have equal RPN, WIMG & PP */
@@ -241,22 +186,8 @@ static inline int pte_check(mmu_ctx_t *ctx, int is_64b, target_ulong pte0,
return ret;
}
-static inline int pte32_check(mmu_ctx_t *ctx, target_ulong pte0,
- target_ulong pte1, int h, int rw, int type)
-{
- return pte_check(ctx, 0, pte0, pte1, h, rw, type);
-}
-
-#if defined(TARGET_PPC64)
-static inline int pte64_check(mmu_ctx_t *ctx, target_ulong pte0,
- target_ulong pte1, int h, int rw, int type)
-{
- return pte_check(ctx, 1, pte0, pte1, h, rw, type);
-}
-#endif
-
-static inline int pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p,
- int ret, int rw)
+static int pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p,
+ int ret, int rw)
{
int store = 0;
@@ -392,7 +323,7 @@ static inline int ppc6xx_tlb_check(CPUPPCState *env, mmu_ctx_t *ctx,
pte_is_valid(tlb->pte0) ? "valid" : "inval",
tlb->EPN, eaddr, tlb->pte1,
rw ? 'S' : 'L', access_type == ACCESS_CODE ? 'I' : 'D');
- switch (pte32_check(ctx, tlb->pte0, tlb->pte1, 0, rw, access_type)) {
+ switch (ppc6xx_tlb_pte_check(ctx, tlb->pte0, tlb->pte1, 0, rw, access_type)) {
case -3:
/* TLB inconsistency */
return -1;
@@ -454,34 +385,8 @@ static inline void bat_size_prot(CPUPPCState *env, target_ulong *blp,
*protp = prot;
}
-static inline void bat_601_size_prot(CPUPPCState *env, target_ulong *blp,
- int *validp, int *protp,
- target_ulong *BATu, target_ulong *BATl)
-{
- target_ulong bl;
- int key, pp, valid, prot;
-
- bl = (*BATl & 0x0000003F) << 17;
- LOG_BATS("b %02x ==> bl " TARGET_FMT_lx " msk " TARGET_FMT_lx "\n",
- (uint8_t)(*BATl & 0x0000003F), bl, ~bl);
- prot = 0;
- valid = (*BATl >> 6) & 1;
- if (valid) {
- pp = *BATu & 0x00000003;
- if (msr_pr == 0) {
- key = (*BATu >> 3) & 1;
- } else {
- key = (*BATu >> 2) & 1;
- }
- prot = pp_check(key, pp, 0);
- }
- *blp = bl;
- *validp = valid;
- *protp = prot;
-}
-
-static inline int get_bat(CPUPPCState *env, mmu_ctx_t *ctx,
- target_ulong virtual, int rw, int type)
+static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
+ target_ulong virtual, int rw, int type)
{
target_ulong *BATlt, *BATut, *BATu, *BATl;
target_ulong BEPIl, BEPIu, bl;
@@ -505,11 +410,7 @@ static inline int get_bat(CPUPPCState *env, mmu_ctx_t *ctx,
BATl = &BATlt[i];
BEPIu = *BATu & 0xF0000000;
BEPIl = *BATu & 0x0FFE0000;
- if (unlikely(env->mmu_model == POWERPC_MMU_601)) {
- bat_601_size_prot(env, &bl, &valid, &prot, BATu, BATl);
- } else {
- bat_size_prot(env, &bl, &valid, &prot, BATu, BATl);
- }
+ bat_size_prot(env, &bl, &valid, &prot, BATu, BATl);
LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
" BATl " TARGET_FMT_lx "\n", __func__,
type == ACCESS_CODE ? 'I' : 'D', i, virtual, *BATu, *BATl);
@@ -556,332 +457,35 @@ static inline int get_bat(CPUPPCState *env, mmu_ctx_t *ctx,
return ret;
}
-static inline hwaddr get_pteg_offset(CPUPPCState *env,
- hwaddr hash,
- int pte_size)
-{
- return (hash * pte_size * 8) & env->htab_mask;
-}
-
-/* PTE table lookup */
-static inline int find_pte2(CPUPPCState *env, mmu_ctx_t *ctx, int is_64b, int h,
- int rw, int type, int target_page_bits)
-{
- hwaddr pteg_off;
- target_ulong pte0, pte1;
- int i, good = -1;
- int ret, r;
-
- ret = -1; /* No entry found */
- pteg_off = get_pteg_offset(env, ctx->hash[h],
- is_64b ? HASH_PTE_SIZE_64 : HASH_PTE_SIZE_32);
- for (i = 0; i < 8; i++) {
-#if defined(TARGET_PPC64)
- if (is_64b) {
- if (env->external_htab) {
- pte0 = ldq_p(env->external_htab + pteg_off + (i * 16));
- pte1 = ldq_p(env->external_htab + pteg_off + (i * 16) + 8);
- } else {
- pte0 = ldq_phys(env->htab_base + pteg_off + (i * 16));
- pte1 = ldq_phys(env->htab_base + pteg_off + (i * 16) + 8);
- }
-
- r = pte64_check(ctx, pte0, pte1, h, rw, type);
- LOG_MMU("Load pte from " TARGET_FMT_lx " => " TARGET_FMT_lx " "
- TARGET_FMT_lx " %d %d %d " TARGET_FMT_lx "\n",
- pteg_off + (i * 16), pte0, pte1, (int)(pte0 & 1), h,
- (int)((pte0 >> 1) & 1), ctx->ptem);
- } else
-#endif
- {
- if (env->external_htab) {
- pte0 = ldl_p(env->external_htab + pteg_off + (i * 8));
- pte1 = ldl_p(env->external_htab + pteg_off + (i * 8) + 4);
- } else {
- pte0 = ldl_phys(env->htab_base + pteg_off + (i * 8));
- pte1 = ldl_phys(env->htab_base + pteg_off + (i * 8) + 4);
- }
- r = pte32_check(ctx, pte0, pte1, h, rw, type);
- LOG_MMU("Load pte from " TARGET_FMT_lx " => " TARGET_FMT_lx " "
- TARGET_FMT_lx " %d %d %d " TARGET_FMT_lx "\n",
- pteg_off + (i * 8), pte0, pte1, (int)(pte0 >> 31), h,
- (int)((pte0 >> 6) & 1), ctx->ptem);
- }
- switch (r) {
- case -3:
- /* PTE inconsistency */
- return -1;
- case -2:
- /* Access violation */
- ret = -2;
- good = i;
- break;
- case -1:
- default:
- /* No PTE match */
- break;
- case 0:
- /* access granted */
- /* XXX: we should go on looping to check all PTEs consistency
- * but if we can speed-up the whole thing as the
- * result would be undefined if PTEs are not consistent.
- */
- ret = 0;
- good = i;
- goto done;
- }
- }
- if (good != -1) {
- done:
- LOG_MMU("found PTE at addr " TARGET_FMT_lx " prot=%01x ret=%d\n",
- ctx->raddr, ctx->prot, ret);
- /* Update page flags */
- pte1 = ctx->raddr;
- if (pte_update_flags(ctx, &pte1, ret, rw) == 1) {
-#if defined(TARGET_PPC64)
- if (is_64b) {
- if (env->external_htab) {
- stq_p(env->external_htab + pteg_off + (good * 16) + 8,
- pte1);
- } else {
- stq_phys_notdirty(env->htab_base + pteg_off +
- (good * 16) + 8, pte1);
- }
- } else
-#endif
- {
- if (env->external_htab) {
- stl_p(env->external_htab + pteg_off + (good * 8) + 4,
- pte1);
- } else {
- stl_phys_notdirty(env->htab_base + pteg_off +
- (good * 8) + 4, pte1);
- }
- }
- }
- }
-
- /* We have a TLB that saves 4K pages, so let's
- * split a huge page to 4k chunks */
- if (target_page_bits != TARGET_PAGE_BITS) {
- ctx->raddr |= (ctx->eaddr & ((1 << target_page_bits) - 1))
- & TARGET_PAGE_MASK;
- }
- return ret;
-}
-
-static inline int find_pte(CPUPPCState *env, mmu_ctx_t *ctx, int h, int rw,
- int type, int target_page_bits)
-{
-#if defined(TARGET_PPC64)
- if (env->mmu_model & POWERPC_MMU_64) {
- return find_pte2(env, ctx, 1, h, rw, type, target_page_bits);
- }
-#endif
-
- return find_pte2(env, ctx, 0, h, rw, type, target_page_bits);
-}
-
-#if defined(TARGET_PPC64)
-static inline ppc_slb_t *slb_lookup(CPUPPCState *env, target_ulong eaddr)
-{
- uint64_t esid_256M, esid_1T;
- int n;
-
- LOG_SLB("%s: eaddr " TARGET_FMT_lx "\n", __func__, eaddr);
-
- esid_256M = (eaddr & SEGMENT_MASK_256M) | SLB_ESID_V;
- esid_1T = (eaddr & SEGMENT_MASK_1T) | SLB_ESID_V;
-
- for (n = 0; n < env->slb_nr; n++) {
- ppc_slb_t *slb = &env->slb[n];
-
- LOG_SLB("%s: slot %d %016" PRIx64 " %016"
- PRIx64 "\n", __func__, n, slb->esid, slb->vsid);
- /* We check for 1T matches on all MMUs here - if the MMU
- * doesn't have 1T segment support, we will have prevented 1T
- * entries from being inserted in the slbmte code. */
- if (((slb->esid == esid_256M) &&
- ((slb->vsid & SLB_VSID_B) == SLB_VSID_B_256M))
- || ((slb->esid == esid_1T) &&
- ((slb->vsid & SLB_VSID_B) == SLB_VSID_B_1T))) {
- return slb;
- }
- }
-
- return NULL;
-}
-
-/*****************************************************************************/
-/* SPR accesses */
-
-void helper_slbia(CPUPPCState *env)
-{
- int n, do_invalidate;
-
- do_invalidate = 0;
- /* XXX: Warning: slbia never invalidates the first segment */
- for (n = 1; n < env->slb_nr; n++) {
- ppc_slb_t *slb = &env->slb[n];
-
- if (slb->esid & SLB_ESID_V) {
- slb->esid &= ~SLB_ESID_V;
- /* XXX: given the fact that segment size is 256 MB or 1TB,
- * and we still don't have a tlb_flush_mask(env, n, mask)
- * in QEMU, we just invalidate all TLBs
- */
- do_invalidate = 1;
- }
- }
- if (do_invalidate) {
- tlb_flush(env, 1);
- }
-}
-
-void helper_slbie(CPUPPCState *env, target_ulong addr)
-{
- ppc_slb_t *slb;
-
- slb = slb_lookup(env, addr);
- if (!slb) {
- return;
- }
-
- if (slb->esid & SLB_ESID_V) {
- slb->esid &= ~SLB_ESID_V;
-
- /* XXX: given the fact that segment size is 256 MB or 1TB,
- * and we still don't have a tlb_flush_mask(env, n, mask)
- * in QEMU, we just invalidate all TLBs
- */
- tlb_flush(env, 1);
- }
-}
-
-int ppc_store_slb(CPUPPCState *env, target_ulong rb, target_ulong rs)
-{
- int slot = rb & 0xfff;
- ppc_slb_t *slb = &env->slb[slot];
-
- if (rb & (0x1000 - env->slb_nr)) {
- return -1; /* Reserved bits set or slot too high */
- }
- if (rs & (SLB_VSID_B & ~SLB_VSID_B_1T)) {
- return -1; /* Bad segment size */
- }
- if ((rs & SLB_VSID_B) && !(env->mmu_model & POWERPC_MMU_1TSEG)) {
- return -1; /* 1T segment on MMU that doesn't support it */
- }
-
- /* Mask out the slot number as we store the entry */
- slb->esid = rb & (SLB_ESID_ESID | SLB_ESID_V);
- slb->vsid = rs;
-
- LOG_SLB("%s: %d " TARGET_FMT_lx " - " TARGET_FMT_lx " => %016" PRIx64
- " %016" PRIx64 "\n", __func__, slot, rb, rs,
- slb->esid, slb->vsid);
-
- return 0;
-}
-
-static int ppc_load_slb_esid(CPUPPCState *env, target_ulong rb,
- target_ulong *rt)
-{
- int slot = rb & 0xfff;
- ppc_slb_t *slb = &env->slb[slot];
-
- if (slot >= env->slb_nr) {
- return -1;
- }
-
- *rt = slb->esid;
- return 0;
-}
-
-static int ppc_load_slb_vsid(CPUPPCState *env, target_ulong rb,
- target_ulong *rt)
-{
- int slot = rb & 0xfff;
- ppc_slb_t *slb = &env->slb[slot];
-
- if (slot >= env->slb_nr) {
- return -1;
- }
-
- *rt = slb->vsid;
- return 0;
-}
-#endif /* defined(TARGET_PPC64) */
-
/* Perform segment based translation */
-static inline int get_segment(CPUPPCState *env, mmu_ctx_t *ctx,
- target_ulong eaddr, int rw, int type)
+static inline int get_segment_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
+ target_ulong eaddr, int rw, int type)
{
hwaddr hash;
target_ulong vsid;
int ds, pr, target_page_bits;
- int ret, ret2;
+ int ret;
+ target_ulong sr, pgidx;
pr = msr_pr;
ctx->eaddr = eaddr;
-#if defined(TARGET_PPC64)
- if (env->mmu_model & POWERPC_MMU_64) {
- ppc_slb_t *slb;
- target_ulong pageaddr;
- int segment_bits;
-
- LOG_MMU("Check SLBs\n");
- slb = slb_lookup(env, eaddr);
- if (!slb) {
- return -5;
- }
-
- if (slb->vsid & SLB_VSID_B) {
- vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT_1T;
- segment_bits = 40;
- } else {
- vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT;
- segment_bits = 28;
- }
-
- target_page_bits = (slb->vsid & SLB_VSID_L)
- ? TARGET_PAGE_BITS_16M : TARGET_PAGE_BITS;
- ctx->key = !!(pr ? (slb->vsid & SLB_VSID_KP)
- : (slb->vsid & SLB_VSID_KS));
- ds = 0;
- ctx->nx = !!(slb->vsid & SLB_VSID_N);
- pageaddr = eaddr & ((1ULL << segment_bits)
- - (1ULL << target_page_bits));
- if (slb->vsid & SLB_VSID_B) {
- hash = vsid ^ (vsid << 25) ^ (pageaddr >> target_page_bits);
- } else {
- hash = vsid ^ (pageaddr >> target_page_bits);
- }
- /* Only 5 bits of the page index are used in the AVPN */
- ctx->ptem = (slb->vsid & SLB_VSID_PTEM) |
- ((pageaddr >> 16) & ((1ULL << segment_bits) - 0x80));
- } else
-#endif /* defined(TARGET_PPC64) */
- {
- target_ulong sr, pgidx;
+ sr = env->sr[eaddr >> 28];
+ ctx->key = (((sr & 0x20000000) && (pr != 0)) ||
+ ((sr & 0x40000000) && (pr == 0))) ? 1 : 0;
+ ds = sr & 0x80000000 ? 1 : 0;
+ ctx->nx = sr & 0x10000000 ? 1 : 0;
+ vsid = sr & 0x00FFFFFF;
+ target_page_bits = TARGET_PAGE_BITS;
+ LOG_MMU("Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx " nip="
+ TARGET_FMT_lx " lr=" TARGET_FMT_lx
+ " ir=%d dr=%d pr=%d %d t=%d\n",
+ eaddr, (int)(eaddr >> 28), sr, env->nip, env->lr, (int)msr_ir,
+ (int)msr_dr, pr != 0 ? 1 : 0, rw, type);
+ pgidx = (eaddr & ~SEGMENT_MASK_256M) >> target_page_bits;
+ hash = vsid ^ pgidx;
+ ctx->ptem = (vsid << 7) | (pgidx >> 10);
- sr = env->sr[eaddr >> 28];
- ctx->key = (((sr & 0x20000000) && (pr != 0)) ||
- ((sr & 0x40000000) && (pr == 0))) ? 1 : 0;
- ds = sr & 0x80000000 ? 1 : 0;
- ctx->nx = sr & 0x10000000 ? 1 : 0;
- vsid = sr & 0x00FFFFFF;
- target_page_bits = TARGET_PAGE_BITS;
- LOG_MMU("Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx " nip="
- TARGET_FMT_lx " lr=" TARGET_FMT_lx
- " ir=%d dr=%d pr=%d %d t=%d\n",
- eaddr, (int)(eaddr >> 28), sr, env->nip, env->lr, (int)msr_ir,
- (int)msr_dr, pr != 0 ? 1 : 0, rw, type);
- pgidx = (eaddr & ~SEGMENT_MASK_256M) >> target_page_bits;
- hash = vsid ^ pgidx;
- ctx->ptem = (vsid << 7) | (pgidx >> 10);
- }
LOG_MMU("pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx "\n",
ctx->key, ds, ctx->nx, vsid);
ret = -1;
@@ -897,33 +501,8 @@ static inline int get_segment(CPUPPCState *env, mmu_ctx_t *ctx,
/* Initialize real address with an invalid value */
ctx->raddr = (hwaddr)-1ULL;
- if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx ||
- env->mmu_model == POWERPC_MMU_SOFT_74xx)) {
- /* Software TLB search */
- ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type);
- } else {
- LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
- " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx
- " hash=" TARGET_FMT_plx "\n",
- env->htab_base, env->htab_mask, vsid, ctx->ptem,
- ctx->hash[0]);
- /* Primary table lookup */
- ret = find_pte(env, ctx, 0, rw, type, target_page_bits);
- if (ret < 0) {
- /* Secondary table lookup */
- if (eaddr != 0xEFFFFFFF) {
- LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
- " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx
- " hash=" TARGET_FMT_plx "\n", env->htab_base,
- env->htab_mask, vsid, ctx->ptem, ctx->hash[1]);
- }
- ret2 = find_pte(env, ctx, 1, rw, type,
- target_page_bits);
- if (ret2 != -1) {
- ret = ret2;
- }
- }
- }
+ /* Software TLB search */
+ ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type);
#if defined(DUMP_PAGE_TABLES)
if (qemu_log_enabled()) {
hwaddr curaddr;
@@ -1309,8 +888,8 @@ static hwaddr booke206_tlb_to_page_size(CPUPPCState *env,
}
/* TLB check function for MAS based SoftTLBs */
-int ppcmas_tlb_check(CPUPPCState *env, ppcmas_tlb_t *tlb,
- hwaddr *raddrp,
+static int ppcmas_tlb_check(CPUPPCState *env, ppcmas_tlb_t *tlb,
+ hwaddr *raddrp,
target_ulong address, uint32_t pid)
{
target_ulong mask;
@@ -1597,27 +1176,93 @@ static void mmubooke206_dump_mmu(FILE *f, fprintf_function cpu_fprintf,
}
}
-#if defined(TARGET_PPC64)
-static void mmubooks_dump_mmu(FILE *f, fprintf_function cpu_fprintf,
- CPUPPCState *env)
+static void mmu6xx_dump_BATs(FILE *f, fprintf_function cpu_fprintf,
+ CPUPPCState *env, int type)
{
+ target_ulong *BATlt, *BATut, *BATu, *BATl;
+ target_ulong BEPIl, BEPIu, bl;
int i;
- uint64_t slbe, slbv;
- cpu_synchronize_state(env);
+ switch (type) {
+ case ACCESS_CODE:
+ BATlt = env->IBAT[1];
+ BATut = env->IBAT[0];
+ break;
+ default:
+ BATlt = env->DBAT[1];
+ BATut = env->DBAT[0];
+ break;
+ }
- cpu_fprintf(f, "SLB\tESID\t\t\tVSID\n");
- for (i = 0; i < env->slb_nr; i++) {
- slbe = env->slb[i].esid;
- slbv = env->slb[i].vsid;
- if (slbe == 0 && slbv == 0) {
- continue;
+ for (i = 0; i < env->nb_BATs; i++) {
+ BATu = &BATut[i];
+ BATl = &BATlt[i];
+ BEPIu = *BATu & 0xF0000000;
+ BEPIl = *BATu & 0x0FFE0000;
+ bl = (*BATu & 0x00001FFC) << 15;
+ cpu_fprintf(f, "%s BAT%d BATu " TARGET_FMT_lx
+ " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " "
+ TARGET_FMT_lx " " TARGET_FMT_lx "\n",
+ type == ACCESS_CODE ? "code" : "data", i,
+ *BATu, *BATl, BEPIu, BEPIl, bl);
+ }
+}
+
+static void mmu6xx_dump_mmu(FILE *f, fprintf_function cpu_fprintf,
+ CPUPPCState *env)
+{
+ ppc6xx_tlb_t *tlb;
+ target_ulong sr;
+ int type, way, entry, i;
+
+ cpu_fprintf(f, "HTAB base = 0x%"HWADDR_PRIx"\n", env->htab_base);
+ cpu_fprintf(f, "HTAB mask = 0x%"HWADDR_PRIx"\n", env->htab_mask);
+
+ cpu_fprintf(f, "\nSegment registers:\n");
+ for (i = 0; i < 32; i++) {
+ sr = env->sr[i];
+ if (sr & 0x80000000) {
+ cpu_fprintf(f, "%02d T=%d Ks=%d Kp=%d BUID=0x%03x "
+ "CNTLR_SPEC=0x%05x\n", i,
+ sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0,
+ sr & 0x20000000 ? 1 : 0, (uint32_t)((sr >> 20) & 0x1FF),
+ (uint32_t)(sr & 0xFFFFF));
+ } else {
+ cpu_fprintf(f, "%02d T=%d Ks=%d Kp=%d N=%d VSID=0x%06x\n", i,
+ sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0,
+ sr & 0x20000000 ? 1 : 0, sr & 0x10000000 ? 1 : 0,
+ (uint32_t)(sr & 0x00FFFFFF));
+ }
+ }
+
+ cpu_fprintf(f, "\nBATs:\n");
+ mmu6xx_dump_BATs(f, cpu_fprintf, env, ACCESS_INT);
+ mmu6xx_dump_BATs(f, cpu_fprintf, env, ACCESS_CODE);
+
+ if (env->id_tlbs != 1) {
+ cpu_fprintf(f, "ERROR: 6xx MMU should have separated TLB"
+ " for code and data\n");
+ }
+
+ cpu_fprintf(f, "\nTLBs [EPN EPN + SIZE]\n");
+
+ for (type = 0; type < 2; type++) {
+ for (way = 0; way < env->nb_ways; way++) {
+ for (entry = env->nb_tlb * type + env->tlb_per_way * way;
+ entry < (env->nb_tlb * type + env->tlb_per_way * (way + 1));
+ entry++) {
+
+ tlb = &env->tlb.tlb6[entry];
+ cpu_fprintf(f, "%s TLB %02d/%02d way:%d %s ["
+ TARGET_FMT_lx " " TARGET_FMT_lx "]\n",
+ type ? "code" : "data", entry % env->nb_tlb,
+ env->nb_tlb, way,
+ pte_is_valid(tlb->pte0) ? "valid" : "inval",
+ tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE);
+ }
}
- cpu_fprintf(f, "%d\t0x%016" PRIx64 "\t0x%016" PRIx64 "\n",
- i, slbe, slbv);
}
}
-#endif
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env)
{
@@ -1628,11 +1273,16 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env)
case POWERPC_MMU_BOOKE206:
mmubooke206_dump_mmu(f, cpu_fprintf, env);
break;
+ case POWERPC_MMU_SOFT_6xx:
+ case POWERPC_MMU_SOFT_74xx:
+ mmu6xx_dump_mmu(f, cpu_fprintf, env);
+ break;
#if defined(TARGET_PPC64)
case POWERPC_MMU_64B:
case POWERPC_MMU_2_06:
+ case POWERPC_MMU_2_06a:
case POWERPC_MMU_2_06d:
- mmubooks_dump_mmu(f, cpu_fprintf, env);
+ dump_slb(f, cpu_fprintf, env);
break;
#endif
default:
@@ -1649,8 +1299,6 @@ static inline int check_physical(CPUPPCState *env, mmu_ctx_t *ctx,
ctx->prot = PAGE_READ | PAGE_EXEC;
ret = 0;
switch (env->mmu_model) {
- case POWERPC_MMU_32B:
- case POWERPC_MMU_601:
case POWERPC_MMU_SOFT_6xx:
case POWERPC_MMU_SOFT_74xx:
case POWERPC_MMU_SOFT_4xx:
@@ -1658,16 +1306,7 @@ static inline int check_physical(CPUPPCState *env, mmu_ctx_t *ctx,
case POWERPC_MMU_BOOKE:
ctx->prot |= PAGE_WRITE;
break;
-#if defined(TARGET_PPC64)
- case POWERPC_MMU_620:
- case POWERPC_MMU_64B:
- case POWERPC_MMU_2_06:
- case POWERPC_MMU_2_06d:
- /* Real address are 60 bits long */
- ctx->raddr &= 0x0FFFFFFFFFFFFFFFULL;
- ctx->prot |= PAGE_WRITE;
- break;
-#endif
+
case POWERPC_MMU_SOFT_4xx_Z:
if (unlikely(msr_pe != 0)) {
/* 403 family add some particular protections,
@@ -1692,15 +1331,10 @@ static inline int check_physical(CPUPPCState *env, mmu_ctx_t *ctx,
}
}
break;
- case POWERPC_MMU_MPC8xx:
- /* XXX: TODO */
- cpu_abort(env, "MPC8xx MMU model is not implemented\n");
- break;
- case POWERPC_MMU_BOOKE206:
- cpu_abort(env, "BookE 2.06 MMU doesn't have physical real mode\n");
- break;
+
default:
- cpu_abort(env, "Unknown or invalid MMU model\n");
+ /* Caller's checks mean we should never get here for other models */
+ abort();
return -1;
}
@@ -1710,71 +1344,62 @@ static inline int check_physical(CPUPPCState *env, mmu_ctx_t *ctx,
static int get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
target_ulong eaddr, int rw, int access_type)
{
- int ret;
+ int ret = -1;
+ bool real_mode = (access_type == ACCESS_CODE && msr_ir == 0)
+ || (access_type != ACCESS_CODE && msr_dr == 0);
#if 0
qemu_log("%s\n", __func__);
#endif
- if ((access_type == ACCESS_CODE && msr_ir == 0) ||
- (access_type != ACCESS_CODE && msr_dr == 0)) {
- if (env->mmu_model == POWERPC_MMU_BOOKE) {
- /* The BookE MMU always performs address translation. The
- IS and DS bits only affect the address space. */
- ret = mmubooke_get_physical_address(env, ctx, eaddr,
- rw, access_type);
- } else if (env->mmu_model == POWERPC_MMU_BOOKE206) {
- ret = mmubooke206_get_physical_address(env, ctx, eaddr, rw,
- access_type);
- } else {
- /* No address translation. */
+
+ switch (env->mmu_model) {
+ case POWERPC_MMU_SOFT_6xx:
+ case POWERPC_MMU_SOFT_74xx:
+ if (real_mode) {
ret = check_physical(env, ctx, eaddr, rw);
- }
- } else {
- ret = -1;
- switch (env->mmu_model) {
- case POWERPC_MMU_32B:
- case POWERPC_MMU_601:
- case POWERPC_MMU_SOFT_6xx:
- case POWERPC_MMU_SOFT_74xx:
+ } else {
/* Try to find a BAT */
if (env->nb_BATs != 0) {
- ret = get_bat(env, ctx, eaddr, rw, access_type);
+ ret = get_bat_6xx_tlb(env, ctx, eaddr, rw, access_type);
}
-#if defined(TARGET_PPC64)
- case POWERPC_MMU_620:
- case POWERPC_MMU_64B:
- case POWERPC_MMU_2_06:
- case POWERPC_MMU_2_06d:
-#endif
if (ret < 0) {
/* We didn't match any BAT entry or don't have BATs */
- ret = get_segment(env, ctx, eaddr, rw, access_type);
+ ret = get_segment_6xx_tlb(env, ctx, eaddr, rw, access_type);
}
- break;
- case POWERPC_MMU_SOFT_4xx:
- case POWERPC_MMU_SOFT_4xx_Z:
+ }
+ break;
+
+ case POWERPC_MMU_SOFT_4xx:
+ case POWERPC_MMU_SOFT_4xx_Z:
+ if (real_mode) {
+ ret = check_physical(env, ctx, eaddr, rw);
+ } else {
ret = mmu40x_get_physical_address(env, ctx, eaddr,
rw, access_type);
- break;
- case POWERPC_MMU_BOOKE:
- ret = mmubooke_get_physical_address(env, ctx, eaddr,
- rw, access_type);
- break;
- case POWERPC_MMU_BOOKE206:
- ret = mmubooke206_get_physical_address(env, ctx, eaddr, rw,
+ }
+ break;
+ case POWERPC_MMU_BOOKE:
+ ret = mmubooke_get_physical_address(env, ctx, eaddr,
+ rw, access_type);
+ break;
+ case POWERPC_MMU_BOOKE206:
+ ret = mmubooke206_get_physical_address(env, ctx, eaddr, rw,
access_type);
- break;
- case POWERPC_MMU_MPC8xx:
- /* XXX: TODO */
- cpu_abort(env, "MPC8xx MMU model is not implemented\n");
- break;
- case POWERPC_MMU_REAL:
+ break;
+ case POWERPC_MMU_MPC8xx:
+ /* XXX: TODO */
+ cpu_abort(env, "MPC8xx MMU model is not implemented\n");
+ break;
+ case POWERPC_MMU_REAL:
+ if (real_mode) {
+ ret = check_physical(env, ctx, eaddr, rw);
+ } else {
cpu_abort(env, "PowerPC in real mode do not do any translation\n");
- return -1;
- default:
- cpu_abort(env, "Unknown or invalid MMU model\n");
- return -1;
}
+ return -1;
+ default:
+ cpu_abort(env, "Unknown or invalid MMU model\n");
+ return -1;
}
#if 0
qemu_log("%s address " TARGET_FMT_lx " => %d " TARGET_FMT_plx "\n",
@@ -1784,12 +1409,39 @@ static int get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
return ret;
}
-hwaddr cpu_get_phys_page_debug(CPUPPCState *env, target_ulong addr)
+hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
mmu_ctx_t ctx;
+ switch (env->mmu_model) {
+#if defined(TARGET_PPC64)
+ case POWERPC_MMU_64B:
+ case POWERPC_MMU_2_06:
+ case POWERPC_MMU_2_06a:
+ case POWERPC_MMU_2_06d:
+ return ppc_hash64_get_phys_page_debug(env, addr);
+#endif
+
+ case POWERPC_MMU_32B:
+ case POWERPC_MMU_601:
+ return ppc_hash32_get_phys_page_debug(env, addr);
+
+ default:
+ ;
+ }
+
if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT) != 0)) {
- return -1;
+
+ /* Some MMUs have separate TLBs for code and data. If we only try an
+ * ACCESS_INT, we may not be able to read instructions mapped by code
+ * TLBs, so we also try a ACCESS_CODE.
+ */
+ if (unlikely(get_physical_address(env, &ctx, addr, 0,
+ ACCESS_CODE) != 0)) {
+ return -1;
+ }
}
return ctx.raddr & TARGET_PAGE_MASK;
@@ -1836,8 +1488,8 @@ static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong address,
}
/* Perform address translation */
-int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
- int mmu_idx)
+static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
+ int rw, int mmu_idx)
{
mmu_ctx_t ctx;
int access_type;
@@ -1858,7 +1510,7 @@ int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
mmu_idx, TARGET_PAGE_SIZE);
ret = 0;
} else if (ret < 0) {
- LOG_MMU_STATE(env);
+ LOG_MMU_STATE(CPU(ppc_env_get_cpu(env)));
if (access_type == ACCESS_CODE) {
switch (ret) {
case -1:
@@ -1880,17 +1532,6 @@ int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
env->spr[SPR_40x_DEAR] = address;
env->spr[SPR_40x_ESR] = 0x00000000;
break;
- case POWERPC_MMU_32B:
- case POWERPC_MMU_601:
-#if defined(TARGET_PPC64)
- case POWERPC_MMU_620:
- case POWERPC_MMU_64B:
- case POWERPC_MMU_2_06:
- case POWERPC_MMU_2_06d:
-#endif
- env->exception_index = POWERPC_EXCP_ISI;
- env->error_code = 0x40000000;
- break;
case POWERPC_MMU_BOOKE206:
booke206_update_mas_tlb_miss(env, address, rw);
/* fall through */
@@ -1932,19 +1573,6 @@ int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
env->exception_index = POWERPC_EXCP_ISI;
env->error_code = 0x10000000;
break;
-#if defined(TARGET_PPC64)
- case -5:
- /* No match in segment table */
- if (env->mmu_model == POWERPC_MMU_620) {
- env->exception_index = POWERPC_EXCP_ISI;
- /* XXX: this might be incorrect */
- env->error_code = 0x40000000;
- } else {
- env->exception_index = POWERPC_EXCP_ISEG;
- env->error_code = 0;
- }
- break;
-#endif
}
} else {
switch (ret) {
@@ -1964,9 +1592,9 @@ int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
tlb_miss:
env->error_code |= ctx.key << 19;
env->spr[SPR_HASH1] = env->htab_base +
- get_pteg_offset(env, ctx.hash[0], HASH_PTE_SIZE_32);
+ get_pteg_offset32(env, ctx.hash[0]);
env->spr[SPR_HASH2] = env->htab_base +
- get_pteg_offset(env, ctx.hash[1], HASH_PTE_SIZE_32);
+ get_pteg_offset32(env, ctx.hash[1]);
break;
case POWERPC_MMU_SOFT_74xx:
if (rw == 1) {
@@ -1992,23 +1620,6 @@ int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
env->spr[SPR_40x_ESR] = 0x00000000;
}
break;
- case POWERPC_MMU_32B:
- case POWERPC_MMU_601:
-#if defined(TARGET_PPC64)
- case POWERPC_MMU_620:
- case POWERPC_MMU_64B:
- case POWERPC_MMU_2_06:
- case POWERPC_MMU_2_06d:
-#endif
- env->exception_index = POWERPC_EXCP_DSI;
- env->error_code = 0;
- env->spr[SPR_DAR] = address;
- if (rw == 1) {
- env->spr[SPR_DSISR] = 0x42000000;
- } else {
- env->spr[SPR_DSISR] = 0x40000000;
- }
- break;
case POWERPC_MMU_MPC8xx:
/* XXX: TODO */
cpu_abort(env, "MPC8xx MMU model is not implemented\n");
@@ -2094,26 +1705,6 @@ int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
break;
}
break;
-#if defined(TARGET_PPC64)
- case -5:
- /* No match in segment table */
- if (env->mmu_model == POWERPC_MMU_620) {
- env->exception_index = POWERPC_EXCP_DSI;
- env->error_code = 0;
- env->spr[SPR_DAR] = address;
- /* XXX: this might be incorrect */
- if (rw == 1) {
- env->spr[SPR_DSISR] = 0x42000000;
- } else {
- env->spr[SPR_DSISR] = 0x40000000;
- }
- } else {
- env->exception_index = POWERPC_EXCP_DSEG;
- env->error_code = 0;
- env->spr[SPR_DAR] = address;
- }
- break;
-#endif
}
}
#if 0
@@ -2260,8 +1851,9 @@ void helper_store_601_batu(CPUPPCState *env, uint32_t nr, target_ulong value)
void helper_store_601_batl(CPUPPCState *env, uint32_t nr, target_ulong value)
{
+#if !defined(FLUSH_ALL_TLBS)
target_ulong mask;
-#if defined(FLUSH_ALL_TLBS)
+#else
int do_inval;
#endif
@@ -2325,9 +1917,9 @@ void ppc_tlb_invalidate_all(CPUPPCState *env)
case POWERPC_MMU_32B:
case POWERPC_MMU_601:
#if defined(TARGET_PPC64)
- case POWERPC_MMU_620:
case POWERPC_MMU_64B:
case POWERPC_MMU_2_06:
+ case POWERPC_MMU_2_06a:
case POWERPC_MMU_2_06d:
#endif /* defined(TARGET_PPC64) */
tlb_flush(env, 1);
@@ -2395,9 +1987,9 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr)
tlb_flush_page(env, addr | (0xF << 28));
break;
#if defined(TARGET_PPC64)
- case POWERPC_MMU_620:
case POWERPC_MMU_64B:
case POWERPC_MMU_2_06:
+ case POWERPC_MMU_2_06a:
case POWERPC_MMU_2_06d:
/* tlbie invalidate TLBs for all segments */
/* XXX: given the fact that there are too many segments to invalidate,
@@ -2419,16 +2011,6 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr)
/*****************************************************************************/
/* Special registers manipulation */
-#if defined(TARGET_PPC64)
-void ppc_store_asr(CPUPPCState *env, target_ulong value)
-{
- if (env->asr != value) {
- env->asr = value;
- tlb_flush(env, 1);
- }
-}
-#endif
-
void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
{
LOG_MMU("%s: " TARGET_FMT_lx "\n", __func__, value);
@@ -2510,41 +2092,6 @@ void helper_store_sr(CPUPPCState *env, target_ulong srnum, target_ulong value)
#endif
}
}
-#endif /* !defined(CONFIG_USER_ONLY) */
-
-#if !defined(CONFIG_USER_ONLY)
-/* SLB management */
-#if defined(TARGET_PPC64)
-void helper_store_slb(CPUPPCState *env, target_ulong rb, target_ulong rs)
-{
- if (ppc_store_slb(env, rb, rs) < 0) {
- helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL);
- }
-}
-
-target_ulong helper_load_slb_esid(CPUPPCState *env, target_ulong rb)
-{
- target_ulong rt = 0;
-
- if (ppc_load_slb_esid(env, rb, &rt) < 0) {
- helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL);
- }
- return rt;
-}
-
-target_ulong helper_load_slb_vsid(CPUPPCState *env, target_ulong rb)
-{
- target_ulong rt = 0;
-
- if (ppc_load_slb_vsid(env, rb, &rt) < 0) {
- helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL);
- }
- return rt;
-}
-#endif /* defined(TARGET_PPC64) */
/* TLB management */
void helper_tlbia(CPUPPCState *env)
@@ -3320,4 +2867,45 @@ void helper_booke206_tlbflush(CPUPPCState *env, uint32_t type)
booke206_flush_tlb(env, flags, 1);
}
-#endif
+
+
+/*****************************************************************************/
+
+#define MMUSUFFIX _mmu
+
+#define SHIFT 0
+#include "exec/softmmu_template.h"
+
+#define SHIFT 1
+#include "exec/softmmu_template.h"
+
+#define SHIFT 2
+#include "exec/softmmu_template.h"
+
+#define SHIFT 3
+#include "exec/softmmu_template.h"
+
+/* try to fill the TLB and return an exception if error. If retaddr is
+ NULL, it means that the function was called in C code (i.e. not
+ from generated code or from helper.c) */
+/* XXX: fix it to restore all registers */
+void tlb_fill(CPUPPCState *env, target_ulong addr, int is_write, int mmu_idx,
+ uintptr_t retaddr)
+{
+ CPUState *cpu = CPU(ppc_env_get_cpu(env));
+ PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
+ int ret;
+
+ if (pcc->handle_mmu_fault) {
+ ret = pcc->handle_mmu_fault(env, addr, is_write, mmu_idx);
+ } else {
+ ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, mmu_idx);
+ }
+ if (unlikely(ret != 0)) {
+ if (likely(retaddr)) {
+ /* now we have a real cpu fault */
+ cpu_restore_state(env, retaddr);
+ }
+ helper_raise_exception_err(env, env->exception_index, env->error_code);
+ }
+}
diff --git a/target-ppc/mpic_helper.c b/target-ppc/mpic_helper.c
deleted file mode 100644
index 2c6a4d30a..000000000
--- a/target-ppc/mpic_helper.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * PowerPC emulation helpers for QEMU.
- *
- * Copyright (c) 2003-2007 Jocelyn Mayer
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-#include "cpu.h"
-#include "helper.h"
-
-/*****************************************************************************/
-/* SPR accesses */
-
-#if !defined(CONFIG_USER_ONLY)
-/*
- * This is an ugly helper for EPR, which is basically the same as accessing
- * the IACK (PIAC) register on the MPIC. Because we model the MPIC as a device
- * that can only talk to the CPU through MMIO, let's access it that way!
- */
-target_ulong helper_load_epr(CPUPPCState *env)
-{
- return ldl_phys(env->mpic_cpu_base + 0xA0);
-}
-#endif
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 987b04eda..f07d70d86 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -19,9 +19,9 @@
*/
#include "cpu.h"
-#include "disas.h"
+#include "disas/disas.h"
#include "tcg-op.h"
-#include "host-utils.h"
+#include "qemu/host-utils.h"
#include "helper.h"
#define GEN_HELPER 1
@@ -66,12 +66,12 @@ static TCGv cpu_lr;
#if defined(TARGET_PPC64)
static TCGv cpu_cfar;
#endif
-static TCGv cpu_xer;
+static TCGv cpu_xer, cpu_so, cpu_ov, cpu_ca;
static TCGv cpu_reserve;
static TCGv cpu_fpscr;
static TCGv_i32 cpu_access_type;
-#include "gen-icount.h"
+#include "exec/gen-icount.h"
void ppc_translate_init(void)
{
@@ -158,6 +158,12 @@ void ppc_translate_init(void)
cpu_xer = tcg_global_mem_new(TCG_AREG0,
offsetof(CPUPPCState, xer), "xer");
+ cpu_so = tcg_global_mem_new(TCG_AREG0,
+ offsetof(CPUPPCState, so), "SO");
+ cpu_ov = tcg_global_mem_new(TCG_AREG0,
+ offsetof(CPUPPCState, ov), "OV");
+ cpu_ca = tcg_global_mem_new(TCG_AREG0,
+ offsetof(CPUPPCState, ca), "CA");
cpu_reserve = tcg_global_mem_new(TCG_AREG0,
offsetof(CPUPPCState, reserve_addr),
@@ -196,8 +202,17 @@ typedef struct DisasContext {
int spe_enabled;
ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
int singlestep_enabled;
+ uint64_t insns_flags;
+ uint64_t insns_flags2;
} DisasContext;
+/* True when active word size < size of target_long. */
+#ifdef TARGET_PPC64
+# define NARROW_MODE(C) (!(C)->sf_mode)
+#else
+# define NARROW_MODE(C) 0
+#endif
+
struct opc_handler_t {
/* invalid bits for instruction 1 (Rc(opcode) == 0) */
uint32_t inval1;
@@ -254,12 +269,10 @@ static inline void gen_set_access_type(DisasContext *ctx, int access_type)
static inline void gen_update_nip(DisasContext *ctx, target_ulong nip)
{
-#if defined(TARGET_PPC64)
- if (ctx->sf_mode)
- tcg_gen_movi_tl(cpu_nip, nip);
- else
-#endif
- tcg_gen_movi_tl(cpu_nip, (uint32_t)nip);
+ if (NARROW_MODE(ctx)) {
+ nip = (uint32_t)nip;
+ }
+ tcg_gen_movi_tl(cpu_nip, nip);
}
static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
@@ -412,9 +425,14 @@ EXTRACT_HELPER(ME, 1, 5);
EXTRACT_HELPER(TO, 21, 5);
EXTRACT_HELPER(CRM, 12, 8);
-EXTRACT_HELPER(FM, 17, 8);
EXTRACT_HELPER(SR, 16, 4);
+
+/* mtfsf/mtfsfi */
+EXTRACT_HELPER(FPBF, 19, 3);
EXTRACT_HELPER(FPIMM, 12, 4);
+EXTRACT_HELPER(FPL, 21, 1);
+EXTRACT_HELPER(FPFLM, 17, 8);
+EXTRACT_HELPER(FPW, 16, 1);
/*** Jump target decoding ***/
/* Displacement */
@@ -590,45 +608,42 @@ static opc_handler_t invalid_handler = {
static inline void gen_op_cmp(TCGv arg0, TCGv arg1, int s, int crf)
{
- int l1, l2, l3;
+ TCGv t0 = tcg_temp_new();
+ TCGv_i32 t1 = tcg_temp_new_i32();
- tcg_gen_trunc_tl_i32(cpu_crf[crf], cpu_xer);
- tcg_gen_shri_i32(cpu_crf[crf], cpu_crf[crf], XER_SO);
- tcg_gen_andi_i32(cpu_crf[crf], cpu_crf[crf], 1);
+ tcg_gen_trunc_tl_i32(cpu_crf[crf], cpu_so);
- l1 = gen_new_label();
- l2 = gen_new_label();
- l3 = gen_new_label();
- if (s) {
- tcg_gen_brcond_tl(TCG_COND_LT, arg0, arg1, l1);
- tcg_gen_brcond_tl(TCG_COND_GT, arg0, arg1, l2);
- } else {
- tcg_gen_brcond_tl(TCG_COND_LTU, arg0, arg1, l1);
- tcg_gen_brcond_tl(TCG_COND_GTU, arg0, arg1, l2);
- }
- tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1 << CRF_EQ);
- tcg_gen_br(l3);
- gen_set_label(l1);
- tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1 << CRF_LT);
- tcg_gen_br(l3);
- gen_set_label(l2);
- tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1 << CRF_GT);
- gen_set_label(l3);
+ tcg_gen_setcond_tl((s ? TCG_COND_LT: TCG_COND_LTU), t0, arg0, arg1);
+ tcg_gen_trunc_tl_i32(t1, t0);
+ tcg_gen_shli_i32(t1, t1, CRF_LT);
+ tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
+
+ tcg_gen_setcond_tl((s ? TCG_COND_GT: TCG_COND_GTU), t0, arg0, arg1);
+ tcg_gen_trunc_tl_i32(t1, t0);
+ tcg_gen_shli_i32(t1, t1, CRF_GT);
+ tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
+
+ tcg_gen_setcond_tl(TCG_COND_EQ, t0, arg0, arg1);
+ tcg_gen_trunc_tl_i32(t1, t0);
+ tcg_gen_shli_i32(t1, t1, CRF_EQ);
+ tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
+
+ tcg_temp_free(t0);
+ tcg_temp_free_i32(t1);
}
static inline void gen_op_cmpi(TCGv arg0, target_ulong arg1, int s, int crf)
{
- TCGv t0 = tcg_const_local_tl(arg1);
+ TCGv t0 = tcg_const_tl(arg1);
gen_op_cmp(arg0, t0, s, crf);
tcg_temp_free(t0);
}
-#if defined(TARGET_PPC64)
static inline void gen_op_cmp32(TCGv arg0, TCGv arg1, int s, int crf)
{
TCGv t0, t1;
- t0 = tcg_temp_local_new();
- t1 = tcg_temp_local_new();
+ t0 = tcg_temp_new();
+ t1 = tcg_temp_new();
if (s) {
tcg_gen_ext32s_tl(t0, arg0);
tcg_gen_ext32s_tl(t1, arg1);
@@ -643,72 +658,66 @@ static inline void gen_op_cmp32(TCGv arg0, TCGv arg1, int s, int crf)
static inline void gen_op_cmpi32(TCGv arg0, target_ulong arg1, int s, int crf)
{
- TCGv t0 = tcg_const_local_tl(arg1);
+ TCGv t0 = tcg_const_tl(arg1);
gen_op_cmp32(arg0, t0, s, crf);
tcg_temp_free(t0);
}
-#endif
static inline void gen_set_Rc0(DisasContext *ctx, TCGv reg)
{
-#if defined(TARGET_PPC64)
- if (!(ctx->sf_mode))
+ if (NARROW_MODE(ctx)) {
gen_op_cmpi32(reg, 0, 1, 0);
- else
-#endif
+ } else {
gen_op_cmpi(reg, 0, 1, 0);
+ }
}
/* cmp */
static void gen_cmp(DisasContext *ctx)
{
-#if defined(TARGET_PPC64)
- if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
- gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
- 1, crfD(ctx->opcode));
- else
-#endif
+ if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
1, crfD(ctx->opcode));
+ } else {
+ gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
+ 1, crfD(ctx->opcode));
+ }
}
/* cmpi */
static void gen_cmpi(DisasContext *ctx)
{
-#if defined(TARGET_PPC64)
- if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
- gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
- 1, crfD(ctx->opcode));
- else
-#endif
+ if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
1, crfD(ctx->opcode));
+ } else {
+ gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
+ 1, crfD(ctx->opcode));
+ }
}
/* cmpl */
static void gen_cmpl(DisasContext *ctx)
{
-#if defined(TARGET_PPC64)
- if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
- gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
- 0, crfD(ctx->opcode));
- else
-#endif
+ if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
0, crfD(ctx->opcode));
+ } else {
+ gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
+ 0, crfD(ctx->opcode));
+ }
}
/* cmpli */
static void gen_cmpli(DisasContext *ctx)
{
-#if defined(TARGET_PPC64)
- if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
- gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
- 0, crfD(ctx->opcode));
- else
-#endif
+ if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
0, crfD(ctx->opcode));
+ } else {
+ gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
+ 0, crfD(ctx->opcode));
+ }
}
/* isel (PowerPC 2.03 specification) */
@@ -737,125 +746,84 @@ static void gen_isel(DisasContext *ctx)
tcg_temp_free_i32(t0);
}
+/* cmpb: PowerPC 2.05 specification */
+static void gen_cmpb(DisasContext *ctx)
+{
+ gen_helper_cmpb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],
+ cpu_gpr[rB(ctx->opcode)]);
+}
+
/*** Integer arithmetic ***/
static inline void gen_op_arith_compute_ov(DisasContext *ctx, TCGv arg0,
TCGv arg1, TCGv arg2, int sub)
{
- int l1;
- TCGv t0;
+ TCGv t0 = tcg_temp_new();
- l1 = gen_new_label();
- /* Start with XER OV disabled, the most likely case */
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
- t0 = tcg_temp_local_new();
- tcg_gen_xor_tl(t0, arg0, arg1);
-#if defined(TARGET_PPC64)
- if (!ctx->sf_mode)
- tcg_gen_ext32s_tl(t0, t0);
-#endif
- if (sub)
- tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0, l1);
- else
- tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
+ tcg_gen_xor_tl(cpu_ov, arg0, arg2);
tcg_gen_xor_tl(t0, arg1, arg2);
-#if defined(TARGET_PPC64)
- if (!ctx->sf_mode)
- tcg_gen_ext32s_tl(t0, t0);
-#endif
- if (sub)
- tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
- else
- tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0, l1);
- tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
- gen_set_label(l1);
+ if (sub) {
+ tcg_gen_and_tl(cpu_ov, cpu_ov, t0);
+ } else {
+ tcg_gen_andc_tl(cpu_ov, cpu_ov, t0);
+ }
tcg_temp_free(t0);
-}
-
-static inline void gen_op_arith_compute_ca(DisasContext *ctx, TCGv arg1,
- TCGv arg2, int sub)
-{
- int l1 = gen_new_label();
-
-#if defined(TARGET_PPC64)
- if (!(ctx->sf_mode)) {
- TCGv t0, t1;
- t0 = tcg_temp_new();
- t1 = tcg_temp_new();
-
- tcg_gen_ext32u_tl(t0, arg1);
- tcg_gen_ext32u_tl(t1, arg2);
- if (sub) {
- tcg_gen_brcond_tl(TCG_COND_GTU, t0, t1, l1);
- } else {
- tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
- }
- tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
- gen_set_label(l1);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
- } else
-#endif
- {
- if (sub) {
- tcg_gen_brcond_tl(TCG_COND_GTU, arg1, arg2, l1);
- } else {
- tcg_gen_brcond_tl(TCG_COND_GEU, arg1, arg2, l1);
- }
- tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
- gen_set_label(l1);
+ if (NARROW_MODE(ctx)) {
+ tcg_gen_ext32s_tl(cpu_ov, cpu_ov);
}
+ tcg_gen_shri_tl(cpu_ov, cpu_ov, TARGET_LONG_BITS - 1);
+ tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
}
/* Common add function */
static inline void gen_op_arith_add(DisasContext *ctx, TCGv ret, TCGv arg1,
- TCGv arg2, int add_ca, int compute_ca,
- int compute_ov)
+ TCGv arg2, bool add_ca, bool compute_ca,
+ bool compute_ov, bool compute_rc0)
{
- TCGv t0, t1;
+ TCGv t0 = ret;
- if ((!compute_ca && !compute_ov) ||
- (!TCGV_EQUAL(ret,arg1) && !TCGV_EQUAL(ret, arg2))) {
- t0 = ret;
- } else {
- t0 = tcg_temp_local_new();
+ if (compute_ca || compute_ov) {
+ t0 = tcg_temp_new();
}
- if (add_ca) {
- t1 = tcg_temp_local_new();
- tcg_gen_andi_tl(t1, cpu_xer, (1 << XER_CA));
- tcg_gen_shri_tl(t1, t1, XER_CA);
+ if (compute_ca) {
+ if (NARROW_MODE(ctx)) {
+ /* Caution: a non-obvious corner case of the spec is that we
+ must produce the *entire* 64-bit addition, but produce the
+ carry into bit 32. */
+ TCGv t1 = tcg_temp_new();
+ tcg_gen_xor_tl(t1, arg1, arg2); /* add without carry */
+ tcg_gen_add_tl(t0, arg1, arg2);
+ if (add_ca) {
+ tcg_gen_add_tl(t0, t0, cpu_ca);
+ }
+ tcg_gen_xor_tl(cpu_ca, t0, t1); /* bits changed w/ carry */
+ tcg_temp_free(t1);
+ tcg_gen_shri_tl(cpu_ca, cpu_ca, 32); /* extract bit 32 */
+ tcg_gen_andi_tl(cpu_ca, cpu_ca, 1);
+ } else {
+ TCGv zero = tcg_const_tl(0);
+ if (add_ca) {
+ tcg_gen_add2_tl(t0, cpu_ca, arg1, zero, cpu_ca, zero);
+ tcg_gen_add2_tl(t0, cpu_ca, t0, cpu_ca, arg2, zero);
+ } else {
+ tcg_gen_add2_tl(t0, cpu_ca, arg1, zero, arg2, zero);
+ }
+ tcg_temp_free(zero);
+ }
} else {
- TCGV_UNUSED(t1);
- }
-
- if (compute_ca && compute_ov) {
- /* Start with XER CA and OV disabled, the most likely case */
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~((1 << XER_CA) | (1 << XER_OV)));
- } else if (compute_ca) {
- /* Start with XER CA disabled, the most likely case */
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
- } else if (compute_ov) {
- /* Start with XER OV disabled, the most likely case */
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
+ tcg_gen_add_tl(t0, arg1, arg2);
+ if (add_ca) {
+ tcg_gen_add_tl(t0, t0, cpu_ca);
+ }
}
- tcg_gen_add_tl(t0, arg1, arg2);
-
- if (compute_ca) {
- gen_op_arith_compute_ca(ctx, t0, arg1, 0);
- }
- if (add_ca) {
- tcg_gen_add_tl(t0, t0, t1);
- gen_op_arith_compute_ca(ctx, t0, t1, 0);
- tcg_temp_free(t1);
- }
if (compute_ov) {
gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 0);
}
-
- if (unlikely(Rc(ctx->opcode) != 0))
+ if (unlikely(compute_rc0)) {
gen_set_Rc0(ctx, t0);
+ }
if (!TCGV_EQUAL(t0, ret)) {
tcg_gen_mov_tl(ret, t0);
@@ -864,21 +832,21 @@ static inline void gen_op_arith_add(DisasContext *ctx, TCGv ret, TCGv arg1,
}
/* Add functions with two operands */
#define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov) \
-static void glue(gen_, name)(DisasContext *ctx) \
+static void glue(gen_, name)(DisasContext *ctx) \
{ \
gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)], \
cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \
- add_ca, compute_ca, compute_ov); \
+ add_ca, compute_ca, compute_ov, Rc(ctx->opcode)); \
}
/* Add functions with one operand and one immediate */
#define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val, \
add_ca, compute_ca, compute_ov) \
-static void glue(gen_, name)(DisasContext *ctx) \
+static void glue(gen_, name)(DisasContext *ctx) \
{ \
- TCGv t0 = tcg_const_local_tl(const_val); \
+ TCGv t0 = tcg_const_tl(const_val); \
gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)], \
cpu_gpr[rA(ctx->opcode)], t0, \
- add_ca, compute_ca, compute_ov); \
+ add_ca, compute_ca, compute_ov, Rc(ctx->opcode)); \
tcg_temp_free(t0); \
}
@@ -906,40 +874,27 @@ static void gen_addi(DisasContext *ctx)
/* li case */
tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm);
} else {
- tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], simm);
+ tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)],
+ cpu_gpr[rA(ctx->opcode)], simm);
}
}
/* addic addic.*/
-static inline void gen_op_addic(DisasContext *ctx, TCGv ret, TCGv arg1,
- int compute_Rc0)
+static inline void gen_op_addic(DisasContext *ctx, bool compute_rc0)
{
- target_long simm = SIMM(ctx->opcode);
-
- /* Start with XER CA and OV disabled, the most likely case */
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
-
- if (likely(simm != 0)) {
- TCGv t0 = tcg_temp_local_new();
- tcg_gen_addi_tl(t0, arg1, simm);
- gen_op_arith_compute_ca(ctx, t0, arg1, 0);
- tcg_gen_mov_tl(ret, t0);
- tcg_temp_free(t0);
- } else {
- tcg_gen_mov_tl(ret, arg1);
- }
- if (compute_Rc0) {
- gen_set_Rc0(ctx, ret);
- }
+ TCGv c = tcg_const_tl(SIMM(ctx->opcode));
+ gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
+ c, 0, 1, 0, compute_rc0);
+ tcg_temp_free(c);
}
static void gen_addic(DisasContext *ctx)
{
- gen_op_addic(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0);
+ gen_op_addic(ctx, 0);
}
static void gen_addic_(DisasContext *ctx)
{
- gen_op_addic(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 1);
+ gen_op_addic(ctx, 1);
}
/* addis */
@@ -951,7 +906,8 @@ static void gen_addis(DisasContext *ctx)
/* lis case */
tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm << 16);
} else {
- tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], simm << 16);
+ tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)],
+ cpu_gpr[rA(ctx->opcode)], simm << 16);
}
}
@@ -976,7 +932,7 @@ static inline void gen_op_arith_divw(DisasContext *ctx, TCGv ret, TCGv arg1,
tcg_gen_divu_i32(t0, t0, t1);
}
if (compute_ov) {
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
+ tcg_gen_movi_tl(cpu_ov, 0);
}
tcg_gen_br(l2);
gen_set_label(l1);
@@ -986,7 +942,8 @@ static inline void gen_op_arith_divw(DisasContext *ctx, TCGv ret, TCGv arg1,
tcg_gen_movi_i32(t0, 0);
}
if (compute_ov) {
- tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
+ tcg_gen_movi_tl(cpu_ov, 1);
+ tcg_gen_movi_tl(cpu_so, 1);
}
gen_set_label(l2);
tcg_gen_extu_i32_tl(ret, t0);
@@ -1027,7 +984,7 @@ static inline void gen_op_arith_divd(DisasContext *ctx, TCGv ret, TCGv arg1,
tcg_gen_divu_i64(ret, arg1, arg2);
}
if (compute_ov) {
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
+ tcg_gen_movi_tl(cpu_ov, 0);
}
tcg_gen_br(l2);
gen_set_label(l1);
@@ -1037,7 +994,8 @@ static inline void gen_op_arith_divd(DisasContext *ctx, TCGv ret, TCGv arg1,
tcg_gen_movi_i64(ret, 0);
}
if (compute_ov) {
- tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
+ tcg_gen_movi_tl(cpu_ov, 1);
+ tcg_gen_movi_tl(cpu_so, 1);
}
gen_set_label(l2);
if (unlikely(Rc(ctx->opcode) != 0))
@@ -1061,24 +1019,15 @@ GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1);
/* mulhw mulhw. */
static void gen_mulhw(DisasContext *ctx)
{
- TCGv_i64 t0, t1;
+ TCGv_i32 t0 = tcg_temp_new_i32();
+ TCGv_i32 t1 = tcg_temp_new_i32();
- t0 = tcg_temp_new_i64();
- t1 = tcg_temp_new_i64();
-#if defined(TARGET_PPC64)
- tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]);
- tcg_gen_mul_i64(t0, t0, t1);
- tcg_gen_shri_i64(cpu_gpr[rD(ctx->opcode)], t0, 32);
-#else
- tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
- tcg_gen_mul_i64(t0, t0, t1);
- tcg_gen_shri_i64(t0, t0, 32);
- tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
-#endif
- tcg_temp_free_i64(t0);
- tcg_temp_free_i64(t1);
+ tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);
+ tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);
+ tcg_gen_muls2_i32(t0, t1, t0, t1);
+ tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t1);
+ tcg_temp_free_i32(t0);
+ tcg_temp_free_i32(t1);
if (unlikely(Rc(ctx->opcode) != 0))
gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
}
@@ -1086,24 +1035,15 @@ static void gen_mulhw(DisasContext *ctx)
/* mulhwu mulhwu. */
static void gen_mulhwu(DisasContext *ctx)
{
- TCGv_i64 t0, t1;
+ TCGv_i32 t0 = tcg_temp_new_i32();
+ TCGv_i32 t1 = tcg_temp_new_i32();
- t0 = tcg_temp_new_i64();
- t1 = tcg_temp_new_i64();
-#if defined(TARGET_PPC64)
- tcg_gen_ext32u_i64(t0, cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_ext32u_i64(t1, cpu_gpr[rB(ctx->opcode)]);
- tcg_gen_mul_i64(t0, t0, t1);
- tcg_gen_shri_i64(cpu_gpr[rD(ctx->opcode)], t0, 32);
-#else
- tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
- tcg_gen_mul_i64(t0, t0, t1);
- tcg_gen_shri_i64(t0, t0, 32);
- tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
-#endif
- tcg_temp_free_i64(t0);
- tcg_temp_free_i64(t1);
+ tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);
+ tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);
+ tcg_gen_mulu2_i32(t0, t1, t0, t1);
+ tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t1);
+ tcg_temp_free_i32(t0);
+ tcg_temp_free_i32(t1);
if (unlikely(Rc(ctx->opcode) != 0))
gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
}
@@ -1121,34 +1061,21 @@ static void gen_mullw(DisasContext *ctx)
/* mullwo mullwo. */
static void gen_mullwo(DisasContext *ctx)
{
- int l1;
- TCGv_i64 t0, t1;
+ TCGv_i32 t0 = tcg_temp_new_i32();
+ TCGv_i32 t1 = tcg_temp_new_i32();
- t0 = tcg_temp_new_i64();
- t1 = tcg_temp_new_i64();
- l1 = gen_new_label();
- /* Start with XER OV disabled, the most likely case */
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
-#if defined(TARGET_PPC64)
- tcg_gen_ext32s_i64(t0, cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_ext32s_i64(t1, cpu_gpr[rB(ctx->opcode)]);
-#else
- tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
-#endif
- tcg_gen_mul_i64(t0, t0, t1);
-#if defined(TARGET_PPC64)
- tcg_gen_ext32s_i64(cpu_gpr[rD(ctx->opcode)], t0);
- tcg_gen_brcond_i64(TCG_COND_EQ, t0, cpu_gpr[rD(ctx->opcode)], l1);
-#else
- tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
- tcg_gen_ext32s_i64(t1, t0);
- tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
-#endif
- tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
- gen_set_label(l1);
- tcg_temp_free_i64(t0);
- tcg_temp_free_i64(t1);
+ tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);
+ tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);
+ tcg_gen_muls2_i32(t0, t1, t0, t1);
+ tcg_gen_ext_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);
+
+ tcg_gen_sari_i32(t0, t0, 31);
+ tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t1);
+ tcg_gen_extu_i32_tl(cpu_ov, t0);
+ tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
+
+ tcg_temp_free_i32(t0);
+ tcg_temp_free_i32(t1);
if (unlikely(Rc(ctx->opcode) != 0))
gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
}
@@ -1159,19 +1086,31 @@ static void gen_mulli(DisasContext *ctx)
tcg_gen_muli_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
SIMM(ctx->opcode));
}
+
#if defined(TARGET_PPC64)
-#define GEN_INT_ARITH_MUL_HELPER(name, opc3) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- gen_helper_##name (cpu_gpr[rD(ctx->opcode)], \
- cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); \
- if (unlikely(Rc(ctx->opcode) != 0)) \
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); \
-}
/* mulhd mulhd. */
-GEN_INT_ARITH_MUL_HELPER(mulhdu, 0x00);
+static void gen_mulhd(DisasContext *ctx)
+{
+ TCGv lo = tcg_temp_new();
+ tcg_gen_muls2_tl(lo, cpu_gpr[rD(ctx->opcode)],
+ cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
+ tcg_temp_free(lo);
+ if (unlikely(Rc(ctx->opcode) != 0)) {
+ gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
+ }
+}
+
/* mulhdu mulhdu. */
-GEN_INT_ARITH_MUL_HELPER(mulhd, 0x02);
+static void gen_mulhdu(DisasContext *ctx)
+{
+ TCGv lo = tcg_temp_new();
+ tcg_gen_mulu2_tl(lo, cpu_gpr[rD(ctx->opcode)],
+ cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
+ tcg_temp_free(lo);
+ if (unlikely(Rc(ctx->opcode) != 0)) {
+ gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
+ }
+}
/* mulld mulld. */
static void gen_mulld(DisasContext *ctx)
@@ -1193,101 +1132,65 @@ static void gen_mulldo(DisasContext *ctx)
}
#endif
-/* neg neg. nego nego. */
-static inline void gen_op_arith_neg(DisasContext *ctx, TCGv ret, TCGv arg1,
- int ov_check)
-{
- int l1 = gen_new_label();
- int l2 = gen_new_label();
- TCGv t0 = tcg_temp_local_new();
-#if defined(TARGET_PPC64)
- if (ctx->sf_mode) {
- tcg_gen_mov_tl(t0, arg1);
- tcg_gen_brcondi_tl(TCG_COND_EQ, t0, INT64_MIN, l1);
- } else
-#endif
- {
- tcg_gen_ext32s_tl(t0, arg1);
- tcg_gen_brcondi_tl(TCG_COND_EQ, t0, INT32_MIN, l1);
- }
- tcg_gen_neg_tl(ret, arg1);
- if (ov_check) {
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
- }
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_mov_tl(ret, t0);
- if (ov_check) {
- tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
- }
- gen_set_label(l2);
- tcg_temp_free(t0);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, ret);
-}
-
-static void gen_neg(DisasContext *ctx)
-{
- gen_op_arith_neg(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0);
-}
-
-static void gen_nego(DisasContext *ctx)
-{
- gen_op_arith_neg(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 1);
-}
-
/* Common subf function */
static inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv arg1,
- TCGv arg2, int add_ca, int compute_ca,
- int compute_ov)
+ TCGv arg2, bool add_ca, bool compute_ca,
+ bool compute_ov, bool compute_rc0)
{
- TCGv t0, t1;
+ TCGv t0 = ret;
- if ((!compute_ca && !compute_ov) ||
- (!TCGV_EQUAL(ret, arg1) && !TCGV_EQUAL(ret, arg2))) {
- t0 = ret;
- } else {
- t0 = tcg_temp_local_new();
+ if (compute_ca || compute_ov) {
+ t0 = tcg_temp_new();
}
- if (add_ca) {
- t1 = tcg_temp_local_new();
- tcg_gen_andi_tl(t1, cpu_xer, (1 << XER_CA));
- tcg_gen_shri_tl(t1, t1, XER_CA);
- } else {
- TCGV_UNUSED(t1);
- }
-
- if (compute_ca && compute_ov) {
- /* Start with XER CA and OV disabled, the most likely case */
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~((1 << XER_CA) | (1 << XER_OV)));
- } else if (compute_ca) {
- /* Start with XER CA disabled, the most likely case */
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
- } else if (compute_ov) {
- /* Start with XER OV disabled, the most likely case */
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
- }
-
- if (add_ca) {
- tcg_gen_not_tl(t0, arg1);
- tcg_gen_add_tl(t0, t0, arg2);
- gen_op_arith_compute_ca(ctx, t0, arg2, 0);
- tcg_gen_add_tl(t0, t0, t1);
- gen_op_arith_compute_ca(ctx, t0, t1, 0);
- tcg_temp_free(t1);
+ if (compute_ca) {
+ /* dest = ~arg1 + arg2 [+ ca]. */
+ if (NARROW_MODE(ctx)) {
+ /* Caution: a non-obvious corner case of the spec is that we
+ must produce the *entire* 64-bit addition, but produce the
+ carry into bit 32. */
+ TCGv inv1 = tcg_temp_new();
+ TCGv t1 = tcg_temp_new();
+ tcg_gen_not_tl(inv1, arg1);
+ if (add_ca) {
+ tcg_gen_add_tl(t0, arg2, cpu_ca);
+ } else {
+ tcg_gen_addi_tl(t0, arg2, 1);
+ }
+ tcg_gen_xor_tl(t1, arg2, inv1); /* add without carry */
+ tcg_gen_add_tl(t0, t0, inv1);
+ tcg_gen_xor_tl(cpu_ca, t0, t1); /* bits changes w/ carry */
+ tcg_temp_free(t1);
+ tcg_gen_shri_tl(cpu_ca, cpu_ca, 32); /* extract bit 32 */
+ tcg_gen_andi_tl(cpu_ca, cpu_ca, 1);
+ } else if (add_ca) {
+ TCGv zero, inv1 = tcg_temp_new();
+ tcg_gen_not_tl(inv1, arg1);
+ zero = tcg_const_tl(0);
+ tcg_gen_add2_tl(t0, cpu_ca, arg2, zero, cpu_ca, zero);
+ tcg_gen_add2_tl(t0, cpu_ca, t0, cpu_ca, inv1, zero);
+ tcg_temp_free(zero);
+ tcg_temp_free(inv1);
+ } else {
+ tcg_gen_setcond_tl(TCG_COND_GEU, cpu_ca, arg2, arg1);
+ tcg_gen_sub_tl(t0, arg2, arg1);
+ }
+ } else if (add_ca) {
+ /* Since we're ignoring carry-out, we can simplify the
+ standard ~arg1 + arg2 + ca to arg2 - arg1 + ca - 1. */
+ tcg_gen_sub_tl(t0, arg2, arg1);
+ tcg_gen_add_tl(t0, t0, cpu_ca);
+ tcg_gen_subi_tl(t0, t0, 1);
} else {
tcg_gen_sub_tl(t0, arg2, arg1);
- if (compute_ca) {
- gen_op_arith_compute_ca(ctx, t0, arg2, 1);
- }
}
+
if (compute_ov) {
gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 1);
}
-
- if (unlikely(Rc(ctx->opcode) != 0))
+ if (unlikely(compute_rc0)) {
gen_set_Rc0(ctx, t0);
+ }
if (!TCGV_EQUAL(t0, ret)) {
tcg_gen_mov_tl(ret, t0);
@@ -1296,21 +1199,21 @@ static inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv arg1,
}
/* Sub functions with Two operands functions */
#define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov) \
-static void glue(gen_, name)(DisasContext *ctx) \
+static void glue(gen_, name)(DisasContext *ctx) \
{ \
gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], \
cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \
- add_ca, compute_ca, compute_ov); \
+ add_ca, compute_ca, compute_ov, Rc(ctx->opcode)); \
}
/* Sub functions with one operand and one immediate */
#define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val, \
add_ca, compute_ca, compute_ov) \
-static void glue(gen_, name)(DisasContext *ctx) \
+static void glue(gen_, name)(DisasContext *ctx) \
{ \
- TCGv t0 = tcg_const_local_tl(const_val); \
+ TCGv t0 = tcg_const_tl(const_val); \
gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], \
cpu_gpr[rA(ctx->opcode)], t0, \
- add_ca, compute_ca, compute_ov); \
+ add_ca, compute_ca, compute_ov, Rc(ctx->opcode)); \
tcg_temp_free(t0); \
}
/* subf subf. subfo subfo. */
@@ -1332,15 +1235,29 @@ GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
/* subfic */
static void gen_subfic(DisasContext *ctx)
{
- /* Start with XER CA and OV disabled, the most likely case */
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
- TCGv t0 = tcg_temp_local_new();
- TCGv t1 = tcg_const_local_tl(SIMM(ctx->opcode));
- tcg_gen_sub_tl(t0, t1, cpu_gpr[rA(ctx->opcode)]);
- gen_op_arith_compute_ca(ctx, t0, t1, 1);
- tcg_temp_free(t1);
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
- tcg_temp_free(t0);
+ TCGv c = tcg_const_tl(SIMM(ctx->opcode));
+ gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
+ c, 0, 1, 0, 0);
+ tcg_temp_free(c);
+}
+
+/* neg neg. nego nego. */
+static inline void gen_op_arith_neg(DisasContext *ctx, bool compute_ov)
+{
+ TCGv zero = tcg_const_tl(0);
+ gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
+ zero, 0, 0, compute_ov, Rc(ctx->opcode));
+ tcg_temp_free(zero);
+}
+
+static void gen_neg(DisasContext *ctx)
+{
+ gen_op_arith_neg(ctx, 0);
+}
+
+static void gen_nego(DisasContext *ctx)
+{
+ gen_op_arith_neg(ctx, 1);
}
/*** Integer logical ***/
@@ -1557,6 +1474,38 @@ static void gen_popcntd(DisasContext *ctx)
}
#endif
+/* prtyw: PowerPC 2.05 specification */
+static void gen_prtyw(DisasContext *ctx)
+{
+ TCGv ra = cpu_gpr[rA(ctx->opcode)];
+ TCGv rs = cpu_gpr[rS(ctx->opcode)];
+ TCGv t0 = tcg_temp_new();
+ tcg_gen_shri_tl(t0, rs, 16);
+ tcg_gen_xor_tl(ra, rs, t0);
+ tcg_gen_shri_tl(t0, ra, 8);
+ tcg_gen_xor_tl(ra, ra, t0);
+ tcg_gen_andi_tl(ra, ra, (target_ulong)0x100000001ULL);
+ tcg_temp_free(t0);
+}
+
+#if defined(TARGET_PPC64)
+/* prtyd: PowerPC 2.05 specification */
+static void gen_prtyd(DisasContext *ctx)
+{
+ TCGv ra = cpu_gpr[rA(ctx->opcode)];
+ TCGv rs = cpu_gpr[rS(ctx->opcode)];
+ TCGv t0 = tcg_temp_new();
+ tcg_gen_shri_tl(t0, rs, 32);
+ tcg_gen_xor_tl(ra, rs, t0);
+ tcg_gen_shri_tl(t0, ra, 16);
+ tcg_gen_xor_tl(ra, ra, t0);
+ tcg_gen_shri_tl(t0, ra, 8);
+ tcg_gen_xor_tl(ra, ra, t0);
+ tcg_gen_andi_tl(ra, ra, 1);
+ tcg_temp_free(t0);
+}
+#endif
+
#if defined(TARGET_PPC64)
/* extsw & extsw. */
GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B);
@@ -1784,8 +1733,6 @@ static inline void gen_rldnm(DisasContext *ctx, uint32_t mb, uint32_t me)
{
TCGv t0;
- mb = MB(ctx->opcode);
- me = ME(ctx->opcode);
t0 = tcg_temp_new();
tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3f);
tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
@@ -1887,30 +1834,25 @@ static void gen_sraw(DisasContext *ctx)
static void gen_srawi(DisasContext *ctx)
{
int sh = SH(ctx->opcode);
- if (sh != 0) {
- int l1, l2;
+ TCGv dst = cpu_gpr[rA(ctx->opcode)];
+ TCGv src = cpu_gpr[rS(ctx->opcode)];
+ if (sh == 0) {
+ tcg_gen_mov_tl(dst, src);
+ tcg_gen_movi_tl(cpu_ca, 0);
+ } else {
TCGv t0;
- l1 = gen_new_label();
- l2 = gen_new_label();
- t0 = tcg_temp_local_new();
- tcg_gen_ext32s_tl(t0, cpu_gpr[rS(ctx->opcode)]);
- tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
- tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
- tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
- tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
- gen_set_label(l2);
- tcg_gen_ext32s_tl(t0, cpu_gpr[rS(ctx->opcode)]);
- tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], t0, sh);
+ tcg_gen_ext32s_tl(dst, src);
+ tcg_gen_andi_tl(cpu_ca, dst, (1ULL << sh) - 1);
+ t0 = tcg_temp_new();
+ tcg_gen_sari_tl(t0, dst, TARGET_LONG_BITS - 1);
+ tcg_gen_and_tl(cpu_ca, cpu_ca, t0);
tcg_temp_free(t0);
- } else {
- tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
+ tcg_gen_setcondi_tl(TCG_COND_NE, cpu_ca, cpu_ca, 0);
+ tcg_gen_sari_tl(dst, dst, sh);
+ }
+ if (unlikely(Rc(ctx->opcode) != 0)) {
+ gen_set_Rc0(ctx, dst);
}
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
}
/* srw & srw. */
@@ -1970,28 +1912,24 @@ static void gen_srad(DisasContext *ctx)
static inline void gen_sradi(DisasContext *ctx, int n)
{
int sh = SH(ctx->opcode) + (n << 5);
- if (sh != 0) {
- int l1, l2;
+ TCGv dst = cpu_gpr[rA(ctx->opcode)];
+ TCGv src = cpu_gpr[rS(ctx->opcode)];
+ if (sh == 0) {
+ tcg_gen_mov_tl(dst, src);
+ tcg_gen_movi_tl(cpu_ca, 0);
+ } else {
TCGv t0;
- l1 = gen_new_label();
- l2 = gen_new_label();
- t0 = tcg_temp_local_new();
- tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
- tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
- tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
- tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
- gen_set_label(l2);
+ tcg_gen_andi_tl(cpu_ca, src, (1ULL << sh) - 1);
+ t0 = tcg_temp_new();
+ tcg_gen_sari_tl(t0, src, TARGET_LONG_BITS - 1);
+ tcg_gen_and_tl(cpu_ca, cpu_ca, t0);
tcg_temp_free(t0);
- tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
- } else {
- tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
+ tcg_gen_setcondi_tl(TCG_COND_NE, cpu_ca, cpu_ca, 0);
+ tcg_gen_sari_tl(dst, src, sh);
+ }
+ if (unlikely(Rc(ctx->opcode) != 0)) {
+ gen_set_Rc0(ctx, dst);
}
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
}
static void gen_sradi0(DisasContext *ctx)
@@ -2276,7 +2214,16 @@ static void gen_fcmpu(DisasContext *ctx)
/*** Floating-point move ***/
/* fabs */
/* XXX: beware that fabs never checks for NaNs nor update FPSCR */
-GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT);
+static void gen_fabs(DisasContext *ctx)
+{
+ if (unlikely(!ctx->fpu_enabled)) {
+ gen_exception(ctx, POWERPC_EXCP_FPU);
+ return;
+ }
+ tcg_gen_andi_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)],
+ ~(1ULL << 63));
+ gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
+}
/* fmr - fmr. */
/* XXX: beware that fmr never checks for NaNs nor update FPSCR */
@@ -2292,10 +2239,42 @@ static void gen_fmr(DisasContext *ctx)
/* fnabs */
/* XXX: beware that fnabs never checks for NaNs nor update FPSCR */
-GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT);
+static void gen_fnabs(DisasContext *ctx)
+{
+ if (unlikely(!ctx->fpu_enabled)) {
+ gen_exception(ctx, POWERPC_EXCP_FPU);
+ return;
+ }
+ tcg_gen_ori_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)],
+ 1ULL << 63);
+ gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
+}
+
/* fneg */
/* XXX: beware that fneg never checks for NaNs nor update FPSCR */
-GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT);
+static void gen_fneg(DisasContext *ctx)
+{
+ if (unlikely(!ctx->fpu_enabled)) {
+ gen_exception(ctx, POWERPC_EXCP_FPU);
+ return;
+ }
+ tcg_gen_xori_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)],
+ 1ULL << 63);
+ gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
+}
+
+/* fcpsgn: PowerPC 2.05 specification */
+/* XXX: beware that fcpsgn never checks for NaNs nor update FPSCR */
+static void gen_fcpsgn(DisasContext *ctx)
+{
+ if (unlikely(!ctx->fpu_enabled)) {
+ gen_exception(ctx, POWERPC_EXCP_FPU);
+ return;
+ }
+ tcg_gen_deposit_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],
+ cpu_fpr[rB(ctx->opcode)], 0, 63);
+ gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
+}
/*** Floating-Point status & ctrl register ***/
@@ -2386,19 +2365,27 @@ static void gen_mtfsb1(DisasContext *ctx)
static void gen_mtfsf(DisasContext *ctx)
{
TCGv_i32 t0;
- int L = ctx->opcode & 0x02000000;
+ int flm, l, w;
if (unlikely(!ctx->fpu_enabled)) {
gen_exception(ctx, POWERPC_EXCP_FPU);
return;
}
+ flm = FPFLM(ctx->opcode);
+ l = FPL(ctx->opcode);
+ w = FPW(ctx->opcode);
+ if (unlikely(w & !(ctx->insns_flags2 & PPC2_ISA205))) {
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
+ return;
+ }
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
gen_reset_fpstatus();
- if (L)
- t0 = tcg_const_i32(0xff);
- else
- t0 = tcg_const_i32(FM(ctx->opcode));
+ if (l) {
+ t0 = tcg_const_i32((ctx->insns_flags2 & PPC2_ISA205) ? 0xffff : 0xff);
+ } else {
+ t0 = tcg_const_i32(flm << (w * 8));
+ }
gen_helper_store_fpscr(cpu_env, cpu_fpr[rB(ctx->opcode)], t0);
tcg_temp_free_i32(t0);
if (unlikely(Rc(ctx->opcode) != 0)) {
@@ -2412,7 +2399,7 @@ static void gen_mtfsf(DisasContext *ctx)
/* mtfsfi */
static void gen_mtfsfi(DisasContext *ctx)
{
- int bf, sh;
+ int bf, sh, w;
TCGv_i64 t0;
TCGv_i32 t1;
@@ -2420,12 +2407,17 @@ static void gen_mtfsfi(DisasContext *ctx)
gen_exception(ctx, POWERPC_EXCP_FPU);
return;
}
- bf = crbD(ctx->opcode) >> 2;
- sh = 7 - bf;
+ w = FPW(ctx->opcode);
+ bf = FPBF(ctx->opcode);
+ if (unlikely(w & !(ctx->insns_flags2 & PPC2_ISA205))) {
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
+ return;
+ }
+ sh = (8 * w) + 7 - bf;
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
gen_reset_fpstatus();
- t0 = tcg_const_i64(FPIMM(ctx->opcode) << (4 * sh));
+ t0 = tcg_const_i64(((uint64_t)FPIMM(ctx->opcode)) << (4 * sh));
t1 = tcg_const_i32(1 << sh);
gen_helper_store_fpscr(cpu_env, t0, t1);
tcg_temp_free_i64(t0);
@@ -2447,45 +2439,37 @@ static inline void gen_addr_imm_index(DisasContext *ctx, TCGv EA,
simm &= ~maskl;
if (rA(ctx->opcode) == 0) {
-#if defined(TARGET_PPC64)
- if (!ctx->sf_mode) {
- tcg_gen_movi_tl(EA, (uint32_t)simm);
- } else
-#endif
+ if (NARROW_MODE(ctx)) {
+ simm = (uint32_t)simm;
+ }
tcg_gen_movi_tl(EA, simm);
} else if (likely(simm != 0)) {
tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], simm);
-#if defined(TARGET_PPC64)
- if (!ctx->sf_mode) {
+ if (NARROW_MODE(ctx)) {
tcg_gen_ext32u_tl(EA, EA);
}
-#endif
} else {
-#if defined(TARGET_PPC64)
- if (!ctx->sf_mode) {
+ if (NARROW_MODE(ctx)) {
tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
- } else
-#endif
- tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
+ } else {
+ tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
+ }
}
}
static inline void gen_addr_reg_index(DisasContext *ctx, TCGv EA)
{
if (rA(ctx->opcode) == 0) {
-#if defined(TARGET_PPC64)
- if (!ctx->sf_mode) {
+ if (NARROW_MODE(ctx)) {
tcg_gen_ext32u_tl(EA, cpu_gpr[rB(ctx->opcode)]);
- } else
-#endif
- tcg_gen_mov_tl(EA, cpu_gpr[rB(ctx->opcode)]);
+ } else {
+ tcg_gen_mov_tl(EA, cpu_gpr[rB(ctx->opcode)]);
+ }
} else {
tcg_gen_add_tl(EA, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
-#if defined(TARGET_PPC64)
- if (!ctx->sf_mode) {
+ if (NARROW_MODE(ctx)) {
tcg_gen_ext32u_tl(EA, EA);
}
-#endif
}
}
@@ -2493,13 +2477,10 @@ static inline void gen_addr_register(DisasContext *ctx, TCGv EA)
{
if (rA(ctx->opcode) == 0) {
tcg_gen_movi_tl(EA, 0);
+ } else if (NARROW_MODE(ctx)) {
+ tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
} else {
-#if defined(TARGET_PPC64)
- if (!ctx->sf_mode) {
- tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
- } else
-#endif
- tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
+ tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
}
}
@@ -2507,11 +2488,9 @@ static inline void gen_addr_add(DisasContext *ctx, TCGv ret, TCGv arg1,
target_long val)
{
tcg_gen_addi_tl(ret, arg1, val);
-#if defined(TARGET_PPC64)
- if (!ctx->sf_mode) {
+ if (NARROW_MODE(ctx)) {
tcg_gen_ext32u_tl(ret, ret);
}
-#endif
}
static inline void gen_check_align(DisasContext *ctx, TCGv EA, int mask)
@@ -2570,7 +2549,6 @@ static inline void gen_qemu_ld32u(DisasContext *ctx, TCGv arg1, TCGv arg2)
}
}
-#if defined(TARGET_PPC64)
static inline void gen_qemu_ld32s(DisasContext *ctx, TCGv arg1, TCGv arg2)
{
if (unlikely(ctx->le_mode)) {
@@ -2580,7 +2558,6 @@ static inline void gen_qemu_ld32s(DisasContext *ctx, TCGv arg1, TCGv arg2)
} else
tcg_gen_qemu_ld32s(arg1, arg2, ctx->mem_idx);
}
-#endif
static inline void gen_qemu_ld64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
{
@@ -3176,9 +3153,7 @@ static void gen_stwcx_(DisasContext *ctx)
{
int l1;
- tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
- tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
- tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
+ tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
l1 = gen_new_label();
tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
@@ -3219,9 +3194,7 @@ static void gen_stdcx_(DisasContext *ctx)
#else
{
int l1;
- tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
- tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
- tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
+ tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
l1 = gen_new_label();
tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
@@ -3243,7 +3216,8 @@ static void gen_sync(DisasContext *ctx)
static void gen_wait(DisasContext *ctx)
{
TCGv_i32 t0 = tcg_temp_new_i32();
- tcg_gen_st_i32(t0, cpu_env, offsetof(CPUPPCState, halted));
+ tcg_gen_st_i32(t0, cpu_env,
+ -offsetof(PowerPCCPU, env) + offsetof(CPUState, halted));
tcg_temp_free_i32(t0);
/* Stop translation, as the CPU is supposed to sleep from now */
gen_exception_err(ctx, EXCP_HLT, 1);
@@ -3342,6 +3316,71 @@ GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT);
/* lfs lfsu lfsux lfsx */
GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT);
+/* lfdp */
+static void gen_lfdp(DisasContext *ctx)
+{
+ TCGv EA;
+ if (unlikely(!ctx->fpu_enabled)) {
+ gen_exception(ctx, POWERPC_EXCP_FPU);
+ return;
+ }
+ gen_set_access_type(ctx, ACCESS_FLOAT);
+ EA = tcg_temp_new();
+ gen_addr_imm_index(ctx, EA, 0); \
+ if (unlikely(ctx->le_mode)) {
+ gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
+ tcg_gen_addi_tl(EA, EA, 8);
+ gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
+ } else {
+ gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
+ tcg_gen_addi_tl(EA, EA, 8);
+ gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
+ }
+ tcg_temp_free(EA);
+}
+
+/* lfdpx */
+static void gen_lfdpx(DisasContext *ctx)
+{
+ TCGv EA;
+ if (unlikely(!ctx->fpu_enabled)) {
+ gen_exception(ctx, POWERPC_EXCP_FPU);
+ return;
+ }
+ gen_set_access_type(ctx, ACCESS_FLOAT);
+ EA = tcg_temp_new();
+ gen_addr_reg_index(ctx, EA);
+ if (unlikely(ctx->le_mode)) {
+ gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
+ tcg_gen_addi_tl(EA, EA, 8);
+ gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
+ } else {
+ gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
+ tcg_gen_addi_tl(EA, EA, 8);
+ gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
+ }
+ tcg_temp_free(EA);
+}
+
+/* lfiwax */
+static void gen_lfiwax(DisasContext *ctx)
+{
+ TCGv EA;
+ TCGv t0;
+ if (unlikely(!ctx->fpu_enabled)) {
+ gen_exception(ctx, POWERPC_EXCP_FPU);
+ return;
+ }
+ gen_set_access_type(ctx, ACCESS_FLOAT);
+ EA = tcg_temp_new();
+ t0 = tcg_temp_new();
+ gen_addr_reg_index(ctx, EA);
+ gen_qemu_ld32s(ctx, t0, EA);
+ tcg_gen_ext_tl_i64(cpu_fpr[rD(ctx->opcode)], t0);
+ tcg_temp_free(EA);
+ tcg_temp_free(t0);
+}
+
/*** Floating-point store ***/
#define GEN_STF(name, stop, opc, type) \
static void glue(gen_, name)(DisasContext *ctx) \
@@ -3435,6 +3474,52 @@ GEN_STFS(stfd, st64, 0x16, PPC_FLOAT);
/* stfs stfsu stfsux stfsx */
GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT);
+/* stfdp */
+static void gen_stfdp(DisasContext *ctx)
+{
+ TCGv EA;
+ if (unlikely(!ctx->fpu_enabled)) {
+ gen_exception(ctx, POWERPC_EXCP_FPU);
+ return;
+ }
+ gen_set_access_type(ctx, ACCESS_FLOAT);
+ EA = tcg_temp_new();
+ gen_addr_imm_index(ctx, EA, 0); \
+ if (unlikely(ctx->le_mode)) {
+ gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
+ tcg_gen_addi_tl(EA, EA, 8);
+ gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
+ } else {
+ gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
+ tcg_gen_addi_tl(EA, EA, 8);
+ gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
+ }
+ tcg_temp_free(EA);
+}
+
+/* stfdpx */
+static void gen_stfdpx(DisasContext *ctx)
+{
+ TCGv EA;
+ if (unlikely(!ctx->fpu_enabled)) {
+ gen_exception(ctx, POWERPC_EXCP_FPU);
+ return;
+ }
+ gen_set_access_type(ctx, ACCESS_FLOAT);
+ EA = tcg_temp_new();
+ gen_addr_reg_index(ctx, EA);
+ if (unlikely(ctx->le_mode)) {
+ gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
+ tcg_gen_addi_tl(EA, EA, 8);
+ gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
+ } else {
+ gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
+ tcg_gen_addi_tl(EA, EA, 8);
+ gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
+ }
+ tcg_temp_free(EA);
+}
+
/* Optional: */
static inline void gen_qemu_st32fiw(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
{
@@ -3459,10 +3544,9 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
{
TranslationBlock *tb;
tb = ctx->tb;
-#if defined(TARGET_PPC64)
- if (!ctx->sf_mode)
+ if (NARROW_MODE(ctx)) {
dest = (uint32_t) dest;
-#endif
+ }
if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
likely(!ctx->singlestep_enabled)) {
tcg_gen_goto_tb(n);
@@ -3490,12 +3574,10 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
static inline void gen_setlr(DisasContext *ctx, target_ulong nip)
{
-#if defined(TARGET_PPC64)
- if (ctx->sf_mode == 0)
- tcg_gen_movi_tl(cpu_lr, (uint32_t)nip);
- else
-#endif
- tcg_gen_movi_tl(cpu_lr, nip);
+ if (NARROW_MODE(ctx)) {
+ nip = (uint32_t)nip;
+ }
+ tcg_gen_movi_tl(cpu_lr, nip);
}
/* b ba bl bla */
@@ -3505,18 +3587,16 @@ static void gen_b(DisasContext *ctx)
ctx->exception = POWERPC_EXCP_BRANCH;
/* sign extend LI */
-#if defined(TARGET_PPC64)
- if (ctx->sf_mode)
- li = ((int64_t)LI(ctx->opcode) << 38) >> 38;
- else
-#endif
- li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
- if (likely(AA(ctx->opcode) == 0))
+ li = LI(ctx->opcode);
+ li = (li ^ 0x02000000) - 0x02000000;
+ if (likely(AA(ctx->opcode) == 0)) {
target = ctx->nip + li - 4;
- else
+ } else {
target = li;
- if (LK(ctx->opcode))
+ }
+ if (LK(ctx->opcode)) {
gen_setlr(ctx, ctx->nip);
+ }
gen_update_cfar(ctx, ctx->nip);
gen_goto_tb(ctx, 0, target);
}
@@ -3552,12 +3632,11 @@ static inline void gen_bcond(DisasContext *ctx, int type)
return;
}
tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1);
-#if defined(TARGET_PPC64)
- if (!ctx->sf_mode)
+ if (NARROW_MODE(ctx)) {
tcg_gen_ext32u_tl(temp, cpu_ctr);
- else
-#endif
+ } else {
tcg_gen_mov_tl(temp, cpu_ctr);
+ }
if (bo & 0x2) {
tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1);
} else {
@@ -3591,20 +3670,14 @@ static inline void gen_bcond(DisasContext *ctx, int type)
gen_set_label(l1);
gen_goto_tb(ctx, 1, ctx->nip);
} else {
-#if defined(TARGET_PPC64)
- if (!(ctx->sf_mode))
+ if (NARROW_MODE(ctx)) {
tcg_gen_andi_tl(cpu_nip, target, (uint32_t)~3);
- else
-#endif
+ } else {
tcg_gen_andi_tl(cpu_nip, target, ~3);
+ }
tcg_gen_exit_tb(0);
gen_set_label(l1);
-#if defined(TARGET_PPC64)
- if (!(ctx->sf_mode))
- tcg_gen_movi_tl(cpu_nip, (uint32_t)ctx->nip);
- else
-#endif
- tcg_gen_movi_tl(cpu_nip, ctx->nip);
+ gen_update_nip(ctx, ctx->nip);
tcg_gen_exit_tb(0);
}
}
@@ -3797,12 +3870,55 @@ static void gen_tdi(DisasContext *ctx)
/*** Processor control ***/
+static void gen_read_xer(TCGv dst)
+{
+ TCGv t0 = tcg_temp_new();
+ TCGv t1 = tcg_temp_new();
+ TCGv t2 = tcg_temp_new();
+ tcg_gen_mov_tl(dst, cpu_xer);
+ tcg_gen_shli_tl(t0, cpu_so, XER_SO);
+ tcg_gen_shli_tl(t1, cpu_ov, XER_OV);
+ tcg_gen_shli_tl(t2, cpu_ca, XER_CA);
+ tcg_gen_or_tl(t0, t0, t1);
+ tcg_gen_or_tl(dst, dst, t2);
+ tcg_gen_or_tl(dst, dst, t0);
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+ tcg_temp_free(t2);
+}
+
+static void gen_write_xer(TCGv src)
+{
+ tcg_gen_andi_tl(cpu_xer, src,
+ ~((1u << XER_SO) | (1u << XER_OV) | (1u << XER_CA)));
+ tcg_gen_shri_tl(cpu_so, src, XER_SO);
+ tcg_gen_shri_tl(cpu_ov, src, XER_OV);
+ tcg_gen_shri_tl(cpu_ca, src, XER_CA);
+ tcg_gen_andi_tl(cpu_so, cpu_so, 1);
+ tcg_gen_andi_tl(cpu_ov, cpu_ov, 1);
+ tcg_gen_andi_tl(cpu_ca, cpu_ca, 1);
+}
+
/* mcrxr */
static void gen_mcrxr(DisasContext *ctx)
{
- tcg_gen_trunc_tl_i32(cpu_crf[crfD(ctx->opcode)], cpu_xer);
- tcg_gen_shri_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], XER_CA);
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_SO | 1 << XER_OV | 1 << XER_CA));
+ TCGv_i32 t0 = tcg_temp_new_i32();
+ TCGv_i32 t1 = tcg_temp_new_i32();
+ TCGv_i32 dst = cpu_crf[crfD(ctx->opcode)];
+
+ tcg_gen_trunc_tl_i32(t0, cpu_so);
+ tcg_gen_trunc_tl_i32(t1, cpu_ov);
+ tcg_gen_trunc_tl_i32(dst, cpu_ca);
+ tcg_gen_shri_i32(t0, t0, 2);
+ tcg_gen_shri_i32(t1, t1, 1);
+ tcg_gen_or_i32(dst, dst, t0);
+ tcg_gen_or_i32(dst, dst, t1);
+ tcg_temp_free_i32(t0);
+ tcg_temp_free_i32(t1);
+
+ tcg_gen_movi_tl(cpu_so, 0);
+ tcg_gen_movi_tl(cpu_ov, 0);
+ tcg_gen_movi_tl(cpu_ca, 0);
}
/* mfcr mfocrf */
@@ -3887,19 +4003,19 @@ static inline void gen_op_mfspr(DisasContext *ctx)
* allowing userland application to read the PVR
*/
if (sprn != SPR_PVR) {
- qemu_log("Trying to read privileged spr %d %03x at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
- printf("Trying to read privileged spr %d %03x at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
+ qemu_log("Trying to read privileged spr %d (0x%03x) at "
+ TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
+ printf("Trying to read privileged spr %d (0x%03x) at "
+ TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
}
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
}
} else {
/* Not defined */
- qemu_log("Trying to read invalid spr %d %03x at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
- printf("Trying to read invalid spr %d %03x at " TARGET_FMT_lx "\n",
- sprn, sprn, ctx->nip);
+ qemu_log("Trying to read invalid spr %d (0x%03x) at "
+ TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
+ printf("Trying to read invalid spr %d (0x%03x) at "
+ TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
}
}
@@ -4032,18 +4148,18 @@ static void gen_mtspr(DisasContext *ctx)
(*write_cb)(ctx, sprn, rS(ctx->opcode));
} else {
/* Privilege exception */
- qemu_log("Trying to write privileged spr %d %03x at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
- printf("Trying to write privileged spr %d %03x at " TARGET_FMT_lx
- "\n", sprn, sprn, ctx->nip);
+ qemu_log("Trying to write privileged spr %d (0x%03x) at "
+ TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
+ printf("Trying to write privileged spr %d (0x%03x) at "
+ TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
}
} else {
/* Not defined */
- qemu_log("Trying to write invalid spr %d %03x at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
- printf("Trying to write invalid spr %d %03x at " TARGET_FMT_lx "\n",
- sprn, sprn, ctx->nip);
+ qemu_log("Trying to write invalid spr %d (0x%03x) at "
+ TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
+ printf("Trying to write invalid spr %d (0x%03x) at "
+ TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
}
}
@@ -4118,29 +4234,21 @@ static void gen_dcbtst(DisasContext *ctx)
/* dcbz */
static void gen_dcbz(DisasContext *ctx)
{
- TCGv t0;
- gen_set_access_type(ctx, ACCESS_CACHE);
- /* NIP cannot be restored if the memory exception comes from an helper */
- gen_update_nip(ctx, ctx->nip - 4);
- t0 = tcg_temp_new();
- gen_addr_reg_index(ctx, t0);
- gen_helper_dcbz(cpu_env, t0);
- tcg_temp_free(t0);
-}
+ TCGv tcgv_addr;
+ TCGv_i32 tcgv_is_dcbzl;
+ int is_dcbzl = ctx->opcode & 0x00200000 ? 1 : 0;
-static void gen_dcbz_970(DisasContext *ctx)
-{
- TCGv t0;
gen_set_access_type(ctx, ACCESS_CACHE);
/* NIP cannot be restored if the memory exception comes from an helper */
gen_update_nip(ctx, ctx->nip - 4);
- t0 = tcg_temp_new();
- gen_addr_reg_index(ctx, t0);
- if (ctx->opcode & 0x00200000)
- gen_helper_dcbz(cpu_env, t0);
- else
- gen_helper_dcbz_970(cpu_env, t0);
- tcg_temp_free(t0);
+ tcgv_addr = tcg_temp_new();
+ tcgv_is_dcbzl = tcg_const_i32(is_dcbzl);
+
+ gen_addr_reg_index(ctx, tcgv_addr);
+ gen_helper_dcbz(cpu_env, tcgv_addr, tcgv_is_dcbzl);
+
+ tcg_temp_free(tcgv_addr);
+ tcg_temp_free_i32(tcgv_is_dcbzl);
}
/* dst / dstt */
@@ -4428,15 +4536,14 @@ static void gen_tlbie(DisasContext *ctx)
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
return;
}
-#if defined(TARGET_PPC64)
- if (!ctx->sf_mode) {
+ if (NARROW_MODE(ctx)) {
TCGv t0 = tcg_temp_new();
tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
gen_helper_tlbie(cpu_env, t0);
tcg_temp_free(t0);
- } else
-#endif
+ } else {
gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
+ }
#endif
}
@@ -4540,10 +4647,11 @@ static void gen_abso(DisasContext *ctx)
int l2 = gen_new_label();
int l3 = gen_new_label();
/* Start with XER OV disabled, the most likely case */
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
+ tcg_gen_movi_tl(cpu_ov, 0);
tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l2);
tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rA(ctx->opcode)], 0x80000000, l1);
- tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
+ tcg_gen_movi_tl(cpu_ov, 1);
+ tcg_gen_movi_tl(cpu_so, 1);
tcg_gen_br(l2);
gen_set_label(l1);
tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
@@ -4624,7 +4732,7 @@ static void gen_dozo(DisasContext *ctx)
TCGv t1 = tcg_temp_new();
TCGv t2 = tcg_temp_new();
/* Start with XER OV disabled, the most likely case */
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
+ tcg_gen_movi_tl(cpu_ov, 0);
tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
tcg_gen_sub_tl(t0, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
tcg_gen_xor_tl(t1, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
@@ -4632,7 +4740,8 @@ static void gen_dozo(DisasContext *ctx)
tcg_gen_andc_tl(t1, t1, t2);
tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
- tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
+ tcg_gen_movi_tl(cpu_ov, 1);
+ tcg_gen_movi_tl(cpu_so, 1);
tcg_gen_br(l2);
gen_set_label(l1);
tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
@@ -4750,7 +4859,7 @@ static void gen_mulo(DisasContext *ctx)
TCGv_i64 t1 = tcg_temp_new_i64();
TCGv t2 = tcg_temp_new();
/* Start with XER OV disabled, the most likely case */
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
+ tcg_gen_movi_tl(cpu_ov, 0);
tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
tcg_gen_mul_i64(t0, t0, t1);
@@ -4760,7 +4869,8 @@ static void gen_mulo(DisasContext *ctx)
tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
tcg_gen_ext32s_i64(t1, t0);
tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
- tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
+ tcg_gen_movi_tl(cpu_ov, 1);
+ tcg_gen_movi_tl(cpu_so, 1);
gen_set_label(l1);
tcg_temp_free_i64(t0);
tcg_temp_free_i64(t1);
@@ -4796,7 +4906,7 @@ static void gen_nabso(DisasContext *ctx)
tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
gen_set_label(l2);
/* nabs never overflows */
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
+ tcg_gen_movi_tl(cpu_ov, 0);
if (unlikely(Rc(ctx->opcode) != 0))
gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
}
@@ -4973,10 +5083,10 @@ static void gen_sraiq(DisasContext *ctx)
tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
tcg_gen_or_tl(t0, t0, t1);
gen_store_spr(SPR_MQ, t0);
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
+ tcg_gen_movi_tl(cpu_ca, 0);
tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
- tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_CA));
+ tcg_gen_movi_tl(cpu_ca, 1);
gen_set_label(l1);
tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
tcg_temp_free(t0);
@@ -5007,10 +5117,10 @@ static void gen_sraq(DisasContext *ctx)
gen_set_label(l1);
tcg_temp_free(t0);
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t1);
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
+ tcg_gen_movi_tl(cpu_ca, 0);
tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l2);
- tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_CA));
+ tcg_gen_movi_tl(cpu_ca, 1);
gen_set_label(l2);
tcg_temp_free(t1);
tcg_temp_free(t2);
@@ -5579,7 +5689,7 @@ static inline void gen_405_mulladd_insn(DisasContext *ctx, int opc2, int opc3,
if (opc3 & 0x10) {
/* Start with XER OV disabled, the most likely case */
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
+ tcg_gen_movi_tl(cpu_ov, 0);
}
if (opc3 & 0x01) {
/* Signed */
@@ -5602,7 +5712,8 @@ static inline void gen_405_mulladd_insn(DisasContext *ctx, int opc2, int opc3,
}
if (opc3 & 0x10) {
/* Check overflow */
- tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
+ tcg_gen_movi_tl(cpu_ov, 1);
+ tcg_gen_movi_tl(cpu_so, 1);
}
gen_set_label(l1);
tcg_gen_mov_tl(cpu_gpr[rt], t0);
@@ -5990,9 +6101,7 @@ static void gen_tlbsx_40x(DisasContext *ctx)
tcg_temp_free(t0);
if (Rc(ctx->opcode)) {
int l1 = gen_new_label();
- tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
- tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
- tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
+ tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
gen_set_label(l1);
@@ -6073,9 +6182,7 @@ static void gen_tlbsx_440(DisasContext *ctx)
tcg_temp_free(t0);
if (Rc(ctx->opcode)) {
int l1 = gen_new_label();
- tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
- tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
- tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
+ tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
gen_set_label(l1);
@@ -7681,11 +7788,9 @@ static inline void gen_addr_spe_imm_index(DisasContext *ctx, TCGv EA, int sh)
tcg_gen_movi_tl(EA, uimm << sh);
} else {
tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], uimm << sh);
-#if defined(TARGET_PPC64)
- if (!ctx->sf_mode) {
+ if (NARROW_MODE(ctx)) {
tcg_gen_ext32u_tl(EA, EA);
}
-#endif
}
}
@@ -8537,6 +8642,7 @@ GEN_HANDLER(cmp, 0x1F, 0x00, 0x00, 0x00400000, PPC_INTEGER),
GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
GEN_HANDLER(cmpl, 0x1F, 0x00, 0x01, 0x00400000, PPC_INTEGER),
GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
+GEN_HANDLER_E(cmpb, 0x1F, 0x1C, 0x0F, 0x00000001, PPC_NONE, PPC2_ISA205),
GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL),
GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
@@ -8564,9 +8670,11 @@ GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB),
GEN_HANDLER(popcntw, 0x1F, 0x1A, 0x0b, 0x0000F801, PPC_POPCNTWD),
+GEN_HANDLER_E(prtyw, 0x1F, 0x1A, 0x04, 0x0000F801, PPC_NONE, PPC2_ISA205),
#if defined(TARGET_PPC64)
GEN_HANDLER(popcntd, 0x1F, 0x1A, 0x0F, 0x0000F801, PPC_POPCNTWD),
GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B),
+GEN_HANDLER_E(prtyd, 0x1F, 0x1A, 0x05, 0x0000F801, PPC_NONE, PPC2_ISA205),
#endif
GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
@@ -8587,13 +8695,17 @@ GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT),
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT),
+GEN_HANDLER(fabs, 0x3F, 0x08, 0x08, 0x001F0000, PPC_FLOAT),
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT),
+GEN_HANDLER(fnabs, 0x3F, 0x08, 0x04, 0x001F0000, PPC_FLOAT),
+GEN_HANDLER(fneg, 0x3F, 0x08, 0x01, 0x001F0000, PPC_FLOAT),
+GEN_HANDLER_E(fcpsgn, 0x3F, 0x08, 0x00, 0x00000000, PPC_NONE, PPC2_ISA205),
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT),
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT),
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT),
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT),
-GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00010000, PPC_FLOAT),
-GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT),
+GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00000000, PPC_FLOAT),
+GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006e0800, PPC_FLOAT),
#if defined(TARGET_PPC64)
GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B),
GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX),
@@ -8648,8 +8760,7 @@ GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE),
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE),
GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE),
GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE),
-GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ),
-GEN_HANDLER2(dcbz_970, "dcbz", 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT),
+GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZ),
GEN_HANDLER(dst, 0x1F, 0x16, 0x0A, 0x01800001, PPC_ALTIVEC),
GEN_HANDLER(dstst, 0x1F, 0x16, 0x0B, 0x02000001, PPC_ALTIVEC),
GEN_HANDLER(dss, 0x1F, 0x16, 0x19, 0x019FF801, PPC_ALTIVEC),
@@ -8945,9 +9056,6 @@ GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT),
GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT),
GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT),
GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT),
-GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT),
-GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT),
-GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT),
#undef GEN_LD
#undef GEN_LDU
@@ -9033,6 +9141,9 @@ GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT)
GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT)
+GEN_HANDLER_E(lfiwax, 0x1f, 0x17, 0x1a, 0x00000001, PPC_NONE, PPC2_ISA205),
+GEN_HANDLER_E(lfdp, 0x39, 0xFF, 0xFF, 0x00200003, PPC_NONE, PPC2_ISA205),
+GEN_HANDLER_E(lfdpx, 0x1F, 0x17, 0x18, 0x00200001, PPC_NONE, PPC2_ISA205),
#undef GEN_STF
#undef GEN_STUF
@@ -9056,6 +9167,8 @@ GEN_STXF(name, stop, 0x17, op | 0x00, type)
GEN_STFS(stfd, st64, 0x16, PPC_FLOAT)
GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT)
GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX)
+GEN_HANDLER_E(stfdp, 0x3D, 0xFF, 0xFF, 0x00200003, PPC_NONE, PPC2_ISA205),
+GEN_HANDLER_E(stfdpx, 0x1F, 0x17, 0x1C, 0x00200001, PPC_NONE, PPC2_ISA205),
#undef GEN_CRLOGIC
#define GEN_CRLOGIC(name, tcg_op, opc) \
@@ -9413,19 +9526,21 @@ GEN_SPEOP_LDST(evstwwo, 0x1E, 2),
/*****************************************************************************/
/* Misc PowerPC helpers */
-void cpu_dump_state (CPUPPCState *env, FILE *f, fprintf_function cpu_fprintf,
- int flags)
+void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+ int flags)
{
#define RGPL 4
#define RFPL 4
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ CPUPPCState *env = &cpu->env;
int i;
- cpu_synchronize_state(env);
+ cpu_synchronize_state(cs);
cpu_fprintf(f, "NIP " TARGET_FMT_lx " LR " TARGET_FMT_lx " CTR "
TARGET_FMT_lx " XER " TARGET_FMT_lx "\n",
- env->nip, env->lr, env->ctr, env->xer);
+ env->nip, env->lr, env->ctr, cpu_read_xer(env));
cpu_fprintf(f, "MSR " TARGET_FMT_lx " HID0 " TARGET_FMT_lx " HF "
TARGET_FMT_lx " idx %d\n", env->msr, env->spr[SPR_HID0],
env->hflags, env->mmu_idx);
@@ -9533,7 +9648,6 @@ void cpu_dump_state (CPUPPCState *env, FILE *f, fprintf_function cpu_fprintf,
case POWERPC_MMU_SOFT_6xx:
case POWERPC_MMU_SOFT_74xx:
#if defined(TARGET_PPC64)
- case POWERPC_MMU_620:
case POWERPC_MMU_64B:
#endif
cpu_fprintf(f, " SDR1 " TARGET_FMT_lx "\n", env->spr[SPR_SDR1]);
@@ -9563,14 +9677,15 @@ void cpu_dump_state (CPUPPCState *env, FILE *f, fprintf_function cpu_fprintf,
#undef RFPL
}
-void cpu_dump_statistics (CPUPPCState *env, FILE*f, fprintf_function cpu_fprintf,
- int flags)
+void ppc_cpu_dump_statistics(CPUState *cs, FILE*f,
+ fprintf_function cpu_fprintf, int flags)
{
#if defined(DO_PPC_STATISTICS)
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
opc_handler_t **t1, **t2, **t3, *handler;
int op1, op2, op3;
- t1 = env->opcodes;
+ t1 = cpu->env.opcodes;
for (op1 = 0; op1 < 64; op1++) {
handler = t1[op1];
if (is_indirect_opcode(handler)) {
@@ -9611,10 +9726,12 @@ void cpu_dump_statistics (CPUPPCState *env, FILE*f, fprintf_function cpu_fprintf
}
/*****************************************************************************/
-static inline void gen_intermediate_code_internal(CPUPPCState *env,
+static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
TranslationBlock *tb,
- int search_pc)
+ bool search_pc)
{
+ CPUState *cs = CPU(cpu);
+ CPUPPCState *env = &cpu->env;
DisasContext ctx, *ctxp = &ctx;
opc_handler_t **table, *handler;
target_ulong pc_start;
@@ -9631,6 +9748,8 @@ static inline void gen_intermediate_code_internal(CPUPPCState *env,
ctx.exception = POWERPC_EXCP_NONE;
ctx.spr_cb = env->spr_cb;
ctx.mem_idx = env->mmu_idx;
+ ctx.insns_flags = env->insns_flags;
+ ctx.insns_flags2 = env->insns_flags2;
ctx.access_type = -1;
ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;
#if defined(TARGET_PPC64)
@@ -9652,8 +9771,9 @@ static inline void gen_intermediate_code_internal(CPUPPCState *env,
ctx.singlestep_enabled = 0;
if ((env->flags & POWERPC_FLAG_BE) && msr_be)
ctx.singlestep_enabled |= CPU_BRANCH_STEP;
- if (unlikely(env->singlestep_enabled))
+ if (unlikely(cs->singlestep_enabled)) {
ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
+ }
#if defined (DO_SINGLE_STEP) && 0
/* Single step trace mode */
msr_se = 1;
@@ -9663,7 +9783,7 @@ static inline void gen_intermediate_code_internal(CPUPPCState *env,
if (max_insns == 0)
max_insns = CF_COUNT_MASK;
- gen_icount_start();
+ gen_tb_start();
/* Set env in case of segfault during code fetch */
while (ctx.exception == POWERPC_EXCP_NONE
&& tcg_ctx.gen_opc_ptr < gen_opc_end) {
@@ -9680,11 +9800,11 @@ static inline void gen_intermediate_code_internal(CPUPPCState *env,
if (lj < j) {
lj++;
while (lj < j)
- gen_opc_instr_start[lj++] = 0;
+ tcg_ctx.gen_opc_instr_start[lj++] = 0;
}
- gen_opc_pc[lj] = ctx.nip;
- gen_opc_instr_start[lj] = 1;
- gen_opc_icount[lj] = num_insns;
+ tcg_ctx.gen_opc_pc[lj] = ctx.nip;
+ tcg_ctx.gen_opc_instr_start[lj] = 1;
+ tcg_ctx.gen_opc_icount[lj] = num_insns;
}
LOG_DISAS("----------------\n");
LOG_DISAS("nip=" TARGET_FMT_lx " super=%d ir=%d\n",
@@ -9698,7 +9818,7 @@ static inline void gen_intermediate_code_internal(CPUPPCState *env,
}
LOG_DISAS("translate opcode %08x (%02x %02x %02x) (%s)\n",
ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
- opc3(ctx.opcode), little_endian ? "little" : "big");
+ opc3(ctx.opcode), ctx.le_mode ? "little" : "big");
if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
tcg_gen_debug_insn_start(ctx.nip);
}
@@ -9755,7 +9875,7 @@ static inline void gen_intermediate_code_internal(CPUPPCState *env,
ctx.exception != POWERPC_EXCP_BRANCH)) {
gen_exception(ctxp, POWERPC_EXCP_TRACE);
} else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
- (env->singlestep_enabled) ||
+ (cs->singlestep_enabled) ||
singlestep ||
num_insns >= max_insns)) {
/* if we reach a page boundary or are single stepping, stop
@@ -9769,19 +9889,19 @@ static inline void gen_intermediate_code_internal(CPUPPCState *env,
if (ctx.exception == POWERPC_EXCP_NONE) {
gen_goto_tb(&ctx, 0, ctx.nip);
} else if (ctx.exception != POWERPC_EXCP_BRANCH) {
- if (unlikely(env->singlestep_enabled)) {
+ if (unlikely(cs->singlestep_enabled)) {
gen_debug_exception(ctxp);
}
/* Generate the return instruction */
tcg_gen_exit_tb(0);
}
- gen_icount_end(tb, num_insns);
+ gen_tb_end(tb, num_insns);
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
if (unlikely(search_pc)) {
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
lj++;
while (lj <= j)
- gen_opc_instr_start[lj++] = 0;
+ tcg_ctx.gen_opc_instr_start[lj++] = 0;
} else {
tb->size = ctx.nip - pc_start;
tb->icount = num_insns;
@@ -9800,15 +9920,15 @@ static inline void gen_intermediate_code_internal(CPUPPCState *env,
void gen_intermediate_code (CPUPPCState *env, struct TranslationBlock *tb)
{
- gen_intermediate_code_internal(env, tb, 0);
+ gen_intermediate_code_internal(ppc_env_get_cpu(env), tb, false);
}
void gen_intermediate_code_pc (CPUPPCState *env, struct TranslationBlock *tb)
{
- gen_intermediate_code_internal(env, tb, 1);
+ gen_intermediate_code_internal(ppc_env_get_cpu(env), tb, true);
}
void restore_state_to_opc(CPUPPCState *env, TranslationBlock *tb, int pc_pos)
{
- env->nip = gen_opc_pc[pc_pos];
+ env->nip = tcg_ctx.gen_opc_pc[pc_pos];
}
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index e63627cac..13b290c59 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -18,23 +18,19 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
-/* A lot of PowerPC definition have been included here.
- * Most of them are not usable for now but have been kept
- * inside "#if defined(TODO) ... #endif" statements to make tests easier.
- */
-
-#include "dis-asm.h"
-#include "gdbstub.h"
-#include <kvm.h>
+#include "disas/bfd.h"
+#include "exec/gdbstub.h"
+#include <sysemu/kvm.h>
#include "kvm_ppc.h"
-#include "arch_init.h"
+#include "sysemu/arch_init.h"
+#include "sysemu/cpus.h"
+#include "cpu-models.h"
+#include "mmu-hash32.h"
+#include "mmu-hash64.h"
//#define PPC_DUMP_CPU
//#define PPC_DEBUG_SPR
//#define PPC_DUMP_SPR_ACCESSES
-#if defined(CONFIG_USER_ONLY)
-#define TODO_USER_ONLY 1
-#endif
/* For user-mode emulation, we don't emulate any IRQ controller */
#if defined(CONFIG_USER_ONLY)
@@ -60,7 +56,7 @@ static void spr_load_dump_spr(int sprn)
{
#ifdef PPC_DUMP_SPR_ACCESSES
TCGv_i32 t0 = tcg_const_i32(sprn);
- gen_helper_load_dump_spr(t0);
+ gen_helper_load_dump_spr(cpu_env, t0);
tcg_temp_free_i32(t0);
#endif
}
@@ -75,7 +71,7 @@ static void spr_store_dump_spr(int sprn)
{
#ifdef PPC_DUMP_SPR_ACCESSES
TCGv_i32 t0 = tcg_const_i32(sprn);
- gen_helper_store_dump_spr(t0);
+ gen_helper_store_dump_spr(cpu_env, t0);
tcg_temp_free_i32(t0);
#endif
}
@@ -117,12 +113,12 @@ static void spr_write_clear (void *opaque, int sprn, int gprn)
/* XER */
static void spr_read_xer (void *opaque, int gprn, int sprn)
{
- tcg_gen_mov_tl(cpu_gpr[gprn], cpu_xer);
+ gen_read_xer(cpu_gpr[gprn]);
}
static void spr_write_xer (void *opaque, int sprn, int gprn)
{
- tcg_gen_mov_tl(cpu_xer, cpu_gpr[gprn]);
+ gen_write_xer(cpu_gpr[gprn]);
}
/* LR */
@@ -371,7 +367,6 @@ static void spr_write_sdr1 (void *opaque, int sprn, int gprn)
}
/* 64 bits PowerPC specific SPRs */
-/* ASR */
#if defined(TARGET_PPC64)
static void spr_read_hior (void *opaque, int gprn, int sprn)
{
@@ -385,16 +380,6 @@ static void spr_write_hior (void *opaque, int sprn, int gprn)
tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, excp_prefix));
tcg_temp_free(t0);
}
-
-static void spr_read_asr (void *opaque, int gprn, int sprn)
-{
- tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, asr));
-}
-
-static void spr_write_asr (void *opaque, int sprn, int gprn)
-{
- gen_helper_store_asr(cpu_env, cpu_gpr[gprn]);
-}
#endif
#endif
@@ -578,26 +563,42 @@ static inline void vscr_init (CPUPPCState *env, uint32_t val)
set_flush_to_zero(vscr_nj, &env->vec_status);
}
-#if defined(CONFIG_USER_ONLY)
-#define spr_register(env, num, name, uea_read, uea_write, \
- oea_read, oea_write, initial_value) \
-do { \
- _spr_register(env, num, name, uea_read, uea_write, initial_value); \
-} while (0)
-static inline void _spr_register (CPUPPCState *env, int num,
- const char *name,
- void (*uea_read)(void *opaque, int gprn, int sprn),
- void (*uea_write)(void *opaque, int sprn, int gprn),
- target_ulong initial_value)
+#ifdef CONFIG_USER_ONLY
+#define spr_register_kvm(env, num, name, uea_read, uea_write, \
+ oea_read, oea_write, one_reg_id, initial_value) \
+ _spr_register(env, num, name, uea_read, uea_write, initial_value)
+#else
+#if !defined(CONFIG_KVM)
+#define spr_register_kvm(env, num, name, uea_read, uea_write, \
+ oea_read, oea_write, one_reg_id, initial_value) \
+ _spr_register(env, num, name, uea_read, uea_write, \
+ oea_read, oea_write, initial_value)
#else
-static inline void spr_register (CPUPPCState *env, int num,
+#define spr_register_kvm(env, num, name, uea_read, uea_write, \
+ oea_read, oea_write, one_reg_id, initial_value) \
+ _spr_register(env, num, name, uea_read, uea_write, \
+ oea_read, oea_write, one_reg_id, initial_value)
+#endif
+#endif
+
+#define spr_register(env, num, name, uea_read, uea_write, \
+ oea_read, oea_write, initial_value) \
+ spr_register_kvm(env, num, name, uea_read, uea_write, \
+ oea_read, oea_write, 0, initial_value)
+
+static inline void _spr_register(CPUPPCState *env, int num,
const char *name,
void (*uea_read)(void *opaque, int gprn, int sprn),
void (*uea_write)(void *opaque, int sprn, int gprn),
+#if !defined(CONFIG_USER_ONLY)
+
void (*oea_read)(void *opaque, int gprn, int sprn),
void (*oea_write)(void *opaque, int sprn, int gprn),
- target_ulong initial_value)
#endif
+#if defined(CONFIG_KVM)
+ uint64_t one_reg_id,
+#endif
+ target_ulong initial_value)
{
ppc_spr_t *spr;
@@ -673,14 +674,14 @@ static void gen_spr_generic (CPUPPCState *env)
static void gen_spr_ne_601 (CPUPPCState *env)
{
/* Exception processing */
- spr_register(env, SPR_DSISR, "DSISR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_DAR, "DAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
+ spr_register_kvm(env, SPR_DSISR, "DSISR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ KVM_REG_PPC_DSISR, 0x00000000);
+ spr_register_kvm(env, SPR_DAR, "DAR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ KVM_REG_PPC_DAR, 0x00000000);
/* Timer */
spr_register(env, SPR_DECR, "DECR",
SPR_NOACCESS, SPR_NOACCESS,
@@ -924,10 +925,10 @@ static void gen_spr_7xx (CPUPPCState *env)
{
/* Breakpoints */
/* XXX : not implemented */
- spr_register(env, SPR_DABR, "DABR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
+ spr_register_kvm(env, SPR_DABR, "DABR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ KVM_REG_PPC_DABR, 0x00000000);
/* XXX : not implemented */
spr_register(env, SPR_IABR, "IABR",
SPR_NOACCESS, SPR_NOACCESS,
@@ -1018,6 +1019,54 @@ static void gen_spr_7xx (CPUPPCState *env)
0x00000000);
}
+#ifdef TARGET_PPC64
+#ifndef CONFIG_USER_ONLY
+static void spr_read_uamr (void *opaque, int gprn, int sprn)
+{
+ gen_load_spr(cpu_gpr[gprn], SPR_AMR);
+ spr_load_dump_spr(SPR_AMR);
+}
+
+static void spr_write_uamr (void *opaque, int sprn, int gprn)
+{
+ gen_store_spr(SPR_AMR, cpu_gpr[gprn]);
+ spr_store_dump_spr(SPR_AMR);
+}
+
+static void spr_write_uamr_pr (void *opaque, int sprn, int gprn)
+{
+ TCGv t0 = tcg_temp_new();
+
+ gen_load_spr(t0, SPR_UAMOR);
+ tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]);
+ gen_store_spr(SPR_AMR, t0);
+ spr_store_dump_spr(SPR_AMR);
+}
+#endif /* CONFIG_USER_ONLY */
+
+static void gen_spr_amr (CPUPPCState *env)
+{
+#ifndef CONFIG_USER_ONLY
+ /* Virtual Page Class Key protection */
+ /* The AMR is accessible either via SPR 13 or SPR 29. 13 is
+ * userspace accessible, 29 is privileged. So we only need to set
+ * the kvm ONE_REG id on one of them, we use 29 */
+ spr_register(env, SPR_UAMR, "UAMR",
+ &spr_read_uamr, &spr_write_uamr_pr,
+ &spr_read_uamr, &spr_write_uamr,
+ 0);
+ spr_register_kvm(env, SPR_AMR, "AMR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ KVM_REG_PPC_AMR, 0xffffffffffffffffULL);
+ spr_register_kvm(env, SPR_UAMOR, "UAMOR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ KVM_REG_PPC_UAMOR, 0);
+#endif /* !CONFIG_USER_ONLY */
+}
+#endif /* TARGET_PPC64 */
+
static void gen_spr_thrm (CPUPPCState *env)
{
/* Thermal management */
@@ -1053,10 +1102,10 @@ static void gen_spr_604 (CPUPPCState *env)
&spr_read_generic, &spr_write_generic,
0x00000000);
/* XXX : not implemented */
- spr_register(env, SPR_DABR, "DABR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
+ spr_register_kvm(env, SPR_DABR, "DABR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ KVM_REG_PPC_DABR, 0x00000000);
/* Performance counters */
/* XXX : not implemented */
spr_register(env, SPR_MMCR0, "MMCR0",
@@ -1100,6 +1149,13 @@ static void gen_spr_603 (CPUPPCState *env)
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
+ /* Breakpoints */
+ /* XXX : not implemented */
+ spr_register(env, SPR_IABR, "IABR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+
}
/* SPR specific to PowerPC G2 implementation */
@@ -1325,7 +1381,7 @@ static void gen_spr_74xx (CPUPPCState *env)
/* XXX : not implemented */
spr_register(env, SPR_L2CR, "L2CR",
SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_generic, NULL,
0x00000000);
/* Not strictly an SPR */
vscr_init(env, 0x00010000);
@@ -2141,184 +2197,17 @@ static void gen_spr_compress (CPUPPCState *env)
0x00000000);
}
-#if defined (TARGET_PPC64)
-/* SPR specific to PowerPC 620 */
-static void gen_spr_620 (CPUPPCState *env)
-{
- /* Processor identification */
- spr_register(env, SPR_PIR, "PIR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_pir,
- 0x00000000);
- spr_register(env, SPR_ASR, "ASR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_asr, &spr_write_asr,
- 0x00000000);
- /* Breakpoints */
- /* XXX : not implemented */
- spr_register(env, SPR_IABR, "IABR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_DABR, "DABR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_SIAR, "SIAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_SDA, "SDA",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_620_PMC1R, "PMC1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_620_PMC1W, "PMC1",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_620_PMC2R, "PMC2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_620_PMC2W, "PMC2",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_620_MMCR0R, "MMCR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_620_MMCR0W, "MMCR0",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, &spr_write_generic,
- 0x00000000);
- /* External access control */
- /* XXX : not implemented */
- spr_register(env, SPR_EAR, "EAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-#if 0 // XXX: check this
- /* XXX : not implemented */
- spr_register(env, SPR_620_PMR0, "PMR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_620_PMR1, "PMR1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_620_PMR2, "PMR2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_620_PMR3, "PMR3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_620_PMR4, "PMR4",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_620_PMR5, "PMR5",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_620_PMR6, "PMR6",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_620_PMR7, "PMR7",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_620_PMR8, "PMR8",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_620_PMR9, "PMR9",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_620_PMRA, "PMR10",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_620_PMRB, "PMR11",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_620_PMRC, "PMR12",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_620_PMRD, "PMR13",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_620_PMRE, "PMR14",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_620_PMRF, "PMR15",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-#endif
- /* XXX : not implemented */
- spr_register(env, SPR_620_BUSCSR, "BUSCSR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_620_L2CR, "L2CR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_620_L2SR, "L2SR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-}
-#endif /* defined (TARGET_PPC64) */
-
static void gen_spr_5xx_8xx (CPUPPCState *env)
{
/* Exception processing */
- spr_register(env, SPR_DSISR, "DSISR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_DAR, "DAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
+ spr_register_kvm(env, SPR_DSISR, "DSISR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ KVM_REG_PPC_DSISR, 0x00000000);
+ spr_register_kvm(env, SPR_DAR, "DAR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ KVM_REG_PPC_DAR, 0x00000000);
/* Timer */
spr_register(env, SPR_DECR, "DECR",
SPR_NOACCESS, SPR_NOACCESS,
@@ -2711,7 +2600,6 @@ static void init_excp_4xx_real (CPUPPCState *env)
env->excp_vectors[POWERPC_EXCP_FIT] = 0x00001010;
env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001020;
env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000;
- env->hreset_excp_prefix = 0x00000000UL;
env->ivor_mask = 0x0000FFF0UL;
env->ivpr_mask = 0xFFFF0000UL;
/* Hardware reset vector */
@@ -2736,7 +2624,6 @@ static void init_excp_4xx_softmmu (CPUPPCState *env)
env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001100;
env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001200;
env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000;
- env->hreset_excp_prefix = 0x00000000UL;
env->ivor_mask = 0x0000FFF0UL;
env->ivpr_mask = 0xFFFF0000UL;
/* Hardware reset vector */
@@ -2762,11 +2649,10 @@ static void init_excp_MPC5xx (CPUPPCState *env)
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001C00;
env->excp_vectors[POWERPC_EXCP_MEXTBR] = 0x00001E00;
env->excp_vectors[POWERPC_EXCP_NMEXTBR] = 0x00001F00;
- env->hreset_excp_prefix = 0x00000000UL;
env->ivor_mask = 0x0000FFF0UL;
env->ivpr_mask = 0xFFFF0000UL;
/* Hardware reset vector */
- env->hreset_vector = 0xFFFFFFFCUL;
+ env->hreset_vector = 0x00000100UL;
#endif
}
@@ -2794,11 +2680,10 @@ static void init_excp_MPC8xx (CPUPPCState *env)
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001C00;
env->excp_vectors[POWERPC_EXCP_MEXTBR] = 0x00001E00;
env->excp_vectors[POWERPC_EXCP_NMEXTBR] = 0x00001F00;
- env->hreset_excp_prefix = 0x00000000UL;
env->ivor_mask = 0x0000FFF0UL;
env->ivpr_mask = 0xFFFF0000UL;
/* Hardware reset vector */
- env->hreset_vector = 0xFFFFFFFCUL;
+ env->hreset_vector = 0x00000100UL;
#endif
}
@@ -2822,9 +2707,8 @@ static void init_excp_G2 (CPUPPCState *env)
env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
- env->hreset_excp_prefix = 0x00000000UL;
/* Hardware reset vector */
- env->hreset_vector = 0xFFFFFFFCUL;
+ env->hreset_vector = 0x00000100UL;
#endif
}
@@ -2851,7 +2735,6 @@ static void init_excp_e200(CPUPPCState *env, target_ulong ivpr_mask)
env->excp_vectors[POWERPC_EXCP_SPEU] = 0x00000000;
env->excp_vectors[POWERPC_EXCP_EFPDI] = 0x00000000;
env->excp_vectors[POWERPC_EXCP_EFPRI] = 0x00000000;
- env->hreset_excp_prefix = 0x00000000UL;
env->ivor_mask = 0x0000FFF7UL;
env->ivpr_mask = ivpr_mask;
/* Hardware reset vector */
@@ -2878,7 +2761,6 @@ static void init_excp_BookE (CPUPPCState *env)
env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00000000;
env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00000000;
env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00000000;
- env->hreset_excp_prefix = 0x00000000UL;
env->ivor_mask = 0x0000FFE0UL;
env->ivpr_mask = 0xFFFF0000UL;
/* Hardware reset vector */
@@ -2901,7 +2783,6 @@ static void init_excp_601 (CPUPPCState *env)
env->excp_vectors[POWERPC_EXCP_IO] = 0x00000A00;
env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
env->excp_vectors[POWERPC_EXCP_RUNM] = 0x00002000;
- env->hreset_excp_prefix = 0xFFF00000UL;
/* Hardware reset vector */
env->hreset_vector = 0x00000100UL;
#endif
@@ -2929,9 +2810,8 @@ static void init_excp_602 (CPUPPCState *env)
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001500;
env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001600;
- env->hreset_excp_prefix = 0xFFF00000UL;
/* Hardware reset vector */
- env->hreset_vector = 0xFFFFFFFCUL;
+ env->hreset_vector = 0x00000100UL;
#endif
}
@@ -2954,9 +2834,8 @@ static void init_excp_603 (CPUPPCState *env)
env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
- env->hreset_excp_prefix = 0x00000000UL;
/* Hardware reset vector */
- env->hreset_vector = 0xFFFFFFFCUL;
+ env->hreset_vector = 0x00000100UL;
#endif
}
@@ -2977,37 +2856,11 @@ static void init_excp_604 (CPUPPCState *env)
env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
- env->hreset_excp_prefix = 0xFFF00000UL;
/* Hardware reset vector */
env->hreset_vector = 0x00000100UL;
#endif
}
-#if defined(TARGET_PPC64)
-static void init_excp_620 (CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
- env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
- env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
- env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
- env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
- env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
- env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
- env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
- env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
- env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
- env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
- env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
- env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
- env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
- env->hreset_excp_prefix = 0xFFF00000UL;
- /* Hardware reset vector */
- env->hreset_vector = 0x0000000000000100ULL;
-#endif
-}
-#endif /* defined(TARGET_PPC64) */
-
static void init_excp_7x0 (CPUPPCState *env)
{
#if !defined(CONFIG_USER_ONLY)
@@ -3026,9 +2879,8 @@ static void init_excp_7x0 (CPUPPCState *env)
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
- env->hreset_excp_prefix = 0x00000000UL;
/* Hardware reset vector */
- env->hreset_vector = 0xFFFFFFFCUL;
+ env->hreset_vector = 0x00000100UL;
#endif
}
@@ -3049,9 +2901,8 @@ static void init_excp_750cl (CPUPPCState *env)
env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
- env->hreset_excp_prefix = 0x00000000UL;
/* Hardware reset vector */
- env->hreset_vector = 0xFFFFFFFCUL;
+ env->hreset_vector = 0x00000100UL;
#endif
}
@@ -3072,9 +2923,8 @@ static void init_excp_750cx (CPUPPCState *env)
env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
- env->hreset_excp_prefix = 0x00000000UL;
/* Hardware reset vector */
- env->hreset_vector = 0xFFFFFFFCUL;
+ env->hreset_vector = 0x00000100UL;
#endif
}
@@ -3100,9 +2950,8 @@ static void init_excp_7x5 (CPUPPCState *env)
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
- env->hreset_excp_prefix = 0x00000000UL;
/* Hardware reset vector */
- env->hreset_vector = 0xFFFFFFFCUL;
+ env->hreset_vector = 0x00000100UL;
#endif
}
@@ -3126,9 +2975,8 @@ static void init_excp_7400 (CPUPPCState *env)
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600;
env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
- env->hreset_excp_prefix = 0x00000000UL;
/* Hardware reset vector */
- env->hreset_vector = 0xFFFFFFFCUL;
+ env->hreset_vector = 0x00000100UL;
#endif
}
@@ -3154,9 +3002,8 @@ static void init_excp_7450 (CPUPPCState *env)
env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600;
- env->hreset_excp_prefix = 0x00000000UL;
/* Hardware reset vector */
- env->hreset_vector = 0xFFFFFFFCUL;
+ env->hreset_vector = 0x00000100UL;
#endif
}
@@ -3184,7 +3031,6 @@ static void init_excp_970 (CPUPPCState *env)
env->excp_vectors[POWERPC_EXCP_MAINT] = 0x00001600;
env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001700;
env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001800;
- env->hreset_excp_prefix = 0x00000000FFF00000ULL;
/* Hardware reset vector */
env->hreset_vector = 0x0000000000000100ULL;
#endif
@@ -3213,7 +3059,6 @@ static void init_excp_POWER7 (CPUPPCState *env)
env->excp_vectors[POWERPC_EXCP_MAINT] = 0x00001600;
env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001700;
env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001800;
- env->hreset_excp_prefix = 0;
/* Hardware reset vector */
env->hreset_vector = 0x0000000000000100ULL;
#endif
@@ -3251,22 +3096,27 @@ static int check_pow_hid0_74xx (CPUPPCState *env)
/*****************************************************************************/
/* PowerPC implementations definitions */
-/* PowerPC 401 */
-#define POWERPC_INSNS_401 (PPC_INSNS_BASE | PPC_STRING | \
- PPC_WRTEE | PPC_DCR | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT | \
- PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_4xx_COMMON | PPC_40x_EXCP)
-#define POWERPC_INSNS2_401 (PPC_NONE)
-#define POWERPC_MSRM_401 (0x00000000000FD201ULL)
-#define POWERPC_MMU_401 (POWERPC_MMU_REAL)
-#define POWERPC_EXCP_401 (POWERPC_EXCP_40x)
-#define POWERPC_INPUT_401 (PPC_FLAGS_INPUT_401)
-#define POWERPC_BFDM_401 (bfd_mach_ppc_403)
-#define POWERPC_FLAG_401 (POWERPC_FLAG_CE | POWERPC_FLAG_DE | \
- POWERPC_FLAG_BUS_CLK)
-#define check_pow_401 check_pow_nocheck
+#define POWERPC_FAMILY(_name) \
+ static void \
+ glue(glue(ppc_, _name), _cpu_family_class_init)(ObjectClass *, void *); \
+ \
+ static const TypeInfo \
+ glue(glue(ppc_, _name), _cpu_family_type_info) = { \
+ .name = stringify(_name) "-family-" TYPE_POWERPC_CPU, \
+ .parent = TYPE_POWERPC_CPU, \
+ .abstract = true, \
+ .class_init = glue(glue(ppc_, _name), _cpu_family_class_init), \
+ }; \
+ \
+ static void glue(glue(ppc_, _name), _cpu_family_register_types)(void) \
+ { \
+ type_register_static( \
+ &glue(glue(ppc_, _name), _cpu_family_type_info)); \
+ } \
+ \
+ type_init(glue(glue(ppc_, _name), _cpu_family_register_types)) \
+ \
+ static void glue(glue(ppc_, _name), _cpu_family_class_init)
static void init_proc_401 (CPUPPCState *env)
{
@@ -3283,23 +3133,28 @@ static void init_proc_401 (CPUPPCState *env)
SET_WDT_PERIOD(16, 20, 24, 28);
}
-/* PowerPC 401x2 */
-#define POWERPC_INSNS_401x2 (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_DCR | PPC_WRTEE | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT | \
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC | \
- PPC_4xx_COMMON | PPC_40x_EXCP)
-#define POWERPC_INSNS2_401x2 (PPC_NONE)
-#define POWERPC_MSRM_401x2 (0x00000000001FD231ULL)
-#define POWERPC_MMU_401x2 (POWERPC_MMU_SOFT_4xx_Z)
-#define POWERPC_EXCP_401x2 (POWERPC_EXCP_40x)
-#define POWERPC_INPUT_401x2 (PPC_FLAGS_INPUT_401)
-#define POWERPC_BFDM_401x2 (bfd_mach_ppc_403)
-#define POWERPC_FLAG_401x2 (POWERPC_FLAG_CE | POWERPC_FLAG_DE | \
- POWERPC_FLAG_BUS_CLK)
-#define check_pow_401x2 check_pow_nocheck
+POWERPC_FAMILY(401)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 401";
+ pcc->init_proc = init_proc_401;
+ pcc->check_pow = check_pow_nocheck;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
+ PPC_WRTEE | PPC_DCR |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
+ PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_4xx_COMMON | PPC_40x_EXCP;
+ pcc->msr_mask = 0x00000000000FD201ULL;
+ pcc->mmu_model = POWERPC_MMU_REAL;
+ pcc->excp_model = POWERPC_EXCP_40x;
+ pcc->bus_model = PPC_FLAGS_INPUT_401;
+ pcc->bfd_mach = bfd_mach_ppc_403;
+ pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
+ POWERPC_FLAG_BUS_CLK;
+}
static void init_proc_401x2 (CPUPPCState *env)
{
@@ -3324,25 +3179,30 @@ static void init_proc_401x2 (CPUPPCState *env)
SET_WDT_PERIOD(16, 20, 24, 28);
}
-/* PowerPC 401x3 */
-#define POWERPC_INSNS_401x3 (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_DCR | PPC_WRTEE | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT | \
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC | \
- PPC_4xx_COMMON | PPC_40x_EXCP)
-#define POWERPC_INSNS2_401x3 (PPC_NONE)
-#define POWERPC_MSRM_401x3 (0x00000000001FD631ULL)
-#define POWERPC_MMU_401x3 (POWERPC_MMU_SOFT_4xx_Z)
-#define POWERPC_EXCP_401x3 (POWERPC_EXCP_40x)
-#define POWERPC_INPUT_401x3 (PPC_FLAGS_INPUT_401)
-#define POWERPC_BFDM_401x3 (bfd_mach_ppc_403)
-#define POWERPC_FLAG_401x3 (POWERPC_FLAG_CE | POWERPC_FLAG_DE | \
- POWERPC_FLAG_BUS_CLK)
-#define check_pow_401x3 check_pow_nocheck
+POWERPC_FAMILY(401x2)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 401x2";
+ pcc->init_proc = init_proc_401x2;
+ pcc->check_pow = check_pow_nocheck;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_DCR | PPC_WRTEE |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
+ PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
+ PPC_4xx_COMMON | PPC_40x_EXCP;
+ pcc->msr_mask = 0x00000000001FD231ULL;
+ pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
+ pcc->excp_model = POWERPC_EXCP_40x;
+ pcc->bus_model = PPC_FLAGS_INPUT_401;
+ pcc->bfd_mach = bfd_mach_ppc_403;
+ pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
+ POWERPC_FLAG_BUS_CLK;
+}
-__attribute__ (( unused ))
static void init_proc_401x3 (CPUPPCState *env)
{
gen_spr_40x(env);
@@ -3360,23 +3220,29 @@ static void init_proc_401x3 (CPUPPCState *env)
SET_WDT_PERIOD(16, 20, 24, 28);
}
-/* IOP480 */
-#define POWERPC_INSNS_IOP480 (PPC_INSNS_BASE | PPC_STRING | \
- PPC_DCR | PPC_WRTEE | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT | \
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC | \
- PPC_4xx_COMMON | PPC_40x_EXCP)
-#define POWERPC_INSNS2_IOP480 (PPC_NONE)
-#define POWERPC_MSRM_IOP480 (0x00000000001FD231ULL)
-#define POWERPC_MMU_IOP480 (POWERPC_MMU_SOFT_4xx_Z)
-#define POWERPC_EXCP_IOP480 (POWERPC_EXCP_40x)
-#define POWERPC_INPUT_IOP480 (PPC_FLAGS_INPUT_401)
-#define POWERPC_BFDM_IOP480 (bfd_mach_ppc_403)
-#define POWERPC_FLAG_IOP480 (POWERPC_FLAG_CE | POWERPC_FLAG_DE | \
- POWERPC_FLAG_BUS_CLK)
-#define check_pow_IOP480 check_pow_nocheck
+POWERPC_FAMILY(401x3)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 401x3";
+ pcc->init_proc = init_proc_401x3;
+ pcc->check_pow = check_pow_nocheck;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_DCR | PPC_WRTEE |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
+ PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
+ PPC_4xx_COMMON | PPC_40x_EXCP;
+ pcc->msr_mask = 0x00000000001FD631ULL;
+ pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
+ pcc->excp_model = POWERPC_EXCP_40x;
+ pcc->bus_model = PPC_FLAGS_INPUT_401;
+ pcc->bfd_mach = bfd_mach_ppc_403;
+ pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
+ POWERPC_FLAG_BUS_CLK;
+}
static void init_proc_IOP480 (CPUPPCState *env)
{
@@ -3401,22 +3267,29 @@ static void init_proc_IOP480 (CPUPPCState *env)
SET_WDT_PERIOD(16, 20, 24, 28);
}
-/* PowerPC 403 */
-#define POWERPC_INSNS_403 (PPC_INSNS_BASE | PPC_STRING | \
- PPC_DCR | PPC_WRTEE | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT | \
- PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_4xx_COMMON | PPC_40x_EXCP)
-#define POWERPC_INSNS2_403 (PPC_NONE)
-#define POWERPC_MSRM_403 (0x000000000007D00DULL)
-#define POWERPC_MMU_403 (POWERPC_MMU_REAL)
-#define POWERPC_EXCP_403 (POWERPC_EXCP_40x)
-#define POWERPC_INPUT_403 (PPC_FLAGS_INPUT_401)
-#define POWERPC_BFDM_403 (bfd_mach_ppc_403)
-#define POWERPC_FLAG_403 (POWERPC_FLAG_CE | POWERPC_FLAG_PX | \
- POWERPC_FLAG_BUS_CLK)
-#define check_pow_403 check_pow_nocheck
+POWERPC_FAMILY(IOP480)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "IOP480";
+ pcc->init_proc = init_proc_IOP480;
+ pcc->check_pow = check_pow_nocheck;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
+ PPC_DCR | PPC_WRTEE |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
+ PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
+ PPC_4xx_COMMON | PPC_40x_EXCP;
+ pcc->msr_mask = 0x00000000001FD231ULL;
+ pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
+ pcc->excp_model = POWERPC_EXCP_40x;
+ pcc->bus_model = PPC_FLAGS_INPUT_401;
+ pcc->bfd_mach = bfd_mach_ppc_403;
+ pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
+ POWERPC_FLAG_BUS_CLK;
+}
static void init_proc_403 (CPUPPCState *env)
{
@@ -3434,23 +3307,28 @@ static void init_proc_403 (CPUPPCState *env)
SET_WDT_PERIOD(16, 20, 24, 28);
}
-/* PowerPC 403 GCX */
-#define POWERPC_INSNS_403GCX (PPC_INSNS_BASE | PPC_STRING | \
- PPC_DCR | PPC_WRTEE | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT | \
- PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC | \
- PPC_4xx_COMMON | PPC_40x_EXCP)
-#define POWERPC_INSNS2_403GCX (PPC_NONE)
-#define POWERPC_MSRM_403GCX (0x000000000007D00DULL)
-#define POWERPC_MMU_403GCX (POWERPC_MMU_SOFT_4xx_Z)
-#define POWERPC_EXCP_403GCX (POWERPC_EXCP_40x)
-#define POWERPC_INPUT_403GCX (PPC_FLAGS_INPUT_401)
-#define POWERPC_BFDM_403GCX (bfd_mach_ppc_403)
-#define POWERPC_FLAG_403GCX (POWERPC_FLAG_CE | POWERPC_FLAG_PX | \
- POWERPC_FLAG_BUS_CLK)
-#define check_pow_403GCX check_pow_nocheck
+POWERPC_FAMILY(403)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 403";
+ pcc->init_proc = init_proc_403;
+ pcc->check_pow = check_pow_nocheck;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
+ PPC_DCR | PPC_WRTEE |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
+ PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_4xx_COMMON | PPC_40x_EXCP;
+ pcc->msr_mask = 0x000000000007D00DULL;
+ pcc->mmu_model = POWERPC_MMU_REAL;
+ pcc->excp_model = POWERPC_EXCP_40x;
+ pcc->bus_model = PPC_FLAGS_INPUT_401;
+ pcc->bfd_mach = bfd_mach_ppc_403;
+ pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_PX |
+ POWERPC_FLAG_BUS_CLK;
+}
static void init_proc_403GCX (CPUPPCState *env)
{
@@ -3487,23 +3365,29 @@ static void init_proc_403GCX (CPUPPCState *env)
SET_WDT_PERIOD(16, 20, 24, 28);
}
-/* PowerPC 405 */
-#define POWERPC_INSNS_405 (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_DCR | PPC_WRTEE | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT | \
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC | \
- PPC_4xx_COMMON | PPC_405_MAC | PPC_40x_EXCP)
-#define POWERPC_INSNS2_405 (PPC_NONE)
-#define POWERPC_MSRM_405 (0x000000000006E630ULL)
-#define POWERPC_MMU_405 (POWERPC_MMU_SOFT_4xx)
-#define POWERPC_EXCP_405 (POWERPC_EXCP_40x)
-#define POWERPC_INPUT_405 (PPC_FLAGS_INPUT_405)
-#define POWERPC_BFDM_405 (bfd_mach_ppc_403)
-#define POWERPC_FLAG_405 (POWERPC_FLAG_CE | POWERPC_FLAG_DWE | \
- POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK)
-#define check_pow_405 check_pow_nocheck
+POWERPC_FAMILY(403GCX)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 403 GCX";
+ pcc->init_proc = init_proc_403GCX;
+ pcc->check_pow = check_pow_nocheck;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
+ PPC_DCR | PPC_WRTEE |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
+ PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
+ PPC_4xx_COMMON | PPC_40x_EXCP;
+ pcc->msr_mask = 0x000000000007D00DULL;
+ pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
+ pcc->excp_model = POWERPC_EXCP_40x;
+ pcc->bus_model = PPC_FLAGS_INPUT_401;
+ pcc->bfd_mach = bfd_mach_ppc_403;
+ pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_PX |
+ POWERPC_FLAG_BUS_CLK;
+}
static void init_proc_405 (CPUPPCState *env)
{
@@ -3539,26 +3423,29 @@ static void init_proc_405 (CPUPPCState *env)
SET_WDT_PERIOD(16, 20, 24, 28);
}
-/* PowerPC 440 EP */
-#define POWERPC_INSNS_440EP (PPC_INSNS_BASE | PPC_STRING | \
- PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL | \
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | \
- PPC_FLOAT_STFIWX | \
- PPC_DCR | PPC_WRTEE | PPC_RFMCI | \
- PPC_CACHE | PPC_CACHE_ICBI | \
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \
- PPC_MEM_TLBSYNC | PPC_MFTB | \
- PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | \
- PPC_440_SPEC)
-#define POWERPC_INSNS2_440EP (PPC_NONE)
-#define POWERPC_MSRM_440EP (0x000000000006FF30ULL)
-#define POWERPC_MMU_440EP (POWERPC_MMU_BOOKE)
-#define POWERPC_EXCP_440EP (POWERPC_EXCP_BOOKE)
-#define POWERPC_INPUT_440EP (PPC_FLAGS_INPUT_BookE)
-#define POWERPC_BFDM_440EP (bfd_mach_ppc_403)
-#define POWERPC_FLAG_440EP (POWERPC_FLAG_CE | POWERPC_FLAG_DWE | \
- POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK)
-#define check_pow_440EP check_pow_nocheck
+POWERPC_FAMILY(405)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 405";
+ pcc->init_proc = init_proc_405;
+ pcc->check_pow = check_pow_nocheck;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_DCR | PPC_WRTEE |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
+ PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
+ PPC_4xx_COMMON | PPC_405_MAC | PPC_40x_EXCP;
+ pcc->msr_mask = 0x000000000006E630ULL;
+ pcc->mmu_model = POWERPC_MMU_SOFT_4xx;
+ pcc->excp_model = POWERPC_EXCP_40x;
+ pcc->bus_model = PPC_FLAGS_INPUT_405;
+ pcc->bfd_mach = bfd_mach_ppc_403;
+ pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
+ POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
+}
static void init_proc_440EP (CPUPPCState *env)
{
@@ -3626,25 +3513,33 @@ static void init_proc_440EP (CPUPPCState *env)
SET_WDT_PERIOD(20, 24, 28, 32);
}
-/* PowerPC 440 GP */
-#define POWERPC_INSNS_440GP (PPC_INSNS_BASE | PPC_STRING | \
- PPC_DCR | PPC_DCRX | PPC_WRTEE | PPC_MFAPIDI | \
- PPC_CACHE | PPC_CACHE_ICBI | \
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \
- PPC_MEM_TLBSYNC | PPC_TLBIVA | PPC_MFTB | \
- PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | \
- PPC_440_SPEC)
-#define POWERPC_INSNS2_440GP (PPC_NONE)
-#define POWERPC_MSRM_440GP (0x000000000006FF30ULL)
-#define POWERPC_MMU_440GP (POWERPC_MMU_BOOKE)
-#define POWERPC_EXCP_440GP (POWERPC_EXCP_BOOKE)
-#define POWERPC_INPUT_440GP (PPC_FLAGS_INPUT_BookE)
-#define POWERPC_BFDM_440GP (bfd_mach_ppc_403)
-#define POWERPC_FLAG_440GP (POWERPC_FLAG_CE | POWERPC_FLAG_DWE | \
- POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK)
-#define check_pow_440GP check_pow_nocheck
+POWERPC_FAMILY(440EP)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 440 EP";
+ pcc->init_proc = init_proc_440EP;
+ pcc->check_pow = check_pow_nocheck;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
+ PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL |
+ PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
+ PPC_FLOAT_STFIWX |
+ PPC_DCR | PPC_WRTEE | PPC_RFMCI |
+ PPC_CACHE | PPC_CACHE_ICBI |
+ PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
+ PPC_MEM_TLBSYNC | PPC_MFTB |
+ PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
+ PPC_440_SPEC;
+ pcc->msr_mask = 0x000000000006FF30ULL;
+ pcc->mmu_model = POWERPC_MMU_BOOKE;
+ pcc->excp_model = POWERPC_EXCP_BOOKE;
+ pcc->bus_model = PPC_FLAGS_INPUT_BookE;
+ pcc->bfd_mach = bfd_mach_ppc_403;
+ pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
+ POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
+}
-__attribute__ (( unused ))
static void init_proc_440GP (CPUPPCState *env)
{
/* Time base */
@@ -3693,25 +3588,30 @@ static void init_proc_440GP (CPUPPCState *env)
SET_WDT_PERIOD(20, 24, 28, 32);
}
-/* PowerPC 440x4 */
-#define POWERPC_INSNS_440x4 (PPC_INSNS_BASE | PPC_STRING | \
- PPC_DCR | PPC_WRTEE | \
- PPC_CACHE | PPC_CACHE_ICBI | \
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \
- PPC_MEM_TLBSYNC | PPC_MFTB | \
- PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | \
- PPC_440_SPEC)
-#define POWERPC_INSNS2_440x4 (PPC_NONE)
-#define POWERPC_MSRM_440x4 (0x000000000006FF30ULL)
-#define POWERPC_MMU_440x4 (POWERPC_MMU_BOOKE)
-#define POWERPC_EXCP_440x4 (POWERPC_EXCP_BOOKE)
-#define POWERPC_INPUT_440x4 (PPC_FLAGS_INPUT_BookE)
-#define POWERPC_BFDM_440x4 (bfd_mach_ppc_403)
-#define POWERPC_FLAG_440x4 (POWERPC_FLAG_CE | POWERPC_FLAG_DWE | \
- POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK)
-#define check_pow_440x4 check_pow_nocheck
+POWERPC_FAMILY(440GP)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 440 GP";
+ pcc->init_proc = init_proc_440GP;
+ pcc->check_pow = check_pow_nocheck;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
+ PPC_DCR | PPC_DCRX | PPC_WRTEE | PPC_MFAPIDI |
+ PPC_CACHE | PPC_CACHE_ICBI |
+ PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
+ PPC_MEM_TLBSYNC | PPC_TLBIVA | PPC_MFTB |
+ PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
+ PPC_440_SPEC;
+ pcc->msr_mask = 0x000000000006FF30ULL;
+ pcc->mmu_model = POWERPC_MMU_BOOKE;
+ pcc->excp_model = POWERPC_EXCP_BOOKE;
+ pcc->bus_model = PPC_FLAGS_INPUT_BookE;
+ pcc->bfd_mach = bfd_mach_ppc_403;
+ pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
+ POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
+}
-__attribute__ (( unused ))
static void init_proc_440x4 (CPUPPCState *env)
{
/* Time base */
@@ -3760,23 +3660,29 @@ static void init_proc_440x4 (CPUPPCState *env)
SET_WDT_PERIOD(20, 24, 28, 32);
}
-/* PowerPC 440x5 */
-#define POWERPC_INSNS_440x5 (PPC_INSNS_BASE | PPC_STRING | \
- PPC_DCR | PPC_WRTEE | PPC_RFMCI | \
- PPC_CACHE | PPC_CACHE_ICBI | \
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \
- PPC_MEM_TLBSYNC | PPC_MFTB | \
- PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | \
- PPC_440_SPEC)
-#define POWERPC_INSNS2_440x5 (PPC_NONE)
-#define POWERPC_MSRM_440x5 (0x000000000006FF30ULL)
-#define POWERPC_MMU_440x5 (POWERPC_MMU_BOOKE)
-#define POWERPC_EXCP_440x5 (POWERPC_EXCP_BOOKE)
-#define POWERPC_INPUT_440x5 (PPC_FLAGS_INPUT_BookE)
-#define POWERPC_BFDM_440x5 (bfd_mach_ppc_403)
-#define POWERPC_FLAG_440x5 (POWERPC_FLAG_CE | POWERPC_FLAG_DWE | \
- POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK)
-#define check_pow_440x5 check_pow_nocheck
+POWERPC_FAMILY(440x4)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 440x4";
+ pcc->init_proc = init_proc_440x4;
+ pcc->check_pow = check_pow_nocheck;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
+ PPC_DCR | PPC_WRTEE |
+ PPC_CACHE | PPC_CACHE_ICBI |
+ PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
+ PPC_MEM_TLBSYNC | PPC_MFTB |
+ PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
+ PPC_440_SPEC;
+ pcc->msr_mask = 0x000000000006FF30ULL;
+ pcc->mmu_model = POWERPC_MMU_BOOKE;
+ pcc->excp_model = POWERPC_EXCP_BOOKE;
+ pcc->bus_model = PPC_FLAGS_INPUT_BookE;
+ pcc->bfd_mach = bfd_mach_ppc_403;
+ pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
+ POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
+}
static void init_proc_440x5 (CPUPPCState *env)
{
@@ -3844,26 +3750,30 @@ static void init_proc_440x5 (CPUPPCState *env)
SET_WDT_PERIOD(20, 24, 28, 32);
}
-/* PowerPC 460 (guessed) */
-#define POWERPC_INSNS_460 (PPC_INSNS_BASE | PPC_STRING | \
- PPC_DCR | PPC_DCRX | PPC_DCRUX | \
- PPC_WRTEE | PPC_MFAPIDI | PPC_MFTB | \
- PPC_CACHE | PPC_CACHE_ICBI | \
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \
- PPC_MEM_TLBSYNC | PPC_TLBIVA | \
- PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | \
- PPC_440_SPEC)
-#define POWERPC_INSNS2_460 (PPC_NONE)
-#define POWERPC_MSRM_460 (0x000000000006FF30ULL)
-#define POWERPC_MMU_460 (POWERPC_MMU_BOOKE)
-#define POWERPC_EXCP_460 (POWERPC_EXCP_BOOKE)
-#define POWERPC_INPUT_460 (PPC_FLAGS_INPUT_BookE)
-#define POWERPC_BFDM_460 (bfd_mach_ppc_403)
-#define POWERPC_FLAG_460 (POWERPC_FLAG_CE | POWERPC_FLAG_DWE | \
- POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK)
-#define check_pow_460 check_pow_nocheck
+POWERPC_FAMILY(440x5)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 440x5";
+ pcc->init_proc = init_proc_440x5;
+ pcc->check_pow = check_pow_nocheck;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
+ PPC_DCR | PPC_WRTEE | PPC_RFMCI |
+ PPC_CACHE | PPC_CACHE_ICBI |
+ PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
+ PPC_MEM_TLBSYNC | PPC_MFTB |
+ PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
+ PPC_440_SPEC;
+ pcc->msr_mask = 0x000000000006FF30ULL;
+ pcc->mmu_model = POWERPC_MMU_BOOKE;
+ pcc->excp_model = POWERPC_EXCP_BOOKE;
+ pcc->bus_model = PPC_FLAGS_INPUT_BookE;
+ pcc->bfd_mach = bfd_mach_ppc_403;
+ pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
+ POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
+}
-__attribute__ (( unused ))
static void init_proc_460 (CPUPPCState *env)
{
/* Time base */
@@ -3935,29 +3845,31 @@ static void init_proc_460 (CPUPPCState *env)
SET_WDT_PERIOD(20, 24, 28, 32);
}
-/* PowerPC 460F (guessed) */
-#define POWERPC_INSNS_460F (PPC_INSNS_BASE | PPC_STRING | \
- PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL | \
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | \
- PPC_FLOAT_STFIWX | PPC_MFTB | \
- PPC_DCR | PPC_DCRX | PPC_DCRUX | \
- PPC_WRTEE | PPC_MFAPIDI | \
- PPC_CACHE | PPC_CACHE_ICBI | \
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \
- PPC_MEM_TLBSYNC | PPC_TLBIVA | \
- PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | \
- PPC_440_SPEC)
-#define POWERPC_INSNS2_460F (PPC_NONE)
-#define POWERPC_MSRM_460 (0x000000000006FF30ULL)
-#define POWERPC_MMU_460F (POWERPC_MMU_BOOKE)
-#define POWERPC_EXCP_460F (POWERPC_EXCP_BOOKE)
-#define POWERPC_INPUT_460F (PPC_FLAGS_INPUT_BookE)
-#define POWERPC_BFDM_460F (bfd_mach_ppc_403)
-#define POWERPC_FLAG_460F (POWERPC_FLAG_CE | POWERPC_FLAG_DWE | \
- POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK)
-#define check_pow_460F check_pow_nocheck
+POWERPC_FAMILY(460)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 460 (guessed)";
+ pcc->init_proc = init_proc_460;
+ pcc->check_pow = check_pow_nocheck;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
+ PPC_DCR | PPC_DCRX | PPC_DCRUX |
+ PPC_WRTEE | PPC_MFAPIDI | PPC_MFTB |
+ PPC_CACHE | PPC_CACHE_ICBI |
+ PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
+ PPC_MEM_TLBSYNC | PPC_TLBIVA |
+ PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
+ PPC_440_SPEC;
+ pcc->msr_mask = 0x000000000006FF30ULL;
+ pcc->mmu_model = POWERPC_MMU_BOOKE;
+ pcc->excp_model = POWERPC_EXCP_BOOKE;
+ pcc->bus_model = PPC_FLAGS_INPUT_BookE;
+ pcc->bfd_mach = bfd_mach_ppc_403;
+ pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
+ POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
+}
-__attribute__ (( unused ))
static void init_proc_460F (CPUPPCState *env)
{
/* Time base */
@@ -4029,22 +3941,34 @@ static void init_proc_460F (CPUPPCState *env)
SET_WDT_PERIOD(20, 24, 28, 32);
}
-/* Freescale 5xx cores (aka RCPU) */
-#define POWERPC_INSNS_MPC5xx (PPC_INSNS_BASE | PPC_STRING | \
- PPC_MEM_EIEIO | PPC_MEM_SYNC | \
- PPC_CACHE_ICBI | PPC_FLOAT | PPC_FLOAT_STFIWX | \
- PPC_MFTB)
-#define POWERPC_INSNS2_MPC5xx (PPC_NONE)
-#define POWERPC_MSRM_MPC5xx (0x000000000001FF43ULL)
-#define POWERPC_MMU_MPC5xx (POWERPC_MMU_REAL)
-#define POWERPC_EXCP_MPC5xx (POWERPC_EXCP_603)
-#define POWERPC_INPUT_MPC5xx (PPC_FLAGS_INPUT_RCPU)
-#define POWERPC_BFDM_MPC5xx (bfd_mach_ppc_505)
-#define POWERPC_FLAG_MPC5xx (POWERPC_FLAG_SE | POWERPC_FLAG_BE | \
- POWERPC_FLAG_BUS_CLK)
-#define check_pow_MPC5xx check_pow_none
+POWERPC_FAMILY(460F)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 460F (guessed)";
+ pcc->init_proc = init_proc_460F;
+ pcc->check_pow = check_pow_nocheck;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
+ PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL |
+ PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
+ PPC_FLOAT_STFIWX | PPC_MFTB |
+ PPC_DCR | PPC_DCRX | PPC_DCRUX |
+ PPC_WRTEE | PPC_MFAPIDI |
+ PPC_CACHE | PPC_CACHE_ICBI |
+ PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
+ PPC_MEM_TLBSYNC | PPC_TLBIVA |
+ PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
+ PPC_440_SPEC;
+ pcc->msr_mask = 0x000000000006FF30ULL;
+ pcc->mmu_model = POWERPC_MMU_BOOKE;
+ pcc->excp_model = POWERPC_EXCP_BOOKE;
+ pcc->bus_model = PPC_FLAGS_INPUT_BookE;
+ pcc->bfd_mach = bfd_mach_ppc_403;
+ pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
+ POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
+}
-__attribute__ (( unused ))
static void init_proc_MPC5xx (CPUPPCState *env)
{
/* Time base */
@@ -4057,21 +3981,27 @@ static void init_proc_MPC5xx (CPUPPCState *env)
/* XXX: TODO: allocate internal IRQ controller */
}
-/* Freescale 8xx cores (aka PowerQUICC) */
-#define POWERPC_INSNS_MPC8xx (PPC_INSNS_BASE | PPC_STRING | \
- PPC_MEM_EIEIO | PPC_MEM_SYNC | \
- PPC_CACHE_ICBI | PPC_MFTB)
-#define POWERPC_INSNS2_MPC8xx (PPC_NONE)
-#define POWERPC_MSRM_MPC8xx (0x000000000001F673ULL)
-#define POWERPC_MMU_MPC8xx (POWERPC_MMU_MPC8xx)
-#define POWERPC_EXCP_MPC8xx (POWERPC_EXCP_603)
-#define POWERPC_INPUT_MPC8xx (PPC_FLAGS_INPUT_RCPU)
-#define POWERPC_BFDM_MPC8xx (bfd_mach_ppc_860)
-#define POWERPC_FLAG_MPC8xx (POWERPC_FLAG_SE | POWERPC_FLAG_BE | \
- POWERPC_FLAG_BUS_CLK)
-#define check_pow_MPC8xx check_pow_none
+POWERPC_FAMILY(MPC5xx)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "Freescale 5xx cores (aka RCPU)";
+ pcc->init_proc = init_proc_MPC5xx;
+ pcc->check_pow = check_pow_none;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
+ PPC_MEM_EIEIO | PPC_MEM_SYNC |
+ PPC_CACHE_ICBI | PPC_FLOAT | PPC_FLOAT_STFIWX |
+ PPC_MFTB;
+ pcc->msr_mask = 0x000000000001FF43ULL;
+ pcc->mmu_model = POWERPC_MMU_REAL;
+ pcc->excp_model = POWERPC_EXCP_603;
+ pcc->bus_model = PPC_FLAGS_INPUT_RCPU;
+ pcc->bfd_mach = bfd_mach_ppc_505;
+ pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
+ POWERPC_FLAG_BUS_CLK;
+}
-__attribute__ (( unused ))
static void init_proc_MPC8xx (CPUPPCState *env)
{
/* Time base */
@@ -4084,24 +4014,27 @@ static void init_proc_MPC8xx (CPUPPCState *env)
/* XXX: TODO: allocate internal IRQ controller */
}
+POWERPC_FAMILY(MPC8xx)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "Freescale 8xx cores (aka PowerQUICC)";
+ pcc->init_proc = init_proc_MPC8xx;
+ pcc->check_pow = check_pow_none;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
+ PPC_MEM_EIEIO | PPC_MEM_SYNC |
+ PPC_CACHE_ICBI | PPC_MFTB;
+ pcc->msr_mask = 0x000000000001F673ULL;
+ pcc->mmu_model = POWERPC_MMU_MPC8xx;
+ pcc->excp_model = POWERPC_EXCP_603;
+ pcc->bus_model = PPC_FLAGS_INPUT_RCPU;
+ pcc->bfd_mach = bfd_mach_ppc_860;
+ pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
+ POWERPC_FLAG_BUS_CLK;
+}
+
/* Freescale 82xx cores (aka PowerQUICC-II) */
-/* PowerPC G2 */
-#define POWERPC_INSNS_G2 (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | \
- PPC_SEGMENT | PPC_EXTERN)
-#define POWERPC_INSNS2_G2 (PPC_NONE)
-#define POWERPC_MSRM_G2 (0x000000000006FFF2ULL)
-#define POWERPC_MMU_G2 (POWERPC_MMU_SOFT_6xx)
-//#define POWERPC_EXCP_G2 (POWERPC_EXCP_G2)
-#define POWERPC_INPUT_G2 (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_G2 (bfd_mach_ppc_ec603e)
-#define POWERPC_FLAG_G2 (POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | \
- POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK)
-#define check_pow_G2 check_pow_hid0
static void init_proc_G2 (CPUPPCState *env)
{
@@ -4143,23 +4076,29 @@ static void init_proc_G2 (CPUPPCState *env)
ppc6xx_irq_init(env);
}
-/* PowerPC G2LE */
-#define POWERPC_INSNS_G2LE (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | \
- PPC_SEGMENT | PPC_EXTERN)
-#define POWERPC_INSNS2_G2LE (PPC_NONE)
-#define POWERPC_MSRM_G2LE (0x000000000007FFF3ULL)
-#define POWERPC_MMU_G2LE (POWERPC_MMU_SOFT_6xx)
-#define POWERPC_EXCP_G2LE (POWERPC_EXCP_G2)
-#define POWERPC_INPUT_G2LE (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_G2LE (bfd_mach_ppc_ec603e)
-#define POWERPC_FLAG_G2LE (POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | \
- POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK)
-#define check_pow_G2LE check_pow_hid0
+POWERPC_FAMILY(G2)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC G2";
+ pcc->init_proc = init_proc_G2;
+ pcc->check_pow = check_pow_hid0;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
+ PPC_SEGMENT | PPC_EXTERN;
+ pcc->msr_mask = 0x000000000006FFF2ULL;
+ pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
+ pcc->excp_model = POWERPC_EXCP_G2;
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_ec603e;
+ pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
+ POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
+}
static void init_proc_G2LE (CPUPPCState *env)
{
@@ -4190,6 +4129,33 @@ static void init_proc_G2LE (CPUPPCState *env)
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
+ /* Breakpoints */
+ /* XXX : not implemented */
+ spr_register(env, SPR_DABR, "DABR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ /* XXX : not implemented */
+ spr_register(env, SPR_DABR2, "DABR2",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ /* XXX : not implemented */
+ spr_register(env, SPR_IABR2, "IABR2",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ /* XXX : not implemented */
+ spr_register(env, SPR_IBCR, "IBCR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ /* XXX : not implemented */
+ spr_register(env, SPR_DBCR, "DBCR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+
/* Memory management */
gen_low_BATs(env);
gen_high_BATs(env);
@@ -4201,35 +4167,30 @@ static void init_proc_G2LE (CPUPPCState *env)
ppc6xx_irq_init(env);
}
-/* e200 core */
-/* XXX: unimplemented instructions:
- * dcblc
- * dcbtlst
- * dcbtstls
- * icblc
- * icbtls
- * tlbivax
- * all SPE multiply-accumulate instructions
- */
-#define POWERPC_INSNS_e200 (PPC_INSNS_BASE | PPC_ISEL | \
- PPC_SPE | PPC_SPE_SINGLE | \
- PPC_WRTEE | PPC_RFDI | \
- PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | \
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \
- PPC_MEM_TLBSYNC | PPC_TLBIVAX | \
- PPC_BOOKE)
-#define POWERPC_INSNS2_e200 (PPC_NONE)
-#define POWERPC_MSRM_e200 (0x000000000606FF30ULL)
-#define POWERPC_MMU_e200 (POWERPC_MMU_BOOKE206)
-#define POWERPC_EXCP_e200 (POWERPC_EXCP_BOOKE)
-#define POWERPC_INPUT_e200 (PPC_FLAGS_INPUT_BookE)
-#define POWERPC_BFDM_e200 (bfd_mach_ppc_860)
-#define POWERPC_FLAG_e200 (POWERPC_FLAG_SPE | POWERPC_FLAG_CE | \
- POWERPC_FLAG_UBLE | POWERPC_FLAG_DE | \
- POWERPC_FLAG_BUS_CLK)
-#define check_pow_e200 check_pow_hid0
+POWERPC_FAMILY(G2LE)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC G2LE";
+ pcc->init_proc = init_proc_G2LE;
+ pcc->check_pow = check_pow_hid0;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
+ PPC_SEGMENT | PPC_EXTERN;
+ pcc->msr_mask = 0x000000000007FFF3ULL;
+ pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
+ pcc->excp_model = POWERPC_EXCP_G2;
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_ec603e;
+ pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
+ POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
+}
-__attribute__ (( unused ))
static void init_proc_e200 (CPUPPCState *env)
{
/* Time base */
@@ -4337,25 +4298,40 @@ static void init_proc_e200 (CPUPPCState *env)
/* XXX: TODO: allocate internal IRQ controller */
}
-/* e300 core */
-#define POWERPC_INSNS_e300 (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | \
- PPC_SEGMENT | PPC_EXTERN)
-#define POWERPC_INSNS2_e300 (PPC_NONE)
-#define POWERPC_MSRM_e300 (0x000000000007FFF3ULL)
-#define POWERPC_MMU_e300 (POWERPC_MMU_SOFT_6xx)
-#define POWERPC_EXCP_e300 (POWERPC_EXCP_603)
-#define POWERPC_INPUT_e300 (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_e300 (bfd_mach_ppc_603)
-#define POWERPC_FLAG_e300 (POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | \
- POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK)
-#define check_pow_e300 check_pow_hid0
+POWERPC_FAMILY(e200)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "e200 core";
+ pcc->init_proc = init_proc_e200;
+ pcc->check_pow = check_pow_hid0;
+ /* XXX: unimplemented instructions:
+ * dcblc
+ * dcbtlst
+ * dcbtstls
+ * icblc
+ * icbtls
+ * tlbivax
+ * all SPE multiply-accumulate instructions
+ */
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
+ PPC_SPE | PPC_SPE_SINGLE |
+ PPC_WRTEE | PPC_RFDI |
+ PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
+ PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
+ PPC_MEM_TLBSYNC | PPC_TLBIVAX |
+ PPC_BOOKE;
+ pcc->msr_mask = 0x000000000606FF30ULL;
+ pcc->mmu_model = POWERPC_MMU_BOOKE206;
+ pcc->excp_model = POWERPC_EXCP_BOOKE;
+ pcc->bus_model = PPC_FLAGS_INPUT_BookE;
+ pcc->bfd_mach = bfd_mach_ppc_860;
+ pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
+ POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
+ POWERPC_FLAG_BUS_CLK;
+}
-__attribute__ (( unused ))
static void init_proc_e300 (CPUPPCState *env)
{
gen_spr_ne_601(env);
@@ -4389,86 +4365,29 @@ static void init_proc_e300 (CPUPPCState *env)
ppc6xx_irq_init(env);
}
-/* e500v1 core */
-#define POWERPC_INSNS_e500v1 (PPC_INSNS_BASE | PPC_ISEL | \
- PPC_SPE | PPC_SPE_SINGLE | \
- PPC_WRTEE | PPC_RFDI | \
- PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | \
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \
- PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC)
-#define POWERPC_INSNS2_e500v1 (PPC2_BOOKE206)
-#define POWERPC_MSRM_e500v1 (0x000000000606FF30ULL)
-#define POWERPC_MMU_e500v1 (POWERPC_MMU_BOOKE206)
-#define POWERPC_EXCP_e500v1 (POWERPC_EXCP_BOOKE)
-#define POWERPC_INPUT_e500v1 (PPC_FLAGS_INPUT_BookE)
-#define POWERPC_BFDM_e500v1 (bfd_mach_ppc_860)
-#define POWERPC_FLAG_e500v1 (POWERPC_FLAG_SPE | POWERPC_FLAG_CE | \
- POWERPC_FLAG_UBLE | POWERPC_FLAG_DE | \
- POWERPC_FLAG_BUS_CLK)
-#define check_pow_e500v1 check_pow_hid0
-#define init_proc_e500v1 init_proc_e500v1
-
-/* e500v2 core */
-#define POWERPC_INSNS_e500v2 (PPC_INSNS_BASE | PPC_ISEL | \
- PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE | \
- PPC_WRTEE | PPC_RFDI | \
- PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | \
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \
- PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC)
-#define POWERPC_INSNS2_e500v2 (PPC2_BOOKE206)
-#define POWERPC_MSRM_e500v2 (0x000000000606FF30ULL)
-#define POWERPC_MMU_e500v2 (POWERPC_MMU_BOOKE206)
-#define POWERPC_EXCP_e500v2 (POWERPC_EXCP_BOOKE)
-#define POWERPC_INPUT_e500v2 (PPC_FLAGS_INPUT_BookE)
-#define POWERPC_BFDM_e500v2 (bfd_mach_ppc_860)
-#define POWERPC_FLAG_e500v2 (POWERPC_FLAG_SPE | POWERPC_FLAG_CE | \
- POWERPC_FLAG_UBLE | POWERPC_FLAG_DE | \
- POWERPC_FLAG_BUS_CLK)
-#define check_pow_e500v2 check_pow_hid0
-#define init_proc_e500v2 init_proc_e500v2
-
-/* e500mc core */
-#define POWERPC_INSNS_e500mc (PPC_INSNS_BASE | PPC_ISEL | \
- PPC_WRTEE | PPC_RFDI | PPC_RFMCI | \
- PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | \
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \
- PPC_FLOAT | PPC_FLOAT_FRES | \
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL | \
- PPC_FLOAT_STFIWX | PPC_WAIT | \
- PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC)
-#define POWERPC_INSNS2_e500mc (PPC2_BOOKE206 | PPC2_PRCNTL)
-#define POWERPC_MSRM_e500mc (0x000000001402FB36ULL)
-#define POWERPC_MMU_e500mc (POWERPC_MMU_BOOKE206)
-#define POWERPC_EXCP_e500mc (POWERPC_EXCP_BOOKE)
-#define POWERPC_INPUT_e500mc (PPC_FLAGS_INPUT_BookE)
-/* Fixme: figure out the correct flag for e500mc */
-#define POWERPC_BFDM_e500mc (bfd_mach_ppc_e500)
-#define POWERPC_FLAG_e500mc (POWERPC_FLAG_CE | POWERPC_FLAG_DE | \
- POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK)
-#define check_pow_e500mc check_pow_none
-#define init_proc_e500mc init_proc_e500mc
-
-/* e5500 core */
-#define POWERPC_INSNS_e5500 (PPC_INSNS_BASE | PPC_ISEL | \
- PPC_WRTEE | PPC_RFDI | PPC_RFMCI | \
- PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | \
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \
- PPC_FLOAT | PPC_FLOAT_FRES | \
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL | \
- PPC_FLOAT_STFIWX | PPC_WAIT | \
- PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC | \
- PPC_64B | PPC_POPCNTB | PPC_POPCNTWD)
-#define POWERPC_INSNS2_e5500 (PPC2_BOOKE206 | PPC2_PRCNTL)
-#define POWERPC_MSRM_e5500 (0x000000009402FB36ULL)
-#define POWERPC_MMU_e5500 (POWERPC_MMU_BOOKE206)
-#define POWERPC_EXCP_e5500 (POWERPC_EXCP_BOOKE)
-#define POWERPC_INPUT_e5500 (PPC_FLAGS_INPUT_BookE)
-/* Fixme: figure out the correct flag for e5500 */
-#define POWERPC_BFDM_e5500 (bfd_mach_ppc_e500)
-#define POWERPC_FLAG_e5500 (POWERPC_FLAG_CE | POWERPC_FLAG_DE | \
- POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK)
-#define check_pow_e5500 check_pow_none
-#define init_proc_e5500 init_proc_e5500
+POWERPC_FAMILY(e300)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "e300 core";
+ pcc->init_proc = init_proc_e300;
+ pcc->check_pow = check_pow_hid0;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
+ PPC_SEGMENT | PPC_EXTERN;
+ pcc->msr_mask = 0x000000000007FFF3ULL;
+ pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
+ pcc->excp_model = POWERPC_EXCP_603;
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_603;
+ pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
+ POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
+}
#if !defined(CONFIG_USER_ONLY)
static void spr_write_mas73(void *opaque, int sprn, int gprn)
@@ -4493,11 +4412,6 @@ static void spr_read_mas73(void *opaque, int gprn, int sprn)
tcg_temp_free(mas7);
}
-static void spr_load_epr(void *opaque, int gprn, int sprn)
-{
- gen_helper_load_epr(cpu_gpr[gprn], cpu_env);
-}
-
#endif
enum fsl_e500_version {
@@ -4656,7 +4570,7 @@ static void init_proc_e500 (CPUPPCState *env, int version)
0x00000000);
spr_register(env, SPR_BOOKE_EPR, "EPR",
SPR_NOACCESS, SPR_NOACCESS,
- &spr_load_epr, SPR_NOACCESS,
+ &spr_read_generic, SPR_NOACCESS,
0x00000000);
/* XXX better abstract into Emb.xxx features */
if (version == fsl_e5500) {
@@ -4689,47 +4603,143 @@ static void init_proc_e500v1(CPUPPCState *env)
init_proc_e500(env, fsl_e500v1);
}
+POWERPC_FAMILY(e500v1)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "e500v1 core";
+ pcc->init_proc = init_proc_e500v1;
+ pcc->check_pow = check_pow_hid0;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
+ PPC_SPE | PPC_SPE_SINGLE |
+ PPC_WRTEE | PPC_RFDI |
+ PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
+ PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
+ PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
+ pcc->insns_flags2 = PPC2_BOOKE206;
+ pcc->msr_mask = 0x000000000606FF30ULL;
+ pcc->mmu_model = POWERPC_MMU_BOOKE206;
+ pcc->excp_model = POWERPC_EXCP_BOOKE;
+ pcc->bus_model = PPC_FLAGS_INPUT_BookE;
+ pcc->bfd_mach = bfd_mach_ppc_860;
+ pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
+ POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
+ POWERPC_FLAG_BUS_CLK;
+}
+
static void init_proc_e500v2(CPUPPCState *env)
{
init_proc_e500(env, fsl_e500v2);
}
+POWERPC_FAMILY(e500v2)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "e500v2 core";
+ pcc->init_proc = init_proc_e500v2;
+ pcc->check_pow = check_pow_hid0;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
+ PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE |
+ PPC_WRTEE | PPC_RFDI |
+ PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
+ PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
+ PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
+ pcc->insns_flags2 = PPC2_BOOKE206;
+ pcc->msr_mask = 0x000000000606FF30ULL;
+ pcc->mmu_model = POWERPC_MMU_BOOKE206;
+ pcc->excp_model = POWERPC_EXCP_BOOKE;
+ pcc->bus_model = PPC_FLAGS_INPUT_BookE;
+ pcc->bfd_mach = bfd_mach_ppc_860;
+ pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
+ POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
+ POWERPC_FLAG_BUS_CLK;
+}
+
static void init_proc_e500mc(CPUPPCState *env)
{
init_proc_e500(env, fsl_e500mc);
}
+POWERPC_FAMILY(e500mc)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "e500mc core";
+ pcc->init_proc = init_proc_e500mc;
+ pcc->check_pow = check_pow_none;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
+ PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
+ PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
+ PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
+ PPC_FLOAT | PPC_FLOAT_FRES |
+ PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
+ PPC_FLOAT_STFIWX | PPC_WAIT |
+ PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
+ pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL;
+ pcc->msr_mask = 0x000000001402FB36ULL;
+ pcc->mmu_model = POWERPC_MMU_BOOKE206;
+ pcc->excp_model = POWERPC_EXCP_BOOKE;
+ pcc->bus_model = PPC_FLAGS_INPUT_BookE;
+ /* FIXME: figure out the correct flag for e500mc */
+ pcc->bfd_mach = bfd_mach_ppc_e500;
+ pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
+ POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
+}
+
#ifdef TARGET_PPC64
static void init_proc_e5500(CPUPPCState *env)
{
init_proc_e500(env, fsl_e5500);
}
+
+POWERPC_FAMILY(e5500)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "e5500 core";
+ pcc->init_proc = init_proc_e5500;
+ pcc->check_pow = check_pow_none;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
+ PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
+ PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
+ PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
+ PPC_FLOAT | PPC_FLOAT_FRES |
+ PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
+ PPC_FLOAT_STFIWX | PPC_WAIT |
+ PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC |
+ PPC_64B | PPC_POPCNTB | PPC_POPCNTWD;
+ pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL;
+ pcc->msr_mask = 0x000000009402FB36ULL;
+ pcc->mmu_model = POWERPC_MMU_BOOKE206;
+ pcc->excp_model = POWERPC_EXCP_BOOKE;
+ pcc->bus_model = PPC_FLAGS_INPUT_BookE;
+ /* FIXME: figure out the correct flag for e5500 */
+ pcc->bfd_mach = bfd_mach_ppc_e500;
+ pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
+ POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
+}
#endif
/* Non-embedded PowerPC */
/* POWER : same as 601, without mfmsr, mfsr */
-#if defined(TODO)
-#define POWERPC_INSNS_POWER (XXX_TODO)
-/* POWER RSC (from RAD6000) */
-#define POWERPC_MSRM_POWER (0x00000000FEF0ULL)
-#endif /* TODO */
-
-/* PowerPC 601 */
-#define POWERPC_INSNS_601 (PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR | \
- PPC_FLOAT | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | \
- PPC_SEGMENT | PPC_EXTERN)
-#define POWERPC_INSNS2_601 (PPC_NONE)
-#define POWERPC_MSRM_601 (0x000000000000FD70ULL)
+POWERPC_FAMILY(POWER)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "POWER";
+ /* pcc->insns_flags = XXX_TODO; */
+ /* POWER RSC (from RAD6000) */
+ pcc->msr_mask = 0x00000000FEF0ULL;
+}
+
#define POWERPC_MSRR_601 (0x0000000000001040ULL)
-//#define POWERPC_MMU_601 (POWERPC_MMU_601)
-//#define POWERPC_EXCP_601 (POWERPC_EXCP_601)
-#define POWERPC_INPUT_601 (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_601 (bfd_mach_ppc_601)
-#define POWERPC_FLAG_601 (POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK)
-#define check_pow_601 check_pow_none
static void init_proc_601 (CPUPPCState *env)
{
@@ -4768,21 +4778,31 @@ static void init_proc_601 (CPUPPCState *env)
ppc6xx_irq_init(env);
}
-/* PowerPC 601v */
-#define POWERPC_INSNS_601v (PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR | \
- PPC_FLOAT | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | \
- PPC_SEGMENT | PPC_EXTERN)
-#define POWERPC_INSNS2_601v (PPC_NONE)
-#define POWERPC_MSRM_601v (0x000000000000FD70ULL)
+POWERPC_FAMILY(601)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 601";
+ pcc->init_proc = init_proc_601;
+ pcc->check_pow = check_pow_none;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
+ PPC_FLOAT |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
+ PPC_SEGMENT | PPC_EXTERN;
+ pcc->msr_mask = 0x000000000000FD70ULL;
+ pcc->mmu_model = POWERPC_MMU_601;
+#if defined(CONFIG_SOFTMMU)
+ pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
+#endif
+ pcc->excp_model = POWERPC_EXCP_601;
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_601;
+ pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK;
+}
+
#define POWERPC_MSRR_601v (0x0000000000001040ULL)
-#define POWERPC_MMU_601v (POWERPC_MMU_601)
-#define POWERPC_EXCP_601v (POWERPC_EXCP_601)
-#define POWERPC_INPUT_601v (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_601v (bfd_mach_ppc_601)
-#define POWERPC_FLAG_601v (POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK)
-#define check_pow_601v check_pow_none
static void init_proc_601v (CPUPPCState *env)
{
@@ -4794,24 +4814,28 @@ static void init_proc_601v (CPUPPCState *env)
0x00000000);
}
-/* PowerPC 602 */
-#define POWERPC_INSNS_602 (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_6xx_TLB | PPC_MEM_TLBSYNC | \
- PPC_SEGMENT | PPC_602_SPEC)
-#define POWERPC_INSNS2_602 (PPC_NONE)
-#define POWERPC_MSRM_602 (0x0000000000C7FF73ULL)
-/* XXX: 602 MMU is quite specific. Should add a special case */
-#define POWERPC_MMU_602 (POWERPC_MMU_SOFT_6xx)
-//#define POWERPC_EXCP_602 (POWERPC_EXCP_602)
-#define POWERPC_INPUT_602 (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_602 (bfd_mach_ppc_602)
-#define POWERPC_FLAG_602 (POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | \
- POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK)
-#define check_pow_602 check_pow_hid0
+POWERPC_FAMILY(601v)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 601v";
+ pcc->init_proc = init_proc_601v;
+ pcc->check_pow = check_pow_none;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
+ PPC_FLOAT |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
+ PPC_SEGMENT | PPC_EXTERN;
+ pcc->msr_mask = 0x000000000000FD70ULL;
+ pcc->mmu_model = POWERPC_MMU_601;
+#if defined(CONFIG_SOFTMMU)
+ pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
+#endif
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_601;
+ pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK;
+}
static void init_proc_602 (CPUPPCState *env)
{
@@ -4840,23 +4864,30 @@ static void init_proc_602 (CPUPPCState *env)
ppc6xx_irq_init(env);
}
-/* PowerPC 603 */
-#define POWERPC_INSNS_603 (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | \
- PPC_SEGMENT | PPC_EXTERN)
-#define POWERPC_INSNS2_603 (PPC_NONE)
-#define POWERPC_MSRM_603 (0x000000000007FF73ULL)
-#define POWERPC_MMU_603 (POWERPC_MMU_SOFT_6xx)
-//#define POWERPC_EXCP_603 (POWERPC_EXCP_603)
-#define POWERPC_INPUT_603 (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_603 (bfd_mach_ppc_603)
-#define POWERPC_FLAG_603 (POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | \
- POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK)
-#define check_pow_603 check_pow_hid0
+POWERPC_FAMILY(602)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 602";
+ pcc->init_proc = init_proc_602;
+ pcc->check_pow = check_pow_hid0;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_6xx_TLB | PPC_MEM_TLBSYNC |
+ PPC_SEGMENT | PPC_602_SPEC;
+ pcc->msr_mask = 0x0000000000C7FF73ULL;
+ /* XXX: 602 MMU is quite specific. Should add a special case */
+ pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
+ pcc->excp_model = POWERPC_EXCP_602;
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_602;
+ pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
+ POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
+}
static void init_proc_603 (CPUPPCState *env)
{
@@ -4885,23 +4916,29 @@ static void init_proc_603 (CPUPPCState *env)
ppc6xx_irq_init(env);
}
-/* PowerPC 603e */
-#define POWERPC_INSNS_603E (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | \
- PPC_SEGMENT | PPC_EXTERN)
-#define POWERPC_INSNS2_603E (PPC_NONE)
-#define POWERPC_MSRM_603E (0x000000000007FF73ULL)
-#define POWERPC_MMU_603E (POWERPC_MMU_SOFT_6xx)
-//#define POWERPC_EXCP_603E (POWERPC_EXCP_603E)
-#define POWERPC_INPUT_603E (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_603E (bfd_mach_ppc_ec603e)
-#define POWERPC_FLAG_603E (POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | \
- POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK)
-#define check_pow_603E check_pow_hid0
+POWERPC_FAMILY(603)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 603";
+ pcc->init_proc = init_proc_603;
+ pcc->check_pow = check_pow_hid0;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
+ PPC_SEGMENT | PPC_EXTERN;
+ pcc->msr_mask = 0x000000000007FF73ULL;
+ pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
+ pcc->excp_model = POWERPC_EXCP_603;
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_603;
+ pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
+ POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
+}
static void init_proc_603E (CPUPPCState *env)
{
@@ -4920,11 +4957,6 @@ static void init_proc_603E (CPUPPCState *env)
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_IABR, "IABR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
/* Memory management */
gen_low_BATs(env);
gen_6xx_7xx_soft_tlb(env, 64, 2);
@@ -4935,23 +4967,29 @@ static void init_proc_603E (CPUPPCState *env)
ppc6xx_irq_init(env);
}
-/* PowerPC 604 */
-#define POWERPC_INSNS_604 (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \
- PPC_SEGMENT | PPC_EXTERN)
-#define POWERPC_INSNS2_604 (PPC_NONE)
-#define POWERPC_MSRM_604 (0x000000000005FF77ULL)
-#define POWERPC_MMU_604 (POWERPC_MMU_32B)
-//#define POWERPC_EXCP_604 (POWERPC_EXCP_604)
-#define POWERPC_INPUT_604 (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_604 (bfd_mach_ppc_604)
-#define POWERPC_FLAG_604 (POWERPC_FLAG_SE | POWERPC_FLAG_BE | \
- POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK)
-#define check_pow_604 check_pow_nocheck
+POWERPC_FAMILY(603E)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 603e";
+ pcc->init_proc = init_proc_603E;
+ pcc->check_pow = check_pow_hid0;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
+ PPC_SEGMENT | PPC_EXTERN;
+ pcc->msr_mask = 0x000000000007FF73ULL;
+ pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
+ pcc->excp_model = POWERPC_EXCP_603E;
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_ec603e;
+ pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
+ POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
+}
static void init_proc_604 (CPUPPCState *env)
{
@@ -4974,23 +5012,32 @@ static void init_proc_604 (CPUPPCState *env)
ppc6xx_irq_init(env);
}
-/* PowerPC 604E */
-#define POWERPC_INSNS_604E (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \
- PPC_SEGMENT | PPC_EXTERN)
-#define POWERPC_INSNS2_604E (PPC_NONE)
-#define POWERPC_MSRM_604E (0x000000000005FF77ULL)
-#define POWERPC_MMU_604E (POWERPC_MMU_32B)
-#define POWERPC_EXCP_604E (POWERPC_EXCP_604)
-#define POWERPC_INPUT_604E (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_604E (bfd_mach_ppc_604)
-#define POWERPC_FLAG_604E (POWERPC_FLAG_SE | POWERPC_FLAG_BE | \
- POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK)
-#define check_pow_604E check_pow_nocheck
+POWERPC_FAMILY(604)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 604";
+ pcc->init_proc = init_proc_604;
+ pcc->check_pow = check_pow_nocheck;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
+ PPC_SEGMENT | PPC_EXTERN;
+ pcc->msr_mask = 0x000000000005FF77ULL;
+ pcc->mmu_model = POWERPC_MMU_32B;
+#if defined(CONFIG_SOFTMMU)
+ pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
+#endif
+ pcc->excp_model = POWERPC_EXCP_604;
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_604;
+ pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
+ POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
+}
static void init_proc_604E (CPUPPCState *env)
{
@@ -5033,23 +5080,32 @@ static void init_proc_604E (CPUPPCState *env)
ppc6xx_irq_init(env);
}
-/* PowerPC 740 */
-#define POWERPC_INSNS_740 (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \
- PPC_SEGMENT | PPC_EXTERN)
-#define POWERPC_INSNS2_740 (PPC_NONE)
-#define POWERPC_MSRM_740 (0x000000000005FF77ULL)
-#define POWERPC_MMU_740 (POWERPC_MMU_32B)
-#define POWERPC_EXCP_740 (POWERPC_EXCP_7x0)
-#define POWERPC_INPUT_740 (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_740 (bfd_mach_ppc_750)
-#define POWERPC_FLAG_740 (POWERPC_FLAG_SE | POWERPC_FLAG_BE | \
- POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK)
-#define check_pow_740 check_pow_hid0
+POWERPC_FAMILY(604E)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 604E";
+ pcc->init_proc = init_proc_604E;
+ pcc->check_pow = check_pow_nocheck;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
+ PPC_SEGMENT | PPC_EXTERN;
+ pcc->msr_mask = 0x000000000005FF77ULL;
+ pcc->mmu_model = POWERPC_MMU_32B;
+#if defined(CONFIG_SOFTMMU)
+ pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
+#endif
+ pcc->excp_model = POWERPC_EXCP_604;
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_604;
+ pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
+ POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
+}
static void init_proc_740 (CPUPPCState *env)
{
@@ -5079,23 +5135,32 @@ static void init_proc_740 (CPUPPCState *env)
ppc6xx_irq_init(env);
}
-/* PowerPC 750 */
-#define POWERPC_INSNS_750 (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \
- PPC_SEGMENT | PPC_EXTERN)
-#define POWERPC_INSNS2_750 (PPC_NONE)
-#define POWERPC_MSRM_750 (0x000000000005FF77ULL)
-#define POWERPC_MMU_750 (POWERPC_MMU_32B)
-#define POWERPC_EXCP_750 (POWERPC_EXCP_7x0)
-#define POWERPC_INPUT_750 (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_750 (bfd_mach_ppc_750)
-#define POWERPC_FLAG_750 (POWERPC_FLAG_SE | POWERPC_FLAG_BE | \
- POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK)
-#define check_pow_750 check_pow_hid0
+POWERPC_FAMILY(740)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 740";
+ pcc->init_proc = init_proc_740;
+ pcc->check_pow = check_pow_hid0;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
+ PPC_SEGMENT | PPC_EXTERN;
+ pcc->msr_mask = 0x000000000005FF77ULL;
+ pcc->mmu_model = POWERPC_MMU_32B;
+#if defined(CONFIG_SOFTMMU)
+ pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
+#endif
+ pcc->excp_model = POWERPC_EXCP_7x0;
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_750;
+ pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
+ POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
+}
static void init_proc_750 (CPUPPCState *env)
{
@@ -5104,7 +5169,7 @@ static void init_proc_750 (CPUPPCState *env)
/* XXX : not implemented */
spr_register(env, SPR_L2CR, "L2CR",
SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_generic, NULL,
0x00000000);
/* Time base */
gen_tbl(env);
@@ -5133,61 +5198,32 @@ static void init_proc_750 (CPUPPCState *env)
ppc6xx_irq_init(env);
}
-/* PowerPC 750 CL */
-/* XXX: not implemented:
- * cache lock instructions:
- * dcbz_l
- * floating point paired instructions
- * psq_lux
- * psq_lx
- * psq_stux
- * psq_stx
- * ps_abs
- * ps_add
- * ps_cmpo0
- * ps_cmpo1
- * ps_cmpu0
- * ps_cmpu1
- * ps_div
- * ps_madd
- * ps_madds0
- * ps_madds1
- * ps_merge00
- * ps_merge01
- * ps_merge10
- * ps_merge11
- * ps_mr
- * ps_msub
- * ps_mul
- * ps_muls0
- * ps_muls1
- * ps_nabs
- * ps_neg
- * ps_nmadd
- * ps_nmsub
- * ps_res
- * ps_rsqrte
- * ps_sel
- * ps_sub
- * ps_sum0
- * ps_sum1
- */
-#define POWERPC_INSNS_750cl (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \
- PPC_SEGMENT | PPC_EXTERN)
-#define POWERPC_INSNS2_750cl (PPC_NONE)
-#define POWERPC_MSRM_750cl (0x000000000005FF77ULL)
-#define POWERPC_MMU_750cl (POWERPC_MMU_32B)
-#define POWERPC_EXCP_750cl (POWERPC_EXCP_7x0)
-#define POWERPC_INPUT_750cl (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_750cl (bfd_mach_ppc_750)
-#define POWERPC_FLAG_750cl (POWERPC_FLAG_SE | POWERPC_FLAG_BE | \
- POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK)
-#define check_pow_750cl check_pow_hid0
+POWERPC_FAMILY(750)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 750";
+ pcc->init_proc = init_proc_750;
+ pcc->check_pow = check_pow_hid0;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
+ PPC_SEGMENT | PPC_EXTERN;
+ pcc->msr_mask = 0x000000000005FF77ULL;
+ pcc->mmu_model = POWERPC_MMU_32B;
+#if defined(CONFIG_SOFTMMU)
+ pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
+#endif
+ pcc->excp_model = POWERPC_EXCP_7x0;
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_750;
+ pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
+ POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
+}
static void init_proc_750cl (CPUPPCState *env)
{
@@ -5196,7 +5232,7 @@ static void init_proc_750cl (CPUPPCState *env)
/* XXX : not implemented */
spr_register(env, SPR_L2CR, "L2CR",
SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_generic, NULL,
0x00000000);
/* Time base */
gen_tbl(env);
@@ -5310,23 +5346,70 @@ static void init_proc_750cl (CPUPPCState *env)
ppc6xx_irq_init(env);
}
-/* PowerPC 750CX */
-#define POWERPC_INSNS_750cx (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \
- PPC_SEGMENT | PPC_EXTERN)
-#define POWERPC_INSNS2_750cx (PPC_NONE)
-#define POWERPC_MSRM_750cx (0x000000000005FF77ULL)
-#define POWERPC_MMU_750cx (POWERPC_MMU_32B)
-#define POWERPC_EXCP_750cx (POWERPC_EXCP_7x0)
-#define POWERPC_INPUT_750cx (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_750cx (bfd_mach_ppc_750)
-#define POWERPC_FLAG_750cx (POWERPC_FLAG_SE | POWERPC_FLAG_BE | \
- POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK)
-#define check_pow_750cx check_pow_hid0
+POWERPC_FAMILY(750cl)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 750 CL";
+ pcc->init_proc = init_proc_750cl;
+ pcc->check_pow = check_pow_hid0;
+ /* XXX: not implemented:
+ * cache lock instructions:
+ * dcbz_l
+ * floating point paired instructions
+ * psq_lux
+ * psq_lx
+ * psq_stux
+ * psq_stx
+ * ps_abs
+ * ps_add
+ * ps_cmpo0
+ * ps_cmpo1
+ * ps_cmpu0
+ * ps_cmpu1
+ * ps_div
+ * ps_madd
+ * ps_madds0
+ * ps_madds1
+ * ps_merge00
+ * ps_merge01
+ * ps_merge10
+ * ps_merge11
+ * ps_mr
+ * ps_msub
+ * ps_mul
+ * ps_muls0
+ * ps_muls1
+ * ps_nabs
+ * ps_neg
+ * ps_nmadd
+ * ps_nmsub
+ * ps_res
+ * ps_rsqrte
+ * ps_sel
+ * ps_sub
+ * ps_sum0
+ * ps_sum1
+ */
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
+ PPC_SEGMENT | PPC_EXTERN;
+ pcc->msr_mask = 0x000000000005FF77ULL;
+ pcc->mmu_model = POWERPC_MMU_32B;
+#if defined(CONFIG_SOFTMMU)
+ pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
+#endif
+ pcc->excp_model = POWERPC_EXCP_7x0;
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_750;
+ pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
+ POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
+}
static void init_proc_750cx (CPUPPCState *env)
{
@@ -5335,7 +5418,7 @@ static void init_proc_750cx (CPUPPCState *env)
/* XXX : not implemented */
spr_register(env, SPR_L2CR, "L2CR",
SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_generic, NULL,
0x00000000);
/* Time base */
gen_tbl(env);
@@ -5368,23 +5451,32 @@ static void init_proc_750cx (CPUPPCState *env)
ppc6xx_irq_init(env);
}
-/* PowerPC 750FX */
-#define POWERPC_INSNS_750fx (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \
- PPC_SEGMENT | PPC_EXTERN)
-#define POWERPC_INSNS2_750fx (PPC_NONE)
-#define POWERPC_MSRM_750fx (0x000000000005FF77ULL)
-#define POWERPC_MMU_750fx (POWERPC_MMU_32B)
-#define POWERPC_EXCP_750fx (POWERPC_EXCP_7x0)
-#define POWERPC_INPUT_750fx (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_750fx (bfd_mach_ppc_750)
-#define POWERPC_FLAG_750fx (POWERPC_FLAG_SE | POWERPC_FLAG_BE | \
- POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK)
-#define check_pow_750fx check_pow_hid0
+POWERPC_FAMILY(750cx)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 750CX";
+ pcc->init_proc = init_proc_750cx;
+ pcc->check_pow = check_pow_hid0;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
+ PPC_SEGMENT | PPC_EXTERN;
+ pcc->msr_mask = 0x000000000005FF77ULL;
+ pcc->mmu_model = POWERPC_MMU_32B;
+#if defined(CONFIG_SOFTMMU)
+ pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
+#endif
+ pcc->excp_model = POWERPC_EXCP_7x0;
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_750;
+ pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
+ POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
+}
static void init_proc_750fx (CPUPPCState *env)
{
@@ -5393,7 +5485,7 @@ static void init_proc_750fx (CPUPPCState *env)
/* XXX : not implemented */
spr_register(env, SPR_L2CR, "L2CR",
SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_generic, NULL,
0x00000000);
/* Time base */
gen_tbl(env);
@@ -5431,23 +5523,32 @@ static void init_proc_750fx (CPUPPCState *env)
ppc6xx_irq_init(env);
}
-/* PowerPC 750GX */
-#define POWERPC_INSNS_750gx (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \
- PPC_SEGMENT | PPC_EXTERN)
-#define POWERPC_INSNS2_750gx (PPC_NONE)
-#define POWERPC_MSRM_750gx (0x000000000005FF77ULL)
-#define POWERPC_MMU_750gx (POWERPC_MMU_32B)
-#define POWERPC_EXCP_750gx (POWERPC_EXCP_7x0)
-#define POWERPC_INPUT_750gx (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_750gx (bfd_mach_ppc_750)
-#define POWERPC_FLAG_750gx (POWERPC_FLAG_SE | POWERPC_FLAG_BE | \
- POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK)
-#define check_pow_750gx check_pow_hid0
+POWERPC_FAMILY(750fx)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 750FX";
+ pcc->init_proc = init_proc_750fx;
+ pcc->check_pow = check_pow_hid0;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
+ PPC_SEGMENT | PPC_EXTERN;
+ pcc->msr_mask = 0x000000000005FF77ULL;
+ pcc->mmu_model = POWERPC_MMU_32B;
+#if defined(CONFIG_SOFTMMU)
+ pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
+#endif
+ pcc->excp_model = POWERPC_EXCP_7x0;
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_750;
+ pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
+ POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
+}
static void init_proc_750gx (CPUPPCState *env)
{
@@ -5456,7 +5557,7 @@ static void init_proc_750gx (CPUPPCState *env)
/* XXX : not implemented (XXX: different from 750fx) */
spr_register(env, SPR_L2CR, "L2CR",
SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_generic, NULL,
0x00000000);
/* Time base */
gen_tbl(env);
@@ -5494,23 +5595,32 @@ static void init_proc_750gx (CPUPPCState *env)
ppc6xx_irq_init(env);
}
-/* PowerPC 745 */
-#define POWERPC_INSNS_745 (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | \
- PPC_SEGMENT | PPC_EXTERN)
-#define POWERPC_INSNS2_745 (PPC_NONE)
-#define POWERPC_MSRM_745 (0x000000000005FF77ULL)
-#define POWERPC_MMU_745 (POWERPC_MMU_SOFT_6xx)
-#define POWERPC_EXCP_745 (POWERPC_EXCP_7x5)
-#define POWERPC_INPUT_745 (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_745 (bfd_mach_ppc_750)
-#define POWERPC_FLAG_745 (POWERPC_FLAG_SE | POWERPC_FLAG_BE | \
- POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK)
-#define check_pow_745 check_pow_hid0
+POWERPC_FAMILY(750gx)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 750GX";
+ pcc->init_proc = init_proc_750gx;
+ pcc->check_pow = check_pow_hid0;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
+ PPC_SEGMENT | PPC_EXTERN;
+ pcc->msr_mask = 0x000000000005FF77ULL;
+ pcc->mmu_model = POWERPC_MMU_32B;
+#if defined(CONFIG_SOFTMMU)
+ pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
+#endif
+ pcc->excp_model = POWERPC_EXCP_7x0;
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_750;
+ pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
+ POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
+}
static void init_proc_745 (CPUPPCState *env)
{
@@ -5548,23 +5658,29 @@ static void init_proc_745 (CPUPPCState *env)
ppc6xx_irq_init(env);
}
-/* PowerPC 755 */
-#define POWERPC_INSNS_755 (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | \
- PPC_SEGMENT | PPC_EXTERN)
-#define POWERPC_INSNS2_755 (PPC_NONE)
-#define POWERPC_MSRM_755 (0x000000000005FF77ULL)
-#define POWERPC_MMU_755 (POWERPC_MMU_SOFT_6xx)
-#define POWERPC_EXCP_755 (POWERPC_EXCP_7x5)
-#define POWERPC_INPUT_755 (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_755 (bfd_mach_ppc_750)
-#define POWERPC_FLAG_755 (POWERPC_FLAG_SE | POWERPC_FLAG_BE | \
- POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK)
-#define check_pow_755 check_pow_hid0
+POWERPC_FAMILY(745)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 745";
+ pcc->init_proc = init_proc_745;
+ pcc->check_pow = check_pow_hid0;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
+ PPC_SEGMENT | PPC_EXTERN;
+ pcc->msr_mask = 0x000000000005FF77ULL;
+ pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
+ pcc->excp_model = POWERPC_EXCP_7x5;
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_750;
+ pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
+ POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
+}
static void init_proc_755 (CPUPPCState *env)
{
@@ -5577,7 +5693,7 @@ static void init_proc_755 (CPUPPCState *env)
/* XXX : not implemented */
spr_register(env, SPR_L2CR, "L2CR",
SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_generic, NULL,
0x00000000);
/* XXX : not implemented */
spr_register(env, SPR_L2PMCR, "L2PMCR",
@@ -5613,28 +5729,29 @@ static void init_proc_755 (CPUPPCState *env)
ppc6xx_irq_init(env);
}
-/* PowerPC 7400 (aka G4) */
-#define POWERPC_INSNS_7400 (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | \
- PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | \
- PPC_CACHE_DCBA | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \
- PPC_MEM_TLBIA | \
- PPC_SEGMENT | PPC_EXTERN | \
- PPC_ALTIVEC)
-#define POWERPC_INSNS2_7400 (PPC_NONE)
-#define POWERPC_MSRM_7400 (0x000000000205FF77ULL)
-#define POWERPC_MMU_7400 (POWERPC_MMU_32B)
-#define POWERPC_EXCP_7400 (POWERPC_EXCP_74xx)
-#define POWERPC_INPUT_7400 (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_7400 (bfd_mach_ppc_7400)
-#define POWERPC_FLAG_7400 (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \
- POWERPC_FLAG_BE | POWERPC_FLAG_PMM | \
- POWERPC_FLAG_BUS_CLK)
-#define check_pow_7400 check_pow_hid0
+POWERPC_FAMILY(755)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 755";
+ pcc->init_proc = init_proc_755;
+ pcc->check_pow = check_pow_hid0;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
+ PPC_SEGMENT | PPC_EXTERN;
+ pcc->msr_mask = 0x000000000005FF77ULL;
+ pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
+ pcc->excp_model = POWERPC_EXCP_7x5;
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_750;
+ pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
+ POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
+}
static void init_proc_7400 (CPUPPCState *env)
{
@@ -5666,28 +5783,37 @@ static void init_proc_7400 (CPUPPCState *env)
ppc6xx_irq_init(env);
}
-/* PowerPC 7410 (aka G4) */
-#define POWERPC_INSNS_7410 (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | \
- PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | \
- PPC_CACHE_DCBA | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \
- PPC_MEM_TLBIA | \
- PPC_SEGMENT | PPC_EXTERN | \
- PPC_ALTIVEC)
-#define POWERPC_INSNS2_7410 (PPC_NONE)
-#define POWERPC_MSRM_7410 (0x000000000205FF77ULL)
-#define POWERPC_MMU_7410 (POWERPC_MMU_32B)
-#define POWERPC_EXCP_7410 (POWERPC_EXCP_74xx)
-#define POWERPC_INPUT_7410 (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_7410 (bfd_mach_ppc_7400)
-#define POWERPC_FLAG_7410 (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \
- POWERPC_FLAG_BE | POWERPC_FLAG_PMM | \
- POWERPC_FLAG_BUS_CLK)
-#define check_pow_7410 check_pow_hid0
+POWERPC_FAMILY(7400)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 7400 (aka G4)";
+ pcc->init_proc = init_proc_7400;
+ pcc->check_pow = check_pow_hid0;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
+ PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI |
+ PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
+ PPC_MEM_TLBIA |
+ PPC_SEGMENT | PPC_EXTERN |
+ PPC_ALTIVEC;
+ pcc->msr_mask = 0x000000000205FF77ULL;
+ pcc->mmu_model = POWERPC_MMU_32B;
+#if defined(CONFIG_SOFTMMU)
+ pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
+#endif
+ pcc->excp_model = POWERPC_EXCP_74xx;
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_7400;
+ pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
+ POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
+ POWERPC_FLAG_BUS_CLK;
+}
static void init_proc_7410 (CPUPPCState *env)
{
@@ -5725,30 +5851,38 @@ static void init_proc_7410 (CPUPPCState *env)
ppc6xx_irq_init(env);
}
-/* PowerPC 7440 (aka G4) */
-#define POWERPC_INSNS_7440 (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | \
- PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | \
- PPC_CACHE_DCBA | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \
- PPC_MEM_TLBIA | PPC_74xx_TLB | \
- PPC_SEGMENT | PPC_EXTERN | \
- PPC_ALTIVEC)
-#define POWERPC_INSNS2_7440 (PPC_NONE)
-#define POWERPC_MSRM_7440 (0x000000000205FF77ULL)
-#define POWERPC_MMU_7440 (POWERPC_MMU_SOFT_74xx)
-#define POWERPC_EXCP_7440 (POWERPC_EXCP_74xx)
-#define POWERPC_INPUT_7440 (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_7440 (bfd_mach_ppc_7400)
-#define POWERPC_FLAG_7440 (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \
- POWERPC_FLAG_BE | POWERPC_FLAG_PMM | \
- POWERPC_FLAG_BUS_CLK)
-#define check_pow_7440 check_pow_hid0_74xx
+POWERPC_FAMILY(7410)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 7410 (aka G4)";
+ pcc->init_proc = init_proc_7410;
+ pcc->check_pow = check_pow_hid0;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
+ PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI |
+ PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
+ PPC_MEM_TLBIA |
+ PPC_SEGMENT | PPC_EXTERN |
+ PPC_ALTIVEC;
+ pcc->msr_mask = 0x000000000205FF77ULL;
+ pcc->mmu_model = POWERPC_MMU_32B;
+#if defined(CONFIG_SOFTMMU)
+ pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
+#endif
+ pcc->excp_model = POWERPC_EXCP_74xx;
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_7400;
+ pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
+ POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
+ POWERPC_FLAG_BUS_CLK;
+}
-__attribute__ (( unused ))
static void init_proc_7440 (CPUPPCState *env)
{
gen_spr_ne_601(env);
@@ -5811,30 +5945,35 @@ static void init_proc_7440 (CPUPPCState *env)
ppc6xx_irq_init(env);
}
-/* PowerPC 7450 (aka G4) */
-#define POWERPC_INSNS_7450 (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | \
- PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | \
- PPC_CACHE_DCBA | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \
- PPC_MEM_TLBIA | PPC_74xx_TLB | \
- PPC_SEGMENT | PPC_EXTERN | \
- PPC_ALTIVEC)
-#define POWERPC_INSNS2_7450 (PPC_NONE)
-#define POWERPC_MSRM_7450 (0x000000000205FF77ULL)
-#define POWERPC_MMU_7450 (POWERPC_MMU_SOFT_74xx)
-#define POWERPC_EXCP_7450 (POWERPC_EXCP_74xx)
-#define POWERPC_INPUT_7450 (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_7450 (bfd_mach_ppc_7400)
-#define POWERPC_FLAG_7450 (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \
- POWERPC_FLAG_BE | POWERPC_FLAG_PMM | \
- POWERPC_FLAG_BUS_CLK)
-#define check_pow_7450 check_pow_hid0_74xx
+POWERPC_FAMILY(7440)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 7440 (aka G4)";
+ pcc->init_proc = init_proc_7440;
+ pcc->check_pow = check_pow_hid0_74xx;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
+ PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI |
+ PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
+ PPC_MEM_TLBIA | PPC_74xx_TLB |
+ PPC_SEGMENT | PPC_EXTERN |
+ PPC_ALTIVEC;
+ pcc->msr_mask = 0x000000000205FF77ULL;
+ pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
+ pcc->excp_model = POWERPC_EXCP_74xx;
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_7400;
+ pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
+ POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
+ POWERPC_FLAG_BUS_CLK;
+}
-__attribute__ (( unused ))
static void init_proc_7450 (CPUPPCState *env)
{
gen_spr_ne_601(env);
@@ -5923,30 +6062,35 @@ static void init_proc_7450 (CPUPPCState *env)
ppc6xx_irq_init(env);
}
-/* PowerPC 7445 (aka G4) */
-#define POWERPC_INSNS_7445 (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | \
- PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | \
- PPC_CACHE_DCBA | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \
- PPC_MEM_TLBIA | PPC_74xx_TLB | \
- PPC_SEGMENT | PPC_EXTERN | \
- PPC_ALTIVEC)
-#define POWERPC_INSNS2_7445 (PPC_NONE)
-#define POWERPC_MSRM_7445 (0x000000000205FF77ULL)
-#define POWERPC_MMU_7445 (POWERPC_MMU_SOFT_74xx)
-#define POWERPC_EXCP_7445 (POWERPC_EXCP_74xx)
-#define POWERPC_INPUT_7445 (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_7445 (bfd_mach_ppc_7400)
-#define POWERPC_FLAG_7445 (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \
- POWERPC_FLAG_BE | POWERPC_FLAG_PMM | \
- POWERPC_FLAG_BUS_CLK)
-#define check_pow_7445 check_pow_hid0_74xx
+POWERPC_FAMILY(7450)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 7450 (aka G4)";
+ pcc->init_proc = init_proc_7450;
+ pcc->check_pow = check_pow_hid0_74xx;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
+ PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI |
+ PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
+ PPC_MEM_TLBIA | PPC_74xx_TLB |
+ PPC_SEGMENT | PPC_EXTERN |
+ PPC_ALTIVEC;
+ pcc->msr_mask = 0x000000000205FF77ULL;
+ pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
+ pcc->excp_model = POWERPC_EXCP_74xx;
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_7400;
+ pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
+ POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
+ POWERPC_FLAG_BUS_CLK;
+}
-__attribute__ (( unused ))
static void init_proc_7445 (CPUPPCState *env)
{
gen_spr_ne_601(env);
@@ -6038,30 +6182,35 @@ static void init_proc_7445 (CPUPPCState *env)
ppc6xx_irq_init(env);
}
-/* PowerPC 7455 (aka G4) */
-#define POWERPC_INSNS_7455 (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | \
- PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | \
- PPC_CACHE_DCBA | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \
- PPC_MEM_TLBIA | PPC_74xx_TLB | \
- PPC_SEGMENT | PPC_EXTERN | \
- PPC_ALTIVEC)
-#define POWERPC_INSNS2_7455 (PPC_NONE)
-#define POWERPC_MSRM_7455 (0x000000000205FF77ULL)
-#define POWERPC_MMU_7455 (POWERPC_MMU_SOFT_74xx)
-#define POWERPC_EXCP_7455 (POWERPC_EXCP_74xx)
-#define POWERPC_INPUT_7455 (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_7455 (bfd_mach_ppc_7400)
-#define POWERPC_FLAG_7455 (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \
- POWERPC_FLAG_BE | POWERPC_FLAG_PMM | \
- POWERPC_FLAG_BUS_CLK)
-#define check_pow_7455 check_pow_hid0_74xx
+POWERPC_FAMILY(7445)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 7445 (aka G4)";
+ pcc->init_proc = init_proc_7445;
+ pcc->check_pow = check_pow_hid0_74xx;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
+ PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI |
+ PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
+ PPC_MEM_TLBIA | PPC_74xx_TLB |
+ PPC_SEGMENT | PPC_EXTERN |
+ PPC_ALTIVEC;
+ pcc->msr_mask = 0x000000000205FF77ULL;
+ pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
+ pcc->excp_model = POWERPC_EXCP_74xx;
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_7400;
+ pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
+ POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
+ POWERPC_FLAG_BUS_CLK;
+}
-__attribute__ (( unused ))
static void init_proc_7455 (CPUPPCState *env)
{
gen_spr_ne_601(env);
@@ -6155,30 +6304,35 @@ static void init_proc_7455 (CPUPPCState *env)
ppc6xx_irq_init(env);
}
-/* PowerPC 7457 (aka G4) */
-#define POWERPC_INSNS_7457 (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | \
- PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | \
- PPC_CACHE_DCBA | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \
- PPC_MEM_TLBIA | PPC_74xx_TLB | \
- PPC_SEGMENT | PPC_EXTERN | \
- PPC_ALTIVEC)
-#define POWERPC_INSNS2_7457 (PPC_NONE)
-#define POWERPC_MSRM_7457 (0x000000000205FF77ULL)
-#define POWERPC_MMU_7457 (POWERPC_MMU_SOFT_74xx)
-#define POWERPC_EXCP_7457 (POWERPC_EXCP_74xx)
-#define POWERPC_INPUT_7457 (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_7457 (bfd_mach_ppc_7400)
-#define POWERPC_FLAG_7457 (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \
- POWERPC_FLAG_BE | POWERPC_FLAG_PMM | \
- POWERPC_FLAG_BUS_CLK)
-#define check_pow_7457 check_pow_hid0_74xx
+POWERPC_FAMILY(7455)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 7455 (aka G4)";
+ pcc->init_proc = init_proc_7455;
+ pcc->check_pow = check_pow_hid0_74xx;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
+ PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI |
+ PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
+ PPC_MEM_TLBIA | PPC_74xx_TLB |
+ PPC_SEGMENT | PPC_EXTERN |
+ PPC_ALTIVEC;
+ pcc->msr_mask = 0x000000000205FF77ULL;
+ pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
+ pcc->excp_model = POWERPC_EXCP_74xx;
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_7400;
+ pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
+ POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
+ POWERPC_FLAG_BUS_CLK;
+}
-__attribute__ (( unused ))
static void init_proc_7457 (CPUPPCState *env)
{
gen_spr_ne_601(env);
@@ -6296,27 +6450,161 @@ static void init_proc_7457 (CPUPPCState *env)
ppc6xx_irq_init(env);
}
-#if defined (TARGET_PPC64)
-/* PowerPC 970 */
-#define POWERPC_INSNS_970 (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | \
- PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZT | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \
- PPC_64B | PPC_ALTIVEC | \
- PPC_SEGMENT_64B | PPC_SLBI)
-#define POWERPC_INSNS2_970 (PPC_NONE)
-#define POWERPC_MSRM_970 (0x900000000204FF36ULL)
-#define POWERPC_MMU_970 (POWERPC_MMU_64B)
-//#define POWERPC_EXCP_970 (POWERPC_EXCP_970)
-#define POWERPC_INPUT_970 (PPC_FLAGS_INPUT_970)
-#define POWERPC_BFDM_970 (bfd_mach_ppc64)
-#define POWERPC_FLAG_970 (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \
- POWERPC_FLAG_BE | POWERPC_FLAG_PMM | \
- POWERPC_FLAG_BUS_CLK)
+POWERPC_FAMILY(7457)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 7457 (aka G4)";
+ pcc->init_proc = init_proc_7457;
+ pcc->check_pow = check_pow_hid0_74xx;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
+ PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI |
+ PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
+ PPC_MEM_TLBIA | PPC_74xx_TLB |
+ PPC_SEGMENT | PPC_EXTERN |
+ PPC_ALTIVEC;
+ pcc->msr_mask = 0x000000000205FF77ULL;
+ pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
+ pcc->excp_model = POWERPC_EXCP_74xx;
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_7400;
+ pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
+ POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
+ POWERPC_FLAG_BUS_CLK;
+}
+
+static void init_proc_e600 (CPUPPCState *env)
+{
+ gen_spr_ne_601(env);
+ gen_spr_7xx(env);
+ /* Time base */
+ gen_tbl(env);
+ /* 74xx specific SPR */
+ gen_spr_74xx(env);
+ /* XXX : not implemented */
+ spr_register(env, SPR_UBAMR, "UBAMR",
+ &spr_read_ureg, SPR_NOACCESS,
+ &spr_read_ureg, SPR_NOACCESS,
+ 0x00000000);
+ /* XXX : not implemented */
+ spr_register(env, SPR_LDSTCR, "LDSTCR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ /* XXX : not implemented */
+ spr_register(env, SPR_ICTRL, "ICTRL",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ /* XXX : not implemented */
+ spr_register(env, SPR_MSSSR0, "MSSSR0",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ /* XXX : not implemented */
+ spr_register(env, SPR_PMC5, "PMC5",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ /* XXX : not implemented */
+ spr_register(env, SPR_UPMC5, "UPMC5",
+ &spr_read_ureg, SPR_NOACCESS,
+ &spr_read_ureg, SPR_NOACCESS,
+ 0x00000000);
+ /* XXX : not implemented */
+ spr_register(env, SPR_PMC6, "PMC6",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ /* XXX : not implemented */
+ spr_register(env, SPR_UPMC6, "UPMC6",
+ &spr_read_ureg, SPR_NOACCESS,
+ &spr_read_ureg, SPR_NOACCESS,
+ 0x00000000);
+ /* SPRGs */
+ spr_register(env, SPR_SPRG4, "SPRG4",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ spr_register(env, SPR_USPRG4, "USPRG4",
+ &spr_read_ureg, SPR_NOACCESS,
+ &spr_read_ureg, SPR_NOACCESS,
+ 0x00000000);
+ spr_register(env, SPR_SPRG5, "SPRG5",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ spr_register(env, SPR_USPRG5, "USPRG5",
+ &spr_read_ureg, SPR_NOACCESS,
+ &spr_read_ureg, SPR_NOACCESS,
+ 0x00000000);
+ spr_register(env, SPR_SPRG6, "SPRG6",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ spr_register(env, SPR_USPRG6, "USPRG6",
+ &spr_read_ureg, SPR_NOACCESS,
+ &spr_read_ureg, SPR_NOACCESS,
+ 0x00000000);
+ spr_register(env, SPR_SPRG7, "SPRG7",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ spr_register(env, SPR_USPRG7, "USPRG7",
+ &spr_read_ureg, SPR_NOACCESS,
+ &spr_read_ureg, SPR_NOACCESS,
+ 0x00000000);
+ /* Memory management */
+ gen_low_BATs(env);
+ gen_high_BATs(env);
+ gen_74xx_soft_tlb(env, 128, 2);
+ init_excp_7450(env);
+ env->dcache_line_size = 32;
+ env->icache_line_size = 32;
+ /* Allocate hardware IRQ controller */
+ ppc6xx_irq_init(env);
+}
+POWERPC_FAMILY(e600)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC e600";
+ pcc->init_proc = init_proc_e600;
+ pcc->check_pow = check_pow_hid0_74xx;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
+ PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI |
+ PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
+ PPC_MEM_TLBIA | PPC_74xx_TLB |
+ PPC_SEGMENT | PPC_EXTERN |
+ PPC_ALTIVEC;
+ pcc->insns_flags2 = PPC_NONE;
+ pcc->msr_mask = 0x000000000205FF77ULL;
+ pcc->mmu_model = POWERPC_MMU_32B;
+#if defined(CONFIG_SOFTMMU)
+ pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
+#endif
+ pcc->excp_model = POWERPC_EXCP_74xx;
+ pcc->bus_model = PPC_FLAGS_INPUT_6xx;
+ pcc->bfd_mach = bfd_mach_ppc_7400;
+ pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
+ POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
+ POWERPC_FLAG_BUS_CLK;
+}
+
+#if defined (TARGET_PPC64)
#if defined(CONFIG_USER_ONLY)
#define POWERPC970_HID5_INIT 0x00000080
#else
@@ -6361,7 +6649,7 @@ static void init_proc_970 (CPUPPCState *env)
/* XXX : not implemented */
spr_register(env, SPR_L2CR, "L2CR",
SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_generic, NULL,
0x00000000);
/* Memory management */
/* XXX: not correct */
@@ -6393,25 +6681,35 @@ static void init_proc_970 (CPUPPCState *env)
vscr_init(env, 0x00010000);
}
-/* PowerPC 970FX (aka G5) */
-#define POWERPC_INSNS_970FX (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | \
- PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZT | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \
- PPC_64B | PPC_ALTIVEC | \
- PPC_SEGMENT_64B | PPC_SLBI)
-#define POWERPC_INSNS2_970FX (PPC_NONE)
-#define POWERPC_MSRM_970FX (0x800000000204FF36ULL)
-#define POWERPC_MMU_970FX (POWERPC_MMU_64B)
-#define POWERPC_EXCP_970FX (POWERPC_EXCP_970)
-#define POWERPC_INPUT_970FX (PPC_FLAGS_INPUT_970)
-#define POWERPC_BFDM_970FX (bfd_mach_ppc64)
-#define POWERPC_FLAG_970FX (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \
- POWERPC_FLAG_BE | POWERPC_FLAG_PMM | \
- POWERPC_FLAG_BUS_CLK)
+POWERPC_FAMILY(970)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 970";
+ pcc->init_proc = init_proc_970;
+ pcc->check_pow = check_pow_970;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
+ PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
+ PPC_64B | PPC_ALTIVEC |
+ PPC_SEGMENT_64B | PPC_SLBI;
+ pcc->msr_mask = 0x900000000204FF36ULL;
+ pcc->mmu_model = POWERPC_MMU_64B;
+#if defined(CONFIG_SOFTMMU)
+ pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
+#endif
+ pcc->excp_model = POWERPC_EXCP_970;
+ pcc->bus_model = PPC_FLAGS_INPUT_970;
+ pcc->bfd_mach = bfd_mach_ppc64;
+ pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
+ POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
+ POWERPC_FLAG_BUS_CLK;
+}
static int check_pow_970FX (CPUPPCState *env)
{
@@ -6451,7 +6749,7 @@ static void init_proc_970FX (CPUPPCState *env)
/* XXX : not implemented */
spr_register(env, SPR_L2CR, "L2CR",
SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_generic, NULL,
0x00000000);
/* Memory management */
/* XXX: not correct */
@@ -6495,25 +6793,35 @@ static void init_proc_970FX (CPUPPCState *env)
vscr_init(env, 0x00010000);
}
-/* PowerPC 970 GX */
-#define POWERPC_INSNS_970GX (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | \
- PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZT | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \
- PPC_64B | PPC_ALTIVEC | \
- PPC_SEGMENT_64B | PPC_SLBI)
-#define POWERPC_INSNS2_970GX (PPC_NONE)
-#define POWERPC_MSRM_970GX (0x800000000204FF36ULL)
-#define POWERPC_MMU_970GX (POWERPC_MMU_64B)
-#define POWERPC_EXCP_970GX (POWERPC_EXCP_970)
-#define POWERPC_INPUT_970GX (PPC_FLAGS_INPUT_970)
-#define POWERPC_BFDM_970GX (bfd_mach_ppc64)
-#define POWERPC_FLAG_970GX (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \
- POWERPC_FLAG_BE | POWERPC_FLAG_PMM | \
- POWERPC_FLAG_BUS_CLK)
+POWERPC_FAMILY(970FX)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 970FX (aka G5)";
+ pcc->init_proc = init_proc_970FX;
+ pcc->check_pow = check_pow_970FX;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
+ PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
+ PPC_64B | PPC_ALTIVEC |
+ PPC_SEGMENT_64B | PPC_SLBI;
+ pcc->msr_mask = 0x800000000204FF36ULL;
+ pcc->mmu_model = POWERPC_MMU_64B;
+#if defined(CONFIG_SOFTMMU)
+ pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
+#endif
+ pcc->excp_model = POWERPC_EXCP_970;
+ pcc->bus_model = PPC_FLAGS_INPUT_970;
+ pcc->bfd_mach = bfd_mach_ppc64;
+ pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
+ POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
+ POWERPC_FLAG_BUS_CLK;
+}
static int check_pow_970GX (CPUPPCState *env)
{
@@ -6553,7 +6861,7 @@ static void init_proc_970GX (CPUPPCState *env)
/* XXX : not implemented */
spr_register(env, SPR_L2CR, "L2CR",
SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_generic, NULL,
0x00000000);
/* Memory management */
/* XXX: not correct */
@@ -6585,25 +6893,35 @@ static void init_proc_970GX (CPUPPCState *env)
vscr_init(env, 0x00010000);
}
-/* PowerPC 970 MP */
-#define POWERPC_INSNS_970MP (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | \
- PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZT | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \
- PPC_64B | PPC_ALTIVEC | \
- PPC_SEGMENT_64B | PPC_SLBI)
-#define POWERPC_INSNS2_970MP (PPC_NONE)
-#define POWERPC_MSRM_970MP (0x900000000204FF36ULL)
-#define POWERPC_MMU_970MP (POWERPC_MMU_64B)
-#define POWERPC_EXCP_970MP (POWERPC_EXCP_970)
-#define POWERPC_INPUT_970MP (PPC_FLAGS_INPUT_970)
-#define POWERPC_BFDM_970MP (bfd_mach_ppc64)
-#define POWERPC_FLAG_970MP (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \
- POWERPC_FLAG_BE | POWERPC_FLAG_PMM | \
- POWERPC_FLAG_BUS_CLK)
+POWERPC_FAMILY(970GX)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 970 GX";
+ pcc->init_proc = init_proc_970GX;
+ pcc->check_pow = check_pow_970GX;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
+ PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
+ PPC_64B | PPC_ALTIVEC |
+ PPC_SEGMENT_64B | PPC_SLBI;
+ pcc->msr_mask = 0x800000000204FF36ULL;
+ pcc->mmu_model = POWERPC_MMU_64B;
+#if defined(CONFIG_SOFTMMU)
+ pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
+#endif
+ pcc->excp_model = POWERPC_EXCP_970;
+ pcc->bus_model = PPC_FLAGS_INPUT_970;
+ pcc->bfd_mach = bfd_mach_ppc64;
+ pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
+ POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
+ POWERPC_FLAG_BUS_CLK;
+}
static int check_pow_970MP (CPUPPCState *env)
{
@@ -6643,7 +6961,7 @@ static void init_proc_970MP (CPUPPCState *env)
/* XXX : not implemented */
spr_register(env, SPR_L2CR, "L2CR",
SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
+ &spr_read_generic, NULL,
0x00000000);
/* Memory management */
/* XXX: not correct */
@@ -6675,28 +6993,139 @@ static void init_proc_970MP (CPUPPCState *env)
vscr_init(env, 0x00010000);
}
-#if defined(TARGET_PPC64)
-/* POWER7 */
-#define POWERPC_INSNS_POWER7 (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | \
- PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZT | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \
- PPC_64B | PPC_ALTIVEC | \
- PPC_SEGMENT_64B | PPC_SLBI | \
- PPC_POPCNTB | PPC_POPCNTWD)
-#define POWERPC_INSNS2_POWER7 (PPC2_VSX | PPC2_DFP | PPC2_DBRX)
-#define POWERPC_MSRM_POWER7 (0x800000000204FF36ULL)
-#define POWERPC_MMU_POWER7 (POWERPC_MMU_2_06)
-#define POWERPC_EXCP_POWER7 (POWERPC_EXCP_POWER7)
-#define POWERPC_INPUT_POWER7 (PPC_FLAGS_INPUT_POWER7)
-#define POWERPC_BFDM_POWER7 (bfd_mach_ppc64)
-#define POWERPC_FLAG_POWER7 (POWERPC_FLAG_VRE | POWERPC_FLAG_SE | \
- POWERPC_FLAG_BE | POWERPC_FLAG_PMM | \
- POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR)
-#define check_pow_POWER7 check_pow_nocheck
+POWERPC_FAMILY(970MP)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PowerPC 970 MP";
+ pcc->init_proc = init_proc_970MP;
+ pcc->check_pow = check_pow_970MP;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
+ PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
+ PPC_64B | PPC_ALTIVEC |
+ PPC_SEGMENT_64B | PPC_SLBI;
+ pcc->msr_mask = 0x900000000204FF36ULL;
+ pcc->mmu_model = POWERPC_MMU_64B;
+#if defined(CONFIG_SOFTMMU)
+ pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
+#endif
+ pcc->excp_model = POWERPC_EXCP_970;
+ pcc->bus_model = PPC_FLAGS_INPUT_970;
+ pcc->bfd_mach = bfd_mach_ppc64;
+ pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
+ POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
+ POWERPC_FLAG_BUS_CLK;
+}
+
+static void init_proc_power5plus(CPUPPCState *env)
+{
+ gen_spr_ne_601(env);
+ gen_spr_7xx(env);
+ /* Time base */
+ gen_tbl(env);
+ /* Hardware implementation registers */
+ /* XXX : not implemented */
+ spr_register(env, SPR_HID0, "HID0",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_clear,
+ 0x60000000);
+ /* XXX : not implemented */
+ spr_register(env, SPR_HID1, "HID1",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ /* XXX : not implemented */
+ spr_register(env, SPR_750FX_HID2, "HID2",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ /* XXX : not implemented */
+ spr_register(env, SPR_970_HID5, "HID5",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ POWERPC970_HID5_INIT);
+ /* XXX : not implemented */
+ spr_register(env, SPR_L2CR, "L2CR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, NULL,
+ 0x00000000);
+ /* Memory management */
+ /* XXX: not correct */
+ gen_low_BATs(env);
+ /* XXX : not implemented */
+ spr_register(env, SPR_MMUCFG, "MMUCFG",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, SPR_NOACCESS,
+ 0x00000000); /* TOFIX */
+ /* XXX : not implemented */
+ spr_register(env, SPR_MMUCSR0, "MMUCSR0",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000); /* TOFIX */
+ spr_register(env, SPR_HIOR, "SPR_HIOR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_hior, &spr_write_hior,
+ 0x00000000);
+ spr_register(env, SPR_CTRL, "SPR_CTRL",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ spr_register(env, SPR_UCTRL, "SPR_UCTRL",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ spr_register(env, SPR_VRSAVE, "SPR_VRSAVE",
+ &spr_read_generic, &spr_write_generic,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+#if !defined(CONFIG_USER_ONLY)
+ env->slb_nr = 64;
+#endif
+ init_excp_970(env);
+ env->dcache_line_size = 128;
+ env->icache_line_size = 128;
+ /* Allocate hardware IRQ controller */
+ ppc970_irq_init(env);
+ /* Can't find information on what this should be on reset. This
+ * value is the one used by 74xx processors. */
+ vscr_init(env, 0x00010000);
+}
+
+POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "POWER5+";
+ pcc->init_proc = init_proc_power5plus;
+ pcc->check_pow = check_pow_970FX;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
+ PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
+ PPC_64B |
+ PPC_SEGMENT_64B | PPC_SLBI;
+ pcc->msr_mask = 0x800000000204FF36ULL;
+ pcc->mmu_model = POWERPC_MMU_64B;
+#if defined(CONFIG_SOFTMMU)
+ pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
+#endif
+ pcc->excp_model = POWERPC_EXCP_970;
+ pcc->bus_model = PPC_FLAGS_INPUT_970;
+ pcc->bfd_mach = bfd_mach_ppc64;
+ pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
+ POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
+ POWERPC_FLAG_BUS_CLK;
+}
static void init_proc_POWER7 (CPUPPCState *env)
{
@@ -6711,22 +7140,34 @@ static void init_proc_POWER7 (CPUPPCState *env)
0x00000000);
#if !defined(CONFIG_USER_ONLY)
/* PURR & SPURR: Hack - treat these as aliases for the TB for now */
- spr_register(env, SPR_PURR, "PURR",
- &spr_read_purr, SPR_NOACCESS,
- &spr_read_purr, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_SPURR, "SPURR",
- &spr_read_purr, SPR_NOACCESS,
- &spr_read_purr, SPR_NOACCESS,
- 0x00000000);
+ spr_register_kvm(env, SPR_PURR, "PURR",
+ &spr_read_purr, SPR_NOACCESS,
+ &spr_read_purr, SPR_NOACCESS,
+ KVM_REG_PPC_PURR, 0x00000000);
+ spr_register_kvm(env, SPR_SPURR, "SPURR",
+ &spr_read_purr, SPR_NOACCESS,
+ &spr_read_purr, SPR_NOACCESS,
+ KVM_REG_PPC_SPURR, 0x00000000);
spr_register(env, SPR_CFAR, "SPR_CFAR",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_cfar, &spr_write_cfar,
0x00000000);
- spr_register(env, SPR_DSCR, "SPR_DSCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
+ spr_register_kvm(env, SPR_DSCR, "SPR_DSCR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ KVM_REG_PPC_DSCR, 0x00000000);
+ spr_register_kvm(env, SPR_MMCRA, "SPR_MMCRA",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ KVM_REG_PPC_MMCRA, 0x00000000);
+ spr_register_kvm(env, SPR_PMC5, "SPR_PMC5",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ KVM_REG_PPC_PMC5, 0x00000000);
+ spr_register_kvm(env, SPR_PMC6, "SPR_PMC6",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ KVM_REG_PPC_PMC6, 0x00000000);
#endif /* !CONFIG_USER_ONLY */
/* Memory management */
/* XXX : not implemented */
@@ -6734,6 +7175,7 @@ static void init_proc_POWER7 (CPUPPCState *env)
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, SPR_NOACCESS,
0x00000000); /* TOFIX */
+ gen_spr_amr(env);
/* XXX : not implemented */
spr_register(env, SPR_CTRL, "SPR_CTRLT",
SPR_NOACCESS, SPR_NOACCESS,
@@ -6747,2666 +7189,100 @@ static void init_proc_POWER7 (CPUPPCState *env)
&spr_read_generic, &spr_write_generic,
&spr_read_generic, &spr_write_generic,
0x00000000);
+ spr_register(env, SPR_PPR, "PPR",
+ &spr_read_generic, &spr_write_generic,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
#if !defined(CONFIG_USER_ONLY)
env->slb_nr = 32;
#endif
init_excp_POWER7(env);
env->dcache_line_size = 128;
env->icache_line_size = 128;
+
/* Allocate hardware IRQ controller */
ppcPOWER7_irq_init(env);
/* Can't find information on what this should be on reset. This
* value is the one used by 74xx processors. */
vscr_init(env, 0x00010000);
}
-#endif /* TARGET_PPC64 */
-
-/* PowerPC 620 */
-#define POWERPC_INSNS_620 (PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | \
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | \
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | \
- PPC_FLOAT_STFIWX | \
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | \
- PPC_MEM_SYNC | PPC_MEM_EIEIO | \
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | \
- PPC_SEGMENT | PPC_EXTERN | \
- PPC_64B | PPC_SLBI)
-#define POWERPC_INSNS2_620 (PPC_NONE)
-#define POWERPC_MSRM_620 (0x800000000005FF77ULL)
-//#define POWERPC_MMU_620 (POWERPC_MMU_620)
-#define POWERPC_EXCP_620 (POWERPC_EXCP_970)
-#define POWERPC_INPUT_620 (PPC_FLAGS_INPUT_6xx)
-#define POWERPC_BFDM_620 (bfd_mach_ppc64)
-#define POWERPC_FLAG_620 (POWERPC_FLAG_SE | POWERPC_FLAG_BE | \
- POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK)
-#define check_pow_620 check_pow_nocheck /* Check this */
-__attribute__ (( unused ))
-static void init_proc_620 (CPUPPCState *env)
+POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
{
- gen_spr_ne_601(env);
- gen_spr_620(env);
- /* Time base */
- gen_tbl(env);
- /* Hardware implementation registers */
- /* XXX : not implemented */
- spr_register(env, SPR_HID0, "HID0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
- gen_low_BATs(env);
- init_excp_620(env);
- env->dcache_line_size = 64;
- env->icache_line_size = 64;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(env);
-}
-#endif /* defined (TARGET_PPC64) */
-
-/* Default 32 bits PowerPC target will be 604 */
-#define CPU_POWERPC_PPC32 CPU_POWERPC_604
-#define POWERPC_INSNS_PPC32 POWERPC_INSNS_604
-#define POWERPC_INSNS2_PPC32 POWERPC_INSNS2_604
-#define POWERPC_MSRM_PPC32 POWERPC_MSRM_604
-#define POWERPC_MMU_PPC32 POWERPC_MMU_604
-#define POWERPC_EXCP_PPC32 POWERPC_EXCP_604
-#define POWERPC_INPUT_PPC32 POWERPC_INPUT_604
-#define POWERPC_BFDM_PPC32 POWERPC_BFDM_604
-#define POWERPC_FLAG_PPC32 POWERPC_FLAG_604
-#define check_pow_PPC32 check_pow_604
-#define init_proc_PPC32 init_proc_604
-
-/* Default 64 bits PowerPC target will be 970 FX */
-#define CPU_POWERPC_PPC64 CPU_POWERPC_970FX
-#define POWERPC_INSNS_PPC64 POWERPC_INSNS_970FX
-#define POWERPC_INSNS2_PPC64 POWERPC_INSNS2_970FX
-#define POWERPC_MSRM_PPC64 POWERPC_MSRM_970FX
-#define POWERPC_MMU_PPC64 POWERPC_MMU_970FX
-#define POWERPC_EXCP_PPC64 POWERPC_EXCP_970FX
-#define POWERPC_INPUT_PPC64 POWERPC_INPUT_970FX
-#define POWERPC_BFDM_PPC64 POWERPC_BFDM_970FX
-#define POWERPC_FLAG_PPC64 POWERPC_FLAG_970FX
-#define check_pow_PPC64 check_pow_970FX
-#define init_proc_PPC64 init_proc_970FX
-
-/* Default PowerPC target will be PowerPC 32 */
-#if defined (TARGET_PPC64) && 0 // XXX: TODO
-#define CPU_POWERPC_DEFAULT CPU_POWERPC_PPC64
-#define POWERPC_INSNS_DEFAULT POWERPC_INSNS_PPC64
-#define POWERPC_INSNS2_DEFAULT POWERPC_INSNS2_PPC64
-#define POWERPC_MSRM_DEFAULT POWERPC_MSRM_PPC64
-#define POWERPC_MMU_DEFAULT POWERPC_MMU_PPC64
-#define POWERPC_EXCP_DEFAULT POWERPC_EXCP_PPC64
-#define POWERPC_INPUT_DEFAULT POWERPC_INPUT_PPC64
-#define POWERPC_BFDM_DEFAULT POWERPC_BFDM_PPC64
-#define POWERPC_FLAG_DEFAULT POWERPC_FLAG_PPC64
-#define check_pow_DEFAULT check_pow_PPC64
-#define init_proc_DEFAULT init_proc_PPC64
-#else
-#define CPU_POWERPC_DEFAULT CPU_POWERPC_PPC32
-#define POWERPC_INSNS_DEFAULT POWERPC_INSNS_PPC32
-#define POWERPC_INSNS2_DEFAULT POWERPC_INSNS2_PPC32
-#define POWERPC_MSRM_DEFAULT POWERPC_MSRM_PPC32
-#define POWERPC_MMU_DEFAULT POWERPC_MMU_PPC32
-#define POWERPC_EXCP_DEFAULT POWERPC_EXCP_PPC32
-#define POWERPC_INPUT_DEFAULT POWERPC_INPUT_PPC32
-#define POWERPC_BFDM_DEFAULT POWERPC_BFDM_PPC32
-#define POWERPC_FLAG_DEFAULT POWERPC_FLAG_PPC32
-#define check_pow_DEFAULT check_pow_PPC32
-#define init_proc_DEFAULT init_proc_PPC32
-#endif
-
-/*****************************************************************************/
-/* PVR definitions for most known PowerPC */
-enum {
- /* PowerPC 401 family */
- /* Generic PowerPC 401 */
-#define CPU_POWERPC_401 CPU_POWERPC_401G2
- /* PowerPC 401 cores */
- CPU_POWERPC_401A1 = 0x00210000,
- CPU_POWERPC_401B2 = 0x00220000,
-#if 0
- CPU_POWERPC_401B3 = xxx,
-#endif
- CPU_POWERPC_401C2 = 0x00230000,
- CPU_POWERPC_401D2 = 0x00240000,
- CPU_POWERPC_401E2 = 0x00250000,
- CPU_POWERPC_401F2 = 0x00260000,
- CPU_POWERPC_401G2 = 0x00270000,
- /* PowerPC 401 microcontrolers */
-#if 0
- CPU_POWERPC_401GF = xxx,
-#endif
-#define CPU_POWERPC_IOP480 CPU_POWERPC_401B2
- /* IBM Processor for Network Resources */
- CPU_POWERPC_COBRA = 0x10100000, /* XXX: 405 ? */
-#if 0
- CPU_POWERPC_XIPCHIP = xxx,
-#endif
- /* PowerPC 403 family */
- /* Generic PowerPC 403 */
-#define CPU_POWERPC_403 CPU_POWERPC_403GC
- /* PowerPC 403 microcontrollers */
- CPU_POWERPC_403GA = 0x00200011,
- CPU_POWERPC_403GB = 0x00200100,
- CPU_POWERPC_403GC = 0x00200200,
- CPU_POWERPC_403GCX = 0x00201400,
-#if 0
- CPU_POWERPC_403GP = xxx,
-#endif
- /* PowerPC 405 family */
- /* Generic PowerPC 405 */
-#define CPU_POWERPC_405 CPU_POWERPC_405D4
- /* PowerPC 405 cores */
-#if 0
- CPU_POWERPC_405A3 = xxx,
-#endif
-#if 0
- CPU_POWERPC_405A4 = xxx,
-#endif
-#if 0
- CPU_POWERPC_405B3 = xxx,
-#endif
-#if 0
- CPU_POWERPC_405B4 = xxx,
-#endif
-#if 0
- CPU_POWERPC_405C3 = xxx,
-#endif
-#if 0
- CPU_POWERPC_405C4 = xxx,
-#endif
- CPU_POWERPC_405D2 = 0x20010000,
-#if 0
- CPU_POWERPC_405D3 = xxx,
-#endif
- CPU_POWERPC_405D4 = 0x41810000,
-#if 0
- CPU_POWERPC_405D5 = xxx,
-#endif
-#if 0
- CPU_POWERPC_405E4 = xxx,
-#endif
-#if 0
- CPU_POWERPC_405F4 = xxx,
-#endif
-#if 0
- CPU_POWERPC_405F5 = xxx,
-#endif
-#if 0
- CPU_POWERPC_405F6 = xxx,
-#endif
- /* PowerPC 405 microcontrolers */
- /* XXX: missing 0x200108a0 */
-#define CPU_POWERPC_405CR CPU_POWERPC_405CRc
- CPU_POWERPC_405CRa = 0x40110041,
- CPU_POWERPC_405CRb = 0x401100C5,
- CPU_POWERPC_405CRc = 0x40110145,
- CPU_POWERPC_405EP = 0x51210950,
-#if 0
- CPU_POWERPC_405EXr = xxx,
-#endif
- CPU_POWERPC_405EZ = 0x41511460, /* 0x51210950 ? */
-#if 0
- CPU_POWERPC_405FX = xxx,
-#endif
-#define CPU_POWERPC_405GP CPU_POWERPC_405GPd
- CPU_POWERPC_405GPa = 0x40110000,
- CPU_POWERPC_405GPb = 0x40110040,
- CPU_POWERPC_405GPc = 0x40110082,
- CPU_POWERPC_405GPd = 0x401100C4,
-#define CPU_POWERPC_405GPe CPU_POWERPC_405CRc
- CPU_POWERPC_405GPR = 0x50910951,
-#if 0
- CPU_POWERPC_405H = xxx,
-#endif
-#if 0
- CPU_POWERPC_405L = xxx,
-#endif
- CPU_POWERPC_405LP = 0x41F10000,
-#if 0
- CPU_POWERPC_405PM = xxx,
-#endif
-#if 0
- CPU_POWERPC_405PS = xxx,
-#endif
-#if 0
- CPU_POWERPC_405S = xxx,
-#endif
- /* IBM network processors */
- CPU_POWERPC_NPE405H = 0x414100C0,
- CPU_POWERPC_NPE405H2 = 0x41410140,
- CPU_POWERPC_NPE405L = 0x416100C0,
- CPU_POWERPC_NPE4GS3 = 0x40B10000,
-#if 0
- CPU_POWERPC_NPCxx1 = xxx,
-#endif
-#if 0
- CPU_POWERPC_NPR161 = xxx,
-#endif
-#if 0
- CPU_POWERPC_LC77700 = xxx,
-#endif
- /* IBM STBxxx (PowerPC 401/403/405 core based microcontrollers) */
-#if 0
- CPU_POWERPC_STB01000 = xxx,
-#endif
-#if 0
- CPU_POWERPC_STB01010 = xxx,
-#endif
-#if 0
- CPU_POWERPC_STB0210 = xxx, /* 401B3 */
-#endif
- CPU_POWERPC_STB03 = 0x40310000, /* 0x40130000 ? */
-#if 0
- CPU_POWERPC_STB043 = xxx,
-#endif
-#if 0
- CPU_POWERPC_STB045 = xxx,
-#endif
- CPU_POWERPC_STB04 = 0x41810000,
- CPU_POWERPC_STB25 = 0x51510950,
-#if 0
- CPU_POWERPC_STB130 = xxx,
-#endif
- /* Xilinx cores */
- CPU_POWERPC_X2VP4 = 0x20010820,
-#define CPU_POWERPC_X2VP7 CPU_POWERPC_X2VP4
- CPU_POWERPC_X2VP20 = 0x20010860,
-#define CPU_POWERPC_X2VP50 CPU_POWERPC_X2VP20
-#if 0
- CPU_POWERPC_ZL10310 = xxx,
-#endif
-#if 0
- CPU_POWERPC_ZL10311 = xxx,
-#endif
-#if 0
- CPU_POWERPC_ZL10320 = xxx,
-#endif
-#if 0
- CPU_POWERPC_ZL10321 = xxx,
-#endif
- /* PowerPC 440 family */
- /* Generic PowerPC 440 */
-#define CPU_POWERPC_440 CPU_POWERPC_440GXf
- /* PowerPC 440 cores */
-#if 0
- CPU_POWERPC_440A4 = xxx,
-#endif
- CPU_POWERPC_440_XILINX = 0x7ff21910,
-#if 0
- CPU_POWERPC_440A5 = xxx,
-#endif
-#if 0
- CPU_POWERPC_440B4 = xxx,
-#endif
-#if 0
- CPU_POWERPC_440F5 = xxx,
-#endif
-#if 0
- CPU_POWERPC_440G5 = xxx,
-#endif
-#if 0
- CPU_POWERPC_440H4 = xxx,
-#endif
-#if 0
- CPU_POWERPC_440H6 = xxx,
-#endif
- /* PowerPC 440 microcontrolers */
-#define CPU_POWERPC_440EP CPU_POWERPC_440EPb
- CPU_POWERPC_440EPa = 0x42221850,
- CPU_POWERPC_440EPb = 0x422218D3,
-#define CPU_POWERPC_440GP CPU_POWERPC_440GPc
- CPU_POWERPC_440GPb = 0x40120440,
- CPU_POWERPC_440GPc = 0x40120481,
-#define CPU_POWERPC_440GR CPU_POWERPC_440GRa
-#define CPU_POWERPC_440GRa CPU_POWERPC_440EPb
- CPU_POWERPC_440GRX = 0x200008D0,
-#define CPU_POWERPC_440EPX CPU_POWERPC_440GRX
-#define CPU_POWERPC_440GX CPU_POWERPC_440GXf
- CPU_POWERPC_440GXa = 0x51B21850,
- CPU_POWERPC_440GXb = 0x51B21851,
- CPU_POWERPC_440GXc = 0x51B21892,
- CPU_POWERPC_440GXf = 0x51B21894,
-#if 0
- CPU_POWERPC_440S = xxx,
-#endif
- CPU_POWERPC_440SP = 0x53221850,
- CPU_POWERPC_440SP2 = 0x53221891,
- CPU_POWERPC_440SPE = 0x53421890,
- /* PowerPC 460 family */
-#if 0
- /* Generic PowerPC 464 */
-#define CPU_POWERPC_464 CPU_POWERPC_464H90
-#endif
- /* PowerPC 464 microcontrolers */
-#if 0
- CPU_POWERPC_464H90 = xxx,
-#endif
-#if 0
- CPU_POWERPC_464H90FP = xxx,
-#endif
- /* Freescale embedded PowerPC cores */
- /* PowerPC MPC 5xx cores (aka RCPU) */
- CPU_POWERPC_MPC5xx = 0x00020020,
-#define CPU_POWERPC_MGT560 CPU_POWERPC_MPC5xx
-#define CPU_POWERPC_MPC509 CPU_POWERPC_MPC5xx
-#define CPU_POWERPC_MPC533 CPU_POWERPC_MPC5xx
-#define CPU_POWERPC_MPC534 CPU_POWERPC_MPC5xx
-#define CPU_POWERPC_MPC555 CPU_POWERPC_MPC5xx
-#define CPU_POWERPC_MPC556 CPU_POWERPC_MPC5xx
-#define CPU_POWERPC_MPC560 CPU_POWERPC_MPC5xx
-#define CPU_POWERPC_MPC561 CPU_POWERPC_MPC5xx
-#define CPU_POWERPC_MPC562 CPU_POWERPC_MPC5xx
-#define CPU_POWERPC_MPC563 CPU_POWERPC_MPC5xx
-#define CPU_POWERPC_MPC564 CPU_POWERPC_MPC5xx
-#define CPU_POWERPC_MPC565 CPU_POWERPC_MPC5xx
-#define CPU_POWERPC_MPC566 CPU_POWERPC_MPC5xx
- /* PowerPC MPC 8xx cores (aka PowerQUICC) */
- CPU_POWERPC_MPC8xx = 0x00500000,
-#define CPU_POWERPC_MGT823 CPU_POWERPC_MPC8xx
-#define CPU_POWERPC_MPC821 CPU_POWERPC_MPC8xx
-#define CPU_POWERPC_MPC823 CPU_POWERPC_MPC8xx
-#define CPU_POWERPC_MPC850 CPU_POWERPC_MPC8xx
-#define CPU_POWERPC_MPC852T CPU_POWERPC_MPC8xx
-#define CPU_POWERPC_MPC855T CPU_POWERPC_MPC8xx
-#define CPU_POWERPC_MPC857 CPU_POWERPC_MPC8xx
-#define CPU_POWERPC_MPC859 CPU_POWERPC_MPC8xx
-#define CPU_POWERPC_MPC860 CPU_POWERPC_MPC8xx
-#define CPU_POWERPC_MPC862 CPU_POWERPC_MPC8xx
-#define CPU_POWERPC_MPC866 CPU_POWERPC_MPC8xx
-#define CPU_POWERPC_MPC870 CPU_POWERPC_MPC8xx
-#define CPU_POWERPC_MPC875 CPU_POWERPC_MPC8xx
-#define CPU_POWERPC_MPC880 CPU_POWERPC_MPC8xx
-#define CPU_POWERPC_MPC885 CPU_POWERPC_MPC8xx
- /* G2 cores (aka PowerQUICC-II) */
- CPU_POWERPC_G2 = 0x00810011,
- CPU_POWERPC_G2H4 = 0x80811010,
- CPU_POWERPC_G2gp = 0x80821010,
- CPU_POWERPC_G2ls = 0x90810010,
- CPU_POWERPC_MPC603 = 0x00810100,
- CPU_POWERPC_G2_HIP3 = 0x00810101,
- CPU_POWERPC_G2_HIP4 = 0x80811014,
- /* G2_LE core (aka PowerQUICC-II) */
- CPU_POWERPC_G2LE = 0x80820010,
- CPU_POWERPC_G2LEgp = 0x80822010,
- CPU_POWERPC_G2LEls = 0xA0822010,
- CPU_POWERPC_G2LEgp1 = 0x80822011,
- CPU_POWERPC_G2LEgp3 = 0x80822013,
- /* MPC52xx microcontrollers */
- /* XXX: MPC 5121 ? */
-#define CPU_POWERPC_MPC52xx CPU_POWERPC_MPC5200
-#define CPU_POWERPC_MPC5200 CPU_POWERPC_MPC5200_v12
-#define CPU_POWERPC_MPC5200_v10 CPU_POWERPC_G2LEgp1
-#define CPU_POWERPC_MPC5200_v11 CPU_POWERPC_G2LEgp1
-#define CPU_POWERPC_MPC5200_v12 CPU_POWERPC_G2LEgp1
-#define CPU_POWERPC_MPC5200B CPU_POWERPC_MPC5200B_v21
-#define CPU_POWERPC_MPC5200B_v20 CPU_POWERPC_G2LEgp1
-#define CPU_POWERPC_MPC5200B_v21 CPU_POWERPC_G2LEgp1
- /* MPC82xx microcontrollers */
-#define CPU_POWERPC_MPC82xx CPU_POWERPC_MPC8280
-#define CPU_POWERPC_MPC8240 CPU_POWERPC_MPC603
-#define CPU_POWERPC_MPC8241 CPU_POWERPC_G2_HIP4
-#define CPU_POWERPC_MPC8245 CPU_POWERPC_G2_HIP4
-#define CPU_POWERPC_MPC8247 CPU_POWERPC_G2LEgp3
-#define CPU_POWERPC_MPC8248 CPU_POWERPC_G2LEgp3
-#define CPU_POWERPC_MPC8250 CPU_POWERPC_MPC8250_HiP4
-#define CPU_POWERPC_MPC8250_HiP3 CPU_POWERPC_G2_HIP3
-#define CPU_POWERPC_MPC8250_HiP4 CPU_POWERPC_G2_HIP4
-#define CPU_POWERPC_MPC8255 CPU_POWERPC_MPC8255_HiP4
-#define CPU_POWERPC_MPC8255_HiP3 CPU_POWERPC_G2_HIP3
-#define CPU_POWERPC_MPC8255_HiP4 CPU_POWERPC_G2_HIP4
-#define CPU_POWERPC_MPC8260 CPU_POWERPC_MPC8260_HiP4
-#define CPU_POWERPC_MPC8260_HiP3 CPU_POWERPC_G2_HIP3
-#define CPU_POWERPC_MPC8260_HiP4 CPU_POWERPC_G2_HIP4
-#define CPU_POWERPC_MPC8264 CPU_POWERPC_MPC8264_HiP4
-#define CPU_POWERPC_MPC8264_HiP3 CPU_POWERPC_G2_HIP3
-#define CPU_POWERPC_MPC8264_HiP4 CPU_POWERPC_G2_HIP4
-#define CPU_POWERPC_MPC8265 CPU_POWERPC_MPC8265_HiP4
-#define CPU_POWERPC_MPC8265_HiP3 CPU_POWERPC_G2_HIP3
-#define CPU_POWERPC_MPC8265_HiP4 CPU_POWERPC_G2_HIP4
-#define CPU_POWERPC_MPC8266 CPU_POWERPC_MPC8266_HiP4
-#define CPU_POWERPC_MPC8266_HiP3 CPU_POWERPC_G2_HIP3
-#define CPU_POWERPC_MPC8266_HiP4 CPU_POWERPC_G2_HIP4
-#define CPU_POWERPC_MPC8270 CPU_POWERPC_G2LEgp3
-#define CPU_POWERPC_MPC8271 CPU_POWERPC_G2LEgp3
-#define CPU_POWERPC_MPC8272 CPU_POWERPC_G2LEgp3
-#define CPU_POWERPC_MPC8275 CPU_POWERPC_G2LEgp3
-#define CPU_POWERPC_MPC8280 CPU_POWERPC_G2LEgp3
- /* e200 family */
- /* e200 cores */
-#define CPU_POWERPC_e200 CPU_POWERPC_e200z6
-#if 0
- CPU_POWERPC_e200z0 = xxx,
-#endif
-#if 0
- CPU_POWERPC_e200z1 = xxx,
-#endif
-#if 0 /* ? */
- CPU_POWERPC_e200z3 = 0x81120000,
-#endif
- CPU_POWERPC_e200z5 = 0x81000000,
- CPU_POWERPC_e200z6 = 0x81120000,
- /* MPC55xx microcontrollers */
-#define CPU_POWERPC_MPC55xx CPU_POWERPC_MPC5567
-#if 0
-#define CPU_POWERPC_MPC5514E CPU_POWERPC_MPC5514E_v1
-#define CPU_POWERPC_MPC5514E_v0 CPU_POWERPC_e200z0
-#define CPU_POWERPC_MPC5514E_v1 CPU_POWERPC_e200z1
-#define CPU_POWERPC_MPC5514G CPU_POWERPC_MPC5514G_v1
-#define CPU_POWERPC_MPC5514G_v0 CPU_POWERPC_e200z0
-#define CPU_POWERPC_MPC5514G_v1 CPU_POWERPC_e200z1
-#define CPU_POWERPC_MPC5515S CPU_POWERPC_e200z1
-#define CPU_POWERPC_MPC5516E CPU_POWERPC_MPC5516E_v1
-#define CPU_POWERPC_MPC5516E_v0 CPU_POWERPC_e200z0
-#define CPU_POWERPC_MPC5516E_v1 CPU_POWERPC_e200z1
-#define CPU_POWERPC_MPC5516G CPU_POWERPC_MPC5516G_v1
-#define CPU_POWERPC_MPC5516G_v0 CPU_POWERPC_e200z0
-#define CPU_POWERPC_MPC5516G_v1 CPU_POWERPC_e200z1
-#define CPU_POWERPC_MPC5516S CPU_POWERPC_e200z1
-#endif
-#if 0
-#define CPU_POWERPC_MPC5533 CPU_POWERPC_e200z3
-#define CPU_POWERPC_MPC5534 CPU_POWERPC_e200z3
-#endif
-#define CPU_POWERPC_MPC5553 CPU_POWERPC_e200z6
-#define CPU_POWERPC_MPC5554 CPU_POWERPC_e200z6
-#define CPU_POWERPC_MPC5561 CPU_POWERPC_e200z6
-#define CPU_POWERPC_MPC5565 CPU_POWERPC_e200z6
-#define CPU_POWERPC_MPC5566 CPU_POWERPC_e200z6
-#define CPU_POWERPC_MPC5567 CPU_POWERPC_e200z6
- /* e300 family */
- /* e300 cores */
-#define CPU_POWERPC_e300 CPU_POWERPC_e300c3
- CPU_POWERPC_e300c1 = 0x00830010,
- CPU_POWERPC_e300c2 = 0x00840010,
- CPU_POWERPC_e300c3 = 0x00850010,
- CPU_POWERPC_e300c4 = 0x00860010,
- /* MPC83xx microcontrollers */
-#define CPU_POWERPC_MPC831x CPU_POWERPC_e300c3
-#define CPU_POWERPC_MPC832x CPU_POWERPC_e300c2
-#define CPU_POWERPC_MPC834x CPU_POWERPC_e300c1
-#define CPU_POWERPC_MPC835x CPU_POWERPC_e300c1
-#define CPU_POWERPC_MPC836x CPU_POWERPC_e300c1
-#define CPU_POWERPC_MPC837x CPU_POWERPC_e300c4
- /* e500 family */
- /* e500 cores */
-#define CPU_POWERPC_e500 CPU_POWERPC_e500v2_v22
-#define CPU_POWERPC_e500v1 CPU_POWERPC_e500v1_v20
-#define CPU_POWERPC_e500v2 CPU_POWERPC_e500v2_v22
- CPU_POWERPC_e500v1_v10 = 0x80200010,
- CPU_POWERPC_e500v1_v20 = 0x80200020,
- CPU_POWERPC_e500v2_v10 = 0x80210010,
- CPU_POWERPC_e500v2_v11 = 0x80210011,
- CPU_POWERPC_e500v2_v20 = 0x80210020,
- CPU_POWERPC_e500v2_v21 = 0x80210021,
- CPU_POWERPC_e500v2_v22 = 0x80210022,
- CPU_POWERPC_e500v2_v30 = 0x80210030,
- CPU_POWERPC_e500mc = 0x80230020,
- CPU_POWERPC_e5500 = 0x80240020,
- /* MPC85xx microcontrollers */
-#define CPU_POWERPC_MPC8533 CPU_POWERPC_MPC8533_v11
-#define CPU_POWERPC_MPC8533_v10 CPU_POWERPC_e500v2_v21
-#define CPU_POWERPC_MPC8533_v11 CPU_POWERPC_e500v2_v22
-#define CPU_POWERPC_MPC8533E CPU_POWERPC_MPC8533E_v11
-#define CPU_POWERPC_MPC8533E_v10 CPU_POWERPC_e500v2_v21
-#define CPU_POWERPC_MPC8533E_v11 CPU_POWERPC_e500v2_v22
-#define CPU_POWERPC_MPC8540 CPU_POWERPC_MPC8540_v21
-#define CPU_POWERPC_MPC8540_v10 CPU_POWERPC_e500v1_v10
-#define CPU_POWERPC_MPC8540_v20 CPU_POWERPC_e500v1_v20
-#define CPU_POWERPC_MPC8540_v21 CPU_POWERPC_e500v1_v20
-#define CPU_POWERPC_MPC8541 CPU_POWERPC_MPC8541_v11
-#define CPU_POWERPC_MPC8541_v10 CPU_POWERPC_e500v1_v20
-#define CPU_POWERPC_MPC8541_v11 CPU_POWERPC_e500v1_v20
-#define CPU_POWERPC_MPC8541E CPU_POWERPC_MPC8541E_v11
-#define CPU_POWERPC_MPC8541E_v10 CPU_POWERPC_e500v1_v20
-#define CPU_POWERPC_MPC8541E_v11 CPU_POWERPC_e500v1_v20
-#define CPU_POWERPC_MPC8543 CPU_POWERPC_MPC8543_v21
-#define CPU_POWERPC_MPC8543_v10 CPU_POWERPC_e500v2_v10
-#define CPU_POWERPC_MPC8543_v11 CPU_POWERPC_e500v2_v11
-#define CPU_POWERPC_MPC8543_v20 CPU_POWERPC_e500v2_v20
-#define CPU_POWERPC_MPC8543_v21 CPU_POWERPC_e500v2_v21
-#define CPU_POWERPC_MPC8543E CPU_POWERPC_MPC8543E_v21
-#define CPU_POWERPC_MPC8543E_v10 CPU_POWERPC_e500v2_v10
-#define CPU_POWERPC_MPC8543E_v11 CPU_POWERPC_e500v2_v11
-#define CPU_POWERPC_MPC8543E_v20 CPU_POWERPC_e500v2_v20
-#define CPU_POWERPC_MPC8543E_v21 CPU_POWERPC_e500v2_v21
-#define CPU_POWERPC_MPC8544 CPU_POWERPC_MPC8544_v11
-#define CPU_POWERPC_MPC8544_v10 CPU_POWERPC_e500v2_v21
-#define CPU_POWERPC_MPC8544_v11 CPU_POWERPC_e500v2_v22
-#define CPU_POWERPC_MPC8544E_v11 CPU_POWERPC_e500v2_v22
-#define CPU_POWERPC_MPC8544E CPU_POWERPC_MPC8544E_v11
-#define CPU_POWERPC_MPC8544E_v10 CPU_POWERPC_e500v2_v21
-#define CPU_POWERPC_MPC8545 CPU_POWERPC_MPC8545_v21
-#define CPU_POWERPC_MPC8545_v10 CPU_POWERPC_e500v2_v10
-#define CPU_POWERPC_MPC8545_v20 CPU_POWERPC_e500v2_v20
-#define CPU_POWERPC_MPC8545_v21 CPU_POWERPC_e500v2_v21
-#define CPU_POWERPC_MPC8545E CPU_POWERPC_MPC8545E_v21
-#define CPU_POWERPC_MPC8545E_v10 CPU_POWERPC_e500v2_v10
-#define CPU_POWERPC_MPC8545E_v20 CPU_POWERPC_e500v2_v20
-#define CPU_POWERPC_MPC8545E_v21 CPU_POWERPC_e500v2_v21
-#define CPU_POWERPC_MPC8547E CPU_POWERPC_MPC8545E_v21
-#define CPU_POWERPC_MPC8547E_v10 CPU_POWERPC_e500v2_v10
-#define CPU_POWERPC_MPC8547E_v20 CPU_POWERPC_e500v2_v20
-#define CPU_POWERPC_MPC8547E_v21 CPU_POWERPC_e500v2_v21
-#define CPU_POWERPC_MPC8548 CPU_POWERPC_MPC8548_v21
-#define CPU_POWERPC_MPC8548_v10 CPU_POWERPC_e500v2_v10
-#define CPU_POWERPC_MPC8548_v11 CPU_POWERPC_e500v2_v11
-#define CPU_POWERPC_MPC8548_v20 CPU_POWERPC_e500v2_v20
-#define CPU_POWERPC_MPC8548_v21 CPU_POWERPC_e500v2_v21
-#define CPU_POWERPC_MPC8548E CPU_POWERPC_MPC8548E_v21
-#define CPU_POWERPC_MPC8548E_v10 CPU_POWERPC_e500v2_v10
-#define CPU_POWERPC_MPC8548E_v11 CPU_POWERPC_e500v2_v11
-#define CPU_POWERPC_MPC8548E_v20 CPU_POWERPC_e500v2_v20
-#define CPU_POWERPC_MPC8548E_v21 CPU_POWERPC_e500v2_v21
-#define CPU_POWERPC_MPC8555 CPU_POWERPC_MPC8555_v11
-#define CPU_POWERPC_MPC8555_v10 CPU_POWERPC_e500v2_v10
-#define CPU_POWERPC_MPC8555_v11 CPU_POWERPC_e500v2_v11
-#define CPU_POWERPC_MPC8555E CPU_POWERPC_MPC8555E_v11
-#define CPU_POWERPC_MPC8555E_v10 CPU_POWERPC_e500v2_v10
-#define CPU_POWERPC_MPC8555E_v11 CPU_POWERPC_e500v2_v11
-#define CPU_POWERPC_MPC8560 CPU_POWERPC_MPC8560_v21
-#define CPU_POWERPC_MPC8560_v10 CPU_POWERPC_e500v2_v10
-#define CPU_POWERPC_MPC8560_v20 CPU_POWERPC_e500v2_v20
-#define CPU_POWERPC_MPC8560_v21 CPU_POWERPC_e500v2_v21
-#define CPU_POWERPC_MPC8567 CPU_POWERPC_e500v2_v22
-#define CPU_POWERPC_MPC8567E CPU_POWERPC_e500v2_v22
-#define CPU_POWERPC_MPC8568 CPU_POWERPC_e500v2_v22
-#define CPU_POWERPC_MPC8568E CPU_POWERPC_e500v2_v22
-#define CPU_POWERPC_MPC8572 CPU_POWERPC_e500v2_v30
-#define CPU_POWERPC_MPC8572E CPU_POWERPC_e500v2_v30
- /* e600 family */
- /* e600 cores */
- CPU_POWERPC_e600 = 0x80040010,
- /* MPC86xx microcontrollers */
-#define CPU_POWERPC_MPC8610 CPU_POWERPC_e600
-#define CPU_POWERPC_MPC8641 CPU_POWERPC_e600
-#define CPU_POWERPC_MPC8641D CPU_POWERPC_e600
- /* PowerPC 6xx cores */
-#define CPU_POWERPC_601 CPU_POWERPC_601_v2
- CPU_POWERPC_601_v0 = 0x00010001,
- CPU_POWERPC_601_v1 = 0x00010001,
-#define CPU_POWERPC_601v CPU_POWERPC_601_v2
- CPU_POWERPC_601_v2 = 0x00010002,
- CPU_POWERPC_602 = 0x00050100,
- CPU_POWERPC_603 = 0x00030100,
-#define CPU_POWERPC_603E CPU_POWERPC_603E_v41
- CPU_POWERPC_603E_v11 = 0x00060101,
- CPU_POWERPC_603E_v12 = 0x00060102,
- CPU_POWERPC_603E_v13 = 0x00060103,
- CPU_POWERPC_603E_v14 = 0x00060104,
- CPU_POWERPC_603E_v22 = 0x00060202,
- CPU_POWERPC_603E_v3 = 0x00060300,
- CPU_POWERPC_603E_v4 = 0x00060400,
- CPU_POWERPC_603E_v41 = 0x00060401,
- CPU_POWERPC_603E7t = 0x00071201,
- CPU_POWERPC_603E7v = 0x00070100,
- CPU_POWERPC_603E7v1 = 0x00070101,
- CPU_POWERPC_603E7v2 = 0x00070201,
- CPU_POWERPC_603E7 = 0x00070200,
- CPU_POWERPC_603P = 0x00070000,
-#define CPU_POWERPC_603R CPU_POWERPC_603E7t
- /* XXX: missing 0x00040303 (604) */
- CPU_POWERPC_604 = 0x00040103,
-#define CPU_POWERPC_604E CPU_POWERPC_604E_v24
- /* XXX: missing 0x00091203 */
- /* XXX: missing 0x00092110 */
- /* XXX: missing 0x00092120 */
- CPU_POWERPC_604E_v10 = 0x00090100,
- CPU_POWERPC_604E_v22 = 0x00090202,
- CPU_POWERPC_604E_v24 = 0x00090204,
- /* XXX: missing 0x000a0100 */
- /* XXX: missing 0x00093102 */
- CPU_POWERPC_604R = 0x000a0101,
-#if 0
- CPU_POWERPC_604EV = xxx, /* XXX: same as 604R ? */
-#endif
- /* PowerPC 740/750 cores (aka G3) */
- /* XXX: missing 0x00084202 */
-#define CPU_POWERPC_7x0 CPU_POWERPC_7x0_v31
- CPU_POWERPC_7x0_v10 = 0x00080100,
- CPU_POWERPC_7x0_v20 = 0x00080200,
- CPU_POWERPC_7x0_v21 = 0x00080201,
- CPU_POWERPC_7x0_v22 = 0x00080202,
- CPU_POWERPC_7x0_v30 = 0x00080300,
- CPU_POWERPC_7x0_v31 = 0x00080301,
- CPU_POWERPC_740E = 0x00080100,
- CPU_POWERPC_750E = 0x00080200,
- CPU_POWERPC_7x0P = 0x10080000,
- /* XXX: missing 0x00087010 (CL ?) */
-#define CPU_POWERPC_750CL CPU_POWERPC_750CL_v20
- CPU_POWERPC_750CL_v10 = 0x00087200,
- CPU_POWERPC_750CL_v20 = 0x00087210, /* aka rev E */
-#define CPU_POWERPC_750CX CPU_POWERPC_750CX_v22
- CPU_POWERPC_750CX_v10 = 0x00082100,
- CPU_POWERPC_750CX_v20 = 0x00082200,
- CPU_POWERPC_750CX_v21 = 0x00082201,
- CPU_POWERPC_750CX_v22 = 0x00082202,
-#define CPU_POWERPC_750CXE CPU_POWERPC_750CXE_v31b
- CPU_POWERPC_750CXE_v21 = 0x00082211,
- CPU_POWERPC_750CXE_v22 = 0x00082212,
- CPU_POWERPC_750CXE_v23 = 0x00082213,
- CPU_POWERPC_750CXE_v24 = 0x00082214,
- CPU_POWERPC_750CXE_v24b = 0x00083214,
- CPU_POWERPC_750CXE_v30 = 0x00082310,
- CPU_POWERPC_750CXE_v31 = 0x00082311,
- CPU_POWERPC_750CXE_v31b = 0x00083311,
- CPU_POWERPC_750CXR = 0x00083410,
- CPU_POWERPC_750FL = 0x70000203,
-#define CPU_POWERPC_750FX CPU_POWERPC_750FX_v23
- CPU_POWERPC_750FX_v10 = 0x70000100,
- CPU_POWERPC_750FX_v20 = 0x70000200,
- CPU_POWERPC_750FX_v21 = 0x70000201,
- CPU_POWERPC_750FX_v22 = 0x70000202,
- CPU_POWERPC_750FX_v23 = 0x70000203,
- CPU_POWERPC_750GL = 0x70020102,
-#define CPU_POWERPC_750GX CPU_POWERPC_750GX_v12
- CPU_POWERPC_750GX_v10 = 0x70020100,
- CPU_POWERPC_750GX_v11 = 0x70020101,
- CPU_POWERPC_750GX_v12 = 0x70020102,
-#define CPU_POWERPC_750L CPU_POWERPC_750L_v32 /* Aka LoneStar */
- CPU_POWERPC_750L_v20 = 0x00088200,
- CPU_POWERPC_750L_v21 = 0x00088201,
- CPU_POWERPC_750L_v22 = 0x00088202,
- CPU_POWERPC_750L_v30 = 0x00088300,
- CPU_POWERPC_750L_v32 = 0x00088302,
- /* PowerPC 745/755 cores */
-#define CPU_POWERPC_7x5 CPU_POWERPC_7x5_v28
- CPU_POWERPC_7x5_v10 = 0x00083100,
- CPU_POWERPC_7x5_v11 = 0x00083101,
- CPU_POWERPC_7x5_v20 = 0x00083200,
- CPU_POWERPC_7x5_v21 = 0x00083201,
- CPU_POWERPC_7x5_v22 = 0x00083202, /* aka D */
- CPU_POWERPC_7x5_v23 = 0x00083203, /* aka E */
- CPU_POWERPC_7x5_v24 = 0x00083204,
- CPU_POWERPC_7x5_v25 = 0x00083205,
- CPU_POWERPC_7x5_v26 = 0x00083206,
- CPU_POWERPC_7x5_v27 = 0x00083207,
- CPU_POWERPC_7x5_v28 = 0x00083208,
-#if 0
- CPU_POWERPC_7x5P = xxx,
-#endif
- /* PowerPC 74xx cores (aka G4) */
- /* XXX: missing 0x000C1101 */
-#define CPU_POWERPC_7400 CPU_POWERPC_7400_v29
- CPU_POWERPC_7400_v10 = 0x000C0100,
- CPU_POWERPC_7400_v11 = 0x000C0101,
- CPU_POWERPC_7400_v20 = 0x000C0200,
- CPU_POWERPC_7400_v21 = 0x000C0201,
- CPU_POWERPC_7400_v22 = 0x000C0202,
- CPU_POWERPC_7400_v26 = 0x000C0206,
- CPU_POWERPC_7400_v27 = 0x000C0207,
- CPU_POWERPC_7400_v28 = 0x000C0208,
- CPU_POWERPC_7400_v29 = 0x000C0209,
-#define CPU_POWERPC_7410 CPU_POWERPC_7410_v14
- CPU_POWERPC_7410_v10 = 0x800C1100,
- CPU_POWERPC_7410_v11 = 0x800C1101,
- CPU_POWERPC_7410_v12 = 0x800C1102, /* aka C */
- CPU_POWERPC_7410_v13 = 0x800C1103, /* aka D */
- CPU_POWERPC_7410_v14 = 0x800C1104, /* aka E */
-#define CPU_POWERPC_7448 CPU_POWERPC_7448_v21
- CPU_POWERPC_7448_v10 = 0x80040100,
- CPU_POWERPC_7448_v11 = 0x80040101,
- CPU_POWERPC_7448_v20 = 0x80040200,
- CPU_POWERPC_7448_v21 = 0x80040201,
-#define CPU_POWERPC_7450 CPU_POWERPC_7450_v21
- CPU_POWERPC_7450_v10 = 0x80000100,
- CPU_POWERPC_7450_v11 = 0x80000101,
- CPU_POWERPC_7450_v12 = 0x80000102,
- CPU_POWERPC_7450_v20 = 0x80000200, /* aka A, B, C, D: 2.04 */
- CPU_POWERPC_7450_v21 = 0x80000201, /* aka E */
-#define CPU_POWERPC_74x1 CPU_POWERPC_74x1_v23
- CPU_POWERPC_74x1_v23 = 0x80000203, /* aka G: 2.3 */
- /* XXX: this entry might be a bug in some documentation */
- CPU_POWERPC_74x1_v210 = 0x80000210, /* aka G: 2.3 ? */
-#define CPU_POWERPC_74x5 CPU_POWERPC_74x5_v32
- CPU_POWERPC_74x5_v10 = 0x80010100,
- /* XXX: missing 0x80010200 */
- CPU_POWERPC_74x5_v21 = 0x80010201, /* aka C: 2.1 */
- CPU_POWERPC_74x5_v32 = 0x80010302,
- CPU_POWERPC_74x5_v33 = 0x80010303, /* aka F: 3.3 */
- CPU_POWERPC_74x5_v34 = 0x80010304, /* aka G: 3.4 */
-#define CPU_POWERPC_74x7 CPU_POWERPC_74x7_v12
- CPU_POWERPC_74x7_v10 = 0x80020100, /* aka A: 1.0 */
- CPU_POWERPC_74x7_v11 = 0x80020101, /* aka B: 1.1 */
- CPU_POWERPC_74x7_v12 = 0x80020102, /* aka C: 1.2 */
-#define CPU_POWERPC_74x7A CPU_POWERPC_74x7A_v12
- CPU_POWERPC_74x7A_v10 = 0x80030100, /* aka A: 1.0 */
- CPU_POWERPC_74x7A_v11 = 0x80030101, /* aka B: 1.1 */
- CPU_POWERPC_74x7A_v12 = 0x80030102, /* aka C: 1.2 */
- /* 64 bits PowerPC */
-#if defined(TARGET_PPC64)
- CPU_POWERPC_620 = 0x00140000,
- CPU_POWERPC_630 = 0x00400000,
- CPU_POWERPC_631 = 0x00410104,
- CPU_POWERPC_POWER4 = 0x00350000,
- CPU_POWERPC_POWER4P = 0x00380000,
- /* XXX: missing 0x003A0201 */
- CPU_POWERPC_POWER5 = 0x003A0203,
-#define CPU_POWERPC_POWER5GR CPU_POWERPC_POWER5
- CPU_POWERPC_POWER5P = 0x003B0000,
-#define CPU_POWERPC_POWER5GS CPU_POWERPC_POWER5P
- CPU_POWERPC_POWER6 = 0x003E0000,
- CPU_POWERPC_POWER6_5 = 0x0F000001, /* POWER6 in POWER5 mode */
- CPU_POWERPC_POWER6A = 0x0F000002,
-#define CPU_POWERPC_POWER7 CPU_POWERPC_POWER7_v20
- CPU_POWERPC_POWER7_v20 = 0x003F0200,
- CPU_POWERPC_POWER7_v21 = 0x003F0201,
- CPU_POWERPC_POWER7_v23 = 0x003F0203,
- CPU_POWERPC_970 = 0x00390202,
-#define CPU_POWERPC_970FX CPU_POWERPC_970FX_v31
- CPU_POWERPC_970FX_v10 = 0x00391100,
- CPU_POWERPC_970FX_v20 = 0x003C0200,
- CPU_POWERPC_970FX_v21 = 0x003C0201,
- CPU_POWERPC_970FX_v30 = 0x003C0300,
- CPU_POWERPC_970FX_v31 = 0x003C0301,
- CPU_POWERPC_970GX = 0x00450000,
-#define CPU_POWERPC_970MP CPU_POWERPC_970MP_v11
- CPU_POWERPC_970MP_v10 = 0x00440100,
- CPU_POWERPC_970MP_v11 = 0x00440101,
-#define CPU_POWERPC_CELL CPU_POWERPC_CELL_v32
- CPU_POWERPC_CELL_v10 = 0x00700100,
- CPU_POWERPC_CELL_v20 = 0x00700400,
- CPU_POWERPC_CELL_v30 = 0x00700500,
- CPU_POWERPC_CELL_v31 = 0x00700501,
-#define CPU_POWERPC_CELL_v32 CPU_POWERPC_CELL_v31
- CPU_POWERPC_RS64 = 0x00330000,
- CPU_POWERPC_RS64II = 0x00340000,
- CPU_POWERPC_RS64III = 0x00360000,
- CPU_POWERPC_RS64IV = 0x00370000,
-#endif /* defined(TARGET_PPC64) */
- /* Original POWER */
- /* XXX: should be POWER (RIOS), RSC3308, RSC4608,
- * POWER2 (RIOS2) & RSC2 (P2SC) here
- */
-#if 0
- CPU_POWER = xxx, /* 0x20000 ? 0x30000 for RSC ? */
-#endif
-#if 0
- CPU_POWER2 = xxx, /* 0x40000 ? */
-#endif
- /* PA Semi core */
- CPU_POWERPC_PA6T = 0x00900000,
-};
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-/* System version register (used on MPC 8xxx) */
-enum {
- POWERPC_SVR_NONE = 0x00000000,
-#define POWERPC_SVR_52xx POWERPC_SVR_5200
-#define POWERPC_SVR_5200 POWERPC_SVR_5200_v12
- POWERPC_SVR_5200_v10 = 0x80110010,
- POWERPC_SVR_5200_v11 = 0x80110011,
- POWERPC_SVR_5200_v12 = 0x80110012,
-#define POWERPC_SVR_5200B POWERPC_SVR_5200B_v21
- POWERPC_SVR_5200B_v20 = 0x80110020,
- POWERPC_SVR_5200B_v21 = 0x80110021,
-#define POWERPC_SVR_55xx POWERPC_SVR_5567
-#if 0
- POWERPC_SVR_5533 = xxx,
-#endif
-#if 0
- POWERPC_SVR_5534 = xxx,
-#endif
-#if 0
- POWERPC_SVR_5553 = xxx,
-#endif
-#if 0
- POWERPC_SVR_5554 = xxx,
-#endif
-#if 0
- POWERPC_SVR_5561 = xxx,
-#endif
-#if 0
- POWERPC_SVR_5565 = xxx,
-#endif
-#if 0
- POWERPC_SVR_5566 = xxx,
-#endif
-#if 0
- POWERPC_SVR_5567 = xxx,
-#endif
-#if 0
- POWERPC_SVR_8313 = xxx,
-#endif
-#if 0
- POWERPC_SVR_8313E = xxx,
-#endif
-#if 0
- POWERPC_SVR_8314 = xxx,
-#endif
-#if 0
- POWERPC_SVR_8314E = xxx,
-#endif
-#if 0
- POWERPC_SVR_8315 = xxx,
-#endif
-#if 0
- POWERPC_SVR_8315E = xxx,
-#endif
-#if 0
- POWERPC_SVR_8321 = xxx,
-#endif
-#if 0
- POWERPC_SVR_8321E = xxx,
-#endif
-#if 0
- POWERPC_SVR_8323 = xxx,
-#endif
-#if 0
- POWERPC_SVR_8323E = xxx,
-#endif
- POWERPC_SVR_8343 = 0x80570010,
- POWERPC_SVR_8343A = 0x80570030,
- POWERPC_SVR_8343E = 0x80560010,
- POWERPC_SVR_8343EA = 0x80560030,
-#define POWERPC_SVR_8347 POWERPC_SVR_8347T
- POWERPC_SVR_8347P = 0x80550010, /* PBGA package */
- POWERPC_SVR_8347T = 0x80530010, /* TBGA package */
-#define POWERPC_SVR_8347A POWERPC_SVR_8347AT
- POWERPC_SVR_8347AP = 0x80550030, /* PBGA package */
- POWERPC_SVR_8347AT = 0x80530030, /* TBGA package */
-#define POWERPC_SVR_8347E POWERPC_SVR_8347ET
- POWERPC_SVR_8347EP = 0x80540010, /* PBGA package */
- POWERPC_SVR_8347ET = 0x80520010, /* TBGA package */
-#define POWERPC_SVR_8347EA POWERPC_SVR_8347EAT
- POWERPC_SVR_8347EAP = 0x80540030, /* PBGA package */
- POWERPC_SVR_8347EAT = 0x80520030, /* TBGA package */
- POWERPC_SVR_8349 = 0x80510010,
- POWERPC_SVR_8349A = 0x80510030,
- POWERPC_SVR_8349E = 0x80500010,
- POWERPC_SVR_8349EA = 0x80500030,
-#if 0
- POWERPC_SVR_8358E = xxx,
-#endif
-#if 0
- POWERPC_SVR_8360E = xxx,
-#endif
-#define POWERPC_SVR_E500 0x40000000
- POWERPC_SVR_8377 = 0x80C70010 | POWERPC_SVR_E500,
- POWERPC_SVR_8377E = 0x80C60010 | POWERPC_SVR_E500,
- POWERPC_SVR_8378 = 0x80C50010 | POWERPC_SVR_E500,
- POWERPC_SVR_8378E = 0x80C40010 | POWERPC_SVR_E500,
- POWERPC_SVR_8379 = 0x80C30010 | POWERPC_SVR_E500,
- POWERPC_SVR_8379E = 0x80C00010 | POWERPC_SVR_E500,
-#define POWERPC_SVR_8533 POWERPC_SVR_8533_v11
- POWERPC_SVR_8533_v10 = 0x80340010 | POWERPC_SVR_E500,
- POWERPC_SVR_8533_v11 = 0x80340011 | POWERPC_SVR_E500,
-#define POWERPC_SVR_8533E POWERPC_SVR_8533E_v11
- POWERPC_SVR_8533E_v10 = 0x803C0010 | POWERPC_SVR_E500,
- POWERPC_SVR_8533E_v11 = 0x803C0011 | POWERPC_SVR_E500,
-#define POWERPC_SVR_8540 POWERPC_SVR_8540_v21
- POWERPC_SVR_8540_v10 = 0x80300010 | POWERPC_SVR_E500,
- POWERPC_SVR_8540_v20 = 0x80300020 | POWERPC_SVR_E500,
- POWERPC_SVR_8540_v21 = 0x80300021 | POWERPC_SVR_E500,
-#define POWERPC_SVR_8541 POWERPC_SVR_8541_v11
- POWERPC_SVR_8541_v10 = 0x80720010 | POWERPC_SVR_E500,
- POWERPC_SVR_8541_v11 = 0x80720011 | POWERPC_SVR_E500,
-#define POWERPC_SVR_8541E POWERPC_SVR_8541E_v11
- POWERPC_SVR_8541E_v10 = 0x807A0010 | POWERPC_SVR_E500,
- POWERPC_SVR_8541E_v11 = 0x807A0011 | POWERPC_SVR_E500,
-#define POWERPC_SVR_8543 POWERPC_SVR_8543_v21
- POWERPC_SVR_8543_v10 = 0x80320010 | POWERPC_SVR_E500,
- POWERPC_SVR_8543_v11 = 0x80320011 | POWERPC_SVR_E500,
- POWERPC_SVR_8543_v20 = 0x80320020 | POWERPC_SVR_E500,
- POWERPC_SVR_8543_v21 = 0x80320021 | POWERPC_SVR_E500,
-#define POWERPC_SVR_8543E POWERPC_SVR_8543E_v21
- POWERPC_SVR_8543E_v10 = 0x803A0010 | POWERPC_SVR_E500,
- POWERPC_SVR_8543E_v11 = 0x803A0011 | POWERPC_SVR_E500,
- POWERPC_SVR_8543E_v20 = 0x803A0020 | POWERPC_SVR_E500,
- POWERPC_SVR_8543E_v21 = 0x803A0021 | POWERPC_SVR_E500,
-#define POWERPC_SVR_8544 POWERPC_SVR_8544_v11
- POWERPC_SVR_8544_v10 = 0x80340110 | POWERPC_SVR_E500,
- POWERPC_SVR_8544_v11 = 0x80340111 | POWERPC_SVR_E500,
-#define POWERPC_SVR_8544E POWERPC_SVR_8544E_v11
- POWERPC_SVR_8544E_v10 = 0x803C0110 | POWERPC_SVR_E500,
- POWERPC_SVR_8544E_v11 = 0x803C0111 | POWERPC_SVR_E500,
-#define POWERPC_SVR_8545 POWERPC_SVR_8545_v21
- POWERPC_SVR_8545_v20 = 0x80310220 | POWERPC_SVR_E500,
- POWERPC_SVR_8545_v21 = 0x80310221 | POWERPC_SVR_E500,
-#define POWERPC_SVR_8545E POWERPC_SVR_8545E_v21
- POWERPC_SVR_8545E_v20 = 0x80390220 | POWERPC_SVR_E500,
- POWERPC_SVR_8545E_v21 = 0x80390221 | POWERPC_SVR_E500,
-#define POWERPC_SVR_8547E POWERPC_SVR_8547E_v21
- POWERPC_SVR_8547E_v20 = 0x80390120 | POWERPC_SVR_E500,
- POWERPC_SVR_8547E_v21 = 0x80390121 | POWERPC_SVR_E500,
-#define POWERPC_SVR_8548 POWERPC_SVR_8548_v21
- POWERPC_SVR_8548_v10 = 0x80310010 | POWERPC_SVR_E500,
- POWERPC_SVR_8548_v11 = 0x80310011 | POWERPC_SVR_E500,
- POWERPC_SVR_8548_v20 = 0x80310020 | POWERPC_SVR_E500,
- POWERPC_SVR_8548_v21 = 0x80310021 | POWERPC_SVR_E500,
-#define POWERPC_SVR_8548E POWERPC_SVR_8548E_v21
- POWERPC_SVR_8548E_v10 = 0x80390010 | POWERPC_SVR_E500,
- POWERPC_SVR_8548E_v11 = 0x80390011 | POWERPC_SVR_E500,
- POWERPC_SVR_8548E_v20 = 0x80390020 | POWERPC_SVR_E500,
- POWERPC_SVR_8548E_v21 = 0x80390021 | POWERPC_SVR_E500,
-#define POWERPC_SVR_8555 POWERPC_SVR_8555_v11
- POWERPC_SVR_8555_v10 = 0x80710010 | POWERPC_SVR_E500,
- POWERPC_SVR_8555_v11 = 0x80710011 | POWERPC_SVR_E500,
-#define POWERPC_SVR_8555E POWERPC_SVR_8555_v11
- POWERPC_SVR_8555E_v10 = 0x80790010 | POWERPC_SVR_E500,
- POWERPC_SVR_8555E_v11 = 0x80790011 | POWERPC_SVR_E500,
-#define POWERPC_SVR_8560 POWERPC_SVR_8560_v21
- POWERPC_SVR_8560_v10 = 0x80700010 | POWERPC_SVR_E500,
- POWERPC_SVR_8560_v20 = 0x80700020 | POWERPC_SVR_E500,
- POWERPC_SVR_8560_v21 = 0x80700021 | POWERPC_SVR_E500,
- POWERPC_SVR_8567 = 0x80750111 | POWERPC_SVR_E500,
- POWERPC_SVR_8567E = 0x807D0111 | POWERPC_SVR_E500,
- POWERPC_SVR_8568 = 0x80750011 | POWERPC_SVR_E500,
- POWERPC_SVR_8568E = 0x807D0011 | POWERPC_SVR_E500,
- POWERPC_SVR_8572 = 0x80E00010 | POWERPC_SVR_E500,
- POWERPC_SVR_8572E = 0x80E80010 | POWERPC_SVR_E500,
-#if 0
- POWERPC_SVR_8610 = xxx,
-#endif
- POWERPC_SVR_8641 = 0x80900021,
- POWERPC_SVR_8641D = 0x80900121,
-};
+ dc->desc = "POWER7";
+ pcc->init_proc = init_proc_POWER7;
+ pcc->check_pow = check_pow_nocheck;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
+ PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
+ PPC_64B | PPC_ALTIVEC |
+ PPC_SEGMENT_64B | PPC_SLBI |
+ PPC_POPCNTB | PPC_POPCNTWD;
+ pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205;
+ pcc->msr_mask = 0x800000000204FF36ULL;
+ pcc->mmu_model = POWERPC_MMU_2_06;
+#if defined(CONFIG_SOFTMMU)
+ pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
+#endif
+ pcc->excp_model = POWERPC_EXCP_POWER7;
+ pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
+ pcc->bfd_mach = bfd_mach_ppc64;
+ pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
+ POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
+ POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR;
+ pcc->l1_dcache_size = 0x8000;
+ pcc->l1_icache_size = 0x8000;
+}
+
+POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-/*****************************************************************************/
-/* PowerPC CPU definitions */
-#define POWERPC_DEF_SVR(_name, _pvr, _svr, _type) \
- { \
- .name = _name, \
- .pvr = _pvr, \
- .svr = _svr, \
- .insns_flags = glue(POWERPC_INSNS_,_type), \
- .insns_flags2 = glue(POWERPC_INSNS2_,_type), \
- .msr_mask = glue(POWERPC_MSRM_,_type), \
- .mmu_model = glue(POWERPC_MMU_,_type), \
- .excp_model = glue(POWERPC_EXCP_,_type), \
- .bus_model = glue(POWERPC_INPUT_,_type), \
- .bfd_mach = glue(POWERPC_BFDM_,_type), \
- .flags = glue(POWERPC_FLAG_,_type), \
- .init_proc = &glue(init_proc_,_type), \
- .check_pow = &glue(check_pow_,_type), \
- }
-#define POWERPC_DEF(_name, _pvr, _type) \
-POWERPC_DEF_SVR(_name, _pvr, POWERPC_SVR_NONE, _type)
-
-static const ppc_def_t ppc_defs[] = {
- /* Embedded PowerPC */
- /* PowerPC 401 family */
- /* Generic PowerPC 401 */
- POWERPC_DEF("401", CPU_POWERPC_401, 401),
- /* PowerPC 401 cores */
- /* PowerPC 401A1 */
- POWERPC_DEF("401A1", CPU_POWERPC_401A1, 401),
- /* PowerPC 401B2 */
- POWERPC_DEF("401B2", CPU_POWERPC_401B2, 401x2),
-#if defined (TODO)
- /* PowerPC 401B3 */
- POWERPC_DEF("401B3", CPU_POWERPC_401B3, 401x3),
-#endif
- /* PowerPC 401C2 */
- POWERPC_DEF("401C2", CPU_POWERPC_401C2, 401x2),
- /* PowerPC 401D2 */
- POWERPC_DEF("401D2", CPU_POWERPC_401D2, 401x2),
- /* PowerPC 401E2 */
- POWERPC_DEF("401E2", CPU_POWERPC_401E2, 401x2),
- /* PowerPC 401F2 */
- POWERPC_DEF("401F2", CPU_POWERPC_401F2, 401x2),
- /* PowerPC 401G2 */
- /* XXX: to be checked */
- POWERPC_DEF("401G2", CPU_POWERPC_401G2, 401x2),
- /* PowerPC 401 microcontrolers */
-#if defined (TODO)
- /* PowerPC 401GF */
- POWERPC_DEF("401GF", CPU_POWERPC_401GF, 401),
-#endif
- /* IOP480 (401 microcontroler) */
- POWERPC_DEF("IOP480", CPU_POWERPC_IOP480, IOP480),
- /* IBM Processor for Network Resources */
- POWERPC_DEF("Cobra", CPU_POWERPC_COBRA, 401),
-#if defined (TODO)
- POWERPC_DEF("Xipchip", CPU_POWERPC_XIPCHIP, 401),
-#endif
- /* PowerPC 403 family */
- /* Generic PowerPC 403 */
- POWERPC_DEF("403", CPU_POWERPC_403, 403),
- /* PowerPC 403 microcontrolers */
- /* PowerPC 403 GA */
- POWERPC_DEF("403GA", CPU_POWERPC_403GA, 403),
- /* PowerPC 403 GB */
- POWERPC_DEF("403GB", CPU_POWERPC_403GB, 403),
- /* PowerPC 403 GC */
- POWERPC_DEF("403GC", CPU_POWERPC_403GC, 403),
- /* PowerPC 403 GCX */
- POWERPC_DEF("403GCX", CPU_POWERPC_403GCX, 403GCX),
-#if defined (TODO)
- /* PowerPC 403 GP */
- POWERPC_DEF("403GP", CPU_POWERPC_403GP, 403),
-#endif
- /* PowerPC 405 family */
- /* Generic PowerPC 405 */
- POWERPC_DEF("405", CPU_POWERPC_405, 405),
- /* PowerPC 405 cores */
-#if defined (TODO)
- /* PowerPC 405 A3 */
- POWERPC_DEF("405A3", CPU_POWERPC_405A3, 405),
-#endif
-#if defined (TODO)
- /* PowerPC 405 A4 */
- POWERPC_DEF("405A4", CPU_POWERPC_405A4, 405),
-#endif
-#if defined (TODO)
- /* PowerPC 405 B3 */
- POWERPC_DEF("405B3", CPU_POWERPC_405B3, 405),
-#endif
-#if defined (TODO)
- /* PowerPC 405 B4 */
- POWERPC_DEF("405B4", CPU_POWERPC_405B4, 405),
-#endif
-#if defined (TODO)
- /* PowerPC 405 C3 */
- POWERPC_DEF("405C3", CPU_POWERPC_405C3, 405),
-#endif
-#if defined (TODO)
- /* PowerPC 405 C4 */
- POWERPC_DEF("405C4", CPU_POWERPC_405C4, 405),
-#endif
- /* PowerPC 405 D2 */
- POWERPC_DEF("405D2", CPU_POWERPC_405D2, 405),
-#if defined (TODO)
- /* PowerPC 405 D3 */
- POWERPC_DEF("405D3", CPU_POWERPC_405D3, 405),
-#endif
- /* PowerPC 405 D4 */
- POWERPC_DEF("405D4", CPU_POWERPC_405D4, 405),
-#if defined (TODO)
- /* PowerPC 405 D5 */
- POWERPC_DEF("405D5", CPU_POWERPC_405D5, 405),
-#endif
-#if defined (TODO)
- /* PowerPC 405 E4 */
- POWERPC_DEF("405E4", CPU_POWERPC_405E4, 405),
-#endif
-#if defined (TODO)
- /* PowerPC 405 F4 */
- POWERPC_DEF("405F4", CPU_POWERPC_405F4, 405),
-#endif
-#if defined (TODO)
- /* PowerPC 405 F5 */
- POWERPC_DEF("405F5", CPU_POWERPC_405F5, 405),
-#endif
-#if defined (TODO)
- /* PowerPC 405 F6 */
- POWERPC_DEF("405F6", CPU_POWERPC_405F6, 405),
-#endif
- /* PowerPC 405 microcontrolers */
- /* PowerPC 405 CR */
- POWERPC_DEF("405CR", CPU_POWERPC_405CR, 405),
- /* PowerPC 405 CRa */
- POWERPC_DEF("405CRa", CPU_POWERPC_405CRa, 405),
- /* PowerPC 405 CRb */
- POWERPC_DEF("405CRb", CPU_POWERPC_405CRb, 405),
- /* PowerPC 405 CRc */
- POWERPC_DEF("405CRc", CPU_POWERPC_405CRc, 405),
- /* PowerPC 405 EP */
- POWERPC_DEF("405EP", CPU_POWERPC_405EP, 405),
-#if defined(TODO)
- /* PowerPC 405 EXr */
- POWERPC_DEF("405EXr", CPU_POWERPC_405EXr, 405),
-#endif
- /* PowerPC 405 EZ */
- POWERPC_DEF("405EZ", CPU_POWERPC_405EZ, 405),
-#if defined(TODO)
- /* PowerPC 405 FX */
- POWERPC_DEF("405FX", CPU_POWERPC_405FX, 405),
-#endif
- /* PowerPC 405 GP */
- POWERPC_DEF("405GP", CPU_POWERPC_405GP, 405),
- /* PowerPC 405 GPa */
- POWERPC_DEF("405GPa", CPU_POWERPC_405GPa, 405),
- /* PowerPC 405 GPb */
- POWERPC_DEF("405GPb", CPU_POWERPC_405GPb, 405),
- /* PowerPC 405 GPc */
- POWERPC_DEF("405GPc", CPU_POWERPC_405GPc, 405),
- /* PowerPC 405 GPd */
- POWERPC_DEF("405GPd", CPU_POWERPC_405GPd, 405),
- /* PowerPC 405 GPe */
- POWERPC_DEF("405GPe", CPU_POWERPC_405GPe, 405),
- /* PowerPC 405 GPR */
- POWERPC_DEF("405GPR", CPU_POWERPC_405GPR, 405),
-#if defined(TODO)
- /* PowerPC 405 H */
- POWERPC_DEF("405H", CPU_POWERPC_405H, 405),
-#endif
-#if defined(TODO)
- /* PowerPC 405 L */
- POWERPC_DEF("405L", CPU_POWERPC_405L, 405),
-#endif
- /* PowerPC 405 LP */
- POWERPC_DEF("405LP", CPU_POWERPC_405LP, 405),
-#if defined(TODO)
- /* PowerPC 405 PM */
- POWERPC_DEF("405PM", CPU_POWERPC_405PM, 405),
-#endif
-#if defined(TODO)
- /* PowerPC 405 PS */
- POWERPC_DEF("405PS", CPU_POWERPC_405PS, 405),
-#endif
-#if defined(TODO)
- /* PowerPC 405 S */
- POWERPC_DEF("405S", CPU_POWERPC_405S, 405),
-#endif
- /* Npe405 H */
- POWERPC_DEF("Npe405H", CPU_POWERPC_NPE405H, 405),
- /* Npe405 H2 */
- POWERPC_DEF("Npe405H2", CPU_POWERPC_NPE405H2, 405),
- /* Npe405 L */
- POWERPC_DEF("Npe405L", CPU_POWERPC_NPE405L, 405),
- /* Npe4GS3 */
- POWERPC_DEF("Npe4GS3", CPU_POWERPC_NPE4GS3, 405),
-#if defined (TODO)
- POWERPC_DEF("Npcxx1", CPU_POWERPC_NPCxx1, 405),
-#endif
-#if defined (TODO)
- POWERPC_DEF("Npr161", CPU_POWERPC_NPR161, 405),
-#endif
-#if defined (TODO)
- /* PowerPC LC77700 (Sanyo) */
- POWERPC_DEF("LC77700", CPU_POWERPC_LC77700, 405),
-#endif
- /* PowerPC 401/403/405 based set-top-box microcontrolers */
-#if defined (TODO)
- /* STB010000 */
- POWERPC_DEF("STB01000", CPU_POWERPC_STB01000, 401x2),
-#endif
-#if defined (TODO)
- /* STB01010 */
- POWERPC_DEF("STB01010", CPU_POWERPC_STB01010, 401x2),
-#endif
-#if defined (TODO)
- /* STB0210 */
- POWERPC_DEF("STB0210", CPU_POWERPC_STB0210, 401x3),
-#endif
- /* STB03xx */
- POWERPC_DEF("STB03", CPU_POWERPC_STB03, 405),
-#if defined (TODO)
- /* STB043x */
- POWERPC_DEF("STB043", CPU_POWERPC_STB043, 405),
-#endif
-#if defined (TODO)
- /* STB045x */
- POWERPC_DEF("STB045", CPU_POWERPC_STB045, 405),
-#endif
- /* STB04xx */
- POWERPC_DEF("STB04", CPU_POWERPC_STB04, 405),
- /* STB25xx */
- POWERPC_DEF("STB25", CPU_POWERPC_STB25, 405),
-#if defined (TODO)
- /* STB130 */
- POWERPC_DEF("STB130", CPU_POWERPC_STB130, 405),
-#endif
- /* Xilinx PowerPC 405 cores */
- POWERPC_DEF("x2vp4", CPU_POWERPC_X2VP4, 405),
- POWERPC_DEF("x2vp7", CPU_POWERPC_X2VP7, 405),
- POWERPC_DEF("x2vp20", CPU_POWERPC_X2VP20, 405),
- POWERPC_DEF("x2vp50", CPU_POWERPC_X2VP50, 405),
-#if defined (TODO)
- /* Zarlink ZL10310 */
- POWERPC_DEF("zl10310", CPU_POWERPC_ZL10310, 405),
-#endif
-#if defined (TODO)
- /* Zarlink ZL10311 */
- POWERPC_DEF("zl10311", CPU_POWERPC_ZL10311, 405),
-#endif
-#if defined (TODO)
- /* Zarlink ZL10320 */
- POWERPC_DEF("zl10320", CPU_POWERPC_ZL10320, 405),
-#endif
-#if defined (TODO)
- /* Zarlink ZL10321 */
- POWERPC_DEF("zl10321", CPU_POWERPC_ZL10321, 405),
-#endif
- /* PowerPC 440 family */
-#if defined(TODO_USER_ONLY)
- /* Generic PowerPC 440 */
- POWERPC_DEF("440", CPU_POWERPC_440, 440GP),
-#endif
- /* PowerPC 440 cores */
-#if defined (TODO)
- /* PowerPC 440 A4 */
- POWERPC_DEF("440A4", CPU_POWERPC_440A4, 440x4),
-#endif
- /* PowerPC 440 Xilinx 5 */
- POWERPC_DEF("440-Xilinx", CPU_POWERPC_440_XILINX, 440x5),
-#if defined (TODO)
- /* PowerPC 440 A5 */
- POWERPC_DEF("440A5", CPU_POWERPC_440A5, 440x5),
-#endif
-#if defined (TODO)
- /* PowerPC 440 B4 */
- POWERPC_DEF("440B4", CPU_POWERPC_440B4, 440x4),
-#endif
-#if defined (TODO)
- /* PowerPC 440 G4 */
- POWERPC_DEF("440G4", CPU_POWERPC_440G4, 440x4),
-#endif
-#if defined (TODO)
- /* PowerPC 440 F5 */
- POWERPC_DEF("440F5", CPU_POWERPC_440F5, 440x5),
-#endif
-#if defined (TODO)
- /* PowerPC 440 G5 */
- POWERPC_DEF("440G5", CPU_POWERPC_440G5, 440x5),
-#endif
-#if defined (TODO)
- /* PowerPC 440H4 */
- POWERPC_DEF("440H4", CPU_POWERPC_440H4, 440x4),
-#endif
-#if defined (TODO)
- /* PowerPC 440H6 */
- POWERPC_DEF("440H6", CPU_POWERPC_440H6, 440Gx5),
-#endif
- /* PowerPC 440 microcontrolers */
- /* PowerPC 440 EP */
- POWERPC_DEF("440EP", CPU_POWERPC_440EP, 440EP),
- /* PowerPC 440 EPa */
- POWERPC_DEF("440EPa", CPU_POWERPC_440EPa, 440EP),
- /* PowerPC 440 EPb */
- POWERPC_DEF("440EPb", CPU_POWERPC_440EPb, 440EP),
- /* PowerPC 440 EPX */
- POWERPC_DEF("440EPX", CPU_POWERPC_440EPX, 440EP),
-#if defined(TODO_USER_ONLY)
- /* PowerPC 440 GP */
- POWERPC_DEF("440GP", CPU_POWERPC_440GP, 440GP),
-#endif
-#if defined(TODO_USER_ONLY)
- /* PowerPC 440 GPb */
- POWERPC_DEF("440GPb", CPU_POWERPC_440GPb, 440GP),
-#endif
-#if defined(TODO_USER_ONLY)
- /* PowerPC 440 GPc */
- POWERPC_DEF("440GPc", CPU_POWERPC_440GPc, 440GP),
-#endif
-#if defined(TODO_USER_ONLY)
- /* PowerPC 440 GR */
- POWERPC_DEF("440GR", CPU_POWERPC_440GR, 440x5),
-#endif
-#if defined(TODO_USER_ONLY)
- /* PowerPC 440 GRa */
- POWERPC_DEF("440GRa", CPU_POWERPC_440GRa, 440x5),
-#endif
-#if defined(TODO_USER_ONLY)
- /* PowerPC 440 GRX */
- POWERPC_DEF("440GRX", CPU_POWERPC_440GRX, 440x5),
-#endif
-#if defined(TODO_USER_ONLY)
- /* PowerPC 440 GX */
- POWERPC_DEF("440GX", CPU_POWERPC_440GX, 440EP),
-#endif
-#if defined(TODO_USER_ONLY)
- /* PowerPC 440 GXa */
- POWERPC_DEF("440GXa", CPU_POWERPC_440GXa, 440EP),
-#endif
-#if defined(TODO_USER_ONLY)
- /* PowerPC 440 GXb */
- POWERPC_DEF("440GXb", CPU_POWERPC_440GXb, 440EP),
-#endif
-#if defined(TODO_USER_ONLY)
- /* PowerPC 440 GXc */
- POWERPC_DEF("440GXc", CPU_POWERPC_440GXc, 440EP),
-#endif
-#if defined(TODO_USER_ONLY)
- /* PowerPC 440 GXf */
- POWERPC_DEF("440GXf", CPU_POWERPC_440GXf, 440EP),
-#endif
-#if defined(TODO)
- /* PowerPC 440 S */
- POWERPC_DEF("440S", CPU_POWERPC_440S, 440),
-#endif
-#if defined(TODO_USER_ONLY)
- /* PowerPC 440 SP */
- POWERPC_DEF("440SP", CPU_POWERPC_440SP, 440EP),
-#endif
-#if defined(TODO_USER_ONLY)
- /* PowerPC 440 SP2 */
- POWERPC_DEF("440SP2", CPU_POWERPC_440SP2, 440EP),
-#endif
-#if defined(TODO_USER_ONLY)
- /* PowerPC 440 SPE */
- POWERPC_DEF("440SPE", CPU_POWERPC_440SPE, 440EP),
-#endif
- /* PowerPC 460 family */
-#if defined (TODO)
- /* Generic PowerPC 464 */
- POWERPC_DEF("464", CPU_POWERPC_464, 460),
-#endif
- /* PowerPC 464 microcontrolers */
-#if defined (TODO)
- /* PowerPC 464H90 */
- POWERPC_DEF("464H90", CPU_POWERPC_464H90, 460),
-#endif
-#if defined (TODO)
- /* PowerPC 464H90F */
- POWERPC_DEF("464H90F", CPU_POWERPC_464H90F, 460F),
-#endif
- /* Freescale embedded PowerPC cores */
- /* MPC5xx family (aka RCPU) */
-#if defined(TODO_USER_ONLY)
- /* Generic MPC5xx core */
- POWERPC_DEF("MPC5xx", CPU_POWERPC_MPC5xx, MPC5xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* Codename for MPC5xx core */
- POWERPC_DEF("RCPU", CPU_POWERPC_MPC5xx, MPC5xx),
-#endif
- /* MPC5xx microcontrollers */
-#if defined(TODO_USER_ONLY)
- /* MGT560 */
- POWERPC_DEF("MGT560", CPU_POWERPC_MGT560, MPC5xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC509 */
- POWERPC_DEF("MPC509", CPU_POWERPC_MPC509, MPC5xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC533 */
- POWERPC_DEF("MPC533", CPU_POWERPC_MPC533, MPC5xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC534 */
- POWERPC_DEF("MPC534", CPU_POWERPC_MPC534, MPC5xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC555 */
- POWERPC_DEF("MPC555", CPU_POWERPC_MPC555, MPC5xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC556 */
- POWERPC_DEF("MPC556", CPU_POWERPC_MPC556, MPC5xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC560 */
- POWERPC_DEF("MPC560", CPU_POWERPC_MPC560, MPC5xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC561 */
- POWERPC_DEF("MPC561", CPU_POWERPC_MPC561, MPC5xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC562 */
- POWERPC_DEF("MPC562", CPU_POWERPC_MPC562, MPC5xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC563 */
- POWERPC_DEF("MPC563", CPU_POWERPC_MPC563, MPC5xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC564 */
- POWERPC_DEF("MPC564", CPU_POWERPC_MPC564, MPC5xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC565 */
- POWERPC_DEF("MPC565", CPU_POWERPC_MPC565, MPC5xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC566 */
- POWERPC_DEF("MPC566", CPU_POWERPC_MPC566, MPC5xx),
-#endif
- /* MPC8xx family (aka PowerQUICC) */
-#if defined(TODO_USER_ONLY)
- /* Generic MPC8xx core */
- POWERPC_DEF("MPC8xx", CPU_POWERPC_MPC8xx, MPC8xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* Codename for MPC8xx core */
- POWERPC_DEF("PowerQUICC", CPU_POWERPC_MPC8xx, MPC8xx),
-#endif
- /* MPC8xx microcontrollers */
-#if defined(TODO_USER_ONLY)
- /* MGT823 */
- POWERPC_DEF("MGT823", CPU_POWERPC_MGT823, MPC8xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC821 */
- POWERPC_DEF("MPC821", CPU_POWERPC_MPC821, MPC8xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC823 */
- POWERPC_DEF("MPC823", CPU_POWERPC_MPC823, MPC8xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC850 */
- POWERPC_DEF("MPC850", CPU_POWERPC_MPC850, MPC8xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC852T */
- POWERPC_DEF("MPC852T", CPU_POWERPC_MPC852T, MPC8xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC855T */
- POWERPC_DEF("MPC855T", CPU_POWERPC_MPC855T, MPC8xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC857 */
- POWERPC_DEF("MPC857", CPU_POWERPC_MPC857, MPC8xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC859 */
- POWERPC_DEF("MPC859", CPU_POWERPC_MPC859, MPC8xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC860 */
- POWERPC_DEF("MPC860", CPU_POWERPC_MPC860, MPC8xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC862 */
- POWERPC_DEF("MPC862", CPU_POWERPC_MPC862, MPC8xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC866 */
- POWERPC_DEF("MPC866", CPU_POWERPC_MPC866, MPC8xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC870 */
- POWERPC_DEF("MPC870", CPU_POWERPC_MPC870, MPC8xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC875 */
- POWERPC_DEF("MPC875", CPU_POWERPC_MPC875, MPC8xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC880 */
- POWERPC_DEF("MPC880", CPU_POWERPC_MPC880, MPC8xx),
-#endif
-#if defined(TODO_USER_ONLY)
- /* MPC885 */
- POWERPC_DEF("MPC885", CPU_POWERPC_MPC885, MPC8xx),
-#endif
- /* MPC82xx family (aka PowerQUICC-II) */
- /* Generic MPC52xx core */
- POWERPC_DEF_SVR("MPC52xx",
- CPU_POWERPC_MPC52xx, POWERPC_SVR_52xx, G2LE),
- /* Generic MPC82xx core */
- POWERPC_DEF("MPC82xx", CPU_POWERPC_MPC82xx, G2),
- /* Codename for MPC82xx */
- POWERPC_DEF("PowerQUICC-II", CPU_POWERPC_MPC82xx, G2),
- /* PowerPC G2 core */
- POWERPC_DEF("G2", CPU_POWERPC_G2, G2),
- /* PowerPC G2 H4 core */
- POWERPC_DEF("G2H4", CPU_POWERPC_G2H4, G2),
- /* PowerPC G2 GP core */
- POWERPC_DEF("G2GP", CPU_POWERPC_G2gp, G2),
- /* PowerPC G2 LS core */
- POWERPC_DEF("G2LS", CPU_POWERPC_G2ls, G2),
- /* PowerPC G2 HiP3 core */
- POWERPC_DEF("G2HiP3", CPU_POWERPC_G2_HIP3, G2),
- /* PowerPC G2 HiP4 core */
- POWERPC_DEF("G2HiP4", CPU_POWERPC_G2_HIP4, G2),
- /* PowerPC MPC603 core */
- POWERPC_DEF("MPC603", CPU_POWERPC_MPC603, 603E),
- /* PowerPC G2le core (same as G2 plus little-endian mode support) */
- POWERPC_DEF("G2le", CPU_POWERPC_G2LE, G2LE),
- /* PowerPC G2LE GP core */
- POWERPC_DEF("G2leGP", CPU_POWERPC_G2LEgp, G2LE),
- /* PowerPC G2LE LS core */
- POWERPC_DEF("G2leLS", CPU_POWERPC_G2LEls, G2LE),
- /* PowerPC G2LE GP1 core */
- POWERPC_DEF("G2leGP1", CPU_POWERPC_G2LEgp1, G2LE),
- /* PowerPC G2LE GP3 core */
- POWERPC_DEF("G2leGP3", CPU_POWERPC_G2LEgp1, G2LE),
- /* PowerPC MPC603 microcontrollers */
- /* MPC8240 */
- POWERPC_DEF("MPC8240", CPU_POWERPC_MPC8240, 603E),
- /* PowerPC G2 microcontrollers */
-#if defined(TODO)
- /* MPC5121 */
- POWERPC_DEF_SVR("MPC5121",
- CPU_POWERPC_MPC5121, POWERPC_SVR_5121, G2LE),
-#endif
- /* MPC5200 */
- POWERPC_DEF_SVR("MPC5200",
- CPU_POWERPC_MPC5200, POWERPC_SVR_5200, G2LE),
- /* MPC5200 v1.0 */
- POWERPC_DEF_SVR("MPC5200_v10",
- CPU_POWERPC_MPC5200_v10, POWERPC_SVR_5200_v10, G2LE),
- /* MPC5200 v1.1 */
- POWERPC_DEF_SVR("MPC5200_v11",
- CPU_POWERPC_MPC5200_v11, POWERPC_SVR_5200_v11, G2LE),
- /* MPC5200 v1.2 */
- POWERPC_DEF_SVR("MPC5200_v12",
- CPU_POWERPC_MPC5200_v12, POWERPC_SVR_5200_v12, G2LE),
- /* MPC5200B */
- POWERPC_DEF_SVR("MPC5200B",
- CPU_POWERPC_MPC5200B, POWERPC_SVR_5200B, G2LE),
- /* MPC5200B v2.0 */
- POWERPC_DEF_SVR("MPC5200B_v20",
- CPU_POWERPC_MPC5200B_v20, POWERPC_SVR_5200B_v20, G2LE),
- /* MPC5200B v2.1 */
- POWERPC_DEF_SVR("MPC5200B_v21",
- CPU_POWERPC_MPC5200B_v21, POWERPC_SVR_5200B_v21, G2LE),
- /* MPC8241 */
- POWERPC_DEF("MPC8241", CPU_POWERPC_MPC8241, G2),
- /* MPC8245 */
- POWERPC_DEF("MPC8245", CPU_POWERPC_MPC8245, G2),
- /* MPC8247 */
- POWERPC_DEF("MPC8247", CPU_POWERPC_MPC8247, G2LE),
- /* MPC8248 */
- POWERPC_DEF("MPC8248", CPU_POWERPC_MPC8248, G2LE),
- /* MPC8250 */
- POWERPC_DEF("MPC8250", CPU_POWERPC_MPC8250, G2),
- /* MPC8250 HiP3 */
- POWERPC_DEF("MPC8250_HiP3", CPU_POWERPC_MPC8250_HiP3, G2),
- /* MPC8250 HiP4 */
- POWERPC_DEF("MPC8250_HiP4", CPU_POWERPC_MPC8250_HiP4, G2),
- /* MPC8255 */
- POWERPC_DEF("MPC8255", CPU_POWERPC_MPC8255, G2),
- /* MPC8255 HiP3 */
- POWERPC_DEF("MPC8255_HiP3", CPU_POWERPC_MPC8255_HiP3, G2),
- /* MPC8255 HiP4 */
- POWERPC_DEF("MPC8255_HiP4", CPU_POWERPC_MPC8255_HiP4, G2),
- /* MPC8260 */
- POWERPC_DEF("MPC8260", CPU_POWERPC_MPC8260, G2),
- /* MPC8260 HiP3 */
- POWERPC_DEF("MPC8260_HiP3", CPU_POWERPC_MPC8260_HiP3, G2),
- /* MPC8260 HiP4 */
- POWERPC_DEF("MPC8260_HiP4", CPU_POWERPC_MPC8260_HiP4, G2),
- /* MPC8264 */
- POWERPC_DEF("MPC8264", CPU_POWERPC_MPC8264, G2),
- /* MPC8264 HiP3 */
- POWERPC_DEF("MPC8264_HiP3", CPU_POWERPC_MPC8264_HiP3, G2),
- /* MPC8264 HiP4 */
- POWERPC_DEF("MPC8264_HiP4", CPU_POWERPC_MPC8264_HiP4, G2),
- /* MPC8265 */
- POWERPC_DEF("MPC8265", CPU_POWERPC_MPC8265, G2),
- /* MPC8265 HiP3 */
- POWERPC_DEF("MPC8265_HiP3", CPU_POWERPC_MPC8265_HiP3, G2),
- /* MPC8265 HiP4 */
- POWERPC_DEF("MPC8265_HiP4", CPU_POWERPC_MPC8265_HiP4, G2),
- /* MPC8266 */
- POWERPC_DEF("MPC8266", CPU_POWERPC_MPC8266, G2),
- /* MPC8266 HiP3 */
- POWERPC_DEF("MPC8266_HiP3", CPU_POWERPC_MPC8266_HiP3, G2),
- /* MPC8266 HiP4 */
- POWERPC_DEF("MPC8266_HiP4", CPU_POWERPC_MPC8266_HiP4, G2),
- /* MPC8270 */
- POWERPC_DEF("MPC8270", CPU_POWERPC_MPC8270, G2LE),
- /* MPC8271 */
- POWERPC_DEF("MPC8271", CPU_POWERPC_MPC8271, G2LE),
- /* MPC8272 */
- POWERPC_DEF("MPC8272", CPU_POWERPC_MPC8272, G2LE),
- /* MPC8275 */
- POWERPC_DEF("MPC8275", CPU_POWERPC_MPC8275, G2LE),
- /* MPC8280 */
- POWERPC_DEF("MPC8280", CPU_POWERPC_MPC8280, G2LE),
- /* e200 family */
- /* Generic PowerPC e200 core */
- POWERPC_DEF("e200", CPU_POWERPC_e200, e200),
- /* Generic MPC55xx core */
-#if defined (TODO)
- POWERPC_DEF_SVR("MPC55xx",
- CPU_POWERPC_MPC55xx, POWERPC_SVR_55xx, e200),
-#endif
-#if defined (TODO)
- /* PowerPC e200z0 core */
- POWERPC_DEF("e200z0", CPU_POWERPC_e200z0, e200),
-#endif
-#if defined (TODO)
- /* PowerPC e200z1 core */
- POWERPC_DEF("e200z1", CPU_POWERPC_e200z1, e200),
-#endif
-#if defined (TODO)
- /* PowerPC e200z3 core */
- POWERPC_DEF("e200z3", CPU_POWERPC_e200z3, e200),
-#endif
- /* PowerPC e200z5 core */
- POWERPC_DEF("e200z5", CPU_POWERPC_e200z5, e200),
- /* PowerPC e200z6 core */
- POWERPC_DEF("e200z6", CPU_POWERPC_e200z6, e200),
- /* PowerPC e200 microcontrollers */
-#if defined (TODO)
- /* MPC5514E */
- POWERPC_DEF_SVR("MPC5514E",
- CPU_POWERPC_MPC5514E, POWERPC_SVR_5514E, e200),
-#endif
-#if defined (TODO)
- /* MPC5514E v0 */
- POWERPC_DEF_SVR("MPC5514E_v0",
- CPU_POWERPC_MPC5514E_v0, POWERPC_SVR_5514E_v0, e200),
-#endif
-#if defined (TODO)
- /* MPC5514E v1 */
- POWERPC_DEF_SVR("MPC5514E_v1",
- CPU_POWERPC_MPC5514E_v1, POWERPC_SVR_5514E_v1, e200),
-#endif
-#if defined (TODO)
- /* MPC5514G */
- POWERPC_DEF_SVR("MPC5514G",
- CPU_POWERPC_MPC5514G, POWERPC_SVR_5514G, e200),
-#endif
-#if defined (TODO)
- /* MPC5514G v0 */
- POWERPC_DEF_SVR("MPC5514G_v0",
- CPU_POWERPC_MPC5514G_v0, POWERPC_SVR_5514G_v0, e200),
-#endif
-#if defined (TODO)
- /* MPC5514G v1 */
- POWERPC_DEF_SVR("MPC5514G_v1",
- CPU_POWERPC_MPC5514G_v1, POWERPC_SVR_5514G_v1, e200),
-#endif
-#if defined (TODO)
- /* MPC5515S */
- POWERPC_DEF_SVR("MPC5515S",
- CPU_POWERPC_MPC5515S, POWERPC_SVR_5515S, e200),
-#endif
-#if defined (TODO)
- /* MPC5516E */
- POWERPC_DEF_SVR("MPC5516E",
- CPU_POWERPC_MPC5516E, POWERPC_SVR_5516E, e200),
-#endif
-#if defined (TODO)
- /* MPC5516E v0 */
- POWERPC_DEF_SVR("MPC5516E_v0",
- CPU_POWERPC_MPC5516E_v0, POWERPC_SVR_5516E_v0, e200),
-#endif
-#if defined (TODO)
- /* MPC5516E v1 */
- POWERPC_DEF_SVR("MPC5516E_v1",
- CPU_POWERPC_MPC5516E_v1, POWERPC_SVR_5516E_v1, e200),
-#endif
-#if defined (TODO)
- /* MPC5516G */
- POWERPC_DEF_SVR("MPC5516G",
- CPU_POWERPC_MPC5516G, POWERPC_SVR_5516G, e200),
-#endif
-#if defined (TODO)
- /* MPC5516G v0 */
- POWERPC_DEF_SVR("MPC5516G_v0",
- CPU_POWERPC_MPC5516G_v0, POWERPC_SVR_5516G_v0, e200),
-#endif
-#if defined (TODO)
- /* MPC5516G v1 */
- POWERPC_DEF_SVR("MPC5516G_v1",
- CPU_POWERPC_MPC5516G_v1, POWERPC_SVR_5516G_v1, e200),
-#endif
-#if defined (TODO)
- /* MPC5516S */
- POWERPC_DEF_SVR("MPC5516S",
- CPU_POWERPC_MPC5516S, POWERPC_SVR_5516S, e200),
-#endif
-#if defined (TODO)
- /* MPC5533 */
- POWERPC_DEF_SVR("MPC5533",
- CPU_POWERPC_MPC5533, POWERPC_SVR_5533, e200),
-#endif
-#if defined (TODO)
- /* MPC5534 */
- POWERPC_DEF_SVR("MPC5534",
- CPU_POWERPC_MPC5534, POWERPC_SVR_5534, e200),
-#endif
-#if defined (TODO)
- /* MPC5553 */
- POWERPC_DEF_SVR("MPC5553",
- CPU_POWERPC_MPC5553, POWERPC_SVR_5553, e200),
-#endif
-#if defined (TODO)
- /* MPC5554 */
- POWERPC_DEF_SVR("MPC5554",
- CPU_POWERPC_MPC5554, POWERPC_SVR_5554, e200),
-#endif
-#if defined (TODO)
- /* MPC5561 */
- POWERPC_DEF_SVR("MPC5561",
- CPU_POWERPC_MPC5561, POWERPC_SVR_5561, e200),
-#endif
-#if defined (TODO)
- /* MPC5565 */
- POWERPC_DEF_SVR("MPC5565",
- CPU_POWERPC_MPC5565, POWERPC_SVR_5565, e200),
-#endif
-#if defined (TODO)
- /* MPC5566 */
- POWERPC_DEF_SVR("MPC5566",
- CPU_POWERPC_MPC5566, POWERPC_SVR_5566, e200),
-#endif
-#if defined (TODO)
- /* MPC5567 */
- POWERPC_DEF_SVR("MPC5567",
- CPU_POWERPC_MPC5567, POWERPC_SVR_5567, e200),
-#endif
- /* e300 family */
- /* Generic PowerPC e300 core */
- POWERPC_DEF("e300", CPU_POWERPC_e300, e300),
- /* PowerPC e300c1 core */
- POWERPC_DEF("e300c1", CPU_POWERPC_e300c1, e300),
- /* PowerPC e300c2 core */
- POWERPC_DEF("e300c2", CPU_POWERPC_e300c2, e300),
- /* PowerPC e300c3 core */
- POWERPC_DEF("e300c3", CPU_POWERPC_e300c3, e300),
- /* PowerPC e300c4 core */
- POWERPC_DEF("e300c4", CPU_POWERPC_e300c4, e300),
- /* PowerPC e300 microcontrollers */
-#if defined (TODO)
- /* MPC8313 */
- POWERPC_DEF_SVR("MPC8313",
- CPU_POWERPC_MPC831x, POWERPC_SVR_8313, e300),
-#endif
-#if defined (TODO)
- /* MPC8313E */
- POWERPC_DEF_SVR("MPC8313E",
- CPU_POWERPC_MPC831x, POWERPC_SVR_8313E, e300),
-#endif
-#if defined (TODO)
- /* MPC8314 */
- POWERPC_DEF_SVR("MPC8314",
- CPU_POWERPC_MPC831x, POWERPC_SVR_8314, e300),
-#endif
-#if defined (TODO)
- /* MPC8314E */
- POWERPC_DEF_SVR("MPC8314E",
- CPU_POWERPC_MPC831x, POWERPC_SVR_8314E, e300),
-#endif
-#if defined (TODO)
- /* MPC8315 */
- POWERPC_DEF_SVR("MPC8315",
- CPU_POWERPC_MPC831x, POWERPC_SVR_8315, e300),
-#endif
-#if defined (TODO)
- /* MPC8315E */
- POWERPC_DEF_SVR("MPC8315E",
- CPU_POWERPC_MPC831x, POWERPC_SVR_8315E, e300),
-#endif
-#if defined (TODO)
- /* MPC8321 */
- POWERPC_DEF_SVR("MPC8321",
- CPU_POWERPC_MPC832x, POWERPC_SVR_8321, e300),
-#endif
-#if defined (TODO)
- /* MPC8321E */
- POWERPC_DEF_SVR("MPC8321E",
- CPU_POWERPC_MPC832x, POWERPC_SVR_8321E, e300),
-#endif
-#if defined (TODO)
- /* MPC8323 */
- POWERPC_DEF_SVR("MPC8323",
- CPU_POWERPC_MPC832x, POWERPC_SVR_8323, e300),
-#endif
-#if defined (TODO)
- /* MPC8323E */
- POWERPC_DEF_SVR("MPC8323E",
- CPU_POWERPC_MPC832x, POWERPC_SVR_8323E, e300),
-#endif
- /* MPC8343 */
- POWERPC_DEF_SVR("MPC8343",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8343, e300),
- /* MPC8343A */
- POWERPC_DEF_SVR("MPC8343A",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8343A, e300),
- /* MPC8343E */
- POWERPC_DEF_SVR("MPC8343E",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8343E, e300),
- /* MPC8343EA */
- POWERPC_DEF_SVR("MPC8343EA",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8343EA, e300),
- /* MPC8347 */
- POWERPC_DEF_SVR("MPC8347",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8347, e300),
- /* MPC8347T */
- POWERPC_DEF_SVR("MPC8347T",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8347T, e300),
- /* MPC8347P */
- POWERPC_DEF_SVR("MPC8347P",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8347P, e300),
- /* MPC8347A */
- POWERPC_DEF_SVR("MPC8347A",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8347A, e300),
- /* MPC8347AT */
- POWERPC_DEF_SVR("MPC8347AT",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8347AT, e300),
- /* MPC8347AP */
- POWERPC_DEF_SVR("MPC8347AP",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8347AP, e300),
- /* MPC8347E */
- POWERPC_DEF_SVR("MPC8347E",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8347E, e300),
- /* MPC8347ET */
- POWERPC_DEF_SVR("MPC8347ET",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8347ET, e300),
- /* MPC8343EP */
- POWERPC_DEF_SVR("MPC8347EP",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8347EP, e300),
- /* MPC8347EA */
- POWERPC_DEF_SVR("MPC8347EA",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8347EA, e300),
- /* MPC8347EAT */
- POWERPC_DEF_SVR("MPC8347EAT",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8347EAT, e300),
- /* MPC8343EAP */
- POWERPC_DEF_SVR("MPC8347EAP",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8347EAP, e300),
- /* MPC8349 */
- POWERPC_DEF_SVR("MPC8349",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8349, e300),
- /* MPC8349A */
- POWERPC_DEF_SVR("MPC8349A",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8349A, e300),
- /* MPC8349E */
- POWERPC_DEF_SVR("MPC8349E",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8349E, e300),
- /* MPC8349EA */
- POWERPC_DEF_SVR("MPC8349EA",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8349EA, e300),
-#if defined (TODO)
- /* MPC8358E */
- POWERPC_DEF_SVR("MPC8358E",
- CPU_POWERPC_MPC835x, POWERPC_SVR_8358E, e300),
-#endif
-#if defined (TODO)
- /* MPC8360E */
- POWERPC_DEF_SVR("MPC8360E",
- CPU_POWERPC_MPC836x, POWERPC_SVR_8360E, e300),
-#endif
- /* MPC8377 */
- POWERPC_DEF_SVR("MPC8377",
- CPU_POWERPC_MPC837x, POWERPC_SVR_8377, e300),
- /* MPC8377E */
- POWERPC_DEF_SVR("MPC8377E",
- CPU_POWERPC_MPC837x, POWERPC_SVR_8377E, e300),
- /* MPC8378 */
- POWERPC_DEF_SVR("MPC8378",
- CPU_POWERPC_MPC837x, POWERPC_SVR_8378, e300),
- /* MPC8378E */
- POWERPC_DEF_SVR("MPC8378E",
- CPU_POWERPC_MPC837x, POWERPC_SVR_8378E, e300),
- /* MPC8379 */
- POWERPC_DEF_SVR("MPC8379",
- CPU_POWERPC_MPC837x, POWERPC_SVR_8379, e300),
- /* MPC8379E */
- POWERPC_DEF_SVR("MPC8379E",
- CPU_POWERPC_MPC837x, POWERPC_SVR_8379E, e300),
- /* e500 family */
- /* PowerPC e500 core */
- POWERPC_DEF("e500", CPU_POWERPC_e500v2_v22, e500v2),
- /* PowerPC e500v1 core */
- POWERPC_DEF("e500v1", CPU_POWERPC_e500v1, e500v1),
- /* PowerPC e500 v1.0 core */
- POWERPC_DEF("e500_v10", CPU_POWERPC_e500v1_v10, e500v1),
- /* PowerPC e500 v2.0 core */
- POWERPC_DEF("e500_v20", CPU_POWERPC_e500v1_v20, e500v1),
- /* PowerPC e500v2 core */
- POWERPC_DEF("e500v2", CPU_POWERPC_e500v2, e500v2),
- /* PowerPC e500v2 v1.0 core */
- POWERPC_DEF("e500v2_v10", CPU_POWERPC_e500v2_v10, e500v2),
- /* PowerPC e500v2 v2.0 core */
- POWERPC_DEF("e500v2_v20", CPU_POWERPC_e500v2_v20, e500v2),
- /* PowerPC e500v2 v2.1 core */
- POWERPC_DEF("e500v2_v21", CPU_POWERPC_e500v2_v21, e500v2),
- /* PowerPC e500v2 v2.2 core */
- POWERPC_DEF("e500v2_v22", CPU_POWERPC_e500v2_v22, e500v2),
- /* PowerPC e500v2 v3.0 core */
- POWERPC_DEF("e500v2_v30", CPU_POWERPC_e500v2_v30, e500v2),
- POWERPC_DEF("e500mc", CPU_POWERPC_e500mc, e500mc),
-#ifdef TARGET_PPC64
- POWERPC_DEF("e5500", CPU_POWERPC_e5500, e5500),
-#endif
- /* PowerPC e500 microcontrollers */
- /* MPC8533 */
- POWERPC_DEF_SVR("MPC8533",
- CPU_POWERPC_MPC8533, POWERPC_SVR_8533, e500v2),
- /* MPC8533 v1.0 */
- POWERPC_DEF_SVR("MPC8533_v10",
- CPU_POWERPC_MPC8533_v10, POWERPC_SVR_8533_v10, e500v2),
- /* MPC8533 v1.1 */
- POWERPC_DEF_SVR("MPC8533_v11",
- CPU_POWERPC_MPC8533_v11, POWERPC_SVR_8533_v11, e500v2),
- /* MPC8533E */
- POWERPC_DEF_SVR("MPC8533E",
- CPU_POWERPC_MPC8533E, POWERPC_SVR_8533E, e500v2),
- /* MPC8533E v1.0 */
- POWERPC_DEF_SVR("MPC8533E_v10",
- CPU_POWERPC_MPC8533E_v10, POWERPC_SVR_8533E_v10, e500v2),
- POWERPC_DEF_SVR("MPC8533E_v11",
- CPU_POWERPC_MPC8533E_v11, POWERPC_SVR_8533E_v11, e500v2),
- /* MPC8540 */
- POWERPC_DEF_SVR("MPC8540",
- CPU_POWERPC_MPC8540, POWERPC_SVR_8540, e500v1),
- /* MPC8540 v1.0 */
- POWERPC_DEF_SVR("MPC8540_v10",
- CPU_POWERPC_MPC8540_v10, POWERPC_SVR_8540_v10, e500v1),
- /* MPC8540 v2.0 */
- POWERPC_DEF_SVR("MPC8540_v20",
- CPU_POWERPC_MPC8540_v20, POWERPC_SVR_8540_v20, e500v1),
- /* MPC8540 v2.1 */
- POWERPC_DEF_SVR("MPC8540_v21",
- CPU_POWERPC_MPC8540_v21, POWERPC_SVR_8540_v21, e500v1),
- /* MPC8541 */
- POWERPC_DEF_SVR("MPC8541",
- CPU_POWERPC_MPC8541, POWERPC_SVR_8541, e500v1),
- /* MPC8541 v1.0 */
- POWERPC_DEF_SVR("MPC8541_v10",
- CPU_POWERPC_MPC8541_v10, POWERPC_SVR_8541_v10, e500v1),
- /* MPC8541 v1.1 */
- POWERPC_DEF_SVR("MPC8541_v11",
- CPU_POWERPC_MPC8541_v11, POWERPC_SVR_8541_v11, e500v1),
- /* MPC8541E */
- POWERPC_DEF_SVR("MPC8541E",
- CPU_POWERPC_MPC8541E, POWERPC_SVR_8541E, e500v1),
- /* MPC8541E v1.0 */
- POWERPC_DEF_SVR("MPC8541E_v10",
- CPU_POWERPC_MPC8541E_v10, POWERPC_SVR_8541E_v10, e500v1),
- /* MPC8541E v1.1 */
- POWERPC_DEF_SVR("MPC8541E_v11",
- CPU_POWERPC_MPC8541E_v11, POWERPC_SVR_8541E_v11, e500v1),
- /* MPC8543 */
- POWERPC_DEF_SVR("MPC8543",
- CPU_POWERPC_MPC8543, POWERPC_SVR_8543, e500v2),
- /* MPC8543 v1.0 */
- POWERPC_DEF_SVR("MPC8543_v10",
- CPU_POWERPC_MPC8543_v10, POWERPC_SVR_8543_v10, e500v2),
- /* MPC8543 v1.1 */
- POWERPC_DEF_SVR("MPC8543_v11",
- CPU_POWERPC_MPC8543_v11, POWERPC_SVR_8543_v11, e500v2),
- /* MPC8543 v2.0 */
- POWERPC_DEF_SVR("MPC8543_v20",
- CPU_POWERPC_MPC8543_v20, POWERPC_SVR_8543_v20, e500v2),
- /* MPC8543 v2.1 */
- POWERPC_DEF_SVR("MPC8543_v21",
- CPU_POWERPC_MPC8543_v21, POWERPC_SVR_8543_v21, e500v2),
- /* MPC8543E */
- POWERPC_DEF_SVR("MPC8543E",
- CPU_POWERPC_MPC8543E, POWERPC_SVR_8543E, e500v2),
- /* MPC8543E v1.0 */
- POWERPC_DEF_SVR("MPC8543E_v10",
- CPU_POWERPC_MPC8543E_v10, POWERPC_SVR_8543E_v10, e500v2),
- /* MPC8543E v1.1 */
- POWERPC_DEF_SVR("MPC8543E_v11",
- CPU_POWERPC_MPC8543E_v11, POWERPC_SVR_8543E_v11, e500v2),
- /* MPC8543E v2.0 */
- POWERPC_DEF_SVR("MPC8543E_v20",
- CPU_POWERPC_MPC8543E_v20, POWERPC_SVR_8543E_v20, e500v2),
- /* MPC8543E v2.1 */
- POWERPC_DEF_SVR("MPC8543E_v21",
- CPU_POWERPC_MPC8543E_v21, POWERPC_SVR_8543E_v21, e500v2),
- /* MPC8544 */
- POWERPC_DEF_SVR("MPC8544",
- CPU_POWERPC_MPC8544, POWERPC_SVR_8544, e500v2),
- /* MPC8544 v1.0 */
- POWERPC_DEF_SVR("MPC8544_v10",
- CPU_POWERPC_MPC8544_v10, POWERPC_SVR_8544_v10, e500v2),
- /* MPC8544 v1.1 */
- POWERPC_DEF_SVR("MPC8544_v11",
- CPU_POWERPC_MPC8544_v11, POWERPC_SVR_8544_v11, e500v2),
- /* MPC8544E */
- POWERPC_DEF_SVR("MPC8544E",
- CPU_POWERPC_MPC8544E, POWERPC_SVR_8544E, e500v2),
- /* MPC8544E v1.0 */
- POWERPC_DEF_SVR("MPC8544E_v10",
- CPU_POWERPC_MPC8544E_v10, POWERPC_SVR_8544E_v10, e500v2),
- /* MPC8544E v1.1 */
- POWERPC_DEF_SVR("MPC8544E_v11",
- CPU_POWERPC_MPC8544E_v11, POWERPC_SVR_8544E_v11, e500v2),
- /* MPC8545 */
- POWERPC_DEF_SVR("MPC8545",
- CPU_POWERPC_MPC8545, POWERPC_SVR_8545, e500v2),
- /* MPC8545 v2.0 */
- POWERPC_DEF_SVR("MPC8545_v20",
- CPU_POWERPC_MPC8545_v20, POWERPC_SVR_8545_v20, e500v2),
- /* MPC8545 v2.1 */
- POWERPC_DEF_SVR("MPC8545_v21",
- CPU_POWERPC_MPC8545_v21, POWERPC_SVR_8545_v21, e500v2),
- /* MPC8545E */
- POWERPC_DEF_SVR("MPC8545E",
- CPU_POWERPC_MPC8545E, POWERPC_SVR_8545E, e500v2),
- /* MPC8545E v2.0 */
- POWERPC_DEF_SVR("MPC8545E_v20",
- CPU_POWERPC_MPC8545E_v20, POWERPC_SVR_8545E_v20, e500v2),
- /* MPC8545E v2.1 */
- POWERPC_DEF_SVR("MPC8545E_v21",
- CPU_POWERPC_MPC8545E_v21, POWERPC_SVR_8545E_v21, e500v2),
- /* MPC8547E */
- POWERPC_DEF_SVR("MPC8547E",
- CPU_POWERPC_MPC8547E, POWERPC_SVR_8547E, e500v2),
- /* MPC8547E v2.0 */
- POWERPC_DEF_SVR("MPC8547E_v20",
- CPU_POWERPC_MPC8547E_v20, POWERPC_SVR_8547E_v20, e500v2),
- /* MPC8547E v2.1 */
- POWERPC_DEF_SVR("MPC8547E_v21",
- CPU_POWERPC_MPC8547E_v21, POWERPC_SVR_8547E_v21, e500v2),
- /* MPC8548 */
- POWERPC_DEF_SVR("MPC8548",
- CPU_POWERPC_MPC8548, POWERPC_SVR_8548, e500v2),
- /* MPC8548 v1.0 */
- POWERPC_DEF_SVR("MPC8548_v10",
- CPU_POWERPC_MPC8548_v10, POWERPC_SVR_8548_v10, e500v2),
- /* MPC8548 v1.1 */
- POWERPC_DEF_SVR("MPC8548_v11",
- CPU_POWERPC_MPC8548_v11, POWERPC_SVR_8548_v11, e500v2),
- /* MPC8548 v2.0 */
- POWERPC_DEF_SVR("MPC8548_v20",
- CPU_POWERPC_MPC8548_v20, POWERPC_SVR_8548_v20, e500v2),
- /* MPC8548 v2.1 */
- POWERPC_DEF_SVR("MPC8548_v21",
- CPU_POWERPC_MPC8548_v21, POWERPC_SVR_8548_v21, e500v2),
- /* MPC8548E */
- POWERPC_DEF_SVR("MPC8548E",
- CPU_POWERPC_MPC8548E, POWERPC_SVR_8548E, e500v2),
- /* MPC8548E v1.0 */
- POWERPC_DEF_SVR("MPC8548E_v10",
- CPU_POWERPC_MPC8548E_v10, POWERPC_SVR_8548E_v10, e500v2),
- /* MPC8548E v1.1 */
- POWERPC_DEF_SVR("MPC8548E_v11",
- CPU_POWERPC_MPC8548E_v11, POWERPC_SVR_8548E_v11, e500v2),
- /* MPC8548E v2.0 */
- POWERPC_DEF_SVR("MPC8548E_v20",
- CPU_POWERPC_MPC8548E_v20, POWERPC_SVR_8548E_v20, e500v2),
- /* MPC8548E v2.1 */
- POWERPC_DEF_SVR("MPC8548E_v21",
- CPU_POWERPC_MPC8548E_v21, POWERPC_SVR_8548E_v21, e500v2),
- /* MPC8555 */
- POWERPC_DEF_SVR("MPC8555",
- CPU_POWERPC_MPC8555, POWERPC_SVR_8555, e500v2),
- /* MPC8555 v1.0 */
- POWERPC_DEF_SVR("MPC8555_v10",
- CPU_POWERPC_MPC8555_v10, POWERPC_SVR_8555_v10, e500v2),
- /* MPC8555 v1.1 */
- POWERPC_DEF_SVR("MPC8555_v11",
- CPU_POWERPC_MPC8555_v11, POWERPC_SVR_8555_v11, e500v2),
- /* MPC8555E */
- POWERPC_DEF_SVR("MPC8555E",
- CPU_POWERPC_MPC8555E, POWERPC_SVR_8555E, e500v2),
- /* MPC8555E v1.0 */
- POWERPC_DEF_SVR("MPC8555E_v10",
- CPU_POWERPC_MPC8555E_v10, POWERPC_SVR_8555E_v10, e500v2),
- /* MPC8555E v1.1 */
- POWERPC_DEF_SVR("MPC8555E_v11",
- CPU_POWERPC_MPC8555E_v11, POWERPC_SVR_8555E_v11, e500v2),
- /* MPC8560 */
- POWERPC_DEF_SVR("MPC8560",
- CPU_POWERPC_MPC8560, POWERPC_SVR_8560, e500v2),
- /* MPC8560 v1.0 */
- POWERPC_DEF_SVR("MPC8560_v10",
- CPU_POWERPC_MPC8560_v10, POWERPC_SVR_8560_v10, e500v2),
- /* MPC8560 v2.0 */
- POWERPC_DEF_SVR("MPC8560_v20",
- CPU_POWERPC_MPC8560_v20, POWERPC_SVR_8560_v20, e500v2),
- /* MPC8560 v2.1 */
- POWERPC_DEF_SVR("MPC8560_v21",
- CPU_POWERPC_MPC8560_v21, POWERPC_SVR_8560_v21, e500v2),
- /* MPC8567 */
- POWERPC_DEF_SVR("MPC8567",
- CPU_POWERPC_MPC8567, POWERPC_SVR_8567, e500v2),
- /* MPC8567E */
- POWERPC_DEF_SVR("MPC8567E",
- CPU_POWERPC_MPC8567E, POWERPC_SVR_8567E, e500v2),
- /* MPC8568 */
- POWERPC_DEF_SVR("MPC8568",
- CPU_POWERPC_MPC8568, POWERPC_SVR_8568, e500v2),
- /* MPC8568E */
- POWERPC_DEF_SVR("MPC8568E",
- CPU_POWERPC_MPC8568E, POWERPC_SVR_8568E, e500v2),
- /* MPC8572 */
- POWERPC_DEF_SVR("MPC8572",
- CPU_POWERPC_MPC8572, POWERPC_SVR_8572, e500v2),
- /* MPC8572E */
- POWERPC_DEF_SVR("MPC8572E",
- CPU_POWERPC_MPC8572E, POWERPC_SVR_8572E, e500v2),
- /* e600 family */
- /* PowerPC e600 core */
- POWERPC_DEF("e600", CPU_POWERPC_e600, 7400),
- /* PowerPC e600 microcontrollers */
-#if defined (TODO)
- /* MPC8610 */
- POWERPC_DEF_SVR("MPC8610",
- CPU_POWERPC_MPC8610, POWERPC_SVR_8610, 7400),
-#endif
- /* MPC8641 */
- POWERPC_DEF_SVR("MPC8641",
- CPU_POWERPC_MPC8641, POWERPC_SVR_8641, 7400),
- /* MPC8641D */
- POWERPC_DEF_SVR("MPC8641D",
- CPU_POWERPC_MPC8641D, POWERPC_SVR_8641D, 7400),
- /* 32 bits "classic" PowerPC */
- /* PowerPC 6xx family */
- /* PowerPC 601 */
- POWERPC_DEF("601", CPU_POWERPC_601, 601v),
- /* PowerPC 601v0 */
- POWERPC_DEF("601_v0", CPU_POWERPC_601_v0, 601),
- /* PowerPC 601v1 */
- POWERPC_DEF("601_v1", CPU_POWERPC_601_v1, 601),
- /* PowerPC 601v */
- POWERPC_DEF("601v", CPU_POWERPC_601v, 601v),
- /* PowerPC 601v2 */
- POWERPC_DEF("601_v2", CPU_POWERPC_601_v2, 601v),
- /* PowerPC 602 */
- POWERPC_DEF("602", CPU_POWERPC_602, 602),
- /* PowerPC 603 */
- POWERPC_DEF("603", CPU_POWERPC_603, 603),
- /* Code name for PowerPC 603 */
- POWERPC_DEF("Vanilla", CPU_POWERPC_603, 603),
- /* PowerPC 603e (aka PID6) */
- POWERPC_DEF("603e", CPU_POWERPC_603E, 603E),
- /* Code name for PowerPC 603e */
- POWERPC_DEF("Stretch", CPU_POWERPC_603E, 603E),
- /* PowerPC 603e v1.1 */
- POWERPC_DEF("603e_v1.1", CPU_POWERPC_603E_v11, 603E),
- /* PowerPC 603e v1.2 */
- POWERPC_DEF("603e_v1.2", CPU_POWERPC_603E_v12, 603E),
- /* PowerPC 603e v1.3 */
- POWERPC_DEF("603e_v1.3", CPU_POWERPC_603E_v13, 603E),
- /* PowerPC 603e v1.4 */
- POWERPC_DEF("603e_v1.4", CPU_POWERPC_603E_v14, 603E),
- /* PowerPC 603e v2.2 */
- POWERPC_DEF("603e_v2.2", CPU_POWERPC_603E_v22, 603E),
- /* PowerPC 603e v3 */
- POWERPC_DEF("603e_v3", CPU_POWERPC_603E_v3, 603E),
- /* PowerPC 603e v4 */
- POWERPC_DEF("603e_v4", CPU_POWERPC_603E_v4, 603E),
- /* PowerPC 603e v4.1 */
- POWERPC_DEF("603e_v4.1", CPU_POWERPC_603E_v41, 603E),
- /* PowerPC 603e (aka PID7) */
- POWERPC_DEF("603e7", CPU_POWERPC_603E7, 603E),
- /* PowerPC 603e7t */
- POWERPC_DEF("603e7t", CPU_POWERPC_603E7t, 603E),
- /* PowerPC 603e7v */
- POWERPC_DEF("603e7v", CPU_POWERPC_603E7v, 603E),
- /* Code name for PowerPC 603ev */
- POWERPC_DEF("Vaillant", CPU_POWERPC_603E7v, 603E),
- /* PowerPC 603e7v1 */
- POWERPC_DEF("603e7v1", CPU_POWERPC_603E7v1, 603E),
- /* PowerPC 603e7v2 */
- POWERPC_DEF("603e7v2", CPU_POWERPC_603E7v2, 603E),
- /* PowerPC 603p (aka PID7v) */
- POWERPC_DEF("603p", CPU_POWERPC_603P, 603E),
- /* PowerPC 603r (aka PID7t) */
- POWERPC_DEF("603r", CPU_POWERPC_603R, 603E),
- /* Code name for PowerPC 603r */
- POWERPC_DEF("Goldeneye", CPU_POWERPC_603R, 603E),
- /* PowerPC 604 */
- POWERPC_DEF("604", CPU_POWERPC_604, 604),
- /* PowerPC 604e (aka PID9) */
- POWERPC_DEF("604e", CPU_POWERPC_604E, 604E),
- /* Code name for PowerPC 604e */
- POWERPC_DEF("Sirocco", CPU_POWERPC_604E, 604E),
- /* PowerPC 604e v1.0 */
- POWERPC_DEF("604e_v1.0", CPU_POWERPC_604E_v10, 604E),
- /* PowerPC 604e v2.2 */
- POWERPC_DEF("604e_v2.2", CPU_POWERPC_604E_v22, 604E),
- /* PowerPC 604e v2.4 */
- POWERPC_DEF("604e_v2.4", CPU_POWERPC_604E_v24, 604E),
- /* PowerPC 604r (aka PIDA) */
- POWERPC_DEF("604r", CPU_POWERPC_604R, 604E),
- /* Code name for PowerPC 604r */
- POWERPC_DEF("Mach5", CPU_POWERPC_604R, 604E),
-#if defined(TODO)
- /* PowerPC 604ev */
- POWERPC_DEF("604ev", CPU_POWERPC_604EV, 604E),
-#endif
- /* PowerPC 7xx family */
- /* Generic PowerPC 740 (G3) */
- POWERPC_DEF("740", CPU_POWERPC_7x0, 740),
- /* Code name for PowerPC 740 */
- POWERPC_DEF("Arthur", CPU_POWERPC_7x0, 740),
- /* Generic PowerPC 750 (G3) */
- POWERPC_DEF("750", CPU_POWERPC_7x0, 750),
- /* Code name for PowerPC 750 */
- POWERPC_DEF("Typhoon", CPU_POWERPC_7x0, 750),
- /* PowerPC 740/750 is also known as G3 */
- POWERPC_DEF("G3", CPU_POWERPC_7x0, 750),
- /* PowerPC 740 v1.0 (G3) */
- POWERPC_DEF("740_v1.0", CPU_POWERPC_7x0_v10, 740),
- /* PowerPC 750 v1.0 (G3) */
- POWERPC_DEF("750_v1.0", CPU_POWERPC_7x0_v10, 750),
- /* PowerPC 740 v2.0 (G3) */
- POWERPC_DEF("740_v2.0", CPU_POWERPC_7x0_v20, 740),
- /* PowerPC 750 v2.0 (G3) */
- POWERPC_DEF("750_v2.0", CPU_POWERPC_7x0_v20, 750),
- /* PowerPC 740 v2.1 (G3) */
- POWERPC_DEF("740_v2.1", CPU_POWERPC_7x0_v21, 740),
- /* PowerPC 750 v2.1 (G3) */
- POWERPC_DEF("750_v2.1", CPU_POWERPC_7x0_v21, 750),
- /* PowerPC 740 v2.2 (G3) */
- POWERPC_DEF("740_v2.2", CPU_POWERPC_7x0_v22, 740),
- /* PowerPC 750 v2.2 (G3) */
- POWERPC_DEF("750_v2.2", CPU_POWERPC_7x0_v22, 750),
- /* PowerPC 740 v3.0 (G3) */
- POWERPC_DEF("740_v3.0", CPU_POWERPC_7x0_v30, 740),
- /* PowerPC 750 v3.0 (G3) */
- POWERPC_DEF("750_v3.0", CPU_POWERPC_7x0_v30, 750),
- /* PowerPC 740 v3.1 (G3) */
- POWERPC_DEF("740_v3.1", CPU_POWERPC_7x0_v31, 740),
- /* PowerPC 750 v3.1 (G3) */
- POWERPC_DEF("750_v3.1", CPU_POWERPC_7x0_v31, 750),
- /* PowerPC 740E (G3) */
- POWERPC_DEF("740e", CPU_POWERPC_740E, 740),
- /* PowerPC 750E (G3) */
- POWERPC_DEF("750e", CPU_POWERPC_750E, 750),
- /* PowerPC 740P (G3) */
- POWERPC_DEF("740p", CPU_POWERPC_7x0P, 740),
- /* PowerPC 750P (G3) */
- POWERPC_DEF("750p", CPU_POWERPC_7x0P, 750),
- /* Code name for PowerPC 740P/750P (G3) */
- POWERPC_DEF("Conan/Doyle", CPU_POWERPC_7x0P, 750),
- /* PowerPC 750CL (G3 embedded) */
- POWERPC_DEF("750cl", CPU_POWERPC_750CL, 750cl),
- /* PowerPC 750CL v1.0 */
- POWERPC_DEF("750cl_v1.0", CPU_POWERPC_750CL_v10, 750cl),
- /* PowerPC 750CL v2.0 */
- POWERPC_DEF("750cl_v2.0", CPU_POWERPC_750CL_v20, 750cl),
- /* PowerPC 750CX (G3 embedded) */
- POWERPC_DEF("750cx", CPU_POWERPC_750CX, 750cx),
- /* PowerPC 750CX v1.0 (G3 embedded) */
- POWERPC_DEF("750cx_v1.0", CPU_POWERPC_750CX_v10, 750cx),
- /* PowerPC 750CX v2.1 (G3 embedded) */
- POWERPC_DEF("750cx_v2.0", CPU_POWERPC_750CX_v20, 750cx),
- /* PowerPC 750CX v2.1 (G3 embedded) */
- POWERPC_DEF("750cx_v2.1", CPU_POWERPC_750CX_v21, 750cx),
- /* PowerPC 750CX v2.2 (G3 embedded) */
- POWERPC_DEF("750cx_v2.2", CPU_POWERPC_750CX_v22, 750cx),
- /* PowerPC 750CXe (G3 embedded) */
- POWERPC_DEF("750cxe", CPU_POWERPC_750CXE, 750cx),
- /* PowerPC 750CXe v2.1 (G3 embedded) */
- POWERPC_DEF("750cxe_v2.1", CPU_POWERPC_750CXE_v21, 750cx),
- /* PowerPC 750CXe v2.2 (G3 embedded) */
- POWERPC_DEF("750cxe_v2.2", CPU_POWERPC_750CXE_v22, 750cx),
- /* PowerPC 750CXe v2.3 (G3 embedded) */
- POWERPC_DEF("750cxe_v2.3", CPU_POWERPC_750CXE_v23, 750cx),
- /* PowerPC 750CXe v2.4 (G3 embedded) */
- POWERPC_DEF("750cxe_v2.4", CPU_POWERPC_750CXE_v24, 750cx),
- /* PowerPC 750CXe v2.4b (G3 embedded) */
- POWERPC_DEF("750cxe_v2.4b", CPU_POWERPC_750CXE_v24b, 750cx),
- /* PowerPC 750CXe v3.0 (G3 embedded) */
- POWERPC_DEF("750cxe_v3.0", CPU_POWERPC_750CXE_v30, 750cx),
- /* PowerPC 750CXe v3.1 (G3 embedded) */
- POWERPC_DEF("750cxe_v3.1", CPU_POWERPC_750CXE_v31, 750cx),
- /* PowerPC 750CXe v3.1b (G3 embedded) */
- POWERPC_DEF("750cxe_v3.1b", CPU_POWERPC_750CXE_v31b, 750cx),
- /* PowerPC 750CXr (G3 embedded) */
- POWERPC_DEF("750cxr", CPU_POWERPC_750CXR, 750cx),
- /* PowerPC 750FL (G3 embedded) */
- POWERPC_DEF("750fl", CPU_POWERPC_750FL, 750fx),
- /* PowerPC 750FX (G3 embedded) */
- POWERPC_DEF("750fx", CPU_POWERPC_750FX, 750fx),
- /* PowerPC 750FX v1.0 (G3 embedded) */
- POWERPC_DEF("750fx_v1.0", CPU_POWERPC_750FX_v10, 750fx),
- /* PowerPC 750FX v2.0 (G3 embedded) */
- POWERPC_DEF("750fx_v2.0", CPU_POWERPC_750FX_v20, 750fx),
- /* PowerPC 750FX v2.1 (G3 embedded) */
- POWERPC_DEF("750fx_v2.1", CPU_POWERPC_750FX_v21, 750fx),
- /* PowerPC 750FX v2.2 (G3 embedded) */
- POWERPC_DEF("750fx_v2.2", CPU_POWERPC_750FX_v22, 750fx),
- /* PowerPC 750FX v2.3 (G3 embedded) */
- POWERPC_DEF("750fx_v2.3", CPU_POWERPC_750FX_v23, 750fx),
- /* PowerPC 750GL (G3 embedded) */
- POWERPC_DEF("750gl", CPU_POWERPC_750GL, 750gx),
- /* PowerPC 750GX (G3 embedded) */
- POWERPC_DEF("750gx", CPU_POWERPC_750GX, 750gx),
- /* PowerPC 750GX v1.0 (G3 embedded) */
- POWERPC_DEF("750gx_v1.0", CPU_POWERPC_750GX_v10, 750gx),
- /* PowerPC 750GX v1.1 (G3 embedded) */
- POWERPC_DEF("750gx_v1.1", CPU_POWERPC_750GX_v11, 750gx),
- /* PowerPC 750GX v1.2 (G3 embedded) */
- POWERPC_DEF("750gx_v1.2", CPU_POWERPC_750GX_v12, 750gx),
- /* PowerPC 750L (G3 embedded) */
- POWERPC_DEF("750l", CPU_POWERPC_750L, 750),
- /* Code name for PowerPC 750L (G3 embedded) */
- POWERPC_DEF("LoneStar", CPU_POWERPC_750L, 750),
- /* PowerPC 750L v2.0 (G3 embedded) */
- POWERPC_DEF("750l_v2.0", CPU_POWERPC_750L_v20, 750),
- /* PowerPC 750L v2.1 (G3 embedded) */
- POWERPC_DEF("750l_v2.1", CPU_POWERPC_750L_v21, 750),
- /* PowerPC 750L v2.2 (G3 embedded) */
- POWERPC_DEF("750l_v2.2", CPU_POWERPC_750L_v22, 750),
- /* PowerPC 750L v3.0 (G3 embedded) */
- POWERPC_DEF("750l_v3.0", CPU_POWERPC_750L_v30, 750),
- /* PowerPC 750L v3.2 (G3 embedded) */
- POWERPC_DEF("750l_v3.2", CPU_POWERPC_750L_v32, 750),
- /* Generic PowerPC 745 */
- POWERPC_DEF("745", CPU_POWERPC_7x5, 745),
- /* Generic PowerPC 755 */
- POWERPC_DEF("755", CPU_POWERPC_7x5, 755),
- /* Code name for PowerPC 745/755 */
- POWERPC_DEF("Goldfinger", CPU_POWERPC_7x5, 755),
- /* PowerPC 745 v1.0 */
- POWERPC_DEF("745_v1.0", CPU_POWERPC_7x5_v10, 745),
- /* PowerPC 755 v1.0 */
- POWERPC_DEF("755_v1.0", CPU_POWERPC_7x5_v10, 755),
- /* PowerPC 745 v1.1 */
- POWERPC_DEF("745_v1.1", CPU_POWERPC_7x5_v11, 745),
- /* PowerPC 755 v1.1 */
- POWERPC_DEF("755_v1.1", CPU_POWERPC_7x5_v11, 755),
- /* PowerPC 745 v2.0 */
- POWERPC_DEF("745_v2.0", CPU_POWERPC_7x5_v20, 745),
- /* PowerPC 755 v2.0 */
- POWERPC_DEF("755_v2.0", CPU_POWERPC_7x5_v20, 755),
- /* PowerPC 745 v2.1 */
- POWERPC_DEF("745_v2.1", CPU_POWERPC_7x5_v21, 745),
- /* PowerPC 755 v2.1 */
- POWERPC_DEF("755_v2.1", CPU_POWERPC_7x5_v21, 755),
- /* PowerPC 745 v2.2 */
- POWERPC_DEF("745_v2.2", CPU_POWERPC_7x5_v22, 745),
- /* PowerPC 755 v2.2 */
- POWERPC_DEF("755_v2.2", CPU_POWERPC_7x5_v22, 755),
- /* PowerPC 745 v2.3 */
- POWERPC_DEF("745_v2.3", CPU_POWERPC_7x5_v23, 745),
- /* PowerPC 755 v2.3 */
- POWERPC_DEF("755_v2.3", CPU_POWERPC_7x5_v23, 755),
- /* PowerPC 745 v2.4 */
- POWERPC_DEF("745_v2.4", CPU_POWERPC_7x5_v24, 745),
- /* PowerPC 755 v2.4 */
- POWERPC_DEF("755_v2.4", CPU_POWERPC_7x5_v24, 755),
- /* PowerPC 745 v2.5 */
- POWERPC_DEF("745_v2.5", CPU_POWERPC_7x5_v25, 745),
- /* PowerPC 755 v2.5 */
- POWERPC_DEF("755_v2.5", CPU_POWERPC_7x5_v25, 755),
- /* PowerPC 745 v2.6 */
- POWERPC_DEF("745_v2.6", CPU_POWERPC_7x5_v26, 745),
- /* PowerPC 755 v2.6 */
- POWERPC_DEF("755_v2.6", CPU_POWERPC_7x5_v26, 755),
- /* PowerPC 745 v2.7 */
- POWERPC_DEF("745_v2.7", CPU_POWERPC_7x5_v27, 745),
- /* PowerPC 755 v2.7 */
- POWERPC_DEF("755_v2.7", CPU_POWERPC_7x5_v27, 755),
- /* PowerPC 745 v2.8 */
- POWERPC_DEF("745_v2.8", CPU_POWERPC_7x5_v28, 745),
- /* PowerPC 755 v2.8 */
- POWERPC_DEF("755_v2.8", CPU_POWERPC_7x5_v28, 755),
-#if defined (TODO)
- /* PowerPC 745P (G3) */
- POWERPC_DEF("745p", CPU_POWERPC_7x5P, 745),
- /* PowerPC 755P (G3) */
- POWERPC_DEF("755p", CPU_POWERPC_7x5P, 755),
-#endif
- /* PowerPC 74xx family */
- /* PowerPC 7400 (G4) */
- POWERPC_DEF("7400", CPU_POWERPC_7400, 7400),
- /* Code name for PowerPC 7400 */
- POWERPC_DEF("Max", CPU_POWERPC_7400, 7400),
- /* PowerPC 74xx is also well known as G4 */
- POWERPC_DEF("G4", CPU_POWERPC_7400, 7400),
- /* PowerPC 7400 v1.0 (G4) */
- POWERPC_DEF("7400_v1.0", CPU_POWERPC_7400_v10, 7400),
- /* PowerPC 7400 v1.1 (G4) */
- POWERPC_DEF("7400_v1.1", CPU_POWERPC_7400_v11, 7400),
- /* PowerPC 7400 v2.0 (G4) */
- POWERPC_DEF("7400_v2.0", CPU_POWERPC_7400_v20, 7400),
- /* PowerPC 7400 v2.1 (G4) */
- POWERPC_DEF("7400_v2.1", CPU_POWERPC_7400_v21, 7400),
- /* PowerPC 7400 v2.2 (G4) */
- POWERPC_DEF("7400_v2.2", CPU_POWERPC_7400_v22, 7400),
- /* PowerPC 7400 v2.6 (G4) */
- POWERPC_DEF("7400_v2.6", CPU_POWERPC_7400_v26, 7400),
- /* PowerPC 7400 v2.7 (G4) */
- POWERPC_DEF("7400_v2.7", CPU_POWERPC_7400_v27, 7400),
- /* PowerPC 7400 v2.8 (G4) */
- POWERPC_DEF("7400_v2.8", CPU_POWERPC_7400_v28, 7400),
- /* PowerPC 7400 v2.9 (G4) */
- POWERPC_DEF("7400_v2.9", CPU_POWERPC_7400_v29, 7400),
- /* PowerPC 7410 (G4) */
- POWERPC_DEF("7410", CPU_POWERPC_7410, 7410),
- /* Code name for PowerPC 7410 */
- POWERPC_DEF("Nitro", CPU_POWERPC_7410, 7410),
- /* PowerPC 7410 v1.0 (G4) */
- POWERPC_DEF("7410_v1.0", CPU_POWERPC_7410_v10, 7410),
- /* PowerPC 7410 v1.1 (G4) */
- POWERPC_DEF("7410_v1.1", CPU_POWERPC_7410_v11, 7410),
- /* PowerPC 7410 v1.2 (G4) */
- POWERPC_DEF("7410_v1.2", CPU_POWERPC_7410_v12, 7410),
- /* PowerPC 7410 v1.3 (G4) */
- POWERPC_DEF("7410_v1.3", CPU_POWERPC_7410_v13, 7410),
- /* PowerPC 7410 v1.4 (G4) */
- POWERPC_DEF("7410_v1.4", CPU_POWERPC_7410_v14, 7410),
- /* PowerPC 7448 (G4) */
- POWERPC_DEF("7448", CPU_POWERPC_7448, 7400),
- /* PowerPC 7448 v1.0 (G4) */
- POWERPC_DEF("7448_v1.0", CPU_POWERPC_7448_v10, 7400),
- /* PowerPC 7448 v1.1 (G4) */
- POWERPC_DEF("7448_v1.1", CPU_POWERPC_7448_v11, 7400),
- /* PowerPC 7448 v2.0 (G4) */
- POWERPC_DEF("7448_v2.0", CPU_POWERPC_7448_v20, 7400),
- /* PowerPC 7448 v2.1 (G4) */
- POWERPC_DEF("7448_v2.1", CPU_POWERPC_7448_v21, 7400),
- /* PowerPC 7450 (G4) */
- POWERPC_DEF("7450", CPU_POWERPC_7450, 7450),
- /* Code name for PowerPC 7450 */
- POWERPC_DEF("Vger", CPU_POWERPC_7450, 7450),
- /* PowerPC 7450 v1.0 (G4) */
- POWERPC_DEF("7450_v1.0", CPU_POWERPC_7450_v10, 7450),
- /* PowerPC 7450 v1.1 (G4) */
- POWERPC_DEF("7450_v1.1", CPU_POWERPC_7450_v11, 7450),
- /* PowerPC 7450 v1.2 (G4) */
- POWERPC_DEF("7450_v1.2", CPU_POWERPC_7450_v12, 7450),
- /* PowerPC 7450 v2.0 (G4) */
- POWERPC_DEF("7450_v2.0", CPU_POWERPC_7450_v20, 7450),
- /* PowerPC 7450 v2.1 (G4) */
- POWERPC_DEF("7450_v2.1", CPU_POWERPC_7450_v21, 7450),
- /* PowerPC 7441 (G4) */
- POWERPC_DEF("7441", CPU_POWERPC_74x1, 7440),
- /* PowerPC 7451 (G4) */
- POWERPC_DEF("7451", CPU_POWERPC_74x1, 7450),
- /* PowerPC 7441 v2.1 (G4) */
- POWERPC_DEF("7441_v2.1", CPU_POWERPC_7450_v21, 7440),
- /* PowerPC 7441 v2.3 (G4) */
- POWERPC_DEF("7441_v2.3", CPU_POWERPC_74x1_v23, 7440),
- /* PowerPC 7451 v2.3 (G4) */
- POWERPC_DEF("7451_v2.3", CPU_POWERPC_74x1_v23, 7450),
- /* PowerPC 7441 v2.10 (G4) */
- POWERPC_DEF("7441_v2.10", CPU_POWERPC_74x1_v210, 7440),
- /* PowerPC 7451 v2.10 (G4) */
- POWERPC_DEF("7451_v2.10", CPU_POWERPC_74x1_v210, 7450),
- /* PowerPC 7445 (G4) */
- POWERPC_DEF("7445", CPU_POWERPC_74x5, 7445),
- /* PowerPC 7455 (G4) */
- POWERPC_DEF("7455", CPU_POWERPC_74x5, 7455),
- /* Code name for PowerPC 7445/7455 */
- POWERPC_DEF("Apollo6", CPU_POWERPC_74x5, 7455),
- /* PowerPC 7445 v1.0 (G4) */
- POWERPC_DEF("7445_v1.0", CPU_POWERPC_74x5_v10, 7445),
- /* PowerPC 7455 v1.0 (G4) */
- POWERPC_DEF("7455_v1.0", CPU_POWERPC_74x5_v10, 7455),
- /* PowerPC 7445 v2.1 (G4) */
- POWERPC_DEF("7445_v2.1", CPU_POWERPC_74x5_v21, 7445),
- /* PowerPC 7455 v2.1 (G4) */
- POWERPC_DEF("7455_v2.1", CPU_POWERPC_74x5_v21, 7455),
- /* PowerPC 7445 v3.2 (G4) */
- POWERPC_DEF("7445_v3.2", CPU_POWERPC_74x5_v32, 7445),
- /* PowerPC 7455 v3.2 (G4) */
- POWERPC_DEF("7455_v3.2", CPU_POWERPC_74x5_v32, 7455),
- /* PowerPC 7445 v3.3 (G4) */
- POWERPC_DEF("7445_v3.3", CPU_POWERPC_74x5_v33, 7445),
- /* PowerPC 7455 v3.3 (G4) */
- POWERPC_DEF("7455_v3.3", CPU_POWERPC_74x5_v33, 7455),
- /* PowerPC 7445 v3.4 (G4) */
- POWERPC_DEF("7445_v3.4", CPU_POWERPC_74x5_v34, 7445),
- /* PowerPC 7455 v3.4 (G4) */
- POWERPC_DEF("7455_v3.4", CPU_POWERPC_74x5_v34, 7455),
- /* PowerPC 7447 (G4) */
- POWERPC_DEF("7447", CPU_POWERPC_74x7, 7445),
- /* PowerPC 7457 (G4) */
- POWERPC_DEF("7457", CPU_POWERPC_74x7, 7455),
- /* Code name for PowerPC 7447/7457 */
- POWERPC_DEF("Apollo7", CPU_POWERPC_74x7, 7455),
- /* PowerPC 7447 v1.0 (G4) */
- POWERPC_DEF("7447_v1.0", CPU_POWERPC_74x7_v10, 7445),
- /* PowerPC 7457 v1.0 (G4) */
- POWERPC_DEF("7457_v1.0", CPU_POWERPC_74x7_v10, 7455),
- /* PowerPC 7447 v1.1 (G4) */
- POWERPC_DEF("7447_v1.1", CPU_POWERPC_74x7_v11, 7445),
- /* PowerPC 7457 v1.1 (G4) */
- POWERPC_DEF("7457_v1.1", CPU_POWERPC_74x7_v11, 7455),
- /* PowerPC 7457 v1.2 (G4) */
- POWERPC_DEF("7457_v1.2", CPU_POWERPC_74x7_v12, 7455),
- /* PowerPC 7447A (G4) */
- POWERPC_DEF("7447A", CPU_POWERPC_74x7A, 7445),
- /* PowerPC 7457A (G4) */
- POWERPC_DEF("7457A", CPU_POWERPC_74x7A, 7455),
- /* PowerPC 7447A v1.0 (G4) */
- POWERPC_DEF("7447A_v1.0", CPU_POWERPC_74x7A_v10, 7445),
- /* PowerPC 7457A v1.0 (G4) */
- POWERPC_DEF("7457A_v1.0", CPU_POWERPC_74x7A_v10, 7455),
- /* Code name for PowerPC 7447A/7457A */
- POWERPC_DEF("Apollo7PM", CPU_POWERPC_74x7A_v10, 7455),
- /* PowerPC 7447A v1.1 (G4) */
- POWERPC_DEF("7447A_v1.1", CPU_POWERPC_74x7A_v11, 7445),
- /* PowerPC 7457A v1.1 (G4) */
- POWERPC_DEF("7457A_v1.1", CPU_POWERPC_74x7A_v11, 7455),
- /* PowerPC 7447A v1.2 (G4) */
- POWERPC_DEF("7447A_v1.2", CPU_POWERPC_74x7A_v12, 7445),
- /* PowerPC 7457A v1.2 (G4) */
- POWERPC_DEF("7457A_v1.2", CPU_POWERPC_74x7A_v12, 7455),
- /* 64 bits PowerPC */
-#if defined (TARGET_PPC64)
- /* PowerPC 620 */
- POWERPC_DEF("620", CPU_POWERPC_620, 620),
- /* Code name for PowerPC 620 */
- POWERPC_DEF("Trident", CPU_POWERPC_620, 620),
-#if defined (TODO)
- /* PowerPC 630 (POWER3) */
- POWERPC_DEF("630", CPU_POWERPC_630, 630),
- POWERPC_DEF("POWER3", CPU_POWERPC_630, 630),
- /* Code names for POWER3 */
- POWERPC_DEF("Boxer", CPU_POWERPC_630, 630),
- POWERPC_DEF("Dino", CPU_POWERPC_630, 630),
-#endif
-#if defined (TODO)
- /* PowerPC 631 (Power 3+) */
- POWERPC_DEF("631", CPU_POWERPC_631, 631),
- POWERPC_DEF("POWER3+", CPU_POWERPC_631, 631),
-#endif
-#if defined (TODO)
- /* POWER4 */
- POWERPC_DEF("POWER4", CPU_POWERPC_POWER4, POWER4),
-#endif
-#if defined (TODO)
- /* POWER4p */
- POWERPC_DEF("POWER4+", CPU_POWERPC_POWER4P, POWER4P),
-#endif
-#if defined (TODO)
- /* POWER5 */
- POWERPC_DEF("POWER5", CPU_POWERPC_POWER5, POWER5),
- /* POWER5GR */
- POWERPC_DEF("POWER5gr", CPU_POWERPC_POWER5GR, POWER5),
-#endif
-#if defined (TODO)
- /* POWER5+ */
- POWERPC_DEF("POWER5+", CPU_POWERPC_POWER5P, POWER5P),
- /* POWER5GS */
- POWERPC_DEF("POWER5gs", CPU_POWERPC_POWER5GS, POWER5P),
-#endif
-#if defined (TODO)
- /* POWER6 */
- POWERPC_DEF("POWER6", CPU_POWERPC_POWER6, POWER6),
- /* POWER6 running in POWER5 mode */
- POWERPC_DEF("POWER6_5", CPU_POWERPC_POWER6_5, POWER5),
- /* POWER6A */
- POWERPC_DEF("POWER6A", CPU_POWERPC_POWER6A, POWER6),
-#endif
- /* POWER7 */
- POWERPC_DEF("POWER7", CPU_POWERPC_POWER7, POWER7),
- POWERPC_DEF("POWER7_v2.0", CPU_POWERPC_POWER7_v20, POWER7),
- POWERPC_DEF("POWER7_v2.1", CPU_POWERPC_POWER7_v21, POWER7),
- POWERPC_DEF("POWER7_v2.3", CPU_POWERPC_POWER7_v23, POWER7),
- /* PowerPC 970 */
- POWERPC_DEF("970", CPU_POWERPC_970, 970),
- /* PowerPC 970FX (G5) */
- POWERPC_DEF("970fx", CPU_POWERPC_970FX, 970FX),
- /* PowerPC 970FX v1.0 (G5) */
- POWERPC_DEF("970fx_v1.0", CPU_POWERPC_970FX_v10, 970FX),
- /* PowerPC 970FX v2.0 (G5) */
- POWERPC_DEF("970fx_v2.0", CPU_POWERPC_970FX_v20, 970FX),
- /* PowerPC 970FX v2.1 (G5) */
- POWERPC_DEF("970fx_v2.1", CPU_POWERPC_970FX_v21, 970FX),
- /* PowerPC 970FX v3.0 (G5) */
- POWERPC_DEF("970fx_v3.0", CPU_POWERPC_970FX_v30, 970FX),
- /* PowerPC 970FX v3.1 (G5) */
- POWERPC_DEF("970fx_v3.1", CPU_POWERPC_970FX_v31, 970FX),
- /* PowerPC 970GX (G5) */
- POWERPC_DEF("970gx", CPU_POWERPC_970GX, 970GX),
- /* PowerPC 970MP */
- POWERPC_DEF("970mp", CPU_POWERPC_970MP, 970MP),
- /* PowerPC 970MP v1.0 */
- POWERPC_DEF("970mp_v1.0", CPU_POWERPC_970MP_v10, 970MP),
- /* PowerPC 970MP v1.1 */
- POWERPC_DEF("970mp_v1.1", CPU_POWERPC_970MP_v11, 970MP),
-#if defined (TODO)
- /* PowerPC Cell */
- POWERPC_DEF("Cell", CPU_POWERPC_CELL, 970),
-#endif
-#if defined (TODO)
- /* PowerPC Cell v1.0 */
- POWERPC_DEF("Cell_v1.0", CPU_POWERPC_CELL_v10, 970),
-#endif
-#if defined (TODO)
- /* PowerPC Cell v2.0 */
- POWERPC_DEF("Cell_v2.0", CPU_POWERPC_CELL_v20, 970),
-#endif
-#if defined (TODO)
- /* PowerPC Cell v3.0 */
- POWERPC_DEF("Cell_v3.0", CPU_POWERPC_CELL_v30, 970),
-#endif
-#if defined (TODO)
- /* PowerPC Cell v3.1 */
- POWERPC_DEF("Cell_v3.1", CPU_POWERPC_CELL_v31, 970),
-#endif
-#if defined (TODO)
- /* PowerPC Cell v3.2 */
- POWERPC_DEF("Cell_v3.2", CPU_POWERPC_CELL_v32, 970),
-#endif
-#if defined (TODO)
- /* RS64 (Apache/A35) */
- /* This one seems to support the whole POWER2 instruction set
- * and the PowerPC 64 one.
- */
- /* What about A10 & A30 ? */
- POWERPC_DEF("RS64", CPU_POWERPC_RS64, RS64),
- POWERPC_DEF("Apache", CPU_POWERPC_RS64, RS64),
- POWERPC_DEF("A35", CPU_POWERPC_RS64, RS64),
-#endif
-#if defined (TODO)
- /* RS64-II (NorthStar/A50) */
- POWERPC_DEF("RS64-II", CPU_POWERPC_RS64II, RS64),
- POWERPC_DEF("NorthStar", CPU_POWERPC_RS64II, RS64),
- POWERPC_DEF("A50", CPU_POWERPC_RS64II, RS64),
-#endif
-#if defined (TODO)
- /* RS64-III (Pulsar) */
- POWERPC_DEF("RS64-III", CPU_POWERPC_RS64III, RS64),
- POWERPC_DEF("Pulsar", CPU_POWERPC_RS64III, RS64),
-#endif
-#if defined (TODO)
- /* RS64-IV (IceStar/IStar/SStar) */
- POWERPC_DEF("RS64-IV", CPU_POWERPC_RS64IV, RS64),
- POWERPC_DEF("IceStar", CPU_POWERPC_RS64IV, RS64),
- POWERPC_DEF("IStar", CPU_POWERPC_RS64IV, RS64),
- POWERPC_DEF("SStar", CPU_POWERPC_RS64IV, RS64),
-#endif
+ dc->desc = "POWER8";
+ pcc->init_proc = init_proc_POWER7;
+ pcc->check_pow = check_pow_nocheck;
+ pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+ PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+ PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
+ PPC_FLOAT_STFIWX |
+ PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC | PPC_MEM_EIEIO |
+ PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
+ PPC_64B | PPC_ALTIVEC |
+ PPC_SEGMENT_64B | PPC_SLBI |
+ PPC_POPCNTB | PPC_POPCNTWD;
+ pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX;
+ pcc->msr_mask = 0x800000000204FF36ULL;
+ pcc->mmu_model = POWERPC_MMU_2_06;
+#if defined(CONFIG_SOFTMMU)
+ pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
+#endif
+ pcc->excp_model = POWERPC_EXCP_POWER7;
+ pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
+ pcc->bfd_mach = bfd_mach_ppc64;
+ pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
+ POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
+ POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR;
+ pcc->l1_dcache_size = 0x8000;
+ pcc->l1_icache_size = 0x8000;
+}
#endif /* defined (TARGET_PPC64) */
- /* POWER */
-#if defined (TODO)
- /* Original POWER */
- POWERPC_DEF("POWER", CPU_POWERPC_POWER, POWER),
- POWERPC_DEF("RIOS", CPU_POWERPC_POWER, POWER),
- POWERPC_DEF("RSC", CPU_POWERPC_POWER, POWER),
- POWERPC_DEF("RSC3308", CPU_POWERPC_POWER, POWER),
- POWERPC_DEF("RSC4608", CPU_POWERPC_POWER, POWER),
-#endif
-#if defined (TODO)
- /* POWER2 */
- POWERPC_DEF("POWER2", CPU_POWERPC_POWER2, POWER),
- POWERPC_DEF("RSC2", CPU_POWERPC_POWER2, POWER),
- POWERPC_DEF("P2SC", CPU_POWERPC_POWER2, POWER),
-#endif
- /* PA semi cores */
-#if defined (TODO)
- /* PA PA6T */
- POWERPC_DEF("PA6T", CPU_POWERPC_PA6T, PA6T),
-#endif
- /* Generic PowerPCs */
-#if defined (TARGET_PPC64)
- POWERPC_DEF("ppc64", CPU_POWERPC_PPC64, PPC64),
-#endif
- POWERPC_DEF("ppc32", CPU_POWERPC_PPC32, PPC32),
- POWERPC_DEF("ppc", CPU_POWERPC_DEFAULT, DEFAULT),
- /* Fallback */
- POWERPC_DEF("default", CPU_POWERPC_DEFAULT, DEFAULT),
-};
+
/*****************************************************************************/
/* Generic CPU instantiation routine */
-static void init_ppc_proc (CPUPPCState *env, const ppc_def_t *def)
+static void init_ppc_proc(PowerPCCPU *cpu)
{
+ PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
+ CPUPPCState *env = &cpu->env;
#if !defined(CONFIG_USER_ONLY)
int i;
@@ -9414,7 +7290,6 @@ static void init_ppc_proc (CPUPPCState *env, const ppc_def_t *def)
/* Set all exception vectors to an invalid address */
for (i = 0; i < POWERPC_EXCP_NB; i++)
env->excp_vectors[i] = (target_ulong)(-1ULL);
- env->hreset_excp_prefix = 0x00000000;
env->ivor_mask = 0x00000000;
env->ivpr_mask = 0x00000000;
/* Default MMU definitions */
@@ -9434,26 +7309,24 @@ static void init_ppc_proc (CPUPPCState *env, const ppc_def_t *def)
#endif
SPR_NOACCESS,
&spr_read_generic, SPR_NOACCESS,
- def->pvr);
+ pcc->pvr);
/* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
- if (def->svr != POWERPC_SVR_NONE) {
- if (def->svr & POWERPC_SVR_E500) {
+ if (pcc->svr != POWERPC_SVR_NONE) {
+ if (pcc->svr & POWERPC_SVR_E500) {
spr_register(env, SPR_E500_SVR, "SVR",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, SPR_NOACCESS,
- def->svr & ~POWERPC_SVR_E500);
+ pcc->svr & ~POWERPC_SVR_E500);
} else {
spr_register(env, SPR_SVR, "SVR",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, SPR_NOACCESS,
- def->svr);
+ pcc->svr);
}
}
/* PowerPC implementation specific initialisations (SPRs, timers, ...) */
- (*def->init_proc)(env);
-#if !defined(CONFIG_USER_ONLY)
- env->excp_prefix = env->hreset_excp_prefix;
-#endif
+ (*pcc->init_proc)(env);
+
/* MSR bits & flags consistency checks */
if (env->msr_mask & (1 << 25)) {
switch (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
@@ -9646,7 +7519,7 @@ static int create_new_table (opc_handler_t **table, unsigned char idx)
{
opc_handler_t **tmp;
- tmp = malloc(0x20 * sizeof(opc_handler_t));
+ tmp = g_malloc(0x20 * sizeof(opc_handler_t));
fill_new_table(tmp, 0x20);
table[idx] = (opc_handler_t *)((uintptr_t)tmp | PPC_INDIRECT);
@@ -9797,27 +7670,27 @@ static void fix_opcode_tables (opc_handler_t **ppc_opcodes)
}
/*****************************************************************************/
-static int create_ppc_opcodes (CPUPPCState *env, const ppc_def_t *def)
+static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp)
{
+ PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
+ CPUPPCState *env = &cpu->env;
opcode_t *opc;
fill_new_table(env->opcodes, 0x40);
for (opc = opcodes; opc < &opcodes[ARRAY_SIZE(opcodes)]; opc++) {
- if (((opc->handler.type & def->insns_flags) != 0) ||
- ((opc->handler.type2 & def->insns_flags2) != 0)) {
+ if (((opc->handler.type & pcc->insns_flags) != 0) ||
+ ((opc->handler.type2 & pcc->insns_flags2) != 0)) {
if (register_insn(env->opcodes, opc) < 0) {
- printf("*** ERROR initializing PowerPC instruction "
- "0x%02x 0x%02x 0x%02x\n", opc->opc1, opc->opc2,
- opc->opc3);
- return -1;
+ error_setg(errp, "ERROR initializing PowerPC instruction "
+ "0x%02x 0x%02x 0x%02x", opc->opc1, opc->opc2,
+ opc->opc3);
+ return;
}
}
}
fix_opcode_tables(env->opcodes);
fflush(stdout);
fflush(stderr);
-
- return 0;
}
#if defined(PPC_DUMP_CPU)
@@ -9913,7 +7786,7 @@ static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
return 8;
}
if (n == 32) {
- /* FPSCR not implemented */
+ helper_store_fpscr(env, ldl_p(mem_buf), 0xffffffff);
return 4;
}
return 0;
@@ -10009,8 +7882,10 @@ static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
return 0;
}
-static int ppc_fixup_cpu(CPUPPCState *env)
+static int ppc_fixup_cpu(PowerPCCPU *cpu)
{
+ CPUPPCState *env = &cpu->env;
+
/* TCG doesn't (yet) emulate some groups of instructions that
* are implemented on some otherwise supported CPUs (e.g. VSX
* and decimal floating point instructions on POWER7). We
@@ -10031,70 +7906,72 @@ static int ppc_fixup_cpu(CPUPPCState *env)
return 0;
}
-int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def)
+static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
{
- env->msr_mask = def->msr_mask;
- env->mmu_model = def->mmu_model;
- env->excp_model = def->excp_model;
- env->bus_model = def->bus_model;
- env->insns_flags = def->insns_flags;
- env->insns_flags2 = def->insns_flags2;
- env->flags = def->flags;
- env->bfd_mach = def->bfd_mach;
- env->check_pow = def->check_pow;
+ CPUState *cs = CPU(dev);
+ PowerPCCPU *cpu = POWERPC_CPU(dev);
+ PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
+ Error *local_err = NULL;
+#if !defined(CONFIG_USER_ONLY)
+ int max_smt = kvm_enabled() ? kvmppc_smt_threads() : 1;
+#endif
-#if defined(TARGET_PPC64)
- if (def->sps)
- env->sps = *def->sps;
- else if (env->mmu_model & POWERPC_MMU_64) {
- /* Use default sets of page sizes */
- static const struct ppc_segment_page_sizes defsps = {
- .sps = {
- { .page_shift = 12, /* 4K */
- .slb_enc = 0,
- .enc = { { .page_shift = 12, .pte_enc = 0 } }
- },
- { .page_shift = 24, /* 16M */
- .slb_enc = 0x100,
- .enc = { { .page_shift = 24, .pte_enc = 0 } }
- },
- },
- };
- env->sps = defsps;
+#if !defined(CONFIG_USER_ONLY)
+ if (smp_threads > max_smt) {
+ error_setg(errp, "Cannot support more than %d threads on PPC with %s",
+ max_smt, kvm_enabled() ? "KVM" : "TCG");
+ return;
}
-#endif /* defined(TARGET_PPC64) */
+#endif
if (kvm_enabled()) {
- if (kvmppc_fixup_cpu(env) != 0) {
- fprintf(stderr, "Unable to virtualize selected CPU with KVM\n");
- exit(1);
+ if (kvmppc_fixup_cpu(cpu) != 0) {
+ error_setg(errp, "Unable to virtualize selected CPU with KVM");
+ return;
}
- } else {
- if (ppc_fixup_cpu(env) != 0) {
- fprintf(stderr, "Unable to emulate selected CPU with TCG\n");
- exit(1);
+ } else if (tcg_enabled()) {
+ if (ppc_fixup_cpu(cpu) != 0) {
+ error_setg(errp, "Unable to emulate selected CPU with TCG");
+ return;
}
}
- if (create_ppc_opcodes(env, def) < 0)
- return -1;
- init_ppc_proc(env, def);
+#if defined(TARGET_PPCEMB)
+ if (pcc->mmu_model != POWERPC_MMU_BOOKE) {
+ error_setg(errp, "CPU does not possess a BookE MMU. "
+ "Please use qemu-system-ppc or qemu-system-ppc64 instead "
+ "or choose another CPU model.");
+ return;
+ }
+#endif
- if (def->insns_flags & PPC_FLOAT) {
- gdb_register_coprocessor(env, gdb_get_float_reg, gdb_set_float_reg,
+ create_ppc_opcodes(cpu, &local_err);
+ if (local_err != NULL) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ init_ppc_proc(cpu);
+
+ if (pcc->insns_flags & PPC_FLOAT) {
+ gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
33, "power-fpu.xml", 0);
}
- if (def->insns_flags & PPC_ALTIVEC) {
- gdb_register_coprocessor(env, gdb_get_avr_reg, gdb_set_avr_reg,
+ if (pcc->insns_flags & PPC_ALTIVEC) {
+ gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg,
34, "power-altivec.xml", 0);
}
- if (def->insns_flags & PPC_SPE) {
- gdb_register_coprocessor(env, gdb_get_spe_reg, gdb_set_spe_reg,
+ if (pcc->insns_flags & PPC_SPE) {
+ gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
34, "power-spe.xml", 0);
}
+ qemu_init_vcpu(cs);
+
+ pcc->parent_realize(dev, errp);
+
#if defined(PPC_DUMP_CPU)
{
+ CPUPPCState *env = &cpu->env;
const char *mmu_model, *excp_model, *bus_model;
switch (env->mmu_model) {
case POWERPC_MMU_32B:
@@ -10132,9 +8009,6 @@ int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def)
case POWERPC_MMU_64B:
mmu_model = "PowerPC 64";
break;
- case POWERPC_MMU_620:
- mmu_model = "PowerPC 620";
- break;
#endif
default:
mmu_model = "Unknown or invalid";
@@ -10210,7 +8084,7 @@ int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def)
}
printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64 "\n"
" MMU model : %s\n",
- def->name, def->pvr, def->msr_mask, mmu_model);
+ pcc->name, pcc->pvr, pcc->msr_mask, mmu_model);
#if !defined(CONFIG_USER_ONLY)
if (env->tlb != NULL) {
printf(" %d %s TLB in %d ways\n",
@@ -10249,56 +8123,111 @@ int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def)
printf(" none\n");
printf(" Time-base/decrementer clock source: %s\n",
env->flags & POWERPC_FLAG_RTC_CLK ? "RTC clock" : "bus clock");
+ dump_ppc_insns(env);
+ dump_ppc_sprs(env);
+ fflush(stdout);
}
- dump_ppc_insns(env);
- dump_ppc_sprs(env);
- fflush(stdout);
#endif
+}
- return 0;
+static void ppc_cpu_unrealizefn(DeviceState *dev, Error **errp)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(dev);
+ CPUPPCState *env = &cpu->env;
+ int i;
+
+ for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) {
+ if (env->opcodes[i] != &invalid_handler) {
+ g_free(env->opcodes[i]);
+ }
+ }
}
-static bool ppc_cpu_usable(const ppc_def_t *def)
+static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b)
{
+ ObjectClass *oc = (ObjectClass *)a;
+ uint32_t pvr = *(uint32_t *)b;
+ PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
+
+ /* -cpu host does a PVR lookup during construction */
+ if (unlikely(strcmp(object_class_get_name(oc),
+ TYPE_HOST_POWERPC_CPU) == 0)) {
+ return -1;
+ }
+
#if defined(TARGET_PPCEMB)
- /* When using the ppcemb target, we only support 440 style cores */
- if (def->mmu_model != POWERPC_MMU_BOOKE) {
- return false;
+ if (pcc->mmu_model != POWERPC_MMU_BOOKE) {
+ return -1;
}
#endif
- return true;
+ return pcc->pvr == pvr ? 0 : -1;
}
-const ppc_def_t *ppc_find_by_pvr(uint32_t pvr)
+PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr)
{
- int i;
+ GSList *list, *item;
+ PowerPCCPUClass *pcc = NULL;
- for (i = 0; i < ARRAY_SIZE(ppc_defs); i++) {
- if (!ppc_cpu_usable(&ppc_defs[i])) {
- continue;
- }
-
- /* If we have an exact match, we're done */
- if (pvr == ppc_defs[i].pvr) {
- return &ppc_defs[i];
- }
+ list = object_class_get_list(TYPE_POWERPC_CPU, false);
+ item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr);
+ if (item != NULL) {
+ pcc = POWERPC_CPU_CLASS(item->data);
}
+ g_slist_free(list);
+
+ return pcc;
+}
+
+static gint ppc_cpu_compare_class_name(gconstpointer a, gconstpointer b)
+{
+ ObjectClass *oc = (ObjectClass *)a;
+ const char *name = b;
+#if defined(TARGET_PPCEMB)
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+#endif
- return NULL;
+ if (strncasecmp(name, object_class_get_name(oc), strlen(name)) == 0 &&
+#if defined(TARGET_PPCEMB)
+ pcc->mmu_model == POWERPC_MMU_BOOKE &&
+#endif
+ strcmp(object_class_get_name(oc) + strlen(name),
+ "-" TYPE_POWERPC_CPU) == 0) {
+ return 0;
+ }
+ return -1;
}
#include <ctype.h>
-const ppc_def_t *cpu_ppc_find_by_name (const char *name)
+static ObjectClass *ppc_cpu_class_by_name(const char *name);
+
+static ObjectClass *ppc_cpu_class_by_alias(PowerPCCPUAlias *alias)
{
- const ppc_def_t *ret;
- const char *p;
- int i, max, len;
+ ObjectClass *invalid_class = (void*)ppc_cpu_class_by_alias;
+
+ /* Cache target class lookups in the alias table */
+ if (!alias->oc) {
+ alias->oc = ppc_cpu_class_by_name(alias->model);
+ if (!alias->oc) {
+ /* Fast check for non-existing aliases */
+ alias->oc = invalid_class;
+ }
+ }
- if (kvm_enabled() && (strcasecmp(name, "host") == 0)) {
- return kvmppc_host_cpu_def();
+ if (alias->oc == invalid_class) {
+ return NULL;
+ } else {
+ return alias->oc;
}
+}
+
+static ObjectClass *ppc_cpu_class_by_name(const char *name)
+{
+ GSList *list, *item;
+ ObjectClass *ret = NULL;
+ const char *p;
+ int i, len;
/* Check if the given name is a PVR */
len = strlen(name);
@@ -10312,55 +8241,184 @@ const ppc_def_t *cpu_ppc_find_by_name (const char *name)
if (!qemu_isxdigit(*p++))
break;
}
- if (i == 8)
- return ppc_find_by_pvr(strtoul(name, NULL, 16));
- }
- ret = NULL;
- max = ARRAY_SIZE(ppc_defs);
- for (i = 0; i < max; i++) {
- if (!ppc_cpu_usable(&ppc_defs[i])) {
- continue;
+ if (i == 8) {
+ ret = OBJECT_CLASS(ppc_cpu_class_by_pvr(strtoul(name, NULL, 16)));
+ return ret;
}
+ }
- if (strcasecmp(name, ppc_defs[i].name) == 0) {
- ret = &ppc_defs[i];
- break;
+ for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
+ if (strcmp(ppc_cpu_aliases[i].alias, name) == 0) {
+ return ppc_cpu_class_by_alias(&ppc_cpu_aliases[i]);
}
}
+ list = object_class_get_list(TYPE_POWERPC_CPU, false);
+ item = g_slist_find_custom(list, name, ppc_cpu_compare_class_name);
+ if (item != NULL) {
+ ret = OBJECT_CLASS(item->data);
+ }
+ g_slist_free(list);
+
return ret;
}
-void ppc_cpu_list (FILE *f, fprintf_function cpu_fprintf)
+PowerPCCPU *cpu_ppc_init(const char *cpu_model)
{
- int i, max;
+ PowerPCCPU *cpu;
+ CPUPPCState *env;
+ ObjectClass *oc;
+ Error *err = NULL;
+
+ oc = ppc_cpu_class_by_name(cpu_model);
+ if (oc == NULL) {
+ return NULL;
+ }
+
+ cpu = POWERPC_CPU(object_new(object_class_get_name(oc)));
+ env = &cpu->env;
+ env->cpu_model_str = cpu_model;
+
+ object_property_set_bool(OBJECT(cpu), true, "realized", &err);
+ if (err != NULL) {
+ fprintf(stderr, "%s\n", error_get_pretty(err));
+ error_free(err);
+ object_unref(OBJECT(cpu));
+ return NULL;
+ }
+
+ return cpu;
+}
+
+/* Sort by PVR, ordering special case "host" last. */
+static gint ppc_cpu_list_compare(gconstpointer a, gconstpointer b)
+{
+ ObjectClass *oc_a = (ObjectClass *)a;
+ ObjectClass *oc_b = (ObjectClass *)b;
+ PowerPCCPUClass *pcc_a = POWERPC_CPU_CLASS(oc_a);
+ PowerPCCPUClass *pcc_b = POWERPC_CPU_CLASS(oc_b);
+ const char *name_a = object_class_get_name(oc_a);
+ const char *name_b = object_class_get_name(oc_b);
+
+ if (strcmp(name_a, TYPE_HOST_POWERPC_CPU) == 0) {
+ return 1;
+ } else if (strcmp(name_b, TYPE_HOST_POWERPC_CPU) == 0) {
+ return -1;
+ } else {
+ /* Avoid an integer overflow during subtraction */
+ if (pcc_a->pvr < pcc_b->pvr) {
+ return -1;
+ } else if (pcc_a->pvr > pcc_b->pvr) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+}
+
+static void ppc_cpu_list_entry(gpointer data, gpointer user_data)
+{
+ ObjectClass *oc = data;
+ CPUListState *s = user_data;
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+ const char *typename = object_class_get_name(oc);
+ char *name;
+ int i;
+
+#if defined(TARGET_PPCEMB)
+ if (pcc->mmu_model != POWERPC_MMU_BOOKE) {
+ return;
+ }
+#endif
+ if (unlikely(strcmp(typename, TYPE_HOST_POWERPC_CPU) == 0)) {
+ return;
+ }
- max = ARRAY_SIZE(ppc_defs);
- for (i = 0; i < max; i++) {
- if (!ppc_cpu_usable(&ppc_defs[i])) {
+ name = g_strndup(typename,
+ strlen(typename) - strlen("-" TYPE_POWERPC_CPU));
+ (*s->cpu_fprintf)(s->file, "PowerPC %-16s PVR %08x\n",
+ name, pcc->pvr);
+ for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
+ PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
+ ObjectClass *alias_oc = ppc_cpu_class_by_alias(alias);
+
+ if (alias_oc != oc) {
continue;
}
+ (*s->cpu_fprintf)(s->file, "PowerPC %-16s (alias for %s)\n",
+ alias->alias, name);
+ }
+ g_free(name);
+}
+
+void ppc_cpu_list(FILE *f, fprintf_function cpu_fprintf)
+{
+ CPUListState s = {
+ .file = f,
+ .cpu_fprintf = cpu_fprintf,
+ };
+ GSList *list;
+
+ list = object_class_get_list(TYPE_POWERPC_CPU, false);
+ list = g_slist_sort(list, ppc_cpu_list_compare);
+ g_slist_foreach(list, ppc_cpu_list_entry, &s);
+ g_slist_free(list);
+
+#ifdef CONFIG_KVM
+ cpu_fprintf(f, "\n");
+ cpu_fprintf(f, "PowerPC %-16s\n", "host");
+#endif
+}
+
+static void ppc_cpu_defs_entry(gpointer data, gpointer user_data)
+{
+ ObjectClass *oc = data;
+ CpuDefinitionInfoList **first = user_data;
+ const char *typename;
+ CpuDefinitionInfoList *entry;
+ CpuDefinitionInfo *info;
+#if defined(TARGET_PPCEMB)
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
- (*cpu_fprintf)(f, "PowerPC %-16s PVR %08x\n",
- ppc_defs[i].name, ppc_defs[i].pvr);
+ if (pcc->mmu_model != POWERPC_MMU_BOOKE) {
+ return;
}
+#endif
+
+ typename = object_class_get_name(oc);
+ info = g_malloc0(sizeof(*info));
+ info->name = g_strndup(typename,
+ strlen(typename) - strlen("-" TYPE_POWERPC_CPU));
+
+ entry = g_malloc0(sizeof(*entry));
+ entry->value = info;
+ entry->next = *first;
+ *first = entry;
}
CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
{
CpuDefinitionInfoList *cpu_list = NULL;
+ GSList *list;
int i;
- for (i = 0; i < ARRAY_SIZE(ppc_defs); i++) {
+ list = object_class_get_list(TYPE_POWERPC_CPU, false);
+ g_slist_foreach(list, ppc_cpu_defs_entry, &cpu_list);
+ g_slist_free(list);
+
+ for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
+ PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
+ ObjectClass *oc;
CpuDefinitionInfoList *entry;
CpuDefinitionInfo *info;
- if (!ppc_cpu_usable(&ppc_defs[i])) {
+ oc = ppc_cpu_class_by_alias(alias);
+ if (oc == NULL) {
continue;
}
info = g_malloc0(sizeof(*info));
- info->name = g_strdup(ppc_defs[i].name);
+ info->name = g_strdup(alias->alias);
entry = g_malloc0(sizeof(*entry));
entry->value = info;
@@ -10371,6 +8429,13 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
return cpu_list;
}
+static void ppc_cpu_set_pc(CPUState *cs, vaddr value)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+
+ cpu->env.nip = value;
+}
+
/* CPUClass::reset() */
static void ppc_cpu_reset(CPUState *s)
{
@@ -10379,11 +8444,6 @@ static void ppc_cpu_reset(CPUState *s)
CPUPPCState *env = &cpu->env;
target_ulong msr;
- if (qemu_loglevel_mask(CPU_LOG_RESET)) {
- qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
- log_cpu_state(env, 0);
- }
-
pcc->parent_reset(s);
msr = (target_ulong)0;
@@ -10404,19 +8464,23 @@ static void ppc_cpu_reset(CPUState *s)
msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
msr |= (target_ulong)1 << MSR_PR;
-#else
- env->excp_prefix = env->hreset_excp_prefix;
- env->nip = env->hreset_vector | env->excp_prefix;
- if (env->mmu_model != POWERPC_MMU_REAL) {
- ppc_tlb_invalidate_all(env);
- }
#endif
- env->msr = msr & env->msr_mask;
+
#if defined(TARGET_PPC64)
if (env->mmu_model & POWERPC_MMU_64) {
env->msr |= (1ULL << MSR_SF);
}
#endif
+
+ hreg_store_msr(env, msr, 1);
+
+#if !defined(CONFIG_USER_ONLY)
+ env->nip = env->hreset_vector | env->excp_prefix;
+ if (env->mmu_model != POWERPC_MMU_REAL) {
+ ppc_tlb_invalidate_all(env);
+ }
+#endif
+
hreg_compute_hflags(env);
env->reserve_addr = (target_ulong)-1ULL;
/* Be sure no exception or interrupt is pending */
@@ -10438,19 +8502,81 @@ static void ppc_cpu_reset(CPUState *s)
static void ppc_cpu_initfn(Object *obj)
{
+ CPUState *cs = CPU(obj);
PowerPCCPU *cpu = POWERPC_CPU(obj);
+ PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
CPUPPCState *env = &cpu->env;
+ cs->env_ptr = env;
cpu_exec_init(env);
+
+ env->msr_mask = pcc->msr_mask;
+ env->mmu_model = pcc->mmu_model;
+ env->excp_model = pcc->excp_model;
+ env->bus_model = pcc->bus_model;
+ env->insns_flags = pcc->insns_flags;
+ env->insns_flags2 = pcc->insns_flags2;
+ env->flags = pcc->flags;
+ env->bfd_mach = pcc->bfd_mach;
+ env->check_pow = pcc->check_pow;
+
+#if defined(TARGET_PPC64)
+ if (pcc->sps) {
+ env->sps = *pcc->sps;
+ } else if (env->mmu_model & POWERPC_MMU_64) {
+ /* Use default sets of page sizes */
+ static const struct ppc_segment_page_sizes defsps = {
+ .sps = {
+ { .page_shift = 12, /* 4K */
+ .slb_enc = 0,
+ .enc = { { .page_shift = 12, .pte_enc = 0 } }
+ },
+ { .page_shift = 24, /* 16M */
+ .slb_enc = 0x100,
+ .enc = { { .page_shift = 24, .pte_enc = 0 } }
+ },
+ },
+ };
+ env->sps = defsps;
+ }
+#endif /* defined(TARGET_PPC64) */
+
+ if (tcg_enabled()) {
+ ppc_translate_init();
+ }
}
static void ppc_cpu_class_init(ObjectClass *oc, void *data)
{
PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
CPUClass *cc = CPU_CLASS(oc);
+ DeviceClass *dc = DEVICE_CLASS(oc);
+
+ pcc->parent_realize = dc->realize;
+ dc->realize = ppc_cpu_realizefn;
+ dc->unrealize = ppc_cpu_unrealizefn;
pcc->parent_reset = cc->reset;
cc->reset = ppc_cpu_reset;
+
+ cc->class_by_name = ppc_cpu_class_by_name;
+ cc->do_interrupt = ppc_cpu_do_interrupt;
+ cc->dump_state = ppc_cpu_dump_state;
+ cc->dump_statistics = ppc_cpu_dump_statistics;
+ cc->set_pc = ppc_cpu_set_pc;
+ cc->gdb_read_register = ppc_cpu_gdb_read_register;
+ cc->gdb_write_register = ppc_cpu_gdb_write_register;
+#ifndef CONFIG_USER_ONLY
+ cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
+ cc->vmsd = &vmstate_ppc_cpu;
+#endif
+
+ cc->gdb_num_core_regs = 71;
+#if defined(TARGET_PPC64)
+ cc->gdb_core_xml_file = "power64-core.xml";
+#else
+ cc->gdb_core_xml_file = "power-core.xml";
+#endif
}
static const TypeInfo ppc_cpu_type_info = {
@@ -10458,7 +8584,7 @@ static const TypeInfo ppc_cpu_type_info = {
.parent = TYPE_CPU,
.instance_size = sizeof(PowerPCCPU),
.instance_init = ppc_cpu_initfn,
- .abstract = false,
+ .abstract = true,
.class_size = sizeof(PowerPCCPUClass),
.class_init = ppc_cpu_class_init,
};
diff --git a/target-ppc/helper.c b/target-ppc/user_only_helper.c
index 48b19a7e1..56e686efd 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/user_only_helper.c
@@ -1,7 +1,8 @@
/*
- * PowerPC emulation helpers for QEMU.
+ * PowerPC MMU stub handling for user mode emulation
*
* Copyright (c) 2003-2007 Jocelyn Mayer
+ * Copyright (c) 2013 David Gibson, IBM Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -18,33 +19,26 @@
*/
#include "cpu.h"
-#include "helper_regs.h"
-#include "kvm.h"
-#include "kvm_ppc.h"
-#include "cpus.h"
-PowerPCCPU *cpu_ppc_init(const char *cpu_model)
+int cpu_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
+ int mmu_idx)
{
- PowerPCCPU *cpu;
- CPUPPCState *env;
- const ppc_def_t *def;
-
- def = cpu_ppc_find_by_name(cpu_model);
- if (!def) {
- return NULL;
- }
-
- cpu = POWERPC_CPU(object_new(TYPE_POWERPC_CPU));
- env = &cpu->env;
-
- if (tcg_enabled()) {
- ppc_translate_init();
+ int exception, error_code;
+
+ if (rw == 2) {
+ exception = POWERPC_EXCP_ISI;
+ error_code = 0x40000000;
+ } else {
+ exception = POWERPC_EXCP_DSI;
+ error_code = 0x40000000;
+ if (rw) {
+ error_code |= 0x02000000;
+ }
+ env->spr[SPR_DAR] = address;
+ env->spr[SPR_DSISR] = error_code;
}
+ env->exception_index = exception;
+ env->error_code = error_code;
- env->cpu_model_str = cpu_model;
- cpu_ppc_register_internal(env, def);
-
- qemu_init_vcpu(env);
-
- return cpu;
+ return 1;
}