blob: 38990316da7c85bfff1455bad7ed412c8c540ae4 [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{
AlexeiFedorovccce3ad2023-04-28 18:29:47 +010017 unsigned long base = rec->regs[1];
18 unsigned long top = base + rec->regs[2];
AlexeiFedorov0fb44552023-04-14 15:37:58 +010019 enum ripas ripas_val = (enum ripas)rec->regs[3];
Soby Mathewb4c6df42022-11-09 11:13:29 +000020
AlexeiFedorovccce3ad2023-04-28 18:29:47 +010021 if ((ripas_val > RIPAS_RAM) ||
22 !GRANULE_ALIGNED(base) || !GRANULE_ALIGNED(top) ||
23 (top <= base) || /* Size is zero, or range overflows */
24 !region_in_rec_par(rec, base, top)) {
AlexeiFedorov97844202023-04-27 15:17:35 +010025 res->action = UPDATE_REC_RETURN_TO_REALM;
26 res->smc_res.x[0] = RSI_ERROR_INPUT;
27 return;
Soby Mathewb4c6df42022-11-09 11:13:29 +000028 }
29
AlexeiFedorovccce3ad2023-04-28 18:29:47 +010030 rec->set_ripas.base = base;
31 rec->set_ripas.top = top;
32 rec->set_ripas.addr = base;
AlexeiFedorov0fb44552023-04-14 15:37:58 +010033 rec->set_ripas.ripas_val = ripas_val;
Soby Mathewb4c6df42022-11-09 11:13:29 +000034
35 rec_exit->exit_reason = RMI_EXIT_RIPAS_CHANGE;
AlexeiFedorovccce3ad2023-04-28 18:29:47 +010036 rec_exit->ripas_base = base;
37 rec_exit->ripas_top = top;
AlexeiFedorov0fb44552023-04-14 15:37:58 +010038 rec_exit->ripas_value = (unsigned int)ripas_val;
Soby Mathewb4c6df42022-11-09 11:13:29 +000039
AlexeiFedorov97844202023-04-27 15:17:35 +010040 res->action = UPDATE_REC_EXIT_TO_HOST;
Soby Mathewb4c6df42022-11-09 11:13:29 +000041}
42
AlexeiFedorov97844202023-04-27 15:17:35 +010043void handle_rsi_ipa_state_get(struct rec *rec,
44 struct rsi_result *res)
Soby Mathewb4c6df42022-11-09 11:13:29 +000045{
AlexeiFedorov97844202023-04-27 15:17:35 +010046 unsigned long ipa = rec->regs[1];
47 unsigned long rtt_level;
Arunachalam Ganapathydbaa8862022-11-03 13:56:18 +000048 enum s2_walk_status ws;
AlexeiFedorov0fb44552023-04-14 15:37:58 +010049 enum ripas ripas_val;
Soby Mathewb4c6df42022-11-09 11:13:29 +000050
AlexeiFedorov97844202023-04-27 15:17:35 +010051 res->action = UPDATE_REC_RETURN_TO_REALM;
Arunachalam Ganapathydbaa8862022-11-03 13:56:18 +000052
53 if (!GRANULE_ALIGNED(ipa) || !addr_in_rec_par(rec, ipa)) {
AlexeiFedorov97844202023-04-27 15:17:35 +010054 res->smc_res.x[0] = RSI_ERROR_INPUT;
55 return;
Soby Mathewb4c6df42022-11-09 11:13:29 +000056 }
57
AlexeiFedorov0fb44552023-04-14 15:37:58 +010058 ws = realm_ipa_get_ripas(rec, ipa, &ripas_val, &rtt_level);
Arunachalam Ganapathydbaa8862022-11-03 13:56:18 +000059 if (ws == WALK_SUCCESS) {
AlexeiFedorov97844202023-04-27 15:17:35 +010060 res->smc_res.x[0] = RSI_SUCCESS;
61 res->smc_res.x[1] = ripas_val;
Arunachalam Ganapathydbaa8862022-11-03 13:56:18 +000062 } else {
63 /* Exit to Host */
AlexeiFedorov97844202023-04-27 15:17:35 +010064 res->action = STAGE_2_TRANSLATION_FAULT;
65 res->rtt_level = rtt_level;
66 res->smc_res.x[0] = RSI_ERROR_INPUT;
Soby Mathewb4c6df42022-11-09 11:13:29 +000067 }
Soby Mathewb4c6df42022-11-09 11:13:29 +000068}