1 /*
2  * Copyright (c) 2023 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <soc.h>
10 #include <posix_native_task.h>
11 #include <nsi_cpu_if.h>
12 #include "bstests.h"
13 #include "bs_tracing.h"
14 #include "phy_sync_ctrl.h"
15 #include "nsi_hw_scheduler.h"
16 #include "nsi_cpu_ctrl.h"
17 #include "nsi_host_trampolines.h"
18 
19 /*
20  * These hooks are to be named nsif_cpu<cpu_number>_<hook_name>, for example nsif_cpu0_boot
21  */
22 #define nsif_cpun_pre_cmdline_hooks  _CONCAT(_CONCAT(nsif_cpu, CONFIG_NATIVE_SIMULATOR_MCU_N),\
23 					     _pre_cmdline_hooks)
24 #define nsif_cpun_save_test_arg      _CONCAT(_CONCAT(nsif_cpu, CONFIG_NATIVE_SIMULATOR_MCU_N),\
25 					     _save_test_arg)
26 #define nsif_cpun_pre_hw_init_hooks  _CONCAT(_CONCAT(nsif_cpu, CONFIG_NATIVE_SIMULATOR_MCU_N),\
27 					     _pre_hw_init_hooks)
28 #define nsif_cpun_boot               _CONCAT(_CONCAT(nsif_cpu, CONFIG_NATIVE_SIMULATOR_MCU_N),\
29 					     _boot)
30 #define nsif_cpun_cleanup            _CONCAT(_CONCAT(nsif_cpu, CONFIG_NATIVE_SIMULATOR_MCU_N),\
31 					     _cleanup)
32 #define nsif_cpun_irq_raised         _CONCAT(_CONCAT(nsif_cpu, CONFIG_NATIVE_SIMULATOR_MCU_N),\
33 					     _irq_raised)
34 #define nsif_cpun_test_hook          _CONCAT(_CONCAT(nsif_cpu, CONFIG_NATIVE_SIMULATOR_MCU_N),\
35 					     _test_hook)
36 #define nsif_cpun_irq_raised_from_sw _CONCAT(_CONCAT(nsif_cpu, CONFIG_NATIVE_SIMULATOR_MCU_N),\
37 					     _irq_raised_from_sw)
38 
nsif_cpun_pre_cmdline_hooks(void)39 NATIVE_SIMULATOR_IF void nsif_cpun_pre_cmdline_hooks(void)
40 {
41 	run_native_tasks(_NATIVE_PRE_BOOT_1_LEVEL);
42 #if defined(CONFIG_NATIVE_SIMULATOR_AUTOSTART_MCU)
43 	nsi_cpu_set_auto_start(CONFIG_NATIVE_SIMULATOR_MCU_N, true);
44 #endif
45 }
46 
47 #define TESTCASAE_ARGV_ALLOCSIZE 128
48 
49 static struct {
50 	char **test_case_argv;
51 	int test_case_argc;
52 	int allocated_size;
53 } test_args;
54 
nsif_cpun_save_test_arg(char * argv)55 NATIVE_SIMULATOR_IF void nsif_cpun_save_test_arg(char *argv)
56 {
57 	if (test_args.test_case_argc >= test_args.allocated_size) {
58 		test_args.allocated_size += TESTCASAE_ARGV_ALLOCSIZE;
59 		test_args.test_case_argv = nsi_host_realloc(test_args.test_case_argv,
60 						test_args.allocated_size * sizeof(char *));
61 		if (test_args.test_case_argv == NULL) { /* LCOV_EXCL_BR_LINE */
62 			bs_trace_error_line("Can't allocate memory\n"); /* LCOV_EXCL_LINE */
63 		}
64 	}
65 
66 	bs_trace_raw(9, "cmdarg: adding '%s' to testcase args[%i]\n",
67 		     argv, test_args.test_case_argc);
68 	test_args.test_case_argv[test_args.test_case_argc++] = argv;
69 }
70 
test_args_free(void)71 static void test_args_free(void)
72 {
73 	if (test_args.test_case_argv) {
74 		nsi_host_free(test_args.test_case_argv);
75 		test_args.test_case_argv = NULL;
76 	}
77 }
78 
79 NATIVE_TASK(test_args_free, ON_EXIT_PRE, 100);
80 
nsif_cpun_pre_hw_init_hooks(void)81 NATIVE_SIMULATOR_IF void nsif_cpun_pre_hw_init_hooks(void)
82 {
83 	run_native_tasks(_NATIVE_PRE_BOOT_2_LEVEL);
84 	phy_sync_ctrl_connect_to_2G4_phy();
85 
86 	/* We pass to a possible testcase its command line arguments */
87 	bst_pass_args(test_args.test_case_argc, test_args.test_case_argv);
88 	phy_sync_ctrl_pre_boot2();
89 }
90 
nsif_cpun_boot(void)91 NATIVE_SIMULATOR_IF void nsif_cpun_boot(void)
92 {
93 	run_native_tasks(_NATIVE_PRE_BOOT_3_LEVEL);
94 	bst_pre_init();
95 	phy_sync_ctrl_pre_boot3();
96 	posix_boot_cpu();
97 	run_native_tasks(_NATIVE_FIRST_SLEEP_LEVEL);
98 	bst_post_init();
99 }
100 
nsif_cpun_cleanup(void)101 NATIVE_SIMULATOR_IF int nsif_cpun_cleanup(void)
102 {
103 	/*
104 	 * Note posix_soc_clean_up() may not return, but in that case,
105 	 * nsif_cpun_cleanup() will be called again
106 	 */
107 	posix_soc_clean_up();
108 
109 	uint8_t bst_result = bst_delete();
110 	return bst_result;
111 }
112 
nsif_cpun_irq_raised(void)113 NATIVE_SIMULATOR_IF void nsif_cpun_irq_raised(void)
114 {
115 	posix_interrupt_raised();
116 }
117 
nsif_cpun_test_hook(void * p)118 NATIVE_SIMULATOR_IF int nsif_cpun_test_hook(void *p)
119 {
120 	(void) p;
121 	bst_tick(nsi_hws_get_time());
122 	return 0;
123 }
124 
nsif_cpun_irq_raised_from_sw(void)125 NATIVE_SIMULATOR_IF void nsif_cpun_irq_raised_from_sw(void)
126 {
127 	void posix_irq_handler_im_from_sw(void);
128 	posix_irq_handler_im_from_sw();
129 }
130