xref: /openbmc/linux/tools/include/nolibc/arch-aarch64.h (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1271661c1SWilly Tarreau /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
2271661c1SWilly Tarreau /*
3271661c1SWilly Tarreau  * AARCH64 specific definitions for NOLIBC
4271661c1SWilly Tarreau  * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
5271661c1SWilly Tarreau  */
6271661c1SWilly Tarreau 
7271661c1SWilly Tarreau #ifndef _NOLIBC_ARCH_AARCH64_H
8271661c1SWilly Tarreau #define _NOLIBC_ARCH_AARCH64_H
9271661c1SWilly Tarreau 
10818924d1SThomas Weißschuh #include "compiler.h"
11*ded8af47SZhangjin Wu #include "crt.h"
12818924d1SThomas Weißschuh 
13271661c1SWilly Tarreau /* Syscalls for AARCH64 :
14271661c1SWilly Tarreau  *   - registers are 64-bit
15271661c1SWilly Tarreau  *   - stack is 16-byte aligned
16271661c1SWilly Tarreau  *   - syscall number is passed in x8
17271661c1SWilly Tarreau  *   - arguments are in x0, x1, x2, x3, x4, x5
18271661c1SWilly Tarreau  *   - the system call is performed by calling svc 0
19271661c1SWilly Tarreau  *   - syscall return comes in x0.
20271661c1SWilly Tarreau  *   - the arguments are cast to long and assigned into the target registers
21271661c1SWilly Tarreau  *     which are then simply passed as registers to the asm code, so that we
22271661c1SWilly Tarreau  *     don't have to experience issues with register constraints.
23271661c1SWilly Tarreau  *
24271661c1SWilly Tarreau  * On aarch64, select() is not implemented so we have to use pselect6().
25271661c1SWilly Tarreau  */
26271661c1SWilly Tarreau #define __ARCH_WANT_SYS_PSELECT6
27271661c1SWilly Tarreau 
28271661c1SWilly Tarreau #define my_syscall0(num)                                                      \
29271661c1SWilly Tarreau ({                                                                            \
3037d62758SAmmar Faizi 	register long _num  __asm__ ("x8") = (num);                           \
3137d62758SAmmar Faizi 	register long _arg1 __asm__ ("x0");                                   \
32271661c1SWilly Tarreau 									      \
3337d62758SAmmar Faizi 	__asm__ volatile (                                                    \
34271661c1SWilly Tarreau 		"svc #0\n"                                                    \
35271661c1SWilly Tarreau 		: "=r"(_arg1)                                                 \
36271661c1SWilly Tarreau 		: "r"(_num)                                                   \
37271661c1SWilly Tarreau 		: "memory", "cc"                                              \
38271661c1SWilly Tarreau 	);                                                                    \
39271661c1SWilly Tarreau 	_arg1;                                                                \
40271661c1SWilly Tarreau })
41271661c1SWilly Tarreau 
42271661c1SWilly Tarreau #define my_syscall1(num, arg1)                                                \
43271661c1SWilly Tarreau ({                                                                            \
4437d62758SAmmar Faizi 	register long _num  __asm__ ("x8") = (num);                           \
4537d62758SAmmar Faizi 	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
46271661c1SWilly Tarreau 									      \
4737d62758SAmmar Faizi 	__asm__ volatile (                                                    \
48271661c1SWilly Tarreau 		"svc #0\n"                                                    \
49271661c1SWilly Tarreau 		: "=r"(_arg1)                                                 \
50271661c1SWilly Tarreau 		: "r"(_arg1),                                                 \
51271661c1SWilly Tarreau 		  "r"(_num)                                                   \
52271661c1SWilly Tarreau 		: "memory", "cc"                                              \
53271661c1SWilly Tarreau 	);                                                                    \
54271661c1SWilly Tarreau 	_arg1;                                                                \
55271661c1SWilly Tarreau })
56271661c1SWilly Tarreau 
57271661c1SWilly Tarreau #define my_syscall2(num, arg1, arg2)                                          \
58271661c1SWilly Tarreau ({                                                                            \
5937d62758SAmmar Faizi 	register long _num  __asm__ ("x8") = (num);                           \
6037d62758SAmmar Faizi 	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
6137d62758SAmmar Faizi 	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
62271661c1SWilly Tarreau 									      \
6337d62758SAmmar Faizi 	__asm__ volatile (                                                    \
64271661c1SWilly Tarreau 		"svc #0\n"                                                    \
65271661c1SWilly Tarreau 		: "=r"(_arg1)                                                 \
66271661c1SWilly Tarreau 		: "r"(_arg1), "r"(_arg2),                                     \
67271661c1SWilly Tarreau 		  "r"(_num)                                                   \
68271661c1SWilly Tarreau 		: "memory", "cc"                                              \
69271661c1SWilly Tarreau 	);                                                                    \
70271661c1SWilly Tarreau 	_arg1;                                                                \
71271661c1SWilly Tarreau })
72271661c1SWilly Tarreau 
73271661c1SWilly Tarreau #define my_syscall3(num, arg1, arg2, arg3)                                    \
74271661c1SWilly Tarreau ({                                                                            \
7537d62758SAmmar Faizi 	register long _num  __asm__ ("x8") = (num);                           \
7637d62758SAmmar Faizi 	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
7737d62758SAmmar Faizi 	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
7837d62758SAmmar Faizi 	register long _arg3 __asm__ ("x2") = (long)(arg3);                    \
79271661c1SWilly Tarreau 									      \
8037d62758SAmmar Faizi 	__asm__ volatile (                                                    \
81271661c1SWilly Tarreau 		"svc #0\n"                                                    \
82271661c1SWilly Tarreau 		: "=r"(_arg1)                                                 \
83271661c1SWilly Tarreau 		: "r"(_arg1), "r"(_arg2), "r"(_arg3),                         \
84271661c1SWilly Tarreau 		  "r"(_num)                                                   \
85271661c1SWilly Tarreau 		: "memory", "cc"                                              \
86271661c1SWilly Tarreau 	);                                                                    \
87271661c1SWilly Tarreau 	_arg1;                                                                \
88271661c1SWilly Tarreau })
89271661c1SWilly Tarreau 
90271661c1SWilly Tarreau #define my_syscall4(num, arg1, arg2, arg3, arg4)                              \
91271661c1SWilly Tarreau ({                                                                            \
9237d62758SAmmar Faizi 	register long _num  __asm__ ("x8") = (num);                           \
9337d62758SAmmar Faizi 	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
9437d62758SAmmar Faizi 	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
9537d62758SAmmar Faizi 	register long _arg3 __asm__ ("x2") = (long)(arg3);                    \
9637d62758SAmmar Faizi 	register long _arg4 __asm__ ("x3") = (long)(arg4);                    \
97271661c1SWilly Tarreau 									      \
9837d62758SAmmar Faizi 	__asm__ volatile (                                                    \
99271661c1SWilly Tarreau 		"svc #0\n"                                                    \
100271661c1SWilly Tarreau 		: "=r"(_arg1)                                                 \
101271661c1SWilly Tarreau 		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4),             \
102271661c1SWilly Tarreau 		  "r"(_num)                                                   \
103271661c1SWilly Tarreau 		: "memory", "cc"                                              \
104271661c1SWilly Tarreau 	);                                                                    \
105271661c1SWilly Tarreau 	_arg1;                                                                \
106271661c1SWilly Tarreau })
107271661c1SWilly Tarreau 
108271661c1SWilly Tarreau #define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)                        \
109271661c1SWilly Tarreau ({                                                                            \
11037d62758SAmmar Faizi 	register long _num  __asm__ ("x8") = (num);                           \
11137d62758SAmmar Faizi 	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
11237d62758SAmmar Faizi 	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
11337d62758SAmmar Faizi 	register long _arg3 __asm__ ("x2") = (long)(arg3);                    \
11437d62758SAmmar Faizi 	register long _arg4 __asm__ ("x3") = (long)(arg4);                    \
11537d62758SAmmar Faizi 	register long _arg5 __asm__ ("x4") = (long)(arg5);                    \
116271661c1SWilly Tarreau 									      \
11737d62758SAmmar Faizi 	__asm__ volatile (                                                    \
118271661c1SWilly Tarreau 		"svc #0\n"                                                    \
119271661c1SWilly Tarreau 		: "=r" (_arg1)                                                \
120271661c1SWilly Tarreau 		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
121271661c1SWilly Tarreau 		  "r"(_num)                                                   \
122271661c1SWilly Tarreau 		: "memory", "cc"                                              \
123271661c1SWilly Tarreau 	);                                                                    \
124271661c1SWilly Tarreau 	_arg1;                                                                \
125271661c1SWilly Tarreau })
126271661c1SWilly Tarreau 
127271661c1SWilly Tarreau #define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)                  \
128271661c1SWilly Tarreau ({                                                                            \
12937d62758SAmmar Faizi 	register long _num  __asm__ ("x8") = (num);                           \
13037d62758SAmmar Faizi 	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
13137d62758SAmmar Faizi 	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
13237d62758SAmmar Faizi 	register long _arg3 __asm__ ("x2") = (long)(arg3);                    \
13337d62758SAmmar Faizi 	register long _arg4 __asm__ ("x3") = (long)(arg4);                    \
13437d62758SAmmar Faizi 	register long _arg5 __asm__ ("x4") = (long)(arg5);                    \
13537d62758SAmmar Faizi 	register long _arg6 __asm__ ("x5") = (long)(arg6);                    \
136271661c1SWilly Tarreau 									      \
13737d62758SAmmar Faizi 	__asm__ volatile (                                                    \
138271661c1SWilly Tarreau 		"svc #0\n"                                                    \
139271661c1SWilly Tarreau 		: "=r" (_arg1)                                                \
140271661c1SWilly Tarreau 		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
141271661c1SWilly Tarreau 		  "r"(_arg6), "r"(_num)                                       \
142271661c1SWilly Tarreau 		: "memory", "cc"                                              \
143271661c1SWilly Tarreau 	);                                                                    \
144271661c1SWilly Tarreau 	_arg1;                                                                \
145271661c1SWilly Tarreau })
146271661c1SWilly Tarreau 
147271661c1SWilly Tarreau /* startup code */
_start(void)148bff60150SZhangjin Wu void __attribute__((weak, noreturn, optimize("Os", "omit-frame-pointer"))) __no_stack_protector _start(void)
1497f854858SWilly Tarreau {
1507f854858SWilly Tarreau 	__asm__ volatile (
151*ded8af47SZhangjin Wu 		"mov x0, sp\n"          /* save stack pointer to x0, as arg1 of _start_c */
152*ded8af47SZhangjin Wu 		"and sp, x0, -16\n"     /* sp must be 16-byte aligned in the callee      */
153*ded8af47SZhangjin Wu 		"bl  _start_c\n"        /* transfer to c runtime                         */
1547f854858SWilly Tarreau 	);
1557f854858SWilly Tarreau 	__builtin_unreachable();
1567f854858SWilly Tarreau }
157fddc8f81SThomas Weißschuh #endif /* _NOLIBC_ARCH_AARCH64_H */
158