xref: /optee_os/core/arch/arm/plat-hisilicon/psci.c (revision 193e08934333b2ffb3b8c7ebaf05c4f8995c569f)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2019, HiSilicon Technologies Co., Ltd.
4  */
5 
6 #include <console.h>
7 #include <io.h>
8 #include <kernel/generic_boot.h>
9 #include <kernel/misc.h>
10 #include <kernel/panic.h>
11 #include <kernel/pm_stubs.h>
12 #include <mm/core_mmu.h>
13 #include <mm/core_memprot.h>
14 #include <platform_config.h>
15 #include <stdint.h>
16 #include <sm/optee_smc.h>
17 #include <sm/psci.h>
18 #include <sm/std_smc.h>
19 #include <tee/entry_std.h>
20 #include <tee/entry_fast.h>
21 
22 #define REG_CPU_SUSSYS_RESET	0xcc
23 #define REG_CPU_START_COMMAND	0x0
24 #define REG_CPU_START_ADDR	0x4
25 #define REG_SYSCTRL_RESET	0x4
26 #define RELEASE_CORE_MASK	(BIT32(25) | BIT32(1))
27 
28 int psci_features(uint32_t psci_fid)
29 {
30 	switch (psci_fid) {
31 	case ARM_SMCCC_VERSION:
32 	case PSCI_PSCI_FEATURES:
33 	case PSCI_VERSION:
34 	case PSCI_SYSTEM_RESET:
35 #ifdef CFG_BOOT_SECONDARY_REQUEST
36 	case PSCI_CPU_ON:
37 #endif
38 		return PSCI_RET_SUCCESS;
39 	default:
40 		return PSCI_RET_NOT_SUPPORTED;
41 	}
42 }
43 
44 uint32_t psci_version(void)
45 {
46 	return PSCI_VERSION_1_0;
47 }
48 
49 void psci_system_reset(void)
50 {
51 	vaddr_t sysctrl = core_mmu_get_va(SYS_CTRL_BASE, MEM_AREA_IO_SEC);
52 
53 	if (!sysctrl) {
54 		EMSG("no sysctrl mapping, hang here");
55 		panic();
56 	}
57 
58 	io_write32(sysctrl + REG_SYSCTRL_RESET, 0xdeadbeef);
59 }
60 
61 #ifdef CFG_BOOT_SECONDARY_REQUEST
62 int psci_cpu_on(uint32_t core_idx, uint32_t entry,
63 		uint32_t context_id)
64 {
65 	uint32_t val = 0;
66 	size_t pos = get_core_pos_mpidr(core_idx);
67 	vaddr_t bootsram = core_mmu_get_va(BOOTSRAM_BASE, MEM_AREA_IO_SEC);
68 	vaddr_t crg = core_mmu_get_va(CPU_CRG_BASE, MEM_AREA_IO_SEC);
69 
70 	if (!bootsram || !crg) {
71 		EMSG("No bootsram or crg mapping");
72 		return PSCI_RET_INVALID_PARAMETERS;
73 	}
74 
75 	if ((pos == 0) || (pos >= CFG_TEE_CORE_NB_CORE))
76 		return PSCI_RET_INVALID_PARAMETERS;
77 
78 	/* set secondary core's NS entry addresses */
79 	generic_boot_set_core_ns_entry(pos, entry, context_id);
80 
81 	val = virt_to_phys((void *)TEE_TEXT_VA_START);
82 	io_write32(bootsram + REG_CPU_START_ADDR, val);
83 	io_write32(bootsram + REG_CPU_START_COMMAND, 0xe51ff004);
84 
85 	/* release secondary core */
86 	io_clrbits32(crg + REG_CPU_SUSSYS_RESET, RELEASE_CORE_MASK);
87 
88 	return PSCI_RET_SUCCESS;
89 }
90 #endif
91