github.com/miolini/go@v0.0.0-20160405192216-fca68c8cb408/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  	MOVW	R13, R4
   343  	SUB	$24, R13
   344  	BIC	$0x7, R13 // alignment for ELF ABI
   345  	BL	(R11)
   346  	MOVW	R4, R13
   347  	RET
   348  
   349  TEXT runtime·sigtramp(SB),NOSPLIT,$12
   350  	// this might be called in external code context,
   351  	// where g is not set.
   352  	// first save R0, because runtime·load_g will clobber it
   353  	MOVW	R0, 4(R13)
   354  	MOVB	runtime·iscgo(SB), R0
   355  	CMP 	$0, R0
   356  	BL.NE	runtime·load_g(SB)
   357  
   358  	MOVW	R1, 8(R13)
   359  	MOVW	R2, 12(R13)
   360  	MOVW  	$runtime·sigtrampgo(SB), R11
   361  	BL	(R11)
   362  	RET
   363  
   364  TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
   365  	MOVW  	$runtime·sigtramp(SB), R11
   366  	B	(R11)
   367  
   368  TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0
   369  	MOVW	sig+0(FP), R0
   370  	MOVW	new+4(FP), R1
   371  	MOVW	old+8(FP), R2
   372  	MOVW	size+12(FP), R3
   373  	MOVW	$SYS_rt_sigprocmask, R7
   374  	SWI	$0
   375  	RET
   376  
   377  TEXT runtime·rt_sigaction(SB),NOSPLIT,$0
   378  	MOVW	sig+0(FP), R0
   379  	MOVW	new+4(FP), R1
   380  	MOVW	old+8(FP), R2
   381  	MOVW	size+12(FP), R3
   382  	MOVW	$SYS_rt_sigaction, R7
   383  	SWI	$0
   384  	MOVW	R0, ret+16(FP)
   385  	RET
   386  
   387  TEXT runtime·usleep(SB),NOSPLIT,$12
   388  	MOVW	usec+0(FP), R0
   389  	CALL	runtime·usplitR0(SB)
   390  	MOVW	R0, 4(R13)
   391  	MOVW	R1, 8(R13)
   392  	MOVW	$0, R0
   393  	MOVW	$0, R1
   394  	MOVW	$0, R2
   395  	MOVW	$0, R3
   396  	MOVW	$4(R13), R4
   397  	MOVW	$SYS_select, R7
   398  	SWI	$0
   399  	RET
   400  
   401  // As for cas, memory barriers are complicated on ARM, but the kernel
   402  // provides a user helper. ARMv5 does not support SMP and has no
   403  // memory barrier instruction at all. ARMv6 added SMP support and has
   404  // a memory barrier, but it requires writing to a coprocessor
   405  // register. ARMv7 introduced the DMB instruction, but it's expensive
   406  // even on single-core devices. The kernel helper takes care of all of
   407  // this for us.
   408  
   409  TEXT publicationBarrier<>(SB),NOSPLIT,$0
   410  	// void __kuser_memory_barrier(void);
   411  	MOVW	$0xffff0fa0, R15 // R15 is hardware PC.
   412  
   413  TEXT ·publicationBarrier(SB),NOSPLIT,$0
   414  	BL	publicationBarrier<>(SB)
   415  	RET
   416  
   417  TEXT runtime·osyield(SB),NOSPLIT,$0
   418  	MOVW	$SYS_sched_yield, R7
   419  	SWI	$0
   420  	RET
   421  
   422  TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0
   423  	MOVW	pid+0(FP), R0
   424  	MOVW	len+4(FP), R1
   425  	MOVW	buf+8(FP), R2
   426  	MOVW	$SYS_sched_getaffinity, R7
   427  	SWI	$0
   428  	MOVW	R0, ret+12(FP)
   429  	RET
   430  
   431  // int32 runtime·epollcreate(int32 size)
   432  TEXT runtime·epollcreate(SB),NOSPLIT,$0
   433  	MOVW	size+0(FP), R0
   434  	MOVW	$SYS_epoll_create, R7
   435  	SWI	$0
   436  	MOVW	R0, ret+4(FP)
   437  	RET
   438  
   439  // int32 runtime·epollcreate1(int32 flags)
   440  TEXT runtime·epollcreate1(SB),NOSPLIT,$0
   441  	MOVW	flags+0(FP), R0
   442  	MOVW	$SYS_epoll_create1, R7
   443  	SWI	$0
   444  	MOVW	R0, ret+4(FP)
   445  	RET
   446  
   447  // func epollctl(epfd, op, fd int32, ev *epollEvent) int
   448  TEXT runtime·epollctl(SB),NOSPLIT,$0
   449  	MOVW	epfd+0(FP), R0
   450  	MOVW	op+4(FP), R1
   451  	MOVW	fd+8(FP), R2
   452  	MOVW	ev+12(FP), R3
   453  	MOVW	$SYS_epoll_ctl, R7
   454  	SWI	$0
   455  	MOVW	R0, ret+16(FP)
   456  	RET
   457  
   458  // int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout)
   459  TEXT runtime·epollwait(SB),NOSPLIT,$0
   460  	MOVW	epfd+0(FP), R0
   461  	MOVW	ev+4(FP), R1
   462  	MOVW	nev+8(FP), R2
   463  	MOVW	timeout+12(FP), R3
   464  	MOVW	$SYS_epoll_wait, R7
   465  	SWI	$0
   466  	MOVW	R0, ret+16(FP)
   467  	RET
   468  
   469  // void runtime·closeonexec(int32 fd)
   470  TEXT runtime·closeonexec(SB),NOSPLIT,$0
   471  	MOVW	fd+0(FP), R0	// fd
   472  	MOVW	$2, R1	// F_SETFD
   473  	MOVW	$1, R2	// FD_CLOEXEC
   474  	MOVW	$SYS_fcntl, R7
   475  	SWI	$0
   476  	RET
   477  
   478  // b __kuser_get_tls @ 0xffff0fe0
   479  TEXT runtime·read_tls_fallback(SB),NOSPLIT,$-4
   480  	MOVW	$0xffff0fe0, R0
   481  	B	(R0)
   482  
   483  TEXT runtime·access(SB),NOSPLIT,$0
   484  	MOVW	name+0(FP), R0
   485  	MOVW	mode+4(FP), R1
   486  	MOVW	$SYS_access, R7
   487  	SWI	$0
   488  	MOVW	R0, ret+8(FP)
   489  	RET
   490  
   491  TEXT runtime·connect(SB),NOSPLIT,$0
   492  	MOVW	fd+0(FP), R0
   493  	MOVW	addr+4(FP), R1
   494  	MOVW	addrlen+8(FP), R2
   495  	MOVW	$SYS_connect, R7
   496  	SWI	$0
   497  	MOVW	R0, ret+12(FP)
   498  	RET
   499  
   500  TEXT runtime·socket(SB),NOSPLIT,$0
   501  	MOVW	domain+0(FP), R0
   502  	MOVW	type+4(FP), R1
   503  	MOVW	protocol+8(FP), R2
   504  	MOVW	$SYS_socket, R7
   505  	SWI	$0
   506  	MOVW	R0, ret+12(FP)
   507  	RET