1 /*
2  * Copyright (c) 2017-2022, Arm Limited. All rights reserved.
3  * Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company)
4  * or an affiliate of Cypress Semiconductor Corporation. All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  */
9 
10 #include "tfm_api.h"
11 #include "cmsis_os2.h"
12 #include "cmsis_compiler.h"
13 #include "tfm_ns_interface.h"
14 #include "tfm_nsid_manager.h"
15 #include "test_app.h"
16 #include "tfm_plat_ns.h"
17 #include "driver/Driver_USART.h"
18 #include "device_cfg.h"
19 #ifdef TFM_PARTITION_NS_AGENT_MAILBOX
20 #include "tfm_multi_core_api.h"
21 #include "tfm_ns_mailbox.h"
22 #endif
23 #include "tfm_log.h"
24 #include "uart_stdout.h"
25 #if (CONFIG_TFM_FLOAT_ABI >= 1)
26 #include "cmsis.h"
27 #endif
28 
29 /**
30  * \brief Modified table template for user defined SVC functions
31  *
32  * \details RTX has a weak definition of osRtxUserSVC, which
33  *          is overridden here
34  */
35 #if defined(__ARMCC_VERSION)
36 #if (__ARMCC_VERSION == 6110004)
37 /* Workaround needed for a bug in Armclang 6.11, more details at:
38  * http://www.keil.com/support/docs/4089.htm
39  */
40 __attribute__((section(".gnu.linkonce")))
41 #endif
42 
43 /* Avoids the semihosting issue */
44 #if (__ARMCC_VERSION >= 6010050)
45 __asm("  .global __ARM_use_no_argv\n");
46 #endif
47 #endif
48 
49 /**
50  * \brief List of RTOS thread attributes
51  */
52 static const osThreadAttr_t thread_attr = {
53     .name = "test_thread",
54     .stack_size = 4096U,
55     .tz_module = ((TZ_ModuleId_t)TFM_DEFAULT_NSID)
56 };
57 /**
58  * \brief Static globals to hold RTOS related quantities,
59  *        main thread
60  */
61 static osThreadFunc_t thread_func = test_app;
62 
63 #ifdef TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD
64 static osThreadFunc_t mailbox_thread_func = tfm_ns_mailbox_thread_runner;
65 static const osThreadAttr_t mailbox_thread_attr = {
66     .name = "mailbox_thread",
67     .stack_size = 1024U
68 };
69 #endif
70 
71 #ifdef TFM_PARTITION_NS_AGENT_MAILBOX
72 static struct ns_mailbox_queue_t ns_mailbox_queue;
73 
tfm_ns_multi_core_boot(void)74 static void tfm_ns_multi_core_boot(void)
75 {
76     int32_t ret;
77 
78     LOG_MSG("Non-secure code running on non-secure core.\r\n");
79 
80     if (tfm_ns_wait_for_s_cpu_ready()) {
81         LOG_MSG("Error sync'ing with secure core.\r\n");
82 
83         /* Avoid undefined behavior after multi-core sync-up failed */
84         for (;;) {
85         }
86     }
87 
88     ret = tfm_ns_mailbox_init(&ns_mailbox_queue);
89     if (ret != MAILBOX_SUCCESS) {
90         LOG_MSG("Non-secure mailbox initialization failed.\r\n");
91 
92         /* Avoid undefined behavior after NS mailbox initialization failed */
93         for (;;) {
94         }
95     }
96 }
97 #endif /* TFM_PARTITION_NS_AGENT_MAILBOX */
98 
99 #ifdef CONFIG_TFM_USE_TRUSTZONE
100 extern uint32_t tfm_ns_interface_init(void);
101 #endif
102 
103 /**
104  * \brief Platform peripherals and devices initialization.
105  *        Can be overridden for platform specific initialization.
106  *
107  * \return  ARM_DRIVER_OK if the initialization succeeds
108  */
tfm_ns_platform_init(void)109 __WEAK int32_t tfm_ns_platform_init(void)
110 {
111     stdio_init();
112 
113     return ARM_DRIVER_OK;
114 }
115 
116 /**
117  * \brief Platform peripherals and devices de-initialization.
118  *        Can be overridden for platform specific initialization.
119  *
120  * \return  ARM_DRIVER_OK if the de-initialization succeeds
121  */
tfm_ns_platform_uninit(void)122 __WEAK int32_t tfm_ns_platform_uninit(void)
123 {
124     stdio_uninit();
125 
126     return ARM_DRIVER_OK;
127 }
128 
129 
tfm_ns_cp_init(void)130 __WEAK int32_t tfm_ns_cp_init(void)
131 {
132 #if (CONFIG_TFM_FLOAT_ABI >= 1)
133 #ifdef __GNUC__
134     /* Enable NSPE privileged and unprivilged access to the FP Extension */
135     SCB->CPACR |= (3U << 10U*2U)     /* enable CP10 full access */
136                   | (3U << 11U*2U);  /* enable CP11 full access */
137 #endif
138 #endif
139     return ARM_DRIVER_OK;
140 }
141 
142 /**
143  * \brief main() function
144  */
145 #ifndef __GNUC__
146 __attribute__((noreturn))
147 #endif
main(void)148 int main(void)
149 {
150     if (tfm_ns_platform_init() != ARM_DRIVER_OK) {
151         /* Avoid undefined behavior if platform init failed */
152         while(1);
153     }
154 
155     if (tfm_ns_cp_init() != ARM_DRIVER_OK) {
156         /* Avoid undefined behavior if co-porcessor init failed */
157         while(1);
158     }
159 
160     (void) osKernelInitialize();
161 
162 #ifdef TFM_PARTITION_NS_AGENT_MAILBOX
163     tfm_ns_multi_core_boot();
164 #endif
165 
166 #ifdef CONFIG_TFM_USE_TRUSTZONE
167     /* Initialize the TFM NS interface */
168     tfm_ns_interface_init();
169 #endif
170 
171 #ifdef TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD
172     (void) osThreadNew(mailbox_thread_func, NULL, &mailbox_thread_attr);
173 #endif
174 
175     (void) osThreadNew(thread_func, NULL, &thread_attr);
176 
177     LOG_MSG("Non-Secure system starting...\r\n");
178     (void) osKernelStart();
179 
180     /* Reached only in case of error */
181     for (;;) {
182     }
183 }
184