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/boot.h>
9 #include <kernel/misc.h>
10 #include <kernel/panic.h>
11 #include <mm/core_mmu.h>
12 #include <mm/core_memprot.h>
13 #include <platform_config.h>
14 #include <stdint.h>
15 #include <sm/optee_smc.h>
16 #include <sm/psci.h>
17 #include <sm/std_smc.h>
18 #include <tee/entry_std.h>
19 #include <tee/entry_fast.h>
20
21 #define REG_CPU_SUSSYS_RESET 0xcc
22 #define REG_CPU_START_COMMAND 0x0
23 #define REG_CPU_START_ADDR 0x4
24 #define REG_SYSCTRL_RESET 0x4
25 #define RELEASE_CORE_MASK (BIT32(25) | BIT32(1))
26
psci_features(uint32_t psci_fid)27 int psci_features(uint32_t psci_fid)
28 {
29 switch (psci_fid) {
30 case ARM_SMCCC_VERSION:
31 case PSCI_PSCI_FEATURES:
32 case PSCI_VERSION:
33 case PSCI_SYSTEM_RESET:
34 #ifdef CFG_BOOT_SECONDARY_REQUEST
35 case PSCI_CPU_ON:
36 #endif
37 return PSCI_RET_SUCCESS;
38 default:
39 return PSCI_RET_NOT_SUPPORTED;
40 }
41 }
42
psci_version(void)43 uint32_t psci_version(void)
44 {
45 return PSCI_VERSION_1_0;
46 }
47
psci_system_reset(void)48 void psci_system_reset(void)
49 {
50 vaddr_t sysctrl = core_mmu_get_va(SYS_CTRL_BASE, MEM_AREA_IO_SEC,
51 SYS_CTRL_SIZE);
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
psci_cpu_on(uint32_t core_idx,uint32_t entry,uint32_t context_id)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 BOOTSRAM_SIZE);
69 vaddr_t crg = core_mmu_get_va(CPU_CRG_BASE, MEM_AREA_IO_SEC,
70 CPU_CRG_SIZE);
71
72 if (!bootsram || !crg) {
73 EMSG("No bootsram or crg mapping");
74 return PSCI_RET_INVALID_PARAMETERS;
75 }
76
77 if ((pos == 0) || (pos >= CFG_TEE_CORE_NB_CORE))
78 return PSCI_RET_INVALID_PARAMETERS;
79
80 /* set secondary core's NS entry addresses */
81 boot_set_core_ns_entry(pos, entry, context_id);
82
83 val = virt_to_phys((void *)TEE_TEXT_VA_START);
84 io_write32(bootsram + REG_CPU_START_ADDR, val);
85 io_write32(bootsram + REG_CPU_START_COMMAND, 0xe51ff004);
86
87 /* release secondary core */
88 io_clrbits32(crg + REG_CPU_SUSSYS_RESET, RELEASE_CORE_MASK);
89
90 return PSCI_RET_SUCCESS;
91 }
92 #endif
93