xref: /rk3399_ARM-atf/plat/qemu/qemu_sbsa/sbsa_sip_svc.c (revision c681d02c6ce2652307a4fcef16bd5626135dfad9)
1*c681d02cSMarcin Juszkiewicz /*
2*c681d02cSMarcin Juszkiewicz  * Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved.
3*c681d02cSMarcin Juszkiewicz  *
4*c681d02cSMarcin Juszkiewicz  * SPDX-License-Identifier: BSD-3-Clause
5*c681d02cSMarcin Juszkiewicz  */
6*c681d02cSMarcin Juszkiewicz 
7*c681d02cSMarcin Juszkiewicz #include <assert.h>
8*c681d02cSMarcin Juszkiewicz 
9*c681d02cSMarcin Juszkiewicz #include <common/runtime_svc.h>
10*c681d02cSMarcin Juszkiewicz #include <libfdt.h>
11*c681d02cSMarcin Juszkiewicz #include <smccc_helpers.h>
12*c681d02cSMarcin Juszkiewicz 
13*c681d02cSMarcin Juszkiewicz /* default platform version is 0.0 */
14*c681d02cSMarcin Juszkiewicz static int platform_version_major;
15*c681d02cSMarcin Juszkiewicz static int platform_version_minor;
16*c681d02cSMarcin Juszkiewicz 
17*c681d02cSMarcin Juszkiewicz #define SMC_FASTCALL       0x80000000
18*c681d02cSMarcin Juszkiewicz #define SMC64_FUNCTION     (SMC_FASTCALL   | 0x40000000)
19*c681d02cSMarcin Juszkiewicz #define SIP_FUNCTION       (SMC64_FUNCTION | 0x02000000)
20*c681d02cSMarcin Juszkiewicz #define SIP_FUNCTION_ID(n) (SIP_FUNCTION   | (n))
21*c681d02cSMarcin Juszkiewicz 
22*c681d02cSMarcin Juszkiewicz /*
23*c681d02cSMarcin Juszkiewicz  * We do not use SMCCC_ARCH_SOC_ID here because qemu_sbsa is virtual platform
24*c681d02cSMarcin Juszkiewicz  * which uses SoC present in QEMU. And they can change on their own while we
25*c681d02cSMarcin Juszkiewicz  * need version of whole 'virtual hardware platform'.
26*c681d02cSMarcin Juszkiewicz  */
27*c681d02cSMarcin Juszkiewicz #define SIP_SVC_VERSION  SIP_FUNCTION_ID(1)
28*c681d02cSMarcin Juszkiewicz 
29*c681d02cSMarcin Juszkiewicz void read_platform_version(void *dtb)
30*c681d02cSMarcin Juszkiewicz {
31*c681d02cSMarcin Juszkiewicz 	int node;
32*c681d02cSMarcin Juszkiewicz 
33*c681d02cSMarcin Juszkiewicz 	node = fdt_path_offset(dtb, "/");
34*c681d02cSMarcin Juszkiewicz 	if (node >= 0) {
35*c681d02cSMarcin Juszkiewicz 		platform_version_major = fdt32_ld(fdt_getprop(dtb, node,
36*c681d02cSMarcin Juszkiewicz 							      "machine-version-major", NULL));
37*c681d02cSMarcin Juszkiewicz 		platform_version_minor = fdt32_ld(fdt_getprop(dtb, node,
38*c681d02cSMarcin Juszkiewicz 							      "machine-version-minor", NULL));
39*c681d02cSMarcin Juszkiewicz 	}
40*c681d02cSMarcin Juszkiewicz }
41*c681d02cSMarcin Juszkiewicz 
42*c681d02cSMarcin Juszkiewicz void sip_svc_init(void)
43*c681d02cSMarcin Juszkiewicz {
44*c681d02cSMarcin Juszkiewicz 	/* Read DeviceTree data before MMU is enabled */
45*c681d02cSMarcin Juszkiewicz 
46*c681d02cSMarcin Juszkiewicz 	void *dtb = (void *)(uintptr_t)ARM_PRELOADED_DTB_BASE;
47*c681d02cSMarcin Juszkiewicz 	int err;
48*c681d02cSMarcin Juszkiewicz 
49*c681d02cSMarcin Juszkiewicz 	err = fdt_open_into(dtb, dtb, PLAT_QEMU_DT_MAX_SIZE);
50*c681d02cSMarcin Juszkiewicz 	if (err < 0) {
51*c681d02cSMarcin Juszkiewicz 		ERROR("Invalid Device Tree at %p: error %d\n", dtb, err);
52*c681d02cSMarcin Juszkiewicz 		return;
53*c681d02cSMarcin Juszkiewicz 	}
54*c681d02cSMarcin Juszkiewicz 
55*c681d02cSMarcin Juszkiewicz 	err = fdt_check_header(dtb);
56*c681d02cSMarcin Juszkiewicz 	if (err < 0) {
57*c681d02cSMarcin Juszkiewicz 		ERROR("Invalid DTB file passed\n");
58*c681d02cSMarcin Juszkiewicz 		return;
59*c681d02cSMarcin Juszkiewicz 	}
60*c681d02cSMarcin Juszkiewicz 
61*c681d02cSMarcin Juszkiewicz 	read_platform_version(dtb);
62*c681d02cSMarcin Juszkiewicz 	INFO("Platform version: %d.%d\n", platform_version_major, platform_version_minor);
63*c681d02cSMarcin Juszkiewicz }
64*c681d02cSMarcin Juszkiewicz 
65*c681d02cSMarcin Juszkiewicz /*
66*c681d02cSMarcin Juszkiewicz  * This function is responsible for handling all SiP calls from the NS world
67*c681d02cSMarcin Juszkiewicz  */
68*c681d02cSMarcin Juszkiewicz uintptr_t sbsa_sip_smc_handler(uint32_t smc_fid,
69*c681d02cSMarcin Juszkiewicz 			       u_register_t x1,
70*c681d02cSMarcin Juszkiewicz 			       u_register_t x2,
71*c681d02cSMarcin Juszkiewicz 			       u_register_t x3,
72*c681d02cSMarcin Juszkiewicz 			       u_register_t x4,
73*c681d02cSMarcin Juszkiewicz 			       void *cookie,
74*c681d02cSMarcin Juszkiewicz 			       void *handle,
75*c681d02cSMarcin Juszkiewicz 			       u_register_t flags)
76*c681d02cSMarcin Juszkiewicz {
77*c681d02cSMarcin Juszkiewicz 	uint32_t ns;
78*c681d02cSMarcin Juszkiewicz 
79*c681d02cSMarcin Juszkiewicz 	/* Determine which security state this SMC originated from */
80*c681d02cSMarcin Juszkiewicz 	ns = is_caller_non_secure(flags);
81*c681d02cSMarcin Juszkiewicz 	if (!ns) {
82*c681d02cSMarcin Juszkiewicz 		ERROR("%s: wrong world SMC (0x%x)\n", __func__, smc_fid);
83*c681d02cSMarcin Juszkiewicz 		SMC_RET1(handle, SMC_UNK);
84*c681d02cSMarcin Juszkiewicz 	}
85*c681d02cSMarcin Juszkiewicz 
86*c681d02cSMarcin Juszkiewicz 	switch (smc_fid) {
87*c681d02cSMarcin Juszkiewicz 	case SIP_SVC_VERSION:
88*c681d02cSMarcin Juszkiewicz 		INFO("Platform version requested\n");
89*c681d02cSMarcin Juszkiewicz 		SMC_RET3(handle, NULL, platform_version_major, platform_version_minor);
90*c681d02cSMarcin Juszkiewicz 
91*c681d02cSMarcin Juszkiewicz 	default:
92*c681d02cSMarcin Juszkiewicz 		ERROR("%s: unhandled SMC (0x%x) (function id: %d)\n", __func__, smc_fid,
93*c681d02cSMarcin Juszkiewicz 		      smc_fid - SIP_FUNCTION);
94*c681d02cSMarcin Juszkiewicz 		SMC_RET1(handle, SMC_UNK);
95*c681d02cSMarcin Juszkiewicz 	}
96*c681d02cSMarcin Juszkiewicz }
97*c681d02cSMarcin Juszkiewicz 
98*c681d02cSMarcin Juszkiewicz int sbsa_sip_smc_setup(void)
99*c681d02cSMarcin Juszkiewicz {
100*c681d02cSMarcin Juszkiewicz 	return 0;
101*c681d02cSMarcin Juszkiewicz }
102*c681d02cSMarcin Juszkiewicz 
103*c681d02cSMarcin Juszkiewicz /* Define a runtime service descriptor for fast SMC calls */
104*c681d02cSMarcin Juszkiewicz DECLARE_RT_SVC(
105*c681d02cSMarcin Juszkiewicz 	sbsa_sip_svc,
106*c681d02cSMarcin Juszkiewicz 	OEN_SIP_START,
107*c681d02cSMarcin Juszkiewicz 	OEN_SIP_END,
108*c681d02cSMarcin Juszkiewicz 	SMC_TYPE_FAST,
109*c681d02cSMarcin Juszkiewicz 	sbsa_sip_smc_setup,
110*c681d02cSMarcin Juszkiewicz 	sbsa_sip_smc_handler
111*c681d02cSMarcin Juszkiewicz );
112