xref: /kvm-unit-tests/lib/s390x/asm/time.h (revision 8a078df4dde8f4a0113b9d45bb02140ea9c24ba5)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Clock utilities for s390
4  *
5  * Authors:
6  *  Thomas Huth <thuth@redhat.com>
7  *
8  * Copied from the s390/intercept test by:
9  *  Pierre Morel <pmorel@linux.ibm.com>
10  */
11 #ifndef _ASMS390X_TIME_H_
12 #define _ASMS390X_TIME_H_
13 
14 #define S390_CLOCK_SHIFT_US	(63 - 51)
15 
16 #define STCK_SHIFT_US	S390_CLOCK_SHIFT_US
17 #define STCK_MAX	((1UL << 52) - 1)
18 
19 #define CPU_TIMER_SHIFT_US	S390_CLOCK_SHIFT_US
20 
21 static inline uint64_t get_clock_us(void)
22 {
23 	uint64_t clk;
24 
25 	asm volatile(" stck %0 " : : "Q"(clk) : "memory");
26 
27 	return clk >> STCK_SHIFT_US;
28 }
29 
30 static inline uint64_t get_clock_ms(void)
31 {
32 	return get_clock_us() / 1000;
33 }
34 
35 static inline void udelay(unsigned long us)
36 {
37 	unsigned long startclk = get_clock_us();
38 	unsigned long c;
39 
40 	do {
41 		c = get_clock_us();
42 		if (c < startclk)
43 			c += STCK_MAX;
44 	} while (c < startclk + us);
45 }
46 
47 static inline void mdelay(unsigned long ms)
48 {
49 	udelay(ms * 1000);
50 }
51 
52 static inline void cpu_timer_set_ms(int64_t timeout_ms)
53 {
54 	int64_t timer_value = (timeout_ms * 1000) << CPU_TIMER_SHIFT_US;
55 
56 	asm volatile (
57 		"spt %[timer_value]\n"
58 		:
59 		: [timer_value] "Q" (timer_value)
60 	);
61 }
62 
63 #endif
64