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
psci_features(uint32_t psci_fid)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
psci_version(void)38 uint32_t psci_version(void)
39 {
40 return PSCI_VERSION_1_0;
41 }
42
psci_cpu_on(uint32_t core_id,uint32_t entry,uint32_t context_id)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
psci_cpu_off(void)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
psci_system_reset(void)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