Merge remote-tracking branches 'asoc/topic/cs35l32', 'asoc/topic/cs35l34', 'asoc...
[sfrench/cifs-2.6.git] / arch / s390 / kernel / vdso64 / gettimeofday.S
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Userland implementation of gettimeofday() for 64 bits processes in a
4  * s390 kernel for use in the vDSO
5  *
6  *  Copyright IBM Corp. 2008
7  *  Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
8  */
9 #include <asm/vdso.h>
10 #include <asm/asm-offsets.h>
11 #include <asm/unistd.h>
12
13         .text
14         .align 4
15         .globl __kernel_gettimeofday
16         .type  __kernel_gettimeofday,@function
17 __kernel_gettimeofday:
18         .cfi_startproc
19         aghi    %r15,-16
20         larl    %r5,_vdso_data
21 0:      ltgr    %r3,%r3                         /* check if tz is NULL */
22         je      1f
23         mvc     0(8,%r3),__VDSO_TIMEZONE(%r5)
24 1:      ltgr    %r2,%r2                         /* check if tv is NULL */
25         je      4f
26         lg      %r4,__VDSO_UPD_COUNT(%r5)       /* load update counter */
27         tmll    %r4,0x0001                      /* pending update ? loop */
28         jnz     0b
29         stcke   0(%r15)                         /* Store TOD clock */
30         lg      %r1,1(%r15)
31         lg      %r0,__VDSO_TS_END(%r5)          /* TOD steering end time */
32         slgr    %r0,%r1                         /* now - ts_steering_end */
33         ltgr    %r0,%r0                         /* past end of steering ? */
34         jm      6f
35         srlg    %r0,%r0,15                      /* 1 per 2^16 */
36         tm      __VDSO_TS_DIR+3(%r5),0x01       /* steering direction? */
37         jz      7f
38         lcgr    %r0,%r0                         /* negative TOD offset */
39 7:      algr    %r1,%r0                         /* add steering offset */
40 6:      sg      %r1,__VDSO_XTIME_STAMP(%r5)     /* TOD - cycle_last */
41         msgf    %r1,__VDSO_TK_MULT(%r5)         /*  * tk->mult */
42         alg     %r1,__VDSO_XTIME_NSEC(%r5)      /*  + tk->xtime_nsec */
43         lg      %r0,__VDSO_XTIME_SEC(%r5)       /* tk->xtime_sec */
44         clg     %r4,__VDSO_UPD_COUNT(%r5)       /* check update counter */
45         jne     0b
46         lgf     %r5,__VDSO_TK_SHIFT(%r5)        /* Timekeeper shift */
47         srlg    %r1,%r1,0(%r5)                  /*  >> tk->shift */
48         larl    %r5,5f
49 2:      clg     %r1,0(%r5)
50         jl      3f
51         slg     %r1,0(%r5)
52         aghi    %r0,1
53         j       2b
54 3:      stg     %r0,0(%r2)                      /* store tv->tv_sec */
55         slgr    %r0,%r0                         /* tv_nsec -> tv_usec */
56         ml      %r0,8(%r5)
57         srlg    %r0,%r0,6
58         stg     %r0,8(%r2)                      /* store tv->tv_usec */
59 4:      lghi    %r2,0
60         aghi    %r15,16
61         br      %r14
62 5:      .quad   1000000000
63         .long   274877907
64         .cfi_endproc
65         .size   __kernel_gettimeofday,.-__kernel_gettimeofday