]>
Commit | Line | Data |
---|---|---|
b020632e MS |
1 | /* |
2 | * Userland implementation of clock_gettime() for 64 bits processes in a | |
3 | * s390 kernel for use in the vDSO | |
4 | * | |
5 | * Copyright IBM Corp. 2008 | |
6 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify | |
9 | * it under the terms of the GNU General Public License (version 2 only) | |
10 | * as published by the Free Software Foundation. | |
11 | */ | |
12 | #include <asm/vdso.h> | |
13 | #include <asm/asm-offsets.h> | |
14 | #include <asm/unistd.h> | |
15 | ||
16 | .text | |
17 | .align 4 | |
18 | .globl __kernel_clock_gettime | |
19 | .type __kernel_clock_gettime,@function | |
20 | __kernel_clock_gettime: | |
21 | .cfi_startproc | |
22 | larl %r5,_vdso_data | |
b3423982 | 23 | cghi %r2,__CLOCK_REALTIME |
b020632e | 24 | je 4f |
c742b31c MS |
25 | cghi %r2,-2 /* CLOCK_THREAD_CPUTIME_ID for this thread */ |
26 | je 9f | |
b3423982 | 27 | cghi %r2,__CLOCK_MONOTONIC |
c742b31c | 28 | jne 12f |
b020632e MS |
29 | |
30 | /* CLOCK_MONOTONIC */ | |
31 | ltgr %r3,%r3 | |
32 | jz 3f /* tp == NULL */ | |
33 | 0: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */ | |
34 | tmll %r4,0x0001 /* pending update ? loop */ | |
35 | jnz 0b | |
36 | stck 48(%r15) /* Store TOD clock */ | |
37 | lg %r1,48(%r15) | |
38 | sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ | |
157a1a27 | 39 | msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */ |
b020632e MS |
40 | srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */ |
41 | alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime */ | |
42 | lg %r0,__VDSO_XTIME_SEC(%r5) | |
43 | alg %r1,__VDSO_WTOM_NSEC(%r5) /* + wall_to_monotonic */ | |
44 | alg %r0,__VDSO_WTOM_SEC(%r5) | |
45 | clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */ | |
46 | jne 0b | |
c742b31c | 47 | larl %r5,13f |
b020632e MS |
48 | 1: clg %r1,0(%r5) |
49 | jl 2f | |
50 | slg %r1,0(%r5) | |
51 | aghi %r0,1 | |
52 | j 1b | |
53 | 2: stg %r0,0(%r3) /* store tp->tv_sec */ | |
54 | stg %r1,8(%r3) /* store tp->tv_nsec */ | |
55 | 3: lghi %r2,0 | |
56 | br %r14 | |
57 | ||
58 | /* CLOCK_REALTIME */ | |
59 | 4: ltr %r3,%r3 /* tp == NULL */ | |
60 | jz 8f | |
61 | 5: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */ | |
62 | tmll %r4,0x0001 /* pending update ? loop */ | |
63 | jnz 5b | |
64 | stck 48(%r15) /* Store TOD clock */ | |
65 | lg %r1,48(%r15) | |
66 | sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ | |
157a1a27 | 67 | msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */ |
b020632e MS |
68 | srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */ |
69 | alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime */ | |
70 | lg %r0,__VDSO_XTIME_SEC(%r5) | |
71 | clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */ | |
72 | jne 5b | |
c742b31c | 73 | larl %r5,13f |
b020632e MS |
74 | 6: clg %r1,0(%r5) |
75 | jl 7f | |
76 | slg %r1,0(%r5) | |
77 | aghi %r0,1 | |
78 | j 6b | |
79 | 7: stg %r0,0(%r3) /* store tp->tv_sec */ | |
80 | stg %r1,8(%r3) /* store tp->tv_nsec */ | |
81 | 8: lghi %r2,0 | |
82 | br %r14 | |
83 | ||
c742b31c MS |
84 | /* CLOCK_THREAD_CPUTIME_ID for this thread */ |
85 | 9: icm %r0,15,__VDSO_ECTG_OK(%r5) | |
86 | jz 12f | |
87 | ear %r2,%a4 | |
88 | llilh %r4,0x0100 | |
89 | sar %a4,%r4 | |
90 | lghi %r4,0 | |
1277580f | 91 | epsw %r5,0 |
c742b31c MS |
92 | sacf 512 /* Magic ectg instruction */ |
93 | .insn ssf,0xc80100000000,__VDSO_ECTG_BASE(4),__VDSO_ECTG_USER(4),4 | |
1277580f MS |
94 | tml %r5,0x4000 |
95 | jo 11f | |
96 | tml %r5,0x8000 | |
97 | jno 10f | |
98 | sacf 256 | |
99 | j 11f | |
100 | 10: sacf 0 | |
101 | 11: sar %a4,%r2 | |
c742b31c MS |
102 | algr %r1,%r0 /* r1 = cputime as TOD value */ |
103 | mghi %r1,1000 /* convert to nanoseconds */ | |
104 | srlg %r1,%r1,12 /* r1 = cputime in nanosec */ | |
105 | lgr %r4,%r1 | |
106 | larl %r5,13f | |
107 | srlg %r1,%r1,9 /* divide by 1000000000 */ | |
108 | mlg %r0,8(%r5) | |
109 | srlg %r0,%r0,11 /* r0 = tv_sec */ | |
110 | stg %r0,0(%r3) | |
111 | msg %r0,0(%r5) /* calculate tv_nsec */ | |
112 | slgr %r4,%r0 /* r4 = tv_nsec */ | |
113 | stg %r4,8(%r3) | |
114 | lghi %r2,0 | |
115 | br %r14 | |
116 | ||
b020632e | 117 | /* Fallback to system call */ |
c742b31c | 118 | 12: lghi %r1,__NR_clock_gettime |
b020632e MS |
119 | svc 0 |
120 | br %r14 | |
121 | ||
c742b31c MS |
122 | 13: .quad 1000000000 |
123 | 14: .quad 19342813113834067 | |
b020632e MS |
124 | .cfi_endproc |
125 | .size __kernel_clock_gettime,.-__kernel_clock_gettime |