blob: 0aaa1f221ba7d498ea1af02f7c50ebabe31c029f [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 <assert.h>
7#include <debug.h>
8#include <psci.h>
9#include <rsi-logger.h>
10#include <smc-rsi.h>
AlexeiFedorov6c119692023-04-21 12:31:15 +010011#include <string.h>
Soby Mathewb4c6df42022-11-09 11:13:29 +000012#include <utils_def.h>
13
14/* RMI handler uses 29 chars for function name */
AlexeiFedorov7b3c3042023-06-28 15:41:11 +010015#define MAX_NAME_LEN 29UL
Soby Mathewb4c6df42022-11-09 11:13:29 +000016
AlexeiFedorov6c119692023-04-21 12:31:15 +010017/* Max 10 64-bit parameters separated by space */
18#define PARAMS_STR_LEN (10UL * sizeof("0123456789ABCDEF"))
Soby Mathewb4c6df42022-11-09 11:13:29 +000019
AlexeiFedorov7b3c3042023-06-28 15:41:11 +010020#define MAX_STATUS_LEN sizeof("{RSI_ERROR_INPUT}")
Soby Mathewb4c6df42022-11-09 11:13:29 +000021
AlexeiFedorov7b3c3042023-06-28 15:41:11 +010022#define BUFFER_SIZE (MAX_NAME_LEN + PARAMS_STR_LEN + \
AlexeiFedorov6c119692023-04-21 12:31:15 +010023 sizeof(" > ") - 1UL + MAX_STATUS_LEN)
Soby Mathewb4c6df42022-11-09 11:13:29 +000024
AlexeiFedorov6c119692023-04-21 12:31:15 +010025struct rsi_handler {
26 const char *fn_name; /* function name */
27 unsigned int num_args; /* number of arguments */
28 unsigned int num_vals; /* number of output values */
Soby Mathewb4c6df42022-11-09 11:13:29 +000029};
30
AlexeiFedorov6c119692023-04-21 12:31:15 +010031#define RSI_HANDLER_ID(_id) SMC64_FID_OFFSET_FROM_RANGE_MIN(RSI, SMC_RSI_##_id)
Soby Mathewb4c6df42022-11-09 11:13:29 +000032
AlexeiFedorov6c119692023-04-21 12:31:15 +010033#define RSI_FUNCTION(_id, _in, _out)[RSI_HANDLER_ID(_id)] = { \
34 .fn_name = #_id, \
35 .num_args = _in, \
36 .num_vals = _out \
37}
38
39static const struct rsi_handler rsi_logger[] = {
40 RSI_FUNCTION(ABI_VERSION, 0U, 1U), /* 0xC4000190 */
41 RSI_FUNCTION(MEASUREMENT_READ, 1U, 8U), /* 0xC4000192 */
42 RSI_FUNCTION(MEASUREMENT_EXTEND, 10U, 0U), /* 0xC4000193 */
43 RSI_FUNCTION(ATTEST_TOKEN_INIT, 9U, 0U), /* 0xC4000194 */
44 RSI_FUNCTION(ATTEST_TOKEN_CONTINUE, 1U, 1U), /* 0xC4000195 */
45 RSI_FUNCTION(REALM_CONFIG, 1U, 0U), /* 0xC4000196 */
AlexeiFedorov63614ea2023-07-14 17:07:20 +010046 RSI_FUNCTION(IPA_STATE_SET, 4U, 1U), /* 0xC4000197 */
AlexeiFedorov6c119692023-04-21 12:31:15 +010047 RSI_FUNCTION(IPA_STATE_GET, 1U, 1U), /* 0xC4000198 */
48 RSI_FUNCTION(HOST_CALL, 1U, 0U) /* 0xC4000199 */
Soby Mathewb4c6df42022-11-09 11:13:29 +000049};
50
AlexeiFedorov6c119692023-04-21 12:31:15 +010051#define RSI_STATUS_STRING(_id)[RSI_##_id] = #_id
Soby Mathewb4c6df42022-11-09 11:13:29 +000052
AlexeiFedorov1716b982023-08-22 14:49:51 +010053static const char *rsi_status_string[] = {
AlexeiFedorov6c119692023-04-21 12:31:15 +010054 RSI_STATUS_STRING(SUCCESS),
55 RSI_STATUS_STRING(ERROR_INPUT),
56 RSI_STATUS_STRING(ERROR_STATE),
57 RSI_STATUS_STRING(INCOMPLETE)
58};
59
60COMPILER_ASSERT(ARRAY_LEN(rsi_status_string) == RSI_ERROR_COUNT);
61
AlexeiFedorov56e1a8e2023-09-01 17:06:13 +010062static const struct rsi_handler *fid_to_rsi_logger(unsigned int id)
Soby Mathewb4c6df42022-11-09 11:13:29 +000063{
AlexeiFedorov56e1a8e2023-09-01 17:06:13 +010064 return &rsi_logger[id - SMC_RSI_ABI_VERSION];
AlexeiFedorov6c119692023-04-21 12:31:15 +010065}
66
67static size_t print_entry(unsigned int id, unsigned long args[],
68 char *buf, size_t len)
69{
70 unsigned int num = 7U; /* up to seven arguments */
71 int cnt;
Soby Mathewb4c6df42022-11-09 11:13:29 +000072
73 switch (id) {
AlexeiFedorov6c119692023-04-21 12:31:15 +010074 case SMC_RSI_ABI_VERSION ... SMC_RSI_HOST_CALL: {
AlexeiFedorov56e1a8e2023-09-01 17:06:13 +010075 const struct rsi_handler *logger = fid_to_rsi_logger(id);
Soby Mathewb4c6df42022-11-09 11:13:29 +000076
AlexeiFedorov6c119692023-04-21 12:31:15 +010077 num = logger->num_args;
78 if (logger->fn_name != NULL) {
79 cnt = snprintf(buf, MAX_NAME_LEN + 1UL,
80 "%s%s", "SMC_RSI_", logger->fn_name);
Soby Mathewb4c6df42022-11-09 11:13:29 +000081 } else {
82 /* Handle gaps in RSI commands numbering */
AlexeiFedorov6c119692023-04-21 12:31:15 +010083 cnt = snprintf(buf, MAX_NAME_LEN + 1UL,
84 "%s%08x", "SMC_RSI_", id);
Soby Mathewb4c6df42022-11-09 11:13:29 +000085 }
Soby Mathewb4c6df42022-11-09 11:13:29 +000086 break;
AlexeiFedorov6c119692023-04-21 12:31:15 +010087 }
Soby Mathewb4c6df42022-11-09 11:13:29 +000088 /* SMC32 PSCI calls */
89 case SMC32_PSCI_FID_MIN ... SMC32_PSCI_FID_MAX:
90 FALLTHROUGH;
91 case SMC64_PSCI_FID_MIN ... SMC64_PSCI_FID_MAX:
AlexeiFedorov6c119692023-04-21 12:31:15 +010092 cnt = snprintf(buf, MAX_NAME_LEN + 1UL, "%s%08x", "PSCI_", id);
Soby Mathewb4c6df42022-11-09 11:13:29 +000093 break;
94
95 /* Other SMC calls */
96 default:
AlexeiFedorov6c119692023-04-21 12:31:15 +010097 cnt = snprintf(buf, MAX_NAME_LEN + 1UL, "%s%08x", "SMC_", id);
Soby Mathewb4c6df42022-11-09 11:13:29 +000098 break;
99 }
100
AlexeiFedorov56e1a8e2023-09-01 17:06:13 +0100101 assert((cnt > 0) && ((unsigned int)cnt < (MAX_NAME_LEN + 1U)));
Soby Mathewb4c6df42022-11-09 11:13:29 +0000102
AlexeiFedorov56e1a8e2023-09-01 17:06:13 +0100103 (void)memset((void *)((uintptr_t)buf + (unsigned int)cnt), (int)' ',
104 MAX_NAME_LEN - (size_t)cnt);
AlexeiFedorov6c119692023-04-21 12:31:15 +0100105
AlexeiFedorov56e1a8e2023-09-01 17:06:13 +0100106 buf = (char *)((uintptr_t)buf + MAX_NAME_LEN);
AlexeiFedorov6c119692023-04-21 12:31:15 +0100107 len -= MAX_NAME_LEN;
108
109 /* Arguments */
110 for (unsigned int i = 0U; i < num; i++) {
111 cnt = snprintf(buf, len, " %lx", args[i]);
112 assert((cnt > 0) && (cnt < (int)len));
AlexeiFedorov56e1a8e2023-09-01 17:06:13 +0100113 buf = (char *)((uintptr_t)buf + (unsigned int)cnt);
AlexeiFedorov6c119692023-04-21 12:31:15 +0100114 len -= (size_t)cnt;
115 }
116
117 return len;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000118}
119
120static int print_status(char *buf, size_t len, unsigned long res)
121{
122 return_code_t rc = unpack_return_code(res);
123
124 if ((unsigned long)rc.status >= RSI_ERROR_COUNT) {
AlexeiFedorov6c119692023-04-21 12:31:15 +0100125 return snprintf(buf, len, " > %lx", res);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000126 }
127
AlexeiFedorov6c119692023-04-21 12:31:15 +0100128 return snprintf(buf, len, " > RSI_%s",
129 rsi_status_string[rc.status]);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000130}
131
132static int print_code(char *buf, size_t len, unsigned long res)
133{
AlexeiFedorov6c119692023-04-21 12:31:15 +0100134 return snprintf(buf, len, " > %lx", res);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000135}
136
AlexeiFedorov6c119692023-04-21 12:31:15 +0100137void rsi_log_on_exit(unsigned int function_id, unsigned long args[],
138 unsigned long regs[], bool exit_to_rec)
Soby Mathewb4c6df42022-11-09 11:13:29 +0000139{
140 char buffer[BUFFER_SIZE];
AlexeiFedorov6c119692023-04-21 12:31:15 +0100141 size_t len = print_entry(function_id, args, buffer, sizeof(buffer));
Soby Mathewb4c6df42022-11-09 11:13:29 +0000142
143 /* Print result when execution continues in REC */
144 if (exit_to_rec) {
AlexeiFedorov56e1a8e2023-09-01 17:06:13 +0100145 char *buf = (char *)((uintptr_t)buffer + sizeof(buffer) - len);
AlexeiFedorov6c119692023-04-21 12:31:15 +0100146 unsigned int num = 3U; /* results in X1-X3 */
147 int cnt;
148
149 switch (function_id) {
150 case SMC_RSI_MEASUREMENT_READ ... SMC_RSI_HOST_CALL: {
AlexeiFedorov56e1a8e2023-09-01 17:06:13 +0100151 const struct rsi_handler *logger =
AlexeiFedorov6c119692023-04-21 12:31:15 +0100152 fid_to_rsi_logger(function_id);
153
Soby Mathewb4c6df42022-11-09 11:13:29 +0000154 /* Print status */
AlexeiFedorov6c119692023-04-21 12:31:15 +0100155 cnt = print_status(buf, len, regs[0]);
156 num = logger->num_vals;
157 break;
158 }
159 case SMC_RSI_ABI_VERSION:
160 num = 0U;
161 FALLTHROUGH;
162 default:
Soby Mathewb4c6df42022-11-09 11:13:29 +0000163 /* Print result code */
AlexeiFedorov6c119692023-04-21 12:31:15 +0100164 cnt = print_code(buf, len, regs[0]);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000165 }
166
AlexeiFedorov6c119692023-04-21 12:31:15 +0100167 assert((cnt > 0) && (cnt < (int)len));
168
169 /* Print output values */
170 for (unsigned int i = 1U; i <= num; i++) {
AlexeiFedorov7e673322023-09-12 18:11:45 +0100171 buf = (char *)((uintptr_t)buf + (unsigned int)cnt);
AlexeiFedorov6c119692023-04-21 12:31:15 +0100172 len -= (size_t)cnt;
173 cnt = snprintf(buf, len, " %lx", regs[i]);
174 assert((cnt > 0) && (cnt < (int)len));
175 }
Soby Mathewb4c6df42022-11-09 11:13:29 +0000176 }
177
178 rmm_log("%s\n", buffer);
179}