summaryrefslogtreecommitdiffstats
path: root/include/asm-powerpc
diff options
context:
space:
mode:
authorMichael Neuling <mikey@neuling.org>2008-06-25 14:07:18 +1000
committerPaul Mackerras <paulus@samba.org>2008-07-01 11:28:50 +1000
commitce48b2100785e5ca629fb3aa8e3b50aca808f692 (patch)
tree63532ff7cc68b18ca4902bd10e03fcbaaf01cade /include/asm-powerpc
parent72ffff5b1792b0fa4d40a8e2f3276fff999820ec (diff)
downloadlinux-ce48b2100785e5ca629fb3aa8e3b50aca808f692.tar.gz
linux-ce48b2100785e5ca629fb3aa8e3b50aca808f692.tar.bz2
linux-ce48b2100785e5ca629fb3aa8e3b50aca808f692.zip
powerpc: Add VSX context save/restore, ptrace and signal support
This patch extends the floating point save and restore code to use the VSX load/stores when VSX is available. This will make FP context save/restore marginally slower on FP only code, when VSX is available, as it has to load/store 128bits rather than just 64bits. Mixing FP, VMX and VSX code will get constant architected state. The signals interface is extended to enable access to VSR 0-31 doubleword 1 after discussions with tool chain maintainers. Backward compatibility is maintained. The ptrace interface is also extended to allow access to VSR 0-31 full registers. Signed-off-by: Michael Neuling <mikey@neuling.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'include/asm-powerpc')
-rw-r--r--include/asm-powerpc/elf.h6
-rw-r--r--include/asm-powerpc/ptrace.h12
-rw-r--r--include/asm-powerpc/reg.h2
-rw-r--r--include/asm-powerpc/sigcontext.h37
-rw-r--r--include/asm-powerpc/system.h9
5 files changed, 63 insertions, 3 deletions
diff --git a/include/asm-powerpc/elf.h b/include/asm-powerpc/elf.h
index d1e3bda0625d..746e53d60cbe 100644
--- a/include/asm-powerpc/elf.h
+++ b/include/asm-powerpc/elf.h
@@ -109,6 +109,7 @@ typedef elf_gregset_t32 compat_elf_gregset_t;
#ifdef __powerpc64__
# define ELF_NVRREG32 33 /* includes vscr & vrsave stuffed together */
# define ELF_NVRREG 34 /* includes vscr & vrsave in split vectors */
+# define ELF_NVSRHALFREG 32 /* Half the vsx registers */
# define ELF_GREG_TYPE elf_greg_t64
#else
# define ELF_NEVRREG 34 /* includes acc (as 2) */
@@ -158,6 +159,7 @@ typedef __vector128 elf_vrreg_t;
typedef elf_vrreg_t elf_vrregset_t[ELF_NVRREG];
#ifdef __powerpc64__
typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
+typedef elf_fpreg_t elf_vsrreghalf_t32[ELF_NVSRHALFREG];
#endif
#ifdef __KERNEL__
@@ -219,8 +221,8 @@ extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *);
typedef elf_vrregset_t elf_fpxregset_t;
#ifdef CONFIG_ALTIVEC
-extern int dump_task_altivec(struct task_struct *, elf_vrregset_t *vrregs);
-#define ELF_CORE_COPY_XFPREGS(tsk, regs) dump_task_altivec(tsk, regs)
+extern int dump_task_vector(struct task_struct *, elf_vrregset_t *vrregs);
+#define ELF_CORE_COPY_XFPREGS(tsk, regs) dump_task_vector(tsk, regs)
#define ELF_CORE_XFPREG_TYPE NT_PPC_VMX
#endif
diff --git a/include/asm-powerpc/ptrace.h b/include/asm-powerpc/ptrace.h
index 38d87e5e569d..3d6e31024e56 100644
--- a/include/asm-powerpc/ptrace.h
+++ b/include/asm-powerpc/ptrace.h
@@ -224,6 +224,14 @@ extern void user_disable_single_step(struct task_struct *);
#define PT_VRSAVE_32 (PT_VR0 + 33*4)
#endif
+/*
+ * Only store first 32 VSRs here. The second 32 VSRs in VR0-31
+ */
+#define PT_VSR0 150 /* each VSR reg occupies 2 slots in 64-bit */
+#define PT_VSR31 (PT_VSR0 + 2*31)
+#ifdef __KERNEL__
+#define PT_VSR0_32 300 /* each VSR reg occupies 4 slots in 32-bit */
+#endif
#endif /* __powerpc64__ */
/*
@@ -246,6 +254,10 @@ extern void user_disable_single_step(struct task_struct *);
#define PTRACE_GETEVRREGS 20
#define PTRACE_SETEVRREGS 21
+/* Get the first 32 128bit VSX registers */
+#define PTRACE_GETVSRREGS 27
+#define PTRACE_SETVSRREGS 28
+
/*
* Get or set a debug register. The first 16 are DABR registers and the
* second 16 are IABR registers.
diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h
index 7256efb5c140..bbccadfee0d6 100644
--- a/include/asm-powerpc/reg.h
+++ b/include/asm-powerpc/reg.h
@@ -30,6 +30,7 @@
#define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */
#define MSR_HV_LG 60 /* Hypervisor state */
#define MSR_VEC_LG 25 /* Enable AltiVec */
+#define MSR_VSX_LG 23 /* Enable VSX */
#define MSR_POW_LG 18 /* Enable Power Management */
#define MSR_WE_LG 18 /* Wait State Enable */
#define MSR_TGPR_LG 17 /* TLB Update registers in use */
@@ -71,6 +72,7 @@
#endif
#define MSR_VEC __MASK(MSR_VEC_LG) /* Enable AltiVec */
+#define MSR_VSX __MASK(MSR_VSX_LG) /* Enable VSX */
#define MSR_POW __MASK(MSR_POW_LG) /* Enable Power Management */
#define MSR_WE __MASK(MSR_WE_LG) /* Wait State Enable */
#define MSR_TGPR __MASK(MSR_TGPR_LG) /* TLB Update registers in use */
diff --git a/include/asm-powerpc/sigcontext.h b/include/asm-powerpc/sigcontext.h
index 165d630e1cf3..9c1f24fd5d11 100644
--- a/include/asm-powerpc/sigcontext.h
+++ b/include/asm-powerpc/sigcontext.h
@@ -43,9 +43,44 @@ struct sigcontext {
* it must be copied via a vector register to/from storage) or as a word.
* The entry with index 33 contains the vrsave as the first word (offset 0)
* within the quadword.
+ *
+ * Part of the VSX data is stored here also by extending vmx_restore
+ * by an additional 32 double words. Architecturally the layout of
+ * the VSR registers and how they overlap on top of the legacy FPR and
+ * VR registers is shown below:
+ *
+ * VSR doubleword 0 VSR doubleword 1
+ * ----------------------------------------------------------------
+ * VSR[0] | FPR[0] | |
+ * ----------------------------------------------------------------
+ * VSR[1] | FPR[1] | |
+ * ----------------------------------------------------------------
+ * | ... | |
+ * | ... | |
+ * ----------------------------------------------------------------
+ * VSR[30] | FPR[30] | |
+ * ----------------------------------------------------------------
+ * VSR[31] | FPR[31] | |
+ * ----------------------------------------------------------------
+ * VSR[32] | VR[0] |
+ * ----------------------------------------------------------------
+ * VSR[33] | VR[1] |
+ * ----------------------------------------------------------------
+ * | ... |
+ * | ... |
+ * ----------------------------------------------------------------
+ * VSR[62] | VR[30] |
+ * ----------------------------------------------------------------
+ * VSR[63] | VR[31] |
+ * ----------------------------------------------------------------
+ *
+ * FPR/VSR 0-31 doubleword 0 is stored in fp_regs, and VMX/VSR 32-63
+ * is stored at the start of vmx_reserve. vmx_reserve is extended for
+ * backwards compatility to store VSR 0-31 doubleword 1 after the VMX
+ * registers and vscr/vrsave.
*/
elf_vrreg_t __user *v_regs;
- long vmx_reserve[ELF_NVRREG+ELF_NVRREG+1];
+ long vmx_reserve[ELF_NVRREG+ELF_NVRREG+32+1];
#endif
};
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index 2642a92b724f..0c12c66733f6 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -139,6 +139,7 @@ extern void enable_kernel_altivec(void);
extern void giveup_altivec(struct task_struct *);
extern void load_up_altivec(struct task_struct *);
extern int emulate_altivec(struct pt_regs *);
+extern void giveup_vsx(struct task_struct *);
extern void enable_kernel_spe(void);
extern void giveup_spe(struct task_struct *);
extern void load_up_spe(struct task_struct *);
@@ -162,6 +163,14 @@ static inline void flush_altivec_to_thread(struct task_struct *t)
}
#endif
+#ifdef CONFIG_VSX
+extern void flush_vsx_to_thread(struct task_struct *);
+#else
+static inline void flush_vsx_to_thread(struct task_struct *t)
+{
+}
+#endif
+
#ifdef CONFIG_SPE
extern void flush_spe_to_thread(struct task_struct *);
#else