Commit 98c45f51 authored by Paul Mackerras's avatar Paul Mackerras Committed by Michael Ellerman

selftests/powerpc/64: Test all paths through copy routines

The hand-coded assembler 64-bit copy routines include feature sections
that select one code path or another depending on which CPU we are
executing on.  The self-tests for these copy routines end up testing
just one path.  This adds a mechanism for selecting any desired code
path at compile time, and makes 2 or 3 versions of each test, each
using a different code path, so as to cover all the possible paths.
Signed-off-by: default avatarPaul Mackerras <paulus@ozlabs.org>
[mpe: Add -mcpu=power4 to CFLAGS for older compilers]
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent a7c81ce3
...@@ -12,6 +12,11 @@ ...@@ -12,6 +12,11 @@
#include <asm/asm-compat.h> #include <asm/asm-compat.h>
#include <asm/feature-fixups.h> #include <asm/feature-fixups.h>
#ifndef SELFTEST_CASE
/* 0 == most CPUs, 1 == POWER6, 2 == Cell */
#define SELFTEST_CASE 0
#endif
#ifdef __BIG_ENDIAN__ #ifdef __BIG_ENDIAN__
#define sLd sld /* Shift towards low-numbered address. */ #define sLd sld /* Shift towards low-numbered address. */
#define sHd srd /* Shift towards high-numbered address. */ #define sHd srd /* Shift towards high-numbered address. */
...@@ -73,6 +78,7 @@ _GLOBAL(__copy_tofrom_user_base) ...@@ -73,6 +78,7 @@ _GLOBAL(__copy_tofrom_user_base)
* At the time of writing the only CPU that has this combination of bits * At the time of writing the only CPU that has this combination of bits
* set is Power6. * set is Power6.
*/ */
test_feature = (SELFTEST_CASE == 1)
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
nop nop
FTR_SECTION_ELSE FTR_SECTION_ELSE
...@@ -82,6 +88,7 @@ ALT_FTR_SECTION_END(CPU_FTR_UNALIGNED_LD_STD | CPU_FTR_CP_USE_DCBTZ, \ ...@@ -82,6 +88,7 @@ ALT_FTR_SECTION_END(CPU_FTR_UNALIGNED_LD_STD | CPU_FTR_CP_USE_DCBTZ, \
.Ldst_aligned: .Ldst_aligned:
addi r3,r3,-16 addi r3,r3,-16
r3_offset = 16 r3_offset = 16
test_feature = (SELFTEST_CASE == 0)
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
andi. r0,r4,7 andi. r0,r4,7
bne .Lsrc_unaligned bne .Lsrc_unaligned
......
...@@ -19,6 +19,11 @@ ...@@ -19,6 +19,11 @@
*/ */
#include <asm/ppc_asm.h> #include <asm/ppc_asm.h>
#ifndef SELFTEST_CASE
/* 0 == don't use VMX, 1 == use VMX */
#define SELFTEST_CASE 0
#endif
#ifdef __BIG_ENDIAN__ #ifdef __BIG_ENDIAN__
#define LVS(VRT,RA,RB) lvsl VRT,RA,RB #define LVS(VRT,RA,RB) lvsl VRT,RA,RB
#define VPERM(VRT,VRA,VRB,VRC) vperm VRT,VRA,VRB,VRC #define VPERM(VRT,VRA,VRB,VRC) vperm VRT,VRA,VRB,VRC
...@@ -80,7 +85,6 @@ ...@@ -80,7 +85,6 @@
_GLOBAL(__copy_tofrom_user_power7) _GLOBAL(__copy_tofrom_user_power7)
#ifdef CONFIG_ALTIVEC
cmpldi r5,16 cmpldi r5,16
cmpldi cr1,r5,3328 cmpldi cr1,r5,3328
...@@ -89,15 +93,12 @@ _GLOBAL(__copy_tofrom_user_power7) ...@@ -89,15 +93,12 @@ _GLOBAL(__copy_tofrom_user_power7)
std r5,-STACKFRAMESIZE+STK_REG(R29)(r1) std r5,-STACKFRAMESIZE+STK_REG(R29)(r1)
blt .Lshort_copy blt .Lshort_copy
bge cr1,.Lvmx_copy
#else
cmpldi r5,16
std r3,-STACKFRAMESIZE+STK_REG(R31)(r1) #ifdef CONFIG_ALTIVEC
std r4,-STACKFRAMESIZE+STK_REG(R30)(r1) test_feature = SELFTEST_CASE
std r5,-STACKFRAMESIZE+STK_REG(R29)(r1) BEGIN_FTR_SECTION
bgt cr1,.Lvmx_copy
blt .Lshort_copy END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
#endif #endif
.Lnonvmx_copy: .Lnonvmx_copy:
...@@ -278,8 +279,8 @@ err1; stb r0,0(r3) ...@@ -278,8 +279,8 @@ err1; stb r0,0(r3)
addi r1,r1,STACKFRAMESIZE addi r1,r1,STACKFRAMESIZE
b .Lnonvmx_copy b .Lnonvmx_copy
#ifdef CONFIG_ALTIVEC
.Lvmx_copy: .Lvmx_copy:
#ifdef CONFIG_ALTIVEC
mflr r0 mflr r0
std r0,16(r1) std r0,16(r1)
stdu r1,-STACKFRAMESIZE(r1) stdu r1,-STACKFRAMESIZE(r1)
......
...@@ -12,6 +12,11 @@ ...@@ -12,6 +12,11 @@
#include <asm/asm-compat.h> #include <asm/asm-compat.h>
#include <asm/feature-fixups.h> #include <asm/feature-fixups.h>
#ifndef SELFTEST_CASE
/* For big-endian, 0 == most CPUs, 1 == POWER6, 2 == Cell */
#define SELFTEST_CASE 0
#endif
.align 7 .align 7
_GLOBAL_TOC(memcpy) _GLOBAL_TOC(memcpy)
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
...@@ -22,10 +27,8 @@ BEGIN_FTR_SECTION ...@@ -22,10 +27,8 @@ BEGIN_FTR_SECTION
#endif #endif
FTR_SECTION_ELSE FTR_SECTION_ELSE
#ifdef CONFIG_PPC_BOOK3S_64 #ifdef CONFIG_PPC_BOOK3S_64
#ifndef SELFTEST
b memcpy_power7 b memcpy_power7
#endif #endif
#endif
ALT_FTR_SECTION_END_IFCLR(CPU_FTR_VMX_COPY) ALT_FTR_SECTION_END_IFCLR(CPU_FTR_VMX_COPY)
#ifdef __LITTLE_ENDIAN__ #ifdef __LITTLE_ENDIAN__
/* dumb little-endian memcpy that will get replaced at runtime */ /* dumb little-endian memcpy that will get replaced at runtime */
...@@ -49,6 +52,7 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_VMX_COPY) ...@@ -49,6 +52,7 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_VMX_COPY)
cleared. cleared.
At the time of writing the only CPU that has this combination of bits At the time of writing the only CPU that has this combination of bits
set is Power6. */ set is Power6. */
test_feature = (SELFTEST_CASE == 1)
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
nop nop
FTR_SECTION_ELSE FTR_SECTION_ELSE
...@@ -57,6 +61,7 @@ ALT_FTR_SECTION_END(CPU_FTR_UNALIGNED_LD_STD | CPU_FTR_CP_USE_DCBTZ, \ ...@@ -57,6 +61,7 @@ ALT_FTR_SECTION_END(CPU_FTR_UNALIGNED_LD_STD | CPU_FTR_CP_USE_DCBTZ, \
CPU_FTR_UNALIGNED_LD_STD) CPU_FTR_UNALIGNED_LD_STD)
.Ldst_aligned: .Ldst_aligned:
addi r3,r3,-16 addi r3,r3,-16
test_feature = (SELFTEST_CASE == 0)
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
andi. r0,r4,7 andi. r0,r4,7
bne .Lsrc_unaligned bne .Lsrc_unaligned
......
...@@ -19,7 +19,10 @@ ...@@ -19,7 +19,10 @@
*/ */
#include <asm/ppc_asm.h> #include <asm/ppc_asm.h>
_GLOBAL(memcpy_power7) #ifndef SELFTEST_CASE
/* 0 == don't use VMX, 1 == use VMX */
#define SELFTEST_CASE 0
#endif
#ifdef __BIG_ENDIAN__ #ifdef __BIG_ENDIAN__
#define LVS(VRT,RA,RB) lvsl VRT,RA,RB #define LVS(VRT,RA,RB) lvsl VRT,RA,RB
...@@ -29,20 +32,17 @@ _GLOBAL(memcpy_power7) ...@@ -29,20 +32,17 @@ _GLOBAL(memcpy_power7)
#define VPERM(VRT,VRA,VRB,VRC) vperm VRT,VRB,VRA,VRC #define VPERM(VRT,VRA,VRB,VRC) vperm VRT,VRB,VRA,VRC
#endif #endif
#ifdef CONFIG_ALTIVEC _GLOBAL(memcpy_power7)
cmpldi r5,16 cmpldi r5,16
cmpldi cr1,r5,4096 cmpldi cr1,r5,4096
std r3,-STACKFRAMESIZE+STK_REG(R31)(r1) std r3,-STACKFRAMESIZE+STK_REG(R31)(r1)
blt .Lshort_copy blt .Lshort_copy
bgt cr1,.Lvmx_copy
#else
cmpldi r5,16
std r3,-STACKFRAMESIZE+STK_REG(R31)(r1)
blt .Lshort_copy #ifdef CONFIG_ALTIVEC
test_feature = SELFTEST_CASE
BEGIN_FTR_SECTION
bgt cr1, .Lvmx_copy
END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
#endif #endif
.Lnonvmx_copy: .Lnonvmx_copy:
...@@ -223,8 +223,8 @@ _GLOBAL(memcpy_power7) ...@@ -223,8 +223,8 @@ _GLOBAL(memcpy_power7)
addi r1,r1,STACKFRAMESIZE addi r1,r1,STACKFRAMESIZE
b .Lnonvmx_copy b .Lnonvmx_copy
#ifdef CONFIG_ALTIVEC
.Lvmx_copy: .Lvmx_copy:
#ifdef CONFIG_ALTIVEC
mflr r0 mflr r0
std r4,-STACKFRAMESIZE+STK_REG(R30)(r1) std r4,-STACKFRAMESIZE+STK_REG(R30)(r1)
std r5,-STACKFRAMESIZE+STK_REG(R29)(r1) std r5,-STACKFRAMESIZE+STK_REG(R29)(r1)
......
copyuser_64 copyuser_64_t0
copyuser_power7 copyuser_64_t1
memcpy_64 copyuser_64_t2
memcpy_power7 copyuser_power7_t0
copyuser_power7_t1
memcpy_64_t0
memcpy_64_t1
memcpy_64_t2
memcpy_power7_t0
memcpy_power7_t1
...@@ -4,18 +4,41 @@ CFLAGS += -m64 ...@@ -4,18 +4,41 @@ CFLAGS += -m64
CFLAGS += -I$(CURDIR) CFLAGS += -I$(CURDIR)
CFLAGS += -D SELFTEST CFLAGS += -D SELFTEST
CFLAGS += -maltivec CFLAGS += -maltivec
CFLAGS += -mcpu=power4
# Use our CFLAGS for the implicit .S rule & set the asm machine type # Use our CFLAGS for the implicit .S rule & set the asm machine type
ASFLAGS = $(CFLAGS) -Wa,-mpower4 ASFLAGS = $(CFLAGS) -Wa,-mpower4
TEST_GEN_PROGS := copyuser_64 copyuser_power7 memcpy_64 memcpy_power7 TEST_GEN_PROGS := copyuser_64_t0 copyuser_64_t1 copyuser_64_t2 \
copyuser_p7_t0 copyuser_p7_t1 \
memcpy_64_t0 memcpy_64_t1 memcpy_64_t2 \
memcpy_p7_t0 memcpy_p7_t1
EXTRA_SOURCES := validate.c ../harness.c EXTRA_SOURCES := validate.c ../harness.c
include ../../lib.mk include ../../lib.mk
$(OUTPUT)/copyuser_64: CPPFLAGS += -D COPY_LOOP=test___copy_tofrom_user_base $(OUTPUT)/copyuser_64_t%: copyuser_64.S $(EXTRA_SOURCES)
$(OUTPUT)/copyuser_power7: CPPFLAGS += -D COPY_LOOP=test___copy_tofrom_user_power7 $(CC) $(CPPFLAGS) $(CFLAGS) \
$(OUTPUT)/memcpy_64: CPPFLAGS += -D COPY_LOOP=test_memcpy -D COPY_LOOP=test___copy_tofrom_user_base \
$(OUTPUT)/memcpy_power7: CPPFLAGS += -D COPY_LOOP=test_memcpy_power7 -D SELFTEST_CASE=$(subst copyuser_64_t,,$(notdir $@)) \
-o $@ $^
$(OUTPUT)/copyuser_p7_t%: copyuser_power7.S $(EXTRA_SOURCES)
$(CC) $(CPPFLAGS) $(CFLAGS) \
-D COPY_LOOP=test___copy_tofrom_user_power7 \
-D SELFTEST_CASE=$(subst copyuser_p7_t,,$(notdir $@)) \
-o $@ $^
# Strictly speaking, we only need the memcpy_64 test cases for big-endian
$(OUTPUT)/memcpy_64_t%: memcpy_64.S $(EXTRA_SOURCES)
$(CC) $(CPPFLAGS) $(CFLAGS) \
-D COPY_LOOP=test_memcpy \
-D SELFTEST_CASE=$(subst memcpy_64_t,,$(notdir $@)) \
-o $@ $^
$(TEST_GEN_PROGS): $(EXTRA_SOURCES) $(OUTPUT)/memcpy_p7_t%: memcpy_power7.S $(EXTRA_SOURCES)
$(CC) $(CPPFLAGS) $(CFLAGS) \
-D COPY_LOOP=test_memcpy_power7 \
-D SELFTEST_CASE=$(subst memcpy_p7_t,,$(notdir $@)) \
-o $@ $^
...@@ -43,17 +43,16 @@ FUNC_START(enter_vmx_ops) ...@@ -43,17 +43,16 @@ FUNC_START(enter_vmx_ops)
FUNC_START(exit_vmx_ops) FUNC_START(exit_vmx_ops)
blr blr
FUNC_START(memcpy_power7)
blr
FUNC_START(__copy_tofrom_user_power7)
blr
FUNC_START(__copy_tofrom_user_base) FUNC_START(__copy_tofrom_user_base)
blr blr
#define BEGIN_FTR_SECTION #define BEGIN_FTR_SECTION .if test_feature
#define FTR_SECTION_ELSE #define FTR_SECTION_ELSE .else
#define ALT_FTR_SECTION_END_IFCLR(x) #define ALT_FTR_SECTION_END_IFCLR(x) .endif
#define ALT_FTR_SECTION_END(x, y) #define ALT_FTR_SECTION_END_IFSET(x) .endif
#define END_FTR_SECTION_IFCLR(x) #define ALT_FTR_SECTION_END(x, y) .endif
#define END_FTR_SECTION_IFCLR(x) .endif
#define END_FTR_SECTION_IFSET(x) .endif
/* Default to taking the first of any alternative feature sections */
test_feature = 1
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment