1 /* 2 * Copyright (c) 2014, STMicroelectronics International N.V. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 #include <stdint.h> 28 #include <string.h> 29 #include <sm/sm.h> 30 #include <sm/tee_mon.h> 31 #include <sm/teesmc.h> 32 #include <sm/teesmc_optee.h> 33 #include <arm.h> 34 #include <kernel/thread.h> 35 #include <kernel/panic.h> 36 #include <kernel/pm_stubs.h> 37 #include <malloc.h> 38 #include <util.h> 39 #include <trace.h> 40 #include <kernel/misc.h> 41 #include <mm/tee_pager.h> 42 #include <mm/core_mmu.h> 43 #include <mm/tee_mmu.h> 44 #include <mm/tee_mmu_defs.h> 45 #include <tee/entry.h> 46 #include <tee/arch_svc.h> 47 #include <console.h> 48 #include <asc.h> 49 #include <assert.h> 50 #include <platform_config.h> 51 52 extern uint8_t __text_init_start[]; 53 extern uint8_t __data_start[]; 54 extern uint8_t __data_end[]; 55 extern uint8_t __bss_start[]; 56 extern uint8_t __bss_end[]; 57 extern uint8_t __init_start[]; 58 extern uint8_t __init_size[]; 59 extern uint8_t __heap1_start[]; 60 extern uint8_t __heap1_end[]; 61 extern uint8_t __heap2_start[]; 62 extern uint8_t __heap2_end[]; 63 extern uint8_t __pageable_part_start[]; 64 extern uint8_t __pageable_part_end[]; 65 extern uint8_t __pageable_start[]; 66 extern uint8_t __pageable_end[]; 67 68 static void main_fiq(void); 69 static void main_tee_entry(struct thread_smc_args *args); 70 71 static const struct thread_handlers handlers = { 72 .std_smc = main_tee_entry, 73 .fast_smc = main_tee_entry, 74 .fiq = main_fiq, 75 .svc = tee_svc_handler, 76 .abort = tee_pager_abort_handler, 77 .cpu_on = pm_panic, 78 .cpu_off = pm_panic, 79 .cpu_suspend = pm_panic, 80 .cpu_resume = pm_panic, 81 .system_off = pm_panic, 82 .system_reset = pm_panic, 83 }; 84 85 #define PADDR_INVALID 0xffffffff 86 87 /* May be overridden in plat-$(PLATFORM)/main.c */ 88 void main_init_gic(void); 89 __weak void main_init_gic(void) 90 { 91 } 92 93 #if defined(CFG_WITH_ARM_TRUSTED_FW) 94 static void init_sec_mon(uint32_t nsec_entry __unused) 95 { 96 assert(nsec_entry == PADDR_INVALID); 97 /* Do nothing as we don't have a secure monitor */ 98 } 99 #else 100 static void init_sec_mon(uint32_t nsec_entry) 101 { 102 struct sm_nsec_ctx *nsec_ctx; 103 104 assert(nsec_entry != PADDR_INVALID); 105 106 /* Initialize secure monitor */ 107 nsec_ctx = sm_get_nsec_ctx(); 108 nsec_ctx->mon_lr = nsec_entry; 109 nsec_ctx->mon_spsr = CPSR_MODE_SVC | CPSR_I; 110 111 } 112 #endif 113 114 #if defined(CFG_WITH_ARM_TRUSTED_FW) 115 static void init_nsacr(void) 116 { 117 } 118 #else 119 static void init_nsacr(void) 120 { 121 /* Normal world can use CP10 and CP11 (SIMD/VFP) */ 122 write_nsacr(read_nsacr() | NSACR_CP10 | NSACR_CP11); 123 } 124 #endif 125 126 #ifdef CFG_WITH_VFP 127 static void init_cpacr(void) 128 { 129 uint32_t cpacr = read_cpacr(); 130 131 /* Enabled usage of CP10 and CP11 (SIMD/VFP) */ 132 cpacr &= ~CPACR_CP(10, CPACR_CP_ACCESS_FULL); 133 cpacr |= CPACR_CP(10, CPACR_CP_ACCESS_PL1_ONLY); 134 cpacr &= ~CPACR_CP(11, CPACR_CP_ACCESS_FULL); 135 cpacr |= CPACR_CP(11, CPACR_CP_ACCESS_PL1_ONLY); 136 write_cpacr(cpacr); 137 } 138 #else 139 static void init_cpacr(void) 140 { 141 /* We're not using VFP/SIMD instructions, leave it disabled */ 142 } 143 #endif 144 145 #ifdef CFG_WITH_PAGER 146 147 static size_t get_block_size(void) 148 { 149 struct core_mmu_table_info tbl_info; 150 unsigned l; 151 152 if (!core_mmu_find_table(CFG_TEE_RAM_START, UINT_MAX, &tbl_info)) 153 panic(); 154 l = tbl_info.level - 1; 155 if (!core_mmu_find_table(CFG_TEE_RAM_START, l, &tbl_info)) 156 panic(); 157 return 1 << tbl_info.shift; 158 } 159 160 static void init_runtime(uint32_t pageable_part) 161 { 162 size_t n; 163 size_t init_size = (size_t)__init_size; 164 size_t pageable_size = __pageable_end - __pageable_start; 165 size_t hash_size = (pageable_size / SMALL_PAGE_SIZE) * 166 TEE_SHA256_HASH_SIZE; 167 tee_mm_entry_t *mm; 168 uint8_t *paged_store; 169 uint8_t *hashes; 170 uint8_t *tmp_hashes = __init_start + init_size; 171 size_t block_size; 172 173 174 TEE_ASSERT(pageable_size % SMALL_PAGE_SIZE == 0); 175 176 177 /* Copy it right after the init area. */ 178 memcpy(tmp_hashes, __data_end + init_size, hash_size); 179 180 /* 181 * Zero BSS area. Note that globals that would normally would go 182 * into BSS which are used before this has to be put into .nozi.* 183 * to avoid getting overwritten. 184 */ 185 memset(__bss_start, 0, __bss_end - __bss_start); 186 187 malloc_init(__heap1_start, __heap1_end - __heap1_start); 188 malloc_add_pool(__heap2_start, __heap2_end - __heap2_start); 189 190 hashes = malloc(hash_size); 191 EMSG("hash_size %zu", hash_size); 192 TEE_ASSERT(hashes); 193 memcpy(hashes, tmp_hashes, hash_size); 194 195 /* 196 * Need tee_mm_sec_ddr initialized to be able to allocate secure 197 * DDR below. 198 */ 199 teecore_init_ta_ram(); 200 201 mm = tee_mm_alloc(&tee_mm_sec_ddr, pageable_size); 202 TEE_ASSERT(mm); 203 paged_store = (uint8_t *)tee_mm_get_smem(mm); 204 /* Copy init part into pageable area */ 205 memcpy(paged_store, __init_start, init_size); 206 /* Copy pageable part after init part into pageable area */ 207 memcpy(paged_store + init_size, (void *)pageable_part, 208 __pageable_part_end - __pageable_part_start); 209 210 /* Check that hashes of what's in pageable area is OK */ 211 DMSG("Checking hashes of pageable area"); 212 for (n = 0; (n * SMALL_PAGE_SIZE) < pageable_size; n++) { 213 const uint8_t *hash = hashes + n * TEE_SHA256_HASH_SIZE; 214 const uint8_t *page = paged_store + n * SMALL_PAGE_SIZE; 215 TEE_Result res; 216 217 DMSG("hash pg_idx %zu hash %p page %p", n, hash, page); 218 res = hash_sha256_check(hash, page, SMALL_PAGE_SIZE); 219 if (res != TEE_SUCCESS) { 220 EMSG("Hash failed for page %zu at %p: res 0x%x", 221 n, page, res); 222 panic(); 223 } 224 } 225 226 /* 227 * Copy what's not initialized in the last init page. Needed 228 * because we're not going fault in the init pages again. We can't 229 * fault in pages until we've switched to the new vector by calling 230 * thread_init_handlers() below. 231 */ 232 if (init_size % SMALL_PAGE_SIZE) { 233 uint8_t *p; 234 235 memcpy(__init_start + init_size, paged_store + init_size, 236 SMALL_PAGE_SIZE - (init_size % SMALL_PAGE_SIZE)); 237 238 p = (uint8_t *)(((vaddr_t)__init_start + init_size) & 239 ~SMALL_PAGE_MASK); 240 241 cache_maintenance_l1(DCACHE_AREA_CLEAN, p, SMALL_PAGE_SIZE); 242 cache_maintenance_l1(ICACHE_AREA_INVALIDATE, p, 243 SMALL_PAGE_SIZE); 244 } 245 246 /* 247 * Initialize the virtual memory pool used for main_mmu_l2_ttb which 248 * is supplied to tee_pager_init() below. 249 */ 250 block_size = get_block_size(); 251 if (!tee_mm_init(&tee_mm_vcore, 252 ROUNDDOWN(CFG_TEE_RAM_START, block_size), 253 ROUNDUP(CFG_TEE_RAM_START + CFG_TEE_RAM_VA_SIZE, 254 block_size), 255 SMALL_PAGE_SHIFT, 0)) 256 panic(); 257 258 /* 259 * Claim virtual memory which isn't paged, note that there migth be 260 * a gap between tee_mm_vcore.lo and TEE_RAM_START which is also 261 * claimed to avoid later allocations to get that memory. 262 */ 263 mm = tee_mm_alloc2(&tee_mm_vcore, tee_mm_vcore.lo, 264 (vaddr_t)(__text_init_start - tee_mm_vcore.lo)); 265 TEE_ASSERT(mm); 266 267 /* 268 * Allocate virtual memory for the pageable area and let the pager 269 * take charge of all the pages already assigned to that memory. 270 */ 271 mm = tee_mm_alloc2(&tee_mm_vcore, (vaddr_t)__pageable_start, 272 pageable_size); 273 TEE_ASSERT(mm); 274 tee_pager_add_area(mm, TEE_PAGER_AREA_RO | TEE_PAGER_AREA_X, 275 paged_store, hashes); 276 tee_pager_add_pages((vaddr_t)__pageable_start, 277 ROUNDUP(init_size, SMALL_PAGE_SIZE) / SMALL_PAGE_SIZE, false); 278 tee_pager_add_pages((vaddr_t)__pageable_start + 279 ROUNDUP(init_size, SMALL_PAGE_SIZE), 280 (pageable_size - ROUNDUP(init_size, SMALL_PAGE_SIZE)) / 281 SMALL_PAGE_SIZE, true); 282 283 } 284 #else 285 static void init_runtime(uint32_t pageable_part __unused) 286 { 287 /* 288 * Zero BSS area. Note that globals that would normally would go 289 * into BSS which are used before this has to be put into .nozi.* 290 * to avoid getting overwritten. 291 */ 292 memset(__bss_start, 0, __bss_end - __bss_start); 293 294 malloc_init(__heap1_start, __heap1_end - __heap1_start); 295 296 /* 297 * Initialized at this stage in the pager version of this function 298 * above 299 */ 300 teecore_init_ta_ram(); 301 } 302 #endif 303 304 static void init_primary_helper(uint32_t nsec_entry) 305 { 306 /* 307 * Mask asynchronous exceptions before switch to the thread vector 308 * as the thread handler requires those to be masked while 309 * executing with the temporary stack. The thread subsystem also 310 * asserts that IRQ is blocked when using most if its functions. 311 */ 312 thread_set_exceptions(THREAD_EXCP_ALL); 313 init_cpacr(); 314 315 init_runtime(0); 316 317 DMSG("TEE initializing\n"); 318 319 thread_init_primary(&handlers); 320 thread_init_per_cpu(); 321 init_sec_mon(nsec_entry); 322 323 324 main_init_gic(); 325 init_nsacr(); 326 } 327 328 static void init_secondary_helper(uint32_t nsec_entry) 329 { 330 /* 331 * Mask asynchronous exceptions before switch to the thread vector 332 * as the thread handler requires those to be masked while 333 * executing with the temporary stack. The thread subsystem also 334 * asserts that IRQ is blocked when using most if its functions. 335 */ 336 thread_set_exceptions(THREAD_EXCP_ALL); 337 338 thread_init_per_cpu(); 339 init_sec_mon(nsec_entry); 340 init_cpacr(); 341 init_nsacr(); 342 343 DMSG("Secondary CPU Switching to normal world boot\n"); 344 } 345 346 #if defined(CFG_WITH_ARM_TRUSTED_FW) 347 uint32_t *generic_boot_init_primary(uint32_t pageable_part) 348 { 349 init_primary_helper(pageable_part, PADDR_INVALID); 350 return thread_vector_table; 351 } 352 353 uint32_t generic_boot_cpu_on_handler(uint32_t a0 __unused, uint32_t a1 __unused) 354 { 355 DMSG("cpu %zu: a0 0x%x", get_core_pos(), a0); 356 init_secondary_helper(PADDR_INVALID); 357 return 0; 358 } 359 #else 360 void generic_boot_init_primary(uint32_t nsec_entry); 361 void generic_boot_init_primary(uint32_t nsec_entry) 362 { 363 init_primary_helper(nsec_entry); 364 } 365 366 void generic_boot_init_secondary(uint32_t nsec_entry); 367 void generic_boot_init_secondary(uint32_t nsec_entry) 368 { 369 init_secondary_helper(nsec_entry); 370 } 371 #endif 372 373 static void main_fiq(void) 374 { 375 panic(); 376 } 377 378 static void main_tee_entry(struct thread_smc_args *args) 379 { 380 /* TODO move to main_init() */ 381 if (init_teecore() != TEE_SUCCESS) 382 panic(); 383 384 tee_entry(args); 385 } 386 387 void console_putc(int ch) 388 { 389 __asc_xmit_char((char)ch); 390 } 391 392 void console_flush(void) 393 { 394 __asc_flush(); 395 } 396