1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <cpu/x86/tsc.h>
14 void udelay(unsigned int us
)
16 unsigned long long start
;
17 unsigned long long current
;
18 unsigned long long clocks
;
20 if (!thread_yield_microseconds(us
))
25 clocks
*= tsc_freq_mhz();
27 while ((current
- start
) < clocks
) {
33 #if CONFIG(TSC_MONOTONIC_TIMER)
36 static struct monotonic_counter
{
38 struct mono_time time
;
42 void timer_monotonic_get(struct mono_time
*mt
)
44 uint64_t current_tick
;
45 uint64_t ticks_elapsed
;
46 unsigned long ticks_per_usec
;
48 if (!mono_counter
.initialized
) {
50 mono_counter
.last_value
= rdtscll();
51 mono_counter
.initialized
= 1;
54 current_tick
= rdtscll();
55 ticks_elapsed
= current_tick
- mono_counter
.last_value
;
56 ticks_per_usec
= tsc_freq_mhz();
58 /* Update current time and tick values only if a full tick occurred. */
59 if (ticks_elapsed
>= ticks_per_usec
) {
60 uint64_t usecs_elapsed
;
62 usecs_elapsed
= ticks_elapsed
/ ticks_per_usec
;
63 mono_time_add_usecs(&mono_counter
.time
, (long)usecs_elapsed
);
64 mono_counter
.last_value
= current_tick
;
68 *mt
= mono_counter
.time
;