nabkah01 | 002e569 | 2022-10-10 12:36:46 +0100 | [diff] [blame] | 1 | |
| 2 | /* |
Arunachalam Ganapathy | 51135c8 | 2025-01-27 11:17:32 +0000 | [diff] [blame] | 3 | * Copyright (c) 2022-2025, Arm Limited. All rights reserved. |
nabkah01 | 002e569 | 2022-10-10 12:36:46 +0100 | [diff] [blame] | 4 | * |
| 5 | * SPDX-License-Identifier: BSD-3-Clause |
| 6 | * |
| 7 | */ |
| 8 | |
| 9 | #include <host_realm_rmi.h> |
| 10 | #include <lib/aarch64/arch_features.h> |
Shruti Gupta | 9110508 | 2024-11-27 05:29:55 +0000 | [diff] [blame] | 11 | #include <realm_helpers.h> |
nabkah01 | 002e569 | 2022-10-10 12:36:46 +0100 | [diff] [blame] | 12 | #include <realm_rsi.h> |
| 13 | #include <smccc.h> |
| 14 | |
nabkah01 | 002e569 | 2022-10-10 12:36:46 +0100 | [diff] [blame] | 15 | /* This function return RSI_ABI_VERSION */ |
Shruti Gupta | 40de8ec | 2023-10-12 21:45:12 +0100 | [diff] [blame] | 16 | u_register_t rsi_get_version(u_register_t req_ver) |
nabkah01 | 002e569 | 2022-10-10 12:36:46 +0100 | [diff] [blame] | 17 | { |
| 18 | smc_ret_values res = {}; |
| 19 | |
| 20 | res = tftf_smc(&(smc_args) |
Arunachalam Ganapathy | 51135c8 | 2025-01-27 11:17:32 +0000 | [diff] [blame] | 21 | {SMC_RSI_VERSION, req_ver, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL}); |
nabkah01 | 002e569 | 2022-10-10 12:36:46 +0100 | [diff] [blame] | 22 | |
Shruti Gupta | 40de8ec | 2023-10-12 21:45:12 +0100 | [diff] [blame] | 23 | if (res.ret0 == SMC_UNKNOWN) { |
| 24 | return SMC_UNKNOWN; |
| 25 | } |
Shruti Gupta | 5abab76 | 2024-11-27 04:57:53 +0000 | [diff] [blame] | 26 | |
| 27 | if (res.ret0 == RSI_ERROR_STATE) { |
| 28 | return RSI_ERROR_STATE; |
| 29 | } |
| 30 | |
AlexeiFedorov | 9a60ecb | 2024-08-06 16:39:00 +0100 | [diff] [blame] | 31 | /* Return lower version */ |
Shruti Gupta | 40de8ec | 2023-10-12 21:45:12 +0100 | [diff] [blame] | 32 | return res.ret1; |
nabkah01 | 002e569 | 2022-10-10 12:36:46 +0100 | [diff] [blame] | 33 | } |
| 34 | |
Arunachalam Ganapathy | c58e469 | 2025-01-28 12:28:59 +0000 | [diff] [blame^] | 35 | /* This function returns RSI feature register at 'feature_reg_index' */ |
| 36 | u_register_t rsi_features(u_register_t feature_reg_index, |
| 37 | u_register_t *feature_reg_value_ret) |
| 38 | { |
| 39 | smc_ret_values res = {}; |
| 40 | |
| 41 | res = tftf_smc(&(smc_args) {SMC_RSI_FEATURES, feature_reg_index, |
| 42 | 0UL, 0UL, 0UL, 0UL, 0UL, 0UL}); |
| 43 | /* This command always returns RSI_SUCCESS */ |
| 44 | if (res.ret0 == RSI_SUCCESS) { |
| 45 | *feature_reg_value_ret = res.ret1; |
| 46 | } |
| 47 | |
| 48 | return res.ret0; |
| 49 | } |
| 50 | |
nabkah01 | 002e569 | 2022-10-10 12:36:46 +0100 | [diff] [blame] | 51 | /* This function call Host and request to exit Realm with proper exit code */ |
Shruti Gupta | 9110508 | 2024-11-27 05:29:55 +0000 | [diff] [blame] | 52 | u_register_t rsi_exit_to_host(enum host_call_cmd exit_code) |
nabkah01 | 002e569 | 2022-10-10 12:36:46 +0100 | [diff] [blame] | 53 | { |
Shruti Gupta | 43a50c3 | 2023-11-28 10:54:27 +0000 | [diff] [blame] | 54 | struct rsi_host_call host_cal __aligned(sizeof(struct rsi_host_call)); |
Shruti Gupta | 9110508 | 2024-11-27 05:29:55 +0000 | [diff] [blame] | 55 | smc_ret_values res = {}; |
Shruti Gupta | 43a50c3 | 2023-11-28 10:54:27 +0000 | [diff] [blame] | 56 | |
nabkah01 | 002e569 | 2022-10-10 12:36:46 +0100 | [diff] [blame] | 57 | host_cal.imm = exit_code; |
Shruti Gupta | 9110508 | 2024-11-27 05:29:55 +0000 | [diff] [blame] | 58 | host_cal.gprs[0] = realm_get_my_plane_num(); |
| 59 | host_cal.gprs[1] = read_mpidr_el1(); |
Arunachalam Ganapathy | 51135c8 | 2025-01-27 11:17:32 +0000 | [diff] [blame] | 60 | res = tftf_smc(&(smc_args) {SMC_RSI_HOST_CALL, (u_register_t)&host_cal, |
nabkah01 | 002e569 | 2022-10-10 12:36:46 +0100 | [diff] [blame] | 61 | 0UL, 0UL, 0UL, 0UL, 0UL, 0UL}); |
Shruti Gupta | 9110508 | 2024-11-27 05:29:55 +0000 | [diff] [blame] | 62 | return res.ret0; |
nabkah01 | 002e569 | 2022-10-10 12:36:46 +0100 | [diff] [blame] | 63 | } |
Shruti Gupta | bb77219 | 2023-10-09 16:08:28 +0100 | [diff] [blame] | 64 | |
| 65 | /* This function will exit to the Host to request RIPAS CHANGE of IPA range */ |
| 66 | u_register_t rsi_ipa_state_set(u_register_t base, |
| 67 | u_register_t top, |
| 68 | rsi_ripas_type ripas, |
| 69 | u_register_t flag, |
| 70 | u_register_t *new_base, |
| 71 | rsi_ripas_respose_type *response) |
| 72 | { |
| 73 | smc_ret_values res = {}; |
| 74 | |
| 75 | res = tftf_smc(&(smc_args) |
Arunachalam Ganapathy | 51135c8 | 2025-01-27 11:17:32 +0000 | [diff] [blame] | 76 | {SMC_RSI_IPA_STATE_SET, base, top, ripas, flag}); |
Shruti Gupta | bb77219 | 2023-10-09 16:08:28 +0100 | [diff] [blame] | 77 | if (res.ret0 == RSI_SUCCESS) { |
| 78 | *new_base = res.ret1; |
| 79 | *response = res.ret2; |
| 80 | } |
| 81 | return res.ret0; |
| 82 | } |
| 83 | |
AlexeiFedorov | 9a60ecb | 2024-08-06 16:39:00 +0100 | [diff] [blame] | 84 | /* This function will return RIPAS of IPA range */ |
| 85 | u_register_t rsi_ipa_state_get(u_register_t base, |
| 86 | u_register_t top, |
| 87 | u_register_t *out_top, |
| 88 | rsi_ripas_type *ripas) |
Shruti Gupta | bb77219 | 2023-10-09 16:08:28 +0100 | [diff] [blame] | 89 | { |
| 90 | smc_ret_values res = {}; |
| 91 | |
| 92 | res = tftf_smc(&(smc_args) |
Arunachalam Ganapathy | 51135c8 | 2025-01-27 11:17:32 +0000 | [diff] [blame] | 93 | {SMC_RSI_IPA_STATE_GET, base, top}); |
Shruti Gupta | bb77219 | 2023-10-09 16:08:28 +0100 | [diff] [blame] | 94 | if (res.ret0 == RSI_SUCCESS) { |
AlexeiFedorov | 9a60ecb | 2024-08-06 16:39:00 +0100 | [diff] [blame] | 95 | *out_top = res.ret1; |
| 96 | *ripas = res.ret2; |
Shruti Gupta | bb77219 | 2023-10-09 16:08:28 +0100 | [diff] [blame] | 97 | } |
| 98 | return res.ret0; |
| 99 | } |
Juan Pablo Conde | 88ffad2 | 2024-10-11 21:22:29 -0500 | [diff] [blame] | 100 | |
| 101 | /* This function will initialize the attestation context */ |
| 102 | u_register_t rsi_attest_token_init(u_register_t challenge_0, |
| 103 | u_register_t challenge_1, |
| 104 | u_register_t challenge_2, |
| 105 | u_register_t challenge_3, |
| 106 | u_register_t challenge_4, |
| 107 | u_register_t challenge_5, |
| 108 | u_register_t challenge_6, |
| 109 | u_register_t challenge_7, |
| 110 | u_register_t *out_token_upper_bound) |
| 111 | { |
| 112 | smc_ret_values_ext res = {}; |
| 113 | |
| 114 | tftf_smc_no_retval_x8(&(smc_args_ext) { |
Arunachalam Ganapathy | 51135c8 | 2025-01-27 11:17:32 +0000 | [diff] [blame] | 115 | SMC_RSI_ATTEST_TOKEN_INIT, |
Juan Pablo Conde | 88ffad2 | 2024-10-11 21:22:29 -0500 | [diff] [blame] | 116 | challenge_0, |
| 117 | challenge_1, |
| 118 | challenge_2, |
| 119 | challenge_3, |
| 120 | challenge_4, |
| 121 | challenge_5, |
| 122 | challenge_6, |
| 123 | challenge_7 |
| 124 | }, |
| 125 | &res); |
| 126 | |
| 127 | if (res.ret0 == RSI_SUCCESS) { |
| 128 | *out_token_upper_bound = res.ret1; |
| 129 | } |
| 130 | |
| 131 | return res.ret0; |
| 132 | } |
| 133 | |
| 134 | /* This function will retrieve the (or part of) attestation token */ |
| 135 | u_register_t rsi_attest_token_continue(u_register_t buffer_addr, |
| 136 | u_register_t offset, |
| 137 | u_register_t buffer_size, |
| 138 | u_register_t *bytes_copied) |
| 139 | { |
| 140 | smc_ret_values res = {}; |
| 141 | |
| 142 | res = tftf_smc(&(smc_args) { |
Arunachalam Ganapathy | 51135c8 | 2025-01-27 11:17:32 +0000 | [diff] [blame] | 143 | SMC_RSI_ATTEST_TOKEN_CONTINUE, |
Juan Pablo Conde | 88ffad2 | 2024-10-11 21:22:29 -0500 | [diff] [blame] | 144 | buffer_addr, |
| 145 | offset, |
| 146 | buffer_size |
| 147 | }); |
| 148 | |
| 149 | if ((res.ret0 == RSI_SUCCESS) || (res.ret0 == RSI_INCOMPLETE)) { |
| 150 | *bytes_copied = res.ret1; |
| 151 | } |
| 152 | return res.ret0; |
| 153 | } |
Shruti Gupta | 5abab76 | 2024-11-27 04:57:53 +0000 | [diff] [blame] | 154 | |
| 155 | u_register_t rsi_realm_config(struct rsi_realm_config *s) |
| 156 | { |
| 157 | smc_ret_values res = {}; |
| 158 | |
| 159 | res = tftf_smc(&(smc_args) |
Arunachalam Ganapathy | 51135c8 | 2025-01-27 11:17:32 +0000 | [diff] [blame] | 160 | {SMC_RSI_REALM_CONFIG, (u_register_t)s}); |
Shruti Gupta | 5abab76 | 2024-11-27 04:57:53 +0000 | [diff] [blame] | 161 | return res.ret0; |
| 162 | } |
| 163 | |
| 164 | u_register_t rsi_mem_get_perm_value(u_register_t plane_index, |
| 165 | u_register_t perm_index, |
| 166 | u_register_t *perm) |
| 167 | { |
| 168 | smc_ret_values res = {}; |
| 169 | |
| 170 | res = tftf_smc(&(smc_args) |
Arunachalam Ganapathy | 51135c8 | 2025-01-27 11:17:32 +0000 | [diff] [blame] | 171 | {SMC_RSI_MEM_GET_PERM_VALUE, plane_index, perm_index}); |
Shruti Gupta | 5abab76 | 2024-11-27 04:57:53 +0000 | [diff] [blame] | 172 | if (res.ret0 == RSI_SUCCESS) { |
| 173 | *perm = res.ret1; |
| 174 | } |
| 175 | return res.ret0; |
| 176 | } |
| 177 | |
| 178 | u_register_t rsi_mem_set_perm_value(u_register_t plane_index, |
| 179 | u_register_t perm_index, |
| 180 | u_register_t perm) |
| 181 | { |
| 182 | smc_ret_values res = {}; |
| 183 | |
| 184 | res = tftf_smc(&(smc_args) |
Arunachalam Ganapathy | 51135c8 | 2025-01-27 11:17:32 +0000 | [diff] [blame] | 185 | {SMC_RSI_MEM_SET_PERM_VALUE, plane_index, perm_index, |
| 186 | perm}); |
Shruti Gupta | 5abab76 | 2024-11-27 04:57:53 +0000 | [diff] [blame] | 187 | return res.ret0; |
| 188 | } |
| 189 | |
| 190 | u_register_t rsi_mem_set_perm_index(u_register_t base, |
| 191 | u_register_t top, |
| 192 | u_register_t perm_index, |
| 193 | u_register_t cookie, |
| 194 | u_register_t *new_base, |
| 195 | u_register_t *response, |
| 196 | u_register_t *new_cookie) |
| 197 | { |
| 198 | smc_ret_values res = {}; |
| 199 | |
| 200 | res = tftf_smc(&(smc_args) |
Arunachalam Ganapathy | 51135c8 | 2025-01-27 11:17:32 +0000 | [diff] [blame] | 201 | {SMC_RSI_MEM_SET_PERM_INDEX, base, top, perm_index, |
| 202 | cookie}); |
Shruti Gupta | 5abab76 | 2024-11-27 04:57:53 +0000 | [diff] [blame] | 203 | if (res.ret0 == RSI_SUCCESS) { |
| 204 | *new_base = res.ret1; |
| 205 | *response = res.ret2; |
| 206 | *new_cookie = res.ret3; |
| 207 | } |
| 208 | return res.ret0; |
| 209 | } |
| 210 | |
| 211 | u_register_t rsi_plane_enter(u_register_t plane_index, |
| 212 | u_register_t plane_run) |
| 213 | { |
| 214 | smc_ret_values res = {}; |
| 215 | |
| 216 | res = tftf_smc(&(smc_args) |
Arunachalam Ganapathy | 51135c8 | 2025-01-27 11:17:32 +0000 | [diff] [blame] | 217 | {SMC_RSI_PLANE_ENTER, plane_index, plane_run}); |
Shruti Gupta | 5abab76 | 2024-11-27 04:57:53 +0000 | [diff] [blame] | 218 | return res.ret0; |
| 219 | } |
Shruti Gupta | 4143468 | 2024-12-05 14:57:48 +0000 | [diff] [blame] | 220 | |
| 221 | u_register_t rsi_plane_reg_read(u_register_t plane_index, |
| 222 | u_register_t register_encoding, |
| 223 | u_register_t *value) |
| 224 | { |
| 225 | smc_ret_values res = {}; |
| 226 | |
| 227 | res = tftf_smc(&(smc_args) |
Arunachalam Ganapathy | 51135c8 | 2025-01-27 11:17:32 +0000 | [diff] [blame] | 228 | {SMC_RSI_PLANE_REG_READ, plane_index, |
| 229 | register_encoding}); |
Shruti Gupta | 4143468 | 2024-12-05 14:57:48 +0000 | [diff] [blame] | 230 | if (res.ret0 == RSI_SUCCESS) { |
| 231 | *value = res.ret1; |
| 232 | } |
| 233 | return res.ret0; |
| 234 | } |
| 235 | |
| 236 | u_register_t rsi_plane_reg_write(u_register_t plane_index, |
| 237 | u_register_t register_encoding, |
| 238 | u_register_t value) |
| 239 | { |
| 240 | smc_ret_values res = {}; |
| 241 | |
| 242 | res = tftf_smc(&(smc_args) |
Arunachalam Ganapathy | 51135c8 | 2025-01-27 11:17:32 +0000 | [diff] [blame] | 243 | {SMC_RSI_PLANE_REG_WRITE, plane_index, |
| 244 | register_encoding, value}); |
Shruti Gupta | 4143468 | 2024-12-05 14:57:48 +0000 | [diff] [blame] | 245 | return res.ret0; |
| 246 | } |
Arunachalam Ganapathy | c58e469 | 2025-01-28 12:28:59 +0000 | [diff] [blame^] | 247 | |
| 248 | /* This function return instance ID of Realm device */ |
| 249 | u_register_t rsi_rdev_get_instance_id(u_register_t rdev_id, |
| 250 | u_register_t *rdev_inst_id) |
| 251 | { |
| 252 | smc_ret_values res = {}; |
| 253 | |
| 254 | res = tftf_smc(&(smc_args) |
| 255 | {SMC_RSI_RDEV_GET_INSTANCE_ID, rdev_id, 0UL, 0UL, 0UL, 0UL, |
| 256 | 0UL, 0UL}); |
| 257 | |
| 258 | if (res.ret0 == RSI_SUCCESS) { |
| 259 | *rdev_inst_id = res.ret1; |
| 260 | } |
| 261 | |
| 262 | return res.ret0; |
| 263 | } |
| 264 | |
| 265 | /* This function return state of the Realm device */ |
| 266 | u_register_t rsi_rdev_get_state(u_register_t rdev_id, u_register_t rdev_inst_id, |
| 267 | u_register_t *rdev_rsi_state) |
| 268 | { |
| 269 | smc_ret_values res = {}; |
| 270 | |
| 271 | res = tftf_smc(&(smc_args) |
| 272 | {SMC_RSI_RDEV_GET_STATE, rdev_id, rdev_inst_id, 0UL, 0UL, 0UL, |
| 273 | 0UL, 0UL}); |
| 274 | |
| 275 | if (res.ret0 == RSI_SUCCESS) { |
| 276 | *rdev_rsi_state = res.ret1; |
| 277 | } |
| 278 | |
| 279 | return res.ret0; |
| 280 | } |
| 281 | |
| 282 | /* This function triggers RDEV interruptible operation to get_measurements */ |
| 283 | u_register_t rsi_rdev_get_measurements(u_register_t rdev_id, |
| 284 | u_register_t rdev_inst_id, |
| 285 | u_register_t meas_params_ptr) |
| 286 | { |
| 287 | smc_ret_values res = {}; |
| 288 | |
| 289 | res = tftf_smc(&(smc_args) |
| 290 | {SMC_RSI_RDEV_GET_MEASUREMENTS, rdev_id, rdev_inst_id, |
| 291 | meas_params_ptr, 0UL, 0UL, 0UL, 0UL}); |
| 292 | |
| 293 | return res.ret0; |
| 294 | } |
| 295 | |
| 296 | /* This function triggers RDEV interruptible operation to get_measurements */ |
| 297 | u_register_t rsi_rdev_get_info(u_register_t rdev_id, u_register_t rdev_inst_id, |
| 298 | u_register_t rdev_info_ptr) |
| 299 | { |
| 300 | smc_ret_values res = {}; |
| 301 | |
| 302 | res = tftf_smc(&(smc_args) |
| 303 | {SMC_RSI_RDEV_GET_INFO, rdev_id, rdev_inst_id, |
| 304 | rdev_info_ptr, 0UL, 0UL, 0UL, 0UL}); |
| 305 | |
| 306 | return res.ret0; |
| 307 | } |
| 308 | |
| 309 | /* This function triggers RDEV interruptible operation to lock */ |
| 310 | u_register_t rsi_rdev_lock(u_register_t rdev_id, u_register_t rdev_inst_id) |
| 311 | { |
| 312 | smc_ret_values res = {}; |
| 313 | |
| 314 | res = tftf_smc(&(smc_args) |
| 315 | {SMC_RSI_RDEV_LOCK, rdev_id, rdev_inst_id, |
| 316 | 0UL, 0UL, 0UL, 0UL, 0UL}); |
| 317 | |
| 318 | return res.ret0; |
| 319 | } |
| 320 | |
| 321 | /* This function triggers RDEV interruptible operation to get interface report */ |
| 322 | u_register_t rsi_rdev_get_interface_report(u_register_t rdev_id, |
| 323 | u_register_t rdev_inst_id, |
| 324 | u_register_t tdisp_version_max) |
| 325 | { |
| 326 | smc_ret_values res = {}; |
| 327 | |
| 328 | res = tftf_smc(&(smc_args) |
| 329 | {SMC_RSI_RDEV_GET_INTERFACE_REPORT, rdev_id, rdev_inst_id, |
| 330 | tdisp_version_max, 0UL, 0UL, 0UL, 0UL}); |
| 331 | |
| 332 | return res.ret0; |
| 333 | } |
| 334 | |
| 335 | /* This function triggers RDEV interruptible operation to start */ |
| 336 | u_register_t rsi_rdev_start(u_register_t rdev_id, u_register_t rdev_inst_id) |
| 337 | { |
| 338 | smc_ret_values res = {}; |
| 339 | |
| 340 | res = tftf_smc(&(smc_args) |
| 341 | {SMC_RSI_RDEV_START, rdev_id, rdev_inst_id, |
| 342 | 0UL, 0UL, 0UL, 0UL, 0UL}); |
| 343 | |
| 344 | return res.ret0; |
| 345 | } |
| 346 | |
| 347 | /* This function triggers RDEV interruptible operation to stop the TDI */ |
| 348 | u_register_t rsi_rdev_stop(u_register_t rdev_id, u_register_t rdev_inst_id) |
| 349 | { |
| 350 | smc_ret_values res = {}; |
| 351 | |
| 352 | res = tftf_smc(&(smc_args) |
| 353 | {SMC_RSI_RDEV_STOP, rdev_id, rdev_inst_id, |
| 354 | 0UL, 0UL, 0UL, 0UL, 0UL}); |
| 355 | |
| 356 | return res.ret0; |
| 357 | } |
| 358 | |
| 359 | /* This function exits the REC to do vdev communicate */ |
| 360 | u_register_t rsi_rdev_continue(u_register_t rdev_id, u_register_t rdev_inst_id) |
| 361 | { |
| 362 | smc_ret_values res = {}; |
| 363 | |
| 364 | res = tftf_smc(&(smc_args) |
| 365 | {SMC_RSI_RDEV_CONTINUE, rdev_id, rdev_inst_id, 0UL, 0UL, |
| 366 | 0UL, 0UL, 0UL}); |
| 367 | |
| 368 | return res.ret0; |
| 369 | } |