/* * Copyright (c) 2017 Oticon A/S * * SPDX-License-Identifier: Apache-2.0 */ /* * The basic principle of operation is: * No asynchronous behavior, no indeterminism. * If you run the same thing 20 times, you get exactly the same result 20 * times. * It does not matter if you are running from console, or in a debugger * and you go for lunch in the middle of the debug session. * * This is achieved as follows: * The execution of native_posix is decoupled from the underlying host and its * peripherals (unless set otherwise). * In general, time in native_posix is simulated. * * But, native_posix can also be linked if desired to the underlying host, * e.g.:You can use the provided Ethernet TAP driver, or a host BLE controller. * * In this case, the no-indeterminism principle is lost. Runs of native_posix * will depend on the host load and the interactions with those real host * peripherals. * */ #include #include #include "hw_models_top.h" #include #include #include #include "cmdline.h" #include "irq_ctrl.h" void posix_exit(int exit_code) { static int max_exit_code; max_exit_code = MAX(exit_code, max_exit_code); /* * posix_soc_clean_up may not return if this is called from a SW thread, * but instead it would get posix_exit() recalled again * ASAP from the HW thread */ posix_soc_clean_up(); hwm_cleanup(); native_cleanup_cmd_line(); exit(max_exit_code); } /** * Run all early native_posix initialization steps, including command * line parsing and CPU start, until we are ready to let the HW models * run via hwm_one_event() */ void posix_init(int argc, char *argv[]) { /* * Let's ensure that even if we are redirecting to a file, we get stdout * and stderr line buffered (default for console) * Note that glibc ignores size. But just in case we set a reasonable * number in case somebody tries to compile against a different library */ setvbuf(stdout, NULL, _IOLBF, 512); setvbuf(stderr, NULL, _IOLBF, 512); run_native_tasks(_NATIVE_PRE_BOOT_1_LEVEL); native_handle_cmd_line(argc, argv); run_native_tasks(_NATIVE_PRE_BOOT_2_LEVEL); hwm_init(); run_native_tasks(_NATIVE_PRE_BOOT_3_LEVEL); posix_boot_cpu(); run_native_tasks(_NATIVE_FIRST_SLEEP_LEVEL); } /** * Execute the simulator for at least the specified timeout, then * return. Note that this does not affect event timing, so the "next * event" may be significantly after the request if the hardware has * not been configured to e.g. send an interrupt when expected. */ void posix_exec_for(uint64_t us) { uint64_t start = hwm_get_time(); do { hwm_one_event(); } while (hwm_get_time() < (start + us)); } #ifndef CONFIG_ARCH_POSIX_LIBFUZZER /** * This is the actual host process main routine. The Zephyr * application's main() is renamed via preprocessor trickery to avoid * collisions. * * Not used when building fuzz cases, as libfuzzer has its own main() * and calls the "OS" through a per-case fuzz test entry point. */ int main(int argc, char *argv[]) { posix_init(argc, argv); while (true) { hwm_one_event(); } /* This line should be unreachable */ return 1; /* LCOV_EXCL_LINE */ } #endif