From ce48b2100785e5ca629fb3aa8e3b50aca808f692 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Wed, 25 Jun 2008 14:07:18 +1000 Subject: 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 Signed-off-by: Paul Mackerras --- include/asm-powerpc/elf.h | 6 ++++-- include/asm-powerpc/ptrace.h | 12 ++++++++++++ include/asm-powerpc/reg.h | 2 ++ include/asm-powerpc/sigcontext.h | 37 ++++++++++++++++++++++++++++++++++++- include/asm-powerpc/system.h | 9 +++++++++ 5 files changed, 63 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/asm-powerpc/elf.h b/include/asm-powerpc/elf.h index d1e3bda..746e53d 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 38d87e5..3d6e310 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 7256efb..bbccadf 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 165d630..9c1f24f 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 2642a92..0c12c66 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 -- cgit v1.1