1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2019-2021 Linaro Ltd. 4 */ 5 6 #include <linux/io.h> 7 #include <linux/of.h> 8 #include <linux/of_address.h> 9 #include <linux/kernel.h> 10 #include <linux/module.h> 11 #include <linux/mutex.h> 12 #include <linux/platform_device.h> 13 #include <linux/slab.h> 14 #include <linux/tee_drv.h> 15 #include <linux/uuid.h> 16 #include <uapi/linux/tee.h> 17 18 #include "../common.h" 19 20 enum scmi_optee_pta_cmd { 21 /* 22 * PTA_SCMI_CMD_CAPABILITIES - Get channel capabilities 23 * 24 * [out] value[0].a: Capability bit mask (enum pta_scmi_caps) 25 * [out] value[0].b: Extended capabilities or 0 26 */ 27 PTA_SCMI_CMD_CAPABILITIES = 0, 28 29 /* 30 * PTA_SCMI_CMD_PROCESS_SMT_CHANNEL - Process SCMI message in SMT buffer 31 * 32 * [in] value[0].a: Channel handle 33 * 34 * Shared memory used for SCMI message/response exhange is expected 35 * already identified and bound to channel handle in both SCMI agent 36 * and SCMI server (OP-TEE) parts. 37 * The memory uses SMT header to carry SCMI meta-data (protocol ID and 38 * protocol message ID). 39 */ 40 PTA_SCMI_CMD_PROCESS_SMT_CHANNEL = 1, 41 42 /* 43 * PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE - Process SMT/SCMI message 44 * 45 * [in] value[0].a: Channel handle 46 * [in/out] memref[1]: Message/response buffer (SMT and SCMI payload) 47 * 48 * Shared memory used for SCMI message/response is a SMT buffer 49 * referenced by param[1]. It shall be 128 bytes large to fit response 50 * payload whatever message playload size. 51 * The memory uses SMT header to carry SCMI meta-data (protocol ID and 52 * protocol message ID). 53 */ 54 PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE = 2, 55 56 /* 57 * PTA_SCMI_CMD_GET_CHANNEL - Get channel handle 58 * 59 * SCMI shm information are 0 if agent expects to use OP-TEE regular SHM 60 * 61 * [in] value[0].a: Channel identifier 62 * [out] value[0].a: Returned channel handle 63 * [in] value[0].b: Requested capabilities mask (enum pta_scmi_caps) 64 */ 65 PTA_SCMI_CMD_GET_CHANNEL = 3, 66 67 /* 68 * PTA_SCMI_CMD_PROCESS_MSG_CHANNEL - Process SCMI message in a MSG 69 * buffer pointed by memref parameters 70 * 71 * [in] value[0].a: Channel handle 72 * [in] memref[1]: Message buffer (MSG and SCMI payload) 73 * [out] memref[2]: Response buffer (MSG and SCMI payload) 74 * 75 * Shared memories used for SCMI message/response are MSG buffers 76 * referenced by param[1] and param[2]. MSG transport protocol 77 * uses a 32bit header to carry SCMI meta-data (protocol ID and 78 * protocol message ID) followed by the effective SCMI message 79 * payload. 80 */ 81 PTA_SCMI_CMD_PROCESS_MSG_CHANNEL = 4, 82 }; 83 84 /* 85 * OP-TEE SCMI service capabilities bit flags (32bit) 86 * 87 * PTA_SCMI_CAPS_SMT_HEADER 88 * When set, OP-TEE supports command using SMT header protocol (SCMI shmem) in 89 * shared memory buffers to carry SCMI protocol synchronisation information. 90 * 91 * PTA_SCMI_CAPS_MSG_HEADER 92 * When set, OP-TEE supports command using MSG header protocol in an OP-TEE 93 * shared memory to carry SCMI protocol synchronisation information and SCMI 94 * message payload. 95 */ 96 #define PTA_SCMI_CAPS_NONE 0 97 #define PTA_SCMI_CAPS_SMT_HEADER BIT(0) 98 #define PTA_SCMI_CAPS_MSG_HEADER BIT(1) 99 #define PTA_SCMI_CAPS_MASK (PTA_SCMI_CAPS_SMT_HEADER | \ 100 PTA_SCMI_CAPS_MSG_HEADER) 101 102 /** 103 * struct scmi_optee_channel - Description of an OP-TEE SCMI channel 104 * 105 * @channel_id: OP-TEE channel ID used for this transport 106 * @tee_session: TEE session identifier 107 * @caps: OP-TEE SCMI channel capabilities 108 * @rx_len: Response size 109 * @mu: Mutex protection on channel access 110 * @cinfo: SCMI channel information 111 * @req: union for SCMI interface 112 * @req.shmem: Virtual base address of the shared memory 113 * @req.msg: Shared memory protocol handle for SCMI request and 114 * synchronous response 115 * @io_ops: Transport specific I/O operations 116 * @tee_shm: TEE shared memory handle @req or NULL if using IOMEM shmem 117 * @link: Reference in agent's channel list 118 */ 119 struct scmi_optee_channel { 120 u32 channel_id; 121 u32 tee_session; 122 u32 caps; 123 u32 rx_len; 124 struct mutex mu; 125 struct scmi_chan_info *cinfo; 126 union { 127 struct scmi_shared_mem __iomem *shmem; 128 struct scmi_msg_payld *msg; 129 } req; 130 struct scmi_shmem_io_ops *io_ops; 131 struct tee_shm *tee_shm; 132 struct list_head link; 133 }; 134 135 /** 136 * struct scmi_optee_agent - OP-TEE transport private data 137 * 138 * @dev: Device used for communication with TEE 139 * @tee_ctx: TEE context used for communication 140 * @caps: Supported channel capabilities 141 * @mu: Mutex for protection of @channel_list 142 * @channel_list: List of all created channels for the agent 143 */ 144 struct scmi_optee_agent { 145 struct device *dev; 146 struct tee_context *tee_ctx; 147 u32 caps; 148 struct mutex mu; 149 struct list_head channel_list; 150 }; 151 152 static struct scmi_transport_core_operations *core; 153 154 /* There can be only 1 SCMI service in OP-TEE we connect to */ 155 static struct scmi_optee_agent *scmi_optee_private; 156 157 /* Open a session toward SCMI OP-TEE service with REE_KERNEL identity */ 158 static int open_session(struct scmi_optee_agent *agent, u32 *tee_session) 159 { 160 struct device *dev = agent->dev; 161 struct tee_client_device *scmi_pta = to_tee_client_device(dev); 162 struct tee_ioctl_open_session_arg arg = { }; 163 int ret; 164 165 memcpy(arg.uuid, scmi_pta->id.uuid.b, TEE_IOCTL_UUID_LEN); 166 arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL; 167 168 ret = tee_client_open_session(agent->tee_ctx, &arg, NULL); 169 if (ret < 0 || arg.ret) { 170 dev_err(dev, "Can't open tee session: %d / %#x\n", ret, arg.ret); 171 return -EOPNOTSUPP; 172 } 173 174 *tee_session = arg.session; 175 176 return 0; 177 } 178 179 static void close_session(struct scmi_optee_agent *agent, u32 tee_session) 180 { 181 tee_client_close_session(agent->tee_ctx, tee_session); 182 } 183 184 static int get_capabilities(struct scmi_optee_agent *agent) 185 { 186 struct tee_ioctl_invoke_arg arg = { }; 187 struct tee_param param[1] = { }; 188 u32 caps; 189 u32 tee_session; 190 int ret; 191 192 ret = open_session(agent, &tee_session); 193 if (ret) 194 return ret; 195 196 arg.func = PTA_SCMI_CMD_CAPABILITIES; 197 arg.session = tee_session; 198 arg.num_params = 1; 199 200 param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT; 201 202 ret = tee_client_invoke_func(agent->tee_ctx, &arg, param); 203 204 close_session(agent, tee_session); 205 206 if (ret < 0 || arg.ret) { 207 dev_err(agent->dev, "Can't get capabilities: %d / %#x\n", ret, arg.ret); 208 return -EOPNOTSUPP; 209 } 210 211 caps = param[0].u.value.a; 212 213 if (!(caps & (PTA_SCMI_CAPS_SMT_HEADER | PTA_SCMI_CAPS_MSG_HEADER))) { 214 dev_err(agent->dev, "OP-TEE SCMI PTA doesn't support SMT and MSG\n"); 215 return -EOPNOTSUPP; 216 } 217 218 agent->caps = caps; 219 220 return 0; 221 } 222 223 static int get_channel(struct scmi_optee_channel *channel) 224 { 225 struct device *dev = scmi_optee_private->dev; 226 struct tee_ioctl_invoke_arg arg = { }; 227 struct tee_param param[1] = { }; 228 unsigned int caps = 0; 229 int ret; 230 231 if (channel->tee_shm) 232 caps = PTA_SCMI_CAPS_MSG_HEADER; 233 else 234 caps = PTA_SCMI_CAPS_SMT_HEADER; 235 236 arg.func = PTA_SCMI_CMD_GET_CHANNEL; 237 arg.session = channel->tee_session; 238 arg.num_params = 1; 239 240 param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT; 241 param[0].u.value.a = channel->channel_id; 242 param[0].u.value.b = caps; 243 244 ret = tee_client_invoke_func(scmi_optee_private->tee_ctx, &arg, param); 245 246 if (ret || arg.ret) { 247 dev_err(dev, "Can't get channel with caps %#x: %d / %#x\n", caps, ret, arg.ret); 248 return -EOPNOTSUPP; 249 } 250 251 /* From now on use channel identifer provided by OP-TEE SCMI service */ 252 channel->channel_id = param[0].u.value.a; 253 channel->caps = caps; 254 255 return 0; 256 } 257 258 static int invoke_process_smt_channel(struct scmi_optee_channel *channel) 259 { 260 struct tee_ioctl_invoke_arg arg = { 261 .func = PTA_SCMI_CMD_PROCESS_SMT_CHANNEL, 262 .session = channel->tee_session, 263 .num_params = 1, 264 }; 265 struct tee_param param[1] = { }; 266 int ret; 267 268 param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; 269 param[0].u.value.a = channel->channel_id; 270 271 ret = tee_client_invoke_func(scmi_optee_private->tee_ctx, &arg, param); 272 if (ret < 0 || arg.ret) { 273 dev_err(scmi_optee_private->dev, "Can't invoke channel %u: %d / %#x\n", 274 channel->channel_id, ret, arg.ret); 275 return -EIO; 276 } 277 278 return 0; 279 } 280 281 static int invoke_process_msg_channel(struct scmi_optee_channel *channel, size_t msg_size) 282 { 283 struct tee_ioctl_invoke_arg arg = { 284 .func = PTA_SCMI_CMD_PROCESS_MSG_CHANNEL, 285 .session = channel->tee_session, 286 .num_params = 3, 287 }; 288 struct tee_param param[3] = { }; 289 int ret; 290 291 param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; 292 param[0].u.value.a = channel->channel_id; 293 294 param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT; 295 param[1].u.memref.shm = channel->tee_shm; 296 param[1].u.memref.size = msg_size; 297 298 param[2].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT; 299 param[2].u.memref.shm = channel->tee_shm; 300 param[2].u.memref.size = SCMI_SHMEM_MAX_PAYLOAD_SIZE; 301 302 ret = tee_client_invoke_func(scmi_optee_private->tee_ctx, &arg, param); 303 if (ret < 0 || arg.ret) { 304 dev_err(scmi_optee_private->dev, "Can't invoke channel %u: %d / %#x\n", 305 channel->channel_id, ret, arg.ret); 306 return -EIO; 307 } 308 309 /* Save response size */ 310 channel->rx_len = param[2].u.memref.size; 311 312 return 0; 313 } 314 315 static bool scmi_optee_chan_available(struct device_node *of_node, int idx) 316 { 317 u32 channel_id; 318 319 return !of_property_read_u32_index(of_node, "linaro,optee-channel-id", 320 idx, &channel_id); 321 } 322 323 static void scmi_optee_clear_channel(struct scmi_chan_info *cinfo) 324 { 325 struct scmi_optee_channel *channel = cinfo->transport_info; 326 327 if (!channel->tee_shm) 328 core->shmem->clear_channel(channel->req.shmem); 329 } 330 331 static int setup_dynamic_shmem(struct device *dev, struct scmi_optee_channel *channel) 332 { 333 const size_t msg_size = SCMI_SHMEM_MAX_PAYLOAD_SIZE; 334 void *shbuf; 335 336 channel->tee_shm = tee_shm_alloc_kernel_buf(scmi_optee_private->tee_ctx, msg_size); 337 if (IS_ERR(channel->tee_shm)) { 338 dev_err(channel->cinfo->dev, "shmem allocation failed\n"); 339 return -ENOMEM; 340 } 341 342 shbuf = tee_shm_get_va(channel->tee_shm, 0); 343 memset(shbuf, 0, msg_size); 344 channel->req.msg = shbuf; 345 channel->rx_len = msg_size; 346 347 return 0; 348 } 349 350 static int setup_static_shmem(struct device *dev, struct scmi_chan_info *cinfo, 351 struct scmi_optee_channel *channel) 352 { 353 channel->req.shmem = core->shmem->setup_iomap(cinfo, dev, true, NULL, 354 &channel->io_ops); 355 if (IS_ERR(channel->req.shmem)) 356 return PTR_ERR(channel->req.shmem); 357 358 return 0; 359 } 360 361 static int setup_shmem(struct device *dev, struct scmi_chan_info *cinfo, 362 struct scmi_optee_channel *channel) 363 { 364 if (of_property_present(cinfo->dev->of_node, "shmem")) 365 return setup_static_shmem(dev, cinfo, channel); 366 else 367 return setup_dynamic_shmem(dev, channel); 368 } 369 370 static int scmi_optee_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, bool tx) 371 { 372 struct scmi_optee_channel *channel; 373 uint32_t channel_id; 374 int ret; 375 376 if (!tx) 377 return -ENODEV; 378 379 channel = devm_kzalloc(dev, sizeof(*channel), GFP_KERNEL); 380 if (!channel) 381 return -ENOMEM; 382 383 ret = of_property_read_u32_index(cinfo->dev->of_node, "linaro,optee-channel-id", 384 0, &channel_id); 385 if (ret) 386 return ret; 387 388 cinfo->transport_info = channel; 389 channel->cinfo = cinfo; 390 channel->channel_id = channel_id; 391 mutex_init(&channel->mu); 392 393 ret = setup_shmem(dev, cinfo, channel); 394 if (ret) 395 return ret; 396 397 ret = open_session(scmi_optee_private, &channel->tee_session); 398 if (ret) 399 goto err_free_shm; 400 401 ret = tee_client_system_session(scmi_optee_private->tee_ctx, channel->tee_session); 402 if (ret) 403 dev_warn(dev, "Could not switch to system session, do best effort\n"); 404 405 ret = get_channel(channel); 406 if (ret) 407 goto err_close_sess; 408 409 /* Enable polling */ 410 cinfo->no_completion_irq = true; 411 412 mutex_lock(&scmi_optee_private->mu); 413 list_add(&channel->link, &scmi_optee_private->channel_list); 414 mutex_unlock(&scmi_optee_private->mu); 415 416 return 0; 417 418 err_close_sess: 419 close_session(scmi_optee_private, channel->tee_session); 420 err_free_shm: 421 if (channel->tee_shm) 422 tee_shm_free(channel->tee_shm); 423 424 return ret; 425 } 426 427 static int scmi_optee_chan_free(int id, void *p, void *data) 428 { 429 struct scmi_chan_info *cinfo = p; 430 struct scmi_optee_channel *channel = cinfo->transport_info; 431 432 /* 433 * Different protocols might share the same chan info, so a previous 434 * call might have already freed the structure. 435 */ 436 if (!channel) 437 return 0; 438 439 mutex_lock(&scmi_optee_private->mu); 440 list_del(&channel->link); 441 mutex_unlock(&scmi_optee_private->mu); 442 443 close_session(scmi_optee_private, channel->tee_session); 444 445 if (channel->tee_shm) { 446 tee_shm_free(channel->tee_shm); 447 channel->tee_shm = NULL; 448 } 449 450 cinfo->transport_info = NULL; 451 channel->cinfo = NULL; 452 453 return 0; 454 } 455 456 static int scmi_optee_send_message(struct scmi_chan_info *cinfo, 457 struct scmi_xfer *xfer) 458 { 459 struct scmi_optee_channel *channel = cinfo->transport_info; 460 int ret; 461 462 mutex_lock(&channel->mu); 463 464 if (channel->tee_shm) { 465 core->msg->tx_prepare(channel->req.msg, xfer); 466 ret = invoke_process_msg_channel(channel, 467 core->msg->command_size(xfer)); 468 } else { 469 core->shmem->tx_prepare(channel->req.shmem, xfer, cinfo, 470 channel->io_ops->toio); 471 ret = invoke_process_smt_channel(channel); 472 } 473 474 if (ret) 475 mutex_unlock(&channel->mu); 476 477 return ret; 478 } 479 480 static void scmi_optee_fetch_response(struct scmi_chan_info *cinfo, 481 struct scmi_xfer *xfer) 482 { 483 struct scmi_optee_channel *channel = cinfo->transport_info; 484 485 if (channel->tee_shm) 486 core->msg->fetch_response(channel->req.msg, 487 channel->rx_len, xfer); 488 else 489 core->shmem->fetch_response(channel->req.shmem, xfer, 490 channel->io_ops->fromio); 491 } 492 493 static void scmi_optee_mark_txdone(struct scmi_chan_info *cinfo, int ret, 494 struct scmi_xfer *__unused) 495 { 496 struct scmi_optee_channel *channel = cinfo->transport_info; 497 498 mutex_unlock(&channel->mu); 499 } 500 501 static struct scmi_transport_ops scmi_optee_ops = { 502 .chan_available = scmi_optee_chan_available, 503 .chan_setup = scmi_optee_chan_setup, 504 .chan_free = scmi_optee_chan_free, 505 .send_message = scmi_optee_send_message, 506 .mark_txdone = scmi_optee_mark_txdone, 507 .fetch_response = scmi_optee_fetch_response, 508 .clear_channel = scmi_optee_clear_channel, 509 }; 510 511 static int scmi_optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data) 512 { 513 return ver->impl_id == TEE_IMPL_ID_OPTEE; 514 } 515 516 static struct scmi_desc scmi_optee_desc = { 517 .ops = &scmi_optee_ops, 518 .max_rx_timeout_ms = 30, 519 .max_msg = 20, 520 .max_msg_size = SCMI_SHMEM_MAX_PAYLOAD_SIZE, 521 .sync_cmds_completed_on_ret = true, 522 }; 523 524 static const struct of_device_id scmi_of_match[] = { 525 { .compatible = "linaro,scmi-optee" }, 526 { /* Sentinel */ }, 527 }; 528 529 DEFINE_SCMI_TRANSPORT_DRIVER(scmi_optee, scmi_optee_driver, scmi_optee_desc, 530 scmi_of_match, core); 531 532 static int scmi_optee_service_probe(struct device *dev) 533 { 534 struct scmi_optee_agent *agent; 535 struct tee_context *tee_ctx; 536 int ret; 537 538 /* Only one SCMI OP-TEE device allowed */ 539 if (scmi_optee_private) { 540 dev_err(dev, "An SCMI OP-TEE device was already initialized: only one allowed\n"); 541 return -EBUSY; 542 } 543 544 tee_ctx = tee_client_open_context(NULL, scmi_optee_ctx_match, NULL, NULL); 545 if (IS_ERR(tee_ctx)) 546 return -ENODEV; 547 548 agent = devm_kzalloc(dev, sizeof(*agent), GFP_KERNEL); 549 if (!agent) { 550 ret = -ENOMEM; 551 goto err; 552 } 553 554 agent->dev = dev; 555 agent->tee_ctx = tee_ctx; 556 INIT_LIST_HEAD(&agent->channel_list); 557 mutex_init(&agent->mu); 558 559 ret = get_capabilities(agent); 560 if (ret) 561 goto err; 562 563 /* Ensure agent resources are all visible before scmi_optee_private is */ 564 smp_mb(); 565 scmi_optee_private = agent; 566 567 ret = platform_driver_register(&scmi_optee_driver); 568 if (ret) { 569 scmi_optee_private = NULL; 570 goto err; 571 } 572 573 return 0; 574 575 err: 576 tee_client_close_context(tee_ctx); 577 578 return ret; 579 } 580 581 static int scmi_optee_service_remove(struct device *dev) 582 { 583 struct scmi_optee_agent *agent = scmi_optee_private; 584 585 if (!scmi_optee_private) 586 return -EINVAL; 587 588 platform_driver_unregister(&scmi_optee_driver); 589 590 if (!list_empty(&scmi_optee_private->channel_list)) 591 return -EBUSY; 592 593 /* Ensure cleared reference is visible before resources are released */ 594 smp_store_mb(scmi_optee_private, NULL); 595 596 tee_client_close_context(agent->tee_ctx); 597 598 return 0; 599 } 600 601 static const struct tee_client_device_id scmi_optee_service_id[] = { 602 { 603 UUID_INIT(0xa8cfe406, 0xd4f5, 0x4a2e, 604 0x9f, 0x8d, 0xa2, 0x5d, 0xc7, 0x54, 0xc0, 0x99) 605 }, 606 { } 607 }; 608 609 MODULE_DEVICE_TABLE(tee, scmi_optee_service_id); 610 611 static struct tee_client_driver scmi_optee_service_driver = { 612 .id_table = scmi_optee_service_id, 613 .driver = { 614 .name = "scmi-optee", 615 .bus = &tee_bus_type, 616 .probe = scmi_optee_service_probe, 617 .remove = scmi_optee_service_remove, 618 }, 619 }; 620 621 static int __init scmi_transport_optee_init(void) 622 { 623 return driver_register(&scmi_optee_service_driver.driver); 624 } 625 module_init(scmi_transport_optee_init); 626 627 static void __exit scmi_transport_optee_exit(void) 628 { 629 driver_unregister(&scmi_optee_service_driver.driver); 630 } 631 module_exit(scmi_transport_optee_exit); 632 633 MODULE_AUTHOR("Etienne Carriere <etienne.carriere@foss.st.com>"); 634 MODULE_DESCRIPTION("SCMI OPTEE Transport driver"); 635 MODULE_LICENSE("GPL"); 636