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 sizeof(uint32_t)); 48 49 if (core_id == 0 || core_id >= CFG_TEE_CORE_NB_CORE) 50 return PSCI_RET_INVALID_PARAMETERS; 51 52 DMSG("core_id: %" PRIu32, core_id); 53 54 boot_set_core_ns_entry(core_id, entry, context_id); 55 io_write32(sctl_va, TEE_LOAD_ADDR); 56 57 dsb(); 58 sev(); 59 60 return PSCI_RET_SUCCESS; 61 } 62 63 int __noreturn psci_cpu_off(void) 64 { 65 DMSG("core_id: %" PRIu32, get_core_pos()); 66 67 psci_armv7_cpu_off(); 68 69 thread_mask_exceptions(THREAD_EXCP_ALL); 70 71 while (1) 72 wfi(); 73 } 74 75 void psci_system_reset(void) 76 { 77 /* Enable software reset */ 78 io_setbits32(core_mmu_get_va(SYSCTRL_REG_RSTEN, MEM_AREA_IO_SEC, 79 sizeof(uint32_t)), 80 SYSCTRL_REG_RSTEN_SWRST_EN | SYSCTRL_REG_RSTEN_MRESET_EN); 81 82 /* Trigger software reset */ 83 io_setbits32(core_mmu_get_va(SYSCTRL_REG_RSTCTRL, MEM_AREA_IO_SEC, 84 sizeof(uint32_t)), 85 SYSCTRL_REG_RSTCTRL_SWRST_REQ); 86 87 dsb(); 88 } 89