1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2017-2018, STMicroelectronics 4 */ 5 6 #include <arm.h> 7 #include <boot_api.h> 8 #include <kernel/generic_boot.h> 9 #include <kernel/interrupt.h> 10 #include <kernel/misc.h> 11 #include <mm/core_memprot.h> 12 #include <platform_config.h> 13 #include <sm/psci.h> 14 #include <trace.h> 15 16 /* 17 * SMP boot support and access to the mailbox 18 */ 19 #define GIC_SEC_SGI_0 8 20 21 static vaddr_t bckreg_base(void) 22 { 23 static void *va; 24 25 if (!cpu_mmu_enabled()) 26 return BKP_REGS_BASE + BKP_REGISTER_OFF; 27 28 if (!va) 29 va = phys_to_virt(BKP_REGS_BASE + BKP_REGISTER_OFF, 30 MEM_AREA_IO_SEC); 31 32 return (vaddr_t)va; 33 } 34 35 static uint32_t *bckreg_address(unsigned int idx) 36 { 37 return (uint32_t *)bckreg_base() + idx; 38 } 39 40 static void release_secondary_early_hpen(size_t __unused pos) 41 { 42 uint32_t *p_entry = bckreg_address(BCKR_CORE1_BRANCH_ADDRESS); 43 uint32_t *p_magic = bckreg_address(BCKR_CORE1_MAGIC_NUMBER); 44 45 *p_entry = TEE_LOAD_ADDR; 46 *p_magic = BOOT_API_A7_CORE1_MAGIC_NUMBER; 47 48 dmb(); 49 isb(); 50 itr_raise_sgi(GIC_SEC_SGI_0, BIT(pos)); 51 } 52 53 /* Override default psci_cpu_on() with platform specific sequence */ 54 int psci_cpu_on(uint32_t core_id, uint32_t entry, uint32_t context_id) 55 { 56 size_t pos = get_core_pos_mpidr(core_id); 57 static bool core_is_released[CFG_TEE_CORE_NB_CORE]; 58 59 if (!pos || pos >= CFG_TEE_CORE_NB_CORE) 60 return PSCI_RET_INVALID_PARAMETERS; 61 62 DMSG("core pos: %zu: ns_entry %#" PRIx32, pos, entry); 63 64 if (core_is_released[pos]) { 65 DMSG("core %zu already released", pos); 66 return PSCI_RET_DENIED; 67 } 68 core_is_released[pos] = true; 69 70 generic_boot_set_core_ns_entry(pos, entry, context_id); 71 release_secondary_early_hpen(pos); 72 } 73 74 /* Override default psci_cpu_on() with platform supported features */ 75 int psci_features(uint32_t psci_fid) 76 { 77 switch (psci_fid) { 78 case PSCI_PSCI_FEATURES: 79 case PSCI_VERSION: 80 #if CFG_TEE_CORE_NB_CORE > 1 81 case PSCI_CPU_ON: 82 #endif 83 return PSCI_RET_SUCCESS; 84 default: 85 return PSCI_RET_NOT_SUPPORTED; 86 } 87 } 88 89 /* Override default psci_version() to enable PSCI_VERSION_1_0 API */ 90 uint32_t psci_version(void) 91 { 92 return PSCI_VERSION_1_0; 93 } 94