aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAnton Blanchard <anton@samba.org>2013-09-22 22:04:39 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-10-11 01:48:28 -0400
commit926f160f460170b0361f600f365369685ad74009 (patch)
tree04537aba608b597cbf3af3d8a774b4c09bd52924 /arch
parent87fec0514f613f8ac43c01b0bc0bc7072c5d10ae (diff)
powerpc: Little endian builds double word swap VSX state during context save/restore
The elements within VSX loads and stores are big endian ordered regardless of endianness. Our VSX context save/restore code uses lxvd2x and stxvd2x which is a 2x doubleword operation. This means the two doublewords will be swapped and we have to perform another swap to undo it. We need to do this on save and restore. Signed-off-by: Anton Blanchard <anton@samba.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/include/asm/ppc-opcode.h3
-rw-r--r--arch/powerpc/include/asm/ppc_asm.h21
2 files changed, 20 insertions, 4 deletions
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index d7fe9f5b46d4..ad5fcf51b252 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -181,6 +181,7 @@
181#define PPC_INST_TLBIVAX 0x7c000624 181#define PPC_INST_TLBIVAX 0x7c000624
182#define PPC_INST_TLBSRX_DOT 0x7c0006a5 182#define PPC_INST_TLBSRX_DOT 0x7c0006a5
183#define PPC_INST_XXLOR 0xf0000510 183#define PPC_INST_XXLOR 0xf0000510
184#define PPC_INST_XXSWAPD 0xf0000250
184#define PPC_INST_XVCPSGNDP 0xf0000780 185#define PPC_INST_XVCPSGNDP 0xf0000780
185#define PPC_INST_TRECHKPT 0x7c0007dd 186#define PPC_INST_TRECHKPT 0x7c0007dd
186#define PPC_INST_TRECLAIM 0x7c00075d 187#define PPC_INST_TRECLAIM 0x7c00075d
@@ -344,6 +345,8 @@
344 VSX_XX1((s), a, b)) 345 VSX_XX1((s), a, b))
345#define XXLOR(t, a, b) stringify_in_c(.long PPC_INST_XXLOR | \ 346#define XXLOR(t, a, b) stringify_in_c(.long PPC_INST_XXLOR | \
346 VSX_XX3((t), a, b)) 347 VSX_XX3((t), a, b))
348#define XXSWAPD(t, a) stringify_in_c(.long PPC_INST_XXSWAPD | \
349 VSX_XX3((t), a, a))
347#define XVCPSGNDP(t, a, b) stringify_in_c(.long (PPC_INST_XVCPSGNDP | \ 350#define XVCPSGNDP(t, a, b) stringify_in_c(.long (PPC_INST_XVCPSGNDP | \
348 VSX_XX3((t), (a), (b)))) 351 VSX_XX3((t), (a), (b))))
349 352
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index 599545738af3..0c51fb4fd2aa 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -180,9 +180,20 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)
180#define REST_32VRS_TRANSACT(n,b,base) REST_16VRS_TRANSACT(n,b,base); \ 180#define REST_32VRS_TRANSACT(n,b,base) REST_16VRS_TRANSACT(n,b,base); \
181 REST_16VRS_TRANSACT(n+16,b,base) 181 REST_16VRS_TRANSACT(n+16,b,base)
182 182
183#ifdef __BIG_ENDIAN__
184#define STXVD2X_ROT(n,b,base) STXVD2X(n,b,base)
185#define LXVD2X_ROT(n,b,base) LXVD2X(n,b,base)
186#else
187#define STXVD2X_ROT(n,b,base) XXSWAPD(n,n); \
188 STXVD2X(n,b,base); \
189 XXSWAPD(n,n)
190
191#define LXVD2X_ROT(n,b,base) LXVD2X(n,b,base); \
192 XXSWAPD(n,n)
193#endif
183 194
184#define SAVE_VSR_TRANSACT(n,b,base) li b,THREAD_TRANSACT_VSR0+(16*(n)); \ 195#define SAVE_VSR_TRANSACT(n,b,base) li b,THREAD_TRANSACT_VSR0+(16*(n)); \
185 STXVD2X(n,R##base,R##b) 196 STXVD2X_ROT(n,R##base,R##b)
186#define SAVE_2VSRS_TRANSACT(n,b,base) SAVE_VSR_TRANSACT(n,b,base); \ 197#define SAVE_2VSRS_TRANSACT(n,b,base) SAVE_VSR_TRANSACT(n,b,base); \
187 SAVE_VSR_TRANSACT(n+1,b,base) 198 SAVE_VSR_TRANSACT(n+1,b,base)
188#define SAVE_4VSRS_TRANSACT(n,b,base) SAVE_2VSRS_TRANSACT(n,b,base); \ 199#define SAVE_4VSRS_TRANSACT(n,b,base) SAVE_2VSRS_TRANSACT(n,b,base); \
@@ -195,7 +206,7 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)
195 SAVE_16VSRS_TRANSACT(n+16,b,base) 206 SAVE_16VSRS_TRANSACT(n+16,b,base)
196 207
197#define REST_VSR_TRANSACT(n,b,base) li b,THREAD_TRANSACT_VSR0+(16*(n)); \ 208#define REST_VSR_TRANSACT(n,b,base) li b,THREAD_TRANSACT_VSR0+(16*(n)); \
198 LXVD2X(n,R##base,R##b) 209 LXVD2X_ROT(n,R##base,R##b)
199#define REST_2VSRS_TRANSACT(n,b,base) REST_VSR_TRANSACT(n,b,base); \ 210#define REST_2VSRS_TRANSACT(n,b,base) REST_VSR_TRANSACT(n,b,base); \
200 REST_VSR_TRANSACT(n+1,b,base) 211 REST_VSR_TRANSACT(n+1,b,base)
201#define REST_4VSRS_TRANSACT(n,b,base) REST_2VSRS_TRANSACT(n,b,base); \ 212#define REST_4VSRS_TRANSACT(n,b,base) REST_2VSRS_TRANSACT(n,b,base); \
@@ -208,13 +219,15 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)
208 REST_16VSRS_TRANSACT(n+16,b,base) 219 REST_16VSRS_TRANSACT(n+16,b,base)
209 220
210/* Save the lower 32 VSRs in the thread VSR region */ 221/* Save the lower 32 VSRs in the thread VSR region */
211#define SAVE_VSR(n,b,base) li b,THREAD_VSR0+(16*(n)); STXVD2X(n,R##base,R##b) 222#define SAVE_VSR(n,b,base) li b,THREAD_VSR0+(16*(n)); \
223 STXVD2X_ROT(n,R##base,R##b)
212#define SAVE_2VSRS(n,b,base) SAVE_VSR(n,b,base); SAVE_VSR(n+1,b,base) 224#define SAVE_2VSRS(n,b,base) SAVE_VSR(n,b,base); SAVE_VSR(n+1,b,base)
213#define SAVE_4VSRS(n,b,base) SAVE_2VSRS(n,b,base); SAVE_2VSRS(n+2,b,base) 225#define SAVE_4VSRS(n,b,base) SAVE_2VSRS(n,b,base); SAVE_2VSRS(n+2,b,base)
214#define SAVE_8VSRS(n,b,base) SAVE_4VSRS(n,b,base); SAVE_4VSRS(n+4,b,base) 226#define SAVE_8VSRS(n,b,base) SAVE_4VSRS(n,b,base); SAVE_4VSRS(n+4,b,base)
215#define SAVE_16VSRS(n,b,base) SAVE_8VSRS(n,b,base); SAVE_8VSRS(n+8,b,base) 227#define SAVE_16VSRS(n,b,base) SAVE_8VSRS(n,b,base); SAVE_8VSRS(n+8,b,base)
216#define SAVE_32VSRS(n,b,base) SAVE_16VSRS(n,b,base); SAVE_16VSRS(n+16,b,base) 228#define SAVE_32VSRS(n,b,base) SAVE_16VSRS(n,b,base); SAVE_16VSRS(n+16,b,base)
217#define REST_VSR(n,b,base) li b,THREAD_VSR0+(16*(n)); LXVD2X(n,R##base,R##b) 229#define REST_VSR(n,b,base) li b,THREAD_VSR0+(16*(n)); \
230 LXVD2X_ROT(n,R##base,R##b)
218#define REST_2VSRS(n,b,base) REST_VSR(n,b,base); REST_VSR(n+1,b,base) 231#define REST_2VSRS(n,b,base) REST_VSR(n,b,base); REST_VSR(n+1,b,base)
219#define REST_4VSRS(n,b,base) REST_2VSRS(n,b,base); REST_2VSRS(n+2,b,base) 232#define REST_4VSRS(n,b,base) REST_2VSRS(n,b,base); REST_2VSRS(n+2,b,base)
220#define REST_8VSRS(n,b,base) REST_4VSRS(n,b,base); REST_4VSRS(n+4,b,base) 233#define REST_8VSRS(n,b,base) REST_4VSRS(n,b,base); REST_4VSRS(n+4,b,base)