xref: /optee_os/core/arch/arm/plat-stm32mp1/pm/psci.c (revision 0323f7b87dd12c496d6fc23ea637442f8b5c20a7)
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