1 /*
2 * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include "build_config_check.h"
9 #include "internal_status_code.h"
10 #include "fih.h"
11 #include "tfm_boot_data.h"
12 #include "memory_symbols.h"
13 #include "spm.h"
14 #include "tfm_hal_isolation.h"
15 #include "tfm_hal_platform.h"
16 #include "tfm_log.h"
17 #include "tfm_version.h"
18 #include "tfm_plat_otp.h"
19 #include "tfm_plat_provisioning.h"
20 #include "ffm/backend.h"
21
22 #ifdef CONFIG_TFM_ENABLE_PROFILING
23 #include "prof_intf_s.h"
24 #endif
25
26 static uintptr_t g_spm_boundary;
27
tfm_core_init(void)28 static fih_int tfm_core_init(void)
29 {
30 enum tfm_plat_err_t plat_err = TFM_PLAT_ERR_SYSTEM_ERR;
31 fih_int fih_rc = FIH_FAILURE;
32 bool provisioning_required;
33
34 /*
35 * Access to any peripheral should be performed after programming
36 * the necessary security components such as PPC/SAU.
37 */
38 FIH_CALL(tfm_hal_set_up_static_boundaries, fih_rc, &g_spm_boundary);
39 if (fih_not_eq(fih_rc, fih_int_encode(TFM_HAL_SUCCESS))) {
40 FIH_RET(fih_int_encode(SPM_ERROR_GENERIC));
41 }
42 #ifdef TFM_FIH_PROFILE_ON
43 FIH_CALL(tfm_hal_verify_static_boundaries, fih_rc);
44 if (fih_not_eq(fih_rc, fih_int_encode(TFM_HAL_SUCCESS))) {
45 tfm_core_panic();
46 }
47 #endif
48
49 FIH_CALL(tfm_hal_platform_init, fih_rc);
50 if (fih_not_eq(fih_rc, fih_int_encode(TFM_HAL_SUCCESS))) {
51 FIH_RET(fih_int_encode(SPM_ERROR_GENERIC));
52 }
53
54 /*
55 * Print the TF-M version and timestamp now that the platform
56 * has initialized the logging backend.
57 */
58 NOTICE("Booting TF-M \033[1;34m"VERSION_FULLSTR"\033[0m\n");
59 NOTICE("Built \033[1;34m"BUILD_TIMESTAMP" UTC\033[0m\n");
60
61 plat_err = tfm_plat_otp_init();
62 if (plat_err != TFM_PLAT_ERR_SUCCESS) {
63 FIH_RET(fih_int_encode(SPM_ERROR_GENERIC));
64 }
65
66 /* Perform provisioning. */
67 plat_err = tfm_plat_provisioning_is_required(&provisioning_required);
68 if (plat_err != TFM_PLAT_ERR_SUCCESS) {
69 FIH_RET(fih_int_encode(SPM_ERROR_GENERIC));
70 }
71
72 if (provisioning_required) {
73 plat_err = tfm_plat_provisioning_perform();
74 if (plat_err != TFM_PLAT_ERR_SUCCESS) {
75 FIH_RET(fih_int_encode(SPM_ERROR_GENERIC));
76 }
77 }
78
79 tfm_plat_provisioning_check_for_dummy_keys();
80
81 /* Configures architecture */
82 tfm_arch_config_extensions();
83
84 VERBOSE("Isolation level is: %u\n", TFM_ISOLATION_LEVEL);
85
86 #if (CONFIG_TFM_FLOAT_ABI == 2)
87 INFO("Float ABI: Hard, Lazy stacking ");
88 #ifdef CONFIG_TFM_LAZY_STACKING
89 INFO_RAW("enabled\n");
90 #else
91 INFO_RAW("disabled\n");
92 #endif
93 #endif
94
95 tfm_core_validate_boot_data();
96
97 FIH_RET(fih_int_encode(SPM_SUCCESS));
98 }
99
get_spm_boundary(void)100 uintptr_t get_spm_boundary(void)
101 {
102 return g_spm_boundary;
103 }
104
main(void)105 int main(void)
106 {
107 #ifdef CONFIG_TFM_ENABLE_PROFILING
108 PROFILING_INIT();
109 #endif
110
111 fih_int fih_rc = FIH_FAILURE;
112
113 tfm_arch_config_branch_protection();
114
115 /* set Main Stack Pointer limit */
116 tfm_arch_set_msplim(SPM_BOOT_STACK_TOP);
117
118 fih_delay_init();
119
120 FIH_CALL(tfm_core_init, fih_rc);
121 if (fih_not_eq(fih_rc, fih_int_encode(SPM_SUCCESS))) {
122 tfm_core_panic();
123 }
124
125 /* All isolation should have been set up at this point */
126 FIH_LABEL_CRITICAL_POINT();
127
128 /*
129 * Prioritise secure exceptions to avoid NS being able to preempt
130 * secure SVC or SecureFault. Do it before PSA API initialization.
131 */
132 tfm_arch_set_secure_exception_priorities();
133
134 #ifdef TFM_FIH_PROFILE_ON
135 /* Check secure exception priority */
136 FIH_CALL(tfm_arch_verify_secure_exception_priorities, fih_rc);
137 if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
138 tfm_core_panic();
139 }
140 #endif
141
142 /* Further SPM initialization. */
143 BACKEND_SPM_INIT();
144
145 return 0;
146 }
147