Commit | Line | Data |
---|---|---|
2874c5fd | 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
a7f290da | 2 | /* |
f061fb03 CL |
3 | * Userland implementation of gettimeofday() for processes |
4 | * for use in the vDSO | |
a7f290da BH |
5 | * |
6 | * Copyright (C) 2004 Benjamin Herrenschmuidt (benh@kernel.crashing.org, | |
7 | * IBM Corp. | |
a7f290da | 8 | */ |
a7f290da BH |
9 | #include <asm/processor.h> |
10 | #include <asm/ppc_asm.h> | |
11 | #include <asm/vdso.h> | |
ec0895f0 | 12 | #include <asm/vdso_datapage.h> |
a7f290da BH |
13 | #include <asm/asm-offsets.h> |
14 | #include <asm/unistd.h> | |
692b21d7 CL |
15 | |
16 | /* | |
17 | * The macro sets two stack frames, one for the caller and one for the callee | |
18 | * because there are no requirement for the caller to set a stack frame when | |
19 | * calling VDSO so it may have omitted to set one, especially on PPC64 | |
20 | */ | |
21 | ||
22 | .macro cvdso_call funct call_time=0 | |
23 | .cfi_startproc | |
24 | PPC_STLU r1, -PPC_MIN_STKFRM(r1) | |
6d65028e | 25 | .cfi_adjust_cfa_offset PPC_MIN_STKFRM |
692b21d7 | 26 | mflr r0 |
692b21d7 | 27 | PPC_STLU r1, -PPC_MIN_STKFRM(r1) |
6d65028e | 28 | .cfi_adjust_cfa_offset PPC_MIN_STKFRM |
692b21d7 | 29 | PPC_STL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1) |
6d65028e | 30 | .cfi_rel_offset lr, PPC_MIN_STKFRM + PPC_LR_STKOFF |
692b21d7 CL |
31 | #ifdef __powerpc64__ |
32 | PPC_STL r2, PPC_MIN_STKFRM + STK_GOT(r1) | |
6d65028e | 33 | .cfi_rel_offset r2, PPC_MIN_STKFRM + STK_GOT |
692b21d7 CL |
34 | #endif |
35 | get_datapage r5 | |
36 | .ifeq \call_time | |
37 | addi r5, r5, VDSO_DATA_OFFSET | |
38 | .else | |
39 | addi r4, r5, VDSO_DATA_OFFSET | |
40 | .endif | |
4e991e3c NP |
41 | #ifdef __powerpc64__ |
42 | bl CFUNC(DOTSYM(\funct)) | |
43 | #else | |
44 | bl \funct | |
45 | #endif | |
692b21d7 CL |
46 | PPC_LL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1) |
47 | #ifdef __powerpc64__ | |
48 | PPC_LL r2, PPC_MIN_STKFRM + STK_GOT(r1) | |
6d65028e | 49 | .cfi_restore r2 |
692b21d7 CL |
50 | #endif |
51 | .ifeq \call_time | |
52 | cmpwi r3, 0 | |
53 | .endif | |
54 | mtlr r0 | |
692b21d7 | 55 | addi r1, r1, 2 * PPC_MIN_STKFRM |
6d65028e ME |
56 | .cfi_restore lr |
57 | .cfi_def_cfa_offset 0 | |
692b21d7 CL |
58 | crclr so |
59 | .ifeq \call_time | |
60 | beqlr+ | |
61 | crset so | |
62 | neg r3, r3 | |
63 | .endif | |
64 | blr | |
65 | .cfi_endproc | |
66 | .endm | |
597bc5c0 | 67 | |
a7f290da BH |
68 | .text |
69 | /* | |
70 | * Exact prototype of gettimeofday | |
71 | * | |
72 | * int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz); | |
73 | * | |
74 | */ | |
75 | V_FUNCTION_BEGIN(__kernel_gettimeofday) | |
ab037dd8 | 76 | cvdso_call __c_kernel_gettimeofday |
a7f290da BH |
77 | V_FUNCTION_END(__kernel_gettimeofday) |
78 | ||
79 | /* | |
80 | * Exact prototype of clock_gettime() | |
81 | * | |
82 | * int __kernel_clock_gettime(clockid_t clock_id, struct timespec *tp); | |
83 | * | |
84 | */ | |
85 | V_FUNCTION_BEGIN(__kernel_clock_gettime) | |
ab037dd8 | 86 | cvdso_call __c_kernel_clock_gettime |
a7f290da BH |
87 | V_FUNCTION_END(__kernel_clock_gettime) |
88 | ||
d0e3fc69 CL |
89 | /* |
90 | * Exact prototype of clock_gettime64() | |
91 | * | |
92 | * int __kernel_clock_gettime64(clockid_t clock_id, struct __timespec64 *ts); | |
93 | * | |
94 | */ | |
f061fb03 | 95 | #ifndef __powerpc64__ |
d0e3fc69 CL |
96 | V_FUNCTION_BEGIN(__kernel_clock_gettime64) |
97 | cvdso_call __c_kernel_clock_gettime64 | |
98 | V_FUNCTION_END(__kernel_clock_gettime64) | |
f061fb03 | 99 | #endif |
a7f290da BH |
100 | |
101 | /* | |
102 | * Exact prototype of clock_getres() | |
103 | * | |
104 | * int __kernel_clock_getres(clockid_t clock_id, struct timespec *res); | |
105 | * | |
106 | */ | |
107 | V_FUNCTION_BEGIN(__kernel_clock_getres) | |
ab037dd8 | 108 | cvdso_call __c_kernel_clock_getres |
a7f290da BH |
109 | V_FUNCTION_END(__kernel_clock_getres) |
110 | ||
111 | ||
fcb41a20 AZ |
112 | /* |
113 | * Exact prototype of time() | |
114 | * | |
115 | * time_t time(time *t); | |
116 | * | |
117 | */ | |
118 | V_FUNCTION_BEGIN(__kernel_time) | |
9b97bea9 | 119 | cvdso_call __c_kernel_time call_time=1 |
fcb41a20 | 120 | V_FUNCTION_END(__kernel_time) |
08c18b63 CL |
121 | |
122 | /* Routines for restoring integer registers, called by the compiler. */ | |
123 | /* Called with r11 pointing to the stack header word of the caller of the */ | |
124 | /* function, just beyond the end of the integer restore area. */ | |
f061fb03 | 125 | #ifndef __powerpc64__ |
08c18b63 CL |
126 | _GLOBAL(_restgpr_31_x) |
127 | _GLOBAL(_rest32gpr_31_x) | |
128 | lwz r0,4(r11) | |
129 | lwz r31,-4(r11) | |
130 | mtlr r0 | |
131 | mr r1,r11 | |
132 | blr | |
f061fb03 | 133 | #endif |