diff options
Diffstat (limited to 'target')
-rw-r--r-- | target/arm/cpu.c | 43 | ||||
-rw-r--r-- | target/arm/cpu.h | 10 | ||||
-rw-r--r-- | target/arm/helper.c | 19 | ||||
-rw-r--r-- | target/arm/internals.h | 21 | ||||
-rw-r--r-- | target/arm/kvm64.c | 4 | ||||
-rw-r--r-- | target/arm/op_helper.c | 23 | ||||
-rw-r--r-- | target/arm/translate.c | 181 | ||||
-rw-r--r-- | target/arm/translate.h | 5 | ||||
-rw-r--r-- | target/ppc/arch_dump.c | 2 | ||||
-rw-r--r-- | target/ppc/cpu-qom.h | 1 | ||||
-rw-r--r-- | target/ppc/cpu.h | 5 | ||||
-rw-r--r-- | target/ppc/helper.h | 1 | ||||
-rw-r--r-- | target/ppc/kvm.c | 152 | ||||
-rw-r--r-- | target/ppc/kvm_ppc.h | 40 | ||||
-rw-r--r-- | target/ppc/misc_helper.c | 8 | ||||
-rw-r--r-- | target/ppc/translate_init.c | 410 | ||||
-rw-r--r-- | target/s390x/cpu_models.c | 4 | ||||
-rw-r--r-- | target/s390x/kvm.c | 16 | ||||
-rw-r--r-- | target/s390x/misc_helper.c | 5 |
19 files changed, 596 insertions, 354 deletions
diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 04b062cb7e..b357aee778 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -304,33 +304,6 @@ bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request) } #if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) -static void arm_v7m_unassigned_access(CPUState *cpu, hwaddr addr, - bool is_write, bool is_exec, int opaque, - unsigned size) -{ - ARMCPU *arm = ARM_CPU(cpu); - CPUARMState *env = &arm->env; - - /* ARMv7-M interrupt return works by loading a magic value into the PC. - * On real hardware the load causes the return to occur. The qemu - * implementation performs the jump normally, then does the exception - * return by throwing a special exception when when the CPU tries to - * execute code at the magic address. - */ - if (env->v7m.exception != 0 && addr >= 0xfffffff0 && is_exec) { - cpu->exception_index = EXCP_EXCEPTION_EXIT; - cpu_loop_exit(cpu); - } - - /* In real hardware an attempt to access parts of the address space - * with nothing there will usually cause an external abort. - * However our QEMU board models are often missing device models where - * the guest can boot anyway with the default read-as-zero/writes-ignored - * behaviour that you get without a QEMU unassigned_access hook. - * So just return here to retain that default behaviour. - */ -} - static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request) { CPUClass *cc = CPU_GET_CLASS(cs); @@ -338,17 +311,7 @@ static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request) CPUARMState *env = &cpu->env; bool ret = false; - /* ARMv7-M interrupt return works by loading a magic value - * into the PC. On real hardware the load causes the - * return to occur. The qemu implementation performs the - * jump normally, then does the exception return when the - * CPU tries to execute code at the magic address. - * This will cause the magic PC value to be pushed to - * the stack if an interrupt occurred at the wrong time. - * We avoid this by disabling interrupts when - * pc contains a magic address. - * - * ARMv7-M interrupt masking works differently than -A or -R. + /* ARMv7-M interrupt masking works differently than -A or -R. * There is no FIQ/IRQ distinction. Instead of I and F bits * masking FIQ and IRQ interrupts, an exception is taken only * if it is higher priority than the current execution priority @@ -356,8 +319,7 @@ static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request) * currently active exception). */ if (interrupt_request & CPU_INTERRUPT_HARD - && (armv7m_nvic_can_take_pending_exception(env->nvic)) - && (env->regs[15] < 0xfffffff0)) { + && (armv7m_nvic_can_take_pending_exception(env->nvic))) { cs->exception_index = EXCP_IRQ; cc->do_interrupt(cs); ret = true; @@ -1091,7 +1053,6 @@ static void arm_v7m_class_init(ObjectClass *oc, void *data) cc->do_interrupt = arm_v7m_cpu_do_interrupt; #endif - cc->do_unassigned_access = arm_v7m_unassigned_access; cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt; } diff --git a/target/arm/cpu.h b/target/arm/cpu.h index a8aabce7dd..1055bfef3d 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -58,6 +58,7 @@ #define EXCP_SEMIHOST 16 /* semihosting call */ #define EXCP_NOCP 17 /* v7M NOCP UsageFault */ #define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */ +/* NB: add new EXCP_ defines to the array in arm_log_exception() too */ #define ARMV7M_EXCP_RESET 1 #define ARMV7M_EXCP_NMI 2 @@ -2290,6 +2291,9 @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env) #define ARM_TBFLAG_NS_MASK (1 << ARM_TBFLAG_NS_SHIFT) #define ARM_TBFLAG_BE_DATA_SHIFT 20 #define ARM_TBFLAG_BE_DATA_MASK (1 << ARM_TBFLAG_BE_DATA_SHIFT) +/* For M profile only, Handler (ie not Thread) mode */ +#define ARM_TBFLAG_HANDLER_SHIFT 21 +#define ARM_TBFLAG_HANDLER_MASK (1 << ARM_TBFLAG_HANDLER_SHIFT) /* Bit usage when in AArch64 state */ #define ARM_TBFLAG_TBI0_SHIFT 0 /* TBI0 for EL0/1 or TBI for EL2/3 */ @@ -2326,6 +2330,8 @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env) (((F) & ARM_TBFLAG_NS_MASK) >> ARM_TBFLAG_NS_SHIFT) #define ARM_TBFLAG_BE_DATA(F) \ (((F) & ARM_TBFLAG_BE_DATA_MASK) >> ARM_TBFLAG_BE_DATA_SHIFT) +#define ARM_TBFLAG_HANDLER(F) \ + (((F) & ARM_TBFLAG_HANDLER_MASK) >> ARM_TBFLAG_HANDLER_SHIFT) #define ARM_TBFLAG_TBI0(F) \ (((F) & ARM_TBFLAG_TBI0_MASK) >> ARM_TBFLAG_TBI0_SHIFT) #define ARM_TBFLAG_TBI1(F) \ @@ -2516,6 +2522,10 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc, } *flags |= fp_exception_el(env) << ARM_TBFLAG_FPEXC_EL_SHIFT; + if (env->v7m.exception != 0) { + *flags |= ARM_TBFLAG_HANDLER_MASK; + } + *cs_base = 0; } diff --git a/target/arm/helper.c b/target/arm/helper.c index 8cb7a9451c..8a3e4480aa 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -6271,6 +6271,25 @@ static void arm_log_exception(int idx) { if (qemu_loglevel_mask(CPU_LOG_INT)) { const char *exc = NULL; + static const char * const excnames[] = { + [EXCP_UDEF] = "Undefined Instruction", + [EXCP_SWI] = "SVC", + [EXCP_PREFETCH_ABORT] = "Prefetch Abort", + [EXCP_DATA_ABORT] = "Data Abort", + [EXCP_IRQ] = "IRQ", + [EXCP_FIQ] = "FIQ", + [EXCP_BKPT] = "Breakpoint", + [EXCP_EXCEPTION_EXIT] = "QEMU v7M exception exit", + [EXCP_KERNEL_TRAP] = "QEMU intercept of kernel commpage", + [EXCP_HVC] = "Hypervisor Call", + [EXCP_HYP_TRAP] = "Hypervisor Trap", + [EXCP_SMC] = "Secure Monitor Call", + [EXCP_VIRQ] = "Virtual IRQ", + [EXCP_VFIQ] = "Virtual FIQ", + [EXCP_SEMIHOST] = "Semihosting call", + [EXCP_NOCP] = "v7M NOCP UsageFault", + [EXCP_INVSTATE] = "v7M INVSTATE UsageFault", + }; if (idx >= 0 && idx < ARRAY_SIZE(excnames)) { exc = excnames[idx]; diff --git a/target/arm/internals.h b/target/arm/internals.h index f742a419ff..1f6efef7c4 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -51,27 +51,6 @@ static inline bool excp_is_internal(int excp) || excp == EXCP_SEMIHOST; } -/* Exception names for debug logging; note that not all of these - * precisely correspond to architectural exceptions. - */ -static const char * const excnames[] = { - [EXCP_UDEF] = "Undefined Instruction", - [EXCP_SWI] = "SVC", - [EXCP_PREFETCH_ABORT] = "Prefetch Abort", - [EXCP_DATA_ABORT] = "Data Abort", - [EXCP_IRQ] = "IRQ", - [EXCP_FIQ] = "FIQ", - [EXCP_BKPT] = "Breakpoint", - [EXCP_EXCEPTION_EXIT] = "QEMU v7M exception exit", - [EXCP_KERNEL_TRAP] = "QEMU intercept of kernel commpage", - [EXCP_HVC] = "Hypervisor Call", - [EXCP_HYP_TRAP] = "Hypervisor Trap", - [EXCP_SMC] = "Secure Monitor Call", - [EXCP_VIRQ] = "Virtual IRQ", - [EXCP_VFIQ] = "Virtual FIQ", - [EXCP_SEMIHOST] = "Semihosting call", -}; - /* Scale factor for generic timers, ie number of ns per tick. * This gives a 62.5MHz timer. */ diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index 61111091ad..a16abc8d12 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -940,7 +940,7 @@ bool kvm_arm_handle_debug(CPUState *cs, struct kvm_debug_exit_arch *debug_exit) * single step at this point so something has gone wrong. */ error_report("%s: guest single-step while debugging unsupported" - " (%"PRIx64", %"PRIx32")\n", + " (%"PRIx64", %"PRIx32")", __func__, env->pc, debug_exit->hsr); return false; } @@ -965,7 +965,7 @@ bool kvm_arm_handle_debug(CPUState *cs, struct kvm_debug_exit_arch *debug_exit) break; } default: - error_report("%s: unhandled debug exit (%"PRIx32", %"PRIx64")\n", + error_report("%s: unhandled debug exit (%"PRIx32", %"PRIx64")", __func__, debug_exit->hsr, env->pc); } diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c index d64c8670fa..156b825040 100644 --- a/target/arm/op_helper.c +++ b/target/arm/op_helper.c @@ -130,7 +130,7 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type, if (unlikely(ret)) { ARMCPU *cpu = ARM_CPU(cs); CPUARMState *env = &cpu->env; - uint32_t syn, exc; + uint32_t syn, exc, fsc; unsigned int target_el; bool same_el; @@ -145,19 +145,32 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type, env->cp15.hpfar_el2 = extract64(fi.s2addr, 12, 47) << 4; } same_el = arm_current_el(env) == target_el; - /* AArch64 syndrome does not have an LPAE bit */ - syn = fsr & ~(1 << 9); + + if (fsr & (1 << 9)) { + /* LPAE format fault status register : bottom 6 bits are + * status code in the same form as needed for syndrome + */ + fsc = extract32(fsr, 0, 6); + } else { + /* Short format FSR : this fault will never actually be reported + * to an EL that uses a syndrome register. Check that here, + * and use a (currently) reserved FSR code in case the constructed + * syndrome does leak into the guest somehow. + */ + assert(target_el != 2 && !arm_el_is_aa64(env, target_el)); + fsc = 0x3f; + } /* For insn and data aborts we assume there is no instruction syndrome * information; this is always true for exceptions reported to EL1. */ if (access_type == MMU_INST_FETCH) { - syn = syn_insn_abort(same_el, 0, fi.s1ptw, syn); + syn = syn_insn_abort(same_el, 0, fi.s1ptw, fsc); exc = EXCP_PREFETCH_ABORT; } else { syn = merge_syn_data_abort(env->exception.syndrome, target_el, same_el, fi.s1ptw, - access_type == MMU_DATA_STORE, syn); + access_type == MMU_DATA_STORE, fsc); if (access_type == MMU_DATA_STORE && arm_feature(env, ARM_FEATURE_V6)) { fsr |= (1 << 11); diff --git a/target/arm/translate.c b/target/arm/translate.c index e32e38cadd..0b5a0bca06 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -296,6 +296,30 @@ static void gen_step_complete_exception(DisasContext *s) s->is_jmp = DISAS_EXC; } +static void gen_singlestep_exception(DisasContext *s) +{ + /* Generate the right kind of exception for singlestep, which is + * either the architectural singlestep or EXCP_DEBUG for QEMU's + * gdb singlestepping. + */ + if (s->ss_active) { + gen_step_complete_exception(s); + } else { + gen_exception_internal(EXCP_DEBUG); + } +} + +static inline bool is_singlestepping(DisasContext *s) +{ + /* Return true if we are singlestepping either because of + * architectural singlestep or QEMU gdbstub singlestep. This does + * not include the command line '-singlestep' mode which is rather + * misnamed as it only means "one instruction per TB" and doesn't + * affect the code we generate. + */ + return s->singlestep_enabled || s->ss_active; +} + static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b) { TCGv_i32 tmp1 = tcg_temp_new_i32(); @@ -880,6 +904,21 @@ static const uint8_t table_logic_cc[16] = { 1, /* mvn */ }; +static inline void gen_set_condexec(DisasContext *s) +{ + if (s->condexec_mask) { + uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1); + TCGv_i32 tmp = tcg_temp_new_i32(); + tcg_gen_movi_i32(tmp, val); + store_cpu_field(tmp, condexec_bits); + } +} + +static inline void gen_set_pc_im(DisasContext *s, target_ulong val) +{ + tcg_gen_movi_i32(cpu_R[15], val); +} + /* Set PC and Thumb state from an immediate address. */ static inline void gen_bx_im(DisasContext *s, uint32_t addr) { @@ -904,6 +943,51 @@ static inline void gen_bx(DisasContext *s, TCGv_i32 var) store_cpu_field(var, thumb); } +/* Set PC and Thumb state from var. var is marked as dead. + * For M-profile CPUs, include logic to detect exception-return + * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC, + * and BX reg, and no others, and happens only for code in Handler mode. + */ +static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var) +{ + /* Generate the same code here as for a simple bx, but flag via + * s->is_jmp that we need to do the rest of the work later. + */ + gen_bx(s, var); + if (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M)) { + s->is_jmp = DISAS_BX_EXCRET; + } +} + +static inline void gen_bx_excret_final_code(DisasContext *s) +{ + /* Generate the code to finish possible exception return and end the TB */ + TCGLabel *excret_label = gen_new_label(); + + /* Is the new PC value in the magic range indicating exception return? */ + tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], 0xff000000, excret_label); + /* No: end the TB as we would for a DISAS_JMP */ + if (is_singlestepping(s)) { + gen_singlestep_exception(s); + } else { + tcg_gen_exit_tb(0); + } + gen_set_label(excret_label); + /* Yes: this is an exception return. + * At this point in runtime env->regs[15] and env->thumb will hold + * the exception-return magic number, which do_v7m_exception_exit() + * will read. Nothing else will be able to see those values because + * the cpu-exec main loop guarantees that we will always go straight + * from raising the exception to the exception-handling code. + * + * gen_ss_advance(s) does nothing on M profile currently but + * calling it is conceptually the right thing as we have executed + * this instruction (compare SWI, HVC, SMC handling). + */ + gen_ss_advance(s); + gen_exception_internal(EXCP_EXCEPTION_EXIT); +} + /* Variant of store_reg which uses branch&exchange logic when storing to r15 in ARM architecture v7 and above. The source must be a temporary and will be marked as dead. */ @@ -923,7 +1007,7 @@ static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var) static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var) { if (reg == 15 && ENABLE_ARCH_5) { - gen_bx(s, var); + gen_bx_excret(s, var); } else { store_reg(s, reg, var); } @@ -1056,11 +1140,6 @@ DO_GEN_ST(8, MO_UB) DO_GEN_ST(16, MO_UW) DO_GEN_ST(32, MO_UL) -static inline void gen_set_pc_im(DisasContext *s, target_ulong val) -{ - tcg_gen_movi_i32(cpu_R[15], val); -} - static inline void gen_hvc(DisasContext *s, int imm16) { /* The pre HVC helper handles cases when HVC gets trapped @@ -1094,17 +1173,6 @@ static inline void gen_smc(DisasContext *s) s->is_jmp = DISAS_SMC; } -static inline void -gen_set_condexec (DisasContext *s) -{ - if (s->condexec_mask) { - uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1); - TCGv_i32 tmp = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, val); - store_cpu_field(tmp, condexec_bits); - } -} - static void gen_exception_internal_insn(DisasContext *s, int offset, int excp) { gen_set_condexec(s); @@ -4092,7 +4160,7 @@ static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest) static inline void gen_jmp (DisasContext *s, uint32_t dest) { - if (unlikely(s->singlestep_enabled || s->ss_active)) { + if (unlikely(is_singlestepping(s))) { /* An indirect jump so that we still trigger the debug exception. */ if (s->thumb) dest |= 1; @@ -9858,7 +9926,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw tmp = tcg_temp_new_i32(); gen_aa32_ld32u(s, tmp, addr, get_mem_index(s)); if (i == 15) { - gen_bx(s, tmp); + gen_bx_excret(s, tmp); } else if (i == rn) { loaded_var = tmp; loaded_base = 1; @@ -9959,7 +10027,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw gen_arm_shift_reg(tmp, op, tmp2, logic_cc); if (logic_cc) gen_logic_CC(tmp); - store_reg_bx(s, rd, tmp); + store_reg(s, rd, tmp); break; case 1: /* Sign/zero extend. */ op = (insn >> 20) & 7; @@ -10485,7 +10553,12 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw } break; case 4: /* bxj */ - /* Trivial implementation equivalent to bx. */ + /* Trivial implementation equivalent to bx. + * This instruction doesn't exist at all for M-profile. + */ + if (arm_dc_feature(s, ARM_FEATURE_M)) { + goto illegal_op; + } tmp = load_reg(s, rn); gen_bx(s, tmp); break; @@ -10885,7 +10958,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw goto illegal_op; } if (rs == 15) { - gen_bx(s, tmp); + gen_bx_excret(s, tmp); } else { store_reg(s, rs, tmp); } @@ -11075,9 +11148,11 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) tmp2 = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp2, val); store_reg(s, 14, tmp2); + gen_bx(s, tmp); + } else { + /* Only BX works as exception-return, not BLX */ + gen_bx_excret(s, tmp); } - /* already thumb, no need to check */ - gen_bx(s, tmp); break; } break; @@ -11752,6 +11827,7 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb) dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags); dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags); dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags); + dc->v7m_handler_mode = ARM_TBFLAG_HANDLER(tb->flags); dc->cp_regs = cpu->cp_regs; dc->features = env->features; @@ -11851,14 +11927,6 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb) dc->is_jmp = DISAS_EXC; break; } -#else - if (arm_dc_feature(dc, ARM_FEATURE_M)) { - /* Branches to the magic exception-return addresses should - * already have been caught via the arm_v7m_unassigned_access hook, - * and never get here. - */ - assert(dc->pc < 0xfffffff0); - } #endif if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) { @@ -11953,9 +12021,8 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb) ((dc->pc >= next_page_start - 3) && insn_crosses_page(env, dc)); } while (!dc->is_jmp && !tcg_op_buf_full() && - !cs->singlestep_enabled && + !is_singlestepping(dc) && !singlestep && - !dc->ss_active && !end_of_page && num_insns < max_insns); @@ -11971,9 +12038,16 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb) /* At this stage dc->condjmp will only be set when the skipped instruction was a conditional branch or trap, and the PC has already been written. */ - if (unlikely(cs->singlestep_enabled || dc->ss_active)) { + gen_set_condexec(dc); + if (dc->is_jmp == DISAS_BX_EXCRET) { + /* Exception return branches need some special case code at the + * end of the TB, which is complex enough that it has to + * handle the single-step vs not and the condition-failed + * insn codepath itself. + */ + gen_bx_excret_final_code(dc); + } else if (unlikely(is_singlestepping(dc))) { /* Unconditional and "condition passed" instruction codepath. */ - gen_set_condexec(dc); switch (dc->is_jmp) { case DISAS_SWI: gen_ss_advance(dc); @@ -11993,24 +12067,8 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb) gen_set_pc_im(dc, dc->pc); /* fall through */ default: - if (dc->ss_active) { - gen_step_complete_exception(dc); - } else { - /* FIXME: Single stepping a WFI insn will not halt - the CPU. */ - gen_exception_internal(EXCP_DEBUG); - } - } - if (dc->condjmp) { - /* "Condition failed" instruction codepath. */ - gen_set_label(dc->condlabel); - gen_set_condexec(dc); - gen_set_pc_im(dc, dc->pc); - if (dc->ss_active) { - gen_step_complete_exception(dc); - } else { - gen_exception_internal(EXCP_DEBUG); - } + /* FIXME: Single stepping a WFI insn will not halt the CPU. */ + gen_singlestep_exception(dc); } } else { /* While branches must always occur at the end of an IT block, @@ -12021,7 +12079,6 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb) - Hardware watchpoints. Hardware breakpoints have already been handled and skip this code. */ - gen_set_condexec(dc); switch(dc->is_jmp) { case DISAS_NEXT: gen_goto_tb(dc, 1, dc->pc); @@ -12061,11 +12118,17 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb) gen_exception(EXCP_SMC, syn_aa32_smc(), 3); break; } - if (dc->condjmp) { - gen_set_label(dc->condlabel); - gen_set_condexec(dc); + } + + if (dc->condjmp) { + /* "Condition failed" instruction codepath for the branch/trap insn */ + gen_set_label(dc->condlabel); + gen_set_condexec(dc); + if (unlikely(is_singlestepping(dc))) { + gen_set_pc_im(dc, dc->pc); + gen_singlestep_exception(dc); + } else { gen_goto_tb(dc, 1, dc->pc); - dc->condjmp = 0; } } diff --git a/target/arm/translate.h b/target/arm/translate.h index abb0760158..629dab945e 100644 --- a/target/arm/translate.h +++ b/target/arm/translate.h @@ -31,6 +31,7 @@ typedef struct DisasContext { bool vfp_enabled; /* FP enabled via FPSCR.EN */ int vec_len; int vec_stride; + bool v7m_handler_mode; /* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI * so that top level loop can generate correct syndrome information. */ @@ -134,6 +135,10 @@ static void disas_set_insn_syndrome(DisasContext *s, uint32_t syn) #define DISAS_HVC 8 #define DISAS_SMC 9 #define DISAS_YIELD 10 +/* M profile branch which might be an exception return (and so needs + * custom end-of-TB code) + */ +#define DISAS_BX_EXCRET 11 #ifdef TARGET_AARCH64 void a64_translate_init(void); diff --git a/target/ppc/arch_dump.c b/target/ppc/arch_dump.c index 28d9cc7d79..8e9397aa58 100644 --- a/target/ppc/arch_dump.c +++ b/target/ppc/arch_dump.c @@ -50,7 +50,7 @@ struct PPCUserRegStruct { struct PPCElfPrstatus { char pad1[112]; struct PPCUserRegStruct pr_reg; - reg_t pad2[4]; + char pad2[40]; } QEMU_PACKED; diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h index 81500e5748..d0cf6ca2a9 100644 --- a/target/ppc/cpu-qom.h +++ b/target/ppc/cpu-qom.h @@ -197,6 +197,7 @@ typedef struct PowerPCCPUClass { int bfd_mach; uint32_t l1_dcache_size, l1_icache_size; const struct ppc_segment_page_sizes *sps; + struct ppc_radix_page_info *radix_page_info; void (*init_proc)(CPUPPCState *env); int (*check_pow)(CPUPPCState *env); int (*handle_mmu_fault)(PowerPCCPU *cpu, vaddr eaddr, int rwx, int mmu_idx); diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 5ee33b3fd3..e0ff0412d6 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -943,6 +943,10 @@ struct ppc_segment_page_sizes { struct ppc_one_seg_page_size sps[PPC_PAGE_SIZES_MAX_SZ]; }; +struct ppc_radix_page_info { + uint32_t count; + uint32_t entries[PPC_PAGE_SIZES_MAX_SZ]; +}; /*****************************************************************************/ /* The whole PowerPC CPU context */ @@ -1196,6 +1200,7 @@ struct PowerPCCPU { uint32_t max_compat; uint32_t compat_pvr; PPCVirtualHypervisor *vhyp; + Object *intc; /* Fields related to migration compatibility hacks */ bool pre_2_8_migration; diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 6d77661f7c..bb6a94a8b3 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -709,6 +709,7 @@ DEF_HELPER_FLAGS_1(load_601_rtcu, TCG_CALL_NO_RWG, tl, env) DEF_HELPER_FLAGS_1(load_purr, TCG_CALL_NO_RWG, tl, env) #endif DEF_HELPER_2(store_sdr1, void, env, tl) +DEF_HELPER_2(store_pidr, void, env, tl) DEF_HELPER_FLAGS_2(store_tbl, TCG_CALL_NO_RWG, void, env, tl) DEF_HELPER_FLAGS_2(store_tbu, TCG_CALL_NO_RWG, void, env, tl) DEF_HELPER_FLAGS_2(store_atbl, TCG_CALL_NO_RWG, void, env, tl) diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 9f1f132cef..8574c369e6 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -49,6 +49,8 @@ #if defined(TARGET_PPC64) #include "hw/ppc/spapr_cpu_core.h" #endif +#include "elf.h" +#include "sysemu/kvm_int.h" //#define DEBUG_KVM @@ -73,6 +75,7 @@ static int cap_booke_sregs; static int cap_ppc_smt; static int cap_ppc_rma; static int cap_spapr_tce; +static int cap_spapr_tce_64; static int cap_spapr_multitce; static int cap_spapr_vfio; static int cap_hior; @@ -83,6 +86,8 @@ static int cap_papr; static int cap_htab_fd; static int cap_fixup_hcalls; static int cap_htm; /* Hardware transactional memory support */ +static int cap_mmu_radix; +static int cap_mmu_hash_v3; static uint32_t debug_inst_opcode; @@ -125,6 +130,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) cap_ppc_smt = kvm_check_extension(s, KVM_CAP_PPC_SMT); cap_ppc_rma = kvm_check_extension(s, KVM_CAP_PPC_RMA); cap_spapr_tce = kvm_check_extension(s, KVM_CAP_SPAPR_TCE); + cap_spapr_tce_64 = kvm_check_extension(s, KVM_CAP_SPAPR_TCE_64); cap_spapr_multitce = kvm_check_extension(s, KVM_CAP_SPAPR_MULTITCE); cap_spapr_vfio = false; cap_one_reg = kvm_check_extension(s, KVM_CAP_ONE_REG); @@ -136,6 +142,8 @@ int kvm_arch_init(MachineState *ms, KVMState *s) cap_htab_fd = kvm_check_extension(s, KVM_CAP_PPC_HTAB_FD); cap_fixup_hcalls = kvm_check_extension(s, KVM_CAP_PPC_FIXUP_HCALL); cap_htm = kvm_vm_check_extension(s, KVM_CAP_PPC_HTM); + cap_mmu_radix = kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_RADIX); + cap_mmu_hash_v3 = kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_HASH_V3); if (!cap_interrupt_level) { fprintf(stderr, "KVM: Couldn't find level irq capability. Expect the " @@ -330,6 +338,61 @@ static void kvm_get_smmu_info(PowerPCCPU *cpu, struct kvm_ppc_smmu_info *info) kvm_get_fallback_smmu_info(cpu, info); } +struct ppc_radix_page_info *kvm_get_radix_page_info(void) +{ + KVMState *s = KVM_STATE(current_machine->accelerator); + struct ppc_radix_page_info *radix_page_info; + struct kvm_ppc_rmmu_info rmmu_info; + int i; + + if (!kvm_check_extension(s, KVM_CAP_PPC_MMU_RADIX)) { + return NULL; + } + if (kvm_vm_ioctl(s, KVM_PPC_GET_RMMU_INFO, &rmmu_info)) { + return NULL; + } + radix_page_info = g_malloc0(sizeof(*radix_page_info)); + radix_page_info->count = 0; + for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) { + if (rmmu_info.ap_encodings[i]) { + radix_page_info->entries[i] = rmmu_info.ap_encodings[i]; + radix_page_info->count++; + } + } + return radix_page_info; +} + +target_ulong kvmppc_configure_v3_mmu(PowerPCCPU *cpu, + bool radix, bool gtse, + uint64_t proc_tbl) +{ + CPUState *cs = CPU(cpu); + int ret; + uint64_t flags = 0; + struct kvm_ppc_mmuv3_cfg cfg = { + .process_table = proc_tbl, + }; + + if (radix) { + flags |= KVM_PPC_MMUV3_RADIX; + } + if (gtse) { + flags |= KVM_PPC_MMUV3_GTSE; + } + cfg.flags = flags; + ret = kvm_vm_ioctl(cs->kvm_state, KVM_PPC_CONFIGURE_V3_MMU, &cfg); + switch (ret) { + case 0: + return H_SUCCESS; + case -EINVAL: + return H_PARAMETER; + case -ENODEV: + return H_NOT_AVAILABLE; + default: + return H_HARDWARE; + } +} + static bool kvm_valid_page_size(uint32_t flags, long rampgsize, uint32_t shift) { if (!(flags & KVM_PPC_PAGE_SIZES_REAL)) { @@ -509,8 +572,11 @@ int kvm_arch_init_vcpu(CPUState *cs) case POWERPC_MMU_2_07: if (!cap_htm && !kvmppc_is_pr(cs->kvm_state)) { /* KVM-HV has transactional memory on POWER8 also without the - * KVM_CAP_PPC_HTM extension, so enable it here instead. */ - cap_htm = true; + * KVM_CAP_PPC_HTM extension, so enable it here instead as + * long as it's availble to userspace on the host. */ + if (qemu_getauxval(AT_HWCAP2) & PPC_FEATURE2_HAS_HTM) { + cap_htm = true; + } } break; default: @@ -2132,13 +2198,24 @@ bool kvmppc_spapr_use_multitce(void) return cap_spapr_multitce; } -void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd, - bool need_vfio) +int kvmppc_spapr_enable_inkernel_multitce(void) +{ + int ret; + + ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_PPC_ENABLE_HCALL, 0, + H_PUT_TCE_INDIRECT, 1); + if (!ret) { + ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_PPC_ENABLE_HCALL, 0, + H_STUFF_TCE, 1); + } + + return ret; +} + +void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t page_shift, + uint64_t bus_offset, uint32_t nb_table, + int *pfd, bool need_vfio) { - struct kvm_create_spapr_tce args = { - .liobn = liobn, - .window_size = window_size, - }; long len; int fd; void *table; @@ -2151,14 +2228,41 @@ void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd, 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); + if (cap_spapr_tce_64) { + struct kvm_create_spapr_tce_64 args = { + .liobn = liobn, + .page_shift = page_shift, + .offset = bus_offset >> page_shift, + .size = nb_table, + .flags = 0 + }; + fd = kvm_vm_ioctl(kvm_state, KVM_CREATE_SPAPR_TCE_64, &args); + if (fd < 0) { + fprintf(stderr, + "KVM: Failed to create TCE64 table for liobn 0x%x\n", + liobn); + return NULL; + } + } else if (cap_spapr_tce) { + uint64_t window_size = (uint64_t) nb_table << page_shift; + struct kvm_create_spapr_tce args = { + .liobn = liobn, + .window_size = window_size, + }; + if ((window_size != args.window_size) || bus_offset) { + 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; + } + } else { return NULL; } - len = (window_size / SPAPR_TCE_PAGE_SIZE) * sizeof(uint64_t); + len = nb_table * sizeof(uint64_t); /* FIXME: round this up to page size */ table = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); @@ -2245,14 +2349,8 @@ static void alter_insns(uint64_t *word, uint64_t flags, bool on) } } -static void kvmppc_host_cpu_initfn(Object *obj) -{ - assert(kvm_enabled()); -} - static void kvmppc_host_cpu_class_init(ObjectClass *oc, void *data) { - DeviceClass *dc = DEVICE_CLASS(oc); PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); uint32_t vmx = kvmppc_get_vmx(); uint32_t dfp = kvmppc_get_dfp(); @@ -2280,8 +2378,9 @@ static void kvmppc_host_cpu_class_init(ObjectClass *oc, void *data) pcc->l1_icache_size = icache_size; } - /* Reason: kvmppc_host_cpu_initfn() dies when !kvm_enabled() */ - dc->cannot_destroy_with_object_finalize_yet = true; +#if defined(TARGET_PPC64) + pcc->radix_page_info = kvm_get_radix_page_info(); +#endif /* defined(TARGET_PPC64) */ } bool kvmppc_has_cap_epr(void) @@ -2304,6 +2403,16 @@ bool kvmppc_has_cap_htm(void) return cap_htm; } +bool kvmppc_has_cap_mmu_radix(void) +{ + return cap_mmu_radix; +} + +bool kvmppc_has_cap_mmu_hash_v3(void) +{ + return cap_mmu_hash_v3; +} + static PowerPCCPUClass *ppc_cpu_get_family_class(PowerPCCPUClass *pcc) { ObjectClass *oc = OBJECT_CLASS(pcc); @@ -2333,7 +2442,6 @@ static int kvm_ppc_register_host_cpu_type(void) { TypeInfo type_info = { .name = TYPE_HOST_POWERPC_CPU, - .instance_init = kvmppc_host_cpu_initfn, .class_init = kvmppc_host_cpu_class_init, }; PowerPCCPUClass *pvr_pcc; diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h index 8e9f42d0c6..f48243d13f 100644 --- a/target/ppc/kvm_ppc.h +++ b/target/ppc/kvm_ppc.h @@ -33,11 +33,16 @@ int kvmppc_clear_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits); int kvmppc_or_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits); int kvmppc_set_tcr(PowerPCCPU *cpu); int kvmppc_booke_watchdog_enable(PowerPCCPU *cpu); +target_ulong kvmppc_configure_v3_mmu(PowerPCCPU *cpu, + bool radix, bool gtse, + uint64_t proc_tbl); #ifndef CONFIG_USER_ONLY off_t kvmppc_alloc_rma(void **rma); bool kvmppc_spapr_use_multitce(void); -void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd, - bool need_vfio); +int kvmppc_spapr_enable_inkernel_multitce(void); +void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t page_shift, + uint64_t bus_offset, uint32_t nb_table, + int *pfd, bool need_vfio); int kvmppc_remove_spapr_tce(void *table, int pfd, uint32_t window_size); int kvmppc_reset_htab(int shift_hint); uint64_t kvmppc_rma_size(uint64_t current_size, unsigned int hash_shift); @@ -53,6 +58,8 @@ void kvmppc_read_hptes(ppc_hash_pte64_t *hptes, hwaddr ptex, int n); void kvmppc_write_hpte(hwaddr ptex, uint64_t pte0, uint64_t pte1); bool kvmppc_has_cap_fixup_hcalls(void); bool kvmppc_has_cap_htm(void); +bool kvmppc_has_cap_mmu_radix(void); +bool kvmppc_has_cap_mmu_hash_v3(void); int kvmppc_enable_hwrng(void); int kvmppc_put_books_sregs(PowerPCCPU *cpu); PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void); @@ -156,6 +163,13 @@ static inline int kvmppc_booke_watchdog_enable(PowerPCCPU *cpu) return -1; } +static inline target_ulong kvmppc_configure_v3_mmu(PowerPCCPU *cpu, + bool radix, bool gtse, + uint64_t proc_tbl) +{ + return 0; +} + #ifndef CONFIG_USER_ONLY static inline off_t kvmppc_alloc_rma(void **rma) { @@ -167,9 +181,15 @@ static inline bool kvmppc_spapr_use_multitce(void) return false; } -static inline void *kvmppc_create_spapr_tce(uint32_t liobn, - uint32_t window_size, int *fd, - bool need_vfio) +static inline int kvmppc_spapr_enable_inkernel_multitce(void) +{ + return -1; +} + +static inline void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t page_shift, + uint64_t bus_offset, + uint32_t nb_table, + int *pfd, bool need_vfio) { return NULL; } @@ -252,6 +272,16 @@ static inline bool kvmppc_has_cap_htm(void) return false; } +static inline bool kvmppc_has_cap_mmu_radix(void) +{ + return false; +} + +static inline bool kvmppc_has_cap_mmu_hash_v3(void) +{ + return false; +} + static inline int kvmppc_enable_hwrng(void) { return -1; diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c index fa573dd7d2..0e4217821b 100644 --- a/target/ppc/misc_helper.c +++ b/target/ppc/misc_helper.c @@ -88,6 +88,14 @@ void helper_store_sdr1(CPUPPCState *env, target_ulong val) } } +void helper_store_pidr(CPUPPCState *env, target_ulong val) +{ + PowerPCCPU *cpu = ppc_env_get_cpu(env); + + env->spr[SPR_BOOKS_PID] = val; + tlb_flush(CPU(cpu)); +} + void helper_store_hid0_601(CPUPPCState *env, target_ulong val) { target_ulong hid0; diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c index c1a901455c..e82e3e65e1 100644 --- a/target/ppc/translate_init.c +++ b/target/ppc/translate_init.c @@ -66,7 +66,7 @@ static void spr_store_dump_spr(int sprn) #endif } -static void spr_write_generic (DisasContext *ctx, int sprn, int gprn) +static void spr_write_generic(DisasContext *ctx, int sprn, int gprn) { gen_store_spr(sprn, cpu_gpr[gprn]); spr_store_dump_spr(sprn); @@ -86,7 +86,7 @@ static void spr_write_generic32(DisasContext *ctx, int sprn, int gprn) #endif } -static void spr_write_clear (DisasContext *ctx, int sprn, int gprn) +static void spr_write_clear(DisasContext *ctx, int sprn, int gprn) { TCGv t0 = tcg_temp_new(); TCGv t1 = tcg_temp_new(); @@ -106,47 +106,47 @@ static void spr_access_nop(DisasContext *ctx, int sprn, int gprn) /* SPR common to all PowerPC */ /* XER */ -static void spr_read_xer (DisasContext *ctx, int gprn, int sprn) +static void spr_read_xer(DisasContext *ctx, int gprn, int sprn) { gen_read_xer(ctx, cpu_gpr[gprn]); } -static void spr_write_xer (DisasContext *ctx, int sprn, int gprn) +static void spr_write_xer(DisasContext *ctx, int sprn, int gprn) { gen_write_xer(cpu_gpr[gprn]); } /* LR */ -static void spr_read_lr (DisasContext *ctx, int gprn, int sprn) +static void spr_read_lr(DisasContext *ctx, int gprn, int sprn) { tcg_gen_mov_tl(cpu_gpr[gprn], cpu_lr); } -static void spr_write_lr (DisasContext *ctx, int sprn, int gprn) +static void spr_write_lr(DisasContext *ctx, int sprn, int gprn) { tcg_gen_mov_tl(cpu_lr, cpu_gpr[gprn]); } /* CFAR */ #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) -static void spr_read_cfar (DisasContext *ctx, int gprn, int sprn) +static void spr_read_cfar(DisasContext *ctx, int gprn, int sprn) { tcg_gen_mov_tl(cpu_gpr[gprn], cpu_cfar); } -static void spr_write_cfar (DisasContext *ctx, int sprn, int gprn) +static void spr_write_cfar(DisasContext *ctx, int sprn, int gprn) { tcg_gen_mov_tl(cpu_cfar, cpu_gpr[gprn]); } #endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */ /* CTR */ -static void spr_read_ctr (DisasContext *ctx, int gprn, int sprn) +static void spr_read_ctr(DisasContext *ctx, int gprn, int sprn) { tcg_gen_mov_tl(cpu_gpr[gprn], cpu_ctr); } -static void spr_write_ctr (DisasContext *ctx, int sprn, int gprn) +static void spr_write_ctr(DisasContext *ctx, int sprn, int gprn) { tcg_gen_mov_tl(cpu_ctr, cpu_gpr[gprn]); } @@ -157,7 +157,7 @@ static void spr_write_ctr (DisasContext *ctx, int sprn, int gprn) /* UPMCx */ /* USIA */ /* UDECR */ -static void spr_read_ureg (DisasContext *ctx, int gprn, int sprn) +static void spr_read_ureg(DisasContext *ctx, int gprn, int sprn) { gen_load_spr(cpu_gpr[gprn], sprn + 0x10); } @@ -172,7 +172,7 @@ static void spr_write_ureg(DisasContext *ctx, int sprn, int gprn) /* SPR common to all non-embedded PowerPC */ /* DECR */ #if !defined(CONFIG_USER_ONLY) -static void spr_read_decr (DisasContext *ctx, int gprn, int sprn) +static void spr_read_decr(DisasContext *ctx, int gprn, int sprn) { if (ctx->tb->cflags & CF_USE_ICOUNT) { gen_io_start(); @@ -184,7 +184,7 @@ static void spr_read_decr (DisasContext *ctx, int gprn, int sprn) } } -static void spr_write_decr (DisasContext *ctx, int sprn, int gprn) +static void spr_write_decr(DisasContext *ctx, int sprn, int gprn) { if (ctx->tb->cflags & CF_USE_ICOUNT) { gen_io_start(); @@ -199,7 +199,7 @@ static void spr_write_decr (DisasContext *ctx, int sprn, int gprn) /* SPR common to all non-embedded PowerPC, except 601 */ /* Time base */ -static void spr_read_tbl (DisasContext *ctx, int gprn, int sprn) +static void spr_read_tbl(DisasContext *ctx, int gprn, int sprn) { if (ctx->tb->cflags & CF_USE_ICOUNT) { gen_io_start(); @@ -211,7 +211,7 @@ static void spr_read_tbl (DisasContext *ctx, int gprn, int sprn) } } -static void spr_read_tbu (DisasContext *ctx, int gprn, int sprn) +static void spr_read_tbu(DisasContext *ctx, int gprn, int sprn) { if (ctx->tb->cflags & CF_USE_ICOUNT) { gen_io_start(); @@ -224,19 +224,19 @@ static void spr_read_tbu (DisasContext *ctx, int gprn, int sprn) } __attribute__ (( unused )) -static void spr_read_atbl (DisasContext *ctx, int gprn, int sprn) +static void spr_read_atbl(DisasContext *ctx, int gprn, int sprn) { gen_helper_load_atbl(cpu_gpr[gprn], cpu_env); } __attribute__ (( unused )) -static void spr_read_atbu (DisasContext *ctx, int gprn, int sprn) +static void spr_read_atbu(DisasContext *ctx, int gprn, int sprn) { gen_helper_load_atbu(cpu_gpr[gprn], cpu_env); } #if !defined(CONFIG_USER_ONLY) -static void spr_write_tbl (DisasContext *ctx, int sprn, int gprn) +static void spr_write_tbl(DisasContext *ctx, int sprn, int gprn) { if (ctx->tb->cflags & CF_USE_ICOUNT) { gen_io_start(); @@ -248,7 +248,7 @@ static void spr_write_tbl (DisasContext *ctx, int sprn, int gprn) } } -static void spr_write_tbu (DisasContext *ctx, int sprn, int gprn) +static void spr_write_tbu(DisasContext *ctx, int sprn, int gprn) { if (ctx->tb->cflags & CF_USE_ICOUNT) { gen_io_start(); @@ -261,20 +261,20 @@ static void spr_write_tbu (DisasContext *ctx, int sprn, int gprn) } __attribute__ (( unused )) -static void spr_write_atbl (DisasContext *ctx, int sprn, int gprn) +static void spr_write_atbl(DisasContext *ctx, int sprn, int gprn) { gen_helper_store_atbl(cpu_env, cpu_gpr[gprn]); } __attribute__ (( unused )) -static void spr_write_atbu (DisasContext *ctx, int sprn, int gprn) +static void spr_write_atbu(DisasContext *ctx, int sprn, int gprn) { gen_helper_store_atbu(cpu_env, cpu_gpr[gprn]); } #if defined(TARGET_PPC64) __attribute__ (( unused )) -static void spr_read_purr (DisasContext *ctx, int gprn, int sprn) +static void spr_read_purr(DisasContext *ctx, int gprn, int sprn) { gen_helper_load_purr(cpu_gpr[gprn], cpu_env); } @@ -310,38 +310,38 @@ static void spr_write_hdecr(DisasContext *ctx, int sprn, int gprn) #if !defined(CONFIG_USER_ONLY) /* IBAT0U...IBAT0U */ /* IBAT0L...IBAT7L */ -static void spr_read_ibat (DisasContext *ctx, int gprn, int sprn) +static void spr_read_ibat(DisasContext *ctx, int gprn, int sprn) { tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2])); } -static void spr_read_ibat_h (DisasContext *ctx, int gprn, int sprn) +static void spr_read_ibat_h(DisasContext *ctx, int gprn, int sprn) { tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, IBAT[sprn & 1][((sprn - SPR_IBAT4U) / 2) + 4])); } -static void spr_write_ibatu (DisasContext *ctx, int sprn, int gprn) +static void spr_write_ibatu(DisasContext *ctx, int sprn, int gprn) { TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2); gen_helper_store_ibatu(cpu_env, t0, cpu_gpr[gprn]); tcg_temp_free_i32(t0); } -static void spr_write_ibatu_h (DisasContext *ctx, int sprn, int gprn) +static void spr_write_ibatu_h(DisasContext *ctx, int sprn, int gprn) { TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_IBAT4U) / 2) + 4); gen_helper_store_ibatu(cpu_env, t0, cpu_gpr[gprn]); tcg_temp_free_i32(t0); } -static void spr_write_ibatl (DisasContext *ctx, int sprn, int gprn) +static void spr_write_ibatl(DisasContext *ctx, int sprn, int gprn) { TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0L) / 2); gen_helper_store_ibatl(cpu_env, t0, cpu_gpr[gprn]); tcg_temp_free_i32(t0); } -static void spr_write_ibatl_h (DisasContext *ctx, int sprn, int gprn) +static void spr_write_ibatl_h(DisasContext *ctx, int sprn, int gprn) { TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_IBAT4L) / 2) + 4); gen_helper_store_ibatl(cpu_env, t0, cpu_gpr[gprn]); @@ -350,38 +350,38 @@ static void spr_write_ibatl_h (DisasContext *ctx, int sprn, int gprn) /* DBAT0U...DBAT7U */ /* DBAT0L...DBAT7L */ -static void spr_read_dbat (DisasContext *ctx, int gprn, int sprn) +static void spr_read_dbat(DisasContext *ctx, int gprn, int sprn) { tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, DBAT[sprn & 1][(sprn - SPR_DBAT0U) / 2])); } -static void spr_read_dbat_h (DisasContext *ctx, int gprn, int sprn) +static void spr_read_dbat_h(DisasContext *ctx, int gprn, int sprn) { tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, DBAT[sprn & 1][((sprn - SPR_DBAT4U) / 2) + 4])); } -static void spr_write_dbatu (DisasContext *ctx, int sprn, int gprn) +static void spr_write_dbatu(DisasContext *ctx, int sprn, int gprn) { TCGv_i32 t0 = tcg_const_i32((sprn - SPR_DBAT0U) / 2); gen_helper_store_dbatu(cpu_env, t0, cpu_gpr[gprn]); tcg_temp_free_i32(t0); } -static void spr_write_dbatu_h (DisasContext *ctx, int sprn, int gprn) +static void spr_write_dbatu_h(DisasContext *ctx, int sprn, int gprn) { TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_DBAT4U) / 2) + 4); gen_helper_store_dbatu(cpu_env, t0, cpu_gpr[gprn]); tcg_temp_free_i32(t0); } -static void spr_write_dbatl (DisasContext *ctx, int sprn, int gprn) +static void spr_write_dbatl(DisasContext *ctx, int sprn, int gprn) { TCGv_i32 t0 = tcg_const_i32((sprn - SPR_DBAT0L) / 2); gen_helper_store_dbatl(cpu_env, t0, cpu_gpr[gprn]); tcg_temp_free_i32(t0); } -static void spr_write_dbatl_h (DisasContext *ctx, int sprn, int gprn) +static void spr_write_dbatl_h(DisasContext *ctx, int sprn, int gprn) { TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_DBAT4L) / 2) + 4); gen_helper_store_dbatl(cpu_env, t0, cpu_gpr[gprn]); @@ -389,19 +389,25 @@ static void spr_write_dbatl_h (DisasContext *ctx, int sprn, int gprn) } /* SDR1 */ -static void spr_write_sdr1 (DisasContext *ctx, int sprn, int gprn) +static void spr_write_sdr1(DisasContext *ctx, int sprn, int gprn) { gen_helper_store_sdr1(cpu_env, cpu_gpr[gprn]); } -/* 64 bits PowerPC specific SPRs */ #if defined(TARGET_PPC64) -static void spr_read_hior (DisasContext *ctx, int gprn, int sprn) +/* 64 bits PowerPC specific SPRs */ +/* PIDR */ +static void spr_write_pidr(DisasContext *ctx, int sprn, int gprn) +{ + gen_helper_store_pidr(cpu_env, cpu_gpr[gprn]); +} + +static void spr_read_hior(DisasContext *ctx, int gprn, int sprn) { tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, excp_prefix)); } -static void spr_write_hior (DisasContext *ctx, int sprn, int gprn) +static void spr_write_hior(DisasContext *ctx, int sprn, int gprn) { TCGv t0 = tcg_temp_new(); tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0x3FFFFF00000ULL); @@ -413,28 +419,28 @@ static void spr_write_hior (DisasContext *ctx, int sprn, int gprn) /* PowerPC 601 specific registers */ /* RTC */ -static void spr_read_601_rtcl (DisasContext *ctx, int gprn, int sprn) +static void spr_read_601_rtcl(DisasContext *ctx, int gprn, int sprn) { gen_helper_load_601_rtcl(cpu_gpr[gprn], cpu_env); } -static void spr_read_601_rtcu (DisasContext *ctx, int gprn, int sprn) +static void spr_read_601_rtcu(DisasContext *ctx, int gprn, int sprn) { gen_helper_load_601_rtcu(cpu_gpr[gprn], cpu_env); } #if !defined(CONFIG_USER_ONLY) -static void spr_write_601_rtcu (DisasContext *ctx, int sprn, int gprn) +static void spr_write_601_rtcu(DisasContext *ctx, int sprn, int gprn) { gen_helper_store_601_rtcu(cpu_env, cpu_gpr[gprn]); } -static void spr_write_601_rtcl (DisasContext *ctx, int sprn, int gprn) +static void spr_write_601_rtcl(DisasContext *ctx, int sprn, int gprn) { gen_helper_store_601_rtcl(cpu_env, cpu_gpr[gprn]); } -static void spr_write_hid0_601 (DisasContext *ctx, int sprn, int gprn) +static void spr_write_hid0_601(DisasContext *ctx, int sprn, int gprn) { gen_helper_store_hid0_601(cpu_env, cpu_gpr[gprn]); /* Must stop the translation as endianness may have changed */ @@ -444,19 +450,19 @@ static void spr_write_hid0_601 (DisasContext *ctx, int sprn, int gprn) /* Unified bats */ #if !defined(CONFIG_USER_ONLY) -static void spr_read_601_ubat (DisasContext *ctx, int gprn, int sprn) +static void spr_read_601_ubat(DisasContext *ctx, int gprn, int sprn) { tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2])); } -static void spr_write_601_ubatu (DisasContext *ctx, int sprn, int gprn) +static void spr_write_601_ubatu(DisasContext *ctx, int sprn, int gprn) { TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2); gen_helper_store_601_batl(cpu_env, t0, cpu_gpr[gprn]); tcg_temp_free_i32(t0); } -static void spr_write_601_ubatl (DisasContext *ctx, int sprn, int gprn) +static void spr_write_601_ubatl(DisasContext *ctx, int sprn, int gprn) { TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2); gen_helper_store_601_batu(cpu_env, t0, cpu_gpr[gprn]); @@ -466,34 +472,34 @@ static void spr_write_601_ubatl (DisasContext *ctx, int sprn, int gprn) /* PowerPC 40x specific registers */ #if !defined(CONFIG_USER_ONLY) -static void spr_read_40x_pit (DisasContext *ctx, int gprn, int sprn) +static void spr_read_40x_pit(DisasContext *ctx, int gprn, int sprn) { gen_helper_load_40x_pit(cpu_gpr[gprn], cpu_env); } -static void spr_write_40x_pit (DisasContext *ctx, int sprn, int gprn) +static void spr_write_40x_pit(DisasContext *ctx, int sprn, int gprn) { gen_helper_store_40x_pit(cpu_env, cpu_gpr[gprn]); } -static void spr_write_40x_dbcr0 (DisasContext *ctx, int sprn, int gprn) +static void spr_write_40x_dbcr0(DisasContext *ctx, int sprn, int gprn) { gen_helper_store_40x_dbcr0(cpu_env, cpu_gpr[gprn]); /* We must stop translation as we may have rebooted */ gen_stop_exception(ctx); } -static void spr_write_40x_sler (DisasContext *ctx, int sprn, int gprn) +static void spr_write_40x_sler(DisasContext *ctx, int sprn, int gprn) { gen_helper_store_40x_sler(cpu_env, cpu_gpr[gprn]); } -static void spr_write_booke_tcr (DisasContext *ctx, int sprn, int gprn) +static void spr_write_booke_tcr(DisasContext *ctx, int sprn, int gprn) { gen_helper_store_booke_tcr(cpu_env, cpu_gpr[gprn]); } -static void spr_write_booke_tsr (DisasContext *ctx, int sprn, int gprn) +static void spr_write_booke_tsr(DisasContext *ctx, int sprn, int gprn) { gen_helper_store_booke_tsr(cpu_env, cpu_gpr[gprn]); } @@ -502,19 +508,19 @@ static void spr_write_booke_tsr (DisasContext *ctx, int sprn, int gprn) /* PowerPC 403 specific registers */ /* PBL1 / PBU1 / PBL2 / PBU2 */ #if !defined(CONFIG_USER_ONLY) -static void spr_read_403_pbr (DisasContext *ctx, int gprn, int sprn) +static void spr_read_403_pbr(DisasContext *ctx, int gprn, int sprn) { tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, pb[sprn - SPR_403_PBL1])); } -static void spr_write_403_pbr (DisasContext *ctx, int sprn, int gprn) +static void spr_write_403_pbr(DisasContext *ctx, int sprn, int gprn) { TCGv_i32 t0 = tcg_const_i32(sprn - SPR_403_PBL1); gen_helper_store_403_pbr(cpu_env, t0, cpu_gpr[gprn]); tcg_temp_free_i32(t0); } -static void spr_write_pir (DisasContext *ctx, int sprn, int gprn) +static void spr_write_pir(DisasContext *ctx, int sprn, int gprn) { TCGv t0 = tcg_temp_new(); tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0xF); @@ -524,7 +530,7 @@ static void spr_write_pir (DisasContext *ctx, int sprn, int gprn) #endif /* SPE specific registers */ -static void spr_read_spefscr (DisasContext *ctx, int gprn, int sprn) +static void spr_read_spefscr(DisasContext *ctx, int gprn, int sprn) { TCGv_i32 t0 = tcg_temp_new_i32(); tcg_gen_ld_i32(t0, cpu_env, offsetof(CPUPPCState, spe_fscr)); @@ -532,7 +538,7 @@ static void spr_read_spefscr (DisasContext *ctx, int gprn, int sprn) tcg_temp_free_i32(t0); } -static void spr_write_spefscr (DisasContext *ctx, int sprn, int gprn) +static void spr_write_spefscr(DisasContext *ctx, int sprn, int gprn) { TCGv_i32 t0 = tcg_temp_new_i32(); tcg_gen_trunc_tl_i32(t0, cpu_gpr[gprn]); @@ -542,7 +548,7 @@ static void spr_write_spefscr (DisasContext *ctx, int sprn, int gprn) #if !defined(CONFIG_USER_ONLY) /* Callback used to write the exception vector base */ -static void spr_write_excp_prefix (DisasContext *ctx, int sprn, int gprn) +static void spr_write_excp_prefix(DisasContext *ctx, int sprn, int gprn) { TCGv t0 = tcg_temp_new(); tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUPPCState, ivpr_mask)); @@ -552,7 +558,7 @@ static void spr_write_excp_prefix (DisasContext *ctx, int sprn, int gprn) tcg_temp_free(t0); } -static void spr_write_excp_vector (DisasContext *ctx, int sprn, int gprn) +static void spr_write_excp_vector(DisasContext *ctx, int sprn, int gprn) { int sprn_offs; @@ -578,7 +584,7 @@ static void spr_write_excp_vector (DisasContext *ctx, int sprn, int gprn) } #endif -static inline void vscr_init (CPUPPCState *env, uint32_t val) +static inline void vscr_init(CPUPPCState *env, uint32_t val) { env->vscr = val; /* Altivec always uses round-to-nearest */ @@ -679,7 +685,7 @@ static inline void _spr_register(CPUPPCState *env, int num, } /* Generic PowerPC SPRs */ -static void gen_spr_generic (CPUPPCState *env) +static void gen_spr_generic(CPUPPCState *env) { /* Integer processing */ spr_register(env, SPR_XER, "XER", @@ -764,7 +770,7 @@ static void gen_spr_sdr1(CPUPPCState *env) } /* BATs 0-3 */ -static void gen_low_BATs (CPUPPCState *env) +static void gen_low_BATs(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) spr_register(env, SPR_IBAT0U, "IBAT0U", @@ -836,7 +842,7 @@ static void gen_low_BATs (CPUPPCState *env) } /* BATs 4-7 */ -static void gen_high_BATs (CPUPPCState *env) +static void gen_high_BATs(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) spr_register(env, SPR_IBAT4U, "IBAT4U", @@ -908,7 +914,7 @@ static void gen_high_BATs (CPUPPCState *env) } /* Generic PowerPC time base */ -static void gen_tbl (CPUPPCState *env) +static void gen_tbl(CPUPPCState *env) { spr_register(env, SPR_VTBL, "TBL", &spr_read_tbl, SPR_NOACCESS, @@ -929,7 +935,7 @@ static void gen_tbl (CPUPPCState *env) } /* Softare table search registers */ -static void gen_6xx_7xx_soft_tlb (CPUPPCState *env, int nb_tlbs, int nb_ways) +static void gen_6xx_7xx_soft_tlb(CPUPPCState *env, int nb_tlbs, int nb_ways) { #if !defined(CONFIG_USER_ONLY) env->nb_tlb = nb_tlbs; @@ -968,7 +974,7 @@ static void gen_6xx_7xx_soft_tlb (CPUPPCState *env, int nb_tlbs, int nb_ways) } /* SPR common to MPC755 and G2 */ -static void gen_spr_G2_755 (CPUPPCState *env) +static void gen_spr_G2_755(CPUPPCState *env) { /* SGPRs */ spr_register(env, SPR_SPRG4, "SPRG4", @@ -990,7 +996,7 @@ static void gen_spr_G2_755 (CPUPPCState *env) } /* SPR common to all 7xx PowerPC implementations */ -static void gen_spr_7xx (CPUPPCState *env) +static void gen_spr_7xx(CPUPPCState *env) { /* Breakpoints */ /* XXX : not implemented */ @@ -1235,7 +1241,7 @@ static void spr_read_thrm(DisasContext *ctx, int gprn, int sprn) } #endif /* !CONFIG_USER_ONLY */ -static void gen_spr_thrm (CPUPPCState *env) +static void gen_spr_thrm(CPUPPCState *env) { /* Thermal management */ /* XXX : not implemented */ @@ -1256,7 +1262,7 @@ static void gen_spr_thrm (CPUPPCState *env) } /* SPR specific to PowerPC 604 implementation */ -static void gen_spr_604 (CPUPPCState *env) +static void gen_spr_604(CPUPPCState *env) { /* Processor identification */ spr_register(env, SPR_PIR, "PIR", @@ -1309,7 +1315,7 @@ static void gen_spr_604 (CPUPPCState *env) } /* SPR specific to PowerPC 603 implementation */ -static void gen_spr_603 (CPUPPCState *env) +static void gen_spr_603(CPUPPCState *env) { /* External access control */ /* XXX : not implemented */ @@ -1327,7 +1333,7 @@ static void gen_spr_603 (CPUPPCState *env) } /* SPR specific to PowerPC G2 implementation */ -static void gen_spr_G2 (CPUPPCState *env) +static void gen_spr_G2(CPUPPCState *env) { /* Memory base address */ /* MBAR */ @@ -1379,7 +1385,7 @@ static void gen_spr_G2 (CPUPPCState *env) } /* SPR specific to PowerPC 602 implementation */ -static void gen_spr_602 (CPUPPCState *env) +static void gen_spr_602(CPUPPCState *env) { /* ESA registers */ /* XXX : not implemented */ @@ -1427,7 +1433,7 @@ static void gen_spr_602 (CPUPPCState *env) } /* SPR specific to PowerPC 601 implementation */ -static void gen_spr_601 (CPUPPCState *env) +static void gen_spr_601(CPUPPCState *env) { /* Multiplication/division register */ /* MQ */ @@ -1503,7 +1509,7 @@ static void gen_spr_601 (CPUPPCState *env) #endif } -static void gen_spr_74xx (CPUPPCState *env) +static void gen_spr_74xx(CPUPPCState *env) { /* Processor identification */ spr_register(env, SPR_PIR, "PIR", @@ -1555,7 +1561,7 @@ static void gen_spr_74xx (CPUPPCState *env) vscr_init(env, 0x00010000); } -static void gen_l3_ctrl (CPUPPCState *env) +static void gen_l3_ctrl(CPUPPCState *env) { /* L3CR */ /* XXX : not implemented */ @@ -1577,7 +1583,7 @@ static void gen_l3_ctrl (CPUPPCState *env) 0x00000000); } -static void gen_74xx_soft_tlb (CPUPPCState *env, int nb_tlbs, int nb_ways) +static void gen_74xx_soft_tlb(CPUPPCState *env, int nb_tlbs, int nb_ways) { #if !defined(CONFIG_USER_ONLY) env->nb_tlb = nb_tlbs; @@ -1603,7 +1609,7 @@ static void gen_74xx_soft_tlb (CPUPPCState *env, int nb_tlbs, int nb_ways) } #if !defined(CONFIG_USER_ONLY) -static void spr_write_e500_l1csr0 (DisasContext *ctx, int sprn, int gprn) +static void spr_write_e500_l1csr0(DisasContext *ctx, int sprn, int gprn) { TCGv t0 = tcg_temp_new(); @@ -1621,12 +1627,12 @@ static void spr_write_e500_l1csr1(DisasContext *ctx, int sprn, int gprn) tcg_temp_free(t0); } -static void spr_write_booke206_mmucsr0 (DisasContext *ctx, int sprn, int gprn) +static void spr_write_booke206_mmucsr0(DisasContext *ctx, int sprn, int gprn) { gen_helper_booke206_tlbflush(cpu_env, cpu_gpr[gprn]); } -static void spr_write_booke_pid (DisasContext *ctx, int sprn, int gprn) +static void spr_write_booke_pid(DisasContext *ctx, int sprn, int gprn) { TCGv_i32 t0 = tcg_const_i32(sprn); gen_helper_booke_setpid(cpu_env, t0, cpu_gpr[gprn]); @@ -1634,7 +1640,15 @@ static void spr_write_booke_pid (DisasContext *ctx, int sprn, int gprn) } #endif -static void gen_spr_usprgh (CPUPPCState *env) +static void gen_spr_usprg3(CPUPPCState *env) +{ + spr_register(env, SPR_USPRG3, "USPRG3", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); +} + +static void gen_spr_usprgh(CPUPPCState *env) { spr_register(env, SPR_USPRG4, "USPRG4", &spr_read_ureg, SPR_NOACCESS, @@ -1655,7 +1669,7 @@ static void gen_spr_usprgh (CPUPPCState *env) } /* PowerPC BookE SPR */ -static void gen_spr_BookE (CPUPPCState *env, uint64_t ivor_mask) +static void gen_spr_BookE(CPUPPCState *env, uint64_t ivor_mask) { const char *ivor_names[64] = { "IVOR0", "IVOR1", "IVOR2", "IVOR3", @@ -1907,7 +1921,7 @@ static void gen_spr_BookE206(CPUPPCState *env, uint32_t mas_mask, } /* SPR specific to PowerPC 440 implementation */ -static void gen_spr_440 (CPUPPCState *env) +static void gen_spr_440(CPUPPCState *env) { /* Cache control */ /* XXX : not implemented */ @@ -2048,7 +2062,7 @@ static void gen_spr_440 (CPUPPCState *env) } /* SPR shared between PowerPC 40x implementations */ -static void gen_spr_40x (CPUPPCState *env) +static void gen_spr_40x(CPUPPCState *env) { /* Cache */ /* not emulated, as QEMU do not emulate caches */ @@ -2103,7 +2117,7 @@ static void gen_spr_40x (CPUPPCState *env) } /* SPR specific to PowerPC 405 implementation */ -static void gen_spr_405 (CPUPPCState *env) +static void gen_spr_405(CPUPPCState *env) { /* MMU */ spr_register(env, SPR_40x_PID, "PID", @@ -2209,7 +2223,7 @@ static void gen_spr_405 (CPUPPCState *env) } /* SPR shared between PowerPC 401 & 403 implementations */ -static void gen_spr_401_403 (CPUPPCState *env) +static void gen_spr_401_403(CPUPPCState *env) { /* Time base */ spr_register(env, SPR_403_VTBL, "TBL", @@ -2237,7 +2251,7 @@ static void gen_spr_401_403 (CPUPPCState *env) } /* SPR specific to PowerPC 401 implementation */ -static void gen_spr_401 (CPUPPCState *env) +static void gen_spr_401(CPUPPCState *env) { /* Debug interface */ /* XXX : not implemented */ @@ -2279,7 +2293,7 @@ static void gen_spr_401 (CPUPPCState *env) 0x00000000); } -static void gen_spr_401x2 (CPUPPCState *env) +static void gen_spr_401x2(CPUPPCState *env) { gen_spr_401(env); spr_register(env, SPR_40x_PID, "PID", @@ -2293,7 +2307,7 @@ static void gen_spr_401x2 (CPUPPCState *env) } /* SPR specific to PowerPC 403 implementation */ -static void gen_spr_403 (CPUPPCState *env) +static void gen_spr_403(CPUPPCState *env) { /* Debug interface */ /* XXX : not implemented */ @@ -2329,7 +2343,7 @@ static void gen_spr_403 (CPUPPCState *env) 0x00000000); } -static void gen_spr_403_real (CPUPPCState *env) +static void gen_spr_403_real(CPUPPCState *env) { spr_register(env, SPR_403_PBL1, "PBL1", SPR_NOACCESS, SPR_NOACCESS, @@ -2349,7 +2363,7 @@ static void gen_spr_403_real (CPUPPCState *env) 0x00000000); } -static void gen_spr_403_mmu (CPUPPCState *env) +static void gen_spr_403_mmu(CPUPPCState *env) { /* MMU */ spr_register(env, SPR_40x_PID, "PID", @@ -2363,7 +2377,7 @@ static void gen_spr_403_mmu (CPUPPCState *env) } /* SPR specific to PowerPC compression coprocessor extension */ -static void gen_spr_compress (CPUPPCState *env) +static void gen_spr_compress(CPUPPCState *env) { /* XXX : not implemented */ spr_register(env, SPR_401_SKR, "SKR", @@ -2372,7 +2386,7 @@ static void gen_spr_compress (CPUPPCState *env) 0x00000000); } -static void gen_spr_5xx_8xx (CPUPPCState *env) +static void gen_spr_5xx_8xx(CPUPPCState *env) { /* Exception processing */ spr_register_kvm(env, SPR_DSISR, "DSISR", @@ -2490,7 +2504,7 @@ static void gen_spr_5xx_8xx (CPUPPCState *env) 0x00000000); } -static void gen_spr_5xx (CPUPPCState *env) +static void gen_spr_5xx(CPUPPCState *env) { /* XXX : not implemented */ spr_register(env, SPR_RCPU_MI_GRA, "MI_GRA", @@ -2599,7 +2613,7 @@ static void gen_spr_5xx (CPUPPCState *env) 0x00000000); } -static void gen_spr_8xx (CPUPPCState *env) +static void gen_spr_8xx(CPUPPCState *env) { /* XXX : not implemented */ spr_register(env, SPR_MPC_IC_CST, "IC_CST", @@ -2761,7 +2775,7 @@ static void gen_spr_8xx (CPUPPCState *env) /*****************************************************************************/ /* Exception vectors models */ -static void init_excp_4xx_real (CPUPPCState *env) +static void init_excp_4xx_real(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000100; @@ -2781,7 +2795,7 @@ static void init_excp_4xx_real (CPUPPCState *env) #endif } -static void init_excp_4xx_softmmu (CPUPPCState *env) +static void init_excp_4xx_softmmu(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000100; @@ -2805,7 +2819,7 @@ static void init_excp_4xx_softmmu (CPUPPCState *env) #endif } -static void init_excp_MPC5xx (CPUPPCState *env) +static void init_excp_MPC5xx(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; @@ -2830,7 +2844,7 @@ static void init_excp_MPC5xx (CPUPPCState *env) #endif } -static void init_excp_MPC8xx (CPUPPCState *env) +static void init_excp_MPC8xx(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; @@ -2861,7 +2875,7 @@ static void init_excp_MPC8xx (CPUPPCState *env) #endif } -static void init_excp_G2 (CPUPPCState *env) +static void init_excp_G2(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; @@ -2916,7 +2930,7 @@ static void init_excp_e200(CPUPPCState *env, target_ulong ivpr_mask) #endif } -static void init_excp_BookE (CPUPPCState *env) +static void init_excp_BookE(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000000; @@ -2942,7 +2956,7 @@ static void init_excp_BookE (CPUPPCState *env) #endif } -static void init_excp_601 (CPUPPCState *env) +static void init_excp_601(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; @@ -2962,7 +2976,7 @@ static void init_excp_601 (CPUPPCState *env) #endif } -static void init_excp_602 (CPUPPCState *env) +static void init_excp_602(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) /* XXX: exception prefix has a special behavior on 602 */ @@ -2989,7 +3003,7 @@ static void init_excp_602 (CPUPPCState *env) #endif } -static void init_excp_603 (CPUPPCState *env) +static void init_excp_603(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; @@ -3013,7 +3027,7 @@ static void init_excp_603 (CPUPPCState *env) #endif } -static void init_excp_604 (CPUPPCState *env) +static void init_excp_604(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; @@ -3035,7 +3049,7 @@ static void init_excp_604 (CPUPPCState *env) #endif } -static void init_excp_7x0 (CPUPPCState *env) +static void init_excp_7x0(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; @@ -3058,7 +3072,7 @@ static void init_excp_7x0 (CPUPPCState *env) #endif } -static void init_excp_750cl (CPUPPCState *env) +static void init_excp_750cl(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; @@ -3080,7 +3094,7 @@ static void init_excp_750cl (CPUPPCState *env) #endif } -static void init_excp_750cx (CPUPPCState *env) +static void init_excp_750cx(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; @@ -3103,7 +3117,7 @@ static void init_excp_750cx (CPUPPCState *env) } /* XXX: Check if this is correct */ -static void init_excp_7x5 (CPUPPCState *env) +static void init_excp_7x5(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; @@ -3129,7 +3143,7 @@ static void init_excp_7x5 (CPUPPCState *env) #endif } -static void init_excp_7400 (CPUPPCState *env) +static void init_excp_7400(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; @@ -3154,7 +3168,7 @@ static void init_excp_7400 (CPUPPCState *env) #endif } -static void init_excp_7450 (CPUPPCState *env) +static void init_excp_7450(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; @@ -3181,8 +3195,8 @@ static void init_excp_7450 (CPUPPCState *env) #endif } -#if defined (TARGET_PPC64) -static void init_excp_970 (CPUPPCState *env) +#if defined(TARGET_PPC64) +static void init_excp_970(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; @@ -3210,7 +3224,7 @@ static void init_excp_970 (CPUPPCState *env) #endif } -static void init_excp_POWER7 (CPUPPCState *env) +static void init_excp_POWER7(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; @@ -3255,17 +3269,17 @@ static void init_excp_POWER8(CPUPPCState *env) /*****************************************************************************/ /* Power management enable checks */ -static int check_pow_none (CPUPPCState *env) +static int check_pow_none(CPUPPCState *env) { return 0; } -static int check_pow_nocheck (CPUPPCState *env) +static int check_pow_nocheck(CPUPPCState *env) { return 1; } -static int check_pow_hid0 (CPUPPCState *env) +static int check_pow_hid0(CPUPPCState *env) { if (env->spr[SPR_HID0] & 0x00E00000) return 1; @@ -3273,7 +3287,7 @@ static int check_pow_hid0 (CPUPPCState *env) return 0; } -static int check_pow_hid0_74xx (CPUPPCState *env) +static int check_pow_hid0_74xx(CPUPPCState *env) { if (env->spr[SPR_HID0] & 0x00600000) return 1; @@ -3318,7 +3332,7 @@ static bool ppc_cpu_interrupts_big_endian_lpcr(PowerPCCPU *cpu) \ static void glue(glue(ppc_, _name), _cpu_family_class_init) -static void init_proc_401 (CPUPPCState *env) +static void init_proc_401(CPUPPCState *env) { gen_spr_40x(env); gen_spr_401_403(env); @@ -3364,7 +3378,7 @@ POWERPC_FAMILY(401)(ObjectClass *oc, void *data) POWERPC_FLAG_BUS_CLK; } -static void init_proc_401x2 (CPUPPCState *env) +static void init_proc_401x2(CPUPPCState *env) { gen_spr_40x(env); gen_spr_401_403(env); @@ -3422,7 +3436,7 @@ POWERPC_FAMILY(401x2)(ObjectClass *oc, void *data) POWERPC_FLAG_BUS_CLK; } -static void init_proc_401x3 (CPUPPCState *env) +static void init_proc_401x3(CPUPPCState *env) { gen_spr_40x(env); gen_spr_401_403(env); @@ -3475,7 +3489,7 @@ POWERPC_FAMILY(401x3)(ObjectClass *oc, void *data) POWERPC_FLAG_BUS_CLK; } -static void init_proc_IOP480 (CPUPPCState *env) +static void init_proc_IOP480(CPUPPCState *env) { gen_spr_40x(env); gen_spr_401_403(env); @@ -3533,7 +3547,7 @@ POWERPC_FAMILY(IOP480)(ObjectClass *oc, void *data) POWERPC_FLAG_BUS_CLK; } -static void init_proc_403 (CPUPPCState *env) +static void init_proc_403(CPUPPCState *env) { gen_spr_40x(env); gen_spr_401_403(env); @@ -3580,7 +3594,7 @@ POWERPC_FAMILY(403)(ObjectClass *oc, void *data) POWERPC_FLAG_BUS_CLK; } -static void init_proc_403GCX (CPUPPCState *env) +static void init_proc_403GCX(CPUPPCState *env) { gen_spr_40x(env); gen_spr_401_403(env); @@ -3647,7 +3661,7 @@ POWERPC_FAMILY(403GCX)(ObjectClass *oc, void *data) POWERPC_FLAG_BUS_CLK; } -static void init_proc_405 (CPUPPCState *env) +static void init_proc_405(CPUPPCState *env) { /* Time base */ gen_tbl(env); @@ -3713,7 +3727,7 @@ POWERPC_FAMILY(405)(ObjectClass *oc, void *data) POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; } -static void init_proc_440EP (CPUPPCState *env) +static void init_proc_440EP(CPUPPCState *env) { /* Time base */ gen_tbl(env); @@ -3817,7 +3831,7 @@ POWERPC_FAMILY(440EP)(ObjectClass *oc, void *data) POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; } -static void init_proc_440GP (CPUPPCState *env) +static void init_proc_440GP(CPUPPCState *env) { /* Time base */ gen_tbl(env); @@ -3900,7 +3914,7 @@ POWERPC_FAMILY(440GP)(ObjectClass *oc, void *data) POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; } -static void init_proc_440x4 (CPUPPCState *env) +static void init_proc_440x4(CPUPPCState *env) { /* Time base */ gen_tbl(env); @@ -3983,7 +3997,7 @@ POWERPC_FAMILY(440x4)(ObjectClass *oc, void *data) POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; } -static void init_proc_440x5 (CPUPPCState *env) +static void init_proc_440x5(CPUPPCState *env) { /* Time base */ gen_tbl(env); @@ -4229,7 +4243,7 @@ POWERPC_FAMILY(460)(ObjectClass *oc, void *data) POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; } -static void init_proc_460F (CPUPPCState *env) +static void init_proc_460F(CPUPPCState *env) { /* Time base */ gen_tbl(env); @@ -4339,7 +4353,7 @@ POWERPC_FAMILY(460F)(ObjectClass *oc, void *data) POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; } -static void init_proc_MPC5xx (CPUPPCState *env) +static void init_proc_MPC5xx(CPUPPCState *env) { /* Time base */ gen_tbl(env); @@ -4383,7 +4397,7 @@ POWERPC_FAMILY(MPC5xx)(ObjectClass *oc, void *data) POWERPC_FLAG_BUS_CLK; } -static void init_proc_MPC8xx (CPUPPCState *env) +static void init_proc_MPC8xx(CPUPPCState *env) { /* Time base */ gen_tbl(env); @@ -4428,7 +4442,7 @@ POWERPC_FAMILY(MPC8xx)(ObjectClass *oc, void *data) /* Freescale 82xx cores (aka PowerQUICC-II) */ -static void init_proc_G2 (CPUPPCState *env) +static void init_proc_G2(CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_sdr1(env); @@ -4507,7 +4521,7 @@ POWERPC_FAMILY(G2)(ObjectClass *oc, void *data) POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK; } -static void init_proc_G2LE (CPUPPCState *env) +static void init_proc_G2LE(CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_sdr1(env); @@ -4589,7 +4603,7 @@ POWERPC_FAMILY(G2LE)(ObjectClass *oc, void *data) POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK; } -static void init_proc_e200 (CPUPPCState *env) +static void init_proc_e200(CPUPPCState *env) { /* Time base */ gen_tbl(env); @@ -4743,7 +4757,7 @@ POWERPC_FAMILY(e200)(ObjectClass *oc, void *data) POWERPC_FLAG_BUS_CLK; } -static void init_proc_e300 (CPUPPCState *env) +static void init_proc_e300(CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_sdr1(env); @@ -4875,7 +4889,7 @@ enum fsl_e500_version { fsl_e5500, }; -static void init_proc_e500 (CPUPPCState *env, int version) +static void init_proc_e500(CPUPPCState *env, int version) { PowerPCCPU *cpu = ppc_env_get_cpu(env); uint32_t tlbncfg[2]; @@ -4908,6 +4922,7 @@ static void init_proc_e500 (CPUPPCState *env, int version) break; } gen_spr_BookE(env, ivor_mask); + gen_spr_usprg3(env); /* Processor identification */ spr_register(env, SPR_BOOKE_PIR, "PIR", SPR_NOACCESS, SPR_NOACCESS, @@ -5243,7 +5258,7 @@ POWERPC_FAMILY(e5500)(ObjectClass *oc, void *data) #define POWERPC_MSRR_601 (0x0000000000001040ULL) -static void init_proc_601 (CPUPPCState *env) +static void init_proc_601(CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_sdr1(env); @@ -5316,7 +5331,7 @@ POWERPC_FAMILY(601)(ObjectClass *oc, void *data) #define POWERPC_MSRR_601v (0x0000000000001040ULL) -static void init_proc_601v (CPUPPCState *env) +static void init_proc_601v(CPUPPCState *env) { init_proc_601(env); /* XXX : not implemented */ @@ -5358,7 +5373,7 @@ POWERPC_FAMILY(601v)(ObjectClass *oc, void *data) pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK; } -static void init_proc_602 (CPUPPCState *env) +static void init_proc_602(CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_sdr1(env); @@ -5428,7 +5443,7 @@ POWERPC_FAMILY(602)(ObjectClass *oc, void *data) POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK; } -static void init_proc_603 (CPUPPCState *env) +static void init_proc_603(CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_sdr1(env); @@ -5495,7 +5510,7 @@ POWERPC_FAMILY(603)(ObjectClass *oc, void *data) POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK; } -static void init_proc_603E (CPUPPCState *env) +static void init_proc_603E(CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_sdr1(env); @@ -5562,7 +5577,7 @@ POWERPC_FAMILY(603E)(ObjectClass *oc, void *data) POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK; } -static void init_proc_604 (CPUPPCState *env) +static void init_proc_604(CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_sdr1(env); @@ -5626,7 +5641,7 @@ POWERPC_FAMILY(604)(ObjectClass *oc, void *data) POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; } -static void init_proc_604E (CPUPPCState *env) +static void init_proc_604E(CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_sdr1(env); @@ -5710,7 +5725,7 @@ POWERPC_FAMILY(604E)(ObjectClass *oc, void *data) POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; } -static void init_proc_740 (CPUPPCState *env) +static void init_proc_740(CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_sdr1(env); @@ -5781,7 +5796,7 @@ POWERPC_FAMILY(740)(ObjectClass *oc, void *data) POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; } -static void init_proc_750 (CPUPPCState *env) +static void init_proc_750(CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_sdr1(env); @@ -5860,7 +5875,7 @@ POWERPC_FAMILY(750)(ObjectClass *oc, void *data) POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; } -static void init_proc_750cl (CPUPPCState *env) +static void init_proc_750cl(CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_sdr1(env); @@ -6062,7 +6077,7 @@ POWERPC_FAMILY(750cl)(ObjectClass *oc, void *data) POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; } -static void init_proc_750cx (CPUPPCState *env) +static void init_proc_750cx(CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_sdr1(env); @@ -6145,7 +6160,7 @@ POWERPC_FAMILY(750cx)(ObjectClass *oc, void *data) POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; } -static void init_proc_750fx (CPUPPCState *env) +static void init_proc_750fx(CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_sdr1(env); @@ -6233,7 +6248,7 @@ POWERPC_FAMILY(750fx)(ObjectClass *oc, void *data) POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; } -static void init_proc_750gx (CPUPPCState *env) +static void init_proc_750gx(CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_sdr1(env); @@ -6321,7 +6336,7 @@ POWERPC_FAMILY(750gx)(ObjectClass *oc, void *data) POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; } -static void init_proc_745 (CPUPPCState *env) +static void init_proc_745(CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_sdr1(env); @@ -6397,7 +6412,7 @@ POWERPC_FAMILY(745)(ObjectClass *oc, void *data) POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; } -static void init_proc_755 (CPUPPCState *env) +static void init_proc_755(CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_sdr1(env); @@ -6484,7 +6499,7 @@ POWERPC_FAMILY(755)(ObjectClass *oc, void *data) POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; } -static void init_proc_7400 (CPUPPCState *env) +static void init_proc_7400(CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_sdr1(env); @@ -6563,7 +6578,7 @@ POWERPC_FAMILY(7400)(ObjectClass *oc, void *data) POWERPC_FLAG_BUS_CLK; } -static void init_proc_7410 (CPUPPCState *env) +static void init_proc_7410(CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_sdr1(env); @@ -6648,7 +6663,7 @@ POWERPC_FAMILY(7410)(ObjectClass *oc, void *data) POWERPC_FLAG_BUS_CLK; } -static void init_proc_7440 (CPUPPCState *env) +static void init_proc_7440(CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_sdr1(env); @@ -6756,7 +6771,7 @@ POWERPC_FAMILY(7440)(ObjectClass *oc, void *data) POWERPC_FLAG_BUS_CLK; } -static void init_proc_7450 (CPUPPCState *env) +static void init_proc_7450(CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_sdr1(env); @@ -6890,7 +6905,7 @@ POWERPC_FAMILY(7450)(ObjectClass *oc, void *data) POWERPC_FLAG_BUS_CLK; } -static void init_proc_7445 (CPUPPCState *env) +static void init_proc_7445(CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_sdr1(env); @@ -7027,7 +7042,7 @@ POWERPC_FAMILY(7445)(ObjectClass *oc, void *data) POWERPC_FLAG_BUS_CLK; } -static void init_proc_7455 (CPUPPCState *env) +static void init_proc_7455(CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_sdr1(env); @@ -7166,7 +7181,7 @@ POWERPC_FAMILY(7455)(ObjectClass *oc, void *data) POWERPC_FLAG_BUS_CLK; } -static void init_proc_7457 (CPUPPCState *env) +static void init_proc_7457(CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_sdr1(env); @@ -7329,7 +7344,7 @@ POWERPC_FAMILY(7457)(ObjectClass *oc, void *data) POWERPC_FLAG_BUS_CLK; } -static void init_proc_e600 (CPUPPCState *env) +static void init_proc_e600(CPUPPCState *env) { gen_spr_ne_601(env); gen_spr_sdr1(env); @@ -7471,7 +7486,7 @@ POWERPC_FAMILY(e600)(ObjectClass *oc, void *data) POWERPC_FLAG_BUS_CLK; } -#if defined (TARGET_PPC64) +#if defined(TARGET_PPC64) #if defined(CONFIG_USER_ONLY) #define POWERPC970_HID5_INIT 0x00000080 #else @@ -7530,7 +7545,7 @@ static void spr_write_prev_upper32(DisasContext *ctx, int sprn, int gprn) tcg_temp_free(spr); } -static int check_pow_970 (CPUPPCState *env) +static int check_pow_970(CPUPPCState *env) { if (env->spr[SPR_HID0] & (HID0_DEEPNAP | HID0_DOZE | HID0_NAP)) { return 1; @@ -8200,7 +8215,7 @@ static void gen_spr_power8_book4(CPUPPCState *env) KVM_REG_PPC_ACOP, 0); spr_register_kvm(env, SPR_BOOKS_PID, "PID", SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, + &spr_read_generic, &spr_write_pidr, KVM_REG_PPC_PID, 0); spr_register_kvm(env, SPR_WORT, "WORT", SPR_NOACCESS, SPR_NOACCESS, @@ -8239,6 +8254,7 @@ static void init_proc_book3s_common(CPUPPCState *env) { gen_spr_ne_601(env); gen_tbl(env); + gen_spr_usprg3(env); gen_spr_book3s_altivec(env); gen_spr_book3s_pmu_sup(env); gen_spr_book3s_pmu_user(env); @@ -8497,7 +8513,7 @@ static const struct ppc_segment_page_sizes POWER7_POWER8_sps = { }; #endif /* CONFIG_SOFTMMU */ -static void init_proc_POWER7 (CPUPPCState *env) +static void init_proc_POWER7(CPUPPCState *env) { /* Common Registers */ init_proc_book3s_common(env); @@ -8808,6 +8824,25 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr; } +#ifdef CONFIG_SOFTMMU +/* + * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings + * Encoded as array of int_32s in the form: + * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy + * x -> AP encoding + * y -> radix mode supported page size (encoded as a shift) + */ +static struct ppc_radix_page_info POWER9_radix_page_info = { + .count = 4, + .entries = { + 0x0000000c, /* 4K - enc: 0x0 */ + 0xa0000010, /* 64K - enc: 0x5 */ + 0x20000015, /* 2M - enc: 0x1 */ + 0x4000001e /* 1G - enc: 0x2 */ + } +}; +#endif /* CONFIG_SOFTMMU */ + static void init_proc_POWER9(CPUPPCState *env) { /* Common Registers */ @@ -8959,6 +8994,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data) pcc->handle_mmu_fault = ppc64_v3_handle_mmu_fault; /* segment page size remain the same */ pcc->sps = &POWER7_POWER8_sps; + pcc->radix_page_info = &POWER9_radix_page_info; #endif pcc->excp_model = POWERPC_EXCP_POWER8; pcc->bus_model = PPC_FLAGS_INPUT_POWER7; @@ -9043,7 +9079,7 @@ void cpu_ppc_set_papr(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp) #endif /* !defined(CONFIG_USER_ONLY) */ -#endif /* defined (TARGET_PPC64) */ +#endif /* defined(TARGET_PPC64) */ /*****************************************************************************/ /* Generic CPU instantiation routine */ @@ -9214,7 +9250,7 @@ static void init_ppc_proc(PowerPCCPU *cpu) } #if defined(PPC_DUMP_CPU) -static void dump_ppc_sprs (CPUPPCState *env) +static void dump_ppc_sprs(CPUPPCState *env) { ppc_spr_t *spr; #if !defined(CONFIG_USER_ONLY) @@ -9263,7 +9299,7 @@ enum { #define PPC_OPCODE_MASK 0x3 -static inline int is_indirect_opcode (void *handler) +static inline int is_indirect_opcode(void *handler) { return ((uintptr_t)handler & PPC_OPCODE_MASK) == PPC_INDIRECT; } @@ -9275,7 +9311,7 @@ static inline opc_handler_t **ind_table(void *handler) /* Instruction table creation */ /* Opcodes tables creation */ -static void fill_new_table (opc_handler_t **table, int len) +static void fill_new_table(opc_handler_t **table, int len) { int i; @@ -9283,7 +9319,7 @@ static void fill_new_table (opc_handler_t **table, int len) table[i] = &invalid_handler; } -static int create_new_table (opc_handler_t **table, unsigned char idx) +static int create_new_table(opc_handler_t **table, unsigned char idx) { opc_handler_t **tmp; @@ -9294,7 +9330,7 @@ static int create_new_table (opc_handler_t **table, unsigned char idx) return 0; } -static int insert_in_table (opc_handler_t **table, unsigned char idx, +static int insert_in_table(opc_handler_t **table, unsigned char idx, opc_handler_t *handler) { if (table[idx] != &invalid_handler) @@ -9304,8 +9340,8 @@ static int insert_in_table (opc_handler_t **table, unsigned char idx, return 0; } -static int register_direct_insn (opc_handler_t **ppc_opcodes, - unsigned char idx, opc_handler_t *handler) +static int register_direct_insn(opc_handler_t **ppc_opcodes, + unsigned char idx, opc_handler_t *handler) { if (insert_in_table(ppc_opcodes, idx, handler) < 0) { printf("*** ERROR: opcode %02x already assigned in main " @@ -9320,9 +9356,9 @@ static int register_direct_insn (opc_handler_t **ppc_opcodes, return 0; } -static int register_ind_in_table (opc_handler_t **table, - unsigned char idx1, unsigned char idx2, - opc_handler_t *handler) +static int register_ind_in_table(opc_handler_t **table, + unsigned char idx1, unsigned char idx2, + opc_handler_t *handler) { if (table[idx1] == &invalid_handler) { if (create_new_table(table, idx1) < 0) { @@ -9355,16 +9391,16 @@ static int register_ind_in_table (opc_handler_t **table, return 0; } -static int register_ind_insn (opc_handler_t **ppc_opcodes, - unsigned char idx1, unsigned char idx2, - opc_handler_t *handler) +static int register_ind_insn(opc_handler_t **ppc_opcodes, + unsigned char idx1, unsigned char idx2, + opc_handler_t *handler) { return register_ind_in_table(ppc_opcodes, idx1, idx2, handler); } -static int register_dblind_insn (opc_handler_t **ppc_opcodes, - unsigned char idx1, unsigned char idx2, - unsigned char idx3, opc_handler_t *handler) +static int register_dblind_insn(opc_handler_t **ppc_opcodes, + unsigned char idx1, unsigned char idx2, + unsigned char idx3, opc_handler_t *handler) { if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) { printf("*** ERROR: unable to join indirect table idx " @@ -9407,7 +9443,7 @@ static int register_trplind_insn(opc_handler_t **ppc_opcodes, } return 0; } -static int register_insn (opc_handler_t **ppc_opcodes, opcode_t *insn) +static int register_insn(opc_handler_t **ppc_opcodes, opcode_t *insn) { if (insn->opc2 != 0xFF) { if (insn->opc3 != 0xFF) { @@ -9435,7 +9471,7 @@ static int register_insn (opc_handler_t **ppc_opcodes, opcode_t *insn) return 0; } -static int test_opcode_table (opc_handler_t **table, int len) +static int test_opcode_table(opc_handler_t **table, int len) { int i, count, tmp; @@ -9462,7 +9498,7 @@ static int test_opcode_table (opc_handler_t **table, int len) return count; } -static void fix_opcode_tables (opc_handler_t **ppc_opcodes) +static void fix_opcode_tables(opc_handler_t **ppc_opcodes) { if (test_opcode_table(ppc_opcodes, PPC_CPU_OPCODES_LEN) == 0) printf("*** WARNING: no opcode defined !\n"); @@ -9493,7 +9529,7 @@ static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp) } #if defined(PPC_DUMP_CPU) -static void dump_ppc_insns (CPUPPCState *env) +static void dump_ppc_insns(CPUPPCState *env) { opc_handler_t **table, *handler; const char *p, *q; @@ -9907,7 +9943,7 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp) case POWERPC_MMU_601: mmu_model = "PowerPC 601"; break; -#if defined (TARGET_PPC64) +#if defined(TARGET_PPC64) case POWERPC_MMU_64B: mmu_model = "PowerPC 64"; break; @@ -9950,7 +9986,7 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp) case POWERPC_EXCP_BOOKE: excp_model = "PowerPC BookE"; break; -#if defined (TARGET_PPC64) +#if defined(TARGET_PPC64) case POWERPC_EXCP_970: excp_model = "PowerPC 970"; break; @@ -9975,7 +10011,7 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp) case PPC_FLAGS_INPUT_RCPU: bus_model = "RCPU / MPC8xx"; break; -#if defined (TARGET_PPC64) +#if defined(TARGET_PPC64) case PPC_FLAGS_INPUT_970: bus_model = "PowerPC 970"; break; diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c index 1434d15315..ce461cc905 100644 --- a/target/s390x/cpu_models.c +++ b/target/s390x/cpu_models.c @@ -376,12 +376,12 @@ static void cpu_model_from_info(S390CPUModel *model, const CpuModelInfo *info, static void qdict_add_disabled_feat(const char *name, void *opaque) { - qdict_put((QDict *) opaque, name, qbool_from_bool(false)); + qdict_put(opaque, name, qbool_from_bool(false)); } static void qdict_add_enabled_feat(const char *name, void *opaque) { - qdict_put((QDict *) opaque, name, qbool_from_bool(true)); + qdict_put(opaque, name, qbool_from_bool(true)); } /* convert S390CPUDef into a static CpuModelInfo */ diff --git a/target/s390x/kvm.c b/target/s390x/kvm.c index ac47154b83..1a249d8359 100644 --- a/target/s390x/kvm.c +++ b/target/s390x/kvm.c @@ -47,16 +47,16 @@ #include "exec/memattrs.h" #include "hw/s390x/s390-virtio-ccw.h" -/* #define DEBUG_KVM */ - -#ifdef DEBUG_KVM -#define DPRINTF(fmt, ...) \ - do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0) -#else -#define DPRINTF(fmt, ...) \ - do { } while (0) +#ifndef DEBUG_KVM +#define DEBUG_KVM 0 #endif +#define DPRINTF(fmt, ...) do { \ + if (DEBUG_KVM) { \ + fprintf(stderr, fmt, ## __VA_ARGS__); \ + } \ +} while (0); + #define kvm_vm_check_mem_attr(s, attr) \ kvm_vm_check_attr(s, KVM_S390_VM_MEM_CTRL, attr) diff --git a/target/s390x/misc_helper.c b/target/s390x/misc_helper.c index 93b0e61366..eca82441d0 100644 --- a/target/s390x/misc_helper.c +++ b/target/s390x/misc_helper.c @@ -288,7 +288,9 @@ void HELPER(diag)(CPUS390XState *env, uint32_t r1, uint32_t r3, uint32_t num) switch (num) { case 0x500: /* KVM hypercall */ + qemu_mutex_lock_iothread(); r = s390_virtio_hypercall(env); + qemu_mutex_unlock_iothread(); break; case 0x44: /* yield */ @@ -515,7 +517,8 @@ uint32_t HELPER(sigp)(CPUS390XState *env, uint64_t order_code, uint32_t r1, /* Remember: Use "R1 or R1 + 1, whichever is the odd-numbered register" as parameter (input). Status (output) is always R1. */ - switch (order_code) { + /* sigp contains the order code in bit positions 56-63, mask it here. */ + switch (order_code & 0xff) { case SIGP_SET_ARCH: /* switch arch */ break; |