Text file
src/runtime/sys_linux_riscv64.s
Documentation: runtime
1// Copyright 2015 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 riscv64, Linux
7//
8
9#include "textflag.h"
10#include "go_asm.h"
11
12#define AT_FDCWD -100
13#define CLOCK_REALTIME 0
14#define CLOCK_MONOTONIC 1
15
16#define SYS_brk 214
17#define SYS_clock_gettime 113
18#define SYS_clone 220
19#define SYS_close 57
20#define SYS_connect 203
21#define SYS_exit 93
22#define SYS_exit_group 94
23#define SYS_faccessat 48
24#define SYS_futex 98
25#define SYS_getpid 172
26#define SYS_gettid 178
27#define SYS_gettimeofday 169
28#define SYS_kill 129
29#define SYS_madvise 233
30#define SYS_mincore 232
31#define SYS_mmap 222
32#define SYS_munmap 215
33#define SYS_nanosleep 101
34#define SYS_openat 56
35#define SYS_pipe2 59
36#define SYS_pselect6 72
37#define SYS_read 63
38#define SYS_rt_sigaction 134
39#define SYS_rt_sigprocmask 135
40#define SYS_rt_sigreturn 139
41#define SYS_sched_getaffinity 123
42#define SYS_sched_yield 124
43#define SYS_setitimer 103
44#define SYS_sigaltstack 132
45#define SYS_socket 198
46#define SYS_tgkill 131
47#define SYS_timer_create 107
48#define SYS_timer_delete 111
49#define SYS_timer_settime 110
50#define SYS_tkill 130
51#define SYS_write 64
52
53// func exit(code int32)
54TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0-4
55 MOVW code+0(FP), A0
56 MOV $SYS_exit_group, A7
57 ECALL
58 RET
59
60// func exitThread(wait *atomic.Uint32)
61TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8
62 MOV wait+0(FP), A0
63 // We're done using the stack.
64 FENCE
65 MOVW ZERO, (A0)
66 FENCE
67 MOV $0, A0 // exit code
68 MOV $SYS_exit, A7
69 ECALL
70 JMP 0(PC)
71
72// func open(name *byte, mode, perm int32) int32
73TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0-20
74 MOV $AT_FDCWD, A0
75 MOV name+0(FP), A1
76 MOVW mode+8(FP), A2
77 MOVW perm+12(FP), A3
78 MOV $SYS_openat, A7
79 ECALL
80 MOV $-4096, T0
81 BGEU T0, A0, 2(PC)
82 MOV $-1, A0
83 MOVW A0, ret+16(FP)
84 RET
85
86// func closefd(fd int32) int32
87TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0-12
88 MOVW fd+0(FP), A0
89 MOV $SYS_close, A7
90 ECALL
91 MOV $-4096, T0
92 BGEU T0, A0, 2(PC)
93 MOV $-1, A0
94 MOVW A0, ret+8(FP)
95 RET
96
97// func write1(fd uintptr, p unsafe.Pointer, n int32) int32
98TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0-28
99 MOV fd+0(FP), A0
100 MOV p+8(FP), A1
101 MOVW n+16(FP), A2
102 MOV $SYS_write, A7
103 ECALL
104 MOVW A0, ret+24(FP)
105 RET
106
107// func read(fd int32, p unsafe.Pointer, n int32) int32
108TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0-28
109 MOVW fd+0(FP), A0
110 MOV p+8(FP), A1
111 MOVW n+16(FP), A2
112 MOV $SYS_read, A7
113 ECALL
114 MOVW A0, ret+24(FP)
115 RET
116
117// func pipe2(flags int32) (r, w int32, errno int32)
118TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20
119 MOV $r+8(FP), A0
120 MOVW flags+0(FP), A1
121 MOV $SYS_pipe2, A7
122 ECALL
123 MOVW A0, errno+16(FP)
124 RET
125
126// func usleep(usec uint32)
127TEXT runtime·usleep(SB),NOSPLIT,$24-4
128 MOVWU usec+0(FP), A0
129 MOV $1000, A1
130 MUL A1, A0, A0
131 MOV $1000000000, A1
132 DIV A1, A0, A2
133 MOV A2, 8(X2)
134 REM A1, A0, A3
135 MOV A3, 16(X2)
136 ADD $8, X2, A0
137 MOV ZERO, A1
138 MOV $SYS_nanosleep, A7
139 ECALL
140 RET
141
142// func gettid() uint32
143TEXT runtime·gettid(SB),NOSPLIT,$0-4
144 MOV $SYS_gettid, A7
145 ECALL
146 MOVW A0, ret+0(FP)
147 RET
148
149// func raise(sig uint32)
150TEXT runtime·raise(SB),NOSPLIT|NOFRAME,$0
151 MOV $SYS_gettid, A7
152 ECALL
153 // arg 1 tid - already in A0
154 MOVW sig+0(FP), A1 // arg 2
155 MOV $SYS_tkill, A7
156 ECALL
157 RET
158
159// func raiseproc(sig uint32)
160TEXT runtime·raiseproc(SB),NOSPLIT|NOFRAME,$0
161 MOV $SYS_getpid, A7
162 ECALL
163 // arg 1 pid - already in A0
164 MOVW sig+0(FP), A1 // arg 2
165 MOV $SYS_kill, A7
166 ECALL
167 RET
168
169// func getpid() int
170TEXT ·getpid(SB),NOSPLIT|NOFRAME,$0-8
171 MOV $SYS_getpid, A7
172 ECALL
173 MOV A0, ret+0(FP)
174 RET
175
176// func tgkill(tgid, tid, sig int)
177TEXT ·tgkill(SB),NOSPLIT|NOFRAME,$0-24
178 MOV tgid+0(FP), A0
179 MOV tid+8(FP), A1
180 MOV sig+16(FP), A2
181 MOV $SYS_tgkill, A7
182 ECALL
183 RET
184
185// func setitimer(mode int32, new, old *itimerval)
186TEXT runtime·setitimer(SB),NOSPLIT|NOFRAME,$0-24
187 MOVW mode+0(FP), A0
188 MOV new+8(FP), A1
189 MOV old+16(FP), A2
190 MOV $SYS_setitimer, A7
191 ECALL
192 RET
193
194// func timer_create(clockid int32, sevp *sigevent, timerid *int32) int32
195TEXT runtime·timer_create(SB),NOSPLIT,$0-28
196 MOVW clockid+0(FP), A0
197 MOV sevp+8(FP), A1
198 MOV timerid+16(FP), A2
199 MOV $SYS_timer_create, A7
200 ECALL
201 MOVW A0, ret+24(FP)
202 RET
203
204// func timer_settime(timerid int32, flags int32, new, old *itimerspec) int32
205TEXT runtime·timer_settime(SB),NOSPLIT,$0-28
206 MOVW timerid+0(FP), A0
207 MOVW flags+4(FP), A1
208 MOV new+8(FP), A2
209 MOV old+16(FP), A3
210 MOV $SYS_timer_settime, A7
211 ECALL
212 MOVW A0, ret+24(FP)
213 RET
214
215// func timer_delete(timerid int32) int32
216TEXT runtime·timer_delete(SB),NOSPLIT,$0-12
217 MOVW timerid+0(FP), A0
218 MOV $SYS_timer_delete, A7
219 ECALL
220 MOVW A0, ret+8(FP)
221 RET
222
223// func mincore(addr unsafe.Pointer, n uintptr, dst *byte) int32
224TEXT runtime·mincore(SB),NOSPLIT|NOFRAME,$0-28
225 MOV addr+0(FP), A0
226 MOV n+8(FP), A1
227 MOV dst+16(FP), A2
228 MOV $SYS_mincore, A7
229 ECALL
230 MOVW A0, ret+24(FP)
231 RET
232
233// func walltime() (sec int64, nsec int32)
234TEXT runtime·walltime(SB),NOSPLIT,$40-12
235 MOV $CLOCK_REALTIME, A0
236
237 MOV runtime·vdsoClockgettimeSym(SB), A7
238 BEQZ A7, fallback
239 MOV X2, S2 // S2,S3,S4 is unchanged by C code
240 MOV g_m(g), S3 // S3 = m
241
242 // Save the old values on stack for reentrant
243 MOV m_vdsoPC(S3), T0
244 MOV T0, 24(X2)
245 MOV m_vdsoSP(S3), T0
246 MOV T0, 32(X2)
247
248 MOV RA, m_vdsoPC(S3)
249 MOV $ret-8(FP), T1 // caller's SP
250 MOV T1, m_vdsoSP(S3)
251
252 MOV m_curg(S3), T1
253 BNE g, T1, noswitch
254
255 MOV m_g0(S3), T1
256 MOV (g_sched+gobuf_sp)(T1), X2
257
258noswitch:
259 SUB $24, X2 // Space for result
260 ANDI $~7, X2 // Align for C code
261 MOV $8(X2), A1
262
263 // Store g on gsignal's stack, see sys_linux_arm64.s for detail
264 MOVBU runtime·iscgo(SB), S4
265 BNEZ S4, nosaveg
266 MOV m_gsignal(S3), S4 // g.m.gsignal
267 BEQZ S4, nosaveg
268 BEQ g, S4, nosaveg
269 MOV (g_stack+stack_lo)(S4), S4 // g.m.gsignal.stack.lo
270 MOV g, (S4)
271
272 JALR RA, A7
273
274 MOV ZERO, (S4)
275 JMP finish
276
277nosaveg:
278 JALR RA, A7
279
280finish:
281 MOV 8(X2), T0 // sec
282 MOV 16(X2), T1 // nsec
283
284 MOV S2, X2 // restore stack
285 MOV 24(X2), A2
286 MOV A2, m_vdsoPC(S3)
287
288 MOV 32(X2), A3
289 MOV A3, m_vdsoSP(S3)
290
291 MOV T0, sec+0(FP)
292 MOVW T1, nsec+8(FP)
293 RET
294
295fallback:
296 MOV $8(X2), A1
297 MOV $SYS_clock_gettime, A7
298 ECALL
299 MOV 8(X2), T0 // sec
300 MOV 16(X2), T1 // nsec
301 MOV T0, sec+0(FP)
302 MOVW T1, nsec+8(FP)
303 RET
304
305// func nanotime1() int64
306TEXT runtime·nanotime1(SB),NOSPLIT,$40-8
307 MOV $CLOCK_MONOTONIC, A0
308
309 MOV runtime·vdsoClockgettimeSym(SB), A7
310 BEQZ A7, fallback
311
312 MOV X2, S2 // S2 = RSP, S2 is unchanged by C code
313 MOV g_m(g), S3 // S3 = m
314 // Save the old values on stack for reentrant
315 MOV m_vdsoPC(S3), T0
316 MOV T0, 24(X2)
317 MOV m_vdsoSP(S3), T0
318 MOV T0, 32(X2)
319
320 MOV RA, m_vdsoPC(S3)
321 MOV $ret-8(FP), T0 // caller's SP
322 MOV T0, m_vdsoSP(S3)
323
324 MOV m_curg(S3), T1
325 BNE g, T1, noswitch
326
327 MOV m_g0(S3), T1
328 MOV (g_sched+gobuf_sp)(T1), X2
329
330noswitch:
331 SUB $24, X2 // Space for result
332 ANDI $~7, X2 // Align for C code
333 MOV $8(X2), A1
334
335 // Store g on gsignal's stack, see sys_linux_arm64.s for detail
336 MOVBU runtime·iscgo(SB), S4
337 BNEZ S4, nosaveg
338 MOV m_gsignal(S3), S4 // g.m.gsignal
339 BEQZ S4, nosaveg
340 BEQ g, S4, nosaveg
341 MOV (g_stack+stack_lo)(S4), S4 // g.m.gsignal.stack.lo
342 MOV g, (S4)
343
344 JALR RA, A7
345
346 MOV ZERO, (S4)
347 JMP finish
348
349nosaveg:
350 JALR RA, A7
351
352finish:
353 MOV 8(X2), T0 // sec
354 MOV 16(X2), T1 // nsec
355 // restore stack
356 MOV S2, X2
357 MOV 24(X2), T2
358 MOV T2, m_vdsoPC(S3)
359
360 MOV 32(X2), T2
361 MOV T2, m_vdsoSP(S3)
362 // sec is in T0, nsec in T1
363 // return nsec in T0
364 MOV $1000000000, T2
365 MUL T2, T0
366 ADD T1, T0
367 MOV T0, ret+0(FP)
368 RET
369
370fallback:
371 MOV $8(X2), A1
372 MOV $SYS_clock_gettime, A7
373 ECALL
374 MOV 8(X2), T0 // sec
375 MOV 16(X2), T1 // nsec
376 MOV $1000000000, T2
377 MUL T2, T0
378 ADD T1, T0
379 MOV T0, ret+0(FP)
380 RET
381
382// func rtsigprocmask(how int32, new, old *sigset, size int32)
383TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28
384 MOVW how+0(FP), A0
385 MOV new+8(FP), A1
386 MOV old+16(FP), A2
387 MOVW size+24(FP), A3
388 MOV $SYS_rt_sigprocmask, A7
389 ECALL
390 MOV $-4096, T0
391 BLTU A0, T0, 2(PC)
392 WORD $0 // crash
393 RET
394
395// func rt_sigaction(sig uintptr, new, old *sigactiont, size uintptr) int32
396TEXT runtime·rt_sigaction(SB),NOSPLIT|NOFRAME,$0-36
397 MOV sig+0(FP), A0
398 MOV new+8(FP), A1
399 MOV old+16(FP), A2
400 MOV size+24(FP), A3
401 MOV $SYS_rt_sigaction, A7
402 ECALL
403 MOVW A0, ret+32(FP)
404 RET
405
406// func sigfwd(fn uintptr, sig uint32, info *siginfo, ctx unsafe.Pointer)
407TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
408 MOVW sig+8(FP), A0
409 MOV info+16(FP), A1
410 MOV ctx+24(FP), A2
411 MOV fn+0(FP), T1
412 JALR RA, T1
413 RET
414
415// func sigtramp(signo, ureg, ctxt unsafe.Pointer)
416TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$64
417 MOVW A0, 8(X2)
418 MOV A1, 16(X2)
419 MOV A2, 24(X2)
420
421 // this might be called in external code context,
422 // where g is not set.
423 MOVBU runtime·iscgo(SB), A0
424 BEQ A0, ZERO, 2(PC)
425 CALL runtime·load_g(SB)
426
427 MOV $runtime·sigtrampgo(SB), A0
428 JALR RA, A0
429 RET
430
431// func cgoSigtramp()
432TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
433 MOV $runtime·sigtramp(SB), T1
434 JALR ZERO, T1
435
436// func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (p unsafe.Pointer, err int)
437TEXT runtime·mmap(SB),NOSPLIT|NOFRAME,$0
438 MOV addr+0(FP), A0
439 MOV n+8(FP), A1
440 MOVW prot+16(FP), A2
441 MOVW flags+20(FP), A3
442 MOVW fd+24(FP), A4
443 MOVW off+28(FP), A5
444 MOV $SYS_mmap, A7
445 ECALL
446 MOV $-4096, T0
447 BGEU T0, A0, 5(PC)
448 SUB A0, ZERO, A0
449 MOV ZERO, p+32(FP)
450 MOV A0, err+40(FP)
451 RET
452ok:
453 MOV A0, p+32(FP)
454 MOV ZERO, err+40(FP)
455 RET
456
457// func munmap(addr unsafe.Pointer, n uintptr)
458TEXT runtime·munmap(SB),NOSPLIT|NOFRAME,$0
459 MOV addr+0(FP), A0
460 MOV n+8(FP), A1
461 MOV $SYS_munmap, A7
462 ECALL
463 MOV $-4096, T0
464 BLTU A0, T0, 2(PC)
465 WORD $0 // crash
466 RET
467
468// func madvise(addr unsafe.Pointer, n uintptr, flags int32)
469TEXT runtime·madvise(SB),NOSPLIT|NOFRAME,$0
470 MOV addr+0(FP), A0
471 MOV n+8(FP), A1
472 MOVW flags+16(FP), A2
473 MOV $SYS_madvise, A7
474 ECALL
475 MOVW A0, ret+24(FP)
476 RET
477
478// func futex(addr unsafe.Pointer, op int32, val uint32, ts, addr2 unsafe.Pointer, val3 uint32) int32
479TEXT runtime·futex(SB),NOSPLIT|NOFRAME,$0
480 MOV addr+0(FP), A0
481 MOVW op+8(FP), A1
482 MOVW val+12(FP), A2
483 MOV ts+16(FP), A3
484 MOV addr2+24(FP), A4
485 MOVW val3+32(FP), A5
486 MOV $SYS_futex, A7
487 ECALL
488 MOVW A0, ret+40(FP)
489 RET
490
491// func clone(flags int32, stk, mp, gp, fn unsafe.Pointer) int32
492TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0
493 MOVW flags+0(FP), A0
494 MOV stk+8(FP), A1
495
496 // Copy mp, gp, fn off parent stack for use by child.
497 MOV mp+16(FP), T0
498 MOV gp+24(FP), T1
499 MOV fn+32(FP), T2
500
501 MOV T0, -8(A1)
502 MOV T1, -16(A1)
503 MOV T2, -24(A1)
504 MOV $1234, T0
505 MOV T0, -32(A1)
506
507 MOV $SYS_clone, A7
508 ECALL
509
510 // In parent, return.
511 BEQ ZERO, A0, child
512 MOVW ZERO, ret+40(FP)
513 RET
514
515child:
516 // In child, on new stack.
517 MOV -32(X2), T0
518 MOV $1234, A0
519 BEQ A0, T0, good
520 WORD $0 // crash
521
522good:
523 // Initialize m->procid to Linux tid
524 MOV $SYS_gettid, A7
525 ECALL
526
527 MOV -24(X2), T2 // fn
528 MOV -16(X2), T1 // g
529 MOV -8(X2), T0 // m
530
531 BEQ ZERO, T0, nog
532 BEQ ZERO, T1, nog
533
534 MOV A0, m_procid(T0)
535
536 // In child, set up new stack
537 MOV T0, g_m(T1)
538 MOV T1, g
539
540nog:
541 // Call fn
542 JALR RA, T2
543
544 // It shouldn't return. If it does, exit this thread.
545 MOV $111, A0
546 MOV $SYS_exit, A7
547 ECALL
548 JMP -3(PC) // keep exiting
549
550// func sigaltstack(new, old *stackt)
551TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0
552 MOV new+0(FP), A0
553 MOV old+8(FP), A1
554 MOV $SYS_sigaltstack, A7
555 ECALL
556 MOV $-4096, T0
557 BLTU A0, T0, 2(PC)
558 WORD $0 // crash
559 RET
560
561// func osyield()
562TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0
563 MOV $SYS_sched_yield, A7
564 ECALL
565 RET
566
567// func sched_getaffinity(pid, len uintptr, buf *uintptr) int32
568TEXT runtime·sched_getaffinity(SB),NOSPLIT|NOFRAME,$0
569 MOV pid+0(FP), A0
570 MOV len+8(FP), A1
571 MOV buf+16(FP), A2
572 MOV $SYS_sched_getaffinity, A7
573 ECALL
574 MOV A0, ret+24(FP)
575 RET
576
577// func sbrk0() uintptr
578TEXT runtime·sbrk0(SB),NOSPLIT,$0-8
579 // Implemented as brk(NULL).
580 MOV $0, A0
581 MOV $SYS_brk, A7
582 ECALL
583 MOVW A0, ret+0(FP)
584 RET
View as plain text