linux/drivers/tee/optee/optee_private.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * Copyright (c) 2015, Linaro Limited
   4 */
   5
   6#ifndef OPTEE_PRIVATE_H
   7#define OPTEE_PRIVATE_H
   8
   9#include <linux/arm-smccc.h>
  10#include <linux/semaphore.h>
  11#include <linux/tee_drv.h>
  12#include <linux/types.h>
  13#include "optee_msg.h"
  14
  15#define OPTEE_MAX_ARG_SIZE      1024
  16
  17/* Some Global Platform error codes used in this driver */
  18#define TEEC_SUCCESS                    0x00000000
  19#define TEEC_ERROR_BAD_PARAMETERS       0xFFFF0006
  20#define TEEC_ERROR_NOT_SUPPORTED        0xFFFF000A
  21#define TEEC_ERROR_COMMUNICATION        0xFFFF000E
  22#define TEEC_ERROR_OUT_OF_MEMORY        0xFFFF000C
  23#define TEEC_ERROR_SHORT_BUFFER         0xFFFF0010
  24
  25#define TEEC_ORIGIN_COMMS               0x00000002
  26
  27typedef void (optee_invoke_fn)(unsigned long, unsigned long, unsigned long,
  28                                unsigned long, unsigned long, unsigned long,
  29                                unsigned long, unsigned long,
  30                                struct arm_smccc_res *);
  31
  32struct optee_call_queue {
  33        /* Serializes access to this struct */
  34        struct mutex mutex;
  35        struct list_head waiters;
  36};
  37
  38struct optee_wait_queue {
  39        /* Serializes access to this struct */
  40        struct mutex mu;
  41        struct list_head db;
  42};
  43
  44/**
  45 * struct optee_supp - supplicant synchronization struct
  46 * @ctx                 the context of current connected supplicant.
  47 *                      if !NULL the supplicant device is available for use,
  48 *                      else busy
  49 * @mutex:              held while accessing content of this struct
  50 * @req_id:             current request id if supplicant is doing synchronous
  51 *                      communication, else -1
  52 * @reqs:               queued request not yet retrieved by supplicant
  53 * @idr:                IDR holding all requests currently being processed
  54 *                      by supplicant
  55 * @reqs_c:             completion used by supplicant when waiting for a
  56 *                      request to be queued.
  57 */
  58struct optee_supp {
  59        /* Serializes access to this struct */
  60        struct mutex mutex;
  61        struct tee_context *ctx;
  62
  63        int req_id;
  64        struct list_head reqs;
  65        struct idr idr;
  66        struct completion reqs_c;
  67};
  68
  69/**
  70 * struct optee - main service struct
  71 * @supp_teedev:        supplicant device
  72 * @teedev:             client device
  73 * @invoke_fn:          function to issue smc or hvc
  74 * @call_queue:         queue of threads waiting to call @invoke_fn
  75 * @wait_queue:         queue of threads from secure world waiting for a
  76 *                      secure world sync object
  77 * @supp:               supplicant synchronization struct for RPC to supplicant
  78 * @pool:               shared memory pool
  79 * @memremaped_shm      virtual address of memory in shared memory pool
  80 * @sec_caps:           secure world capabilities defined by
  81 *                      OPTEE_SMC_SEC_CAP_* in optee_smc.h
  82 * @scan_bus_done       flag if device registation was already done.
  83 * @scan_bus_wq         workqueue to scan optee bus and register optee drivers
  84 * @scan_bus_work       workq to scan optee bus and register optee drivers
  85 */
  86struct optee {
  87        struct tee_device *supp_teedev;
  88        struct tee_device *teedev;
  89        optee_invoke_fn *invoke_fn;
  90        struct optee_call_queue call_queue;
  91        struct optee_wait_queue wait_queue;
  92        struct optee_supp supp;
  93        struct tee_shm_pool *pool;
  94        void *memremaped_shm;
  95        u32 sec_caps;
  96        bool   scan_bus_done;
  97        struct workqueue_struct *scan_bus_wq;
  98        struct work_struct scan_bus_work;
  99};
 100
 101struct optee_session {
 102        struct list_head list_node;
 103        u32 session_id;
 104};
 105
 106struct optee_context_data {
 107        /* Serializes access to this struct */
 108        struct mutex mutex;
 109        struct list_head sess_list;
 110};
 111
 112struct optee_rpc_param {
 113        u32     a0;
 114        u32     a1;
 115        u32     a2;
 116        u32     a3;
 117        u32     a4;
 118        u32     a5;
 119        u32     a6;
 120        u32     a7;
 121};
 122
 123/* Holds context that is preserved during one STD call */
 124struct optee_call_ctx {
 125        /* information about pages list used in last allocation */
 126        void *pages_list;
 127        size_t num_entries;
 128};
 129
 130void optee_handle_rpc(struct tee_context *ctx, struct optee_rpc_param *param,
 131                      struct optee_call_ctx *call_ctx);
 132void optee_rpc_finalize_call(struct optee_call_ctx *call_ctx);
 133
 134void optee_wait_queue_init(struct optee_wait_queue *wq);
 135void optee_wait_queue_exit(struct optee_wait_queue *wq);
 136
 137u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
 138                        struct tee_param *param);
 139
 140int optee_supp_read(struct tee_context *ctx, void __user *buf, size_t len);
 141int optee_supp_write(struct tee_context *ctx, void __user *buf, size_t len);
 142void optee_supp_init(struct optee_supp *supp);
 143void optee_supp_uninit(struct optee_supp *supp);
 144void optee_supp_release(struct optee_supp *supp);
 145
 146int optee_supp_recv(struct tee_context *ctx, u32 *func, u32 *num_params,
 147                    struct tee_param *param);
 148int optee_supp_send(struct tee_context *ctx, u32 ret, u32 num_params,
 149                    struct tee_param *param);
 150
 151u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg);
 152int optee_open_session(struct tee_context *ctx,
 153                       struct tee_ioctl_open_session_arg *arg,
 154                       struct tee_param *param);
 155int optee_close_session(struct tee_context *ctx, u32 session);
 156int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
 157                      struct tee_param *param);
 158int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session);
 159
 160void optee_enable_shm_cache(struct optee *optee);
 161void optee_disable_shm_cache(struct optee *optee);
 162void optee_disable_unmapped_shm_cache(struct optee *optee);
 163
 164int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm,
 165                       struct page **pages, size_t num_pages,
 166                       unsigned long start);
 167int optee_shm_unregister(struct tee_context *ctx, struct tee_shm *shm);
 168
 169int optee_shm_register_supp(struct tee_context *ctx, struct tee_shm *shm,
 170                            struct page **pages, size_t num_pages,
 171                            unsigned long start);
 172int optee_shm_unregister_supp(struct tee_context *ctx, struct tee_shm *shm);
 173
 174int optee_from_msg_param(struct tee_param *params, size_t num_params,
 175                         const struct optee_msg_param *msg_params);
 176int optee_to_msg_param(struct optee_msg_param *msg_params, size_t num_params,
 177                       const struct tee_param *params);
 178
 179u64 *optee_allocate_pages_list(size_t num_entries);
 180void optee_free_pages_list(void *array, size_t num_entries);
 181void optee_fill_pages_list(u64 *dst, struct page **pages, int num_pages,
 182                           size_t page_offset);
 183
 184#define PTA_CMD_GET_DEVICES             0x0
 185#define PTA_CMD_GET_DEVICES_SUPP        0x1
 186int optee_enumerate_devices(u32 func);
 187void optee_unregister_devices(void);
 188
 189/*
 190 * Small helpers
 191 */
 192
 193static inline void *reg_pair_to_ptr(u32 reg0, u32 reg1)
 194{
 195        return (void *)(unsigned long)(((u64)reg0 << 32) | reg1);
 196}
 197
 198static inline void reg_pair_from_64(u32 *reg0, u32 *reg1, u64 val)
 199{
 200        *reg0 = val >> 32;
 201        *reg1 = val;
 202}
 203
 204#endif /*OPTEE_PRIVATE_H*/
 205