Merge tag 'pull-sp-20240412' of https://gitlab.com/rth7680/qemu into staging
[qemu/armbru.git] / linux-user / riscv / vdso.S
blobc37275233a0657b07235cc96a589ec47665de758
1 /*
2  * RISC-V linux replacement vdso.
3  *
4  * Copyright 2021 Linaro, Ltd.
5  *
6  * SPDX-License-Identifier: GPL-2.0-or-later
7  */
9 #include <asm/unistd.h>
10 #include <asm/errno.h>
12 #if __riscv_xlen == 32
13 # define TARGET_ABI32
14 #endif
15 #include "vdso-asmoffset.h"
17         .text
19 .macro endf name
20         .globl  \name
21         .type   \name, @function
22         .size   \name, . - \name
23 .endm
25 .macro raw_syscall nr
26         li      a7, \nr
27         ecall
28 .endm
30 .macro vdso_syscall name, nr
31 \name:
32         raw_syscall \nr
33         ret
34 endf    \name
35 .endm
37 __vdso_gettimeofday:
38         .cfi_startproc
39 #ifdef __NR_gettimeofday
40         raw_syscall __NR_gettimeofday
41         ret
42 #else
43         /* No gettimeofday, fall back to clock_gettime64. */
44         beq     a1, zero, 1f
45         sw      zero, 0(a1)     /* tz->tz_minuteswest = 0 */
46         sw      zero, 4(a1)     /* tz->tz_dsttime = 0 */
47 1:      addi    sp, sp, -32
48         .cfi_adjust_cfa_offset 32
49         sw      a0, 16(sp)      /* save tv */
50         mv      a0, sp
51         raw_syscall __NR_clock_gettime64
52         lw      t0, 0(sp)       /* timespec.tv_sec.low */
53         lw      t1, 4(sp)       /* timespec.tv_sec.high */
54         lw      t2, 8(sp)       /* timespec.tv_nsec.low */
55         lw      a1, 16(sp)      /* restore tv */
56         addi    sp, sp, 32
57         .cfi_adjust_cfa_offset -32
58         bne     a0, zero, 9f    /* syscall error? */
59         li      a0, -EOVERFLOW
60         bne     t1, zero, 9f    /* y2038? */
61         li      a0, 0
62         li      t3, 1000
63         divu    t2, t2, t3      /* nsec -> usec */
64         sw      t0, 0(a1)       /* tz->tv_sec */
65         sw      t2, 4(a1)       /* tz->tv_usec */
66 9:      ret
67 #endif
68         .cfi_endproc
69 endf __vdso_gettimeofday
71         .cfi_startproc
73 #ifdef __NR_clock_gettime
74 vdso_syscall __vdso_clock_gettime, __NR_clock_gettime
75 #else
76 vdso_syscall __vdso_clock_gettime, __NR_clock_gettime64
77 #endif
79 #ifdef __NR_clock_getres
80 vdso_syscall __vdso_clock_getres, __NR_clock_getres
81 #else
82 vdso_syscall __vdso_clock_getres, __NR_clock_getres_time64
83 #endif
85 vdso_syscall __vdso_getcpu, __NR_getcpu
87 __vdso_flush_icache:
88         /* qemu does not need to flush the icache */
89         li      a0, 0
90         ret
91 endf __vdso_flush_icache
93         .cfi_endproc
96  * Start the unwind info at least one instruction before the signal
97  * trampoline, because the unwinder will assume we are returning
98  * after a call site.
99  */
101         .cfi_startproc simple
102         .cfi_signal_frame
104 #define sizeof_reg      (__riscv_xlen / 8)
105 #define sizeof_freg     8
106 #define B_GR    0
107 #define B_FR    offsetof_freg0
109         .cfi_def_cfa    2, offsetof_uc_mcontext
111         /* Return address */
112         .cfi_return_column 64
113         .cfi_offset     64, B_GR + 0                    /* pc */
115         /* Integer registers */
116         .cfi_offset     1, B_GR + 1 * sizeof_reg        /* r1 (ra) */
117         .cfi_offset     2, B_GR + 2 * sizeof_reg        /* r2 (sp) */
118         .cfi_offset     3, B_GR + 3 * sizeof_reg
119         .cfi_offset     4, B_GR + 4 * sizeof_reg
120         .cfi_offset     5, B_GR + 5 * sizeof_reg
121         .cfi_offset     6, B_GR + 6 * sizeof_reg
122         .cfi_offset     7, B_GR + 7 * sizeof_reg
123         .cfi_offset     8, B_GR + 8 * sizeof_reg
124         .cfi_offset     9, B_GR + 9 * sizeof_reg
125         .cfi_offset     10, B_GR + 10 * sizeof_reg
126         .cfi_offset     11, B_GR + 11 * sizeof_reg
127         .cfi_offset     12, B_GR + 12 * sizeof_reg
128         .cfi_offset     13, B_GR + 13 * sizeof_reg
129         .cfi_offset     14, B_GR + 14 * sizeof_reg
130         .cfi_offset     15, B_GR + 15 * sizeof_reg
131         .cfi_offset     16, B_GR + 16 * sizeof_reg
132         .cfi_offset     17, B_GR + 17 * sizeof_reg
133         .cfi_offset     18, B_GR + 18 * sizeof_reg
134         .cfi_offset     19, B_GR + 19 * sizeof_reg
135         .cfi_offset     20, B_GR + 20 * sizeof_reg
136         .cfi_offset     21, B_GR + 21 * sizeof_reg
137         .cfi_offset     22, B_GR + 22 * sizeof_reg
138         .cfi_offset     23, B_GR + 23 * sizeof_reg
139         .cfi_offset     24, B_GR + 24 * sizeof_reg
140         .cfi_offset     25, B_GR + 25 * sizeof_reg
141         .cfi_offset     26, B_GR + 26 * sizeof_reg
142         .cfi_offset     27, B_GR + 27 * sizeof_reg
143         .cfi_offset     28, B_GR + 28 * sizeof_reg
144         .cfi_offset     29, B_GR + 29 * sizeof_reg
145         .cfi_offset     30, B_GR + 30 * sizeof_reg
146         .cfi_offset     31, B_GR + 31 * sizeof_reg      /* r31 */
148         .cfi_offset     32, B_FR + 0                    /* f0 */
149         .cfi_offset     33, B_FR + 1 * sizeof_freg      /* f1 */
150         .cfi_offset     34, B_FR + 2 * sizeof_freg
151         .cfi_offset     35, B_FR + 3 * sizeof_freg
152         .cfi_offset     36, B_FR + 4 * sizeof_freg
153         .cfi_offset     37, B_FR + 5 * sizeof_freg
154         .cfi_offset     38, B_FR + 6 * sizeof_freg
155         .cfi_offset     39, B_FR + 7 * sizeof_freg
156         .cfi_offset     40, B_FR + 8 * sizeof_freg
157         .cfi_offset     41, B_FR + 9 * sizeof_freg
158         .cfi_offset     42, B_FR + 10 * sizeof_freg
159         .cfi_offset     43, B_FR + 11 * sizeof_freg
160         .cfi_offset     44, B_FR + 12 * sizeof_freg
161         .cfi_offset     45, B_FR + 13 * sizeof_freg
162         .cfi_offset     46, B_FR + 14 * sizeof_freg
163         .cfi_offset     47, B_FR + 15 * sizeof_freg
164         .cfi_offset     48, B_FR + 16 * sizeof_freg
165         .cfi_offset     49, B_FR + 17 * sizeof_freg
166         .cfi_offset     50, B_FR + 18 * sizeof_freg
167         .cfi_offset     51, B_FR + 19 * sizeof_freg
168         .cfi_offset     52, B_FR + 20 * sizeof_freg
169         .cfi_offset     53, B_FR + 21 * sizeof_freg
170         .cfi_offset     54, B_FR + 22 * sizeof_freg
171         .cfi_offset     55, B_FR + 23 * sizeof_freg
172         .cfi_offset     56, B_FR + 24 * sizeof_freg
173         .cfi_offset     57, B_FR + 25 * sizeof_freg
174         .cfi_offset     58, B_FR + 26 * sizeof_freg
175         .cfi_offset     59, B_FR + 27 * sizeof_freg
176         .cfi_offset     60, B_FR + 28 * sizeof_freg
177         .cfi_offset     61, B_FR + 29 * sizeof_freg
178         .cfi_offset     62, B_FR + 30 * sizeof_freg
179         .cfi_offset     63, B_FR + 31 * sizeof_freg     /* f31 */
181         nop
183 __vdso_rt_sigreturn:
184         raw_syscall __NR_rt_sigreturn
185 endf __vdso_rt_sigreturn
187         .cfi_endproc