1 /* 2 * Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 9 #include <common/runtime_svc.h> 10 #include <smccc_helpers.h> 11 12 #include <sbsa_platform.h> 13 14 #define SMC_FASTCALL 0x80000000 15 #define SMC64_FUNCTION (SMC_FASTCALL | 0x40000000) 16 #define SIP_FUNCTION (SMC64_FUNCTION | 0x02000000) 17 #define SIP_FUNCTION_ID(n) (SIP_FUNCTION | (n)) 18 19 /* 20 * We do not use SMCCC_ARCH_SOC_ID here because qemu_sbsa is virtual platform 21 * which uses SoC present in QEMU. And they can change on their own while we 22 * need version of whole 'virtual hardware platform'. 23 */ 24 #define SIP_SVC_VERSION SIP_FUNCTION_ID(1) 25 #define SIP_SVC_GET_GIC SIP_FUNCTION_ID(100) 26 #define SIP_SVC_GET_GIC_ITS SIP_FUNCTION_ID(101) 27 #define SIP_SVC_GET_CPU_COUNT SIP_FUNCTION_ID(200) 28 #define SIP_SVC_GET_CPU_NODE SIP_FUNCTION_ID(201) 29 #define SIP_SVC_GET_CPU_TOPOLOGY SIP_FUNCTION_ID(202) 30 #define SIP_SVC_GET_MEMORY_NODE_COUNT SIP_FUNCTION_ID(300) 31 #define SIP_SVC_GET_MEMORY_NODE SIP_FUNCTION_ID(301) 32 33 uintptr_t sbsa_get_gicd(void); 34 uintptr_t sbsa_get_gicr(void); 35 36 /* 37 * This function is responsible for handling all SiP calls from the NS world 38 */ 39 uintptr_t sbsa_sip_smc_handler(uint32_t smc_fid, 40 u_register_t x1, 41 u_register_t x2, 42 u_register_t x3, 43 u_register_t x4, 44 void *cookie, 45 void *handle, 46 u_register_t flags) 47 { 48 uint32_t ns; 49 uint64_t index; 50 51 /* Determine which security state this SMC originated from */ 52 ns = is_caller_non_secure(flags); 53 if (!ns) { 54 ERROR("%s: wrong world SMC (0x%x)\n", __func__, smc_fid); 55 SMC_RET1(handle, SMC_UNK); 56 } 57 58 switch (smc_fid) { 59 case SIP_SVC_VERSION: 60 INFO("Platform version requested\n"); 61 SMC_RET3(handle, NULL, sbsa_platform_version_major(), 62 sbsa_platform_version_minor()); 63 64 case SIP_SVC_GET_GIC: 65 SMC_RET3(handle, NULL, sbsa_get_gicd(), sbsa_get_gicr()); 66 67 case SIP_SVC_GET_GIC_ITS: 68 SMC_RET2(handle, NULL, sbsa_platform_gic_its_addr()); 69 70 case SIP_SVC_GET_CPU_COUNT: 71 SMC_RET2(handle, NULL, sbsa_platform_num_cpus()); 72 73 case SIP_SVC_GET_CPU_NODE: 74 index = x1; 75 if (index < PLATFORM_CORE_COUNT) { 76 struct platform_cpu_data data; 77 78 data = sbsa_platform_cpu_node(index); 79 80 SMC_RET3(handle, NULL, data.nodeid, data.mpidr); 81 } else { 82 SMC_RET1(handle, SMC_ARCH_CALL_INVAL_PARAM); 83 } 84 85 case SIP_SVC_GET_CPU_TOPOLOGY: 86 struct platform_cpu_topology topology; 87 88 topology = sbsa_platform_cpu_topology(); 89 90 if (topology.cores > 0) { 91 SMC_RET5(handle, NULL, topology.sockets, 92 topology.clusters, topology.cores, 93 topology.threads); 94 } else { 95 /* we do not know topology so we report SMC as unknown */ 96 SMC_RET1(handle, SMC_UNK); 97 } 98 99 case SIP_SVC_GET_MEMORY_NODE_COUNT: 100 SMC_RET2(handle, NULL, sbsa_platform_num_memnodes()); 101 102 case SIP_SVC_GET_MEMORY_NODE: 103 index = x1; 104 if (index < PLAT_MAX_MEM_NODES) { 105 struct platform_memory_data data; 106 107 data = sbsa_platform_memory_node(index); 108 109 SMC_RET4(handle, NULL, data.nodeid, 110 data.addr_base, data.addr_size); 111 } else { 112 SMC_RET1(handle, SMC_ARCH_CALL_INVAL_PARAM); 113 } 114 115 default: 116 ERROR("%s: unhandled SMC (0x%x) (function id: %d)\n", __func__, smc_fid, 117 smc_fid - SIP_FUNCTION); 118 SMC_RET1(handle, SMC_UNK); 119 } 120 } 121 122 int sbsa_sip_smc_setup(void) 123 { 124 return 0; 125 } 126 127 /* Define a runtime service descriptor for fast SMC calls */ 128 DECLARE_RT_SVC( 129 sbsa_sip_svc, 130 OEN_SIP_START, 131 OEN_SIP_END, 132 SMC_TYPE_FAST, 133 sbsa_sip_smc_setup, 134 sbsa_sip_smc_handler 135 ); 136