Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
  1/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
  2/*
  3 * AARCH64 specific definitions for NOLIBC
  4 * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
  5 */
  6
  7#ifndef _NOLIBC_ARCH_AARCH64_H
  8#define _NOLIBC_ARCH_AARCH64_H
  9
 10/* O_* macros for fcntl/open are architecture-specific */
 11#define O_RDONLY            0
 12#define O_WRONLY            1
 13#define O_RDWR              2
 14#define O_CREAT          0x40
 15#define O_EXCL           0x80
 16#define O_NOCTTY        0x100
 17#define O_TRUNC         0x200
 18#define O_APPEND        0x400
 19#define O_NONBLOCK      0x800
 20#define O_DIRECTORY    0x4000
 21
 22/* The struct returned by the newfstatat() syscall. Differs slightly from the
 23 * x86_64's stat one by field ordering, so be careful.
 24 */
 25struct sys_stat_struct {
 26	unsigned long   st_dev;
 27	unsigned long   st_ino;
 28	unsigned int    st_mode;
 29	unsigned int    st_nlink;
 30	unsigned int    st_uid;
 31	unsigned int    st_gid;
 32
 33	unsigned long   st_rdev;
 34	unsigned long   __pad1;
 35	long            st_size;
 36	int             st_blksize;
 37	int             __pad2;
 38
 39	long            st_blocks;
 40	long            st_atime;
 41	unsigned long   st_atime_nsec;
 42	long            st_mtime;
 43
 44	unsigned long   st_mtime_nsec;
 45	long            st_ctime;
 46	unsigned long   st_ctime_nsec;
 47	unsigned int    __unused[2];
 48};
 49
 50/* Syscalls for AARCH64 :
 51 *   - registers are 64-bit
 52 *   - stack is 16-byte aligned
 53 *   - syscall number is passed in x8
 54 *   - arguments are in x0, x1, x2, x3, x4, x5
 55 *   - the system call is performed by calling svc 0
 56 *   - syscall return comes in x0.
 57 *   - the arguments are cast to long and assigned into the target registers
 58 *     which are then simply passed as registers to the asm code, so that we
 59 *     don't have to experience issues with register constraints.
 60 *
 61 * On aarch64, select() is not implemented so we have to use pselect6().
 62 */
 63#define __ARCH_WANT_SYS_PSELECT6
 64
 65#define my_syscall0(num)                                                      \
 66({                                                                            \
 67	register long _num  __asm__ ("x8") = (num);                           \
 68	register long _arg1 __asm__ ("x0");                                   \
 69	                                                                      \
 70	__asm__  volatile (                                                   \
 71		"svc #0\n"                                                    \
 72		: "=r"(_arg1)                                                 \
 73		: "r"(_num)                                                   \
 74		: "memory", "cc"                                              \
 75	);                                                                    \
 76	_arg1;                                                                \
 77})
 78
 79#define my_syscall1(num, arg1)                                                \
 80({                                                                            \
 81	register long _num  __asm__ ("x8") = (num);                           \
 82	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
 83	                                                                      \
 84	__asm__  volatile (                                                   \
 85		"svc #0\n"                                                    \
 86		: "=r"(_arg1)                                                 \
 87		: "r"(_arg1),                                                 \
 88		  "r"(_num)                                                   \
 89		: "memory", "cc"                                              \
 90	);                                                                    \
 91	_arg1;                                                                \
 92})
 93
 94#define my_syscall2(num, arg1, arg2)                                          \
 95({                                                                            \
 96	register long _num  __asm__ ("x8") = (num);                           \
 97	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
 98	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
 99	                                                                      \
100	__asm__  volatile (                                                   \
101		"svc #0\n"                                                    \
102		: "=r"(_arg1)                                                 \
103		: "r"(_arg1), "r"(_arg2),                                     \
104		  "r"(_num)                                                   \
105		: "memory", "cc"                                              \
106	);                                                                    \
107	_arg1;                                                                \
108})
109
110#define my_syscall3(num, arg1, arg2, arg3)                                    \
111({                                                                            \
112	register long _num  __asm__ ("x8") = (num);                           \
113	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
114	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
115	register long _arg3 __asm__ ("x2") = (long)(arg3);                    \
116	                                                                      \
117	__asm__  volatile (                                                   \
118		"svc #0\n"                                                    \
119		: "=r"(_arg1)                                                 \
120		: "r"(_arg1), "r"(_arg2), "r"(_arg3),                         \
121		  "r"(_num)                                                   \
122		: "memory", "cc"                                              \
123	);                                                                    \
124	_arg1;                                                                \
125})
126
127#define my_syscall4(num, arg1, arg2, arg3, arg4)                              \
128({                                                                            \
129	register long _num  __asm__ ("x8") = (num);                           \
130	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
131	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
132	register long _arg3 __asm__ ("x2") = (long)(arg3);                    \
133	register long _arg4 __asm__ ("x3") = (long)(arg4);                    \
134	                                                                      \
135	__asm__  volatile (                                                   \
136		"svc #0\n"                                                    \
137		: "=r"(_arg1)                                                 \
138		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4),             \
139		  "r"(_num)                                                   \
140		: "memory", "cc"                                              \
141	);                                                                    \
142	_arg1;                                                                \
143})
144
145#define my_syscall5(num, arg1, arg2, arg3, arg4, arg5)                        \
146({                                                                            \
147	register long _num  __asm__ ("x8") = (num);                           \
148	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
149	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
150	register long _arg3 __asm__ ("x2") = (long)(arg3);                    \
151	register long _arg4 __asm__ ("x3") = (long)(arg4);                    \
152	register long _arg5 __asm__ ("x4") = (long)(arg5);                    \
153	                                                                      \
154	__asm__  volatile (                                                   \
155		"svc #0\n"                                                    \
156		: "=r" (_arg1)                                                \
157		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
158		  "r"(_num)                                                   \
159		: "memory", "cc"                                              \
160	);                                                                    \
161	_arg1;                                                                \
162})
163
164#define my_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)                  \
165({                                                                            \
166	register long _num  __asm__ ("x8") = (num);                           \
167	register long _arg1 __asm__ ("x0") = (long)(arg1);                    \
168	register long _arg2 __asm__ ("x1") = (long)(arg2);                    \
169	register long _arg3 __asm__ ("x2") = (long)(arg3);                    \
170	register long _arg4 __asm__ ("x3") = (long)(arg4);                    \
171	register long _arg5 __asm__ ("x4") = (long)(arg5);                    \
172	register long _arg6 __asm__ ("x5") = (long)(arg6);                    \
173	                                                                      \
174	__asm__  volatile (                                                   \
175		"svc #0\n"                                                    \
176		: "=r" (_arg1)                                                \
177		: "r"(_arg1), "r"(_arg2), "r"(_arg3), "r"(_arg4), "r"(_arg5), \
178		  "r"(_arg6), "r"(_num)                                       \
179		: "memory", "cc"                                              \
180	);                                                                    \
181	_arg1;                                                                \
182})
183
184/* startup code */
185__asm__ (".section .text\n"
186    ".weak _start\n"
187    "_start:\n"
188    "ldr x0, [sp]\n"              // argc (x0) was in the stack
189    "add x1, sp, 8\n"             // argv (x1) = sp
190    "lsl x2, x0, 3\n"             // envp (x2) = 8*argc ...
191    "add x2, x2, 8\n"             //           + 8 (skip null)
192    "add x2, x2, x1\n"            //           + argv
193    "and sp, x1, -16\n"           // sp must be 16-byte aligned in the callee
194    "bl main\n"                   // main() returns the status code, we'll exit with it.
195    "mov x8, 93\n"                // NR_exit == 93
196    "svc #0\n"
197    "");
198
199#endif // _NOLIBC_ARCH_AARCH64_H