aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorMichael Ellerman <mpe@ellerman.id.au>2015-03-28 06:35:17 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2015-03-28 07:08:47 -0400
commit4cd968ef4249fde24194b7b9a74be87dd7f8ed0f (patch)
tree1c749db1558db4e3d0c646c5f760ed828cbd8b86 /tools
parent529d235a0e190ded1d21ccc80a73e625ebcad09b (diff)
selftests/powerpc: Add a test of the switch_endian() syscall
This adds a test of the switch_endian() syscall we added in the previous commit. We test it by calling the endian switch syscall, and then executing some code in the other endian to check everything went as expected. That code checks registers we expect to be maintained are. If the endian switch failed to happen that code sequence will be illegal and cause the test to abort. We then switch back to the original endian, do the same checks and finally write a success message and exit(0). Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'tools')
-rw-r--r--tools/testing/selftests/powerpc/Makefile2
-rw-r--r--tools/testing/selftests/powerpc/switch_endian/.gitignore2
-rw-r--r--tools/testing/selftests/powerpc/switch_endian/Makefile24
-rw-r--r--tools/testing/selftests/powerpc/switch_endian/check.S100
-rw-r--r--tools/testing/selftests/powerpc/switch_endian/common.h6
-rw-r--r--tools/testing/selftests/powerpc/switch_endian/switch_endian_test.S81
6 files changed, 214 insertions, 1 deletions
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile
index 27dff8241de3..a5d5be7ec4c7 100644
--- a/tools/testing/selftests/powerpc/Makefile
+++ b/tools/testing/selftests/powerpc/Makefile
@@ -13,7 +13,7 @@ CFLAGS := -Wall -O2 -flto -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CUR
13 13
14export CC CFLAGS 14export CC CFLAGS
15 15
16SUB_DIRS = pmu copyloops mm tm primitives stringloops vphn 16SUB_DIRS = pmu copyloops mm tm primitives stringloops vphn switch_endian
17 17
18endif 18endif
19 19
diff --git a/tools/testing/selftests/powerpc/switch_endian/.gitignore b/tools/testing/selftests/powerpc/switch_endian/.gitignore
new file mode 100644
index 000000000000..89e762eab676
--- /dev/null
+++ b/tools/testing/selftests/powerpc/switch_endian/.gitignore
@@ -0,0 +1,2 @@
1switch_endian_test
2check-reversed.S
diff --git a/tools/testing/selftests/powerpc/switch_endian/Makefile b/tools/testing/selftests/powerpc/switch_endian/Makefile
new file mode 100644
index 000000000000..081473db22b7
--- /dev/null
+++ b/tools/testing/selftests/powerpc/switch_endian/Makefile
@@ -0,0 +1,24 @@
1CC := $(CROSS_COMPILE)gcc
2PROGS := switch_endian_test
3
4ASFLAGS += -O2 -Wall -g -nostdlib -m64
5
6all: $(PROGS)
7
8switch_endian_test: check-reversed.S
9
10check-reversed.o: check.o
11 $(CROSS_COMPILE)objcopy -j .text --reverse-bytes=4 -O binary $< $@
12
13check-reversed.S: check-reversed.o
14 hexdump -v -e '/1 ".byte 0x%02X\n"' $< > $@
15
16run_tests: all
17 @-for PROG in $(PROGS); do \
18 ./$$PROG; \
19 done;
20
21clean:
22 rm -f $(PROGS) *.o check-reversed.S
23
24.PHONY: all run_tests clean
diff --git a/tools/testing/selftests/powerpc/switch_endian/check.S b/tools/testing/selftests/powerpc/switch_endian/check.S
new file mode 100644
index 000000000000..e2484d2c24f4
--- /dev/null
+++ b/tools/testing/selftests/powerpc/switch_endian/check.S
@@ -0,0 +1,100 @@
1#include "common.h"
2
3/*
4 * Checks that registers contain what we expect, ie. they were not clobbered by
5 * the syscall.
6 *
7 * r15: pattern to check registers against.
8 *
9 * At the end r3 == 0 if everything's OK.
10 */
11 nop # guaranteed to be illegal in reverse-endian
12 mr r9,r15
13 cmpd r9,r3 # check r3
14 bne 1f
15 addi r9,r15,4 # check r4
16 cmpd r9,r4
17 bne 1f
18 lis r9,0x00FF # check CR
19 ori r9,r9,0xF000
20 mfcr r10
21 and r10,r10,r9
22 cmpw r9,r10
23 addi r9,r15,34
24 bne 1f
25 addi r9,r15,32 # check LR
26 mflr r10
27 cmpd r9,r10
28 bne 1f
29 addi r9,r15,5 # check r5
30 cmpd r9,r5
31 bne 1f
32 addi r9,r15,6 # check r6
33 cmpd r9,r6
34 bne 1f
35 addi r9,r15,7 # check r7
36 cmpd r9,r7
37 bne 1f
38 addi r9,r15,8 # check r8
39 cmpd r9,r8
40 bne 1f
41 addi r9,r15,13 # check r13
42 cmpd r9,r13
43 bne 1f
44 addi r9,r15,14 # check r14
45 cmpd r9,r14
46 bne 1f
47 addi r9,r15,16 # check r16
48 cmpd r9,r16
49 bne 1f
50 addi r9,r15,17 # check r17
51 cmpd r9,r17
52 bne 1f
53 addi r9,r15,18 # check r18
54 cmpd r9,r18
55 bne 1f
56 addi r9,r15,19 # check r19
57 cmpd r9,r19
58 bne 1f
59 addi r9,r15,20 # check r20
60 cmpd r9,r20
61 bne 1f
62 addi r9,r15,21 # check r21
63 cmpd r9,r21
64 bne 1f
65 addi r9,r15,22 # check r22
66 cmpd r9,r22
67 bne 1f
68 addi r9,r15,23 # check r23
69 cmpd r9,r23
70 bne 1f
71 addi r9,r15,24 # check r24
72 cmpd r9,r24
73 bne 1f
74 addi r9,r15,25 # check r25
75 cmpd r9,r25
76 bne 1f
77 addi r9,r15,26 # check r26
78 cmpd r9,r26
79 bne 1f
80 addi r9,r15,27 # check r27
81 cmpd r9,r27
82 bne 1f
83 addi r9,r15,28 # check r28
84 cmpd r9,r28
85 bne 1f
86 addi r9,r15,29 # check r29
87 cmpd r9,r29
88 bne 1f
89 addi r9,r15,30 # check r30
90 cmpd r9,r30
91 bne 1f
92 addi r9,r15,31 # check r31
93 cmpd r9,r31
94 bne 1f
95 b 2f
961: mr r3, r9
97 li r0, __NR_exit
98 sc
992: li r0, __NR_switch_endian
100 nop
diff --git a/tools/testing/selftests/powerpc/switch_endian/common.h b/tools/testing/selftests/powerpc/switch_endian/common.h
new file mode 100644
index 000000000000..69e399698c64
--- /dev/null
+++ b/tools/testing/selftests/powerpc/switch_endian/common.h
@@ -0,0 +1,6 @@
1#include <ppc-asm.h>
2#include <asm/unistd.h>
3
4#ifndef __NR_switch_endian
5#define __NR_switch_endian 363
6#endif
diff --git a/tools/testing/selftests/powerpc/switch_endian/switch_endian_test.S b/tools/testing/selftests/powerpc/switch_endian/switch_endian_test.S
new file mode 100644
index 000000000000..ef7c971abb67
--- /dev/null
+++ b/tools/testing/selftests/powerpc/switch_endian/switch_endian_test.S
@@ -0,0 +1,81 @@
1#include "common.h"
2
3 .data
4 .balign 8
5message:
6 .ascii "success: switch_endian_test\n\0"
7
8 .section ".toc"
9 .balign 8
10pattern:
11 .llong 0x5555AAAA5555AAAA
12
13 .text
14FUNC_START(_start)
15 /* Load the pattern */
16 ld r15, pattern@TOC(%r2)
17
18 /* Setup CR, only CR2-CR4 are maintained */
19 lis r3, 0x00FF
20 ori r3, r3, 0xF000
21 mtcr r3
22
23 /* Load the pattern slightly modified into the registers */
24 mr r3, r15
25 addi r4, r15, 4
26
27 addi r5, r15, 32
28 mtlr r5
29
30 addi r5, r15, 5
31 addi r6, r15, 6
32 addi r7, r15, 7
33 addi r8, r15, 8
34
35 /* r9 - r12 are clobbered */
36
37 addi r13, r15, 13
38 addi r14, r15, 14
39
40 /* Skip r15 we're using it */
41
42 addi r16, r15, 16
43 addi r17, r15, 17
44 addi r18, r15, 18
45 addi r19, r15, 19
46 addi r20, r15, 20
47 addi r21, r15, 21
48 addi r22, r15, 22
49 addi r23, r15, 23
50 addi r24, r15, 24
51 addi r25, r15, 25
52 addi r26, r15, 26
53 addi r27, r15, 27
54 addi r28, r15, 28
55 addi r29, r15, 29
56 addi r30, r15, 30
57 addi r31, r15, 31
58
59 /*
60 * Call the syscall to switch endian.
61 * It clobbers r9-r12, XER, CTR and CR0-1,5-7.
62 */
63 li r0, __NR_switch_endian
64 sc
65
66#include "check-reversed.S"
67
68 /* Flip back, r0 already has the switch syscall number */
69 .long 0x02000044 /* sc */
70
71#include "check.S"
72
73 li r0, __NR_write
74 li r3, 1 /* stdout */
75 ld r4, message@got(%r2)
76 li r5, 28 /* strlen(message3) */
77 sc
78 li r0, __NR_exit
79 li r3, 0
80 sc
81 b .