1 /*
2  * Copyright (c) 2017 Oticon A/S
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdbool.h>
8 #include "zephyr/types.h"
9 #include "fake_timer.h"
10 #include "time_machine.h"
11 #include <arch/posix/posix_soc_if.h>
12 #include <posix_board_if.h>
13 #include <posix_soc.h>
14 
15 /**
16  * Replacement to the kernel k_busy_wait()
17  * Will block this thread (and therefore the whole Zephyr) during usec_to_wait
18  *
19  * Note that interrupts may be received in the meanwhile and that therefore this
20  * thread may lose context.
21  * Therefore the wait time may be considerably longer.
22  *
23  * All this function ensures is that it will return after usec_to_wait or later.
24  */
arch_busy_wait(uint32_t usec_to_wait)25 void arch_busy_wait(uint32_t usec_to_wait)
26 {
27 	bs_time_t time_end = tm_get_hw_time() + usec_to_wait;
28 
29 	while (tm_get_hw_time() < time_end) {
30 		/*
31 		 * There may be wakes due to other interrupts or nested calls to
32 		 * k_busy_wait in interrupt handlers
33 		 */
34 		fake_timer_wake_in_time(time_end);
35 		posix_halt_cpu();
36 	}
37 }
38 
39 /**
40  * Will block this thread (and therefore the whole Zephyr) during usec_to_waste
41  *
42  * Very similar to arch_busy_wait(), but if an interrupt or context switch
43  * occurs this function will continue waiting after, ensuring that
44  * usec_to_waste are spent in this context, irrespectively of how much more
45  * time would be spent on interrupt handling or possible switched-in tasks.
46  *
47  * Can be used to emulate code execution time.
48  */
posix_cpu_hold(uint32_t usec_to_waste)49 void posix_cpu_hold(uint32_t usec_to_waste)
50 {
51 	bs_time_t time_start;
52 	int64_t to_wait = usec_to_waste;
53 
54 	while (to_wait > 0) {
55 		/*
56 		 * There may be wakes due to other interrupts or nested calls to
57 		 * cpu_hold in interrupt handlers
58 		 */
59 		time_start = tm_get_hw_time();
60 		fake_timer_wake_in_time(time_start + to_wait);
61 		posix_change_cpu_state_and_wait(true);
62 		to_wait -= tm_get_hw_time() - time_start;
63 
64 		posix_irq_handler();
65 	}
66 }
67