clock_gettime.S 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  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. .text
  16. .align 4
  17. .globl __kernel_clock_gettime
  18. .type __kernel_clock_gettime,@function
  19. __kernel_clock_gettime:
  20. .cfi_startproc
  21. larl %r5,_vdso_data
  22. cghi %r2,CLOCK_REALTIME
  23. je 4f
  24. cghi %r2,CLOCK_MONOTONIC
  25. jne 9f
  26. /* CLOCK_MONOTONIC */
  27. ltgr %r3,%r3
  28. jz 3f /* tp == NULL */
  29. 0: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */
  30. tmll %r4,0x0001 /* pending update ? loop */
  31. jnz 0b
  32. stck 48(%r15) /* Store TOD clock */
  33. lg %r1,48(%r15)
  34. sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
  35. mghi %r1,1000
  36. srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */
  37. alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime */
  38. lg %r0,__VDSO_XTIME_SEC(%r5)
  39. alg %r1,__VDSO_WTOM_NSEC(%r5) /* + wall_to_monotonic */
  40. alg %r0,__VDSO_WTOM_SEC(%r5)
  41. clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */
  42. jne 0b
  43. larl %r5,10f
  44. 1: clg %r1,0(%r5)
  45. jl 2f
  46. slg %r1,0(%r5)
  47. aghi %r0,1
  48. j 1b
  49. 2: stg %r0,0(%r3) /* store tp->tv_sec */
  50. stg %r1,8(%r3) /* store tp->tv_nsec */
  51. 3: lghi %r2,0
  52. br %r14
  53. /* CLOCK_REALTIME */
  54. 4: ltr %r3,%r3 /* tp == NULL */
  55. jz 8f
  56. 5: lg %r4,__VDSO_UPD_COUNT(%r5) /* load update counter */
  57. tmll %r4,0x0001 /* pending update ? loop */
  58. jnz 5b
  59. stck 48(%r15) /* Store TOD clock */
  60. lg %r1,48(%r15)
  61. sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
  62. mghi %r1,1000
  63. srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */
  64. alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime */
  65. lg %r0,__VDSO_XTIME_SEC(%r5)
  66. clg %r4,__VDSO_UPD_COUNT(%r5) /* check update counter */
  67. jne 5b
  68. larl %r5,10f
  69. 6: clg %r1,0(%r5)
  70. jl 7f
  71. slg %r1,0(%r5)
  72. aghi %r0,1
  73. j 6b
  74. 7: stg %r0,0(%r3) /* store tp->tv_sec */
  75. stg %r1,8(%r3) /* store tp->tv_nsec */
  76. 8: lghi %r2,0
  77. br %r14
  78. /* Fallback to system call */
  79. 9: lghi %r1,__NR_clock_gettime
  80. svc 0
  81. br %r14
  82. 10: .quad 1000000000
  83. .cfi_endproc
  84. .size __kernel_clock_gettime,.-__kernel_clock_gettime