Soby Mathew | b4c6df4 | 2022-11-09 11:13:29 +0000 | [diff] [blame^] | 1 | /* |
| 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 | |
| 12 | struct 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 | |
| 64 | out_unmap_rd: |
| 65 | buffer_unmap(rd); |
| 66 | return res; |
| 67 | } |