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