blob: 2324fcf5bf7e793f853cbdd1146cf137a18b8d1e [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
13bool handle_rsi_ipa_state_set(struct rec *rec, struct rmi_rec_exit *rec_exit)
14{
15 unsigned long start = rec->regs[1];
16 unsigned long size = rec->regs[2];
17 unsigned long end = start + size;
AlexeiFedorov0fb44552023-04-14 15:37:58 +010018 enum ripas ripas_val = (enum ripas)rec->regs[3];
Soby Mathewb4c6df42022-11-09 11:13:29 +000019
AlexeiFedorov0fb44552023-04-14 15:37:58 +010020 if (ripas_val > RIPAS_RAM) {
Soby Mathewb4c6df42022-11-09 11:13:29 +000021 return true;
22 }
23
24 if (!GRANULE_ALIGNED(start)) {
25 return true;
26 }
27
28 if (!GRANULE_ALIGNED(size)) {
29 return true;
30 }
31
32 if (end <= start) {
33 /* Size is zero, or range overflows */
34 return true;
35 }
36
37 if (!region_in_rec_par(rec, start, end)) {
38 return true;
39 }
40
AlexeiFedorov5cf35ba2023-04-25 10:02:20 +010041 rec->set_ripas.base = start;
42 rec->set_ripas.top = end;
Soby Mathewb4c6df42022-11-09 11:13:29 +000043 rec->set_ripas.addr = start;
AlexeiFedorov0fb44552023-04-14 15:37:58 +010044 rec->set_ripas.ripas_val = ripas_val;
Soby Mathewb4c6df42022-11-09 11:13:29 +000045
46 rec_exit->exit_reason = RMI_EXIT_RIPAS_CHANGE;
47 rec_exit->ripas_base = start;
48 rec_exit->ripas_size = size;
AlexeiFedorov0fb44552023-04-14 15:37:58 +010049 rec_exit->ripas_value = (unsigned int)ripas_val;
Soby Mathewb4c6df42022-11-09 11:13:29 +000050
51 return false;
52}
53
Arunachalam Ganapathydbaa8862022-11-03 13:56:18 +000054struct rsi_walk_smc_result handle_rsi_ipa_state_get(struct rec *rec)
Soby Mathewb4c6df42022-11-09 11:13:29 +000055{
Arunachalam Ganapathydbaa8862022-11-03 13:56:18 +000056 struct rsi_walk_smc_result res = { 0 };
57 enum s2_walk_status ws;
58 unsigned long rtt_level, ipa;
AlexeiFedorov0fb44552023-04-14 15:37:58 +010059 enum ripas ripas_val;
Soby Mathewb4c6df42022-11-09 11:13:29 +000060
Arunachalam Ganapathydbaa8862022-11-03 13:56:18 +000061 ipa = rec->regs[1];
62
63 /* Exit to realm */
64 res.walk_result.abort = false;
65
66 if (!GRANULE_ALIGNED(ipa) || !addr_in_rec_par(rec, ipa)) {
67 res.smc_res.x[0] = RSI_ERROR_INPUT;
68 return res;
Soby Mathewb4c6df42022-11-09 11:13:29 +000069 }
70
AlexeiFedorov0fb44552023-04-14 15:37:58 +010071 ws = realm_ipa_get_ripas(rec, ipa, &ripas_val, &rtt_level);
Arunachalam Ganapathydbaa8862022-11-03 13:56:18 +000072 if (ws == WALK_SUCCESS) {
73 res.smc_res.x[0] = RSI_SUCCESS;
AlexeiFedorov0fb44552023-04-14 15:37:58 +010074 res.smc_res.x[1] = ripas_val;
Arunachalam Ganapathydbaa8862022-11-03 13:56:18 +000075 } else {
76 /* Exit to Host */
77 res.walk_result.abort = true;
78 res.walk_result.rtt_level = rtt_level;
Soby Mathewb4c6df42022-11-09 11:13:29 +000079 }
80
Arunachalam Ganapathydbaa8862022-11-03 13:56:18 +000081 return res;
Soby Mathewb4c6df42022-11-09 11:13:29 +000082}