1de6b79d8SGovindraj Raja /*
2f69f5512SNandan J * Copyright (c) 2024-2025, Arm Limited and Contributors. All rights reserved.
3de6b79d8SGovindraj Raja *
4de6b79d8SGovindraj Raja * SPDX-License-Identifier: BSD-3-Clause
5de6b79d8SGovindraj Raja */
6de6b79d8SGovindraj Raja
7de6b79d8SGovindraj Raja #include <stdint.h>
8de6b79d8SGovindraj Raja
9de6b79d8SGovindraj Raja #include <common/debug.h>
10de6b79d8SGovindraj Raja #include <common/runtime_svc.h>
11273b8983SGovindraj Raja #include <lib/debugfs.h>
12f7679d43SGovindraj Raja #include <lib/pmf/pmf.h>
13f69f5512SNandan J #if PLAT_ARM_ACS_SMC_HANDLER
14f69f5512SNandan J #include <plat/arm/common/plat_acs_smc_handler.h>
15f69f5512SNandan J #endif /* PLAT_ARM_ACS_SMC_HANDLER */
16*96546b5cSManish Pandey #include <services/spm_mm_svc.h>
17de6b79d8SGovindraj Raja #include <services/ven_el3_svc.h>
18de6b79d8SGovindraj Raja #include <tools_share/uuid.h>
19de6b79d8SGovindraj Raja
20de6b79d8SGovindraj Raja /* vendor-specific EL3 UUID */
21de6b79d8SGovindraj Raja DEFINE_SVC_UUID2(ven_el3_svc_uid,
22de6b79d8SGovindraj Raja 0xb6011dca, 0x57c4, 0x407e, 0x83, 0xf0,
23de6b79d8SGovindraj Raja 0xa7, 0xed, 0xda, 0xf0, 0xdf, 0x6c);
24de6b79d8SGovindraj Raja
ven_el3_svc_setup(void)25de6b79d8SGovindraj Raja static int ven_el3_svc_setup(void)
26de6b79d8SGovindraj Raja {
27273b8983SGovindraj Raja #if USE_DEBUGFS
28273b8983SGovindraj Raja if (debugfs_smc_setup() != 0) {
29273b8983SGovindraj Raja return 1;
30273b8983SGovindraj Raja }
31273b8983SGovindraj Raja #endif /* USE_DEBUGFS */
32273b8983SGovindraj Raja
33f7679d43SGovindraj Raja #if ENABLE_PMF
34f7679d43SGovindraj Raja if (pmf_setup() != 0) {
35f7679d43SGovindraj Raja return 1;
36f7679d43SGovindraj Raja }
37f7679d43SGovindraj Raja #endif /* ENABLE_PMF */
38f7679d43SGovindraj Raja
39de6b79d8SGovindraj Raja return 0;
40de6b79d8SGovindraj Raja }
41de6b79d8SGovindraj Raja
42de6b79d8SGovindraj Raja /*
43de6b79d8SGovindraj Raja * This function handles Arm defined vendor-specific EL3 Service Calls.
44de6b79d8SGovindraj Raja */
ven_el3_svc_handler(unsigned int smc_fid,u_register_t x1,u_register_t x2,u_register_t x3,u_register_t x4,void * cookie,void * handle,u_register_t flags)45de6b79d8SGovindraj Raja static uintptr_t ven_el3_svc_handler(unsigned int smc_fid,
46de6b79d8SGovindraj Raja u_register_t x1,
47de6b79d8SGovindraj Raja u_register_t x2,
48de6b79d8SGovindraj Raja u_register_t x3,
49de6b79d8SGovindraj Raja u_register_t x4,
50de6b79d8SGovindraj Raja void *cookie,
51de6b79d8SGovindraj Raja void *handle,
52de6b79d8SGovindraj Raja u_register_t flags)
53de6b79d8SGovindraj Raja {
54273b8983SGovindraj Raja #if USE_DEBUGFS
55273b8983SGovindraj Raja /*
56273b8983SGovindraj Raja * Dispatch debugfs calls to debugfs SMC handler and return its
57273b8983SGovindraj Raja * return value.
58273b8983SGovindraj Raja */
59273b8983SGovindraj Raja if (is_debugfs_fid(smc_fid)) {
60273b8983SGovindraj Raja return debugfs_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
61273b8983SGovindraj Raja handle, flags);
62273b8983SGovindraj Raja }
63273b8983SGovindraj Raja #endif /* USE_DEBUGFS */
64273b8983SGovindraj Raja
65f7679d43SGovindraj Raja #if ENABLE_PMF
66f7679d43SGovindraj Raja
67f7679d43SGovindraj Raja /*
68f7679d43SGovindraj Raja * Dispatch PMF calls to PMF SMC handler and return its return
69f7679d43SGovindraj Raja * value
70f7679d43SGovindraj Raja */
71f7679d43SGovindraj Raja if (is_pmf_fid(smc_fid)) {
72f7679d43SGovindraj Raja return pmf_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
73f7679d43SGovindraj Raja handle, flags);
74f7679d43SGovindraj Raja }
75f7679d43SGovindraj Raja
76f7679d43SGovindraj Raja #endif /* ENABLE_PMF */
77f7679d43SGovindraj Raja
78f69f5512SNandan J #if PLAT_ARM_ACS_SMC_HANDLER
79f69f5512SNandan J /*
80f69f5512SNandan J * Dispatch ACS calls to ACS SMC handler and return its return value
81f69f5512SNandan J */
82f69f5512SNandan J if (is_acs_fid(smc_fid)) {
83f69f5512SNandan J return plat_arm_acs_smc_handler(smc_fid, x1, x2, x3, x4, handle);
84f69f5512SNandan J }
85f69f5512SNandan J #endif /* PLAT_ARM_ACS_SMC_HANDLER */
86f69f5512SNandan J
87de6b79d8SGovindraj Raja switch (smc_fid) {
88de6b79d8SGovindraj Raja case VEN_EL3_SVC_UID:
89de6b79d8SGovindraj Raja /* Return UID to the caller */
90de6b79d8SGovindraj Raja SMC_UUID_RET(handle, ven_el3_svc_uid);
91de6b79d8SGovindraj Raja break;
92de6b79d8SGovindraj Raja case VEN_EL3_SVC_VERSION:
93de6b79d8SGovindraj Raja SMC_RET2(handle, VEN_EL3_SVC_VERSION_MAJOR, VEN_EL3_SVC_VERSION_MINOR);
94de6b79d8SGovindraj Raja break;
95*96546b5cSManish Pandey #if SPM_MM
96*96546b5cSManish Pandey /*
97*96546b5cSManish Pandey * Handle TPM start SMC as mentioned in TCG ACPI specification.
98*96546b5cSManish Pandey */
99*96546b5cSManish Pandey case TPM_START_SMC_32:
100*96546b5cSManish Pandey case TPM_START_SMC_64:
101*96546b5cSManish Pandey return spm_mm_tpm_start_handler(smc_fid, x1, x2, x3, x4, cookie,
102*96546b5cSManish Pandey handle, flags);
103*96546b5cSManish Pandey break;
104*96546b5cSManish Pandey #endif
105de6b79d8SGovindraj Raja default:
106273b8983SGovindraj Raja WARN("Unimplemented vendor-specific EL3 Service call: 0x%x\n", smc_fid);
107de6b79d8SGovindraj Raja SMC_RET1(handle, SMC_UNK);
108de6b79d8SGovindraj Raja break;
109de6b79d8SGovindraj Raja }
110de6b79d8SGovindraj Raja }
111de6b79d8SGovindraj Raja
112de6b79d8SGovindraj Raja /* Define a runtime service descriptor for fast SMC calls */
113de6b79d8SGovindraj Raja DECLARE_RT_SVC(
114de6b79d8SGovindraj Raja ven_el3_svc,
115de6b79d8SGovindraj Raja OEN_VEN_EL3_START,
116de6b79d8SGovindraj Raja OEN_VEN_EL3_END,
117de6b79d8SGovindraj Raja SMC_TYPE_FAST,
118de6b79d8SGovindraj Raja ven_el3_svc_setup,
119de6b79d8SGovindraj Raja ven_el3_svc_handler
120de6b79d8SGovindraj Raja );
121