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)12void 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 25 /* use 64-bit math to prevent overflow when multiplying */ 26 uint32_t cycles_to_wait = (uint32_t)( 27 (uint64_t)usec_to_wait * 28 (uint64_t)sys_clock_hw_cycles_per_sec() / 29 (uint64_t)USEC_PER_SEC 30 ); 31 32 for (;;) { 33 uint32_t current_cycles = k_cycle_get_32(); 34 35 /* this handles the rollover on an unsigned 32-bit value */ 36 if ((current_cycles - start_cycles) >= cycles_to_wait) { 37 break; 38 } 39 } 40 #else 41 /* 42 * Crude busy loop for the purpose of being able to configure out 43 * system timer support. 44 */ 45 unsigned int loops_per_usec = CONFIG_BUSYWAIT_CPU_LOOPS_PER_USEC; 46 unsigned int loops = loops_per_usec * usec_to_wait; 47 48 while (loops-- > 0) { 49 arch_nop(); 50 } 51 #endif 52 53 SYS_PORT_TRACING_FUNC_EXIT(k_thread, busy_wait, usec_to_wait); 54 } 55 56 #ifdef CONFIG_USERSPACE z_vrfy_k_busy_wait(uint32_t usec_to_wait)57static inline void z_vrfy_k_busy_wait(uint32_t usec_to_wait) 58 { 59 z_impl_k_busy_wait(usec_to_wait); 60 } 61 #include <syscalls/k_busy_wait_mrsh.c> 62 #endif /* CONFIG_USERSPACE */ 63