xref: /aosp_15_r20/external/coreboot/src/arch/arm64/smc.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <arch/smc.h>
4 #include <console/console.h>
5 #include <types.h>
6 
7 /* Assumes at least a PSCI implementation is present */
smccc_supports_arch_soc_id(void)8 uint8_t smccc_supports_arch_soc_id(void)
9 {
10 	static uint8_t supported = 0xff;
11 	uint64_t smc_ret;
12 
13 	if (supported != 0xff)
14 		return supported;
15 
16 	// PSCI_FEATURES mandatory from PSCI 1.0
17 	smc_ret = smc_call0(PSCI_VERSION);
18 	if (smc_ret < 0x10000)
19 		goto fail;
20 
21 	smc_ret = smc_call1(PSCI_FEATURES, SMCCC_VERSION);
22 	if (smc_ret == PSCI_NOT_SUPPORTED)
23 		goto fail;
24 
25 	// SMCCC_ARCH_FEATURES supported from SMCCC 1.1
26 	smc_ret = smc_call0(SMCCC_VERSION);
27 	if (smc_ret < 0x10001)
28 		goto fail;
29 
30 	smc_ret = smc_call1(SMCCC_ARCH_FEATURES, SMCCC_ARCH_SOC_ID);
31 	if (smc_ret != SMC_SUCCESS)
32 		goto fail;
33 
34 	supported = 1;
35 	return supported;
36 
37 fail:
38 	supported = 0;
39 	return supported;
40 }
41 
smccc_arch_soc_id(uint32_t * jep106code,uint32_t * soc_revision)42 enum cb_err smccc_arch_soc_id(uint32_t *jep106code, uint32_t *soc_revision)
43 {
44 	uint64_t smc_ret;
45 
46 	if (jep106code == NULL || soc_revision == NULL)
47 		return CB_ERR_ARG;
48 
49 	smc_ret = smc_call1(SMCCC_ARCH_SOC_ID, SMCCC_GET_SOC_VERSION);
50 	if (smc_ret != SMC_INVALID_PARAMETER)
51 		*jep106code = smc_ret;
52 	else
53 		*jep106code = -1;
54 
55 	smc_ret = smc_call1(SMCCC_ARCH_SOC_ID, SMCCC_GET_SOC_REVISION);
56 	if (smc_ret != SMC_INVALID_PARAMETER)
57 		*soc_revision = smc_ret;
58 	else
59 		*soc_revision = -1;
60 
61 	if (*jep106code == -1 || *soc_revision == -1) {
62 		printk(BIOS_ERR, "SMCCC_ARCH_SOC_ID failed!\n");
63 		return CB_ERR;
64 	} else
65 		return CB_SUCCESS;
66 }
67