github.com/fjballest/golang@v0.0.0-20151209143359-e4c5fe594ca8/src/runtime/sys_linux_arm.s (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //
     6  // System calls and other sys.stuff for arm, Linux
     7  //
     8  
     9  #include "go_asm.h"
    10  #include "go_tls.h"
    11  #include "textflag.h"
    12  
    13  // for EABI, as we don't support OABI
    14  #define SYS_BASE 0x0
    15  
    16  #define SYS_exit (SYS_BASE + 1)
    17  #define SYS_read (SYS_BASE + 3)
    18  #define SYS_write (SYS_BASE + 4)
    19  #define SYS_open (SYS_BASE + 5)
    20  #define SYS_close (SYS_BASE + 6)
    21  #define SYS_getpid (SYS_BASE + 20)
    22  #define SYS_kill (SYS_BASE + 37)
    23  #define SYS_gettimeofday (SYS_BASE + 78)
    24  #define SYS_clone (SYS_BASE + 120)
    25  #define SYS_rt_sigreturn (SYS_BASE + 173)
    26  #define SYS_rt_sigaction (SYS_BASE + 174)
    27  #define SYS_rt_sigprocmask (SYS_BASE + 175)
    28  #define SYS_sigaltstack (SYS_BASE + 186)
    29  #define SYS_mmap2 (SYS_BASE + 192)
    30  #define SYS_futex (SYS_BASE + 240)
    31  #define SYS_exit_group (SYS_BASE + 248)
    32  #define SYS_munmap (SYS_BASE + 91)
    33  #define SYS_madvise (SYS_BASE + 220)
    34  #define SYS_setitimer (SYS_BASE + 104)
    35  #define SYS_mincore (SYS_BASE + 219)
    36  #define SYS_gettid (SYS_BASE + 224)
    37  #define SYS_tkill (SYS_BASE + 238)
    38  #define SYS_sched_yield (SYS_BASE + 158)
    39  #define SYS_select (SYS_BASE + 142) // newselect
    40  #define SYS_ugetrlimit (SYS_BASE + 191)
    41  #define SYS_sched_getaffinity (SYS_BASE + 242)
    42  #define SYS_clock_gettime (SYS_BASE + 263)
    43  #define SYS_epoll_create (SYS_BASE + 250)
    44  #define SYS_epoll_ctl (SYS_BASE + 251)
    45  #define SYS_epoll_wait (SYS_BASE + 252)
    46  #define SYS_epoll_create1 (SYS_BASE + 357)
    47  #define SYS_fcntl (SYS_BASE + 55)
    48  #define SYS_access (SYS_BASE + 33)
    49  #define SYS_connect (SYS_BASE + 283)
    50  #define SYS_socket (SYS_BASE + 281)
    51  
    52  #define ARM_BASE (SYS_BASE + 0x0f0000)
    53  
    54  TEXT runtime·open(SB),NOSPLIT,$0
    55  	MOVW	name+0(FP), R0
    56  	MOVW	mode+4(FP), R1
    57  	MOVW	perm+8(FP), R2
    58  	MOVW	$SYS_open, R7
    59  	SWI	$0
    60  	MOVW	$0xfffff001, R1
    61  	CMP	R1, R0
    62  	MOVW.HI	$-1, R0
    63  	MOVW	R0, ret+12(FP)
    64  	RET
    65  
    66  TEXT runtime·closefd(SB),NOSPLIT,$0
    67  	MOVW	fd+0(FP), R0
    68  	MOVW	$SYS_close, R7
    69  	SWI	$0
    70  	MOVW	$0xfffff001, R1
    71  	CMP	R1, R0
    72  	MOVW.HI	$-1, R0
    73  	MOVW	R0, ret+4(FP)
    74  	RET
    75  
    76  TEXT runtime·write(SB),NOSPLIT,$0
    77  	MOVW	fd+0(FP), R0
    78  	MOVW	p+4(FP), R1
    79  	MOVW	n+8(FP), R2
    80  	MOVW	$SYS_write, R7
    81  	SWI	$0
    82  	MOVW	$0xfffff001, R1
    83  	CMP	R1, R0
    84  	MOVW.HI	$-1, R0
    85  	MOVW	R0, ret+12(FP)
    86  	RET
    87  
    88  TEXT runtime·read(SB),NOSPLIT,$0
    89  	MOVW	fd+0(FP), R0
    90  	MOVW	p+4(FP), R1
    91  	MOVW	n+8(FP), R2
    92  	MOVW	$SYS_read, R7
    93  	SWI	$0
    94  	MOVW	$0xfffff001, R1
    95  	CMP	R1, R0
    96  	MOVW.HI	$-1, R0
    97  	MOVW	R0, ret+12(FP)
    98  	RET
    99  
   100  TEXT runtime·getrlimit(SB),NOSPLIT,$0
   101  	MOVW	kind+0(FP), R0
   102  	MOVW	limit+4(FP), R1
   103  	MOVW	$SYS_ugetrlimit, R7
   104  	SWI	$0
   105  	MOVW	R0, ret+8(FP)
   106  	RET
   107  
   108  TEXT runtime·exit(SB),NOSPLIT,$-4
   109  	MOVW	code+0(FP), R0
   110  	MOVW	$SYS_exit_group, R7
   111  	SWI	$0
   112  	MOVW	$1234, R0
   113  	MOVW	$1002, R1
   114  	MOVW	R0, (R1)	// fail hard
   115  
   116  TEXT runtime·exit1(SB),NOSPLIT,$-4
   117  	MOVW	code+0(FP), R0
   118  	MOVW	$SYS_exit, R7
   119  	SWI	$0
   120  	MOVW	$1234, R0
   121  	MOVW	$1003, R1
   122  	MOVW	R0, (R1)	// fail hard
   123  
   124  TEXT runtime·gettid(SB),NOSPLIT,$0-4
   125  	MOVW	$SYS_gettid, R7
   126  	SWI	$0
   127  	MOVW	R0, ret+0(FP)
   128  	RET
   129  
   130  TEXT	runtime·raise(SB),NOSPLIT,$-4
   131  	MOVW	$SYS_gettid, R7
   132  	SWI	$0
   133  	// arg 1 tid already in R0 from gettid
   134  	MOVW	sig+0(FP), R1	// arg 2 - signal
   135  	MOVW	$SYS_tkill, R7
   136  	SWI	$0
   137  	RET
   138  
   139  TEXT	runtime·raiseproc(SB),NOSPLIT,$-4
   140  	MOVW	$SYS_getpid, R7
   141  	SWI	$0
   142  	// arg 1 tid already in R0 from getpid
   143  	MOVW	sig+0(FP), R1	// arg 2 - signal
   144  	MOVW	$SYS_kill, R7
   145  	SWI	$0
   146  	RET
   147  
   148  TEXT runtime·mmap(SB),NOSPLIT,$0
   149  	MOVW	addr+0(FP), R0
   150  	MOVW	n+4(FP), R1
   151  	MOVW	prot+8(FP), R2
   152  	MOVW	flags+12(FP), R3
   153  	MOVW	fd+16(FP), R4
   154  	MOVW	off+20(FP), R5
   155  	MOVW	$SYS_mmap2, R7
   156  	SWI	$0
   157  	MOVW	$0xfffff001, R6
   158  	CMP		R6, R0
   159  	RSB.HI	$0, R0
   160  	MOVW	R0, ret+24(FP)
   161  	RET
   162  
   163  TEXT runtime·munmap(SB),NOSPLIT,$0
   164  	MOVW	addr+0(FP), R0
   165  	MOVW	n+4(FP), R1
   166  	MOVW	$SYS_munmap, R7
   167  	SWI	$0
   168  	MOVW	$0xfffff001, R6
   169  	CMP 	R6, R0
   170  	MOVW.HI	$0, R8  // crash on syscall failure
   171  	MOVW.HI	R8, (R8)
   172  	RET
   173  
   174  TEXT runtime·madvise(SB),NOSPLIT,$0
   175  	MOVW	addr+0(FP), R0
   176  	MOVW	n+4(FP), R1
   177  	MOVW	flags+8(FP), R2
   178  	MOVW	$SYS_madvise, R7
   179  	SWI	$0
   180  	// ignore failure - maybe pages are locked
   181  	RET
   182  
   183  TEXT runtime·setitimer(SB),NOSPLIT,$0
   184  	MOVW	mode+0(FP), R0
   185  	MOVW	new+4(FP), R1
   186  	MOVW	old+8(FP), R2
   187  	MOVW	$SYS_setitimer, R7
   188  	SWI	$0
   189  	RET
   190  
   191  TEXT runtime·mincore(SB),NOSPLIT,$0
   192  	MOVW	addr+0(FP), R0
   193  	MOVW	n+4(FP), R1
   194  	MOVW	dst+8(FP), R2
   195  	MOVW	$SYS_mincore, R7
   196  	SWI	$0
   197  	MOVW	R0, ret+12(FP)
   198  	RET
   199  
   200  TEXT time·now(SB), NOSPLIT, $32
   201  	MOVW	$0, R0  // CLOCK_REALTIME
   202  	MOVW	$8(R13), R1  // timespec
   203  	MOVW	$SYS_clock_gettime, R7
   204  	SWI	$0
   205  	
   206  	MOVW	8(R13), R0  // sec
   207  	MOVW	12(R13), R2  // nsec
   208  	
   209  	MOVW	R0, sec+0(FP)
   210  	MOVW	$0, R1
   211  	MOVW	R1, loc+4(FP)
   212  	MOVW	R2, nsec+8(FP)
   213  	RET	
   214  
   215  // int64 nanotime(void)
   216  TEXT runtime·nanotime(SB),NOSPLIT,$32
   217  	MOVW	$1, R0  // CLOCK_MONOTONIC
   218  	MOVW	$8(R13), R1  // timespec
   219  	MOVW	$SYS_clock_gettime, R7
   220  	SWI	$0
   221  	
   222  	MOVW	8(R13), R0  // sec
   223  	MOVW	12(R13), R2  // nsec
   224  	
   225  	MOVW	$1000000000, R3
   226  	MULLU	R0, R3, (R1, R0)
   227  	MOVW	$0, R4
   228  	ADD.S	R2, R0
   229  	ADC	R4, R1
   230  
   231  	MOVW	R0, ret_lo+0(FP)
   232  	MOVW	R1, ret_hi+4(FP)
   233  	RET
   234  
   235  // int32 futex(int32 *uaddr, int32 op, int32 val,
   236  //	struct timespec *timeout, int32 *uaddr2, int32 val2);
   237  TEXT runtime·futex(SB),NOSPLIT,$0
   238  	// TODO: Rewrite to use FP references. Vet complains.
   239  	MOVW	4(R13), R0
   240  	MOVW	8(R13), R1
   241  	MOVW	12(R13), R2
   242  	MOVW	16(R13), R3
   243  	MOVW	20(R13), R4
   244  	MOVW	24(R13), R5
   245  	MOVW	$SYS_futex, R7
   246  	SWI	$0
   247  	MOVW	R0, ret+24(FP)
   248  	RET
   249  
   250  // int32 clone(int32 flags, void *stack, M *mp, G *gp, void (*fn)(void));
   251  TEXT runtime·clone(SB),NOSPLIT,$0
   252  	MOVW	flags+0(FP), R0
   253  	MOVW	stk+4(FP), R1
   254  	MOVW	$0, R2	// parent tid ptr
   255  	MOVW	$0, R3	// tls_val
   256  	MOVW	$0, R4	// child tid ptr
   257  	MOVW	$0, R5
   258  
   259  	// Copy mp, gp, fn off parent stack for use by child.
   260  	// TODO(kaib): figure out which registers are clobbered by clone and avoid stack copying
   261  	MOVW	$-16(R1), R1
   262  	MOVW	mm+8(FP), R6
   263  	MOVW	R6, 0(R1)
   264  	MOVW	gg+12(FP), R6
   265  	MOVW	R6, 4(R1)
   266  	MOVW	fn+16(FP), R6
   267  	MOVW	R6, 8(R1)
   268  	MOVW	$1234, R6
   269  	MOVW	R6, 12(R1)
   270  
   271  	MOVW	$SYS_clone, R7
   272  	SWI	$0
   273  
   274  	// In parent, return.
   275  	CMP	$0, R0
   276  	BEQ	3(PC)
   277  	MOVW	R0, ret+20(FP)
   278  	RET
   279  
   280  	// Paranoia: check that SP is as we expect. Use R13 to avoid linker 'fixup'
   281  	MOVW	12(R13), R0
   282  	MOVW	$1234, R1
   283  	CMP	R0, R1
   284  	BEQ	2(PC)
   285  	BL	runtime·abort(SB)
   286  
   287  	MOVW	0(R13), R8    // m
   288  	MOVW	4(R13), R0    // g
   289  
   290  	CMP	$0, R8
   291  	BEQ	nog
   292  	CMP	$0, R0
   293  	BEQ	nog
   294  
   295  	MOVW	R0, g
   296  	MOVW	R8, g_m(g)
   297  
   298  	// paranoia; check they are not nil
   299  	MOVW	0(R8), R0
   300  	MOVW	0(g), R0
   301  
   302  	BL	runtime·emptyfunc(SB)	// fault if stack check is wrong
   303  
   304  	// Initialize m->procid to Linux tid
   305  	MOVW	$SYS_gettid, R7
   306  	SWI	$0
   307  	MOVW	g_m(g), R8
   308  	MOVW	R0, m_procid(R8)
   309  
   310  nog:
   311  	// Call fn
   312  	MOVW	8(R13), R0
   313  	MOVW	$16(R13), R13
   314  	BL	(R0)
   315  
   316  	// It shouldn't return.  If it does, exit that thread.
   317  	SUB	$16, R13 // restore the stack pointer to avoid memory corruption
   318  	MOVW	$0, R0
   319  	MOVW	R0, 4(R13)
   320  	BL	runtime·exit1(SB)
   321  
   322  	MOVW	$1234, R0
   323  	MOVW	$1005, R1
   324  	MOVW	R0, (R1)
   325  
   326  TEXT runtime·sigaltstack(SB),NOSPLIT,$0
   327  	MOVW	new+0(FP), R0
   328  	MOVW	old+4(FP), R1
   329  	MOVW	$SYS_sigaltstack, R7
   330  	SWI	$0
   331  	MOVW	$0xfffff001, R6
   332  	CMP 	R6, R0
   333  	MOVW.HI	$0, R8  // crash on syscall failure
   334  	MOVW.HI	R8, (R8)
   335  	RET
   336  
   337  TEXT runtime·sigfwd(SB),NOSPLIT,$0-16
   338  	MOVW	sig+4(FP), R0
   339  	MOVW	info+8(FP), R1
   340  	MOVW	ctx+12(FP), R2
   341  	MOVW	fn+0(FP), R11
   342  	BL	(R11)
   343  	RET
   344  
   345  TEXT runtime·sigtramp(SB),NOSPLIT,$12
   346  	// this might be called in external code context,
   347  	// where g is not set.
   348  	// first save R0, because runtime·load_g will clobber it
   349  	MOVW	R0, 4(R13)
   350  	MOVB	runtime·iscgo(SB), R0
   351  	CMP 	$0, R0
   352  	BL.NE	runtime·load_g(SB)
   353  
   354  	MOVW	R1, 8(R13)
   355  	MOVW	R2, 12(R13)
   356  	MOVW  	$runtime·sigtrampgo(SB), R11
   357  	BL	(R11)
   358  	RET
   359  
   360  TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0
   361  	MOVW	sig+0(FP), R0
   362  	MOVW	new+4(FP), R1
   363  	MOVW	old+8(FP), R2
   364  	MOVW	size+12(FP), R3
   365  	MOVW	$SYS_rt_sigprocmask, R7
   366  	SWI	$0
   367  	RET
   368  
   369  TEXT runtime·rt_sigaction(SB),NOSPLIT,$0
   370  	MOVW	sig+0(FP), R0
   371  	MOVW	new+4(FP), R1
   372  	MOVW	old+8(FP), R2
   373  	MOVW	size+12(FP), R3
   374  	MOVW	$SYS_rt_sigaction, R7
   375  	SWI	$0
   376  	MOVW	R0, ret+16(FP)
   377  	RET
   378  
   379  TEXT runtime·usleep(SB),NOSPLIT,$12
   380  	MOVW	usec+0(FP), R0
   381  	CALL	runtime·usplitR0(SB)
   382  	MOVW	R0, 4(R13)
   383  	MOVW	R1, 8(R13)
   384  	MOVW	$0, R0
   385  	MOVW	$0, R1
   386  	MOVW	$0, R2
   387  	MOVW	$0, R3
   388  	MOVW	$4(R13), R4
   389  	MOVW	$SYS_select, R7
   390  	SWI	$0
   391  	RET
   392  
   393  // As for cas, memory barriers are complicated on ARM, but the kernel
   394  // provides a user helper. ARMv5 does not support SMP and has no
   395  // memory barrier instruction at all. ARMv6 added SMP support and has
   396  // a memory barrier, but it requires writing to a coprocessor
   397  // register. ARMv7 introduced the DMB instruction, but it's expensive
   398  // even on single-core devices. The kernel helper takes care of all of
   399  // this for us.
   400  
   401  TEXT publicationBarrier<>(SB),NOSPLIT,$0
   402  	// void __kuser_memory_barrier(void);
   403  	MOVW	$0xffff0fa0, R15 // R15 is hardware PC.
   404  
   405  TEXT ·publicationBarrier(SB),NOSPLIT,$0
   406  	BL	publicationBarrier<>(SB)
   407  	RET
   408  
   409  TEXT runtime·osyield(SB),NOSPLIT,$0
   410  	MOVW	$SYS_sched_yield, R7
   411  	SWI	$0
   412  	RET
   413  
   414  TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0
   415  	MOVW	pid+0(FP), R0
   416  	MOVW	len+4(FP), R1
   417  	MOVW	buf+8(FP), R2
   418  	MOVW	$SYS_sched_getaffinity, R7
   419  	SWI	$0
   420  	MOVW	R0, ret+12(FP)
   421  	RET
   422  
   423  // int32 runtime·epollcreate(int32 size)
   424  TEXT runtime·epollcreate(SB),NOSPLIT,$0
   425  	MOVW	size+0(FP), R0
   426  	MOVW	$SYS_epoll_create, R7
   427  	SWI	$0
   428  	MOVW	R0, ret+4(FP)
   429  	RET
   430  
   431  // int32 runtime·epollcreate1(int32 flags)
   432  TEXT runtime·epollcreate1(SB),NOSPLIT,$0
   433  	MOVW	flags+0(FP), R0
   434  	MOVW	$SYS_epoll_create1, R7
   435  	SWI	$0
   436  	MOVW	R0, ret+4(FP)
   437  	RET
   438  
   439  // func epollctl(epfd, op, fd int32, ev *epollEvent) int
   440  TEXT runtime·epollctl(SB),NOSPLIT,$0
   441  	MOVW	epfd+0(FP), R0
   442  	MOVW	op+4(FP), R1
   443  	MOVW	fd+8(FP), R2
   444  	MOVW	ev+12(FP), R3
   445  	MOVW	$SYS_epoll_ctl, R7
   446  	SWI	$0
   447  	MOVW	R0, ret+16(FP)
   448  	RET
   449  
   450  // int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout)
   451  TEXT runtime·epollwait(SB),NOSPLIT,$0
   452  	MOVW	epfd+0(FP), R0
   453  	MOVW	ev+4(FP), R1
   454  	MOVW	nev+8(FP), R2
   455  	MOVW	timeout+12(FP), R3
   456  	MOVW	$SYS_epoll_wait, R7
   457  	SWI	$0
   458  	MOVW	R0, ret+16(FP)
   459  	RET
   460  
   461  // void runtime·closeonexec(int32 fd)
   462  TEXT runtime·closeonexec(SB),NOSPLIT,$0
   463  	MOVW	fd+0(FP), R0	// fd
   464  	MOVW	$2, R1	// F_SETFD
   465  	MOVW	$1, R2	// FD_CLOEXEC
   466  	MOVW	$SYS_fcntl, R7
   467  	SWI	$0
   468  	RET
   469  
   470  // b __kuser_get_tls @ 0xffff0fe0
   471  TEXT runtime·read_tls_fallback(SB),NOSPLIT,$-4
   472  	MOVW	$0xffff0fe0, R0
   473  	B	(R0)
   474  
   475  TEXT runtime·access(SB),NOSPLIT,$0
   476  	MOVW	name+0(FP), R0
   477  	MOVW	mode+4(FP), R1
   478  	MOVW	$SYS_access, R7
   479  	SWI	$0
   480  	MOVW	R0, ret+8(FP)
   481  	RET
   482  
   483  TEXT runtime·connect(SB),NOSPLIT,$0
   484  	MOVW	fd+0(FP), R0
   485  	MOVW	addr+4(FP), R1
   486  	MOVW	addrlen+8(FP), R2
   487  	MOVW	$SYS_connect, R7
   488  	SWI	$0
   489  	MOVW	R0, ret+12(FP)
   490  	RET
   491  
   492  TEXT runtime·socket(SB),NOSPLIT,$0
   493  	MOVW	domain+0(FP), R0
   494  	MOVW	type+4(FP), R1
   495  	MOVW	protocol+8(FP), R2
   496  	MOVW	$SYS_socket, R7
   497  	SWI	$0
   498  	MOVW	R0, ret+12(FP)
   499  	RET