...
Run Format

Text file src/runtime/sys_linux_arm.s

Documentation: runtime

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

View as plain text