| 
									
										
										
										
											2008-12-25 13:38:36 +01:00
										 |  |  | /* | 
					
						
							|  |  |  |  * Userland implementation of clock_gettime() for 64 bits processes in a | 
					
						
							|  |  |  |  * s390 kernel for use in the vDSO | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Copyright IBM Corp. 2008 | 
					
						
							|  |  |  |  *  Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or modify
 | 
					
						
							|  |  |  |  * it under the terms of the GNU General Public License (version 2 only) | 
					
						
							|  |  |  |  * as published by the Free Software Foundation. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #include <asm/vdso.h> | 
					
						
							|  |  |  | #include <asm/asm-offsets.h> | 
					
						
							|  |  |  | #include <asm/unistd.h> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	.text | 
					
						
							|  |  |  | 	.align 4
 | 
					
						
							|  |  |  | 	.globl __kernel_clock_gettime
 | 
					
						
							|  |  |  | 	.type  __kernel_clock_gettime,@function
 | 
					
						
							|  |  |  | __kernel_clock_gettime: | 
					
						
							|  |  |  | 	.cfi_startproc | 
					
						
							|  |  |  | 	larl	%r5,_vdso_data | 
					
						
							| 
									
										
										
										
											2014-08-29 12:31:45 +02:00
										 |  |  | 	cghi	%r2,__CLOCK_REALTIME_COARSE | 
					
						
							|  |  |  | 	je	4f | 
					
						
							| 
									
										
										
										
											2010-10-29 16:50:41 +02:00
										 |  |  | 	cghi	%r2,__CLOCK_REALTIME | 
					
						
							| 
									
										
										
										
											2014-08-29 10:16:03 +02:00
										 |  |  | 	je	5f | 
					
						
							| 
									
										
										
										
											2013-12-02 14:54:56 +01:00
										 |  |  | 	cghi	%r2,__CLOCK_THREAD_CPUTIME_ID | 
					
						
							|  |  |  | 	je	9f | 
					
						
							|  |  |  | 	cghi	%r2,-2		/* Per-thread CPUCLOCK with PID=0, VIRT=1 */ | 
					
						
							| 
									
										
										
										
											2008-12-31 15:11:42 +01:00
										 |  |  | 	je	9f | 
					
						
							| 
									
										
										
										
											2014-08-29 12:31:45 +02:00
										 |  |  | 	cghi	%r2,__CLOCK_MONOTONIC_COARSE | 
					
						
							|  |  |  | 	je	3f | 
					
						
							| 
									
										
										
										
											2010-10-29 16:50:41 +02:00
										 |  |  | 	cghi	%r2,__CLOCK_MONOTONIC | 
					
						
							| 
									
										
										
										
											2008-12-31 15:11:42 +01:00
										 |  |  | 	jne	12f | 
					
						
							| 
									
										
										
										
											2008-12-25 13:38:36 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* CLOCK_MONOTONIC */ | 
					
						
							|  |  |  | 0:	lg	%r4,__VDSO_UPD_COUNT(%r5)	/* load update counter */ | 
					
						
							|  |  |  | 	tmll	%r4,0x0001			/* pending update ? loop */ | 
					
						
							|  |  |  | 	jnz	0b | 
					
						
							| 
									
										
										
										
											2014-08-29 12:44:40 +02:00
										 |  |  | 	stcke	48(%r15)			/* Store TOD clock */ | 
					
						
							| 
									
										
										
										
											2013-11-22 10:04:53 +01:00
										 |  |  | 	lgf	%r2,__VDSO_TK_SHIFT(%r5)	/* Timekeeper shift */ | 
					
						
							| 
									
										
										
										
											2013-12-02 18:00:36 +01:00
										 |  |  | 	lg	%r0,__VDSO_WTOM_SEC(%r5) | 
					
						
							| 
									
										
										
										
											2014-08-29 12:44:40 +02:00
										 |  |  | 	lg	%r1,49(%r15) | 
					
						
							| 
									
										
										
										
											2008-12-25 13:38:36 +01:00
										 |  |  | 	sg	%r1,__VDSO_XTIME_STAMP(%r5)	/* TOD - cycle_last */ | 
					
						
							| 
									
										
										
										
											2013-11-22 10:04:53 +01:00
										 |  |  | 	msgf	%r1,__VDSO_TK_MULT(%r5)		/*  * tk->mult */ | 
					
						
							| 
									
										
										
										
											2013-12-02 18:00:36 +01:00
										 |  |  | 	alg	%r1,__VDSO_WTOM_NSEC(%r5) | 
					
						
							| 
									
										
										
										
											2013-11-22 10:04:53 +01:00
										 |  |  | 	srlg	%r1,%r1,0(%r2)			/*  >> tk->shift */ | 
					
						
							| 
									
										
										
										
											2008-12-25 13:38:36 +01:00
										 |  |  | 	clg	%r4,__VDSO_UPD_COUNT(%r5)	/* check update counter */ | 
					
						
							|  |  |  | 	jne	0b | 
					
						
							| 
									
										
										
										
											2008-12-31 15:11:42 +01:00
										 |  |  | 	larl	%r5,13f | 
					
						
							| 
									
										
										
										
											2008-12-25 13:38:36 +01:00
										 |  |  | 1:	clg	%r1,0(%r5) | 
					
						
							|  |  |  | 	jl	2f | 
					
						
							|  |  |  | 	slg	%r1,0(%r5) | 
					
						
							|  |  |  | 	aghi	%r0,1 | 
					
						
							|  |  |  | 	j	1b | 
					
						
							|  |  |  | 2:	stg	%r0,0(%r3)			/* store tp->tv_sec */ | 
					
						
							|  |  |  | 	stg	%r1,8(%r3)			/* store tp->tv_nsec */ | 
					
						
							| 
									
										
										
										
											2014-08-29 10:16:03 +02:00
										 |  |  | 	lghi	%r2,0 | 
					
						
							| 
									
										
										
										
											2008-12-25 13:38:36 +01:00
										 |  |  | 	br	%r14 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-29 12:31:45 +02:00
										 |  |  | 	/* CLOCK_MONOTONIC_COARSE */ | 
					
						
							|  |  |  | 3:	lg	%r4,__VDSO_UPD_COUNT(%r5)	/* load update counter */ | 
					
						
							|  |  |  | 	tmll	%r4,0x0001			/* pending update ? loop */ | 
					
						
							|  |  |  | 	jnz	3b | 
					
						
							|  |  |  | 	lg	%r0,__VDSO_WTOM_CRS_SEC(%r5) | 
					
						
							|  |  |  | 	lg	%r1,__VDSO_WTOM_CRS_NSEC(%r5) | 
					
						
							|  |  |  | 	clg	%r4,__VDSO_UPD_COUNT(%r5)	/* check update counter */ | 
					
						
							|  |  |  | 	jne	3b | 
					
						
							|  |  |  | 	j	2b | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* CLOCK_REALTIME_COARSE */ | 
					
						
							|  |  |  | 4:	lg	%r4,__VDSO_UPD_COUNT(%r5)	/* load update counter */ | 
					
						
							|  |  |  | 	tmll	%r4,0x0001			/* pending update ? loop */ | 
					
						
							|  |  |  | 	jnz	4b | 
					
						
							|  |  |  | 	lg	%r0,__VDSO_XTIME_CRS_SEC(%r5) | 
					
						
							|  |  |  | 	lg	%r1,__VDSO_XTIME_CRS_NSEC(%r5) | 
					
						
							|  |  |  | 	clg	%r4,__VDSO_UPD_COUNT(%r5)	/* check update counter */ | 
					
						
							|  |  |  | 	jne	4b | 
					
						
							|  |  |  | 	j	7f | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-25 13:38:36 +01:00
										 |  |  | 	/* CLOCK_REALTIME */ | 
					
						
							|  |  |  | 5:	lg	%r4,__VDSO_UPD_COUNT(%r5)	/* load update counter */ | 
					
						
							|  |  |  | 	tmll	%r4,0x0001			/* pending update ? loop */ | 
					
						
							|  |  |  | 	jnz	5b | 
					
						
							| 
									
										
										
										
											2014-08-29 12:44:40 +02:00
										 |  |  | 	stcke	48(%r15)			/* Store TOD clock */ | 
					
						
							| 
									
										
										
										
											2013-11-22 10:04:53 +01:00
										 |  |  | 	lgf	%r2,__VDSO_TK_SHIFT(%r5)	/* Timekeeper shift */ | 
					
						
							| 
									
										
										
										
											2014-08-29 12:44:40 +02:00
										 |  |  | 	lg	%r1,49(%r15) | 
					
						
							| 
									
										
										
										
											2008-12-25 13:38:36 +01:00
										 |  |  | 	sg	%r1,__VDSO_XTIME_STAMP(%r5)	/* TOD - cycle_last */ | 
					
						
							| 
									
										
										
										
											2013-11-22 10:04:53 +01:00
										 |  |  | 	msgf	%r1,__VDSO_TK_MULT(%r5)		/*  * tk->mult */ | 
					
						
							|  |  |  | 	alg	%r1,__VDSO_XTIME_NSEC(%r5)	/*  + tk->xtime_nsec */ | 
					
						
							|  |  |  | 	srlg	%r1,%r1,0(%r2)			/*  >> tk->shift */ | 
					
						
							|  |  |  | 	lg	%r0,__VDSO_XTIME_SEC(%r5)	/* tk->xtime_sec */ | 
					
						
							| 
									
										
										
										
											2008-12-25 13:38:36 +01:00
										 |  |  | 	clg	%r4,__VDSO_UPD_COUNT(%r5)	/* check update counter */ | 
					
						
							|  |  |  | 	jne	5b | 
					
						
							| 
									
										
										
										
											2008-12-31 15:11:42 +01:00
										 |  |  | 	larl	%r5,13f | 
					
						
							| 
									
										
										
										
											2008-12-25 13:38:36 +01:00
										 |  |  | 6:	clg	%r1,0(%r5) | 
					
						
							|  |  |  | 	jl	7f | 
					
						
							|  |  |  | 	slg	%r1,0(%r5) | 
					
						
							|  |  |  | 	aghi	%r0,1 | 
					
						
							|  |  |  | 	j	6b | 
					
						
							|  |  |  | 7:	stg	%r0,0(%r3)			/* store tp->tv_sec */ | 
					
						
							|  |  |  | 	stg	%r1,8(%r3)			/* store tp->tv_nsec */ | 
					
						
							| 
									
										
										
										
											2014-08-29 10:16:03 +02:00
										 |  |  | 	lghi	%r2,0 | 
					
						
							| 
									
										
										
										
											2008-12-25 13:38:36 +01:00
										 |  |  | 	br	%r14 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-31 15:11:42 +01:00
										 |  |  | 	/* CLOCK_THREAD_CPUTIME_ID for this thread */ | 
					
						
							|  |  |  | 9:	icm	%r0,15,__VDSO_ECTG_OK(%r5) | 
					
						
							|  |  |  | 	jz	12f | 
					
						
							|  |  |  | 	ear	%r2,%a4 | 
					
						
							|  |  |  | 	llilh	%r4,0x0100 | 
					
						
							|  |  |  | 	sar	%a4,%r4 | 
					
						
							|  |  |  | 	lghi	%r4,0 | 
					
						
							| 
									
										
										
										
											2009-07-24 12:39:52 +02:00
										 |  |  | 	epsw	%r5,0 | 
					
						
							| 
									
										
										
										
											2008-12-31 15:11:42 +01:00
										 |  |  | 	sacf	512				/* Magic ectg instruction */ | 
					
						
							|  |  |  | 	.insn	ssf,0xc80100000000,__VDSO_ECTG_BASE(4),__VDSO_ECTG_USER(4),4 | 
					
						
							| 
									
										
										
										
											2009-07-24 12:39:52 +02:00
										 |  |  | 	tml	%r5,0x4000 | 
					
						
							|  |  |  | 	jo	11f | 
					
						
							|  |  |  | 	tml	%r5,0x8000 | 
					
						
							|  |  |  | 	jno	10f | 
					
						
							|  |  |  | 	sacf	256 | 
					
						
							|  |  |  | 	j	11f | 
					
						
							|  |  |  | 10:	sacf	0 | 
					
						
							|  |  |  | 11:	sar	%a4,%r2 | 
					
						
							| 
									
										
										
										
											2008-12-31 15:11:42 +01:00
										 |  |  | 	algr	%r1,%r0				/* r1 = cputime as TOD value */ | 
					
						
							|  |  |  | 	mghi	%r1,1000			/* convert to nanoseconds */ | 
					
						
							|  |  |  | 	srlg	%r1,%r1,12			/* r1 = cputime in nanosec */ | 
					
						
							|  |  |  | 	lgr	%r4,%r1 | 
					
						
							|  |  |  | 	larl	%r5,13f | 
					
						
							|  |  |  | 	srlg	%r1,%r1,9			/* divide by 1000000000 */ | 
					
						
							|  |  |  | 	mlg	%r0,8(%r5) | 
					
						
							|  |  |  | 	srlg	%r0,%r0,11			/* r0 = tv_sec */ | 
					
						
							|  |  |  | 	stg	%r0,0(%r3) | 
					
						
							|  |  |  | 	msg	%r0,0(%r5)			/* calculate tv_nsec */ | 
					
						
							|  |  |  | 	slgr	%r4,%r0				/* r4 = tv_nsec */ | 
					
						
							|  |  |  | 	stg	%r4,8(%r3) | 
					
						
							|  |  |  | 	lghi	%r2,0 | 
					
						
							|  |  |  | 	br	%r14 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-25 13:38:36 +01:00
										 |  |  | 	/* Fallback to system call */ | 
					
						
							| 
									
										
										
										
											2008-12-31 15:11:42 +01:00
										 |  |  | 12:	lghi	%r1,__NR_clock_gettime | 
					
						
							| 
									
										
										
										
											2008-12-25 13:38:36 +01:00
										 |  |  | 	svc	0 | 
					
						
							|  |  |  | 	br	%r14 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-31 15:11:42 +01:00
										 |  |  | 13:	.quad	1000000000 | 
					
						
							|  |  |  | 14:	.quad	19342813113834067 | 
					
						
							| 
									
										
										
										
											2008-12-25 13:38:36 +01:00
										 |  |  | 	.cfi_endproc | 
					
						
							|  |  |  | 	.size	__kernel_clock_gettime,.-__kernel_clock_gettime |