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 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 43 uint32_t psci_version(void) 44 { 45 return PSCI_VERSION_1_0; 46 } 47 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 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_LOAD_ADDR); 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