1 /*
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>
11 #include <utils_def.h>
12
13 /* RMI handler uses 29 chars for function name */
14 #define MAX_NAME_LEN 29U
15
16 /* 5 64-bit parameters separated by space + 1 trailing space */
17 #define PARAMS_STR_LEN (5U * sizeof("0123456789ABCDEF") + 1U)
18
19 #define MAX_STATUS_LEN sizeof("{RSI_ERROR_INPUT}")
20
21 #define BUFFER_SIZE (MAX_NAME_LEN + PARAMS_STR_LEN + \
22 sizeof("> ") - 1U + \
23 MAX_STATUS_LEN)
24
25 #define RSI_FUNCTION(id) \
26 [SMC_RSI_##id - SMC_RSI_ABI_VERSION] = #id
27
28 static const char *rsi_logger[] = {
29 RSI_FUNCTION(ABI_VERSION), /* 0xC4000190 */
30 RSI_FUNCTION(MEASUREMENT_READ), /* 0xC4000192 */
31 RSI_FUNCTION(MEASUREMENT_EXTEND), /* 0xC4000193 */
32 RSI_FUNCTION(ATTEST_TOKEN_INIT), /* 0xC4000194 */
33 RSI_FUNCTION(ATTEST_TOKEN_CONTINUE), /* 0xC4000195 */
34 RSI_FUNCTION(REALM_CONFIG), /* 0xC4000196 */
35 RSI_FUNCTION(IPA_STATE_SET), /* 0xC4000197 */
36 RSI_FUNCTION(IPA_STATE_GET), /* 0xC4000198 */
37 RSI_FUNCTION(HOST_CALL) /* 0xC4000199 */
38 };
39
40 #define RSI_STATUS_HANDLER(id)[id] = #id
41
42 const char *rsi_status_handler[] = {
43 RSI_STATUS_HANDLER(RSI_SUCCESS),
44 RSI_STATUS_HANDLER(RSI_ERROR_INPUT),
45 RSI_STATUS_HANDLER(RSI_ERROR_STATE),
46 RSI_STATUS_HANDLER(RSI_INCOMPLETE)
47 };
48
49 COMPILER_ASSERT(ARRAY_LEN(rsi_status_handler) == RSI_ERROR_COUNT);
50
print_entry(unsigned int id,unsigned long args[5],char * buf,size_t len)51 static int print_entry(unsigned int id, unsigned long args[5],
52 char *buf, size_t len)
53 {
54 char name[sizeof("SMC_RSI_ATTEST_TOKEN_CONTINUE")];
55 int cnt __unused;
56
57 switch (id) {
58 case SMC_RSI_ABI_VERSION ... SMC_RSI_HOST_CALL:
59
60 if (rsi_logger[id - SMC_RSI_ABI_VERSION] != NULL) {
61 cnt = snprintf(name, sizeof(name), "%s%s", "SMC_RSI_",
62 rsi_logger[id - SMC_RSI_ABI_VERSION]);
63 } else {
64 /* Handle gaps in RSI commands numbering */
65 cnt = snprintf(name, sizeof(name), "%s%08x", "SMC_RSI_", id);
66 }
67
68 break;
69
70 /* SMC32 PSCI calls */
71 case SMC32_PSCI_FID_MIN ... SMC32_PSCI_FID_MAX:
72 FALLTHROUGH;
73 case SMC64_PSCI_FID_MIN ... SMC64_PSCI_FID_MAX:
74 cnt = snprintf(name, sizeof(name), "%s%08x", "PSCI_", id);
75 break;
76
77 /* Other SMC calls */
78 default:
79 cnt = snprintf(name, sizeof(name), "%s%08x", "SMC_", id);
80 break;
81 }
82
83 assert((cnt > 0) && (cnt < sizeof(name)));
84
85 return snprintf(buf, len, "%-29s %8lx %8lx %8lx %8lx %8lx ",
86 name, args[0], args[1], args[2], args[3], args[4]);
87 }
88
print_status(char * buf,size_t len,unsigned long res)89 static int print_status(char *buf, size_t len, unsigned long res)
90 {
91 return_code_t rc = unpack_return_code(res);
92
93 if ((unsigned long)rc.status >= RSI_ERROR_COUNT) {
94 return snprintf(buf, len, "> %lx", res);
95 }
96
97 return snprintf(buf, len, "> %s",
98 rsi_status_handler[rc.status]);
99 }
100
print_code(char * buf,size_t len,unsigned long res)101 static int print_code(char *buf, size_t len, unsigned long res)
102 {
103 return snprintf(buf, len, "> %lx", res);
104 }
105
rsi_log_on_exit(unsigned int function_id,unsigned long args[5],unsigned long res,bool exit_to_rec)106 void rsi_log_on_exit(unsigned int function_id, unsigned long args[5],
107 unsigned long res, bool exit_to_rec)
108 {
109 char buffer[BUFFER_SIZE];
110 char *buf_ptr = buffer;
111 size_t buf_len = sizeof(buffer);
112 int cnt = print_entry(function_id, args, buf_ptr, buf_len);
113
114 assert((cnt > 0) && (cnt < buf_len));
115
116 buf_ptr += cnt;
117 buf_len -= cnt;
118
119 /* Print result when execution continues in REC */
120 if (exit_to_rec) {
121 if ((function_id >= SMC_RSI_MEASUREMENT_READ) &&
122 (function_id <= SMC_RSI_HOST_CALL)) {
123 /* Print status */
124 cnt = print_status(buf_ptr, buf_len, res);
125 } else {
126 /* Print result code */
127 cnt = print_code(buf_ptr, buf_len, res);
128 }
129
130 assert((cnt > 0) && (cnt < buf_len));
131 }
132
133 rmm_log("%s\n", buffer);
134 }
135