xref: /rk3399_ARM-atf/services/std_svc/firme/firme_base_service.c (revision 430f246e58d146949d399d72294f56403672bee0)
1 /*
2  * Copyright (c) 2026, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <stdint.h>
8 
9 #include <arch.h>
10 #include <arch_features.h>
11 #include <common/debug.h>
12 #include <lib/gpt_rme/gpt_rme.h>
13 #include <lib/smccc.h>
14 #include <services/firme_svc.h>
15 #include <smccc_helpers.h>
16 
17 /* Feature reg 0 indicates which ABIs are supported for base service. */
18 #define FEAT_REG_0_DEFAULT (FIRME_BASE_VERSION_BIT | FIRME_BASE_FEATURES_BIT)
19 
20 /* Feature reg 1 shows available services and base functionalities. */
21 #define FEAT_REG_1_DEFAULT					\
22 	((0x0 & FIRME_BASE_MAX_SH_BUF_PG_CNT_MASK))		\
23 			<< FIRME_BASE_MAX_SH_BUF_PG_CNT_SHIFT |	\
24 		((0x0 & FIRME_BASE_MIN_SH_BUF_SZ_MASK)		\
25 		 << FIRME_BASE_MIN_SH_BUF_SZ_SHIFT)
26 
27 /* Structure describing base service. */
28 firme_service_info_t base_info = {
29 	.version = FIRME_VERSION(FIRME_BASE_VERSION_MAJOR,
30 				 FIRME_BASE_VERSION_MINOR),
31 	.instance_support =
32 		(BIT(FIRME_SECURE) | BIT(FIRME_NONSECURE) | BIT(FIRME_REALM)),
33 	.num_feature_regs = 2,
34 	.feature_reg = { FEAT_REG_0_DEFAULT, FEAT_REG_1_DEFAULT },
35 };
36 
firme_base_get_feat_reg_1(firme_instance_e instance)37 static uint64_t firme_base_get_feat_reg_1(firme_instance_e instance)
38 {
39 	firme_service_info_t *info __unused;
40 	uint64_t reg = base_info.feature_reg[1];
41 
42 	info = firme_granule_mgmt_service_get_info();
43 	if ((info != NULL) &&
44 	    ((info->instance_support & BIT(instance)) != 0U)) {
45 		reg |= FIRME_BASE_SERVICE_GRANULE_MGMT_BIT;
46 	}
47 
48 	return reg;
49 }
50 
get_firme_service_version(firme_instance_e instance,firme_service_id_e service_id)51 static int32_t get_firme_service_version(firme_instance_e instance,
52 					 firme_service_id_e service_id)
53 {
54 	firme_service_info_t *info = NULL;
55 
56 	if (service_id >= FIRME_SERVICE_ID_MAX) {
57 		return FIRME_NOT_SUPPORTED;
58 	}
59 
60 	switch (service_id) {
61 	case FIRME_BASE_ID:
62 		info = &base_info;
63 		break;
64 	case FIRME_GRANULE_MGMT_ID:
65 		info = firme_granule_mgmt_service_get_info();
66 		break;
67 	default:
68 		return FIRME_NOT_SUPPORTED;
69 	}
70 
71 	if ((info != NULL) && (info->instance_support & BIT(instance))) {
72 		return info->version;
73 	}
74 
75 	/* Return zero to indicate not supported. */
76 	return FIRME_NOT_SUPPORTED;
77 }
78 
get_firme_feature_reg(uint64_t * reg,firme_instance_e instance,uint8_t service_id,uint8_t reg_index)79 static int32_t get_firme_feature_reg(uint64_t *reg, firme_instance_e instance,
80 				     uint8_t service_id, uint8_t reg_index)
81 {
82 	firme_service_info_t *info = NULL;
83 
84 	if (service_id >= FIRME_SERVICE_ID_MAX) {
85 		return FIRME_NOT_SUPPORTED;
86 	}
87 
88 	switch (service_id) {
89 	case FIRME_BASE_ID:
90 		if (reg_index < base_info.num_feature_regs) {
91 			if (reg_index == 1) {
92 				*reg = firme_base_get_feat_reg_1(instance);
93 			} else {
94 				*reg = base_info.feature_reg[reg_index];
95 			}
96 			return FIRME_SUCCESS;
97 		}
98 		break;
99 	case FIRME_GRANULE_MGMT_ID:
100 		info = firme_granule_mgmt_service_get_info();
101 		break;
102 	}
103 
104 	if ((info != NULL) && (reg_index < info->num_feature_regs) &&
105 	    (info->instance_support & BIT(instance))) {
106 		*reg = info->feature_reg[reg_index];
107 		return FIRME_SUCCESS;
108 	}
109 
110 	return FIRME_NOT_SUPPORTED;
111 }
112 
firme_base_service_handler(firme_instance_e instance,uint32_t smc_fid,uint64_t x1,uint64_t x2,uint64_t x3,uint64_t x4,void * cookie,void * handle,uint64_t flags)113 u_register_t firme_base_service_handler(firme_instance_e instance,
114 					uint32_t smc_fid, uint64_t x1,
115 					uint64_t x2, uint64_t x3, uint64_t x4,
116 					void *cookie, void *handle,
117 					uint64_t flags)
118 {
119 	uint64_t reg;
120 
121 	switch (smc_fid) {
122 	case FIRME_SERVICE_VERSION_FID:
123 		SMC_RET1(handle,
124 			 get_firme_service_version(instance, (uint8_t)x1));
125 		break;
126 	case FIRME_SERVICE_FEATURES_FID:
127 		if (get_firme_feature_reg(&reg, instance, (uint8_t)x1,
128 					  (uint8_t)x2) == FIRME_SUCCESS) {
129 			SMC_RET2(handle, FIRME_SUCCESS, reg);
130 		} else {
131 			SMC_RET1(handle, FIRME_NOT_SUPPORTED);
132 		}
133 		break;
134 	default:
135 		ERROR("FIRME Base Service FID 0x%X not implemented\n", smc_fid);
136 		SMC_RET1(handle, FIRME_NOT_SUPPORTED);
137 	}
138 }
139