vtgl

terminal emulator implemented in OpenGL
git clone anongit@rnpnr.xyz:vtgl.git
Log | Files | Refs | Feed | LICENSE

os_linux_aarch64.c (4113B)


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