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