| /* |
| * PowerPC CPU initialization for qemu. |
| * |
| * Copyright (c) 2003-2007 Jocelyn Mayer |
| * Copyright 2011 Freescale Semiconductor, Inc. |
| * |
| * 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.1 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 "qemu/osdep.h" |
| #include "disas/dis-asm.h" |
| #include "exec/gdbstub.h" |
| #include "kvm_ppc.h" |
| #include "sysemu/cpus.h" |
| #include "sysemu/hw_accel.h" |
| #include "sysemu/tcg.h" |
| #include "cpu-models.h" |
| #include "mmu-hash32.h" |
| #include "mmu-hash64.h" |
| #include "qemu/error-report.h" |
| #include "qemu/module.h" |
| #include "qemu/qemu-print.h" |
| #include "qapi/error.h" |
| #include "qapi/qmp/qnull.h" |
| #include "qapi/visitor.h" |
| #include "hw/qdev-properties.h" |
| #include "hw/ppc/ppc.h" |
| #include "mmu-book3s-v3.h" |
| #include "qemu/cutils.h" |
| #include "disas/capstone.h" |
| #include "fpu/softfloat.h" |
| #include "qapi/qapi-commands-machine-target.h" |
| |
| #include "helper_regs.h" |
| #include "internal.h" |
| #include "spr_common.h" |
| #include "power8-pmu.h" |
| |
| /* #define PPC_DEBUG_SPR */ |
| /* #define USE_APPLE_GDB */ |
| |
| static inline void vscr_init(CPUPPCState *env, uint32_t val) |
| { |
| /* Altivec always uses round-to-nearest */ |
| set_float_rounding_mode(float_round_nearest_even, &env->vec_status); |
| ppc_store_vscr(env, val); |
| } |
| |
| static void register_745_sprs(CPUPPCState *env) |
| { |
| /* SGPRs */ |
| spr_register(env, SPR_SPRG4, "SPRG4", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_SPRG5, "SPRG5", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_SPRG6, "SPRG6", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_SPRG7, "SPRG7", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| /* Hardware implementation registers */ |
| spr_register(env, SPR_HID0, "HID0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_HID1, "HID1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_HID2, "HID2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| } |
| |
| static void register_755_sprs(CPUPPCState *env) |
| { |
| /* L2 cache control */ |
| spr_register(env, SPR_L2CR, "L2CR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, spr_access_nop, |
| 0x00000000); |
| |
| spr_register(env, SPR_L2PMCR, "L2PMCR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| } |
| |
| /* SPR common to all 7xx PowerPC implementations */ |
| static void register_7xx_sprs(CPUPPCState *env) |
| { |
| /* Breakpoints */ |
| spr_register_kvm(env, SPR_DABR, "DABR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| KVM_REG_PPC_DABR, 0x00000000); |
| |
| spr_register(env, SPR_IABR, "IABR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| /* Cache management */ |
| spr_register(env, SPR_ICTC, "ICTC", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| /* Performance monitors */ |
| spr_register(env, SPR_7XX_MMCR0, "MMCR0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_MMCR1, "MMCR1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_PMC1, "PMC1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_PMC2, "PMC2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_PMC3, "PMC3", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_PMC4, "PMC4", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_SIAR, "SIAR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, SPR_NOACCESS, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_UMMCR0, "UMMCR0", |
| &spr_read_ureg, SPR_NOACCESS, |
| &spr_read_ureg, SPR_NOACCESS, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_UMMCR1, "UMMCR1", |
| &spr_read_ureg, SPR_NOACCESS, |
| &spr_read_ureg, SPR_NOACCESS, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_UPMC1, "UPMC1", |
| &spr_read_ureg, SPR_NOACCESS, |
| &spr_read_ureg, SPR_NOACCESS, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_UPMC2, "UPMC2", |
| &spr_read_ureg, SPR_NOACCESS, |
| &spr_read_ureg, SPR_NOACCESS, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_UPMC3, "UPMC3", |
| &spr_read_ureg, SPR_NOACCESS, |
| &spr_read_ureg, SPR_NOACCESS, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_UPMC4, "UPMC4", |
| &spr_read_ureg, SPR_NOACCESS, |
| &spr_read_ureg, SPR_NOACCESS, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_USIAR, "USIAR", |
| &spr_read_ureg, SPR_NOACCESS, |
| &spr_read_ureg, SPR_NOACCESS, |
| 0x00000000); |
| /* External access control */ |
| spr_register(env, SPR_EAR, "EAR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| /* Hardware implementation registers */ |
| spr_register(env, SPR_HID0, "HID0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_HID1, "HID1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| } |
| |
| #ifdef TARGET_PPC64 |
| static void register_amr_sprs(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_generic, &spr_write_amr, |
| &spr_read_generic, &spr_write_amr, |
| 0); |
| spr_register_kvm_hv(env, SPR_AMR, "AMR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_amr, |
| &spr_read_generic, &spr_write_generic, |
| KVM_REG_PPC_AMR, 0); |
| spr_register_kvm_hv(env, SPR_UAMOR, "UAMOR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_uamor, |
| &spr_read_generic, &spr_write_generic, |
| KVM_REG_PPC_UAMOR, 0); |
| spr_register_hv(env, SPR_AMOR, "AMOR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0); |
| #endif /* !CONFIG_USER_ONLY */ |
| } |
| |
| static void register_iamr_sprs(CPUPPCState *env) |
| { |
| #ifndef CONFIG_USER_ONLY |
| spr_register_kvm_hv(env, SPR_IAMR, "IAMR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_iamr, |
| &spr_read_generic, &spr_write_generic, |
| KVM_REG_PPC_IAMR, 0); |
| #endif /* !CONFIG_USER_ONLY */ |
| } |
| #endif /* TARGET_PPC64 */ |
| |
| /* SPR specific to PowerPC 604 implementation */ |
| static void register_604_sprs(CPUPPCState *env) |
| { |
| /* Processor identification */ |
| spr_register(env, SPR_PIR, "PIR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_pir, |
| 0x00000000); |
| /* Breakpoints */ |
| spr_register(env, SPR_IABR, "IABR", |
| 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 */ |
| spr_register(env, SPR_7XX_MMCR0, "MMCR0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_PMC1, "PMC1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_PMC2, "PMC2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_SIAR, "SIAR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, SPR_NOACCESS, |
| 0x00000000); |
| |
| spr_register(env, SPR_SDA, "SDA", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, SPR_NOACCESS, |
| 0x00000000); |
| /* External access control */ |
| spr_register(env, SPR_EAR, "EAR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| /* Hardware implementation registers */ |
| spr_register(env, SPR_HID0, "HID0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| } |
| |
| static void register_604e_sprs(CPUPPCState *env) |
| { |
| spr_register(env, SPR_7XX_MMCR1, "MMCR1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_PMC3, "PMC3", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_PMC4, "PMC4", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| /* Hardware implementation registers */ |
| spr_register(env, SPR_HID1, "HID1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| } |
| |
| /* SPR specific to PowerPC 603 implementation */ |
| static void register_603_sprs(CPUPPCState *env) |
| { |
| /* External access control */ |
| spr_register(env, SPR_EAR, "EAR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| /* Breakpoints */ |
| spr_register(env, SPR_IABR, "IABR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_HID0, "HID0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_HID1, "HID1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| } |
| |
| static void register_e300_sprs(CPUPPCState *env) |
| { |
| /* hardware implementation registers */ |
| spr_register(env, SPR_HID2, "HID2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| /* Breakpoints */ |
| spr_register(env, SPR_DABR, "DABR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_DABR2, "DABR2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_IABR2, "IABR2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_IBCR, "IBCR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_DBCR, "DBCR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| } |
| |
| /* SPR specific to PowerPC G2 implementation */ |
| static void register_G2_sprs(CPUPPCState *env) |
| { |
| /* Memory base address */ |
| /* MBAR */ |
| spr_register(env, SPR_MBAR, "MBAR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| /* Exception processing */ |
| spr_register(env, SPR_BOOKE_CSRR0, "CSRR0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_BOOKE_CSRR1, "CSRR1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| /* Breakpoints */ |
| spr_register(env, SPR_DABR, "DABR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_DABR2, "DABR2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_IABR, "IABR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_IABR2, "IABR2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_IBCR, "IBCR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_DBCR, "DBCR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| /* External access control */ |
| spr_register(env, SPR_EAR, "EAR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| /* Hardware implementation register */ |
| spr_register(env, SPR_HID0, "HID0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_HID1, "HID1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_HID2, "HID2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| /* SGPRs */ |
| spr_register(env, SPR_SPRG4, "SPRG4", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_SPRG5, "SPRG5", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_SPRG6, "SPRG6", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_SPRG7, "SPRG7", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| } |
| |
| static void register_74xx_sprs(CPUPPCState *env) |
| { |
| /* Breakpoints */ |
| spr_register_kvm(env, SPR_DABR, "DABR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| KVM_REG_PPC_DABR, 0x00000000); |
| |
| spr_register(env, SPR_IABR, "IABR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| /* Cache management */ |
| spr_register(env, SPR_ICTC, "ICTC", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| /* Performance monitors */ |
| spr_register(env, SPR_7XX_MMCR0, "MMCR0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_MMCR1, "MMCR1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_PMC1, "PMC1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_PMC2, "PMC2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_PMC3, "PMC3", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_PMC4, "PMC4", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_SIAR, "SIAR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, SPR_NOACCESS, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_UMMCR0, "UMMCR0", |
| &spr_read_ureg, SPR_NOACCESS, |
| &spr_read_ureg, SPR_NOACCESS, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_UMMCR1, "UMMCR1", |
| &spr_read_ureg, SPR_NOACCESS, |
| &spr_read_ureg, SPR_NOACCESS, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_UPMC1, "UPMC1", |
| &spr_read_ureg, SPR_NOACCESS, |
| &spr_read_ureg, SPR_NOACCESS, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_UPMC2, "UPMC2", |
| &spr_read_ureg, SPR_NOACCESS, |
| &spr_read_ureg, SPR_NOACCESS, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_UPMC3, "UPMC3", |
| &spr_read_ureg, SPR_NOACCESS, |
| &spr_read_ureg, SPR_NOACCESS, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_UPMC4, "UPMC4", |
| &spr_read_ureg, SPR_NOACCESS, |
| &spr_read_ureg, SPR_NOACCESS, |
| 0x00000000); |
| |
| spr_register(env, SPR_7XX_USIAR, "USIAR", |
| &spr_read_ureg, SPR_NOACCESS, |
| &spr_read_ureg, SPR_NOACCESS, |
| 0x00000000); |
| /* External access control */ |
| spr_register(env, SPR_EAR, "EAR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| /* Processor identification */ |
| spr_register(env, SPR_PIR, "PIR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_pir, |
| 0x00000000); |
| |
| spr_register(env, SPR_74XX_MMCR2, "MMCR2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_74XX_UMMCR2, "UMMCR2", |
| &spr_read_ureg, SPR_NOACCESS, |
| &spr_read_ureg, SPR_NOACCESS, |
| 0x00000000); |
| |
| spr_register(env, SPR_BAMR, "BAMR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MSSCR0, "MSSCR0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| /* Hardware implementation registers */ |
| spr_register(env, SPR_HID0, "HID0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_HID1, "HID1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| /* Altivec */ |
| spr_register(env, SPR_VRSAVE, "VRSAVE", |
| &spr_read_generic, &spr_write_generic, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_L2CR, "L2CR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, spr_access_nop, |
| 0x00000000); |
| } |
| |
| static void register_l3_ctrl(CPUPPCState *env) |
| { |
| /* L3CR */ |
| spr_register(env, SPR_L3CR, "L3CR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| /* L3ITCR0 */ |
| spr_register(env, SPR_L3ITCR0, "L3ITCR0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| /* L3PM */ |
| spr_register(env, SPR_L3PM, "L3PM", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| } |
| |
| /* PowerPC BookE SPR */ |
| static void register_BookE_sprs(CPUPPCState *env, uint64_t ivor_mask) |
| { |
| const char *ivor_names[64] = { |
| "IVOR0", "IVOR1", "IVOR2", "IVOR3", |
| "IVOR4", "IVOR5", "IVOR6", "IVOR7", |
| "IVOR8", "IVOR9", "IVOR10", "IVOR11", |
| "IVOR12", "IVOR13", "IVOR14", "IVOR15", |
| "IVOR16", "IVOR17", "IVOR18", "IVOR19", |
| "IVOR20", "IVOR21", "IVOR22", "IVOR23", |
| "IVOR24", "IVOR25", "IVOR26", "IVOR27", |
| "IVOR28", "IVOR29", "IVOR30", "IVOR31", |
| "IVOR32", "IVOR33", "IVOR34", "IVOR35", |
| "IVOR36", "IVOR37", "IVOR38", "IVOR39", |
| "IVOR40", "IVOR41", "IVOR42", "IVOR43", |
| "IVOR44", "IVOR45", "IVOR46", "IVOR47", |
| "IVOR48", "IVOR49", "IVOR50", "IVOR51", |
| "IVOR52", "IVOR53", "IVOR54", "IVOR55", |
| "IVOR56", "IVOR57", "IVOR58", "IVOR59", |
| "IVOR60", "IVOR61", "IVOR62", "IVOR63", |
| }; |
| #define SPR_BOOKE_IVORxx (-1) |
| int ivor_sprn[64] = { |
| SPR_BOOKE_IVOR0, SPR_BOOKE_IVOR1, SPR_BOOKE_IVOR2, SPR_BOOKE_IVOR3, |
| SPR_BOOKE_IVOR4, SPR_BOOKE_IVOR5, SPR_BOOKE_IVOR6, SPR_BOOKE_IVOR7, |
| SPR_BOOKE_IVOR8, SPR_BOOKE_IVOR9, SPR_BOOKE_IVOR10, SPR_BOOKE_IVOR11, |
| SPR_BOOKE_IVOR12, SPR_BOOKE_IVOR13, SPR_BOOKE_IVOR14, SPR_BOOKE_IVOR15, |
| SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, |
| SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, |
| SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, |
| SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, |
| SPR_BOOKE_IVOR32, SPR_BOOKE_IVOR33, SPR_BOOKE_IVOR34, SPR_BOOKE_IVOR35, |
| SPR_BOOKE_IVOR36, SPR_BOOKE_IVOR37, SPR_BOOKE_IVOR38, SPR_BOOKE_IVOR39, |
| SPR_BOOKE_IVOR40, SPR_BOOKE_IVOR41, SPR_BOOKE_IVOR42, SPR_BOOKE_IVORxx, |
| SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, |
| SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, |
| SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, |
| SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, |
| SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, |
| }; |
| int i; |
| |
| /* Interrupt processing */ |
| spr_register(env, SPR_BOOKE_CSRR0, "CSRR0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_BOOKE_CSRR1, "CSRR1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| /* Debug */ |
| spr_register(env, SPR_BOOKE_IAC1, "IAC1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_BOOKE_IAC2, "IAC2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_BOOKE_DAC1, "DAC1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_BOOKE_DAC2, "DAC2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_BOOKE_DBCR0, "DBCR0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_40x_dbcr0, |
| 0x00000000); |
| |
| spr_register(env, SPR_BOOKE_DBCR1, "DBCR1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_BOOKE_DBCR2, "DBCR2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_BOOKE_DSRR0, "DSRR0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_BOOKE_DSRR1, "DSRR1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_BOOKE_DBSR, "DBSR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_clear, |
| 0x00000000); |
| spr_register(env, SPR_BOOKE_DEAR, "DEAR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_BOOKE_ESR, "ESR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_BOOKE_IVPR, "IVPR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_excp_prefix, |
| 0x00000000); |
| /* Exception vectors */ |
| for (i = 0; i < 64; i++) { |
| if (ivor_mask & (1ULL << i)) { |
| if (ivor_sprn[i] == SPR_BOOKE_IVORxx) { |
| fprintf(stderr, "ERROR: IVOR %d SPR is not defined\n", i); |
| exit(1); |
| } |
| spr_register(env, ivor_sprn[i], ivor_names[i], |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_excp_vector, |
| 0x00000000); |
| } |
| } |
| spr_register(env, SPR_BOOKE_PID, "PID", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_booke_pid, |
| 0x00000000); |
| spr_register(env, SPR_BOOKE_TCR, "TCR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_booke_tcr, |
| 0x00000000); |
| spr_register(env, SPR_BOOKE_TSR, "TSR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_booke_tsr, |
| 0x00000000); |
| /* Timer */ |
| spr_register(env, SPR_DECR, "DECR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_decr, &spr_write_decr, |
| 0x00000000); |
| spr_register(env, SPR_BOOKE_DECAR, "DECAR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| SPR_NOACCESS, &spr_write_generic, |
| 0x00000000); |
| /* SPRGs */ |
| spr_register(env, SPR_USPRG0, "USPRG0", |
| &spr_read_generic, &spr_write_generic, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_SPRG4, "SPRG4", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_SPRG5, "SPRG5", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_SPRG6, "SPRG6", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_SPRG7, "SPRG7", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_BOOKE_SPRG8, "SPRG8", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_BOOKE_SPRG9, "SPRG9", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| } |
| |
| #if !defined(CONFIG_USER_ONLY) |
| static inline uint32_t register_tlbncfg(uint32_t assoc, uint32_t minsize, |
| uint32_t maxsize, uint32_t flags, |
| uint32_t nentries) |
| { |
| return (assoc << TLBnCFG_ASSOC_SHIFT) | |
| (minsize << TLBnCFG_MINSIZE_SHIFT) | |
| (maxsize << TLBnCFG_MAXSIZE_SHIFT) | |
| flags | nentries; |
| } |
| #endif /* !CONFIG_USER_ONLY */ |
| |
| /* BookE 2.06 storage control registers */ |
| static void register_BookE206_sprs(CPUPPCState *env, uint32_t mas_mask, |
| uint32_t *tlbncfg, uint32_t mmucfg) |
| { |
| #if !defined(CONFIG_USER_ONLY) |
| const char *mas_names[8] = { |
| "MAS0", "MAS1", "MAS2", "MAS3", "MAS4", "MAS5", "MAS6", "MAS7", |
| }; |
| int mas_sprn[8] = { |
| SPR_BOOKE_MAS0, SPR_BOOKE_MAS1, SPR_BOOKE_MAS2, SPR_BOOKE_MAS3, |
| SPR_BOOKE_MAS4, SPR_BOOKE_MAS5, SPR_BOOKE_MAS6, SPR_BOOKE_MAS7, |
| }; |
| int i; |
| |
| /* TLB assist registers */ |
| for (i = 0; i < 8; i++) { |
| if (mas_mask & (1 << i)) { |
| spr_register(env, mas_sprn[i], mas_names[i], |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, |
| (i == 2 && (env->insns_flags & PPC_64B)) |
| ? &spr_write_generic : &spr_write_generic32, |
| 0x00000000); |
| } |
| } |
| if (env->nb_pids > 1) { |
| spr_register(env, SPR_BOOKE_PID1, "PID1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_booke_pid, |
| 0x00000000); |
| } |
| if (env->nb_pids > 2) { |
| spr_register(env, SPR_BOOKE_PID2, "PID2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_booke_pid, |
| 0x00000000); |
| } |
| |
| spr_register(env, SPR_BOOKE_EPLC, "EPLC", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_eplc, |
| 0x00000000); |
| spr_register(env, SPR_BOOKE_EPSC, "EPSC", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_epsc, |
| 0x00000000); |
| |
| spr_register(env, SPR_MMUCFG, "MMUCFG", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, SPR_NOACCESS, |
| mmucfg); |
| switch (env->nb_ways) { |
| case 4: |
| spr_register(env, SPR_BOOKE_TLB3CFG, "TLB3CFG", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, SPR_NOACCESS, |
| tlbncfg[3]); |
| /* Fallthru */ |
| case 3: |
| spr_register(env, SPR_BOOKE_TLB2CFG, "TLB2CFG", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, SPR_NOACCESS, |
| tlbncfg[2]); |
| /* Fallthru */ |
| case 2: |
| spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, SPR_NOACCESS, |
| tlbncfg[1]); |
| /* Fallthru */ |
| case 1: |
| spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, SPR_NOACCESS, |
| tlbncfg[0]); |
| /* Fallthru */ |
| case 0: |
| default: |
| break; |
| } |
| #endif |
| } |
| |
| /* SPR specific to PowerPC 440 implementation */ |
| static void register_440_sprs(CPUPPCState *env) |
| { |
| /* Cache control */ |
| spr_register(env, SPR_440_DNV0, "DNV0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_440_DNV1, "DNV1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_440_DNV2, "DNV2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_440_DNV3, "DNV3", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_440_DTV0, "DTV0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_440_DTV1, "DTV1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_440_DTV2, "DTV2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_440_DTV3, "DTV3", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_440_DVLIM, "DVLIM", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_440_INV0, "INV0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_440_INV1, "INV1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_440_INV2, "INV2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_440_INV3, "INV3", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_440_ITV0, "ITV0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_440_ITV1, "ITV1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_440_ITV2, "ITV2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_440_ITV3, "ITV3", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_440_IVLIM, "IVLIM", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| /* Cache debug */ |
| spr_register(env, SPR_BOOKE_DCDBTRH, "DCDBTRH", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, SPR_NOACCESS, |
| 0x00000000); |
| |
| spr_register(env, SPR_BOOKE_DCDBTRL, "DCDBTRL", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, SPR_NOACCESS, |
| 0x00000000); |
| |
| spr_register(env, SPR_BOOKE_ICDBDR, "ICDBDR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, SPR_NOACCESS, |
| 0x00000000); |
| |
| spr_register(env, SPR_BOOKE_ICDBTRH, "ICDBTRH", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, SPR_NOACCESS, |
| 0x00000000); |
| |
| spr_register(env, SPR_BOOKE_ICDBTRL, "ICDBTRL", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, SPR_NOACCESS, |
| 0x00000000); |
| |
| spr_register(env, SPR_440_DBDR, "DBDR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| /* Processor control */ |
| spr_register(env, SPR_4xx_CCR0, "CCR0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_440_RSTCFG, "RSTCFG", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, SPR_NOACCESS, |
| 0x00000000); |
| /* Storage control */ |
| spr_register(env, SPR_440_MMUCR, "MMUCR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| /* Processor identification */ |
| spr_register(env, SPR_BOOKE_PIR, "PIR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_pir, |
| 0x00000000); |
| |
| spr_register(env, SPR_BOOKE_IAC3, "IAC3", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_BOOKE_IAC4, "IAC4", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_BOOKE_DVC1, "DVC1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_BOOKE_DVC2, "DVC2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| } |
| |
| /* SPR shared between PowerPC 40x implementations */ |
| static void register_40x_sprs(CPUPPCState *env) |
| { |
| /* Cache */ |
| /* not emulated, as QEMU do not emulate caches */ |
| spr_register(env, SPR_40x_DCCR, "DCCR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| /* not emulated, as QEMU do not emulate caches */ |
| spr_register(env, SPR_40x_ICCR, "ICCR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| /* not emulated, as QEMU do not emulate caches */ |
| spr_register(env, SPR_BOOKE_ICDBDR, "ICDBDR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, SPR_NOACCESS, |
| 0x00000000); |
| /* Exception */ |
| spr_register(env, SPR_40x_DEAR, "DEAR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_40x_ESR, "ESR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_40x_EVPR, "EVPR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_excp_prefix, |
| 0x00000000); |
| spr_register(env, SPR_40x_SRR2, "SRR2", |
| &spr_read_generic, &spr_write_generic, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_40x_SRR3, "SRR3", |
| &spr_read_generic, &spr_write_generic, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| /* Timers */ |
| spr_register(env, SPR_40x_PIT, "PIT", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_40x_pit, &spr_write_40x_pit, |
| 0x00000000); |
| spr_register(env, SPR_40x_TCR, "TCR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_40x_tcr, |
| 0x00000000); |
| spr_register(env, SPR_40x_TSR, "TSR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_40x_tsr, |
| 0x00000000); |
| } |
| |
| /* SPR specific to PowerPC 405 implementation */ |
| static void register_405_sprs(CPUPPCState *env) |
| { |
| /* MMU */ |
| spr_register(env, SPR_40x_PID, "PID", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_40x_pid, |
| 0x00000000); |
| spr_register(env, SPR_4xx_CCR0, "CCR0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00700000); |
| /* Debug interface */ |
| spr_register(env, SPR_40x_DBCR0, "DBCR0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_40x_dbcr0, |
| 0x00000000); |
| |
| spr_register(env, SPR_405_DBCR1, "DBCR1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_40x_DBSR, "DBSR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_clear, |
| /* Last reset was system reset */ |
| 0x00000300); |
| |
| spr_register(env, SPR_40x_DAC1, "DAC1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_40x_DAC2, "DAC2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_405_DVC1, "DVC1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_405_DVC2, "DVC2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_40x_IAC1, "IAC1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_40x_IAC2, "IAC2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_405_IAC3, "IAC3", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_405_IAC4, "IAC4", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| /* Storage control */ |
| spr_register(env, SPR_405_SLER, "SLER", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_40x_sler, |
| 0x00000000); |
| spr_register(env, SPR_40x_ZPR, "ZPR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_405_SU0R, "SU0R", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| /* SPRG */ |
| spr_register(env, SPR_USPRG0, "USPRG0", |
| &spr_read_ureg, SPR_NOACCESS, |
| &spr_read_ureg, SPR_NOACCESS, |
| 0x00000000); |
| spr_register(env, SPR_SPRG4, "SPRG4", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_SPRG5, "SPRG5", |
| SPR_NOACCESS, SPR_NOACCESS, |
| spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_SPRG6, "SPRG6", |
| SPR_NOACCESS, SPR_NOACCESS, |
| spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_SPRG7, "SPRG7", |
| SPR_NOACCESS, SPR_NOACCESS, |
| spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| /* Bus access control */ |
| /* not emulated, as QEMU never does speculative access */ |
| spr_register(env, SPR_40x_SGR, "SGR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0xFFFFFFFF); |
| /* not emulated, as QEMU do not emulate caches */ |
| spr_register(env, SPR_40x_DCWR, "DCWR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| } |
| |
| |
| static void register_5xx_8xx_sprs(CPUPPCState *env) |
| { |
| /* Exception processing */ |
| 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, |
| &spr_read_decr, &spr_write_decr, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_EIE, "EIE", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_EID, "EID", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_NRI, "NRI", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_CMPA, "CMPA", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_CMPB, "CMPB", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_CMPC, "CMPC", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_CMPD, "CMPD", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_ECR, "ECR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_DER, "DER", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_COUNTA, "COUNTA", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_COUNTB, "COUNTB", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_CMPE, "CMPE", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_CMPF, "CMPF", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_CMPG, "CMPG", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_CMPH, "CMPH", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_LCTRL1, "LCTRL1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_LCTRL2, "LCTRL2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_BAR, "BAR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_DPDR, "DPDR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_IMMR, "IMMR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| } |
| |
| static void register_5xx_sprs(CPUPPCState *env) |
| { |
| spr_register(env, SPR_RCPU_MI_GRA, "MI_GRA", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_RCPU_L2U_GRA, "L2U_GRA", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_RPCU_BBCMCR, "L2U_BBCMCR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_RCPU_L2U_MCR, "L2U_MCR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_RCPU_MI_RBA0, "MI_RBA0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_RCPU_MI_RBA1, "MI_RBA1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_RCPU_MI_RBA2, "MI_RBA2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_RCPU_MI_RBA3, "MI_RBA3", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_RCPU_L2U_RBA0, "L2U_RBA0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_RCPU_L2U_RBA1, "L2U_RBA1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_RCPU_L2U_RBA2, "L2U_RBA2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_RCPU_L2U_RBA3, "L2U_RBA3", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_RCPU_MI_RA0, "MI_RA0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_RCPU_MI_RA1, "MI_RA1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_RCPU_MI_RA2, "MI_RA2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_RCPU_MI_RA3, "MI_RA3", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_RCPU_L2U_RA0, "L2U_RA0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_RCPU_L2U_RA1, "L2U_RA1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_RCPU_L2U_RA2, "L2U_RA2", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_RCPU_L2U_RA3, "L2U_RA3", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_RCPU_FPECR, "FPECR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| } |
| |
| static void register_8xx_sprs(CPUPPCState *env) |
| { |
| |
| spr_register(env, SPR_MPC_IC_CST, "IC_CST", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_IC_ADR, "IC_ADR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_IC_DAT, "IC_DAT", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_DC_CST, "DC_CST", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_DC_ADR, "DC_ADR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_DC_DAT, "DC_DAT", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_MI_CTR, "MI_CTR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_MI_AP, "MI_AP", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_MI_EPN, "MI_EPN", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_MI_TWC, "MI_TWC", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_MI_RPN, "MI_RPN", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_MI_DBCAM, "MI_DBCAM", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_MI_DBRAM0, "MI_DBRAM0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_MI_DBRAM1, "MI_DBRAM1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_MD_CTR, "MD_CTR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_MD_CASID, "MD_CASID", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_MD_AP, "MD_AP", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_MD_EPN, "MD_EPN", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_MD_TWB, "MD_TWB", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_MD_TWC, "MD_TWC", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_MD_RPN, "MD_RPN", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_MD_TW, "MD_TW", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_MD_DBCAM, "MD_DBCAM", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_MD_DBRAM0, "MD_DBRAM0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MPC_MD_DBRAM1, "MD_DBRAM1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| } |
| |
| /* |
| * AMR => SPR 29 (Power 2.04) |
| * CTRL => SPR 136 (Power 2.04) |
| * CTRL => SPR 152 (Power 2.04) |
| * SCOMC => SPR 276 (64 bits ?) |
| * SCOMD => SPR 277 (64 bits ?) |
| * TBU40 => SPR 286 (Power 2.04 hypv) |
| * HSPRG0 => SPR 304 (Power 2.04 hypv) |
| * HSPRG1 => SPR 305 (Power 2.04 hypv) |
| * HDSISR => SPR 306 (Power 2.04 hypv) |
| * HDAR => SPR 307 (Power 2.04 hypv) |
| * PURR => SPR 309 (Power 2.04 hypv) |
| * HDEC => SPR 310 (Power 2.04 hypv) |
| * HIOR => SPR 311 (hypv) |
| * RMOR => SPR 312 (970) |
| * HRMOR => SPR 313 (Power 2.04 hypv) |
| * HSRR0 => SPR 314 (Power 2.04 hypv) |
| * HSRR1 => SPR 315 (Power 2.04 hypv) |
| * LPIDR => SPR 317 (970) |
| * EPR => SPR 702 (Power 2.04 emb) |
| * perf => 768-783 (Power 2.04) |
| * perf => 784-799 (Power 2.04) |
| * PPR => SPR 896 (Power 2.04) |
| * DABRX => 1015 (Power 2.04 hypv) |
| * FPECR => SPR 1022 (?) |
| * ... and more (thermal management, performance counters, ...) |
| */ |
| |
| /*****************************************************************************/ |
| /* Exception vectors models */ |
| static void init_excp_4xx_softmmu(CPUPPCState *env) |
| { |
| #if !defined(CONFIG_USER_ONLY) |
| env->excp_vectors[POWERPC_EXCP_CRITICAL] = 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_SYSCALL] = 0x00000C00; |
| env->excp_vectors[POWERPC_EXCP_PIT] = 0x00001000; |
| env->excp_vectors[POWERPC_EXCP_FIT] = 0x00001010; |
| env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001020; |
| env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001100; |
| env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001200; |
| env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000; |
| env->ivor_mask = 0x0000FFF0UL; |
| env->ivpr_mask = 0xFFFF0000UL; |
| /* Hardware reset vector */ |
| env->hreset_vector = 0xFFFFFFFCUL; |
| #endif |
| } |
| |
| static void init_excp_MPC5xx(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_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_FPA] = 0x00000E00; |
| env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001000; |
| env->excp_vectors[POWERPC_EXCP_DABR] = 0x00001C00; |
| env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001C00; |
| env->excp_vectors[POWERPC_EXCP_MEXTBR] = 0x00001E00; |
| env->excp_vectors[POWERPC_EXCP_NMEXTBR] = 0x00001F00; |
| env->ivor_mask = 0x0000FFF0UL; |
| env->ivpr_mask = 0xFFFF0000UL; |
| /* Hardware reset vector */ |
| env->hreset_vector = 0x00000100UL; |
| #endif |
| } |
| |
| static void init_excp_MPC8xx(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_FPA] = 0x00000E00; |
| env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001000; |
| env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001100; |
| env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001200; |
| env->excp_vectors[POWERPC_EXCP_ITLBE] = 0x00001300; |
| env->excp_vectors[POWERPC_EXCP_DTLBE] = 0x00001400; |
| env->excp_vectors[POWERPC_EXCP_DABR] = 0x00001C00; |
| env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001C00; |
| env->excp_vectors[POWERPC_EXCP_MEXTBR] = 0x00001E00; |
| env->excp_vectors[POWERPC_EXCP_NMEXTBR] = 0x00001F00; |
| env->ivor_mask = 0x0000FFF0UL; |
| env->ivpr_mask = 0xFFFF0000UL; |
| /* Hardware reset vector */ |
| env->hreset_vector = 0x00000100UL; |
| #endif |
| } |
| |
| static void init_excp_G2(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_CRITICAL] = 0x00000A00; |
| env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; |
| env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; |
| env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000; |
| env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100; |
| env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200; |
| env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; |
| env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; |
| /* Hardware reset vector */ |
| env->hreset_vector = 0x00000100UL; |
| #endif |
| } |
| |
| static void init_excp_e200(CPUPPCState *env, target_ulong ivpr_mask) |
| { |
| #if !defined(CONFIG_USER_ONLY) |
| env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000FFC; |
| env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_APU] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_FIT] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_WDT] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00000000; |
| /* |
| * These two are the same IVOR as POWERPC_EXCP_VPU and |
| * POWERPC_EXCP_VPUA. We deal with that when dispatching at |
| * powerpc_excp(). |
| */ |
| env->excp_vectors[POWERPC_EXCP_SPEU] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_EFPDI] = 0x00000000; |
| |
| env->excp_vectors[POWERPC_EXCP_EFPRI] = 0x00000000; |
| env->ivor_mask = 0x0000FFF7UL; |
| env->ivpr_mask = ivpr_mask; |
| /* Hardware reset vector */ |
| env->hreset_vector = 0xFFFFFFFCUL; |
| #endif |
| } |
| |
| static void init_excp_BookE(CPUPPCState *env) |
| { |
| #if !defined(CONFIG_USER_ONLY) |
| env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_APU] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_FIT] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_WDT] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00000000; |
| env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00000000; |
| env->ivor_mask = 0x0000FFF0UL; |
| env->ivpr_mask = 0xFFFF0000UL; |
| /* Hardware reset vector */ |
| env->hreset_vector = 0xFFFFFFFCUL; |
| #endif |
| } |
| |
| static void init_excp_603(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_IFTLB] = 0x00001000; |
| env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100; |
| env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200; |
| env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; |
| env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; |
| /* Hardware reset vector */ |
| env->hreset_vector = 0x00000100UL; |
| #endif |
| } |
| |
| static void init_excp_604(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; |
| /* Hardware reset vector */ |
| env->hreset_vector = 0x00000100UL; |
| #endif |
| } |
| |
| static void init_excp_7x0(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->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700; |
| /* Hardware reset vector */ |
| env->hreset_vector = 0x00000100UL; |
| #endif |
| } |
| |
| static void init_excp_750cl(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; |
| /* Hardware reset vector */ |
| env->hreset_vector = 0x00000100UL; |
| #endif |
| } |
| |
| static void init_excp_750cx(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_THERM] = 0x00001700; |
| /* Hardware reset vector */ |
| env->hreset_vector = 0x00000100UL; |
| #endif |
| } |
| |
| /* XXX: Check if this is correct */ |
| static void init_excp_7x5(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_IFTLB] = 0x00001000; |
| env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100; |
| env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200; |
| env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; |
| env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; |
| env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700; |
| /* Hardware reset vector */ |
| env->hreset_vector = 0x00000100UL; |
| #endif |
| } |
| |
| static void init_excp_7400(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_VPU] = 0x00000F20; |
| env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; |
| env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; |
| env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600; |
| env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700; |
| /* Hardware reset vector */ |
| env->hreset_vector = 0x00000100UL; |
| #endif |
| } |
| |
| static void init_excp_7450(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_VPU] = 0x00000F20; |
| env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; |
| env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; |
| env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600; |
| /* Hardware reset vector */ |
| env->hreset_vector = 0x00000100UL; |
| #endif |
| } |
| |
| #if defined(TARGET_PPC64) |
| static void init_excp_970(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_DSEG] = 0x00000380; |
| env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; |
| env->excp_vectors[POWERPC_EXCP_ISEG] = 0x00000480; |
| 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_HDECR] = 0x00000980; |
| 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_VPU] = 0x00000F20; |
| env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; |
| env->excp_vectors[POWERPC_EXCP_MAINT] = 0x00001600; |
| env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001700; |
| env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001800; |
| /* Hardware reset vector */ |
| env->hreset_vector = 0x0000000000000100ULL; |
| #endif |
| } |
| |
| static void init_excp_POWER7(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_DSEG] = 0x00000380; |
| env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; |
| env->excp_vectors[POWERPC_EXCP_ISEG] = 0x00000480; |
| 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_HDECR] = 0x00000980; |
| env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; |
| env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; |
| env->excp_vectors[POWERPC_EXCP_HDSI] = 0x00000E00; |
| env->excp_vectors[POWERPC_EXCP_HISI] = 0x00000E20; |
| env->excp_vectors[POWERPC_EXCP_HV_EMU] = 0x00000E40; |
| env->excp_vectors[POWERPC_EXCP_HV_MAINT] = 0x00000E60; |
| env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; |
| env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20; |
| env->excp_vectors[POWERPC_EXCP_VSXU] = 0x00000F40; |
| /* Hardware reset vector */ |
| env->hreset_vector = 0x0000000000000100ULL; |
| #endif |
| } |
| |
| static void init_excp_POWER8(CPUPPCState *env) |
| { |
| init_excp_POWER7(env); |
| |
| #if !defined(CONFIG_USER_ONLY) |
| env->excp_vectors[POWERPC_EXCP_SDOOR] = 0x00000A00; |
| env->excp_vectors[POWERPC_EXCP_FU] = 0x00000F60; |
| env->excp_vectors[POWERPC_EXCP_HV_FU] = 0x00000F80; |
| env->excp_vectors[POWERPC_EXCP_SDOOR_HV] = 0x00000E80; |
| |
| /* Userland exceptions without vector value in PowerISA v3.1 */ |
| env->excp_vectors[POWERPC_EXCP_PERFM_EBB] = 0x0; |
| env->excp_vectors[POWERPC_EXCP_EXTERNAL_EBB] = 0x0; |
| #endif |
| } |
| |
| static void init_excp_POWER9(CPUPPCState *env) |
| { |
| init_excp_POWER8(env); |
| |
| #if !defined(CONFIG_USER_ONLY) |
| env->excp_vectors[POWERPC_EXCP_HVIRT] = 0x00000EA0; |
| env->excp_vectors[POWERPC_EXCP_SYSCALL_VECTORED] = 0x00017000; |
| #endif |
| } |
| |
| static void init_excp_POWER10(CPUPPCState *env) |
| { |
| init_excp_POWER9(env); |
| } |
| |
| #endif |
| |
| static int check_pow_hid0(CPUPPCState *env) |
| { |
| if (env->spr[SPR_HID0] & 0x00E00000) { |
| return 1; |
| } |
| |
| return 0; |
| } |
| |
| static int check_pow_hid0_74xx(CPUPPCState *env) |
| { |
| if (env->spr[SPR_HID0] & 0x00600000) { |
| return 1; |
| } |
| |
| return 0; |
| } |
| |
| static void init_proc_405(CPUPPCState *env) |
| { |
| register_40x_sprs(env); |
| register_405_sprs(env); |
| register_usprgh_sprs(env); |
| |
| /* Memory management */ |
| #if !defined(CONFIG_USER_ONLY) |
| env->nb_tlb = 64; |
| env->nb_ways = 1; |
| env->id_tlbs = 0; |
| env->tlb_type = TLB_EMB; |
| #endif |
| init_excp_4xx_softmmu(env); |
| env->dcache_line_size = 32; |
| env->icache_line_size = 32; |
| /* Allocate hardware IRQ controller */ |
| ppc40x_irq_init(env_archcpu(env)); |
| |
| SET_FIT_PERIOD(8, 12, 16, 20); |
| SET_WDT_PERIOD(16, 20, 24, 28); |
| } |
| |
| 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 = (1ull << MSR_WE) | |
| (1ull << MSR_CE) | |
| (1ull << MSR_EE) | |
| (1ull << MSR_PR) | |
| (1ull << MSR_FP) | |
| (1ull << MSR_ME) | |
| (1ull << MSR_DWE) | |
| (1ull << MSR_DE) | |
| (1ull << MSR_IR) | |
| (1ull << MSR_DR); |
| 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) |
| { |
| register_BookE_sprs(env, 0x000000000000FFFFULL); |
| register_440_sprs(env); |
| register_usprgh_sprs(env); |
| |
| spr_register(env, SPR_BOOKE_MCSR, "MCSR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_440_CCR1, "CCR1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| /* Memory management */ |
| #if !defined(CONFIG_USER_ONLY) |
| env->nb_tlb = 64; |
| env->nb_ways = 1; |
| env->id_tlbs = 0; |
| env->tlb_type = TLB_EMB; |
| #endif |
| init_excp_BookE(env); |
| env->dcache_line_size = 32; |
| env->icache_line_size = 32; |
| ppc40x_irq_init(env_archcpu(env)); |
| |
| SET_FIT_PERIOD(12, 16, 20, 24); |
| SET_WDT_PERIOD(20, 24, 28, 32); |
| } |
| |
| 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 = (1ull << MSR_POW) | |
| (1ull << MSR_CE) | |
| (1ull << MSR_EE) | |
| (1ull << MSR_PR) | |
| (1ull << MSR_FP) | |
| (1ull << MSR_ME) | |
| (1ull << MSR_FE0) | |
| (1ull << MSR_DWE) | |
| (1ull << MSR_DE) | |
| (1ull << MSR_FE1) | |
| (1ull << MSR_IR) | |
| (1ull << MSR_DR); |
| 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; |
| } |
| |
| POWERPC_FAMILY(460EX)(ObjectClass *oc, void *data) |
| { |
| DeviceClass *dc = DEVICE_CLASS(oc); |
| PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); |
| |
| dc->desc = "PowerPC 460 EX"; |
| 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_DCRX | 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 = (1ull << MSR_POW) | |
| (1ull << MSR_CE) | |
| (1ull << MSR_EE) | |
| (1ull << MSR_PR) | |
| (1ull << MSR_FP) | |
| (1ull << MSR_ME) | |
| (1ull << MSR_FE0) | |
| (1ull << MSR_DWE) | |
| (1ull << MSR_DE) | |
| (1ull << MSR_FE1) | |
| (1ull << MSR_IR) | |
| (1ull << MSR_DR); |
| 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_440GP(CPUPPCState *env) |
| { |
| register_BookE_sprs(env, 0x000000000000FFFFULL); |
| register_440_sprs(env); |
| register_usprgh_sprs(env); |
| |
| /* Memory management */ |
| #if !defined(CONFIG_USER_ONLY) |
| env->nb_tlb = 64; |
| env->nb_ways = 1; |
| env->id_tlbs = 0; |
| env->tlb_type = TLB_EMB; |
| #endif |
| init_excp_BookE(env); |
| env->dcache_line_size = 32; |
| env->icache_line_size = 32; |
| /* XXX: TODO: allocate internal IRQ controller */ |
| |
| SET_FIT_PERIOD(12, 16, 20, 24); |
| SET_WDT_PERIOD(20, 24, 28, 32); |
| } |
| |
| 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 = (1ull << MSR_POW) | |
| (1ull << MSR_CE) | |
| (1ull << MSR_EE) | |
| (1ull << MSR_PR) | |
| (1ull << MSR_FP) | |
| (1ull << MSR_ME) | |
| (1ull << MSR_FE0) | |
| (1ull << MSR_DWE) | |
| (1ull << MSR_DE) | |
| (1ull << MSR_FE1) | |
| (1ull << MSR_IR) | |
| (1ull << MSR_DR); |
| 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) |
| { |
| register_BookE_sprs(env, 0x000000000000FFFFULL); |
| register_440_sprs(env); |
| register_usprgh_sprs(env); |
| |
| spr_register(env, SPR_BOOKE_MCSR, "MCSR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_440_CCR1, "CCR1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| /* Memory management */ |
| #if !defined(CONFIG_USER_ONLY) |
| env->nb_tlb = 64; |
| env->nb_ways = 1; |
| env->id_tlbs = 0; |
| env->tlb_type = TLB_EMB; |
| #endif |
| init_excp_BookE(env); |
| env->dcache_line_size = 32; |
| env->icache_line_size = 32; |
| ppc40x_irq_init(env_archcpu(env)); |
| |
| SET_FIT_PERIOD(12, 16, 20, 24); |
| SET_WDT_PERIOD(20, 24, 28, 32); |
| } |
| |
| 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 = (1ull << MSR_POW) | |
| (1ull << MSR_CE) | |
| (1ull << MSR_EE) | |
| (1ull << MSR_PR) | |
| (1ull << MSR_FP) | |
| (1ull << MSR_ME) | |
| (1ull << MSR_FE0) | |
| (1ull << MSR_DWE) | |
| (1ull << MSR_DE) | |
| (1ull << MSR_FE1) | |
| (1ull << MSR_IR) | |
| (1ull << MSR_DR); |
| 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; |
| } |
| |
| POWERPC_FAMILY(440x5wDFPU)(ObjectClass *oc, void *data) |
| { |
| DeviceClass *dc = DEVICE_CLASS(oc); |
| PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); |
| |
| dc->desc = "PowerPC 440x5 with double precision FPU"; |
| pcc->init_proc = init_proc_440x5; |
| pcc->check_pow = check_pow_nocheck; |
| pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | |
| PPC_FLOAT | PPC_FLOAT_FSQRT | |
| 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->insns_flags2 = PPC2_FP_CVT_S64; |
| pcc->msr_mask = (1ull << MSR_POW) | |
| (1ull << MSR_CE) | |
| (1ull << MSR_EE) | |
| (1ull << MSR_PR) | |
| (1ull << MSR_FP) | |
| (1ull << MSR_ME) | |
| (1ull << MSR_FE0) | |
| (1ull << MSR_DWE) | |
| (1ull << MSR_DE) | |
| (1ull << MSR_FE1) | |
| (1ull << MSR_IR) | |
| (1ull << MSR_DR); |
| 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_MPC5xx(CPUPPCState *env) |
| { |
| register_5xx_8xx_sprs(env); |
| register_5xx_sprs(env); |
| init_excp_MPC5xx(env); |
| env->dcache_line_size = 32; |
| env->icache_line_size = 32; |
| /* XXX: TODO: allocate internal IRQ controller */ |
| } |
| |
| 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 = (1ull << MSR_ILE) | |
| (1ull << MSR_EE) | |
| (1ull << MSR_PR) | |
| (1ull << MSR_FP) | |
| (1ull << MSR_ME) | |
| (1ull << MSR_FE0) | |
| (1ull << MSR_SE) | |
| (1ull << MSR_DE) | |
| (1ull << MSR_FE1) | |
| (1ull << MSR_EP) | |
| (1ull << MSR_RI) | |
| (1ull << MSR_LE); |
| pcc->mmu_model = POWERPC_MMU_REAL; |
| pcc->excp_model = POWERPC_EXCP_6xx; |
| 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; |
| } |
| |
| static void init_proc_MPC8xx(CPUPPCState *env) |
| { |
| register_5xx_8xx_sprs(env); |
| register_8xx_sprs(env); |
| init_excp_MPC8xx(env); |
| env->dcache_line_size = 32; |
| env->icache_line_size = 32; |
| /* 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 = (1ull << MSR_ILE) | |
| (1ull << MSR_EE) | |
| (1ull << MSR_PR) | |
| (1ull << MSR_FP) | |
| (1ull << MSR_ME) | |
| (1ull << MSR_SE) | |
| (1ull << MSR_DE) | |
| (1ull << MSR_EP) | |
| (1ull << MSR_IR) | |
| (1ull << MSR_DR) | |
| (1ull << MSR_RI) | |
| (1ull << MSR_LE); |
| pcc->mmu_model = POWERPC_MMU_MPC8xx; |
| pcc->excp_model = POWERPC_EXCP_6xx; |
| 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) */ |
| |
| static void init_proc_G2(CPUPPCState *env) |
| { |
| register_non_embedded_sprs(env); |
| register_sdr1_sprs(env); |
| register_G2_sprs(env); |
| |
| /* Memory management */ |
| register_low_BATs(env); |
| register_high_BATs(env); |
| register_6xx_7xx_soft_tlb(env, 64, 2); |
| init_excp_G2(env); |
| env->dcache_line_size = 32; |
| env->icache_line_size = 32; |
| /* Allocate hardware IRQ controller */ |
| ppc6xx_irq_init(env_archcpu(env)); |
| } |
| |
| 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 = (1ull << MSR_POW) | |
| (1ull << MSR_TGPR) | |
| (1ull << MSR_EE) | |
| (1ull << MSR_PR) | |
| (1ull << MSR_FP) | |
| (1ull << MSR_ME) | |
| (1ull << MSR_FE0) | |
| (1ull << MSR_SE) | |
| (1ull << MSR_DE) | |
| (1ull << MSR_FE1) | |
| (1ull << MSR_AL) | |
| (1ull << MSR_EP) | |
| (1ull << MSR_IR) | |
| (1ull << MSR_DR) | |
| (1ull << MSR_RI); |
| pcc->mmu_model = POWERPC_MMU_SOFT_6xx; |
| pcc->excp_model = POWERPC_EXCP_6xx; |
| 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; |
| } |
| |
| 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_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 = (1ull << MSR_POW) | |
| (1ull << MSR_TGPR) | |
| (1ull << MSR_ILE) | |
| (1ull << MSR_EE) | |
| (1ull << MSR_PR) | |
| (1ull << MSR_FP) | |
| (1ull << MSR_ME) | |
| (1ull << MSR_FE0) | |
| (1ull << MSR_SE) | |
| (1ull << MSR_DE) | |
| (1ull << MSR_FE1) | |
| (1ull << MSR_AL) | |
| (1ull << MSR_EP) | |
| (1ull << MSR_IR) | |
| (1ull << MSR_DR) | |
| (1ull << MSR_RI) | |
| (1ull << MSR_LE); |
| pcc->mmu_model = POWERPC_MMU_SOFT_6xx; |
| pcc->excp_model = POWERPC_EXCP_6xx; |
| 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_e200(CPUPPCState *env) |
| { |
| register_BookE_sprs(env, 0x000000070000FFFFULL); |
| |
| spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR", |
| &spr_read_spefscr, &spr_write_spefscr, |
| &spr_read_spefscr, &spr_write_spefscr, |
| 0x00000000); |
| /* Memory management */ |
| register_BookE206_sprs(env, 0x0000005D, NULL, 0); |
| register_usprgh_sprs(env); |
| |
| spr_register(env, SPR_HID0, "HID0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_HID1, "HID1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_Exxx_ALTCTXCR, "ALTCTXCR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_Exxx_BUCSR, "BUCSR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_Exxx_CTXCR, "CTXCR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_Exxx_DBCNT, "DBCNT", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_Exxx_DBCR3, "DBCR3", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0", |
| &spr_read_generic, SPR_NOACCESS, |
| &spr_read_generic, SPR_NOACCESS, |
| 0x00000000); |
| |
| spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_Exxx_L1FINV0, "L1FINV0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_BOOKE_IAC3, "IAC3", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_BOOKE_IAC4, "IAC4", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| |
| spr_register(env, SPR_MMUCSR0, "MMUCSR0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); /* TOFIX */ |
| spr_register(env, SPR_BOOKE_DSRR0, "DSRR0", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| spr_register(env, SPR_BOOKE_DSRR1, "DSRR1", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_generic, |
| 0x00000000); |
| #if !defined(CONFIG_USER_ONLY) |
| env->nb_tlb = 64; |
| env->nb_ways = 1; |
| env->id_tlbs = 0; |
| env->tlb_type = TLB_EMB; |
| #endif |
| init_excp_e200(env, 0xFFFF0000UL); |
| env->dcache_line_size = 32; |
| env->icache_line_size = 32; |
| /* XXX: TODO: allocate internal IRQ controller */ |
| } |
| |
| 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 = (1ull << MSR_UCLE) | |
| (1ull << MSR_SPE) | |
| (1ull << MSR_POW) | |
| (1ull << MSR_CE) | |
| (1ull << MSR_EE) | |
| (1ull << MSR_PR) | |
| (1ull << MSR_FP) | |
| (1ull << MSR_ME) | |
| (1ull << MSR_FE0) | |
| (1ull << MSR_DWE) | |
| (1ull << MSR_DE) | |
| (1ull << MSR_FE1) | |
| (1ull << MSR_IR) | |
| (1ull << MSR_DR); |
| 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; |
| } |
| |
| enum fsl_e500_version { |
| fsl_e500v1, |
| fsl_e500v2, |
| fsl_e500mc, |
| fsl_e5500, |
| fsl_e6500, |
| }; |
| |
| static void init_proc_e500(CPUPPCState *env, int version) |
| { |
| uint32_t tlbncfg[2]; |
| uint64_t ivor_mask; |
| uint64_t ivpr_mask = 0xFFFF0000ULL; |
| uint32_t l1cfg0 = 0x3800 /* 8 ways */ |
| | 0x0020; /* 32 kb */ |
| uint32_t l1cfg1 = 0x3800 /* 8 ways */ |
| | 0x0020; /* 32 kb */ |
| uint32_t mmucfg = 0; |
| #if !defined(CONFIG_USER_ONLY) |
| int i; |
| #endif |
| |
| /* |
| * XXX The e500 doesn't implement IVOR7 and IVOR9, but doesn't |
| * complain when accessing them. |
| * register_BookE_sprs(env, 0x0000000F0000FD7FULL); |
| */ |
| switch (version) { |
| case fsl_e500v1: |
| case fsl_e500v2: |
| default: |
| ivor_mask = 0x0000000F0000FFFFULL; |
| break; |
| case fsl_e500mc: |
| case fsl_e5500: |
| ivor_mask = 0x000003FE0000FFFFULL; |
| break; |
| case fsl_e6500: |
| ivor_mask = 0x000003FF0000FFFFULL; |
| break; |
| } |
| register_BookE_sprs(env, ivor_mask); |
| |
| spr_register(env, SPR_USPRG3, "USPRG3", |
| &spr_read_ureg, SPR_NOACCESS, |
| &spr_read_ureg, SPR_NOACCESS, |
| 0x00000000); |
| |
| /* Processor identification */ |
| spr_register(env, SPR_BOOKE_PIR, "PIR", |
| SPR_NOACCESS, SPR_NOACCESS, |
| &spr_read_generic, &spr_write_pir, |
| 0x00000000); |
| |
| spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR", |
| &spr_read_spefscr, &spr_write_spefscr, |
| &spr_read_spefscr, &spr_write_spefscr, |
| 0x00000000); |
| #if !defined(CONFIG_USER_ONLY) |
| /* Memory management */ |
| env->nb_pids = 3; |
| env->nb_ways = 2; |
| env->id_tlbs = 0; |
| switch (version) { |
| case fsl_e500v1: |
| tlbncfg[0] = register_tlbncfg(2, 1, 1, 0, 256); |
| tlbncfg[1] = register_tlbncfg(16, 1, 9, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16); |
| break; |
| case fsl_e500v2: |
|