1 /*
2  * SPDX-License-Identifier: BSD-3-Clause
3  * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4  */
5 
6 #include <buffer.h>
7 #include <granule.h>
8 #include <realm.h>
9 #include <rsi-handler.h>
10 #include <smc-rsi.h>
11 
12 COMPILER_ASSERT(RSI_RPV_SIZE == RPV_SIZE);
13 
handle_rsi_realm_config(struct rec * rec,struct rsi_result * res)14 void handle_rsi_realm_config(struct rec *rec, struct rsi_result *res)
15 {
16 	unsigned long ipa = rec->regs[1];
17 	enum s2_walk_status walk_status;
18 	struct s2_walk_result walk_res;
19 	struct granule *gr;
20 	struct rsi_realm_config *config;
21 	struct rd *rd;
22 
23 	res->action = UPDATE_REC_RETURN_TO_REALM;
24 
25 	if (!GRANULE_ALIGNED(ipa) || !addr_in_rec_par(rec, ipa)) {
26 		res->smc_res.x[0] = RSI_ERROR_INPUT;
27 		return;
28 	}
29 
30 	walk_status = realm_ipa_to_pa(rec, ipa, &walk_res);
31 
32 	if (walk_status == WALK_FAIL) {
33 		if (walk_res.ripas_val == RIPAS_EMPTY) {
34 			res->smc_res.x[0] = RSI_ERROR_INPUT;
35 		} else {
36 			res->action = STAGE_2_TRANSLATION_FAULT;
37 			res->rtt_level = walk_res.rtt_level;
38 		}
39 		return;
40 	}
41 
42 	if (walk_status == WALK_INVALID_PARAMS) {
43 		res->smc_res.x[0] = RSI_ERROR_INPUT;
44 		return;
45 	}
46 
47 	/* Map Realm data granule to RMM address space */
48 	gr = find_granule(walk_res.pa);
49 	config = (struct rsi_realm_config *)buffer_granule_map(gr, SLOT_REALM);
50 	assert(config != NULL);
51 
52 	/* Populate config structure */
53 	config->ipa_width = rec->realm_info.s2_ctx.ipa_bits;
54 	if (rec->realm_info.algorithm == HASH_SHA_256) {
55 		config->algorithm = RSI_HASH_SHA_256;
56 	} else {
57 		config->algorithm = RSI_HASH_SHA_512;
58 	}
59 
60 	/* Map rd granule */
61 	rd = buffer_granule_map(rec->realm_info.g_rd, SLOT_RD);
62 	assert(rd != NULL);
63 
64 	/* Populate Realm Personalization Value */
65 	(void)memcpy(config->rpv, rd->rpv, RSI_RPV_SIZE);
66 
67 	/* Unmap rd granule */
68 	buffer_unmap(rd);
69 
70 	/* Unmap Realm data granule */
71 	buffer_unmap(config);
72 
73 	/* Unlock last level RTT */
74 	granule_unlock(walk_res.llt);
75 
76 	/* Write output values */
77 	res->smc_res.x[0] = RSI_SUCCESS;
78 }
79