1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#define _GNU_SOURCE
23
24#include <stdio.h>
25#include <unistd.h>
26#include <stdlib.h>
27#include "utils.h"
28#include <sched.h>
29
30#define READ_FD 0
31#define WRITE_FD 1
32
33#define NUM_LOOPS 1000
34
35
36#define PASTE(RA, RB, L, RC) \
37 .long (0x7c00070c | (RA) << (31-15) | (RB) << (31-20) | (L) << (31-10) | (RC) << (31-31))
38
39int paste(void *i)
40{
41 int cr;
42
43 asm volatile(str(PASTE(0, %1, 1, 1))";"
44 "mfcr %0;"
45 : "=r" (cr)
46 : "b" (i)
47 : "memory"
48 );
49 return cr;
50}
51
52
53#define COPY(RA, RB, L) \
54 .long (0x7c00060c | (RA) << (31-15) | (RB) << (31-20) | (L) << (31-10))
55
56void copy(void *i)
57{
58 asm volatile(str(COPY(0, %0, 1))";"
59 :
60 : "b" (i)
61 : "memory"
62 );
63}
64
65int test_cp_abort(void)
66{
67
68 char buf[128] __cacheline_aligned;
69 cpu_set_t cpuset;
70 int fd1[2], fd2[2], pid;
71 char c;
72
73
74 SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_00));
75
76
77
78
79
80 CPU_ZERO(&cpuset);
81 CPU_SET(pick_online_cpu(), &cpuset);
82 FAIL_IF(sched_setaffinity(0, sizeof(cpuset), &cpuset));
83
84 FAIL_IF(pipe(fd1) || pipe(fd2));
85
86 pid = fork();
87 FAIL_IF(pid < 0);
88
89 if (!pid) {
90 for (int i = 0; i < NUM_LOOPS; i++) {
91 FAIL_IF((write(fd1[WRITE_FD], &c, 1)) != 1);
92 FAIL_IF((read(fd2[READ_FD], &c, 1)) != 1);
93
94 FAIL_IF(paste(buf) & 0x20000000);
95 }
96 } else {
97 for (int i = 0; i < NUM_LOOPS; i++) {
98 FAIL_IF((read(fd1[READ_FD], &c, 1)) != 1);
99 copy(buf);
100 FAIL_IF((write(fd2[WRITE_FD], &c, 1) != 1));
101 }
102 }
103 return 0;
104
105}
106
107int main(int argc, char *argv[])
108{
109 return test_harness(test_cp_abort, "cp_abort");
110}
111