1 /*
2  * Copyright (c) 2018 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/drivers/timer/system_timer.h>
9 #include <zephyr/sys_clock.h>
10 #include <kernel_arch_interface.h>
11 
z_impl_k_busy_wait(uint32_t usec_to_wait)12 void z_impl_k_busy_wait(uint32_t usec_to_wait)
13 {
14 	SYS_PORT_TRACING_FUNC_ENTER(k_thread, busy_wait, usec_to_wait);
15 	if (usec_to_wait == 0U) {
16 		SYS_PORT_TRACING_FUNC_EXIT(k_thread, busy_wait, usec_to_wait);
17 		return;
18 	}
19 
20 #if defined(CONFIG_ARCH_HAS_CUSTOM_BUSY_WAIT)
21 	arch_busy_wait(usec_to_wait);
22 #elif defined(CONFIG_SYS_CLOCK_EXISTS)
23 	uint32_t start_cycles = k_cycle_get_32();
24 	uint32_t cycles_to_wait = k_us_to_cyc_ceil32(usec_to_wait);
25 
26 	for (;;) {
27 		uint32_t current_cycles = k_cycle_get_32();
28 
29 		/* this handles the rollover on an unsigned 32-bit value */
30 		if ((current_cycles - start_cycles) >= cycles_to_wait) {
31 			break;
32 		}
33 	}
34 #else
35 	/*
36 	 * Crude busy loop for the purpose of being able to configure out
37 	 * system timer support.
38 	 */
39 	unsigned int loops_per_usec = CONFIG_BUSYWAIT_CPU_LOOPS_PER_USEC;
40 	unsigned int loops = loops_per_usec * usec_to_wait;
41 
42 	while (loops-- > 0) {
43 		arch_nop();
44 	}
45 #endif
46 
47 	SYS_PORT_TRACING_FUNC_EXIT(k_thread, busy_wait, usec_to_wait);
48 }
49 
50 #ifdef CONFIG_USERSPACE
z_vrfy_k_busy_wait(uint32_t usec_to_wait)51 static inline void z_vrfy_k_busy_wait(uint32_t usec_to_wait)
52 {
53 	z_impl_k_busy_wait(usec_to_wait);
54 }
55 #include <syscalls/k_busy_wait_mrsh.c>
56 #endif /* CONFIG_USERSPACE */
57