xref: /kvm-unit-tests/lib/s390x/asm/time.h (revision 4cb1ee8f2277348cc13662ee3fd5e12b4f33358e)
165b436f2SPierre Morel /*
265b436f2SPierre Morel  * Clock utilities for s390
365b436f2SPierre Morel  *
465b436f2SPierre Morel  * Authors:
565b436f2SPierre Morel  *  Thomas Huth <thuth@redhat.com>
665b436f2SPierre Morel  *
765b436f2SPierre Morel  * Copied from the s390/intercept test by:
865b436f2SPierre Morel  *  Pierre Morel <pmorel@linux.ibm.com>
965b436f2SPierre Morel  *
1065b436f2SPierre Morel  * This code is free software; you can redistribute it and/or modify it
1165b436f2SPierre Morel  * under the terms of the GNU General Public License version 2.
1265b436f2SPierre Morel  */
1365b436f2SPierre Morel #ifndef ASM_S390X_TIME_H
1465b436f2SPierre Morel #define ASM_S390X_TIME_H
1565b436f2SPierre Morel 
16*4cb1ee8fSPierre Morel #define STCK_SHIFT_US	(63 - 51)
17*4cb1ee8fSPierre Morel #define STCK_MAX	((1UL << 52) - 1)
18*4cb1ee8fSPierre Morel 
19*4cb1ee8fSPierre Morel static inline uint64_t get_clock_us(void)
2065b436f2SPierre Morel {
2165b436f2SPierre Morel 	uint64_t clk;
2265b436f2SPierre Morel 
2365b436f2SPierre Morel 	asm volatile(" stck %0 " : : "Q"(clk) : "memory");
2465b436f2SPierre Morel 
25*4cb1ee8fSPierre Morel 	return clk >> STCK_SHIFT_US;
26*4cb1ee8fSPierre Morel }
27*4cb1ee8fSPierre Morel 
28*4cb1ee8fSPierre Morel static inline uint64_t get_clock_ms(void)
29*4cb1ee8fSPierre Morel {
30*4cb1ee8fSPierre Morel 	return get_clock_us() / 1000;
31*4cb1ee8fSPierre Morel }
32*4cb1ee8fSPierre Morel 
33*4cb1ee8fSPierre Morel static inline void udelay(unsigned long us)
34*4cb1ee8fSPierre Morel {
35*4cb1ee8fSPierre Morel 	unsigned long startclk = get_clock_us();
36*4cb1ee8fSPierre Morel 	unsigned long c;
37*4cb1ee8fSPierre Morel 
38*4cb1ee8fSPierre Morel 	do {
39*4cb1ee8fSPierre Morel 		c = get_clock_us();
40*4cb1ee8fSPierre Morel 		if (c < startclk)
41*4cb1ee8fSPierre Morel 			c += STCK_MAX;
42*4cb1ee8fSPierre Morel 	} while (c < startclk + us);
43*4cb1ee8fSPierre Morel }
44*4cb1ee8fSPierre Morel 
45*4cb1ee8fSPierre Morel static inline void mdelay(unsigned long ms)
46*4cb1ee8fSPierre Morel {
47*4cb1ee8fSPierre Morel 	udelay(ms * 1000);
4865b436f2SPierre Morel }
4965b436f2SPierre Morel 
5065b436f2SPierre Morel #endif
51