Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * Userland implementation of gettimeofday() for processes
0004  * for use in the vDSO
0005  *
0006  * Copyright (C) 2004 Benjamin Herrenschmuidt (benh@kernel.crashing.org,
0007  *                    IBM Corp.
0008  */
0009 #include <asm/processor.h>
0010 #include <asm/ppc_asm.h>
0011 #include <asm/vdso.h>
0012 #include <asm/vdso_datapage.h>
0013 #include <asm/asm-offsets.h>
0014 #include <asm/unistd.h>
0015 
0016 /*
0017  * The macro sets two stack frames, one for the caller and one for the callee
0018  * because there are no requirement for the caller to set a stack frame when
0019  * calling VDSO so it may have omitted to set one, especially on PPC64
0020  */
0021 
0022 .macro cvdso_call funct call_time=0
0023   .cfi_startproc
0024     PPC_STLU    r1, -PPC_MIN_STKFRM(r1)
0025   .cfi_adjust_cfa_offset PPC_MIN_STKFRM
0026     mflr        r0
0027     PPC_STLU    r1, -PPC_MIN_STKFRM(r1)
0028   .cfi_adjust_cfa_offset PPC_MIN_STKFRM
0029     PPC_STL     r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
0030   .cfi_rel_offset lr, PPC_MIN_STKFRM + PPC_LR_STKOFF
0031 #ifdef __powerpc64__
0032     PPC_STL     r2, PPC_MIN_STKFRM + STK_GOT(r1)
0033   .cfi_rel_offset r2, PPC_MIN_STKFRM + STK_GOT
0034 #endif
0035     get_datapage    r5
0036     .ifeq   \call_time
0037     addi        r5, r5, VDSO_DATA_OFFSET
0038     .else
0039     addi        r4, r5, VDSO_DATA_OFFSET
0040     .endif
0041     bl      DOTSYM(\funct)
0042     PPC_LL      r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
0043 #ifdef __powerpc64__
0044     PPC_LL      r2, PPC_MIN_STKFRM + STK_GOT(r1)
0045   .cfi_restore r2
0046 #endif
0047     .ifeq   \call_time
0048     cmpwi       r3, 0
0049     .endif
0050     mtlr        r0
0051     addi        r1, r1, 2 * PPC_MIN_STKFRM
0052   .cfi_restore lr
0053   .cfi_def_cfa_offset 0
0054     crclr       so
0055     .ifeq   \call_time
0056     beqlr+
0057     crset       so
0058     neg     r3, r3
0059     .endif
0060     blr
0061   .cfi_endproc
0062 .endm
0063 
0064     .text
0065 /*
0066  * Exact prototype of gettimeofday
0067  *
0068  * int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz);
0069  *
0070  */
0071 V_FUNCTION_BEGIN(__kernel_gettimeofday)
0072     cvdso_call __c_kernel_gettimeofday
0073 V_FUNCTION_END(__kernel_gettimeofday)
0074 
0075 /*
0076  * Exact prototype of clock_gettime()
0077  *
0078  * int __kernel_clock_gettime(clockid_t clock_id, struct timespec *tp);
0079  *
0080  */
0081 V_FUNCTION_BEGIN(__kernel_clock_gettime)
0082     cvdso_call __c_kernel_clock_gettime
0083 V_FUNCTION_END(__kernel_clock_gettime)
0084 
0085 /*
0086  * Exact prototype of clock_gettime64()
0087  *
0088  * int __kernel_clock_gettime64(clockid_t clock_id, struct __timespec64 *ts);
0089  *
0090  */
0091 #ifndef __powerpc64__
0092 V_FUNCTION_BEGIN(__kernel_clock_gettime64)
0093     cvdso_call __c_kernel_clock_gettime64
0094 V_FUNCTION_END(__kernel_clock_gettime64)
0095 #endif
0096 
0097 /*
0098  * Exact prototype of clock_getres()
0099  *
0100  * int __kernel_clock_getres(clockid_t clock_id, struct timespec *res);
0101  *
0102  */
0103 V_FUNCTION_BEGIN(__kernel_clock_getres)
0104     cvdso_call __c_kernel_clock_getres
0105 V_FUNCTION_END(__kernel_clock_getres)
0106 
0107 
0108 /*
0109  * Exact prototype of time()
0110  *
0111  * time_t time(time *t);
0112  *
0113  */
0114 V_FUNCTION_BEGIN(__kernel_time)
0115     cvdso_call __c_kernel_time call_time=1
0116 V_FUNCTION_END(__kernel_time)
0117 
0118 /* Routines for restoring integer registers, called by the compiler.  */
0119 /* Called with r11 pointing to the stack header word of the caller of the */
0120 /* function, just beyond the end of the integer restore area.  */
0121 #ifndef __powerpc64__
0122 _GLOBAL(_restgpr_31_x)
0123 _GLOBAL(_rest32gpr_31_x)
0124     lwz r0,4(r11)
0125     lwz r31,-4(r11)
0126     mtlr    r0
0127     mr  r1,r11
0128     blr
0129 #endif