drivers/tee/tstee/core.c

Source file repositories/reference/linux-study-clean/drivers/tee/tstee/core.c

File Facts

System
Linux kernel
Corpus path
drivers/tee/tstee/core.c
Extension
.c
Size
11638 bytes
Lines
481
Domain
Driver Families
Bucket
drivers/tee
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (shm->size < req_len) {
			dev_err(&ffa_dev->dev,
				"request doesn't fit into shared memory buffer\n");
			rc = -EINVAL;
			goto out;
		}

		handle = shm->sec_world_id;
	} else {
		handle = FFA_INVALID_MEM_HANDLE;
	}

	ffa_args[TS_RPC_CTRL_REG] = TS_RPC_CTRL_PACK_IFACE_OPCODE(iface_id,
								  opcode);
	ffa_args[TS_RPC_SERVICE_MEM_HANDLE_LSW] = lower_32_bits(handle);
	ffa_args[TS_RPC_SERVICE_MEM_HANDLE_MSW] = upper_32_bits(handle);
	ffa_args[TS_RPC_SERVICE_REQ_LEN] = req_len;
	ffa_args[TS_RPC_SERVICE_CLIENT_ID] = 0;

	arg_list_to_ffa_data(ffa_args, &ffa_data);
	rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
	if (rc)
		goto out;

	arg_list_from_ffa_data(&ffa_data, ffa_args);

	if (ffa_args[TS_RPC_SERVICE_RPC_STATUS] != TS_RPC_OK) {
		dev_err(&ffa_dev->dev, "invoke_func rpc status: %d\n",
			ffa_args[TS_RPC_SERVICE_RPC_STATUS]);
		rc = -EINVAL;
		goto out;
	}

	arg->ret = ffa_args[TS_RPC_SERVICE_STATUS];
	if (shm && shm->size >= ffa_args[TS_RPC_SERVICE_RESP_LEN])
		param[0].u.value.a = ffa_args[TS_RPC_SERVICE_RESP_LEN];

out:
	if (shm)
		tee_shm_put(shm);

	return rc;
}

static int tstee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
			      struct page **pages, size_t num_pages,
			      unsigned long start __always_unused)
{
	struct tstee *tstee = tee_get_drvdata(ctx->teedev);
	struct ffa_device *ffa_dev = tstee->ffa_dev;
	struct ffa_mem_region_attributes mem_attr = {
		.receiver = tstee->ffa_dev->vm_id,
		.attrs = FFA_MEM_RW,
		.flag = 0,
	};
	struct ffa_mem_ops_args mem_args = {
		.attrs = &mem_attr,
		.use_txbuf = true,
		.nattrs = 1,
		.flags = 0,
	};
	struct ffa_send_direct_data ffa_data;
	struct sg_table sgt;
	u32 ffa_args[FFA_DIRECT_REQ_ARG_NUM] = {};
	int rc;

	rc = sg_alloc_table_from_pages(&sgt, pages, num_pages, 0,
				       num_pages * PAGE_SIZE, GFP_KERNEL);
	if (rc)
		return rc;

	mem_args.sg = sgt.sgl;
	rc = ffa_dev->ops->mem_ops->memory_share(&mem_args);
	sg_free_table(&sgt);
	if (rc)
		return rc;

	shm->sec_world_id = mem_args.g_handle;

	ffa_args[TS_RPC_CTRL_REG] =
			TS_RPC_CTRL_PACK_IFACE_OPCODE(TS_RPC_MGMT_IFACE_ID,
						      TS_RPC_OP_RETRIEVE_MEM);
	ffa_args[TS_RPC_RETRIEVE_MEM_HANDLE_LSW] =
			lower_32_bits(shm->sec_world_id);
	ffa_args[TS_RPC_RETRIEVE_MEM_HANDLE_MSW] =
			upper_32_bits(shm->sec_world_id);
	ffa_args[TS_RPC_RETRIEVE_MEM_TAG_LSW] = 0;
	ffa_args[TS_RPC_RETRIEVE_MEM_TAG_MSW] = 0;

	arg_list_to_ffa_data(ffa_args, &ffa_data);

Annotation

Implementation Notes