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 | |
9b2efe03 | 22 | aghi %r15,-16 |
b020632e | 23 | larl %r5,_vdso_data |
b7eacb59 MS |
24 | cghi %r2,__CLOCK_REALTIME_COARSE |
25 | je 4f | |
b3423982 | 26 | cghi %r2,__CLOCK_REALTIME |
5da76157 | 27 | je 5f |
b5e64b3d MS |
28 | cghi %r2,__CLOCK_THREAD_CPUTIME_ID |
29 | je 9f | |
30 | cghi %r2,-2 /* Per-thread CPUCLOCK with PID=0, VIRT=1 */ | |
c742b31c | 31 | je 9f |
b7eacb59 MS |
32 | cghi %r2,__CLOCK_MONOTONIC_COARSE |
33 | je 3f | |
b3423982 | 34 | cghi %r2,__CLOCK_MONOTONIC |
c742b31c | 35 | jne 12f |
b020632e MS |
36 | |
37 | /* CLOCK_MONOTONIC */ | |
b020632e MS |
38 | 0: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */ |
39 | tmll %r4,0x0001 /* pending update ? loop */ | |
40 | jnz 0b | |
9b2efe03 | 41 | stcke 0(%r15) /* Store TOD clock */ |
79c74ecb | 42 | lgf %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ |
ca5de58b | 43 | lg %r0,__VDSO_WTOM_SEC(%r5) |
9b2efe03 | 44 | lg %r1,1(%r15) |
b020632e | 45 | sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ |
79c74ecb | 46 | msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */ |
ca5de58b | 47 | alg %r1,__VDSO_WTOM_NSEC(%r5) |
79c74ecb | 48 | srlg %r1,%r1,0(%r2) /* >> tk->shift */ |
b020632e MS |
49 | clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */ |
50 | jne 0b | |
c742b31c | 51 | larl %r5,13f |
b020632e MS |
52 | 1: clg %r1,0(%r5) |
53 | jl 2f | |
54 | slg %r1,0(%r5) | |
55 | aghi %r0,1 | |
56 | j 1b | |
57 | 2: stg %r0,0(%r3) /* store tp->tv_sec */ | |
58 | stg %r1,8(%r3) /* store tp->tv_nsec */ | |
5da76157 | 59 | lghi %r2,0 |
9b2efe03 | 60 | aghi %r15,16 |
b020632e MS |
61 | br %r14 |
62 | ||
b7eacb59 MS |
63 | /* CLOCK_MONOTONIC_COARSE */ |
64 | 3: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */ | |
65 | tmll %r4,0x0001 /* pending update ? loop */ | |
66 | jnz 3b | |
67 | lg %r0,__VDSO_WTOM_CRS_SEC(%r5) | |
68 | lg %r1,__VDSO_WTOM_CRS_NSEC(%r5) | |
69 | clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */ | |
70 | jne 3b | |
71 | j 2b | |
72 | ||
73 | /* CLOCK_REALTIME_COARSE */ | |
74 | 4: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */ | |
75 | tmll %r4,0x0001 /* pending update ? loop */ | |
76 | jnz 4b | |
77 | lg %r0,__VDSO_XTIME_CRS_SEC(%r5) | |
78 | lg %r1,__VDSO_XTIME_CRS_NSEC(%r5) | |
79 | clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */ | |
80 | jne 4b | |
81 | j 7f | |
82 | ||
b020632e | 83 | /* CLOCK_REALTIME */ |
b020632e MS |
84 | 5: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */ |
85 | tmll %r4,0x0001 /* pending update ? loop */ | |
86 | jnz 5b | |
9b2efe03 | 87 | stcke 0(%r15) /* Store TOD clock */ |
79c74ecb | 88 | lgf %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ |
9b2efe03 | 89 | lg %r1,1(%r15) |
b020632e | 90 | sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ |
79c74ecb MS |
91 | msgf %r1,__VDSO_TK_MULT(%r5) /* * tk->mult */ |
92 | alg %r1,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */ | |
93 | srlg %r1,%r1,0(%r2) /* >> tk->shift */ | |
94 | lg %r0,__VDSO_XTIME_SEC(%r5) /* tk->xtime_sec */ | |
b020632e MS |
95 | clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */ |
96 | jne 5b | |
c742b31c | 97 | larl %r5,13f |
b020632e MS |
98 | 6: clg %r1,0(%r5) |
99 | jl 7f | |
100 | slg %r1,0(%r5) | |
101 | aghi %r0,1 | |
102 | j 6b | |
103 | 7: stg %r0,0(%r3) /* store tp->tv_sec */ | |
104 | stg %r1,8(%r3) /* store tp->tv_nsec */ | |
5da76157 | 105 | lghi %r2,0 |
9b2efe03 | 106 | aghi %r15,16 |
b020632e MS |
107 | br %r14 |
108 | ||
c742b31c MS |
109 | /* CLOCK_THREAD_CPUTIME_ID for this thread */ |
110 | 9: icm %r0,15,__VDSO_ECTG_OK(%r5) | |
111 | jz 12f | |
112 | ear %r2,%a4 | |
113 | llilh %r4,0x0100 | |
114 | sar %a4,%r4 | |
115 | lghi %r4,0 | |
1277580f | 116 | epsw %r5,0 |
c742b31c MS |
117 | sacf 512 /* Magic ectg instruction */ |
118 | .insn ssf,0xc80100000000,__VDSO_ECTG_BASE(4),__VDSO_ECTG_USER(4),4 | |
1277580f MS |
119 | tml %r5,0x4000 |
120 | jo 11f | |
121 | tml %r5,0x8000 | |
122 | jno 10f | |
123 | sacf 256 | |
124 | j 11f | |
125 | 10: sacf 0 | |
126 | 11: sar %a4,%r2 | |
c742b31c MS |
127 | algr %r1,%r0 /* r1 = cputime as TOD value */ |
128 | mghi %r1,1000 /* convert to nanoseconds */ | |
129 | srlg %r1,%r1,12 /* r1 = cputime in nanosec */ | |
130 | lgr %r4,%r1 | |
131 | larl %r5,13f | |
132 | srlg %r1,%r1,9 /* divide by 1000000000 */ | |
133 | mlg %r0,8(%r5) | |
134 | srlg %r0,%r0,11 /* r0 = tv_sec */ | |
135 | stg %r0,0(%r3) | |
136 | msg %r0,0(%r5) /* calculate tv_nsec */ | |
137 | slgr %r4,%r0 /* r4 = tv_nsec */ | |
138 | stg %r4,8(%r3) | |
139 | lghi %r2,0 | |
9b2efe03 | 140 | aghi %r15,16 |
c742b31c MS |
141 | br %r14 |
142 | ||
b020632e | 143 | /* Fallback to system call */ |
c742b31c | 144 | 12: lghi %r1,__NR_clock_gettime |
b020632e | 145 | svc 0 |
9b2efe03 | 146 | aghi %r15,16 |
b020632e MS |
147 | br %r14 |
148 | ||
c742b31c MS |
149 | 13: .quad 1000000000 |
150 | 14: .quad 19342813113834067 | |
b020632e MS |
151 | .cfi_endproc |
152 | .size __kernel_clock_gettime,.-__kernel_clock_gettime |