Branch data Line data Source code
1 : : /* 2 : : * Copyright (c) 2017 Oticon A/S 3 : : * 4 : : * SPDX-License-Identifier: Apache-2.0 5 : : */ 6 : : 7 : : /* 8 : : * The basic principle of operation is: 9 : : * No asynchronous behavior, no indeterminism. 10 : : * If you run the same thing 20 times, you get exactly the same result 20 11 : : * times. 12 : : * It does not matter if you are running from console, or in a debugger 13 : : * and you go for lunch in the middle of the debug session. 14 : : * 15 : : * This is achieved as follows: 16 : : * The execution of native_posix is decoupled from the underlying host and its 17 : : * peripherals (unless set otherwise). 18 : : * In general, time in native_posix is simulated. 19 : : * 20 : : * But, native_posix can also be linked if desired to the underlying host, 21 : : * e.g.:You can use the provided Ethernet TAP driver, or a host BLE controller. 22 : : * 23 : : * In this case, the no-indeterminism principle is lost. Runs of native_posix 24 : : * will depend on the host load and the interactions with those real host 25 : : * peripherals. 26 : : * 27 : : */ 28 : : 29 : : #include <stdio.h> 30 : : #include <soc.h> 31 : : #include "hw_models_top.h" 32 : : #include <stdlib.h> 33 : : #include <zephyr/sys/util.h> 34 : : #include <zephyr/sys/time_units.h> 35 : : #include "cmdline.h" 36 : : #include "irq_ctrl.h" 37 : : 38 : 2 : void posix_exit(int exit_code) 39 : : { 40 : 2 : static int max_exit_code; 41 : : 42 : 2 : max_exit_code = MAX(exit_code, max_exit_code); 43 : : /* 44 : : * posix_soc_clean_up may not return if this is called from a SW thread, 45 : : * but instead it would get posix_exit() recalled again 46 : : * ASAP from the HW thread 47 : : */ 48 : 2 : posix_soc_clean_up(); 49 : 1 : hwm_cleanup(); 50 : 1 : native_cleanup_cmd_line(); 51 : 1 : exit(max_exit_code); 52 : : } 53 : : 54 : : /** 55 : : * Run all early native_posix initialization steps, including command 56 : : * line parsing and CPU start, until we are ready to let the HW models 57 : : * run via hwm_one_event() 58 : : */ 59 : 1 : void posix_init(int argc, char *argv[]) 60 : : { 61 : : /* 62 : : * Let's ensure that even if we are redirecting to a file, we get stdout 63 : : * and stderr line buffered (default for console) 64 : : * Note that glibc ignores size. But just in case we set a reasonable 65 : : * number in case somebody tries to compile against a different library 66 : : */ 67 : 1 : setvbuf(stdout, NULL, _IOLBF, 512); 68 : 1 : setvbuf(stderr, NULL, _IOLBF, 512); 69 : : 70 : 1 : run_native_tasks(_NATIVE_PRE_BOOT_1_LEVEL); 71 : : 72 : 1 : native_handle_cmd_line(argc, argv); 73 : : 74 : 1 : run_native_tasks(_NATIVE_PRE_BOOT_2_LEVEL); 75 : : 76 : 1 : hwm_init(); 77 : : 78 : 1 : run_native_tasks(_NATIVE_PRE_BOOT_3_LEVEL); 79 : : 80 : 1 : posix_boot_cpu(); 81 : : 82 : 0 : run_native_tasks(_NATIVE_FIRST_SLEEP_LEVEL); 83 : 0 : } 84 : : 85 : : /** 86 : : * Execute the simulator for at least the specified timeout, then 87 : : * return. Note that this does not affect event timing, so the "next 88 : : * event" may be significantly after the request if the hardware has 89 : : * not been configured to e.g. send an interrupt when expected. 90 : : */ 91 : 0 : void posix_exec_for(uint64_t us) 92 : : { 93 : 0 : uint64_t start = hwm_get_time(); 94 : : 95 : 0 : do { 96 : 0 : hwm_one_event(); 97 [ # # ]: 0 : } while (hwm_get_time() < (start + us)); 98 : 0 : } 99 : : 100 : : #ifndef CONFIG_ARCH_POSIX_LIBFUZZER 101 : : 102 : : /** 103 : : * This is the actual host process main routine. The Zephyr 104 : : * application's main() is renamed via preprocessor trickery to avoid 105 : : * collisions. 106 : : * 107 : : * Not used when building fuzz cases, as libfuzzer has its own main() 108 : : * and calls the "OS" through a per-case fuzz test entry point. 109 : : */ 110 : 1 : int main(int argc, char *argv[]) 111 : : { 112 : 1 : posix_init(argc, argv); 113 : 0 : while (true) { 114 : 0 : hwm_one_event(); 115 : : } 116 : : 117 : : /* This line should be unreachable */ 118 : : return 1; /* LCOV_EXCL_LINE */ 119 : : } 120 : : 121 : : #endif