1// Copyright 2020 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5//go:build zos && s390x && gc
6// +build zos
7// +build s390x
8// +build gc
9
10#include "textflag.h"
11
12#define PSALAA            1208(R0)
13#define GTAB64(x)           80(x)
14#define LCA64(x)            88(x)
15#define CAA(x)               8(x)
16#define EDCHPXV(x)        1016(x)       // in the CAA
17#define SAVSTACK_ASYNC(x)  336(x)       // in the LCA
18
19// SS_*, where x=SAVSTACK_ASYNC
20#define SS_LE(x)             0(x)
21#define SS_GO(x)             8(x)
22#define SS_ERRNO(x)         16(x)
23#define SS_ERRNOJR(x)       20(x)
24
25#define LE_CALL BYTE $0x0D; BYTE $0x76; // BL R7, R6
26
27TEXT ·clearErrno(SB),NOSPLIT,$0-0
28	BL	addrerrno<>(SB)
29	MOVD	$0, 0(R3)
30	RET
31
32// Returns the address of errno in R3.
33TEXT addrerrno<>(SB),NOSPLIT|NOFRAME,$0-0
34	// Get library control area (LCA).
35	MOVW	PSALAA, R8
36	MOVD	LCA64(R8), R8
37
38	// Get __errno FuncDesc.
39	MOVD	CAA(R8), R9
40	MOVD	EDCHPXV(R9), R9
41	ADD	$(0x156*16), R9
42	LMG	0(R9), R5, R6
43
44	// Switch to saved LE stack.
45	MOVD	SAVSTACK_ASYNC(R8), R9
46	MOVD	0(R9), R4
47	MOVD	$0, 0(R9)
48
49	// Call __errno function.
50	LE_CALL
51	NOPH
52
53	// Switch back to Go stack.
54	XOR	R0, R0      // Restore R0 to $0.
55	MOVD	R4, 0(R9)   // Save stack pointer.
56	RET
57
58TEXT ·syscall_syscall(SB),NOSPLIT,$0-56
59	BL	runtime·entersyscall(SB)
60	MOVD	a1+8(FP), R1
61	MOVD	a2+16(FP), R2
62	MOVD	a3+24(FP), R3
63
64	// Get library control area (LCA).
65	MOVW	PSALAA, R8
66	MOVD	LCA64(R8), R8
67
68	// Get function.
69	MOVD	CAA(R8), R9
70	MOVD	EDCHPXV(R9), R9
71	MOVD	trap+0(FP), R5
72	SLD	$4, R5
73	ADD	R5, R9
74	LMG	0(R9), R5, R6
75
76	// Restore LE stack.
77	MOVD	SAVSTACK_ASYNC(R8), R9
78	MOVD	0(R9), R4
79	MOVD	$0, 0(R9)
80
81	// Call function.
82	LE_CALL
83	NOPH
84	XOR	R0, R0      // Restore R0 to $0.
85	MOVD	R4, 0(R9)   // Save stack pointer.
86
87	MOVD	R3, r1+32(FP)
88	MOVD	R0, r2+40(FP)
89	MOVD	R0, err+48(FP)
90	MOVW	R3, R4
91	CMP	R4, $-1
92	BNE	done
93	BL	addrerrno<>(SB)
94	MOVWZ	0(R3), R3
95	MOVD	R3, err+48(FP)
96done:
97	BL	runtime·exitsyscall(SB)
98	RET
99
100TEXT ·syscall_rawsyscall(SB),NOSPLIT,$0-56
101	MOVD	a1+8(FP), R1
102	MOVD	a2+16(FP), R2
103	MOVD	a3+24(FP), R3
104
105	// Get library control area (LCA).
106	MOVW	PSALAA, R8
107	MOVD	LCA64(R8), R8
108
109	// Get function.
110	MOVD	CAA(R8), R9
111	MOVD	EDCHPXV(R9), R9
112	MOVD	trap+0(FP), R5
113	SLD	$4, R5
114	ADD	R5, R9
115	LMG	0(R9), R5, R6
116
117	// Restore LE stack.
118	MOVD	SAVSTACK_ASYNC(R8), R9
119	MOVD	0(R9), R4
120	MOVD	$0, 0(R9)
121
122	// Call function.
123	LE_CALL
124	NOPH
125	XOR	R0, R0      // Restore R0 to $0.
126	MOVD	R4, 0(R9)   // Save stack pointer.
127
128	MOVD	R3, r1+32(FP)
129	MOVD	R0, r2+40(FP)
130	MOVD	R0, err+48(FP)
131	MOVW	R3, R4
132	CMP	R4, $-1
133	BNE	done
134	BL	addrerrno<>(SB)
135	MOVWZ	0(R3), R3
136	MOVD	R3, err+48(FP)
137done:
138	RET
139
140TEXT ·syscall_syscall6(SB),NOSPLIT,$0-80
141	BL	runtime·entersyscall(SB)
142	MOVD	a1+8(FP), R1
143	MOVD	a2+16(FP), R2
144	MOVD	a3+24(FP), R3
145
146	// Get library control area (LCA).
147	MOVW	PSALAA, R8
148	MOVD	LCA64(R8), R8
149
150	// Get function.
151	MOVD	CAA(R8), R9
152	MOVD	EDCHPXV(R9), R9
153	MOVD	trap+0(FP), R5
154	SLD	$4, R5
155	ADD	R5, R9
156	LMG	0(R9), R5, R6
157
158	// Restore LE stack.
159	MOVD	SAVSTACK_ASYNC(R8), R9
160	MOVD	0(R9), R4
161	MOVD	$0, 0(R9)
162
163	// Fill in parameter list.
164	MOVD	a4+32(FP), R12
165	MOVD	R12, (2176+24)(R4)
166	MOVD	a5+40(FP), R12
167	MOVD	R12, (2176+32)(R4)
168	MOVD	a6+48(FP), R12
169	MOVD	R12, (2176+40)(R4)
170
171	// Call function.
172	LE_CALL
173	NOPH
174	XOR	R0, R0      // Restore R0 to $0.
175	MOVD	R4, 0(R9)   // Save stack pointer.
176
177	MOVD	R3, r1+56(FP)
178	MOVD	R0, r2+64(FP)
179	MOVD	R0, err+72(FP)
180	MOVW	R3, R4
181	CMP	R4, $-1
182	BNE	done
183	BL	addrerrno<>(SB)
184	MOVWZ	0(R3), R3
185	MOVD	R3, err+72(FP)
186done:
187	BL	runtime·exitsyscall(SB)
188	RET
189
190TEXT ·syscall_rawsyscall6(SB),NOSPLIT,$0-80
191	MOVD	a1+8(FP), R1
192	MOVD	a2+16(FP), R2
193	MOVD	a3+24(FP), R3
194
195	// Get library control area (LCA).
196	MOVW	PSALAA, R8
197	MOVD	LCA64(R8), R8
198
199	// Get function.
200	MOVD	CAA(R8), R9
201	MOVD	EDCHPXV(R9), R9
202	MOVD	trap+0(FP), R5
203	SLD	$4, R5
204	ADD	R5, R9
205	LMG	0(R9), R5, R6
206
207	// Restore LE stack.
208	MOVD	SAVSTACK_ASYNC(R8), R9
209	MOVD	0(R9), R4
210	MOVD	$0, 0(R9)
211
212	// Fill in parameter list.
213	MOVD	a4+32(FP), R12
214	MOVD	R12, (2176+24)(R4)
215	MOVD	a5+40(FP), R12
216	MOVD	R12, (2176+32)(R4)
217	MOVD	a6+48(FP), R12
218	MOVD	R12, (2176+40)(R4)
219
220	// Call function.
221	LE_CALL
222	NOPH
223	XOR	R0, R0      // Restore R0 to $0.
224	MOVD	R4, 0(R9)   // Save stack pointer.
225
226	MOVD	R3, r1+56(FP)
227	MOVD	R0, r2+64(FP)
228	MOVD	R0, err+72(FP)
229	MOVW	R3, R4
230	CMP	R4, $-1
231	BNE	done
232	BL	·rrno<>(SB)
233	MOVWZ	0(R3), R3
234	MOVD	R3, err+72(FP)
235done:
236	RET
237
238TEXT ·syscall_syscall9(SB),NOSPLIT,$0
239	BL	runtime·entersyscall(SB)
240	MOVD	a1+8(FP), R1
241	MOVD	a2+16(FP), R2
242	MOVD	a3+24(FP), R3
243
244	// Get library control area (LCA).
245	MOVW	PSALAA, R8
246	MOVD	LCA64(R8), R8
247
248	// Get function.
249	MOVD	CAA(R8), R9
250	MOVD	EDCHPXV(R9), R9
251	MOVD	trap+0(FP), R5
252	SLD	$4, R5
253	ADD	R5, R9
254	LMG	0(R9), R5, R6
255
256	// Restore LE stack.
257	MOVD	SAVSTACK_ASYNC(R8), R9
258	MOVD	0(R9), R4
259	MOVD	$0, 0(R9)
260
261	// Fill in parameter list.
262	MOVD	a4+32(FP), R12
263	MOVD	R12, (2176+24)(R4)
264	MOVD	a5+40(FP), R12
265	MOVD	R12, (2176+32)(R4)
266	MOVD	a6+48(FP), R12
267	MOVD	R12, (2176+40)(R4)
268	MOVD	a7+56(FP), R12
269	MOVD	R12, (2176+48)(R4)
270	MOVD	a8+64(FP), R12
271	MOVD	R12, (2176+56)(R4)
272	MOVD	a9+72(FP), R12
273	MOVD	R12, (2176+64)(R4)
274
275	// Call function.
276	LE_CALL
277	NOPH
278	XOR	R0, R0      // Restore R0 to $0.
279	MOVD	R4, 0(R9)   // Save stack pointer.
280
281	MOVD	R3, r1+80(FP)
282	MOVD	R0, r2+88(FP)
283	MOVD	R0, err+96(FP)
284	MOVW	R3, R4
285	CMP	R4, $-1
286	BNE	done
287	BL	addrerrno<>(SB)
288	MOVWZ	0(R3), R3
289	MOVD	R3, err+96(FP)
290done:
291        BL	runtime·exitsyscall(SB)
292        RET
293
294TEXT ·syscall_rawsyscall9(SB),NOSPLIT,$0
295	MOVD	a1+8(FP), R1
296	MOVD	a2+16(FP), R2
297	MOVD	a3+24(FP), R3
298
299	// Get library control area (LCA).
300	MOVW	PSALAA, R8
301	MOVD	LCA64(R8), R8
302
303	// Get function.
304	MOVD	CAA(R8), R9
305	MOVD	EDCHPXV(R9), R9
306	MOVD	trap+0(FP), R5
307	SLD	$4, R5
308	ADD	R5, R9
309	LMG	0(R9), R5, R6
310
311	// Restore LE stack.
312	MOVD	SAVSTACK_ASYNC(R8), R9
313	MOVD	0(R9), R4
314	MOVD	$0, 0(R9)
315
316	// Fill in parameter list.
317	MOVD	a4+32(FP), R12
318	MOVD	R12, (2176+24)(R4)
319	MOVD	a5+40(FP), R12
320	MOVD	R12, (2176+32)(R4)
321	MOVD	a6+48(FP), R12
322	MOVD	R12, (2176+40)(R4)
323	MOVD	a7+56(FP), R12
324	MOVD	R12, (2176+48)(R4)
325	MOVD	a8+64(FP), R12
326	MOVD	R12, (2176+56)(R4)
327	MOVD	a9+72(FP), R12
328	MOVD	R12, (2176+64)(R4)
329
330	// Call function.
331	LE_CALL
332	NOPH
333	XOR	R0, R0      // Restore R0 to $0.
334	MOVD	R4, 0(R9)   // Save stack pointer.
335
336	MOVD	R3, r1+80(FP)
337	MOVD	R0, r2+88(FP)
338	MOVD	R0, err+96(FP)
339	MOVW	R3, R4
340	CMP	R4, $-1
341	BNE	done
342	BL	addrerrno<>(SB)
343	MOVWZ	0(R3), R3
344	MOVD	R3, err+96(FP)
345done:
346	RET
347
348// func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64)
349TEXT ·svcCall(SB),NOSPLIT,$0
350	BL	runtime·save_g(SB)   // Save g and stack pointer
351	MOVW	PSALAA, R8
352	MOVD	LCA64(R8), R8
353	MOVD	SAVSTACK_ASYNC(R8), R9
354	MOVD	R15, 0(R9)
355
356	MOVD	argv+8(FP), R1       // Move function arguments into registers
357	MOVD	dsa+16(FP), g
358	MOVD	fnptr+0(FP), R15
359
360	BYTE	$0x0D                // Branch to function
361	BYTE	$0xEF
362
363	BL	runtime·load_g(SB)   // Restore g and stack pointer
364	MOVW	PSALAA, R8
365	MOVD	LCA64(R8), R8
366	MOVD	SAVSTACK_ASYNC(R8), R9
367	MOVD	0(R9), R15
368
369	RET
370
371// func svcLoad(name *byte) unsafe.Pointer
372TEXT ·svcLoad(SB),NOSPLIT,$0
373	MOVD	R15, R2          // Save go stack pointer
374	MOVD	name+0(FP), R0   // Move SVC args into registers
375	MOVD	$0x80000000, R1
376	MOVD	$0, R15
377	BYTE	$0x0A            // SVC 08 LOAD
378	BYTE	$0x08
379	MOVW	R15, R3          // Save return code from SVC
380	MOVD	R2, R15          // Restore go stack pointer
381	CMP	R3, $0           // Check SVC return code
382	BNE	error
383
384	MOVD	$-2, R3          // Reset last bit of entry point to zero
385	AND	R0, R3
386	MOVD	R3, addr+8(FP)   // Return entry point returned by SVC
387	CMP	R0, R3           // Check if last bit of entry point was set
388	BNE	done
389
390	MOVD	R15, R2          // Save go stack pointer
391	MOVD	$0, R15          // Move SVC args into registers (entry point still in r0 from SVC 08)
392	BYTE	$0x0A            // SVC 09 DELETE
393	BYTE	$0x09
394	MOVD	R2, R15          // Restore go stack pointer
395
396error:
397	MOVD	$0, addr+8(FP)   // Return 0 on failure
398done:
399	XOR	R0, R0           // Reset r0 to 0
400	RET
401
402// func svcUnload(name *byte, fnptr unsafe.Pointer) int64
403TEXT ·svcUnload(SB),NOSPLIT,$0
404	MOVD	R15, R2          // Save go stack pointer
405	MOVD	name+0(FP), R0   // Move SVC args into registers
406	MOVD	addr+8(FP), R15
407	BYTE	$0x0A            // SVC 09
408	BYTE	$0x09
409	XOR	R0, R0           // Reset r0 to 0
410	MOVD	R15, R1          // Save SVC return code
411	MOVD	R2, R15          // Restore go stack pointer
412	MOVD	R1, rc+0(FP)     // Return SVC return code
413	RET
414
415// func gettid() uint64
416TEXT ·gettid(SB), NOSPLIT, $0
417	// Get library control area (LCA).
418	MOVW PSALAA, R8
419	MOVD LCA64(R8), R8
420
421	// Get CEECAATHDID
422	MOVD CAA(R8), R9
423	MOVD 0x3D0(R9), R9
424	MOVD R9, ret+0(FP)
425
426	RET
427