diff options
Diffstat (limited to 'target-ppc')
| -rw-r--r-- | target-ppc/cpu.h | 47 | ||||
| -rw-r--r-- | target-ppc/helper.c | 100 | ||||
| -rw-r--r-- | target-ppc/kvm.c | 50 | ||||
| -rw-r--r-- | target-ppc/kvm_ppc.h | 12 | ||||
| -rw-r--r-- | target-ppc/machine.c | 4 | ||||
| -rw-r--r-- | target-ppc/op_helper.c | 12 | ||||
| -rw-r--r-- | target-ppc/translate.c | 138 | ||||
| -rw-r--r-- | target-ppc/translate_init.c | 53 |
8 files changed, 229 insertions, 187 deletions
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index fbcf4881a8..ca6f1cb58c 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -71,7 +71,7 @@ #endif /* defined (TARGET_PPC64) */ -#define CPUState struct CPUPPCState +#define CPUArchState struct CPUPPCState #include "cpu-defs.h" @@ -1173,12 +1173,12 @@ 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); -void booke206_flush_tlb(CPUState *env, int flags, const int check_iprot); -target_phys_addr_t booke206_tlb_to_page_size(CPUState *env, ppcmas_tlb_t *tlb); -int ppcemb_tlb_check(CPUState *env, ppcemb_tlb_t *tlb, +void booke206_flush_tlb(CPUPPCState *env, int flags, const int check_iprot); +target_phys_addr_t booke206_tlb_to_page_size(CPUPPCState *env, ppcmas_tlb_t *tlb); +int ppcemb_tlb_check(CPUPPCState *env, ppcemb_tlb_t *tlb, target_phys_addr_t *raddrp, target_ulong address, uint32_t pid, int ext, int i); -int ppcmas_tlb_check(CPUState *env, ppcmas_tlb_t *tlb, +int ppcmas_tlb_check(CPUPPCState *env, ppcmas_tlb_t *tlb, target_phys_addr_t *raddrp, target_ulong address, uint32_t pid); void ppc_tlb_invalidate_all (CPUPPCState *env); @@ -1226,13 +1226,13 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val); #define MMU_MODE1_SUFFIX _kernel #define MMU_MODE2_SUFFIX _hypv #define MMU_USER_IDX 0 -static inline int cpu_mmu_index (CPUState *env) +static inline int cpu_mmu_index (CPUPPCState *env) { return env->mmu_idx; } #if defined(CONFIG_USER_ONLY) -static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) +static inline void cpu_clone_regs(CPUPPCState *env, target_ulong newsp) { if (newsp) env->gpr[1] = newsp; @@ -1918,8 +1918,10 @@ enum { PPC2_DFP = 0x0000000000000004ULL, /* Embedded.Processor Control */ PPC2_PRCNTL = 0x0000000000000008ULL, + /* Byte-reversed, indexed, double-word load and store */ + PPC2_DBRX = 0x0000000000000010ULL, -#define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_PRCNTL) +#define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_PRCNTL | PPC2_DBRX) }; /*****************************************************************************/ @@ -2051,9 +2053,12 @@ enum { PPC_INTERRUPT_PERFM, /* Performance monitor interrupt */ }; +/* CPU should be reset next, restart from scratch afterwards */ +#define CPU_INTERRUPT_RESET CPU_INTERRUPT_TGT_INT_0 + /*****************************************************************************/ -static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, +static inline void cpu_get_tb_cpu_state(CPUPPCState *env, target_ulong *pc, target_ulong *cs_base, int *flags) { *pc = env->nip; @@ -2061,7 +2066,7 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, *flags = env->hflags; } -static inline void cpu_set_tls(CPUState *env, target_ulong newtls) +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 @@ -2073,7 +2078,7 @@ static inline void cpu_set_tls(CPUState *env, target_ulong newtls) } #if !defined(CONFIG_USER_ONLY) -static inline int booke206_tlbm_id(CPUState *env, ppcmas_tlb_t *tlbm) +static inline int booke206_tlbm_id(CPUPPCState *env, ppcmas_tlb_t *tlbm) { uintptr_t tlbml = (uintptr_t)tlbm; uintptr_t tlbl = (uintptr_t)env->tlb.tlbm; @@ -2081,21 +2086,21 @@ static inline int booke206_tlbm_id(CPUState *env, ppcmas_tlb_t *tlbm) return (tlbml - tlbl) / sizeof(env->tlb.tlbm[0]); } -static inline int booke206_tlb_size(CPUState *env, int tlbn) +static inline int booke206_tlb_size(CPUPPCState *env, int tlbn) { uint32_t tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlbn]; int r = tlbncfg & TLBnCFG_N_ENTRY; return r; } -static inline int booke206_tlb_ways(CPUState *env, int tlbn) +static inline int booke206_tlb_ways(CPUPPCState *env, int tlbn) { uint32_t tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlbn]; int r = tlbncfg >> TLBnCFG_ASSOC_SHIFT; return r; } -static inline int booke206_tlbm_to_tlbn(CPUState *env, ppcmas_tlb_t *tlbm) +static inline int booke206_tlbm_to_tlbn(CPUPPCState *env, ppcmas_tlb_t *tlbm) { int id = booke206_tlbm_id(env, tlbm); int end = 0; @@ -2112,14 +2117,14 @@ static inline int booke206_tlbm_to_tlbn(CPUState *env, ppcmas_tlb_t *tlbm) return 0; } -static inline int booke206_tlbm_to_way(CPUState *env, ppcmas_tlb_t *tlb) +static inline int booke206_tlbm_to_way(CPUPPCState *env, ppcmas_tlb_t *tlb) { int tlbn = booke206_tlbm_to_tlbn(env, tlb); int tlbid = booke206_tlbm_id(env, tlb); return tlbid & (booke206_tlb_ways(env, tlbn) - 1); } -static inline ppcmas_tlb_t *booke206_get_tlbm(CPUState *env, const int tlbn, +static inline ppcmas_tlb_t *booke206_get_tlbm(CPUPPCState *env, const int tlbn, target_ulong ea, int way) { int r; @@ -2146,7 +2151,7 @@ static inline ppcmas_tlb_t *booke206_get_tlbm(CPUState *env, const int tlbn, } /* returns bitmap of supported page sizes for a given TLB */ -static inline uint32_t booke206_tlbnps(CPUState *env, const int tlbn) +static inline uint32_t booke206_tlbnps(CPUPPCState *env, const int tlbn) { bool mav2 = false; uint32_t ret = 0; @@ -2168,20 +2173,20 @@ static inline uint32_t booke206_tlbnps(CPUState *env, const int tlbn) #endif -extern void (*cpu_ppc_hypercall)(CPUState *); +extern void (*cpu_ppc_hypercall)(CPUPPCState *); -static inline bool cpu_has_work(CPUState *env) +static inline bool cpu_has_work(CPUPPCState *env) { return msr_ee && (env->interrupt_request & CPU_INTERRUPT_HARD); } #include "exec-all.h" -static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) +static inline void cpu_pc_from_tb(CPUPPCState *env, TranslationBlock *tb) { env->nip = tb->pc; } -void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env); +void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env); #endif /* !defined (__CPU_PPC_H__) */ diff --git a/target-ppc/helper.c b/target-ppc/helper.c index 928fbcf3cb..39dcc273e5 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -16,15 +16,9 @@ * 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 <stdarg.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <inttypes.h> #include "cpu.h" #include "helper_regs.h" -#include "qemu-common.h" #include "kvm.h" #include "kvm_ppc.h" #include "cpus.h" @@ -73,13 +67,13 @@ /*****************************************************************************/ /* PowerPC Hypercall emulation */ -void (*cpu_ppc_hypercall)(CPUState *); +void (*cpu_ppc_hypercall)(CPUPPCState *); /*****************************************************************************/ /* PowerPC MMU emulation */ #if defined(CONFIG_USER_ONLY) -int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, +int cpu_ppc_handle_mmu_fault (CPUPPCState *env, target_ulong address, int rw, int mmu_idx) { int exception, error_code; @@ -297,7 +291,7 @@ static inline int pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p, } /* Software driven TLB helpers */ -static inline int ppc6xx_tlb_getnum(CPUState *env, target_ulong eaddr, int way, +static inline int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr, int way, int is_code) { int nr; @@ -313,7 +307,7 @@ static inline int ppc6xx_tlb_getnum(CPUState *env, target_ulong eaddr, int way, return nr; } -static inline void ppc6xx_tlb_invalidate_all(CPUState *env) +static inline void ppc6xx_tlb_invalidate_all(CPUPPCState *env) { ppc6xx_tlb_t *tlb; int nr, max; @@ -330,7 +324,7 @@ static inline void ppc6xx_tlb_invalidate_all(CPUState *env) tlb_flush(env, 1); } -static inline void __ppc6xx_tlb_invalidate_virt(CPUState *env, +static inline void __ppc6xx_tlb_invalidate_virt(CPUPPCState *env, target_ulong eaddr, int is_code, int match_epn) { @@ -355,13 +349,13 @@ static inline void __ppc6xx_tlb_invalidate_virt(CPUState *env, #endif } -static inline void ppc6xx_tlb_invalidate_virt(CPUState *env, +static inline void ppc6xx_tlb_invalidate_virt(CPUPPCState *env, target_ulong eaddr, int is_code) { __ppc6xx_tlb_invalidate_virt(env, eaddr, is_code, 0); } -void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code, +void ppc6xx_tlb_store (CPUPPCState *env, target_ulong EPN, int way, int is_code, target_ulong pte0, target_ulong pte1) { ppc6xx_tlb_t *tlb; @@ -380,7 +374,7 @@ void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code, env->last_way = way; } -static inline int ppc6xx_tlb_check(CPUState *env, mmu_ctx_t *ctx, +static inline int ppc6xx_tlb_check(CPUPPCState *env, mmu_ctx_t *ctx, target_ulong eaddr, int rw, int access_type) { ppc6xx_tlb_t *tlb; @@ -442,7 +436,7 @@ static inline int ppc6xx_tlb_check(CPUState *env, mmu_ctx_t *ctx, } /* Perform BAT hit & translation */ -static inline void bat_size_prot(CPUState *env, target_ulong *blp, int *validp, +static inline void bat_size_prot(CPUPPCState *env, target_ulong *blp, int *validp, int *protp, target_ulong *BATu, target_ulong *BATl) { @@ -467,7 +461,7 @@ static inline void bat_size_prot(CPUState *env, target_ulong *blp, int *validp, *protp = prot; } -static inline void bat_601_size_prot(CPUState *env, target_ulong *blp, +static inline void bat_601_size_prot(CPUPPCState *env, target_ulong *blp, int *validp, int *protp, target_ulong *BATu, target_ulong *BATl) { @@ -492,7 +486,7 @@ static inline void bat_601_size_prot(CPUState *env, target_ulong *blp, *protp = prot; } -static inline int get_bat(CPUState *env, mmu_ctx_t *ctx, target_ulong virtual, +static inline int get_bat(CPUPPCState *env, mmu_ctx_t *ctx, target_ulong virtual, int rw, int type) { target_ulong *BATlt, *BATut, *BATu, *BATl; @@ -567,7 +561,7 @@ static inline int get_bat(CPUState *env, mmu_ctx_t *ctx, target_ulong virtual, return ret; } -static inline target_phys_addr_t get_pteg_offset(CPUState *env, +static inline target_phys_addr_t get_pteg_offset(CPUPPCState *env, target_phys_addr_t hash, int pte_size) { @@ -575,7 +569,7 @@ static inline target_phys_addr_t get_pteg_offset(CPUState *env, } /* PTE table lookup */ -static inline int _find_pte(CPUState *env, mmu_ctx_t *ctx, int is_64b, int h, +static inline int _find_pte(CPUPPCState *env, mmu_ctx_t *ctx, int is_64b, int h, int rw, int type, int target_page_bits) { target_phys_addr_t pteg_off; @@ -597,12 +591,6 @@ static inline int _find_pte(CPUState *env, mmu_ctx_t *ctx, int is_64b, int h, pte1 = ldq_phys(env->htab_base + pteg_off + (i * 16) + 8); } - /* 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) - pte1 |= (ctx->eaddr & (( 1 << target_page_bits ) - 1)) - & TARGET_PAGE_MASK; - 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", @@ -678,10 +666,16 @@ static inline int _find_pte(CPUState *env, mmu_ctx_t *ctx, int is_64b, int h, } } + /* 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(CPUState *env, mmu_ctx_t *ctx, int h, int rw, +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) @@ -818,7 +812,7 @@ int ppc_load_slb_vsid (CPUPPCState *env, target_ulong rb, target_ulong *rt) #endif /* defined(TARGET_PPC64) */ /* Perform segment based translation */ -static inline int get_segment(CPUState *env, mmu_ctx_t *ctx, +static inline int get_segment(CPUPPCState *env, mmu_ctx_t *ctx, target_ulong eaddr, int rw, int type) { target_phys_addr_t hash; @@ -1008,7 +1002,7 @@ static inline int get_segment(CPUState *env, mmu_ctx_t *ctx, } /* Generic TLB check function for embedded PowerPC implementations */ -int ppcemb_tlb_check(CPUState *env, ppcemb_tlb_t *tlb, +int ppcemb_tlb_check(CPUPPCState *env, ppcemb_tlb_t *tlb, target_phys_addr_t *raddrp, target_ulong address, uint32_t pid, int ext, int i) @@ -1061,7 +1055,7 @@ int ppcemb_tlb_search (CPUPPCState *env, target_ulong address, uint32_t pid) } /* Helpers specific to PowerPC 40x implementations */ -static inline void ppc4xx_tlb_invalidate_all(CPUState *env) +static inline void ppc4xx_tlb_invalidate_all(CPUPPCState *env) { ppcemb_tlb_t *tlb; int i; @@ -1073,7 +1067,7 @@ static inline void ppc4xx_tlb_invalidate_all(CPUState *env) tlb_flush(env, 1); } -static inline void ppc4xx_tlb_invalidate_virt(CPUState *env, +static inline void ppc4xx_tlb_invalidate_virt(CPUPPCState *env, target_ulong eaddr, uint32_t pid) { #if !defined(FLUSH_ALL_TLBS) @@ -1097,7 +1091,7 @@ static inline void ppc4xx_tlb_invalidate_virt(CPUState *env, #endif } -static int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx, +static int mmu40x_get_physical_address (CPUPPCState *env, mmu_ctx_t *ctx, target_ulong address, int rw, int access_type) { ppcemb_tlb_t *tlb; @@ -1168,7 +1162,7 @@ void store_40x_sler (CPUPPCState *env, uint32_t val) env->spr[SPR_405_SLER] = val; } -static inline int mmubooke_check_tlb (CPUState *env, ppcemb_tlb_t *tlb, +static inline int mmubooke_check_tlb (CPUPPCState *env, ppcemb_tlb_t *tlb, target_phys_addr_t *raddr, int *prot, target_ulong address, int rw, int access_type, int i) @@ -1238,7 +1232,7 @@ found_tlb: return ret; } -static int mmubooke_get_physical_address (CPUState *env, mmu_ctx_t *ctx, +static int mmubooke_get_physical_address (CPUPPCState *env, mmu_ctx_t *ctx, target_ulong address, int rw, int access_type) { @@ -1270,7 +1264,7 @@ static int mmubooke_get_physical_address (CPUState *env, mmu_ctx_t *ctx, return ret; } -void booke206_flush_tlb(CPUState *env, int flags, const int check_iprot) +void booke206_flush_tlb(CPUPPCState *env, int flags, const int check_iprot) { int tlb_size; int i, j; @@ -1291,7 +1285,7 @@ void booke206_flush_tlb(CPUState *env, int flags, const int check_iprot) tlb_flush(env, 1); } -target_phys_addr_t booke206_tlb_to_page_size(CPUState *env, ppcmas_tlb_t *tlb) +target_phys_addr_t booke206_tlb_to_page_size(CPUPPCState *env, ppcmas_tlb_t *tlb) { int tlbm_size; @@ -1301,7 +1295,7 @@ target_phys_addr_t booke206_tlb_to_page_size(CPUState *env, ppcmas_tlb_t *tlb) } /* TLB check function for MAS based SoftTLBs */ -int ppcmas_tlb_check(CPUState *env, ppcmas_tlb_t *tlb, +int ppcmas_tlb_check(CPUPPCState *env, ppcmas_tlb_t *tlb, target_phys_addr_t *raddrp, target_ulong address, uint32_t pid) { @@ -1337,7 +1331,7 @@ int ppcmas_tlb_check(CPUState *env, ppcmas_tlb_t *tlb, return 0; } -static int mmubooke206_check_tlb(CPUState *env, ppcmas_tlb_t *tlb, +static int mmubooke206_check_tlb(CPUPPCState *env, ppcmas_tlb_t *tlb, target_phys_addr_t *raddr, int *prot, target_ulong address, int rw, int access_type) @@ -1423,7 +1417,7 @@ found_tlb: return ret; } -static int mmubooke206_get_physical_address(CPUState *env, mmu_ctx_t *ctx, +static int mmubooke206_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx, target_ulong address, int rw, int access_type) { @@ -1473,7 +1467,7 @@ static const char *book3e_tsize_to_str[32] = { }; static void mmubooke206_dump_one_tlb(FILE *f, fprintf_function cpu_fprintf, - CPUState *env, int tlbn, int offset, + CPUPPCState *env, int tlbn, int offset, int tlbsize) { ppcmas_tlb_t *entry; @@ -1520,7 +1514,7 @@ static void mmubooke206_dump_one_tlb(FILE *f, fprintf_function cpu_fprintf, } static void mmubooke206_dump_mmu(FILE *f, fprintf_function cpu_fprintf, - CPUState *env) + CPUPPCState *env) { int offset = 0; int i; @@ -1544,7 +1538,7 @@ 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, - CPUState *env) + CPUPPCState *env) { int i; uint64_t slbe, slbv; @@ -1564,7 +1558,7 @@ static void mmubooks_dump_mmu(FILE *f, fprintf_function cpu_fprintf, } #endif -void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env) +void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env) { switch (env->mmu_model) { case POWERPC_MMU_BOOKE206: @@ -1581,7 +1575,7 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env) } } -static inline int check_physical(CPUState *env, mmu_ctx_t *ctx, +static inline int check_physical(CPUPPCState *env, mmu_ctx_t *ctx, target_ulong eaddr, int rw) { int in_plb, ret; @@ -1647,7 +1641,7 @@ static inline int check_physical(CPUState *env, mmu_ctx_t *ctx, return ret; } -int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, +int get_physical_address (CPUPPCState *env, mmu_ctx_t *ctx, target_ulong eaddr, int rw, int access_type) { int ret; @@ -1722,7 +1716,7 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, return ret; } -target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr) +target_phys_addr_t cpu_get_phys_page_debug (CPUPPCState *env, target_ulong addr) { mmu_ctx_t ctx; @@ -1732,7 +1726,7 @@ target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr) return ctx.raddr & TARGET_PAGE_MASK; } -static void booke206_update_mas_tlb_miss(CPUState *env, target_ulong address, +static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong address, int rw) { env->spr[SPR_BOOKE_MAS0] = env->spr[SPR_BOOKE_MAS4] & MAS4_TLBSELD_MASK; @@ -1773,7 +1767,7 @@ static void booke206_update_mas_tlb_miss(CPUState *env, target_ulong address, } /* Perform address translation */ -int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, +int cpu_ppc_handle_mmu_fault (CPUPPCState *env, target_ulong address, int rw, int mmu_idx) { mmu_ctx_t ctx; @@ -2440,19 +2434,19 @@ void ppc_store_msr (CPUPPCState *env, target_ulong value) /*****************************************************************************/ /* Exception processing */ #if defined (CONFIG_USER_ONLY) -void do_interrupt (CPUState *env) +void do_interrupt (CPUPPCState *env) { env->exception_index = POWERPC_EXCP_NONE; env->error_code = 0; } -void ppc_hw_interrupt (CPUState *env) +void ppc_hw_interrupt (CPUPPCState *env) { env->exception_index = POWERPC_EXCP_NONE; env->error_code = 0; } #else /* defined (CONFIG_USER_ONLY) */ -static inline void dump_syscall(CPUState *env) +static inline void dump_syscall(CPUPPCState *env) { qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64 " r3=%016" PRIx64 " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64 @@ -2465,7 +2459,7 @@ static inline void dump_syscall(CPUState *env) /* Note that this function should be greatly optimized * when called with a constant excp, from ppc_hw_interrupt */ -static inline void powerpc_excp(CPUState *env, int excp_model, int excp) +static inline void powerpc_excp(CPUPPCState *env, int excp_model, int excp) { target_ulong msr, new_msr, vector; int srr0, srr1, asrr0, asrr1; @@ -3014,7 +3008,7 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp) } } -void do_interrupt (CPUState *env) +void do_interrupt (CPUPPCState *env) { powerpc_excp(env, env->excp_model, env->exception_index); } @@ -3142,7 +3136,7 @@ void cpu_dump_rfi (target_ulong RA, target_ulong msr) TARGET_FMT_lx "\n", RA, msr); } -void cpu_reset(CPUPPCState *env) +void cpu_state_reset(CPUPPCState *env) { target_ulong msr; diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 50cfa02f78..724f4c7815 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -93,7 +93,7 @@ int kvm_arch_init(KVMState *s) return 0; } -static int kvm_arch_sync_sregs(CPUState *cenv) +static int kvm_arch_sync_sregs(CPUPPCState *cenv) { struct kvm_sregs sregs; int ret; @@ -121,7 +121,7 @@ static int kvm_arch_sync_sregs(CPUState *cenv) } /* Set up a shared TLB array with KVM */ -static int kvm_booke206_tlb_init(CPUState *env) +static int kvm_booke206_tlb_init(CPUPPCState *env) { struct kvm_book3e_206_tlb_params params = {}; struct kvm_config_tlb cfg = {}; @@ -166,7 +166,7 @@ static int kvm_booke206_tlb_init(CPUState *env) return 0; } -int kvm_arch_init_vcpu(CPUState *cenv) +int kvm_arch_init_vcpu(CPUPPCState *cenv) { int ret; @@ -189,11 +189,11 @@ int kvm_arch_init_vcpu(CPUState *cenv) return ret; } -void kvm_arch_reset_vcpu(CPUState *env) +void kvm_arch_reset_vcpu(CPUPPCState *env) { } -static void kvm_sw_tlb_put(CPUState *env) +static void kvm_sw_tlb_put(CPUPPCState *env) { struct kvm_dirty_tlb dirty_tlb; unsigned char *bitmap; @@ -218,7 +218,7 @@ static void kvm_sw_tlb_put(CPUState *env) g_free(bitmap); } -int kvm_arch_put_registers(CPUState *env, int level) +int kvm_arch_put_registers(CPUPPCState *env, int level) { struct kvm_regs regs; int ret; @@ -263,7 +263,7 @@ int kvm_arch_put_registers(CPUState *env, int level) return ret; } -int kvm_arch_get_registers(CPUState *env) +int kvm_arch_get_registers(CPUPPCState *env) { struct kvm_regs regs; struct kvm_sregs sregs; @@ -440,7 +440,7 @@ int kvm_arch_get_registers(CPUState *env) return 0; } -int kvmppc_set_interrupt(CPUState *env, int irq, int level) +int kvmppc_set_interrupt(CPUPPCState *env, int irq, int level) { unsigned virq = level ? KVM_INTERRUPT_SET_LEVEL : KVM_INTERRUPT_UNSET; @@ -465,7 +465,7 @@ int kvmppc_set_interrupt(CPUState *env, int irq, int level) #define PPC_INPUT_INT PPC6xx_INPUT_INT #endif -void kvm_arch_pre_run(CPUState *env, struct kvm_run *run) +void kvm_arch_pre_run(CPUPPCState *env, struct kvm_run *run) { int r; unsigned irq; @@ -498,16 +498,16 @@ void kvm_arch_pre_run(CPUState *env, struct kvm_run *run) * anyways, so we will get a chance to deliver the rest. */ } -void kvm_arch_post_run(CPUState *env, struct kvm_run *run) +void kvm_arch_post_run(CPUPPCState *env, struct kvm_run *run) { } -int kvm_arch_process_async_events(CPUState *env) +int kvm_arch_process_async_events(CPUPPCState *env) { return env->halted; } -static int kvmppc_handle_halt(CPUState *env) +static int kvmppc_handle_halt(CPUPPCState *env) { if (!(env->interrupt_request & CPU_INTERRUPT_HARD) && (msr_ee)) { env->halted = 1; @@ -518,7 +518,7 @@ static int kvmppc_handle_halt(CPUState *env) } /* map dcr access to existing qemu dcr emulation */ -static int kvmppc_handle_dcr_read(CPUState *env, uint32_t dcrn, uint32_t *data) +static int kvmppc_handle_dcr_read(CPUPPCState *env, uint32_t dcrn, uint32_t *data) { if (ppc_dcr_read(env->dcr_env, dcrn, data) < 0) fprintf(stderr, "Read to unhandled DCR (0x%x)\n", dcrn); @@ -526,7 +526,7 @@ static int kvmppc_handle_dcr_read(CPUState *env, uint32_t dcrn, uint32_t *data) return 0; } -static int kvmppc_handle_dcr_write(CPUState *env, uint32_t dcrn, uint32_t data) +static int kvmppc_handle_dcr_write(CPUPPCState *env, uint32_t dcrn, uint32_t data) { if (ppc_dcr_write(env->dcr_env, dcrn, data) < 0) fprintf(stderr, "Write to unhandled DCR (0x%x)\n", dcrn); @@ -534,7 +534,7 @@ static int kvmppc_handle_dcr_write(CPUState *env, uint32_t dcrn, uint32_t data) return 0; } -int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run) +int kvm_arch_handle_exit(CPUPPCState *env, struct kvm_run *run) { int ret; @@ -704,7 +704,7 @@ uint32_t kvmppc_get_dfp(void) return kvmppc_read_int_cpu_dt("ibm,dfp"); } -int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len) +int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len) { uint32_t *hc = (uint32_t*)buf; @@ -734,7 +734,7 @@ int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len) return 0; } -void kvmppc_set_papr(CPUState *env) +void kvmppc_set_papr(CPUPPCState *env) { struct kvm_enable_cap cap = {}; struct kvm_one_reg reg = {}; @@ -843,12 +843,18 @@ void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd) int fd; void *table; + /* Must set fd to -1 so we don't try to munmap when called for + * destroying the table, which the upper layers -will- do + */ + *pfd = -1; if (!cap_spapr_tce) { return NULL; } fd = kvm_vm_ioctl(kvm_state, KVM_CREATE_SPAPR_TCE, &args); if (fd < 0) { + fprintf(stderr, "KVM: Failed to create TCE table for liobn 0x%x\n", + liobn); return NULL; } @@ -857,6 +863,8 @@ void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd) table = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (table == MAP_FAILED) { + fprintf(stderr, "KVM: Failed to map TCE table for liobn 0x%x\n", + liobn); close(fd); return NULL; } @@ -876,8 +884,8 @@ int kvmppc_remove_spapr_tce(void *table, int fd, uint32_t window_size) len = (window_size / SPAPR_VIO_TCE_PAGE_SIZE)*sizeof(VIOsPAPR_RTCE); if ((munmap(table, len) < 0) || (close(fd) < 0)) { - fprintf(stderr, "KVM: Unexpected error removing KVM SPAPR TCE " - "table: %s", strerror(errno)); + fprintf(stderr, "KVM: Unexpected error removing TCE table: %s", + strerror(errno)); /* Leak the table */ } @@ -930,12 +938,12 @@ const ppc_def_t *kvmppc_host_cpu_def(void) return spec; } -bool kvm_arch_stop_on_emulation_error(CPUState *env) +bool kvm_arch_stop_on_emulation_error(CPUPPCState *env) { return true; } -int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr) +int kvm_arch_on_sigbus_vcpu(CPUPPCState *env, int code, void *addr) { return 1; } diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h index f9c0198311..8f1267c6cc 100644 --- a/target-ppc/kvm_ppc.h +++ b/target-ppc/kvm_ppc.h @@ -19,9 +19,9 @@ 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_hypercall(CPUState *env, uint8_t *buf, int buf_len); -int kvmppc_set_interrupt(CPUState *env, int irq, int level); -void kvmppc_set_papr(CPUState *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_smt_threads(void); #ifndef CONFIG_USER_ONLY off_t kvmppc_alloc_rma(const char *name, MemoryRegion *sysmem); @@ -52,17 +52,17 @@ static inline uint32_t kvmppc_get_dfp(void) return 0; } -static inline int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len) +static inline int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len) { return -1; } -static inline int kvmppc_set_interrupt(CPUState *env, int irq, int level) +static inline int kvmppc_set_interrupt(CPUPPCState *env, int irq, int level) { return -1; } -static inline void kvmppc_set_papr(CPUState *env) +static inline void kvmppc_set_papr(CPUPPCState *env) { } diff --git a/target-ppc/machine.c b/target-ppc/machine.c index 1c40d4358a..70e25825fb 100644 --- a/target-ppc/machine.c +++ b/target-ppc/machine.c @@ -4,7 +4,7 @@ void cpu_save(QEMUFile *f, void *opaque) { - CPUState *env = (CPUState *)opaque; + CPUPPCState *env = (CPUPPCState *)opaque; unsigned int i, j; for (i = 0; i < 32; i++) @@ -91,7 +91,7 @@ void cpu_save(QEMUFile *f, void *opaque) int cpu_load(QEMUFile *f, void *opaque, int version_id) { - CPUState *env = (CPUState *)opaque; + CPUPPCState *env = (CPUPPCState *)opaque; unsigned int i, j; target_ulong sdr1; diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index 3f4e06789f..40927b65b1 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -3714,11 +3714,11 @@ uint32_t helper_efdcmpeq (uint64_t op1, uint64_t op2) 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(CPUState *env1, target_ulong addr, int is_write, int mmu_idx, +void tlb_fill(CPUPPCState *env1, target_ulong addr, int is_write, int mmu_idx, void *retaddr) { TranslationBlock *tb; - CPUState *saved_env; + CPUPPCState *saved_env; unsigned long pc; int ret; @@ -4200,7 +4200,7 @@ target_ulong helper_440_tlbsx (target_ulong address) /* PowerPC BookE 2.06 TLB management */ -static ppcmas_tlb_t *booke206_cur_tlb(CPUState *env) +static ppcmas_tlb_t *booke206_cur_tlb(CPUPPCState *env) { uint32_t tlbncfg = 0; int esel = (env->spr[SPR_BOOKE_MAS0] & MAS0_ESEL_MASK) >> MAS0_ESEL_SHIFT; @@ -4306,7 +4306,7 @@ void helper_booke206_tlbwe(void) } } -static inline void booke206_tlb_to_mas(CPUState *env, ppcmas_tlb_t *tlb) +static inline void booke206_tlb_to_mas(CPUPPCState *env, ppcmas_tlb_t *tlb) { int tlbn = booke206_tlbm_to_tlbn(env, tlb); int way = booke206_tlbm_to_way(env, tlb); @@ -4387,7 +4387,7 @@ void helper_booke206_tlbsx(target_ulong address) env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT; } -static inline void booke206_invalidate_ea_tlb(CPUState *env, int tlbn, +static inline void booke206_invalidate_ea_tlb(CPUPPCState *env, int tlbn, uint32_t ea) { int i; @@ -4553,7 +4553,7 @@ void helper_msgsnd(target_ulong rb) { int irq = dbell2irq(rb); int pir = rb & DBELL_PIRTAG_MASK; - CPUState *cenv; + CPUPPCState *cenv; if (irq < 0) { return; diff --git a/target-ppc/translate.c b/target-ppc/translate.c index b2780dbe55..c9a503a1db 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -17,16 +17,10 @@ * 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 <stdarg.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <inttypes.h> #include "cpu.h" #include "disas.h" #include "tcg-op.h" -#include "qemu-common.h" #include "host-utils.h" #include "helper.h" @@ -97,7 +91,7 @@ void ppc_translate_init(void) for (i = 0; i < 8; i++) { snprintf(p, cpu_reg_names_size, "crf%d", i); cpu_crf[i] = tcg_global_mem_new_i32(TCG_AREG0, - offsetof(CPUState, crf[i]), p); + offsetof(CPUPPCState, crf[i]), p); p += 5; cpu_reg_names_size -= 5; } @@ -105,30 +99,30 @@ void ppc_translate_init(void) for (i = 0; i < 32; i++) { snprintf(p, cpu_reg_names_size, "r%d", i); cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0, - offsetof(CPUState, gpr[i]), p); + offsetof(CPUPPCState, gpr[i]), p); p += (i < 10) ? 3 : 4; cpu_reg_names_size -= (i < 10) ? 3 : 4; #if !defined(TARGET_PPC64) snprintf(p, cpu_reg_names_size, "r%dH", i); cpu_gprh[i] = tcg_global_mem_new_i32(TCG_AREG0, - offsetof(CPUState, gprh[i]), p); + offsetof(CPUPPCState, gprh[i]), p); p += (i < 10) ? 4 : 5; cpu_reg_names_size -= (i < 10) ? 4 : 5; #endif snprintf(p, cpu_reg_names_size, "fp%d", i); cpu_fpr[i] = tcg_global_mem_new_i64(TCG_AREG0, - offsetof(CPUState, fpr[i]), p); + offsetof(CPUPPCState, fpr[i]), p); p += (i < 10) ? 4 : 5; cpu_reg_names_size -= (i < 10) ? 4 : 5; snprintf(p, cpu_reg_names_size, "avr%dH", i); #ifdef HOST_WORDS_BIGENDIAN cpu_avrh[i] = tcg_global_mem_new_i64(TCG_AREG0, - offsetof(CPUState, avr[i].u64[0]), p); + offsetof(CPUPPCState, avr[i].u64[0]), p); #else cpu_avrh[i] = tcg_global_mem_new_i64(TCG_AREG0, - offsetof(CPUState, avr[i].u64[1]), p); + offsetof(CPUPPCState, avr[i].u64[1]), p); #endif p += (i < 10) ? 6 : 7; cpu_reg_names_size -= (i < 10) ? 6 : 7; @@ -136,44 +130,44 @@ void ppc_translate_init(void) snprintf(p, cpu_reg_names_size, "avr%dL", i); #ifdef HOST_WORDS_BIGENDIAN cpu_avrl[i] = tcg_global_mem_new_i64(TCG_AREG0, - offsetof(CPUState, avr[i].u64[1]), p); + offsetof(CPUPPCState, avr[i].u64[1]), p); #else cpu_avrl[i] = tcg_global_mem_new_i64(TCG_AREG0, - offsetof(CPUState, avr[i].u64[0]), p); + offsetof(CPUPPCState, avr[i].u64[0]), p); #endif p += (i < 10) ? 6 : 7; cpu_reg_names_size -= (i < 10) ? 6 : 7; } cpu_nip = tcg_global_mem_new(TCG_AREG0, - offsetof(CPUState, nip), "nip"); + offsetof(CPUPPCState, nip), "nip"); cpu_msr = tcg_global_mem_new(TCG_AREG0, - offsetof(CPUState, msr), "msr"); + offsetof(CPUPPCState, msr), "msr"); cpu_ctr = tcg_global_mem_new(TCG_AREG0, - offsetof(CPUState, ctr), "ctr"); + offsetof(CPUPPCState, ctr), "ctr"); cpu_lr = tcg_global_mem_new(TCG_AREG0, - offsetof(CPUState, lr), "lr"); + offsetof(CPUPPCState, lr), "lr"); #if defined(TARGET_PPC64) cpu_cfar = tcg_global_mem_new(TCG_AREG0, - offsetof(CPUState, cfar), "cfar"); + offsetof(CPUPPCState, cfar), "cfar"); #endif cpu_xer = tcg_global_mem_new(TCG_AREG0, - offsetof(CPUState, xer), "xer"); + offsetof(CPUPPCState, xer), "xer"); cpu_reserve = tcg_global_mem_new(TCG_AREG0, - offsetof(CPUState, reserve_addr), + offsetof(CPUPPCState, reserve_addr), "reserve_addr"); cpu_fpscr = tcg_global_mem_new_i32(TCG_AREG0, - offsetof(CPUState, fpscr), "fpscr"); + offsetof(CPUPPCState, fpscr), "fpscr"); cpu_access_type = tcg_global_mem_new_i32(TCG_AREG0, - offsetof(CPUState, access_type), "access_type"); + offsetof(CPUPPCState, access_type), "access_type"); /* register helpers */ #define GEN_HELPER 2 @@ -570,12 +564,12 @@ static inline target_ulong MASK(uint32_t start, uint32_t end) /* SPR load/store helpers */ static inline void gen_load_spr(TCGv t, int reg) { - tcg_gen_ld_tl(t, cpu_env, offsetof(CPUState, spr[reg])); + tcg_gen_ld_tl(t, cpu_env, offsetof(CPUPPCState, spr[reg])); } static inline void gen_store_spr(int reg, TCGv t) { - tcg_gen_st_tl(t, cpu_env, offsetof(CPUState, spr[reg])); + tcg_gen_st_tl(t, cpu_env, offsetof(CPUPPCState, spr[reg])); } /* Invalid instruction */ @@ -2656,7 +2650,7 @@ static void glue(gen_, name##ux)(DisasContext *ctx) tcg_temp_free(EA); \ } -#define GEN_LDX(name, ldop, opc2, opc3, type) \ +#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2) \ static void glue(gen_, name##x)(DisasContext *ctx) \ { \ TCGv EA; \ @@ -2666,6 +2660,8 @@ static void glue(gen_, name##x)(DisasContext *ctx) \ gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA); \ tcg_temp_free(EA); \ } +#define GEN_LDX(name, ldop, opc2, opc3, type) \ + GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE) #define GEN_LDS(name, ldop, op, type) \ GEN_LD(name, ldop, op | 0x20, type); \ @@ -2799,8 +2795,8 @@ static void glue(gen_, name##ux)(DisasContext *ctx) tcg_temp_free(EA); \ } -#define GEN_STX(name, stop, opc2, opc3, type) \ -static void glue(gen_, name##x)(DisasContext *ctx) \ +#define GEN_STX_E(name, stop, opc2, opc3, type, type2) \ +static void glue(gen_, name##x)(DisasContext *ctx) \ { \ TCGv EA; \ gen_set_access_type(ctx, ACCESS_INT); \ @@ -2809,6 +2805,8 @@ static void glue(gen_, name##x)(DisasContext *ctx) gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA); \ tcg_temp_free(EA); \ } +#define GEN_STX(name, stop, opc2, opc3, type) \ + GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE) #define GEN_STS(name, stop, op, type) \ GEN_ST(name, stop, op | 0x20, type); \ @@ -2897,6 +2895,18 @@ static inline void gen_qemu_ld32ur(DisasContext *ctx, TCGv arg1, TCGv arg2) } GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER); +#if defined(TARGET_PPC64) +/* ldbrx */ +static inline void gen_qemu_ld64ur(DisasContext *ctx, TCGv arg1, TCGv arg2) +{ + tcg_gen_qemu_ld64(arg1, arg2, ctx->mem_idx); + if (likely(!ctx->le_mode)) { + tcg_gen_bswap64_tl(arg1, arg1); + } +} +GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX); +#endif /* TARGET_PPC64 */ + /* sthbrx */ static inline void gen_qemu_st16r(DisasContext *ctx, TCGv arg1, TCGv arg2) { @@ -2927,6 +2937,22 @@ static inline void gen_qemu_st32r(DisasContext *ctx, TCGv arg1, TCGv arg2) } GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER); +#if defined(TARGET_PPC64) +/* stdbrx */ +static inline void gen_qemu_st64r(DisasContext *ctx, TCGv arg1, TCGv arg2) +{ + if (likely(!ctx->le_mode)) { + TCGv t0 = tcg_temp_new(); + tcg_gen_bswap64_tl(t0, arg1); + tcg_gen_qemu_st64(t0, arg2, ctx->mem_idx); + tcg_temp_free(t0); + } else { + tcg_gen_qemu_st64(arg1, arg2, ctx->mem_idx); + } +} +GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX); +#endif /* TARGET_PPC64 */ + /*** Integer load and store multiple ***/ /* lmw */ @@ -3084,7 +3110,7 @@ static void gen_lwarx(DisasContext *ctx) gen_check_align(ctx, t0, 0x03); gen_qemu_ld32u(ctx, gpr, t0); tcg_gen_mov_tl(cpu_reserve, t0); - tcg_gen_st_tl(gpr, cpu_env, offsetof(CPUState, reserve_val)); + tcg_gen_st_tl(gpr, cpu_env, offsetof(CPUPPCState, reserve_val)); tcg_temp_free(t0); } @@ -3095,9 +3121,9 @@ static void gen_conditional_store (DisasContext *ctx, TCGv EA, TCGv t0 = tcg_temp_new(); uint32_t save_exception = ctx->exception; - tcg_gen_st_tl(EA, cpu_env, offsetof(CPUState, reserve_ea)); + tcg_gen_st_tl(EA, cpu_env, offsetof(CPUPPCState, reserve_ea)); tcg_gen_movi_tl(t0, (size << 5) | reg); - tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, reserve_info)); + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, reserve_info)); tcg_temp_free(t0); gen_update_nip(ctx, ctx->nip-4); ctx->exception = POWERPC_EXCP_BRANCH; @@ -3146,7 +3172,7 @@ static void gen_ldarx(DisasContext *ctx) gen_check_align(ctx, t0, 0x07); gen_qemu_ld64(ctx, gpr, t0); tcg_gen_mov_tl(cpu_reserve, t0); - tcg_gen_st_tl(gpr, cpu_env, offsetof(CPUState, reserve_val)); + tcg_gen_st_tl(gpr, cpu_env, offsetof(CPUPPCState, reserve_val)); tcg_temp_free(t0); } @@ -3187,7 +3213,7 @@ 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(CPUState, halted)); + tcg_gen_st_i32(t0, cpu_env, offsetof(CPUPPCState, halted)); tcg_temp_free_i32(t0); /* Stop translation, as the CPU is supposed to sleep from now */ gen_exception_err(ctx, EXCP_HLT, 1); @@ -6401,7 +6427,7 @@ static void gen_mfvscr(DisasContext *ctx) } tcg_gen_movi_i64(cpu_avrh[rD(ctx->opcode)], 0); t = tcg_temp_new_i32(); - tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, vscr)); + tcg_gen_ld_i32(t, cpu_env, offsetof(CPUPPCState, vscr)); tcg_gen_extu_i32_i64(cpu_avrl[rD(ctx->opcode)], t); tcg_temp_free_i32(t); } @@ -6754,7 +6780,7 @@ static inline void gen_evmra(DisasContext *ctx) /* spe_acc := rA */ tcg_gen_st_i64(cpu_gpr[rA(ctx->opcode)], cpu_env, - offsetof(CPUState, spe_acc)); + offsetof(CPUPPCState, spe_acc)); #else TCGv_i64 tmp = tcg_temp_new_i64(); @@ -6762,7 +6788,7 @@ static inline void gen_evmra(DisasContext *ctx) tcg_gen_concat_i32_i64(tmp, cpu_gpr[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]); /* spe_acc := tmp */ - tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUState, spe_acc)); + tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUPPCState, spe_acc)); tcg_temp_free_i64(tmp); /* rD := rA */ @@ -7405,7 +7431,7 @@ static inline void gen_evmwumia(DisasContext *ctx) /* acc := rD */ gen_load_gpr64(tmp, rD(ctx->opcode)); - tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUState, spe_acc)); + tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUPPCState, spe_acc)); tcg_temp_free_i64(tmp); } @@ -7428,13 +7454,13 @@ static inline void gen_evmwumiaa(DisasContext *ctx) gen_load_gpr64(tmp, rD(ctx->opcode)); /* Load acc */ - tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUState, spe_acc)); + tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc)); /* acc := tmp + acc */ tcg_gen_add_i64(acc, acc, tmp); /* Store acc */ - tcg_gen_st_i64(acc, cpu_env, offsetof(CPUState, spe_acc)); + tcg_gen_st_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc)); /* rD := acc */ gen_store_gpr64(rD(ctx->opcode), acc); @@ -7482,7 +7508,7 @@ static inline void gen_evmwsmia(DisasContext *ctx) /* acc := rD */ gen_load_gpr64(tmp, rD(ctx->opcode)); - tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUState, spe_acc)); + tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUPPCState, spe_acc)); tcg_temp_free_i64(tmp); } @@ -7501,13 +7527,13 @@ static inline void gen_evmwsmiaa(DisasContext *ctx) gen_load_gpr64(tmp, rD(ctx->opcode)); /* Load acc */ - tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUState, spe_acc)); + tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc)); /* acc := tmp + acc */ tcg_gen_add_i64(acc, acc, tmp); /* Store acc */ - tcg_gen_st_i64(acc, cpu_env, offsetof(CPUState, spe_acc)); + tcg_gen_st_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc)); /* rD := acc */ gen_store_gpr64(rD(ctx->opcode), acc); @@ -8824,7 +8850,7 @@ GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT), #undef GEN_LD #undef GEN_LDU #undef GEN_LDUX -#undef GEN_LDX +#undef GEN_LDX_E #undef GEN_LDS #define GEN_LD(name, ldop, opc, type) \ GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type), @@ -8832,8 +8858,8 @@ GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type), GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type), #define GEN_LDUX(name, ldop, opc2, opc3, type) \ GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type), -#define GEN_LDX(name, ldop, opc2, opc3, type) \ -GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type), +#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2) \ +GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2), #define GEN_LDS(name, ldop, op, type) \ GEN_LD(name, ldop, op | 0x20, type) \ GEN_LDU(name, ldop, op | 0x21, type) \ @@ -8849,6 +8875,7 @@ GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B) GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B) GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B) GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B) +GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX) #endif GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER) GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER) @@ -8856,7 +8883,7 @@ GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER) #undef GEN_ST #undef GEN_STU #undef GEN_STUX -#undef GEN_STX +#undef GEN_STX_E #undef GEN_STS #define GEN_ST(name, stop, opc, type) \ GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type), @@ -8864,8 +8891,8 @@ GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type), GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type), #define GEN_STUX(name, stop, opc2, opc3, type) \ GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type), -#define GEN_STX(name, stop, opc2, opc3, type) \ -GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type), +#define GEN_STX_E(name, stop, opc2, opc3, type, type2) \ +GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2), #define GEN_STS(name, stop, op, type) \ GEN_ST(name, stop, op | 0x20, type) \ GEN_STU(name, stop, op | 0x21, type) \ @@ -8878,6 +8905,7 @@ GEN_STS(stw, st32, 0x04, PPC_INTEGER) #if defined(TARGET_PPC64) GEN_STUX(std, st64, 0x15, 0x05, PPC_64B) GEN_STX(std, st64, 0x15, 0x04, PPC_64B) +GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX) #endif GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER) GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER) @@ -9283,7 +9311,7 @@ GEN_SPEOP_LDST(evstwwo, 0x1E, 2), /*****************************************************************************/ /* Misc PowerPC helpers */ -void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf, +void cpu_dump_state (CPUPPCState *env, FILE *f, fprintf_function cpu_fprintf, int flags) { #define RGPL 4 @@ -9291,6 +9319,8 @@ void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf, int i; + cpu_synchronize_state(env); + 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); @@ -9431,7 +9461,7 @@ void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf, #undef RFPL } -void cpu_dump_statistics (CPUState *env, FILE*f, fprintf_function cpu_fprintf, +void cpu_dump_statistics (CPUPPCState *env, FILE*f, fprintf_function cpu_fprintf, int flags) { #if defined(DO_PPC_STATISTICS) @@ -9479,7 +9509,7 @@ void cpu_dump_statistics (CPUState *env, FILE*f, fprintf_function cpu_fprintf, } /*****************************************************************************/ -static inline void gen_intermediate_code_internal(CPUState *env, +static inline void gen_intermediate_code_internal(CPUPPCState *env, TranslationBlock *tb, int search_pc) { @@ -9664,17 +9694,17 @@ static inline void gen_intermediate_code_internal(CPUState *env, #endif } -void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb) +void gen_intermediate_code (CPUPPCState *env, struct TranslationBlock *tb) { gen_intermediate_code_internal(env, tb, 0); } -void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb) +void gen_intermediate_code_pc (CPUPPCState *env, struct TranslationBlock *tb) { gen_intermediate_code_internal(env, tb, 1); } -void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos) +void restore_state_to_opc(CPUPPCState *env, TranslationBlock *tb, int pc_pos) { env->nip = gen_opc_pc[pc_pos]; } diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 6253076f68..367eefaf9e 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -268,12 +268,12 @@ static void spr_read_purr (void *opaque, int gprn, int sprn) /* IBAT0L...IBAT7L */ static void spr_read_ibat (void *opaque, int gprn, int sprn) { - tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2])); + tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2])); } static void spr_read_ibat_h (void *opaque, int gprn, int sprn) { - tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, IBAT[sprn & 1][(sprn - SPR_IBAT4U) / 2])); + tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, IBAT[sprn & 1][(sprn - SPR_IBAT4U) / 2])); } static void spr_write_ibatu (void *opaque, int sprn, int gprn) @@ -308,12 +308,12 @@ static void spr_write_ibatl_h (void *opaque, int sprn, int gprn) /* DBAT0L...DBAT7L */ static void spr_read_dbat (void *opaque, int gprn, int sprn) { - tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, DBAT[sprn & 1][(sprn - SPR_DBAT0U) / 2])); + tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, DBAT[sprn & 1][(sprn - SPR_DBAT0U) / 2])); } static void spr_read_dbat_h (void *opaque, int gprn, int sprn) { - tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, DBAT[sprn & 1][((sprn - SPR_DBAT4U) / 2) + 4])); + tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, DBAT[sprn & 1][((sprn - SPR_DBAT4U) / 2) + 4])); } static void spr_write_dbatu (void *opaque, int sprn, int gprn) @@ -355,20 +355,20 @@ static void spr_write_sdr1 (void *opaque, int sprn, int gprn) #if defined(TARGET_PPC64) static void spr_read_hior (void *opaque, int gprn, int sprn) { - tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, excp_prefix)); + tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, excp_prefix)); } static void spr_write_hior (void *opaque, int sprn, int gprn) { TCGv t0 = tcg_temp_new(); tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0x3FFFFF00000ULL); - tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, excp_prefix)); + 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(CPUState, asr)); + tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, asr)); } static void spr_write_asr (void *opaque, int sprn, int gprn) @@ -415,7 +415,7 @@ static void spr_write_hid0_601 (void *opaque, int sprn, int gprn) #if !defined(CONFIG_USER_ONLY) static void spr_read_601_ubat (void *opaque, int gprn, int sprn) { - tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2])); + tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2])); } static void spr_write_601_ubatu (void *opaque, int sprn, int gprn) @@ -475,7 +475,7 @@ static void spr_write_booke_tsr (void *opaque, int sprn, int gprn) #if !defined(CONFIG_USER_ONLY) static void spr_read_403_pbr (void *opaque, int gprn, int sprn) { - tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, pb[sprn - SPR_403_PBL1])); + tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, pb[sprn - SPR_403_PBL1])); } static void spr_write_403_pbr (void *opaque, int sprn, int gprn) @@ -498,7 +498,7 @@ static void spr_write_pir (void *opaque, int sprn, int gprn) static void spr_read_spefscr (void *opaque, int gprn, int sprn) { TCGv_i32 t0 = tcg_temp_new_i32(); - tcg_gen_ld_i32(t0, cpu_env, offsetof(CPUState, spe_fscr)); + tcg_gen_ld_i32(t0, cpu_env, offsetof(CPUPPCState, spe_fscr)); tcg_gen_extu_i32_tl(cpu_gpr[gprn], t0); tcg_temp_free_i32(t0); } @@ -507,7 +507,7 @@ static void spr_write_spefscr (void *opaque, int sprn, int gprn) { TCGv_i32 t0 = tcg_temp_new_i32(); tcg_gen_trunc_tl_i32(t0, cpu_gpr[gprn]); - tcg_gen_st_i32(t0, cpu_env, offsetof(CPUState, spe_fscr)); + tcg_gen_st_i32(t0, cpu_env, offsetof(CPUPPCState, spe_fscr)); tcg_temp_free_i32(t0); } @@ -516,9 +516,9 @@ static void spr_write_spefscr (void *opaque, int sprn, int gprn) static void spr_write_excp_prefix (void *opaque, int sprn, int gprn) { TCGv t0 = tcg_temp_new(); - tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, ivpr_mask)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUPPCState, ivpr_mask)); tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]); - tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, excp_prefix)); + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, excp_prefix)); gen_store_spr(sprn, t0); tcg_temp_free(t0); } @@ -542,9 +542,9 @@ static void spr_write_excp_vector (void *opaque, int sprn, int gprn) } TCGv t0 = tcg_temp_new(); - tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, ivor_mask)); + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUPPCState, ivor_mask)); tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]); - tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, excp_vectors[sprn_offs])); + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, excp_vectors[sprn_offs])); gen_store_spr(sprn, t0); tcg_temp_free(t0); } @@ -6571,7 +6571,7 @@ static void init_proc_970MP (CPUPPCState *env) PPC_64B | PPC_ALTIVEC | \ PPC_SEGMENT_64B | PPC_SLBI | \ PPC_POPCNTB | PPC_POPCNTWD) -#define POWERPC_INSNS2_POWER7 (PPC2_VSX | PPC2_DFP) +#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) @@ -6588,6 +6588,11 @@ static void init_proc_POWER7 (CPUPPCState *env) gen_spr_7xx(env); /* Time base */ gen_tbl(env); + /* Processor identification */ + spr_register(env, SPR_PIR, "PIR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_pir, + 0x00000000); #if !defined(CONFIG_USER_ONLY) /* PURR & SPURR: Hack - treat these as aliases for the TB for now */ spr_register(env, SPR_PURR, "PURR", @@ -6713,7 +6718,7 @@ static void init_proc_620 (CPUPPCState *env) #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_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 @@ -6725,7 +6730,7 @@ static void init_proc_620 (CPUPPCState *env) #else #define CPU_POWERPC_DEFAULT CPU_POWERPC_PPC32 #define POWERPC_INSNS_DEFAULT POWERPC_INSNS_PPC32 -#define POWERPC_INSNS2_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 @@ -9768,7 +9773,7 @@ static void dump_ppc_insns (CPUPPCState *env) } #endif -static int gdb_get_float_reg(CPUState *env, uint8_t *mem_buf, int n) +static int gdb_get_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n) { if (n < 32) { stfq_p(mem_buf, env->fpr[n]); @@ -9781,7 +9786,7 @@ static int gdb_get_float_reg(CPUState *env, uint8_t *mem_buf, int n) return 0; } -static int gdb_set_float_reg(CPUState *env, uint8_t *mem_buf, int n) +static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n) { if (n < 32) { env->fpr[n] = ldfq_p(mem_buf); @@ -9794,7 +9799,7 @@ static int gdb_set_float_reg(CPUState *env, uint8_t *mem_buf, int n) return 0; } -static int gdb_get_avr_reg(CPUState *env, uint8_t *mem_buf, int n) +static int gdb_get_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) { if (n < 32) { #ifdef HOST_WORDS_BIGENDIAN @@ -9817,7 +9822,7 @@ static int gdb_get_avr_reg(CPUState *env, uint8_t *mem_buf, int n) return 0; } -static int gdb_set_avr_reg(CPUState *env, uint8_t *mem_buf, int n) +static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) { if (n < 32) { #ifdef HOST_WORDS_BIGENDIAN @@ -9840,7 +9845,7 @@ static int gdb_set_avr_reg(CPUState *env, uint8_t *mem_buf, int n) return 0; } -static int gdb_get_spe_reg(CPUState *env, uint8_t *mem_buf, int n) +static int gdb_get_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n) { if (n < 32) { #if defined(TARGET_PPC64) @@ -9861,7 +9866,7 @@ static int gdb_get_spe_reg(CPUState *env, uint8_t *mem_buf, int n) return 0; } -static int gdb_set_spe_reg(CPUState *env, uint8_t *mem_buf, int n) +static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n) { if (n < 32) { #if defined(TARGET_PPC64) |