]>
Commit | Line | Data |
---|---|---|
2874c5fd | 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
01127f1e CB |
2 | /* |
3 | * Copyright 2015, Cyril Bur, IBM Corp. | |
01127f1e CB |
4 | */ |
5 | ||
15ec3997 SG |
6 | #include "basic_asm.h" |
7 | #include "vmx_asm.h" | |
01127f1e CB |
8 | |
9 | # Should be safe from C, only touches r4, r5 and v0,v1,v2 | |
10 | FUNC_START(check_vmx) | |
e5ab8be6 | 11 | PUSH_BASIC_STACK(32) |
01127f1e CB |
12 | mr r4,r3 |
13 | li r3,1 # assume a bad result | |
14 | li r5,0 | |
15 | lvx v0,r5,r4 | |
16 | vcmpequd. v1,v0,v20 | |
17 | vmr v2,v1 | |
18 | ||
19 | addi r5,r5,16 | |
20 | lvx v0,r5,r4 | |
21 | vcmpequd. v1,v0,v21 | |
22 | vand v2,v2,v1 | |
23 | ||
24 | addi r5,r5,16 | |
25 | lvx v0,r5,r4 | |
26 | vcmpequd. v1,v0,v22 | |
27 | vand v2,v2,v1 | |
28 | ||
29 | addi r5,r5,16 | |
30 | lvx v0,r5,r4 | |
31 | vcmpequd. v1,v0,v23 | |
32 | vand v2,v2,v1 | |
33 | ||
34 | addi r5,r5,16 | |
35 | lvx v0,r5,r4 | |
36 | vcmpequd. v1,v0,v24 | |
37 | vand v2,v2,v1 | |
38 | ||
39 | addi r5,r5,16 | |
40 | lvx v0,r5,r4 | |
41 | vcmpequd. v1,v0,v25 | |
42 | vand v2,v2,v1 | |
43 | ||
44 | addi r5,r5,16 | |
45 | lvx v0,r5,r4 | |
46 | vcmpequd. v1,v0,v26 | |
47 | vand v2,v2,v1 | |
48 | ||
49 | addi r5,r5,16 | |
50 | lvx v0,r5,r4 | |
51 | vcmpequd. v1,v0,v27 | |
52 | vand v2,v2,v1 | |
53 | ||
54 | addi r5,r5,16 | |
55 | lvx v0,r5,r4 | |
56 | vcmpequd. v1,v0,v28 | |
57 | vand v2,v2,v1 | |
58 | ||
59 | addi r5,r5,16 | |
60 | lvx v0,r5,r4 | |
61 | vcmpequd. v1,v0,v29 | |
62 | vand v2,v2,v1 | |
63 | ||
64 | addi r5,r5,16 | |
65 | lvx v0,r5,r4 | |
66 | vcmpequd. v1,v0,v30 | |
67 | vand v2,v2,v1 | |
68 | ||
69 | addi r5,r5,16 | |
70 | lvx v0,r5,r4 | |
71 | vcmpequd. v1,v0,v31 | |
72 | vand v2,v2,v1 | |
73 | ||
74 | li r5,STACK_FRAME_LOCAL(0,0) | |
75 | stvx v2,r5,sp | |
76 | ldx r0,r5,sp | |
77 | cmpdi r0,0xffffffffffffffff | |
78 | bne 1f | |
79 | li r3,0 | |
e5ab8be6 | 80 | 1: POP_BASIC_STACK(32) |
01127f1e CB |
81 | blr |
82 | FUNC_END(check_vmx) | |
83 | ||
84 | # Safe from C | |
85 | FUNC_START(test_vmx) | |
86 | # r3 holds pointer to where to put the result of fork | |
87 | # r4 holds pointer to the pid | |
88 | # v20-v31 are non-volatile | |
89 | PUSH_BASIC_STACK(512) | |
90 | std r3,STACK_FRAME_PARAM(0)(sp) # Address of varray | |
91 | std r4,STACK_FRAME_PARAM(1)(sp) # address of pid | |
92 | PUSH_VMX(STACK_FRAME_LOCAL(2,0),r4) | |
93 | ||
94 | bl load_vmx | |
95 | nop | |
96 | ||
97 | li r0,__NR_fork | |
98 | sc | |
99 | # Pass the result of fork back to the caller | |
100 | ld r9,STACK_FRAME_PARAM(1)(sp) | |
101 | std r3,0(r9) | |
102 | ||
103 | ld r3,STACK_FRAME_PARAM(0)(sp) | |
104 | bl check_vmx | |
105 | nop | |
106 | ||
107 | POP_VMX(STACK_FRAME_LOCAL(2,0),r4) | |
108 | POP_BASIC_STACK(512) | |
109 | blr | |
110 | FUNC_END(test_vmx) | |
e5ab8be6 CB |
111 | |
112 | # int preempt_vmx(vector int *varray, int *threads_starting, int *running) | |
113 | # On starting will (atomically) decrement threads_starting as a signal that | |
114 | # the VMX have been loaded with varray. Will proceed to check the validity of | |
115 | # the VMX registers while running is not zero. | |
116 | FUNC_START(preempt_vmx) | |
117 | PUSH_BASIC_STACK(512) | |
118 | std r3,STACK_FRAME_PARAM(0)(sp) # vector int *varray | |
119 | std r4,STACK_FRAME_PARAM(1)(sp) # int *threads_starting | |
120 | std r5,STACK_FRAME_PARAM(2)(sp) # int *running | |
121 | # VMX need to write to 16 byte aligned addresses, skip STACK_FRAME_LOCAL(3,0) | |
122 | PUSH_VMX(STACK_FRAME_LOCAL(4,0),r4) | |
123 | ||
124 | bl load_vmx | |
125 | nop | |
126 | ||
127 | sync | |
128 | # Atomic DEC | |
129 | ld r3,STACK_FRAME_PARAM(1)(sp) | |
130 | 1: lwarx r4,0,r3 | |
131 | addi r4,r4,-1 | |
132 | stwcx. r4,0,r3 | |
133 | bne- 1b | |
134 | ||
135 | 2: ld r3,STACK_FRAME_PARAM(0)(sp) | |
136 | bl check_vmx | |
137 | nop | |
138 | cmpdi r3,0 | |
139 | bne 3f | |
140 | ld r4,STACK_FRAME_PARAM(2)(sp) | |
141 | ld r5,0(r4) | |
142 | cmpwi r5,0 | |
143 | bne 2b | |
144 | ||
145 | 3: POP_VMX(STACK_FRAME_LOCAL(4,0),r4) | |
146 | POP_BASIC_STACK(512) | |
147 | blr | |
148 | FUNC_END(preempt_vmx) |