aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
Diffstat (limited to 'target')
-rw-r--r--target/arm/cpu.c43
-rw-r--r--target/arm/cpu.h10
-rw-r--r--target/arm/helper.c19
-rw-r--r--target/arm/internals.h21
-rw-r--r--target/arm/kvm64.c4
-rw-r--r--target/arm/op_helper.c23
-rw-r--r--target/arm/translate.c181
-rw-r--r--target/arm/translate.h5
-rw-r--r--target/ppc/arch_dump.c2
-rw-r--r--target/ppc/cpu-qom.h1
-rw-r--r--target/ppc/cpu.h5
-rw-r--r--target/ppc/helper.h1
-rw-r--r--target/ppc/kvm.c152
-rw-r--r--target/ppc/kvm_ppc.h40
-rw-r--r--target/ppc/misc_helper.c8
-rw-r--r--target/ppc/translate_init.c410
-rw-r--r--target/s390x/cpu_models.c4
-rw-r--r--target/s390x/kvm.c16
-rw-r--r--target/s390x/misc_helper.c5
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;