blob: 38a6446c32c2918810b29e1d505ed755736b409c [file] [log] [blame]
Soby Mathewb4c6df42022-11-09 11:13:29 +00001/*
2 * SPDX-License-Identifier: BSD-3-Clause
3 * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4 */
5
6#include <granule.h>
7#include <realm.h>
8#include <rsi-config.h>
9#include <rsi-walk.h>
10#include <smc-rsi.h>
11
12struct rsi_config_result handle_rsi_realm_config(struct rec *rec)
13{
14 struct rsi_config_result res = { 0 };
15 unsigned long ipa = rec->regs[1];
16 struct rd *rd;
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
22 if (!GRANULE_ALIGNED(ipa) || !addr_in_rec_par(rec, ipa)) {
23 res.smc_res.x[0] = RSI_ERROR_INPUT;
24 return res;
25 }
26
27 rd = granule_map(rec->realm_info.g_rd, SLOT_RD);
28
29 walk_status = realm_ipa_to_pa(rd, ipa, &walk_res);
30
31 if (walk_status == WALK_FAIL) {
32 if (s2_walk_result_match_ripas(&walk_res, RMI_EMPTY)) {
33 res.smc_res.x[0] = RSI_ERROR_INPUT;
34 } else {
35 /* Exit to Host */
36 res.walk_result.abort = true;
37 res.walk_result.rtt_level = walk_res.rtt_level;
38 }
39 goto out_unmap_rd;
40 }
41
42 if (walk_status == WALK_INVALID_PARAMS) {
43 /* Return error to Realm */
44 res.smc_res.x[0] = RSI_ERROR_INPUT;
45 goto out_unmap_rd;
46 }
47
48 /* Map Realm data granule to RMM address space */
49 gr = find_granule(walk_res.pa);
50 config = (struct rsi_realm_config *)granule_map(gr, SLOT_RSI_CALL);
51
52 /* Populate config structure */
53 config->ipa_width = rec->realm_info.ipa_bits;
54
55 /* Unmap Realm data granule */
56 buffer_unmap(config);
57
58 /* Unlock last level RTT */
59 granule_unlock(walk_res.llt);
60
61 /* Write output values */
62 res.smc_res.x[0] = RSI_SUCCESS;
63
64out_unmap_rd:
65 buffer_unmap(rd);
66 return res;
67}