aboutsummaryrefslogtreecommitdiff
path: root/target-ppc/misc_helper.c
diff options
context:
space:
mode:
authorAlexey Kardashevskiy <aik@ozlabs.ru>2014-06-04 22:50:56 +1000
committerAlexander Graf <agraf@suse.de>2014-06-16 13:24:44 +0200
commit7019cb3d883c5fdd8e4e75d753eded288d94b592 (patch)
tree866dc05ccd1fe023a1782ff6fb2bc0cad5f3a685 /target-ppc/misc_helper.c
parentd1a721ab816d1b954c0988aafdec4e109b953a9f (diff)
downloadqemu-arm-7019cb3d883c5fdd8e4e75d753eded288d94b592.tar.gz
target-ppc: Add POWER8's FSCR SPR
This adds an FSCR (Facility Status and Control Register) SPR. This defines names for FSCR bits. This defines new exception type - POWERPC_EXCP_FU - "facility unavailable" (FU). This registers an interrupt vector for it at 0xF60 as PowerISA defines. This adds a TCG helper_fscr_facility_check() helper to raise an exception if the facility is not enabled. It updates the interrupt cause field in FSCR. This adds a TCG translation block generation code. The helper may be used for HFSCR too as it has the same format. The helper raising FU exceptions is not used by this patch but will be in the next ones. This adds gen_update_current_nip() to update NIP in DisasContext. This helper is not used now and will be called before checking for a condition for throwing an FU exception. Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> Reviewed-by: Tom Musta <tommusta@gmail.com> Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'target-ppc/misc_helper.c')
-rw-r--r--target-ppc/misc_helper.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/target-ppc/misc_helper.c b/target-ppc/misc_helper.c
index 7331b1b240..554831faca 100644
--- a/target-ppc/misc_helper.c
+++ b/target-ppc/misc_helper.c
@@ -34,6 +34,33 @@ void helper_store_dump_spr(CPUPPCState *env, uint32_t sprn)
qemu_log("Write SPR %d %03x <= " TARGET_FMT_lx "\n", sprn, sprn,
env->spr[sprn]);
}
+
+#ifdef TARGET_PPC64
+static void raise_fu_exception(CPUPPCState *env, uint32_t bit,
+ uint32_t sprn, uint32_t cause)
+{
+ qemu_log("Facility SPR %d is unavailable (SPR FSCR:%d)\n", sprn, bit);
+
+ env->spr[SPR_FSCR] &= ~((target_ulong)FSCR_IC_MASK << FSCR_IC_POS);
+ cause &= FSCR_IC_MASK;
+ env->spr[SPR_FSCR] |= (target_ulong)cause << FSCR_IC_POS;
+
+ helper_raise_exception_err(env, POWERPC_EXCP_FU, 0);
+}
+#endif
+
+void helper_fscr_facility_check(CPUPPCState *env, uint32_t bit,
+ uint32_t sprn, uint32_t cause)
+{
+#ifdef TARGET_PPC64
+ if (env->spr[SPR_FSCR] & (1ULL << bit)) {
+ /* Facility is enabled, continue */
+ return;
+ }
+ raise_fu_exception(env, bit, sprn, cause);
+#endif
+}
+
#if !defined(CONFIG_USER_ONLY)
void helper_store_sdr1(CPUPPCState *env, target_ulong val)