1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2012 - 2014 Cisco Systems
4  * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
5  */
6 
7 #ifndef __TIMER_INTERNAL_H__
8 #define __TIMER_INTERNAL_H__
9 #include <linux/list.h>
10 #include <asm/bug.h>
11 
12 #define TIMER_MULTIPLIER 256
13 #define TIMER_MIN_DELTA  500
14 
15 enum time_travel_mode {
16 	TT_MODE_OFF,
17 	TT_MODE_BASIC,
18 	TT_MODE_INFCPU,
19 	TT_MODE_EXTERNAL,
20 };
21 
22 #ifdef CONFIG_UML_TIME_TRAVEL_SUPPORT
23 struct time_travel_event {
24 	unsigned long long time;
25 	void (*fn)(struct time_travel_event *d);
26 	struct list_head list;
27 	bool pending, onstack;
28 };
29 
30 extern enum time_travel_mode time_travel_mode;
31 
32 void time_travel_sleep(void);
33 
34 static inline void
35 time_travel_set_event_fn(struct time_travel_event *e,
36 			 void (*fn)(struct time_travel_event *d))
37 {
38 	e->fn = fn;
39 }
40 
41 void __time_travel_propagate_time(void);
42 
43 static inline void time_travel_propagate_time(void)
44 {
45 	if (time_travel_mode == TT_MODE_EXTERNAL)
46 		__time_travel_propagate_time();
47 }
48 
49 void __time_travel_wait_readable(int fd);
50 
51 static inline void time_travel_wait_readable(int fd)
52 {
53 	if (time_travel_mode == TT_MODE_EXTERNAL)
54 		__time_travel_wait_readable(fd);
55 }
56 
57 void time_travel_add_irq_event(struct time_travel_event *e);
58 void time_travel_add_event_rel(struct time_travel_event *e,
59 			       unsigned long long delay_ns);
60 bool time_travel_del_event(struct time_travel_event *e);
61 #else
62 struct time_travel_event {
63 };
64 
65 #define time_travel_mode TT_MODE_OFF
66 
67 static inline void time_travel_sleep(void)
68 {
69 }
70 
71 /* this is a macro so the event/function need not exist */
72 #define time_travel_set_event_fn(e, fn) do {} while (0)
73 
74 static inline void time_travel_propagate_time(void)
75 {
76 }
77 
78 static inline void time_travel_wait_readable(int fd)
79 {
80 }
81 
82 static inline void time_travel_add_irq_event(struct time_travel_event *e)
83 {
84 	WARN_ON(1);
85 }
86 
87 /*
88  * not inlines so the data structure need not exist,
89  * cause linker failures
90  */
91 extern void time_travel_not_configured(void);
92 #define time_travel_add_event_rel(...) time_travel_not_configured()
93 #define time_travel_del_event(...) time_travel_not_configured()
94 #endif /* CONFIG_UML_TIME_TRAVEL_SUPPORT */
95 
96 /*
97  * Without CONFIG_UML_TIME_TRAVEL_SUPPORT this is a linker error if used,
98  * which is intentional since we really shouldn't link it in that case.
99  */
100 void time_travel_ndelay(unsigned long nsec);
101 #endif /* __TIMER_INTERNAL_H__ */
102