blob: 5db269d2a0d2213a2f183ae945815a7b1a92ef0b [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)] = { \
Chuyue Luod7386682023-09-22 11:55:47 +010034 .fn_name = (#_id), \
35 .num_args = (_in), \
36 .num_vals = (_out) \
AlexeiFedorov6c119692023-04-21 12:31:15 +010037}
38
39static const struct rsi_handler rsi_logger[] = {
AlexeiFedorov1d9e9972023-09-15 14:59:57 +010040 RSI_FUNCTION(ABI_VERSION, 1U, 1U), /* 0xC4000190 */
41 RSI_FUNCTION(FEATURES, 1U, 1U), /* 0xC4000191 */
AlexeiFedorov6c119692023-04-21 12:31:15 +010042 RSI_FUNCTION(MEASUREMENT_READ, 1U, 8U), /* 0xC4000192 */
43 RSI_FUNCTION(MEASUREMENT_EXTEND, 10U, 0U), /* 0xC4000193 */
44 RSI_FUNCTION(ATTEST_TOKEN_INIT, 9U, 0U), /* 0xC4000194 */
45 RSI_FUNCTION(ATTEST_TOKEN_CONTINUE, 1U, 1U), /* 0xC4000195 */
46 RSI_FUNCTION(REALM_CONFIG, 1U, 0U), /* 0xC4000196 */
AlexeiFedorov9b29c6b2023-09-12 17:09:50 +010047 RSI_FUNCTION(IPA_STATE_SET, 4U, 2U), /* 0xC4000197 */
AlexeiFedorov6c119692023-04-21 12:31:15 +010048 RSI_FUNCTION(IPA_STATE_GET, 1U, 1U), /* 0xC4000198 */
49 RSI_FUNCTION(HOST_CALL, 1U, 0U) /* 0xC4000199 */
Soby Mathewb4c6df42022-11-09 11:13:29 +000050};
51
AlexeiFedorov6c119692023-04-21 12:31:15 +010052#define RSI_STATUS_STRING(_id)[RSI_##_id] = #_id
Soby Mathewb4c6df42022-11-09 11:13:29 +000053
AlexeiFedorov04418f42023-09-13 10:50:33 +010054static const char * const rsi_status_string[] = {
AlexeiFedorov6c119692023-04-21 12:31:15 +010055 RSI_STATUS_STRING(SUCCESS),
56 RSI_STATUS_STRING(ERROR_INPUT),
57 RSI_STATUS_STRING(ERROR_STATE),
58 RSI_STATUS_STRING(INCOMPLETE)
59};
60
61COMPILER_ASSERT(ARRAY_LEN(rsi_status_string) == RSI_ERROR_COUNT);
62
AlexeiFedorov56e1a8e2023-09-01 17:06:13 +010063static const struct rsi_handler *fid_to_rsi_logger(unsigned int id)
Soby Mathewb4c6df42022-11-09 11:13:29 +000064{
AlexeiFedorov56e1a8e2023-09-01 17:06:13 +010065 return &rsi_logger[id - SMC_RSI_ABI_VERSION];
AlexeiFedorov6c119692023-04-21 12:31:15 +010066}
67
68static size_t print_entry(unsigned int id, unsigned long args[],
69 char *buf, size_t len)
70{
71 unsigned int num = 7U; /* up to seven arguments */
72 int cnt;
Soby Mathewb4c6df42022-11-09 11:13:29 +000073
74 switch (id) {
AlexeiFedorov6c119692023-04-21 12:31:15 +010075 case SMC_RSI_ABI_VERSION ... SMC_RSI_HOST_CALL: {
AlexeiFedorov56e1a8e2023-09-01 17:06:13 +010076 const struct rsi_handler *logger = fid_to_rsi_logger(id);
Soby Mathewb4c6df42022-11-09 11:13:29 +000077
AlexeiFedorov6c119692023-04-21 12:31:15 +010078 num = logger->num_args;
AlexeiFedorov1d9e9972023-09-15 14:59:57 +010079 cnt = snprintf(buf, MAX_NAME_LEN + 1UL,
AlexeiFedorov6c119692023-04-21 12:31:15 +010080 "%s%s", "SMC_RSI_", logger->fn_name);
Soby Mathewb4c6df42022-11-09 11:13:29 +000081 break;
AlexeiFedorov6c119692023-04-21 12:31:15 +010082 }
Soby Mathewb4c6df42022-11-09 11:13:29 +000083 /* SMC32 PSCI calls */
84 case SMC32_PSCI_FID_MIN ... SMC32_PSCI_FID_MAX:
85 FALLTHROUGH;
86 case SMC64_PSCI_FID_MIN ... SMC64_PSCI_FID_MAX:
AlexeiFedorov6c119692023-04-21 12:31:15 +010087 cnt = snprintf(buf, MAX_NAME_LEN + 1UL, "%s%08x", "PSCI_", id);
Soby Mathewb4c6df42022-11-09 11:13:29 +000088 break;
89
90 /* Other SMC calls */
91 default:
AlexeiFedorov6c119692023-04-21 12:31:15 +010092 cnt = snprintf(buf, MAX_NAME_LEN + 1UL, "%s%08x", "SMC_", id);
Soby Mathewb4c6df42022-11-09 11:13:29 +000093 break;
94 }
95
AlexeiFedorov56e1a8e2023-09-01 17:06:13 +010096 assert((cnt > 0) && ((unsigned int)cnt < (MAX_NAME_LEN + 1U)));
Soby Mathewb4c6df42022-11-09 11:13:29 +000097
Chuyue Luo85834402023-09-25 10:27:08 +010098 (void)memset((void *)((uintptr_t)buf + (unsigned int)cnt), ' ',
AlexeiFedorov56e1a8e2023-09-01 17:06:13 +010099 MAX_NAME_LEN - (size_t)cnt);
AlexeiFedorov6c119692023-04-21 12:31:15 +0100100
AlexeiFedorov56e1a8e2023-09-01 17:06:13 +0100101 buf = (char *)((uintptr_t)buf + MAX_NAME_LEN);
AlexeiFedorov6c119692023-04-21 12:31:15 +0100102 len -= MAX_NAME_LEN;
103
104 /* Arguments */
105 for (unsigned int i = 0U; i < num; i++) {
106 cnt = snprintf(buf, len, " %lx", args[i]);
107 assert((cnt > 0) && (cnt < (int)len));
AlexeiFedorov56e1a8e2023-09-01 17:06:13 +0100108 buf = (char *)((uintptr_t)buf + (unsigned int)cnt);
AlexeiFedorov6c119692023-04-21 12:31:15 +0100109 len -= (size_t)cnt;
110 }
111
112 return len;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000113}
114
115static int print_status(char *buf, size_t len, unsigned long res)
116{
117 return_code_t rc = unpack_return_code(res);
118
119 if ((unsigned long)rc.status >= RSI_ERROR_COUNT) {
AlexeiFedorov6c119692023-04-21 12:31:15 +0100120 return snprintf(buf, len, " > %lx", res);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000121 }
122
AlexeiFedorov6c119692023-04-21 12:31:15 +0100123 return snprintf(buf, len, " > RSI_%s",
124 rsi_status_string[rc.status]);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000125}
126
127static int print_code(char *buf, size_t len, unsigned long res)
128{
AlexeiFedorov6c119692023-04-21 12:31:15 +0100129 return snprintf(buf, len, " > %lx", res);
Soby Mathewb4c6df42022-11-09 11:13:29 +0000130}
131
AlexeiFedorov6c119692023-04-21 12:31:15 +0100132void rsi_log_on_exit(unsigned int function_id, unsigned long args[],
AlexeiFedorov29ad2bd2023-09-13 09:43:49 +0100133 unsigned long regs[])
Soby Mathewb4c6df42022-11-09 11:13:29 +0000134{
135 char buffer[BUFFER_SIZE];
AlexeiFedorov6c119692023-04-21 12:31:15 +0100136 size_t len = print_entry(function_id, args, buffer, sizeof(buffer));
AlexeiFedorov29ad2bd2023-09-13 09:43:49 +0100137 char *buf = (char *)((uintptr_t)buffer + sizeof(buffer) - len);
138 unsigned int num = 3U; /* results in X1-X3 */
139 int cnt;
Soby Mathewb4c6df42022-11-09 11:13:29 +0000140
AlexeiFedorov29ad2bd2023-09-13 09:43:49 +0100141 switch (function_id) {
AlexeiFedorov1d9e9972023-09-15 14:59:57 +0100142 case SMC_RSI_ABI_VERSION ... SMC_RSI_HOST_CALL: {
AlexeiFedorov29ad2bd2023-09-13 09:43:49 +0100143 const struct rsi_handler *logger =
144 fid_to_rsi_logger(function_id);
AlexeiFedorov6c119692023-04-21 12:31:15 +0100145
AlexeiFedorov29ad2bd2023-09-13 09:43:49 +0100146 /* Print status */
147 cnt = print_status(buf, len, regs[0]);
148 num = logger->num_vals;
149 break;
150 }
AlexeiFedorov29ad2bd2023-09-13 09:43:49 +0100151 default:
152 /* Print result code */
153 cnt = print_code(buf, len, regs[0]);
154 }
AlexeiFedorov6c119692023-04-21 12:31:15 +0100155
AlexeiFedorov29ad2bd2023-09-13 09:43:49 +0100156 assert((cnt > 0) && (cnt < (int)len));
Soby Mathewb4c6df42022-11-09 11:13:29 +0000157
AlexeiFedorov29ad2bd2023-09-13 09:43:49 +0100158 /* Print output values */
159 for (unsigned int i = 1U; i <= num; i++) {
160 buf = (char *)((uintptr_t)buf + (unsigned int)cnt);
161 len -= (size_t)cnt;
162 cnt = snprintf(buf, len, " %lx", regs[i]);
AlexeiFedorov6c119692023-04-21 12:31:15 +0100163 assert((cnt > 0) && (cnt < (int)len));
Soby Mathewb4c6df42022-11-09 11:13:29 +0000164 }
165
166 rmm_log("%s\n", buffer);
167}