platform_linux_aarch64.c (3999B)
1 /* TODO: generate this whole file with a metaprogram */ 2 3 /* See LICENSE for license details. */ 4 #ifndef asm 5 #ifdef __asm 6 #define asm __asm 7 #else 8 #define asm __asm__ 9 #endif 10 #endif 11 12 #define SYS_dup3 24 13 #define SYS_inotify_init1 26 14 #define SYS_inotify_add_watch 27 15 #define SYS_inotify_rm_watch 28 16 #define SYS_ioctl 29 17 #define SYS_ftruncate 46 18 #define SYS_openat 56 19 #define SYS_close 57 20 #define SYS_read 63 21 #define SYS_write 64 22 #define SYS_pwrite64 68 23 #define SYS_pselect6 72 24 #define SYS_exit_group 94 25 #define SYS_futex 98 26 #define SYS_clock_gettime 113 27 #define SYS_setsid 157 28 #define SYS_prctl 167 29 #define SYS_clone 220 30 #define SYS_execve 221 31 #define SYS_mmap 222 32 #define SYS_madvise 233 33 #define SYS_wait4 260 34 #define SYS_memfd_create 279 35 #define SYS_statx 291 36 37 #define SIGCHLD 17 38 39 /* NOTE(rnp): technically arm64 can have 4K, 16K or 64K pages but we will just assume 64K */ 40 #define PAGE_SIZE 65536 41 42 /* TODO: check that this is equivalent */ 43 typedef u64 sys_fd_set[16]; 44 45 static FORCE_INLINE i64 46 syscall0(i64 n) 47 { 48 register i64 x8 asm("x8") = n; 49 register i64 x0 asm("x0"); 50 asm volatile ("svc 0" 51 : "=x"(x0) 52 : "x"(x8) 53 : "memory", "cc" 54 ); 55 return x0; 56 } 57 58 static FORCE_INLINE i64 59 syscall1(i64 n, i64 a1) 60 { 61 register i64 x8 asm("x8") = n; 62 register i64 x0 asm("x0") = a1; 63 asm volatile ("svc 0" 64 : "+x"(x0) 65 : "x"(x8) 66 : "memory", "cc" 67 ); 68 return x0; 69 } 70 71 static FORCE_INLINE i64 72 syscall2(i64 n, i64 a1, i64 a2) 73 { 74 register i64 x8 asm("x8") = n; 75 register i64 x0 asm("x0") = a1; 76 register i64 x1 asm("x1") = a2; 77 asm volatile ("svc 0" 78 : "+x"(x0) 79 : "x"(x8), "x"(x1) 80 : "memory", "cc" 81 ); 82 return x0; 83 } 84 85 static FORCE_INLINE i64 86 syscall3(i64 n, i64 a1, i64 a2, i64 a3) 87 { 88 register i64 x8 asm("x8") = n; 89 register i64 x0 asm("x0") = a1; 90 register i64 x1 asm("x1") = a2; 91 register i64 x2 asm("x2") = a3; 92 asm volatile ("svc 0" 93 : "+x"(x0) 94 : "x"(x8), "x"(x1), "x"(x2) 95 : "memory", "cc" 96 ); 97 return x0; 98 } 99 100 static FORCE_INLINE i64 101 syscall4(i64 n, i64 a1, i64 a2, i64 a3, i64 a4) 102 { 103 register i64 x8 asm("x8") = n; 104 register i64 x0 asm("x0") = a1; 105 register i64 x1 asm("x1") = a2; 106 register i64 x2 asm("x2") = a3; 107 register i64 x3 asm("x3") = a4; 108 asm volatile ("svc 0" 109 : "+x"(x0) 110 : "x"(x8), "x"(x1), "x"(x2), "x"(x3) 111 : "memory", "cc" 112 ); 113 return x0; 114 } 115 116 static FORCE_INLINE i64 117 syscall5(i64 n, i64 a1, i64 a2, i64 a3, i64 a4, i64 a5) 118 { 119 register i64 x8 asm("x8") = n; 120 register i64 x0 asm("x0") = a1; 121 register i64 x1 asm("x1") = a2; 122 register i64 x2 asm("x2") = a3; 123 register i64 x3 asm("x3") = a4; 124 register i64 x4 asm("x4") = a5; 125 asm volatile ("svc 0" 126 : "+x"(x0) 127 : "x"(x8), "x"(x1), "x"(x2), "x"(x3), "x"(x4) 128 : "memory", "cc" 129 ); 130 return x0; 131 } 132 133 static FORCE_INLINE i64 134 syscall6(i64 n, i64 a1, i64 a2, i64 a3, i64 a4, i64 a5, i64 a6) 135 { 136 register i64 x8 asm("x8") = n; 137 register i64 x0 asm("x0") = a1; 138 register i64 x1 asm("x1") = a2; 139 register i64 x2 asm("x2") = a3; 140 register i64 x3 asm("x3") = a4; 141 register i64 x4 asm("x4") = a5; 142 register i64 x5 asm("x5") = a6; 143 asm volatile ("svc 0" 144 : "+x"(x0) 145 : "x"(x8), "x"(x1), "x"(x2), "x"(x3), "x"(x4), "x"(x5) 146 : "memory", "cc" 147 ); 148 return x0; 149 } 150 151 __attribute__((naked)) 152 static i64 153 new_thread(void *stack_base) 154 { 155 asm volatile ( 156 "mov x8, #220\n" // SYS_clone 157 "mov x1, x0\n" // arg2 = new stack 158 "mov x0, #0xF00\n" // arg1 = clone flags (VM|FS|FILES|SIGHAND|THREAD|SYSVMEM) 159 "movk x0, #0x5, lsl #16\n" // no 32 bit immediates in general on arm 160 "svc 0\n" 161 "cbnz x0, 1f\n" // don't clobber syscall return in calling thread 162 "mov x0, sp\n" 163 "ldr x1, [sp]\n" // arm doesn't take the return address from the stack; 164 "blr x1\n" // we need to load it and branch to it 165 "1: ret" 166 ::: "x8", "x1", "memory", "cc" 167 ); 168 } 169 170 #include "platform_linux_common.c"