1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2023 Andes Technology Corporation 4 * Copyright 2022-2023 NXP 5 */ 6 7 #include <assert.h> 8 #include <compiler.h> 9 #include <config.h> 10 #include <console.h> 11 #include <keep.h> 12 #include <kernel/boot.h> 13 #include <kernel/dt.h> 14 #include <kernel/linker.h> 15 #include <kernel/misc.h> 16 #include <kernel/panic.h> 17 #include <kernel/thread.h> 18 #include <mm/core_memprot.h> 19 #include <mm/core_mmu.h> 20 #include <mm/tee_mm.h> 21 #include <mm/tee_pager.h> 22 #include <platform_config.h> 23 #include <riscv.h> 24 #include <sbi.h> 25 #include <stdio.h> 26 #include <trace.h> 27 #include <util.h> 28 29 #define PADDR_INVALID ULONG_MAX 30 31 paddr_t start_addr; 32 unsigned long boot_args[4]; 33 34 uint32_t sem_cpu_sync[CFG_TEE_CORE_NB_CORE]; 35 36 #if defined(CFG_DT) 37 static int mark_tddram_as_reserved(struct dt_descriptor *dt) 38 { 39 return add_res_mem_dt_node(dt, "optee_core", CFG_TDDRAM_START, 40 CFG_TDDRAM_SIZE); 41 } 42 43 static void update_external_dt(void) 44 { 45 struct dt_descriptor *dt = get_external_dt_desc(); 46 47 if (!dt || !dt->blob) 48 return; 49 50 #ifdef CFG_CORE_RESERVED_SHM 51 if (mark_static_shm_as_reserved(dt)) 52 panic("Failed to config non-secure memory"); 53 #endif 54 55 if (mark_tddram_as_reserved(dt)) 56 panic("Failed to config secure memory"); 57 } 58 #else /*CFG_DT*/ 59 static void update_external_dt(void) 60 { 61 } 62 #endif /*!CFG_DT*/ 63 64 void init_sec_mon(unsigned long nsec_entry __maybe_unused) 65 { 66 assert(nsec_entry == PADDR_INVALID); 67 /* Do nothing as we don't have a secure monitor */ 68 } 69 70 #ifdef CFG_RISCV_S_MODE 71 static void start_secondary_cores(void) 72 { 73 size_t i = 0; 74 size_t pos = get_core_pos(); 75 76 for (i = 0; i < CFG_TEE_CORE_NB_CORE; i++) 77 if (i != pos && IS_ENABLED(CFG_RISCV_SBI) && 78 sbi_hsm_hart_start(i, start_addr, i)) 79 EMSG("Error starting secondary hart %zu", i); 80 } 81 #endif 82 83 void init_tee_runtime(void) 84 { 85 call_preinitcalls(); 86 call_early_initcalls(); 87 call_service_initcalls(); 88 } 89 90 static bool add_padding_to_pool(vaddr_t va, size_t len, void *ptr __unused) 91 { 92 malloc_add_pool((void *)va, len); 93 return true; 94 } 95 96 static void init_primary(unsigned long nsec_entry) 97 { 98 vaddr_t va __maybe_unused = 0; 99 100 thread_init_core_local_stacks(); 101 102 /* 103 * Mask asynchronous exceptions before switch to the thread vector 104 * as the thread handler requires those to be masked while 105 * executing with the temporary stack. The thread subsystem also 106 * asserts that the foreign interrupts are blocked when using most of 107 * its functions. 108 */ 109 thread_set_exceptions(THREAD_EXCP_ALL); 110 111 malloc_add_pool(__heap1_start, __heap1_end - __heap1_start); 112 IMSG_RAW("\n"); 113 114 core_mmu_save_mem_map(); 115 core_mmu_init_phys_mem(); 116 boot_mem_foreach_padding(add_padding_to_pool, NULL); 117 va = boot_mem_release_unused(); 118 119 thread_init_boot_thread(); 120 thread_init_primary(); 121 thread_init_per_cpu(); 122 init_sec_mon(nsec_entry); 123 } 124 125 /* May be overridden in plat-$(PLATFORM)/main.c */ 126 __weak void plat_primary_init_early(void) 127 { 128 } 129 130 /* May be overridden in plat-$(PLATFORM)/main.c */ 131 __weak void boot_primary_init_intc(void) 132 { 133 } 134 135 /* May be overridden in plat-$(PLATFORM)/main.c */ 136 __weak void boot_secondary_init_intc(void) 137 { 138 } 139 140 void boot_init_primary_early(void) 141 { 142 unsigned long e = PADDR_INVALID; 143 144 init_primary(e); 145 } 146 147 void boot_init_primary_late(unsigned long fdt, 148 unsigned long tos_fw_config __unused) 149 { 150 init_external_dt(fdt, CFG_DTB_MAX_SIZE); 151 discover_nsec_memory(); 152 update_external_dt(); 153 154 IMSG("OP-TEE version: %s", core_v_str); 155 if (IS_ENABLED(CFG_INSECURE)) { 156 IMSG("WARNING: This OP-TEE configuration might be insecure!"); 157 IMSG("WARNING: Please check https://optee.readthedocs.io/en/latest/architecture/porting_guidelines.html"); 158 } 159 IMSG("Primary CPU initializing"); 160 boot_primary_init_intc(); 161 init_tee_runtime(); 162 } 163 164 void __weak boot_init_primary_final(void) 165 { 166 boot_mem_release_tmp_alloc(); 167 168 call_driver_initcalls(); 169 call_finalcalls(); 170 IMSG("Primary CPU initialized"); 171 172 #ifdef CFG_RISCV_S_MODE 173 start_secondary_cores(); 174 #endif 175 } 176 177 static void init_secondary_helper(unsigned long nsec_entry) 178 { 179 size_t pos = get_core_pos(); 180 181 IMSG("Secondary CPU %zu initializing", pos); 182 183 /* 184 * Mask asynchronous exceptions before switch to the thread vector 185 * as the thread handler requires those to be masked while 186 * executing with the temporary stack. The thread subsystem also 187 * asserts that the foreign interrupts are blocked when using most of 188 * its functions. 189 */ 190 thread_set_exceptions(THREAD_EXCP_ALL); 191 192 thread_init_per_cpu(); 193 init_sec_mon(nsec_entry); 194 boot_secondary_init_intc(); 195 196 IMSG("Secondary CPU %zu initialized", pos); 197 } 198 199 void boot_init_secondary(unsigned long nsec_entry __unused) 200 { 201 init_secondary_helper(PADDR_INVALID); 202 } 203