1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2017, Schneider Electric 4 * Copyright (c) 2020, Linaro Limited 5 */ 6 7 #include <arm.h> 8 #include <io.h> 9 #include <kernel/boot.h> 10 #include <kernel/misc.h> 11 #include <mm/core_memprot.h> 12 #include <platform_config.h> 13 #include <sm/psci.h> 14 #include <sm/std_smc.h> 15 16 #define SYSCTRL_REG_RSTEN (SYSCTRL_BASE + 0x120) 17 #define SYSCTRL_REG_RSTCTRL (SYSCTRL_BASE + 0x198) 18 #define SYSCTRL_BOOTADDR_REG (SYSCTRL_BASE + 0x204) 19 20 #define SYSCTRL_REG_RSTEN_MRESET_EN BIT(0) 21 #define SYSCTRL_REG_RSTEN_SWRST_EN BIT(6) 22 #define SYSCTRL_REG_RSTCTRL_SWRST_REQ BIT(6) 23 24 int psci_features(uint32_t psci_fid) 25 { 26 switch (psci_fid) { 27 case PSCI_PSCI_FEATURES: 28 case PSCI_VERSION: 29 case PSCI_CPU_ON: 30 case PSCI_CPU_OFF: 31 case PSCI_SYSTEM_RESET: 32 return PSCI_RET_SUCCESS; 33 default: 34 return PSCI_RET_NOT_SUPPORTED; 35 } 36 } 37 38 uint32_t psci_version(void) 39 { 40 return PSCI_VERSION_1_0; 41 } 42 43 int psci_cpu_on(uint32_t core_id, uint32_t entry, uint32_t context_id) 44 { 45 vaddr_t sctl_va = core_mmu_get_va(SYSCTRL_BOOTADDR_REG, 46 MEM_AREA_IO_SEC); 47 48 if (core_id == 0 || core_id >= CFG_TEE_CORE_NB_CORE) 49 return PSCI_RET_INVALID_PARAMETERS; 50 51 DMSG("core_id: %" PRIu32, core_id); 52 53 boot_set_core_ns_entry(core_id, entry, context_id); 54 io_write32(sctl_va, TEE_LOAD_ADDR); 55 56 dsb(); 57 sev(); 58 59 return PSCI_RET_SUCCESS; 60 } 61 62 int __noreturn psci_cpu_off(void) 63 { 64 DMSG("core_id: %" PRIu32, get_core_pos()); 65 66 psci_armv7_cpu_off(); 67 68 thread_mask_exceptions(THREAD_EXCP_ALL); 69 70 while (1) 71 wfi(); 72 } 73 74 void psci_system_reset(void) 75 { 76 /* Enable software reset */ 77 io_setbits32(core_mmu_get_va(SYSCTRL_REG_RSTEN, MEM_AREA_IO_SEC), 78 SYSCTRL_REG_RSTEN_SWRST_EN | SYSCTRL_REG_RSTEN_MRESET_EN); 79 80 /* Trigger software reset */ 81 io_setbits32(core_mmu_get_va(SYSCTRL_REG_RSTCTRL, MEM_AREA_IO_SEC), 82 SYSCTRL_REG_RSTCTRL_SWRST_REQ); 83 84 dsb(); 85 } 86