diff options
author | Michael Neuling <mikey@neuling.org> | 2008-06-25 00:07:18 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2008-06-30 21:28:50 -0400 |
commit | ce48b2100785e5ca629fb3aa8e3b50aca808f692 (patch) | |
tree | 63532ff7cc68b18ca4902bd10e03fcbaaf01cade /include/asm-powerpc | |
parent | 72ffff5b1792b0fa4d40a8e2f3276fff999820ec (diff) |
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.h | 6 | ||||
-rw-r--r-- | include/asm-powerpc/ptrace.h | 12 | ||||
-rw-r--r-- | include/asm-powerpc/reg.h | 2 | ||||
-rw-r--r-- | include/asm-powerpc/sigcontext.h | 37 | ||||
-rw-r--r-- | include/asm-powerpc/system.h | 9 |
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; | |||
109 | #ifdef __powerpc64__ | 109 | #ifdef __powerpc64__ |
110 | # define ELF_NVRREG32 33 /* includes vscr & vrsave stuffed together */ | 110 | # define ELF_NVRREG32 33 /* includes vscr & vrsave stuffed together */ |
111 | # define ELF_NVRREG 34 /* includes vscr & vrsave in split vectors */ | 111 | # define ELF_NVRREG 34 /* includes vscr & vrsave in split vectors */ |
112 | # define ELF_NVSRHALFREG 32 /* Half the vsx registers */ | ||
112 | # define ELF_GREG_TYPE elf_greg_t64 | 113 | # define ELF_GREG_TYPE elf_greg_t64 |
113 | #else | 114 | #else |
114 | # define ELF_NEVRREG 34 /* includes acc (as 2) */ | 115 | # define ELF_NEVRREG 34 /* includes acc (as 2) */ |
@@ -158,6 +159,7 @@ typedef __vector128 elf_vrreg_t; | |||
158 | typedef elf_vrreg_t elf_vrregset_t[ELF_NVRREG]; | 159 | typedef elf_vrreg_t elf_vrregset_t[ELF_NVRREG]; |
159 | #ifdef __powerpc64__ | 160 | #ifdef __powerpc64__ |
160 | typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32]; | 161 | typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32]; |
162 | typedef elf_fpreg_t elf_vsrreghalf_t32[ELF_NVSRHALFREG]; | ||
161 | #endif | 163 | #endif |
162 | 164 | ||
163 | #ifdef __KERNEL__ | 165 | #ifdef __KERNEL__ |
@@ -219,8 +221,8 @@ extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *); | |||
219 | typedef elf_vrregset_t elf_fpxregset_t; | 221 | typedef elf_vrregset_t elf_fpxregset_t; |
220 | 222 | ||
221 | #ifdef CONFIG_ALTIVEC | 223 | #ifdef CONFIG_ALTIVEC |
222 | extern int dump_task_altivec(struct task_struct *, elf_vrregset_t *vrregs); | 224 | extern int dump_task_vector(struct task_struct *, elf_vrregset_t *vrregs); |
223 | #define ELF_CORE_COPY_XFPREGS(tsk, regs) dump_task_altivec(tsk, regs) | 225 | #define ELF_CORE_COPY_XFPREGS(tsk, regs) dump_task_vector(tsk, regs) |
224 | #define ELF_CORE_XFPREG_TYPE NT_PPC_VMX | 226 | #define ELF_CORE_XFPREG_TYPE NT_PPC_VMX |
225 | #endif | 227 | #endif |
226 | 228 | ||
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 *); | |||
224 | #define PT_VRSAVE_32 (PT_VR0 + 33*4) | 224 | #define PT_VRSAVE_32 (PT_VR0 + 33*4) |
225 | #endif | 225 | #endif |
226 | 226 | ||
227 | /* | ||
228 | * Only store first 32 VSRs here. The second 32 VSRs in VR0-31 | ||
229 | */ | ||
230 | #define PT_VSR0 150 /* each VSR reg occupies 2 slots in 64-bit */ | ||
231 | #define PT_VSR31 (PT_VSR0 + 2*31) | ||
232 | #ifdef __KERNEL__ | ||
233 | #define PT_VSR0_32 300 /* each VSR reg occupies 4 slots in 32-bit */ | ||
234 | #endif | ||
227 | #endif /* __powerpc64__ */ | 235 | #endif /* __powerpc64__ */ |
228 | 236 | ||
229 | /* | 237 | /* |
@@ -246,6 +254,10 @@ extern void user_disable_single_step(struct task_struct *); | |||
246 | #define PTRACE_GETEVRREGS 20 | 254 | #define PTRACE_GETEVRREGS 20 |
247 | #define PTRACE_SETEVRREGS 21 | 255 | #define PTRACE_SETEVRREGS 21 |
248 | 256 | ||
257 | /* Get the first 32 128bit VSX registers */ | ||
258 | #define PTRACE_GETVSRREGS 27 | ||
259 | #define PTRACE_SETVSRREGS 28 | ||
260 | |||
249 | /* | 261 | /* |
250 | * Get or set a debug register. The first 16 are DABR registers and the | 262 | * Get or set a debug register. The first 16 are DABR registers and the |
251 | * second 16 are IABR registers. | 263 | * 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 @@ | |||
30 | #define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */ | 30 | #define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */ |
31 | #define MSR_HV_LG 60 /* Hypervisor state */ | 31 | #define MSR_HV_LG 60 /* Hypervisor state */ |
32 | #define MSR_VEC_LG 25 /* Enable AltiVec */ | 32 | #define MSR_VEC_LG 25 /* Enable AltiVec */ |
33 | #define MSR_VSX_LG 23 /* Enable VSX */ | ||
33 | #define MSR_POW_LG 18 /* Enable Power Management */ | 34 | #define MSR_POW_LG 18 /* Enable Power Management */ |
34 | #define MSR_WE_LG 18 /* Wait State Enable */ | 35 | #define MSR_WE_LG 18 /* Wait State Enable */ |
35 | #define MSR_TGPR_LG 17 /* TLB Update registers in use */ | 36 | #define MSR_TGPR_LG 17 /* TLB Update registers in use */ |
@@ -71,6 +72,7 @@ | |||
71 | #endif | 72 | #endif |
72 | 73 | ||
73 | #define MSR_VEC __MASK(MSR_VEC_LG) /* Enable AltiVec */ | 74 | #define MSR_VEC __MASK(MSR_VEC_LG) /* Enable AltiVec */ |
75 | #define MSR_VSX __MASK(MSR_VSX_LG) /* Enable VSX */ | ||
74 | #define MSR_POW __MASK(MSR_POW_LG) /* Enable Power Management */ | 76 | #define MSR_POW __MASK(MSR_POW_LG) /* Enable Power Management */ |
75 | #define MSR_WE __MASK(MSR_WE_LG) /* Wait State Enable */ | 77 | #define MSR_WE __MASK(MSR_WE_LG) /* Wait State Enable */ |
76 | #define MSR_TGPR __MASK(MSR_TGPR_LG) /* TLB Update registers in use */ | 78 | #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 { | |||
43 | * it must be copied via a vector register to/from storage) or as a word. | 43 | * it must be copied via a vector register to/from storage) or as a word. |
44 | * The entry with index 33 contains the vrsave as the first word (offset 0) | 44 | * The entry with index 33 contains the vrsave as the first word (offset 0) |
45 | * within the quadword. | 45 | * within the quadword. |
46 | * | ||
47 | * Part of the VSX data is stored here also by extending vmx_restore | ||
48 | * by an additional 32 double words. Architecturally the layout of | ||
49 | * the VSR registers and how they overlap on top of the legacy FPR and | ||
50 | * VR registers is shown below: | ||
51 | * | ||
52 | * VSR doubleword 0 VSR doubleword 1 | ||
53 | * ---------------------------------------------------------------- | ||
54 | * VSR[0] | FPR[0] | | | ||
55 | * ---------------------------------------------------------------- | ||
56 | * VSR[1] | FPR[1] | | | ||
57 | * ---------------------------------------------------------------- | ||
58 | * | ... | | | ||
59 | * | ... | | | ||
60 | * ---------------------------------------------------------------- | ||
61 | * VSR[30] | FPR[30] | | | ||
62 | * ---------------------------------------------------------------- | ||
63 | * VSR[31] | FPR[31] | | | ||
64 | * ---------------------------------------------------------------- | ||
65 | * VSR[32] | VR[0] | | ||
66 | * ---------------------------------------------------------------- | ||
67 | * VSR[33] | VR[1] | | ||
68 | * ---------------------------------------------------------------- | ||
69 | * | ... | | ||
70 | * | ... | | ||
71 | * ---------------------------------------------------------------- | ||
72 | * VSR[62] | VR[30] | | ||
73 | * ---------------------------------------------------------------- | ||
74 | * VSR[63] | VR[31] | | ||
75 | * ---------------------------------------------------------------- | ||
76 | * | ||
77 | * FPR/VSR 0-31 doubleword 0 is stored in fp_regs, and VMX/VSR 32-63 | ||
78 | * is stored at the start of vmx_reserve. vmx_reserve is extended for | ||
79 | * backwards compatility to store VSR 0-31 doubleword 1 after the VMX | ||
80 | * registers and vscr/vrsave. | ||
46 | */ | 81 | */ |
47 | elf_vrreg_t __user *v_regs; | 82 | elf_vrreg_t __user *v_regs; |
48 | long vmx_reserve[ELF_NVRREG+ELF_NVRREG+1]; | 83 | long vmx_reserve[ELF_NVRREG+ELF_NVRREG+32+1]; |
49 | #endif | 84 | #endif |
50 | }; | 85 | }; |
51 | 86 | ||
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); | |||
139 | extern void giveup_altivec(struct task_struct *); | 139 | extern void giveup_altivec(struct task_struct *); |
140 | extern void load_up_altivec(struct task_struct *); | 140 | extern void load_up_altivec(struct task_struct *); |
141 | extern int emulate_altivec(struct pt_regs *); | 141 | extern int emulate_altivec(struct pt_regs *); |
142 | extern void giveup_vsx(struct task_struct *); | ||
142 | extern void enable_kernel_spe(void); | 143 | extern void enable_kernel_spe(void); |
143 | extern void giveup_spe(struct task_struct *); | 144 | extern void giveup_spe(struct task_struct *); |
144 | extern void load_up_spe(struct task_struct *); | 145 | extern void load_up_spe(struct task_struct *); |
@@ -162,6 +163,14 @@ static inline void flush_altivec_to_thread(struct task_struct *t) | |||
162 | } | 163 | } |
163 | #endif | 164 | #endif |
164 | 165 | ||
166 | #ifdef CONFIG_VSX | ||
167 | extern void flush_vsx_to_thread(struct task_struct *); | ||
168 | #else | ||
169 | static inline void flush_vsx_to_thread(struct task_struct *t) | ||
170 | { | ||
171 | } | ||
172 | #endif | ||
173 | |||
165 | #ifdef CONFIG_SPE | 174 | #ifdef CONFIG_SPE |
166 | extern void flush_spe_to_thread(struct task_struct *); | 175 | extern void flush_spe_to_thread(struct task_struct *); |
167 | #else | 176 | #else |