drivers/firmware/efi/stmm/tee_stmm_efi.c

Source file repositories/reference/linux-study-clean/drivers/firmware/efi/stmm/tee_stmm_efi.c

File Facts

System
Linux kernel
Corpus path
drivers/firmware/efi/stmm/tee_stmm_efi.c
Extension
.c
Size
16944 bytes
Lines
598
Domain
Driver Families
Bucket
drivers/firmware
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

struct tee_stmm_efi_private {
	struct tee_context *ctx;
	u32 session;
	struct device *dev;
};

static struct tee_stmm_efi_private pvt_data;

/* UUID of the stmm PTA */
static const struct tee_client_device_id tee_stmm_efi_id_table[] = {
	{PTA_STMM_UUID},
	{}
};

static int tee_ctx_match(struct tee_ioctl_version_data *ver, const void *data)
{
	/* currently only OP-TEE is supported as a communication path */
	if (ver->impl_id == TEE_IMPL_ID_OPTEE)
		return 1;
	else
		return 0;
}

/**
 * tee_mm_communicate() - Pass a buffer to StandaloneMM running in TEE
 *
 * @comm_buf:		locally allocated communication buffer
 * @dsize:		buffer size
 * Return:		status code
 */
static efi_status_t tee_mm_communicate(void *comm_buf, size_t dsize)
{
	size_t buf_size;
	struct efi_mm_communicate_header *mm_hdr;
	struct tee_ioctl_invoke_arg arg;
	struct tee_param param[4];
	struct tee_shm *shm = NULL;
	int rc;

	if (!comm_buf)
		return EFI_INVALID_PARAMETER;

	mm_hdr = (struct efi_mm_communicate_header *)comm_buf;
	buf_size = mm_hdr->message_len + sizeof(efi_guid_t) + sizeof(size_t);

	if (dsize != buf_size)
		return EFI_INVALID_PARAMETER;

	shm = tee_shm_register_kernel_buf(pvt_data.ctx, comm_buf, buf_size);
	if (IS_ERR(shm)) {
		dev_err(pvt_data.dev, "Unable to register shared memory\n");
		return EFI_UNSUPPORTED;
	}

	memset(&arg, 0, sizeof(arg));
	arg.func = PTA_STMM_CMD_COMMUNICATE;
	arg.session = pvt_data.session;
	arg.num_params = 4;

	memset(param, 0, sizeof(param));
	param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT;
	param[0].u.memref.size = buf_size;
	param[0].u.memref.shm = shm;
	param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT;
	param[2].attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
	param[3].attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;

	rc = tee_client_invoke_func(pvt_data.ctx, &arg, param);
	tee_shm_free(shm);

	if (rc < 0 || arg.ret != 0) {
		dev_err(pvt_data.dev,
			"PTA_STMM_CMD_COMMUNICATE invoke error: 0x%x\n", arg.ret);
		return EFI_DEVICE_ERROR;
	}

	switch (param[1].u.value.a) {
	case ARM_SVC_SPM_RET_SUCCESS:
		return EFI_SUCCESS;

	case ARM_SVC_SPM_RET_INVALID_PARAMS:
		return EFI_INVALID_PARAMETER;

	case ARM_SVC_SPM_RET_DENIED:
		return EFI_ACCESS_DENIED;

	case ARM_SVC_SPM_RET_NO_MEMORY:
		return EFI_OUT_OF_RESOURCES;

	default:

Annotation

Implementation Notes