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