| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- // SPDX-License-Identifier: GPL-2.0-only
- /*
- * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
- */
- #include <linux/delay.h>
- #include "qcomtee.h"
- /**
- * DOC: Primordial Object
- *
- * After boot, the kernel provides a static object of type
- * %QCOMTEE_OBJECT_TYPE_CB called the primordial object. This object is used
- * for native kernel services or privileged operations.
- *
- * We support:
- * - %QCOMTEE_OBJECT_OP_MAP_REGION to map a memory object and return mapping
- * object and mapping information (see qcomtee_mem_object_map()).
- * - %QCOMTEE_OBJECT_OP_YIELD to yield by the thread running in QTEE.
- * - %QCOMTEE_OBJECT_OP_SLEEP to wait for a period of time.
- */
- #define QCOMTEE_OBJECT_OP_MAP_REGION 0
- #define QCOMTEE_OBJECT_OP_YIELD 1
- #define QCOMTEE_OBJECT_OP_SLEEP 2
- /* Mapping information format as expected by QTEE. */
- struct qcomtee_mapping_info {
- u64 paddr;
- u64 len;
- u32 perms;
- } __packed;
- static int
- qcomtee_primordial_obj_dispatch(struct qcomtee_object_invoke_ctx *oic,
- struct qcomtee_object *primordial_object_unused,
- u32 op, struct qcomtee_arg *args)
- {
- struct qcomtee_mapping_info *map_info;
- struct qcomtee_object *mem_object;
- struct qcomtee_object *map_object;
- int err = 0;
- switch (op) {
- case QCOMTEE_OBJECT_OP_YIELD:
- cond_resched();
- /* No output object. */
- oic->data = NULL;
- break;
- case QCOMTEE_OBJECT_OP_SLEEP:
- /* Check message format matched QCOMTEE_OBJECT_OP_SLEEP op. */
- if (qcomtee_args_len(args) != 1 ||
- args[0].type != QCOMTEE_ARG_TYPE_IB ||
- args[0].b.size < sizeof(u32))
- return -EINVAL;
- msleep(*(u32 *)(args[0].b.addr));
- /* No output object. */
- oic->data = NULL;
- break;
- case QCOMTEE_OBJECT_OP_MAP_REGION:
- if (qcomtee_args_len(args) != 3 ||
- args[0].type != QCOMTEE_ARG_TYPE_OB ||
- args[1].type != QCOMTEE_ARG_TYPE_IO ||
- args[2].type != QCOMTEE_ARG_TYPE_OO ||
- args[0].b.size < sizeof(struct qcomtee_mapping_info))
- return -EINVAL;
- map_info = args[0].b.addr;
- mem_object = args[1].o;
- qcomtee_mem_object_map(mem_object, &map_object,
- &map_info->paddr, &map_info->len,
- &map_info->perms);
- args[2].o = map_object;
- /* One output object; pass it for cleanup to notify. */
- oic->data = map_object;
- qcomtee_object_put(mem_object);
- break;
- default:
- err = -EINVAL;
- }
- return err;
- }
- /* Called after submitting the callback response. */
- static void qcomtee_primordial_obj_notify(struct qcomtee_object_invoke_ctx *oic,
- struct qcomtee_object *unused,
- int err)
- {
- struct qcomtee_object *object = oic->data;
- /* If err, QTEE did not obtain mapping object. Drop it. */
- if (object && err)
- qcomtee_object_put(object);
- }
- static struct qcomtee_object_operations qcomtee_primordial_obj_ops = {
- .dispatch = qcomtee_primordial_obj_dispatch,
- .notify = qcomtee_primordial_obj_notify,
- };
- struct qcomtee_object qcomtee_primordial_object = {
- .name = "primordial",
- .object_type = QCOMTEE_OBJECT_TYPE_CB,
- .ops = &qcomtee_primordial_obj_ops
- };
|