blob: 1affda7552059eb842fe7fb8b8e5b45dd9a01a11 [file] [log] [blame]
Soby Mathewb4c6df42022-11-09 11:13:29 +00001/*
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
5 */
6
7#include <realm.h>
8#include <ripas.h>
AlexeiFedorov5b186ad2023-04-26 14:43:18 +01009#include <rsi-handler.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +000010#include <smc-rsi.h>
11#include <status.h>
12
AlexeiFedorov97844202023-04-27 15:17:35 +010013void handle_rsi_ipa_state_set(struct rec *rec,
14 struct rmi_rec_exit *rec_exit,
15 struct rsi_result *res)
Soby Mathewb4c6df42022-11-09 11:13:29 +000016{
17 unsigned long start = rec->regs[1];
18 unsigned long size = rec->regs[2];
19 unsigned long end = start + size;
AlexeiFedorov0fb44552023-04-14 15:37:58 +010020 enum ripas ripas_val = (enum ripas)rec->regs[3];
Soby Mathewb4c6df42022-11-09 11:13:29 +000021
AlexeiFedorov97844202023-04-27 15:17:35 +010022 if ((ripas_val > RIPAS_RAM) ||
23 !GRANULE_ALIGNED(start) || !GRANULE_ALIGNED(size) ||
24 (end <= start) || /* Size is zero, or range overflows */
25 !region_in_rec_par(rec, start, end)) {
26 res->action = UPDATE_REC_RETURN_TO_REALM;
27 res->smc_res.x[0] = RSI_ERROR_INPUT;
28 return;
Soby Mathewb4c6df42022-11-09 11:13:29 +000029 }
30
AlexeiFedorov5cf35ba2023-04-25 10:02:20 +010031 rec->set_ripas.base = start;
32 rec->set_ripas.top = end;
Soby Mathewb4c6df42022-11-09 11:13:29 +000033 rec->set_ripas.addr = start;
AlexeiFedorov0fb44552023-04-14 15:37:58 +010034 rec->set_ripas.ripas_val = ripas_val;
Soby Mathewb4c6df42022-11-09 11:13:29 +000035
36 rec_exit->exit_reason = RMI_EXIT_RIPAS_CHANGE;
37 rec_exit->ripas_base = start;
38 rec_exit->ripas_size = size;
AlexeiFedorov0fb44552023-04-14 15:37:58 +010039 rec_exit->ripas_value = (unsigned int)ripas_val;
Soby Mathewb4c6df42022-11-09 11:13:29 +000040
AlexeiFedorov97844202023-04-27 15:17:35 +010041 res->action = UPDATE_REC_EXIT_TO_HOST;
Soby Mathewb4c6df42022-11-09 11:13:29 +000042}
43
AlexeiFedorov97844202023-04-27 15:17:35 +010044void handle_rsi_ipa_state_get(struct rec *rec,
45 struct rsi_result *res)
Soby Mathewb4c6df42022-11-09 11:13:29 +000046{
AlexeiFedorov97844202023-04-27 15:17:35 +010047 unsigned long ipa = rec->regs[1];
48 unsigned long rtt_level;
Arunachalam Ganapathydbaa8862022-11-03 13:56:18 +000049 enum s2_walk_status ws;
AlexeiFedorov0fb44552023-04-14 15:37:58 +010050 enum ripas ripas_val;
Soby Mathewb4c6df42022-11-09 11:13:29 +000051
AlexeiFedorov97844202023-04-27 15:17:35 +010052 res->action = UPDATE_REC_RETURN_TO_REALM;
Arunachalam Ganapathydbaa8862022-11-03 13:56:18 +000053
54 if (!GRANULE_ALIGNED(ipa) || !addr_in_rec_par(rec, ipa)) {
AlexeiFedorov97844202023-04-27 15:17:35 +010055 res->smc_res.x[0] = RSI_ERROR_INPUT;
56 return;
Soby Mathewb4c6df42022-11-09 11:13:29 +000057 }
58
AlexeiFedorov0fb44552023-04-14 15:37:58 +010059 ws = realm_ipa_get_ripas(rec, ipa, &ripas_val, &rtt_level);
Arunachalam Ganapathydbaa8862022-11-03 13:56:18 +000060 if (ws == WALK_SUCCESS) {
AlexeiFedorov97844202023-04-27 15:17:35 +010061 res->smc_res.x[0] = RSI_SUCCESS;
62 res->smc_res.x[1] = ripas_val;
Arunachalam Ganapathydbaa8862022-11-03 13:56:18 +000063 } else {
64 /* Exit to Host */
AlexeiFedorov97844202023-04-27 15:17:35 +010065 res->action = STAGE_2_TRANSLATION_FAULT;
66 res->rtt_level = rtt_level;
67 res->smc_res.x[0] = RSI_ERROR_INPUT;
Soby Mathewb4c6df42022-11-09 11:13:29 +000068 }
Soby Mathewb4c6df42022-11-09 11:13:29 +000069}