// SPDX-License-Identifier: BSD-2-Clause /* * Copyright (c) 2023 Andes Technology Corporation * Copyright 2022-2023 NXP */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define PADDR_INVALID ULONG_MAX paddr_t start_addr; unsigned long boot_args[4]; uint32_t sem_cpu_sync[CFG_TEE_CORE_NB_CORE]; #if defined(CFG_DT) static int mark_tddram_as_reserved(struct dt_descriptor *dt) { return add_res_mem_dt_node(dt, "optee_core", CFG_TDDRAM_START, CFG_TDDRAM_SIZE); } static void update_external_dt(void) { struct dt_descriptor *dt = get_external_dt_desc(); if (!dt || !dt->blob) return; if (mark_tddram_as_reserved(dt)) panic("Failed to config secure memory"); } #else /*CFG_DT*/ static void update_external_dt(void) { } #endif /*!CFG_DT*/ void init_sec_mon(unsigned long nsec_entry __maybe_unused) { assert(nsec_entry == PADDR_INVALID); /* Do nothing as we don't have a secure monitor */ } #ifdef CFG_RISCV_S_MODE static void start_secondary_cores(void) { size_t i = 0; size_t pos = get_core_pos(); for (i = 0; i < CFG_TEE_CORE_NB_CORE; i++) if (i != pos && IS_ENABLED(CFG_RISCV_SBI) && sbi_boot_hart(i, start_addr, i)) EMSG("Error starting secondary hart %zu", i); } #endif static void init_runtime(void) { malloc_add_pool(__heap1_start, __heap1_end - __heap1_start); IMSG_RAW("\n"); } void init_tee_runtime(void) { core_mmu_init_ta_ram(); call_preinitcalls(); call_initcalls(); } static void init_primary(unsigned long nsec_entry) { thread_init_core_local_stacks(); /* * Mask asynchronous exceptions before switch to the thread vector * as the thread handler requires those to be masked while * executing with the temporary stack. The thread subsystem also * asserts that the foreign interrupts are blocked when using most of * its functions. */ thread_set_exceptions(THREAD_EXCP_ALL); init_runtime(); thread_init_boot_thread(); thread_init_primary(); thread_init_per_cpu(); init_sec_mon(nsec_entry); } /* May be overridden in plat-$(PLATFORM)/main.c */ __weak void plat_primary_init_early(void) { } /* May be overridden in plat-$(PLATFORM)/main.c */ __weak void boot_primary_init_intc(void) { } /* May be overridden in plat-$(PLATFORM)/main.c */ __weak void boot_secondary_init_intc(void) { } void boot_init_primary_early(void) { unsigned long e = PADDR_INVALID; init_primary(e); } void boot_init_primary_late(unsigned long fdt, unsigned long tos_fw_config __unused) { init_external_dt(fdt, CFG_DTB_MAX_SIZE); update_external_dt(); IMSG("OP-TEE version: %s", core_v_str); if (IS_ENABLED(CFG_INSECURE)) { IMSG("WARNING: This OP-TEE configuration might be insecure!"); IMSG("WARNING: Please check https://optee.readthedocs.io/en/latest/architecture/porting_guidelines.html"); } IMSG("Primary CPU initializing"); boot_primary_init_intc(); init_tee_runtime(); call_finalcalls(); IMSG("Primary CPU initialized"); #ifdef CFG_RISCV_S_MODE start_secondary_cores(); #endif } static void init_secondary_helper(unsigned long nsec_entry) { size_t pos = get_core_pos(); IMSG("Secondary CPU %zu initializing", pos); /* * Mask asynchronous exceptions before switch to the thread vector * as the thread handler requires those to be masked while * executing with the temporary stack. The thread subsystem also * asserts that the foreign interrupts are blocked when using most of * its functions. */ thread_set_exceptions(THREAD_EXCP_ALL); thread_init_per_cpu(); init_sec_mon(nsec_entry); boot_secondary_init_intc(); IMSG("Secondary CPU %zu initialized", pos); } void boot_init_secondary(unsigned long nsec_entry __unused) { init_secondary_helper(PADDR_INVALID); }