1/* 2 * Userland implementation of clock_gettime() for 32 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 ahi %r15,-16 23 basr %r5,0 240: al %r5,21f-0b(%r5) /* get &_vdso_data */ 25 chi %r2,__CLOCK_REALTIME_COARSE 26 je 10f 27 chi %r2,__CLOCK_REALTIME 28 je 11f 29 chi %r2,__CLOCK_MONOTONIC_COARSE 30 je 9f 31 chi %r2,__CLOCK_MONOTONIC 32 jne 19f 33 34 /* CLOCK_MONOTONIC */ 351: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ 36 tml %r4,0x0001 /* pending update ? loop */ 37 jnz 1b 38 stcke 0(%r15) /* Store TOD clock */ 39 lm %r0,%r1,1(%r15) 40 s %r0,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ 41 sl %r1,__VDSO_XTIME_STAMP+4(%r5) 42 brc 3,2f 43 ahi %r0,-1 442: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */ 45 lr %r2,%r0 46 l %r0,__VDSO_TK_MULT(%r5) 47 ltr %r1,%r1 48 mr %r0,%r0 49 jnm 3f 50 a %r0,__VDSO_TK_MULT(%r5) 513: alr %r0,%r2 52 al %r0,__VDSO_WTOM_NSEC(%r5) 53 al %r1,__VDSO_WTOM_NSEC+4(%r5) 54 brc 12,5f 55 ahi %r0,1 565: l %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ 57 srdl %r0,0(%r2) /* >> tk->shift */ 58 l %r2,__VDSO_WTOM_SEC+4(%r5) 59 cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ 60 jne 1b 61 basr %r5,0 626: ltr %r0,%r0 63 jnz 7f 64 cl %r1,20f-6b(%r5) 65 jl 8f 667: ahi %r2,1 67 sl %r1,20f-6b(%r5) 68 brc 3,6b 69 ahi %r0,-1 70 j 6b 718: st %r2,0(%r3) /* store tp->tv_sec */ 72 st %r1,4(%r3) /* store tp->tv_nsec */ 73 lhi %r2,0 74 ahi %r15,16 75 br %r14 76 77 /* CLOCK_MONOTONIC_COARSE */ 789: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ 79 tml %r4,0x0001 /* pending update ? loop */ 80 jnz 9b 81 l %r2,__VDSO_WTOM_CRS_SEC+4(%r5) 82 l %r1,__VDSO_WTOM_CRS_NSEC+4(%r5) 83 cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ 84 jne 9b 85 j 8b 86 87 /* CLOCK_REALTIME_COARSE */ 8810: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ 89 tml %r4,0x0001 /* pending update ? loop */ 90 jnz 10b 91 l %r2,__VDSO_XTIME_CRS_SEC+4(%r5) 92 l %r1,__VDSO_XTIME_CRS_NSEC+4(%r5) 93 cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ 94 jne 10b 95 j 17f 96 97 /* CLOCK_REALTIME */ 9811: l %r4,__VDSO_UPD_COUNT+4(%r5) /* load update counter */ 99 tml %r4,0x0001 /* pending update ? loop */ 100 jnz 11b 101 stcke 0(%r15) /* Store TOD clock */ 102 lm %r0,%r1,1(%r15) 103 s %r0,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */ 104 sl %r1,__VDSO_XTIME_STAMP+4(%r5) 105 brc 3,12f 106 ahi %r0,-1 10712: ms %r0,__VDSO_TK_MULT(%r5) /* * tk->mult */ 108 lr %r2,%r0 109 l %r0,__VDSO_TK_MULT(%r5) 110 ltr %r1,%r1 111 mr %r0,%r0 112 jnm 13f 113 a %r0,__VDSO_TK_MULT(%r5) 11413: alr %r0,%r2 115 al %r0,__VDSO_XTIME_NSEC(%r5) /* + tk->xtime_nsec */ 116 al %r1,__VDSO_XTIME_NSEC+4(%r5) 117 brc 12,14f 118 ahi %r0,1 11914: l %r2,__VDSO_TK_SHIFT(%r5) /* Timekeeper shift */ 120 srdl %r0,0(%r2) /* >> tk->shift */ 121 l %r2,__VDSO_XTIME_SEC+4(%r5) 122 cl %r4,__VDSO_UPD_COUNT+4(%r5) /* check update counter */ 123 jne 11b 124 basr %r5,0 12515: ltr %r0,%r0 126 jnz 16f 127 cl %r1,20f-15b(%r5) 128 jl 17f 12916: ahi %r2,1 130 sl %r1,20f-15b(%r5) 131 brc 3,15b 132 ahi %r0,-1 133 j 15b 13417: st %r2,0(%r3) /* store tp->tv_sec */ 135 st %r1,4(%r3) /* store tp->tv_nsec */ 136 lhi %r2,0 137 ahi %r15,16 138 br %r14 139 140 /* Fallback to system call */ 14119: lhi %r1,__NR_clock_gettime 142 svc 0 143 ahi %r15,16 144 br %r14 145 14620: .long 1000000000 14721: .long _vdso_data - 0b 148 .cfi_endproc 149 .size __kernel_clock_gettime,.-__kernel_clock_gettime 150