Lines Matching +full:secure +full:- +full:firmware
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2017-2018, Intel Corporation
19 #include <linux/firmware/intel/stratix10-smc.h>
20 #include <linux/firmware/intel/stratix10-svc-client.h>
24 * SVC_NUM_DATA_IN_FIFO - number of struct stratix10_svc_data in the FIFO
26 * SVC_NUM_CHANNEL - number of channel supported by service layer driver
28 * FPGA_CONFIG_DATA_CLAIM_TIMEOUT_MS - claim back the submitted buffer(s)
29 * from the secure world for FPGA manager to reuse, or to free the buffer(s)
30 * when all bit-stream data had be send.
32 * FPGA_CONFIG_STATUS_TIMEOUT_SEC - poll the FPGA configuration status,
42 #define STRATIX10_RSU "stratix10-rsu"
51 * struct stratix10_svc - svc private data
59 * struct stratix10_svc_sh_memory - service shared memory structure
63 * @invoke_fn: function to issue secure monitor or hypervisor call
66 * block. The shared memory blocked is allocated by secure monitor software
67 * at secure world.
80 * struct stratix10_svc_data_mem - service memory structure
98 * struct stratix10_svc_data - service data structure
106 * This struct is used in service FIFO for inter-process communication.
118 * struct stratix10_svc_controller - service controller
129 * @invoke_fn: function to issue secure monitor call or hypervisor call
132 * handle secure monitor or hypervisor call.
149 * struct stratix10_svc_chan - service communication channel
169 * svc_pa_to_va() - translate physical address to virtual address
179 pr_debug("claim back P-addr=0x%016x\n", (unsigned int)addr); in svc_pa_to_va()
181 if (pmem->paddr == addr) in svc_pa_to_va()
182 return pmem->vaddr; in svc_pa_to_va()
189 * svc_thread_cmd_data_claim() - claim back buffer from the secure world
194 * Claim back the submitted buffers from the secure world and pass buffer
204 reinit_completion(&ctrl->complete_status); in svc_thread_cmd_data_claim()
209 ctrl->invoke_fn(INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE, in svc_thread_cmd_data_claim()
214 complete(&ctrl->complete_status); in svc_thread_cmd_data_claim()
217 cb_data->status = BIT(SVC_STATUS_BUFFER_DONE); in svc_thread_cmd_data_claim()
218 cb_data->kaddr1 = svc_pa_to_va(res.a1); in svc_thread_cmd_data_claim()
219 cb_data->kaddr2 = (res.a2) ? in svc_thread_cmd_data_claim()
221 cb_data->kaddr3 = (res.a3) ? in svc_thread_cmd_data_claim()
223 p_data->chan->scl->receive_cb(p_data->chan->scl, in svc_thread_cmd_data_claim()
226 pr_debug("%s: secure world busy, polling again\n", in svc_thread_cmd_data_claim()
231 wait_for_completion_timeout(&ctrl->complete_status, timeout)); in svc_thread_cmd_data_claim()
235 * svc_thread_cmd_config_status() - check configuration status
240 * Check whether the secure firmware at secure world has finished the FPGA
250 cb_data->kaddr1 = NULL; in svc_thread_cmd_config_status()
251 cb_data->kaddr2 = NULL; in svc_thread_cmd_config_status()
252 cb_data->kaddr3 = NULL; in svc_thread_cmd_config_status()
253 cb_data->status = BIT(SVC_STATUS_ERROR); in svc_thread_cmd_config_status()
259 ctrl->invoke_fn(INTEL_SIP_SMC_FPGA_CONFIG_ISDONE, in svc_thread_cmd_config_status()
270 count_in_sec--; in svc_thread_cmd_config_status()
274 cb_data->status = BIT(SVC_STATUS_COMPLETED); in svc_thread_cmd_config_status()
276 p_data->chan->scl->receive_cb(p_data->chan->scl, cb_data); in svc_thread_cmd_config_status()
280 * svc_thread_recv_status_ok() - handle the successful status
291 cb_data->kaddr1 = NULL; in svc_thread_recv_status_ok()
292 cb_data->kaddr2 = NULL; in svc_thread_recv_status_ok()
293 cb_data->kaddr3 = NULL; in svc_thread_recv_status_ok()
295 switch (p_data->command) { in svc_thread_recv_status_ok()
299 cb_data->status = BIT(SVC_STATUS_OK); in svc_thread_recv_status_ok()
302 cb_data->status = BIT(SVC_STATUS_BUFFER_SUBMITTED); in svc_thread_recv_status_ok()
305 cb_data->status = BIT(SVC_STATUS_COMPLETED); in svc_thread_recv_status_ok()
309 cb_data->status = BIT(SVC_STATUS_OK); in svc_thread_recv_status_ok()
310 cb_data->kaddr1 = &res.a1; in svc_thread_recv_status_ok()
313 cb_data->status = BIT(SVC_STATUS_OK); in svc_thread_recv_status_ok()
314 cb_data->kaddr1 = &res.a1; in svc_thread_recv_status_ok()
315 cb_data->kaddr2 = &res.a2; in svc_thread_recv_status_ok()
323 p_data->chan->scl->receive_cb(p_data->chan->scl, cb_data); in svc_thread_recv_status_ok()
327 * svc_normal_to_secure_thread() - the function to run in the kthread
332 * SMC or HVC calls between kernel driver and secure monitor software.
334 * Return: 0 for success or -ENOMEM on error.
348 return -ENOMEM; in svc_normal_to_secure_thread()
353 return -ENOMEM; in svc_normal_to_secure_thread()
364 ret_fifo = kfifo_out_spinlocked(&ctrl->svc_fifo, in svc_normal_to_secure_thread()
366 &ctrl->svc_fifo_lock); in svc_normal_to_secure_thread()
372 (unsigned int)pdata->paddr, pdata->command, in svc_normal_to_secure_thread()
373 (unsigned int)pdata->size); in svc_normal_to_secure_thread()
375 switch (pdata->command) { in svc_normal_to_secure_thread()
381 pr_debug("conf_type=%u\n", (unsigned int)pdata->flag); in svc_normal_to_secure_thread()
382 a1 = pdata->flag; in svc_normal_to_secure_thread()
387 a1 = (unsigned long)pdata->paddr; in svc_normal_to_secure_thread()
388 a2 = (unsigned long)pdata->size; in svc_normal_to_secure_thread()
402 a1 = pdata->arg[0]; in svc_normal_to_secure_thread()
407 a1 = pdata->arg[0]; in svc_normal_to_secure_thread()
429 pr_debug("%s: before SMC call -- a0=0x%016x a1=0x%016x", in svc_normal_to_secure_thread()
433 ctrl->invoke_fn(a0, a1, a2, 0, 0, 0, 0, 0, &res); in svc_normal_to_secure_thread()
435 pr_debug("%s: after SMC call -- res.a0=0x%016x", in svc_normal_to_secure_thread()
441 if (pdata->command == COMMAND_RSU_STATUS) { in svc_normal_to_secure_thread()
443 cbdata->status = BIT(SVC_STATUS_ERROR); in svc_normal_to_secure_thread()
445 cbdata->status = BIT(SVC_STATUS_OK); in svc_normal_to_secure_thread()
447 cbdata->kaddr1 = &res; in svc_normal_to_secure_thread()
448 cbdata->kaddr2 = NULL; in svc_normal_to_secure_thread()
449 cbdata->kaddr3 = NULL; in svc_normal_to_secure_thread()
450 pdata->chan->scl->receive_cb(pdata->chan->scl, cbdata); in svc_normal_to_secure_thread()
459 switch (pdata->command) { in svc_normal_to_secure_thread()
479 cbdata->status = BIT(SVC_STATUS_ERROR); in svc_normal_to_secure_thread()
480 cbdata->kaddr1 = NULL; in svc_normal_to_secure_thread()
481 cbdata->kaddr2 = NULL; in svc_normal_to_secure_thread()
482 cbdata->kaddr3 = NULL; in svc_normal_to_secure_thread()
483 pdata->chan->scl->receive_cb(pdata->chan->scl, cbdata); in svc_normal_to_secure_thread()
486 pr_warn("Secure firmware doesn't support...\n"); in svc_normal_to_secure_thread()
489 * be compatible with older version firmware which in svc_normal_to_secure_thread()
492 if ((pdata->command == COMMAND_RSU_RETRY) || in svc_normal_to_secure_thread()
493 (pdata->command == COMMAND_RSU_MAX_RETRY) || in svc_normal_to_secure_thread()
494 (pdata->command == COMMAND_RSU_NOTIFY)) { in svc_normal_to_secure_thread()
495 cbdata->status = in svc_normal_to_secure_thread()
497 cbdata->kaddr1 = NULL; in svc_normal_to_secure_thread()
498 cbdata->kaddr2 = NULL; in svc_normal_to_secure_thread()
499 cbdata->kaddr3 = NULL; in svc_normal_to_secure_thread()
500 pdata->chan->scl->receive_cb( in svc_normal_to_secure_thread()
501 pdata->chan->scl, cbdata); in svc_normal_to_secure_thread()
515 * svc_normal_to_secure_shm_thread() - the function to run in the kthread
520 * physical address of memory block reserved by secure monitor software at
521 * secure world.
533 /* SMC or HVC call to get shared memory info from secure world */ in svc_normal_to_secure_shm_thread()
534 sh_mem->invoke_fn(INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM, in svc_normal_to_secure_shm_thread()
537 sh_mem->addr = res.a1; in svc_normal_to_secure_shm_thread()
538 sh_mem->size = res.a2; in svc_normal_to_secure_shm_thread()
540 pr_err("%s: after SMC call -- res.a0=0x%016x", __func__, in svc_normal_to_secure_shm_thread()
542 sh_mem->addr = 0; in svc_normal_to_secure_shm_thread()
543 sh_mem->size = 0; in svc_normal_to_secure_shm_thread()
546 complete(&sh_mem->sync_complete); in svc_normal_to_secure_shm_thread()
551 * svc_get_sh_memory() - get memory block reserved by secure monitor SW
556 * reserved by secure monitor software, or negative value on error.
561 struct device *dev = &pdev->dev; in svc_get_sh_memory()
565 init_completion(&sh_memory->sync_complete); in svc_get_sh_memory()
574 return -EINVAL; in svc_get_sh_memory()
579 if (!wait_for_completion_timeout(&sh_memory->sync_complete, 10 * HZ)) { in svc_get_sh_memory()
581 "timeout to get sh-memory paras from secure world\n"); in svc_get_sh_memory()
582 return -ETIMEDOUT; in svc_get_sh_memory()
585 if (!sh_memory->addr || !sh_memory->size) { in svc_get_sh_memory()
587 "failed to get shared memory info from secure world\n"); in svc_get_sh_memory()
588 return -ENOMEM; in svc_get_sh_memory()
592 (unsigned int)sh_memory->addr, in svc_get_sh_memory()
593 (unsigned int)sh_memory->size); in svc_get_sh_memory()
599 * svc_create_memory_pool() - create a memory pool from reserved memory block
609 struct device *dev = &pdev->dev; in svc_create_memory_pool()
617 size_t page_mask = PAGE_SIZE - 1; in svc_create_memory_pool()
621 begin = roundup(sh_memory->addr, PAGE_SIZE); in svc_create_memory_pool()
622 end = rounddown(sh_memory->addr + sh_memory->size, PAGE_SIZE); in svc_create_memory_pool()
624 size = end - begin; in svc_create_memory_pool()
628 return ERR_PTR(-EINVAL); in svc_create_memory_pool()
637 return ERR_PTR(-EINVAL); in svc_create_memory_pool()
639 genpool = gen_pool_create(min_alloc_order, -1); in svc_create_memory_pool()
642 return ERR_PTR(-ENOMEM); in svc_create_memory_pool()
645 ret = gen_pool_add_virt(genpool, vaddr, paddr, size, -1); in svc_create_memory_pool()
656 * svc_smccc_smc() - secure monitor call between normal and secure world
677 * svc_smccc_hvc() - hypervisor call between normal and secure world
698 * get_invoke_func() - invoke SMC or HVC call
707 if (of_property_read_string(dev->of_node, "method", &method)) { in get_invoke_func()
709 return ERR_PTR(-ENXIO); in get_invoke_func()
719 return ERR_PTR(-EINVAL); in get_invoke_func()
723 * stratix10_svc_request_channel_byname() - request a service channel
735 struct device *dev = client->dev; in stratix10_svc_request_channel_byname()
743 return ERR_PTR(-EPROBE_DEFER); in stratix10_svc_request_channel_byname()
748 if (!strcmp(controller->chans[i].name, name)) { in stratix10_svc_request_channel_byname()
749 chan = &controller->chans[i]; in stratix10_svc_request_channel_byname()
757 return ERR_PTR(-EINVAL); in stratix10_svc_request_channel_byname()
760 if (chan->scl || !try_module_get(controller->dev->driver->owner)) { in stratix10_svc_request_channel_byname()
762 return ERR_PTR(-EBUSY); in stratix10_svc_request_channel_byname()
765 spin_lock_irqsave(&chan->lock, flag); in stratix10_svc_request_channel_byname()
766 chan->scl = client; in stratix10_svc_request_channel_byname()
767 chan->ctrl->num_active_client++; in stratix10_svc_request_channel_byname()
768 spin_unlock_irqrestore(&chan->lock, flag); in stratix10_svc_request_channel_byname()
775 * stratix10_svc_free_channel() - free service channel
784 spin_lock_irqsave(&chan->lock, flag); in stratix10_svc_free_channel()
785 chan->scl = NULL; in stratix10_svc_free_channel()
786 chan->ctrl->num_active_client--; in stratix10_svc_free_channel()
787 module_put(chan->ctrl->dev->driver->owner); in stratix10_svc_free_channel()
788 spin_unlock_irqrestore(&chan->lock, flag); in stratix10_svc_free_channel()
793 * stratix10_svc_send() - send a message data to the remote
799 * layer driver's queue for being sent to the secure world.
801 * Return: 0 for success, -ENOMEM or -ENOBUFS on error.
814 return -ENOMEM; in stratix10_svc_send()
817 if (!chan->ctrl->task) { in stratix10_svc_send()
818 chan->ctrl->task = in stratix10_svc_send()
820 (void *)chan->ctrl, in stratix10_svc_send()
823 if (IS_ERR(chan->ctrl->task)) { in stratix10_svc_send()
824 dev_err(chan->ctrl->dev, in stratix10_svc_send()
827 return -EINVAL; in stratix10_svc_send()
829 kthread_bind(chan->ctrl->task, cpu); in stratix10_svc_send()
830 wake_up_process(chan->ctrl->task); in stratix10_svc_send()
833 pr_debug("%s: sent P-va=%p, P-com=%x, P-size=%u\n", __func__, in stratix10_svc_send()
834 p_msg->payload, p_msg->command, in stratix10_svc_send()
835 (unsigned int)p_msg->payload_length); in stratix10_svc_send()
838 if (p_msg->command == COMMAND_RECONFIG) { in stratix10_svc_send()
841 p_msg->payload; in stratix10_svc_send()
842 p_data->flag = ct->flags; in stratix10_svc_send()
846 if (p_mem->vaddr == p_msg->payload) { in stratix10_svc_send()
847 p_data->paddr = p_mem->paddr; in stratix10_svc_send()
852 p_data->command = p_msg->command; in stratix10_svc_send()
853 p_data->arg[0] = p_msg->arg[0]; in stratix10_svc_send()
854 p_data->arg[1] = p_msg->arg[1]; in stratix10_svc_send()
855 p_data->arg[2] = p_msg->arg[2]; in stratix10_svc_send()
856 p_data->size = p_msg->payload_length; in stratix10_svc_send()
857 p_data->chan = chan; in stratix10_svc_send()
859 (unsigned int)p_data->paddr, p_data->command, in stratix10_svc_send()
860 (unsigned int)p_data->size); in stratix10_svc_send()
861 ret = kfifo_in_spinlocked(&chan->ctrl->svc_fifo, p_data, in stratix10_svc_send()
863 &chan->ctrl->svc_fifo_lock); in stratix10_svc_send()
868 return -ENOBUFS; in stratix10_svc_send()
875 * stratix10_svc_done() - complete service request transactions
885 if (chan->ctrl->task && chan->ctrl->num_active_client <= 1) { in stratix10_svc_done()
887 kthread_stop(chan->ctrl->task); in stratix10_svc_done()
888 chan->ctrl->task = NULL; in stratix10_svc_done()
894 * stratix10_svc_allocate_memory() - allocate memory
909 struct gen_pool *genpool = chan->ctrl->genpool; in stratix10_svc_allocate_memory()
910 size_t s = roundup(size, 1 << genpool->min_alloc_order); in stratix10_svc_allocate_memory()
912 pmem = devm_kzalloc(chan->ctrl->dev, sizeof(*pmem), GFP_KERNEL); in stratix10_svc_allocate_memory()
914 return ERR_PTR(-ENOMEM); in stratix10_svc_allocate_memory()
918 return ERR_PTR(-ENOMEM); in stratix10_svc_allocate_memory()
923 pmem->vaddr = (void *)va; in stratix10_svc_allocate_memory()
924 pmem->paddr = pa; in stratix10_svc_allocate_memory()
925 pmem->size = s; in stratix10_svc_allocate_memory()
926 list_add_tail(&pmem->node, &svc_data_mem); in stratix10_svc_allocate_memory()
928 pmem->vaddr, (unsigned int)pmem->paddr); in stratix10_svc_allocate_memory()
935 * stratix10_svc_free_memory() - free allocated memory
947 if (pmem->vaddr == kaddr) { in stratix10_svc_free_memory()
948 size = pmem->size; in stratix10_svc_free_memory()
952 gen_pool_free(chan->ctrl->genpool, (unsigned long)kaddr, size); in stratix10_svc_free_memory()
953 pmem->vaddr = NULL; in stratix10_svc_free_memory()
954 list_del(&pmem->node); in stratix10_svc_free_memory()
959 {.compatible = "intel,stratix10-svc"},
960 {.compatible = "intel,agilex-svc"},
966 struct device *dev = &pdev->dev; in stratix10_svc_drv_probe()
980 return -EINVAL; in stratix10_svc_drv_probe()
984 return -ENOMEM; in stratix10_svc_drv_probe()
986 sh_memory->invoke_fn = invoke_fn; in stratix10_svc_drv_probe()
993 return -ENOMEM; in stratix10_svc_drv_probe()
998 return -ENOMEM; in stratix10_svc_drv_probe()
1003 return -ENOMEM; in stratix10_svc_drv_probe()
1005 controller->dev = dev; in stratix10_svc_drv_probe()
1006 controller->num_chans = SVC_NUM_CHANNEL; in stratix10_svc_drv_probe()
1007 controller->num_active_client = 0; in stratix10_svc_drv_probe()
1008 controller->chans = chans; in stratix10_svc_drv_probe()
1009 controller->genpool = genpool; in stratix10_svc_drv_probe()
1010 controller->task = NULL; in stratix10_svc_drv_probe()
1011 controller->invoke_fn = invoke_fn; in stratix10_svc_drv_probe()
1012 init_completion(&controller->complete_status); in stratix10_svc_drv_probe()
1015 ret = kfifo_alloc(&controller->svc_fifo, fifo_size, GFP_KERNEL); in stratix10_svc_drv_probe()
1020 spin_lock_init(&controller->svc_fifo_lock); in stratix10_svc_drv_probe()
1032 list_add_tail(&controller->node, &svc_ctrl); in stratix10_svc_drv_probe()
1038 ret = -ENOMEM; in stratix10_svc_drv_probe()
1042 svc->stratix10_svc_rsu = platform_device_alloc(STRATIX10_RSU, 0); in stratix10_svc_drv_probe()
1043 if (!svc->stratix10_svc_rsu) { in stratix10_svc_drv_probe()
1045 ret = -ENOMEM; in stratix10_svc_drv_probe()
1049 ret = platform_device_add(svc->stratix10_svc_rsu); in stratix10_svc_drv_probe()
1060 platform_device_put(svc->stratix10_svc_rsu); in stratix10_svc_drv_probe()
1062 kfifo_free(&controller->svc_fifo); in stratix10_svc_drv_probe()
1068 struct stratix10_svc *svc = dev_get_drvdata(&pdev->dev); in stratix10_svc_drv_remove()
1071 platform_device_unregister(svc->stratix10_svc_rsu); in stratix10_svc_drv_remove()
1073 kfifo_free(&ctrl->svc_fifo); in stratix10_svc_drv_remove()
1074 if (ctrl->task) { in stratix10_svc_drv_remove()
1075 kthread_stop(ctrl->task); in stratix10_svc_drv_remove()
1076 ctrl->task = NULL; in stratix10_svc_drv_remove()
1078 if (ctrl->genpool) in stratix10_svc_drv_remove()
1079 gen_pool_destroy(ctrl->genpool); in stratix10_svc_drv_remove()
1080 list_del(&ctrl->node); in stratix10_svc_drv_remove()
1089 .name = "stratix10-svc",
1100 fw_np = of_find_node_by_name(NULL, "firmware"); in stratix10_svc_init()
1102 return -ENODEV; in stratix10_svc_init()
1106 return -ENODEV; in stratix10_svc_init()
1127 MODULE_ALIAS("platform:stratix10-svc");