|
@@ -0,0 +1,426 @@
|
|
|
+// Copyright 2020 The Go Authors. All rights reserved.
|
|
|
+// Use of this source code is governed by a BSD-style
|
|
|
+// license that can be found in the LICENSE file.
|
|
|
+
|
|
|
+//go:build zos && s390x && gc
|
|
|
+// +build zos
|
|
|
+// +build s390x
|
|
|
+// +build gc
|
|
|
+
|
|
|
+#include "textflag.h"
|
|
|
+
|
|
|
+#define PSALAA 1208(R0)
|
|
|
+#define GTAB64(x) 80(x)
|
|
|
+#define LCA64(x) 88(x)
|
|
|
+#define CAA(x) 8(x)
|
|
|
+#define EDCHPXV(x) 1016(x) // in the CAA
|
|
|
+#define SAVSTACK_ASYNC(x) 336(x) // in the LCA
|
|
|
+
|
|
|
+// SS_*, where x=SAVSTACK_ASYNC
|
|
|
+#define SS_LE(x) 0(x)
|
|
|
+#define SS_GO(x) 8(x)
|
|
|
+#define SS_ERRNO(x) 16(x)
|
|
|
+#define SS_ERRNOJR(x) 20(x)
|
|
|
+
|
|
|
+#define LE_CALL BYTE $0x0D; BYTE $0x76; // BL R7, R6
|
|
|
+
|
|
|
+TEXT ·clearErrno(SB),NOSPLIT,$0-0
|
|
|
+ BL addrerrno<>(SB)
|
|
|
+ MOVD $0, 0(R3)
|
|
|
+ RET
|
|
|
+
|
|
|
+// Returns the address of errno in R3.
|
|
|
+TEXT addrerrno<>(SB),NOSPLIT|NOFRAME,$0-0
|
|
|
+ // Get library control area (LCA).
|
|
|
+ MOVW PSALAA, R8
|
|
|
+ MOVD LCA64(R8), R8
|
|
|
+
|
|
|
+ // Get __errno FuncDesc.
|
|
|
+ MOVD CAA(R8), R9
|
|
|
+ MOVD EDCHPXV(R9), R9
|
|
|
+ ADD $(0x156*16), R9
|
|
|
+ LMG 0(R9), R5, R6
|
|
|
+
|
|
|
+ // Switch to saved LE stack.
|
|
|
+ MOVD SAVSTACK_ASYNC(R8), R9
|
|
|
+ MOVD 0(R9), R4
|
|
|
+ MOVD $0, 0(R9)
|
|
|
+
|
|
|
+ // Call __errno function.
|
|
|
+ LE_CALL
|
|
|
+ NOPH
|
|
|
+
|
|
|
+ // Switch back to Go stack.
|
|
|
+ XOR R0, R0 // Restore R0 to $0.
|
|
|
+ MOVD R4, 0(R9) // Save stack pointer.
|
|
|
+ RET
|
|
|
+
|
|
|
+TEXT ·syscall_syscall(SB),NOSPLIT,$0-56
|
|
|
+ BL runtime·entersyscall(SB)
|
|
|
+ MOVD a1+8(FP), R1
|
|
|
+ MOVD a2+16(FP), R2
|
|
|
+ MOVD a3+24(FP), R3
|
|
|
+
|
|
|
+ // Get library control area (LCA).
|
|
|
+ MOVW PSALAA, R8
|
|
|
+ MOVD LCA64(R8), R8
|
|
|
+
|
|
|
+ // Get function.
|
|
|
+ MOVD CAA(R8), R9
|
|
|
+ MOVD EDCHPXV(R9), R9
|
|
|
+ MOVD trap+0(FP), R5
|
|
|
+ SLD $4, R5
|
|
|
+ ADD R5, R9
|
|
|
+ LMG 0(R9), R5, R6
|
|
|
+
|
|
|
+ // Restore LE stack.
|
|
|
+ MOVD SAVSTACK_ASYNC(R8), R9
|
|
|
+ MOVD 0(R9), R4
|
|
|
+ MOVD $0, 0(R9)
|
|
|
+
|
|
|
+ // Call function.
|
|
|
+ LE_CALL
|
|
|
+ NOPH
|
|
|
+ XOR R0, R0 // Restore R0 to $0.
|
|
|
+ MOVD R4, 0(R9) // Save stack pointer.
|
|
|
+
|
|
|
+ MOVD R3, r1+32(FP)
|
|
|
+ MOVD R0, r2+40(FP)
|
|
|
+ MOVD R0, err+48(FP)
|
|
|
+ MOVW R3, R4
|
|
|
+ CMP R4, $-1
|
|
|
+ BNE done
|
|
|
+ BL addrerrno<>(SB)
|
|
|
+ MOVWZ 0(R3), R3
|
|
|
+ MOVD R3, err+48(FP)
|
|
|
+done:
|
|
|
+ BL runtime·exitsyscall(SB)
|
|
|
+ RET
|
|
|
+
|
|
|
+TEXT ·syscall_rawsyscall(SB),NOSPLIT,$0-56
|
|
|
+ MOVD a1+8(FP), R1
|
|
|
+ MOVD a2+16(FP), R2
|
|
|
+ MOVD a3+24(FP), R3
|
|
|
+
|
|
|
+ // Get library control area (LCA).
|
|
|
+ MOVW PSALAA, R8
|
|
|
+ MOVD LCA64(R8), R8
|
|
|
+
|
|
|
+ // Get function.
|
|
|
+ MOVD CAA(R8), R9
|
|
|
+ MOVD EDCHPXV(R9), R9
|
|
|
+ MOVD trap+0(FP), R5
|
|
|
+ SLD $4, R5
|
|
|
+ ADD R5, R9
|
|
|
+ LMG 0(R9), R5, R6
|
|
|
+
|
|
|
+ // Restore LE stack.
|
|
|
+ MOVD SAVSTACK_ASYNC(R8), R9
|
|
|
+ MOVD 0(R9), R4
|
|
|
+ MOVD $0, 0(R9)
|
|
|
+
|
|
|
+ // Call function.
|
|
|
+ LE_CALL
|
|
|
+ NOPH
|
|
|
+ XOR R0, R0 // Restore R0 to $0.
|
|
|
+ MOVD R4, 0(R9) // Save stack pointer.
|
|
|
+
|
|
|
+ MOVD R3, r1+32(FP)
|
|
|
+ MOVD R0, r2+40(FP)
|
|
|
+ MOVD R0, err+48(FP)
|
|
|
+ MOVW R3, R4
|
|
|
+ CMP R4, $-1
|
|
|
+ BNE done
|
|
|
+ BL addrerrno<>(SB)
|
|
|
+ MOVWZ 0(R3), R3
|
|
|
+ MOVD R3, err+48(FP)
|
|
|
+done:
|
|
|
+ RET
|
|
|
+
|
|
|
+TEXT ·syscall_syscall6(SB),NOSPLIT,$0-80
|
|
|
+ BL runtime·entersyscall(SB)
|
|
|
+ MOVD a1+8(FP), R1
|
|
|
+ MOVD a2+16(FP), R2
|
|
|
+ MOVD a3+24(FP), R3
|
|
|
+
|
|
|
+ // Get library control area (LCA).
|
|
|
+ MOVW PSALAA, R8
|
|
|
+ MOVD LCA64(R8), R8
|
|
|
+
|
|
|
+ // Get function.
|
|
|
+ MOVD CAA(R8), R9
|
|
|
+ MOVD EDCHPXV(R9), R9
|
|
|
+ MOVD trap+0(FP), R5
|
|
|
+ SLD $4, R5
|
|
|
+ ADD R5, R9
|
|
|
+ LMG 0(R9), R5, R6
|
|
|
+
|
|
|
+ // Restore LE stack.
|
|
|
+ MOVD SAVSTACK_ASYNC(R8), R9
|
|
|
+ MOVD 0(R9), R4
|
|
|
+ MOVD $0, 0(R9)
|
|
|
+
|
|
|
+ // Fill in parameter list.
|
|
|
+ MOVD a4+32(FP), R12
|
|
|
+ MOVD R12, (2176+24)(R4)
|
|
|
+ MOVD a5+40(FP), R12
|
|
|
+ MOVD R12, (2176+32)(R4)
|
|
|
+ MOVD a6+48(FP), R12
|
|
|
+ MOVD R12, (2176+40)(R4)
|
|
|
+
|
|
|
+ // Call function.
|
|
|
+ LE_CALL
|
|
|
+ NOPH
|
|
|
+ XOR R0, R0 // Restore R0 to $0.
|
|
|
+ MOVD R4, 0(R9) // Save stack pointer.
|
|
|
+
|
|
|
+ MOVD R3, r1+56(FP)
|
|
|
+ MOVD R0, r2+64(FP)
|
|
|
+ MOVD R0, err+72(FP)
|
|
|
+ MOVW R3, R4
|
|
|
+ CMP R4, $-1
|
|
|
+ BNE done
|
|
|
+ BL addrerrno<>(SB)
|
|
|
+ MOVWZ 0(R3), R3
|
|
|
+ MOVD R3, err+72(FP)
|
|
|
+done:
|
|
|
+ BL runtime·exitsyscall(SB)
|
|
|
+ RET
|
|
|
+
|
|
|
+TEXT ·syscall_rawsyscall6(SB),NOSPLIT,$0-80
|
|
|
+ MOVD a1+8(FP), R1
|
|
|
+ MOVD a2+16(FP), R2
|
|
|
+ MOVD a3+24(FP), R3
|
|
|
+
|
|
|
+ // Get library control area (LCA).
|
|
|
+ MOVW PSALAA, R8
|
|
|
+ MOVD LCA64(R8), R8
|
|
|
+
|
|
|
+ // Get function.
|
|
|
+ MOVD CAA(R8), R9
|
|
|
+ MOVD EDCHPXV(R9), R9
|
|
|
+ MOVD trap+0(FP), R5
|
|
|
+ SLD $4, R5
|
|
|
+ ADD R5, R9
|
|
|
+ LMG 0(R9), R5, R6
|
|
|
+
|
|
|
+ // Restore LE stack.
|
|
|
+ MOVD SAVSTACK_ASYNC(R8), R9
|
|
|
+ MOVD 0(R9), R4
|
|
|
+ MOVD $0, 0(R9)
|
|
|
+
|
|
|
+ // Fill in parameter list.
|
|
|
+ MOVD a4+32(FP), R12
|
|
|
+ MOVD R12, (2176+24)(R4)
|
|
|
+ MOVD a5+40(FP), R12
|
|
|
+ MOVD R12, (2176+32)(R4)
|
|
|
+ MOVD a6+48(FP), R12
|
|
|
+ MOVD R12, (2176+40)(R4)
|
|
|
+
|
|
|
+ // Call function.
|
|
|
+ LE_CALL
|
|
|
+ NOPH
|
|
|
+ XOR R0, R0 // Restore R0 to $0.
|
|
|
+ MOVD R4, 0(R9) // Save stack pointer.
|
|
|
+
|
|
|
+ MOVD R3, r1+56(FP)
|
|
|
+ MOVD R0, r2+64(FP)
|
|
|
+ MOVD R0, err+72(FP)
|
|
|
+ MOVW R3, R4
|
|
|
+ CMP R4, $-1
|
|
|
+ BNE done
|
|
|
+ BL ·rrno<>(SB)
|
|
|
+ MOVWZ 0(R3), R3
|
|
|
+ MOVD R3, err+72(FP)
|
|
|
+done:
|
|
|
+ RET
|
|
|
+
|
|
|
+TEXT ·syscall_syscall9(SB),NOSPLIT,$0
|
|
|
+ BL runtime·entersyscall(SB)
|
|
|
+ MOVD a1+8(FP), R1
|
|
|
+ MOVD a2+16(FP), R2
|
|
|
+ MOVD a3+24(FP), R3
|
|
|
+
|
|
|
+ // Get library control area (LCA).
|
|
|
+ MOVW PSALAA, R8
|
|
|
+ MOVD LCA64(R8), R8
|
|
|
+
|
|
|
+ // Get function.
|
|
|
+ MOVD CAA(R8), R9
|
|
|
+ MOVD EDCHPXV(R9), R9
|
|
|
+ MOVD trap+0(FP), R5
|
|
|
+ SLD $4, R5
|
|
|
+ ADD R5, R9
|
|
|
+ LMG 0(R9), R5, R6
|
|
|
+
|
|
|
+ // Restore LE stack.
|
|
|
+ MOVD SAVSTACK_ASYNC(R8), R9
|
|
|
+ MOVD 0(R9), R4
|
|
|
+ MOVD $0, 0(R9)
|
|
|
+
|
|
|
+ // Fill in parameter list.
|
|
|
+ MOVD a4+32(FP), R12
|
|
|
+ MOVD R12, (2176+24)(R4)
|
|
|
+ MOVD a5+40(FP), R12
|
|
|
+ MOVD R12, (2176+32)(R4)
|
|
|
+ MOVD a6+48(FP), R12
|
|
|
+ MOVD R12, (2176+40)(R4)
|
|
|
+ MOVD a7+56(FP), R12
|
|
|
+ MOVD R12, (2176+48)(R4)
|
|
|
+ MOVD a8+64(FP), R12
|
|
|
+ MOVD R12, (2176+56)(R4)
|
|
|
+ MOVD a9+72(FP), R12
|
|
|
+ MOVD R12, (2176+64)(R4)
|
|
|
+
|
|
|
+ // Call function.
|
|
|
+ LE_CALL
|
|
|
+ NOPH
|
|
|
+ XOR R0, R0 // Restore R0 to $0.
|
|
|
+ MOVD R4, 0(R9) // Save stack pointer.
|
|
|
+
|
|
|
+ MOVD R3, r1+80(FP)
|
|
|
+ MOVD R0, r2+88(FP)
|
|
|
+ MOVD R0, err+96(FP)
|
|
|
+ MOVW R3, R4
|
|
|
+ CMP R4, $-1
|
|
|
+ BNE done
|
|
|
+ BL addrerrno<>(SB)
|
|
|
+ MOVWZ 0(R3), R3
|
|
|
+ MOVD R3, err+96(FP)
|
|
|
+done:
|
|
|
+ BL runtime·exitsyscall(SB)
|
|
|
+ RET
|
|
|
+
|
|
|
+TEXT ·syscall_rawsyscall9(SB),NOSPLIT,$0
|
|
|
+ MOVD a1+8(FP), R1
|
|
|
+ MOVD a2+16(FP), R2
|
|
|
+ MOVD a3+24(FP), R3
|
|
|
+
|
|
|
+ // Get library control area (LCA).
|
|
|
+ MOVW PSALAA, R8
|
|
|
+ MOVD LCA64(R8), R8
|
|
|
+
|
|
|
+ // Get function.
|
|
|
+ MOVD CAA(R8), R9
|
|
|
+ MOVD EDCHPXV(R9), R9
|
|
|
+ MOVD trap+0(FP), R5
|
|
|
+ SLD $4, R5
|
|
|
+ ADD R5, R9
|
|
|
+ LMG 0(R9), R5, R6
|
|
|
+
|
|
|
+ // Restore LE stack.
|
|
|
+ MOVD SAVSTACK_ASYNC(R8), R9
|
|
|
+ MOVD 0(R9), R4
|
|
|
+ MOVD $0, 0(R9)
|
|
|
+
|
|
|
+ // Fill in parameter list.
|
|
|
+ MOVD a4+32(FP), R12
|
|
|
+ MOVD R12, (2176+24)(R4)
|
|
|
+ MOVD a5+40(FP), R12
|
|
|
+ MOVD R12, (2176+32)(R4)
|
|
|
+ MOVD a6+48(FP), R12
|
|
|
+ MOVD R12, (2176+40)(R4)
|
|
|
+ MOVD a7+56(FP), R12
|
|
|
+ MOVD R12, (2176+48)(R4)
|
|
|
+ MOVD a8+64(FP), R12
|
|
|
+ MOVD R12, (2176+56)(R4)
|
|
|
+ MOVD a9+72(FP), R12
|
|
|
+ MOVD R12, (2176+64)(R4)
|
|
|
+
|
|
|
+ // Call function.
|
|
|
+ LE_CALL
|
|
|
+ NOPH
|
|
|
+ XOR R0, R0 // Restore R0 to $0.
|
|
|
+ MOVD R4, 0(R9) // Save stack pointer.
|
|
|
+
|
|
|
+ MOVD R3, r1+80(FP)
|
|
|
+ MOVD R0, r2+88(FP)
|
|
|
+ MOVD R0, err+96(FP)
|
|
|
+ MOVW R3, R4
|
|
|
+ CMP R4, $-1
|
|
|
+ BNE done
|
|
|
+ BL addrerrno<>(SB)
|
|
|
+ MOVWZ 0(R3), R3
|
|
|
+ MOVD R3, err+96(FP)
|
|
|
+done:
|
|
|
+ RET
|
|
|
+
|
|
|
+// func svcCall(fnptr unsafe.Pointer, argv *unsafe.Pointer, dsa *uint64)
|
|
|
+TEXT ·svcCall(SB),NOSPLIT,$0
|
|
|
+ BL runtime·save_g(SB) // Save g and stack pointer
|
|
|
+ MOVW PSALAA, R8
|
|
|
+ MOVD LCA64(R8), R8
|
|
|
+ MOVD SAVSTACK_ASYNC(R8), R9
|
|
|
+ MOVD R15, 0(R9)
|
|
|
+
|
|
|
+ MOVD argv+8(FP), R1 // Move function arguments into registers
|
|
|
+ MOVD dsa+16(FP), g
|
|
|
+ MOVD fnptr+0(FP), R15
|
|
|
+
|
|
|
+ BYTE $0x0D // Branch to function
|
|
|
+ BYTE $0xEF
|
|
|
+
|
|
|
+ BL runtime·load_g(SB) // Restore g and stack pointer
|
|
|
+ MOVW PSALAA, R8
|
|
|
+ MOVD LCA64(R8), R8
|
|
|
+ MOVD SAVSTACK_ASYNC(R8), R9
|
|
|
+ MOVD 0(R9), R15
|
|
|
+
|
|
|
+ RET
|
|
|
+
|
|
|
+// func svcLoad(name *byte) unsafe.Pointer
|
|
|
+TEXT ·svcLoad(SB),NOSPLIT,$0
|
|
|
+ MOVD R15, R2 // Save go stack pointer
|
|
|
+ MOVD name+0(FP), R0 // Move SVC args into registers
|
|
|
+ MOVD $0x80000000, R1
|
|
|
+ MOVD $0, R15
|
|
|
+ BYTE $0x0A // SVC 08 LOAD
|
|
|
+ BYTE $0x08
|
|
|
+ MOVW R15, R3 // Save return code from SVC
|
|
|
+ MOVD R2, R15 // Restore go stack pointer
|
|
|
+ CMP R3, $0 // Check SVC return code
|
|
|
+ BNE error
|
|
|
+
|
|
|
+ MOVD $-2, R3 // Reset last bit of entry point to zero
|
|
|
+ AND R0, R3
|
|
|
+ MOVD R3, addr+8(FP) // Return entry point returned by SVC
|
|
|
+ CMP R0, R3 // Check if last bit of entry point was set
|
|
|
+ BNE done
|
|
|
+
|
|
|
+ MOVD R15, R2 // Save go stack pointer
|
|
|
+ MOVD $0, R15 // Move SVC args into registers (entry point still in r0 from SVC 08)
|
|
|
+ BYTE $0x0A // SVC 09 DELETE
|
|
|
+ BYTE $0x09
|
|
|
+ MOVD R2, R15 // Restore go stack pointer
|
|
|
+
|
|
|
+error:
|
|
|
+ MOVD $0, addr+8(FP) // Return 0 on failure
|
|
|
+done:
|
|
|
+ XOR R0, R0 // Reset r0 to 0
|
|
|
+ RET
|
|
|
+
|
|
|
+// func svcUnload(name *byte, fnptr unsafe.Pointer) int64
|
|
|
+TEXT ·svcUnload(SB),NOSPLIT,$0
|
|
|
+ MOVD R15, R2 // Save go stack pointer
|
|
|
+ MOVD name+0(FP), R0 // Move SVC args into registers
|
|
|
+ MOVD addr+8(FP), R15
|
|
|
+ BYTE $0x0A // SVC 09
|
|
|
+ BYTE $0x09
|
|
|
+ XOR R0, R0 // Reset r0 to 0
|
|
|
+ MOVD R15, R1 // Save SVC return code
|
|
|
+ MOVD R2, R15 // Restore go stack pointer
|
|
|
+ MOVD R1, rc+0(FP) // Return SVC return code
|
|
|
+ RET
|
|
|
+
|
|
|
+// func gettid() uint64
|
|
|
+TEXT ·gettid(SB), NOSPLIT, $0
|
|
|
+ // Get library control area (LCA).
|
|
|
+ MOVW PSALAA, R8
|
|
|
+ MOVD LCA64(R8), R8
|
|
|
+
|
|
|
+ // Get CEECAATHDID
|
|
|
+ MOVD CAA(R8), R9
|
|
|
+ MOVD 0x3D0(R9), R9
|
|
|
+ MOVD R9, ret+0(FP)
|
|
|
+
|
|
|
+ RET
|