msm: adsprpc: add fastrpc driver files
Add fastrpc driver files, which provide a communication mechanism that allows clients to make remote method invocations across processor boundary to application, compute and sensors DSP processors. Change-Id: Idca98e5304f61ca7462d82f1252fe51982907d1c Acked-by: Thyagarajan Venkatanarayanan <venkatan@qti.qualcomm.com> Signed-off-by: Tharun Kumar Merugu <mtharu@codeaurora.org>
This commit is contained in:
@@ -540,6 +540,15 @@ source "drivers/s390/char/Kconfig"
|
||||
|
||||
source "drivers/char/xillybus/Kconfig"
|
||||
|
||||
config MSM_ADSPRPC
|
||||
tristate "QTI ADSP RPC driver"
|
||||
depends on QCOM_GLINK
|
||||
help
|
||||
Provides a communication mechanism that allows clients to
|
||||
make remote method invocations across processor boundary to
|
||||
applications/compute DSP processor.
|
||||
Say M if you want to enable this module.
|
||||
|
||||
config ADI
|
||||
tristate "SPARC Privileged ADI driver"
|
||||
depends on SPARC64
|
||||
|
||||
@@ -57,4 +57,8 @@ js-rtc-y = rtc.o
|
||||
|
||||
obj-$(CONFIG_XILLYBUS) += xillybus/
|
||||
obj-$(CONFIG_POWERNV_OP_PANEL) += powernv-op-panel.o
|
||||
obj-$(CONFIG_MSM_ADSPRPC) += adsprpc.o
|
||||
ifdef CONFIG_COMPAT
|
||||
obj-$(CONFIG_MSM_ADSPRPC) += adsprpc_compat.o
|
||||
endif
|
||||
obj-$(CONFIG_ADI) += adi.o
|
||||
|
||||
3999
drivers/char/adsprpc.c
Normal file
3999
drivers/char/adsprpc.c
Normal file
File diff suppressed because it is too large
Load Diff
579
drivers/char/adsprpc_compat.c
Normal file
579
drivers/char/adsprpc_compat.c
Normal file
@@ -0,0 +1,579 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
#include <linux/compat.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/msm_ion.h>
|
||||
|
||||
#include "adsprpc_compat.h"
|
||||
#include "adsprpc_shared.h"
|
||||
|
||||
#define COMPAT_FASTRPC_IOCTL_INVOKE \
|
||||
_IOWR('R', 1, struct compat_fastrpc_ioctl_invoke)
|
||||
#define COMPAT_FASTRPC_IOCTL_MMAP \
|
||||
_IOWR('R', 2, struct compat_fastrpc_ioctl_mmap)
|
||||
#define COMPAT_FASTRPC_IOCTL_MUNMAP \
|
||||
_IOWR('R', 3, struct compat_fastrpc_ioctl_munmap)
|
||||
#define COMPAT_FASTRPC_IOCTL_INVOKE_FD \
|
||||
_IOWR('R', 4, struct compat_fastrpc_ioctl_invoke_fd)
|
||||
#define COMPAT_FASTRPC_IOCTL_INIT \
|
||||
_IOWR('R', 6, struct compat_fastrpc_ioctl_init)
|
||||
#define COMPAT_FASTRPC_IOCTL_INVOKE_ATTRS \
|
||||
_IOWR('R', 7, struct compat_fastrpc_ioctl_invoke_attrs)
|
||||
#define COMPAT_FASTRPC_IOCTL_GETPERF \
|
||||
_IOWR('R', 9, struct compat_fastrpc_ioctl_perf)
|
||||
#define COMPAT_FASTRPC_IOCTL_INIT_ATTRS \
|
||||
_IOWR('R', 10, struct compat_fastrpc_ioctl_init_attrs)
|
||||
#define COMPAT_FASTRPC_IOCTL_INVOKE_CRC \
|
||||
_IOWR('R', 11, struct compat_fastrpc_ioctl_invoke_crc)
|
||||
#define COMPAT_FASTRPC_IOCTL_CONTROL \
|
||||
_IOWR('R', 12, struct compat_fastrpc_ioctl_control)
|
||||
#define COMPAT_FASTRPC_IOCTL_MMAP_64 \
|
||||
_IOWR('R', 14, struct compat_fastrpc_ioctl_mmap_64)
|
||||
#define COMPAT_FASTRPC_IOCTL_MUNMAP_64 \
|
||||
_IOWR('R', 15, struct compat_fastrpc_ioctl_munmap_64)
|
||||
|
||||
struct compat_remote_buf {
|
||||
compat_uptr_t pv; /* buffer pointer */
|
||||
compat_size_t len; /* length of buffer */
|
||||
};
|
||||
|
||||
union compat_remote_arg {
|
||||
struct compat_remote_buf buf;
|
||||
compat_uint_t h;
|
||||
};
|
||||
|
||||
struct compat_fastrpc_ioctl_invoke {
|
||||
compat_uint_t handle; /* remote handle */
|
||||
compat_uint_t sc; /* scalars describing the data */
|
||||
compat_uptr_t pra; /* remote arguments list */
|
||||
};
|
||||
|
||||
struct compat_fastrpc_ioctl_invoke_fd {
|
||||
struct compat_fastrpc_ioctl_invoke inv;
|
||||
compat_uptr_t fds; /* fd list */
|
||||
};
|
||||
|
||||
struct compat_fastrpc_ioctl_invoke_attrs {
|
||||
struct compat_fastrpc_ioctl_invoke inv;
|
||||
compat_uptr_t fds; /* fd list */
|
||||
compat_uptr_t attrs; /* attribute list */
|
||||
};
|
||||
|
||||
struct compat_fastrpc_ioctl_invoke_crc {
|
||||
struct compat_fastrpc_ioctl_invoke inv;
|
||||
compat_uptr_t fds; /* fd list */
|
||||
compat_uptr_t attrs; /* attribute list */
|
||||
compat_uptr_t crc; /* crc list */
|
||||
};
|
||||
|
||||
struct compat_fastrpc_ioctl_mmap {
|
||||
compat_int_t fd; /* ion fd */
|
||||
compat_uint_t flags; /* flags for dsp to map with */
|
||||
compat_uptr_t vaddrin; /* optional virtual address */
|
||||
compat_size_t size; /* size */
|
||||
compat_uptr_t vaddrout; /* dsps virtual address */
|
||||
};
|
||||
|
||||
struct compat_fastrpc_ioctl_mmap_64 {
|
||||
compat_int_t fd; /* ion fd */
|
||||
compat_uint_t flags; /* flags for dsp to map with */
|
||||
compat_u64 vaddrin; /* optional virtual address */
|
||||
compat_size_t size; /* size */
|
||||
compat_u64 vaddrout; /* dsps virtual address */
|
||||
};
|
||||
|
||||
struct compat_fastrpc_ioctl_munmap {
|
||||
compat_uptr_t vaddrout; /* address to unmap */
|
||||
compat_size_t size; /* size */
|
||||
};
|
||||
|
||||
struct compat_fastrpc_ioctl_munmap_64 {
|
||||
compat_u64 vaddrout; /* address to unmap */
|
||||
compat_size_t size; /* size */
|
||||
};
|
||||
|
||||
struct compat_fastrpc_ioctl_init {
|
||||
compat_uint_t flags; /* one of FASTRPC_INIT_* macros */
|
||||
compat_uptr_t file; /* pointer to elf file */
|
||||
compat_int_t filelen; /* elf file length */
|
||||
compat_int_t filefd; /* ION fd for the file */
|
||||
compat_uptr_t mem; /* mem for the PD */
|
||||
compat_int_t memlen; /* mem length */
|
||||
compat_int_t memfd; /* ION fd for the mem */
|
||||
};
|
||||
|
||||
struct compat_fastrpc_ioctl_init_attrs {
|
||||
struct compat_fastrpc_ioctl_init init;
|
||||
compat_int_t attrs; /* attributes to init process */
|
||||
compat_int_t siglen; /* test signature file length */
|
||||
};
|
||||
|
||||
struct compat_fastrpc_ioctl_perf { /* kernel performance data */
|
||||
compat_uptr_t data;
|
||||
compat_int_t numkeys;
|
||||
compat_uptr_t keys;
|
||||
};
|
||||
|
||||
#define FASTRPC_CONTROL_LATENCY (1)
|
||||
struct compat_fastrpc_ctrl_latency {
|
||||
compat_uint_t enable; /* latency control enable */
|
||||
compat_uint_t level; /* level of control */
|
||||
};
|
||||
|
||||
#define FASTRPC_CONTROL_KALLOC (3)
|
||||
struct compat_fastrpc_ctrl_kalloc {
|
||||
compat_uint_t kalloc_support; /* Remote memory allocation from kernel */
|
||||
};
|
||||
|
||||
struct compat_fastrpc_ioctl_control {
|
||||
compat_uint_t req;
|
||||
union {
|
||||
struct compat_fastrpc_ctrl_latency lp;
|
||||
struct compat_fastrpc_ctrl_kalloc kalloc;
|
||||
};
|
||||
};
|
||||
|
||||
static int compat_get_fastrpc_ioctl_invoke(
|
||||
struct compat_fastrpc_ioctl_invoke_crc __user *inv32,
|
||||
struct fastrpc_ioctl_invoke_crc __user **inva,
|
||||
unsigned int cmd)
|
||||
{
|
||||
compat_uint_t u, sc;
|
||||
compat_size_t s;
|
||||
compat_uptr_t p;
|
||||
struct fastrpc_ioctl_invoke_crc *inv;
|
||||
union compat_remote_arg *pra32;
|
||||
union remote_arg *pra;
|
||||
int err, len, j;
|
||||
|
||||
err = get_user(sc, &inv32->inv.sc);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
len = REMOTE_SCALARS_LENGTH(sc);
|
||||
VERIFY(err, NULL != (inv = compat_alloc_user_space(
|
||||
sizeof(*inv) + len * sizeof(*pra))));
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
|
||||
pra = (union remote_arg *)(inv + 1);
|
||||
err = put_user(pra, &inv->inv.pra);
|
||||
err |= put_user(sc, &inv->inv.sc);
|
||||
err |= get_user(u, &inv32->inv.handle);
|
||||
err |= put_user(u, &inv->inv.handle);
|
||||
err |= get_user(p, &inv32->inv.pra);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
pra32 = compat_ptr(p);
|
||||
pra = (union remote_arg *)(inv + 1);
|
||||
for (j = 0; j < len; j++) {
|
||||
err |= get_user(p, &pra32[j].buf.pv);
|
||||
err |= put_user(p, (uintptr_t *)&pra[j].buf.pv);
|
||||
err |= get_user(s, &pra32[j].buf.len);
|
||||
err |= put_user(s, &pra[j].buf.len);
|
||||
}
|
||||
|
||||
err |= put_user(NULL, &inv->fds);
|
||||
if (cmd != COMPAT_FASTRPC_IOCTL_INVOKE) {
|
||||
err |= get_user(p, &inv32->fds);
|
||||
err |= put_user(p, (compat_uptr_t *)&inv->fds);
|
||||
}
|
||||
err |= put_user(NULL, &inv->attrs);
|
||||
if ((cmd == COMPAT_FASTRPC_IOCTL_INVOKE_ATTRS) ||
|
||||
(cmd == COMPAT_FASTRPC_IOCTL_INVOKE_CRC)) {
|
||||
err |= get_user(p, &inv32->attrs);
|
||||
err |= put_user(p, (compat_uptr_t *)&inv->attrs);
|
||||
}
|
||||
err |= put_user(NULL, (compat_uptr_t __user **)&inv->crc);
|
||||
if (cmd == COMPAT_FASTRPC_IOCTL_INVOKE_CRC) {
|
||||
err |= get_user(p, &inv32->crc);
|
||||
err |= put_user(p, (compat_uptr_t __user *)&inv->crc);
|
||||
}
|
||||
|
||||
*inva = inv;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int compat_get_fastrpc_ioctl_mmap(
|
||||
struct compat_fastrpc_ioctl_mmap __user *map32,
|
||||
struct fastrpc_ioctl_mmap __user *map)
|
||||
{
|
||||
compat_uint_t u;
|
||||
compat_int_t i;
|
||||
compat_size_t s;
|
||||
compat_uptr_t p;
|
||||
int err;
|
||||
|
||||
err = get_user(i, &map32->fd);
|
||||
err |= put_user(i, &map->fd);
|
||||
err |= get_user(u, &map32->flags);
|
||||
err |= put_user(u, &map->flags);
|
||||
err |= get_user(p, &map32->vaddrin);
|
||||
err |= put_user(p, (uintptr_t *)&map->vaddrin);
|
||||
err |= get_user(s, &map32->size);
|
||||
err |= put_user(s, &map->size);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int compat_get_fastrpc_ioctl_mmap_64(
|
||||
struct compat_fastrpc_ioctl_mmap_64 __user *map32,
|
||||
struct fastrpc_ioctl_mmap __user *map)
|
||||
{
|
||||
compat_uint_t u;
|
||||
compat_int_t i;
|
||||
compat_size_t s;
|
||||
compat_u64 p;
|
||||
int err;
|
||||
|
||||
err = get_user(i, &map32->fd);
|
||||
err |= put_user(i, &map->fd);
|
||||
err |= get_user(u, &map32->flags);
|
||||
err |= put_user(u, &map->flags);
|
||||
err |= get_user(p, &map32->vaddrin);
|
||||
err |= put_user(p, &map->vaddrin);
|
||||
err |= get_user(s, &map32->size);
|
||||
err |= put_user(s, &map->size);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int compat_put_fastrpc_ioctl_mmap(
|
||||
struct compat_fastrpc_ioctl_mmap __user *map32,
|
||||
struct fastrpc_ioctl_mmap __user *map)
|
||||
{
|
||||
compat_uptr_t p;
|
||||
int err;
|
||||
|
||||
err = get_user(p, &map->vaddrout);
|
||||
err |= put_user(p, &map32->vaddrout);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int compat_put_fastrpc_ioctl_mmap_64(
|
||||
struct compat_fastrpc_ioctl_mmap_64 __user *map32,
|
||||
struct fastrpc_ioctl_mmap __user *map)
|
||||
{
|
||||
compat_u64 p;
|
||||
int err;
|
||||
|
||||
err = get_user(p, &map->vaddrout);
|
||||
err |= put_user(p, &map32->vaddrout);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int compat_get_fastrpc_ioctl_munmap(
|
||||
struct compat_fastrpc_ioctl_munmap __user *unmap32,
|
||||
struct fastrpc_ioctl_munmap __user *unmap)
|
||||
{
|
||||
compat_uptr_t p;
|
||||
compat_size_t s;
|
||||
int err;
|
||||
|
||||
err = get_user(p, &unmap32->vaddrout);
|
||||
err |= put_user(p, &unmap->vaddrout);
|
||||
err |= get_user(s, &unmap32->size);
|
||||
err |= put_user(s, &unmap->size);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int compat_get_fastrpc_ioctl_munmap_64(
|
||||
struct compat_fastrpc_ioctl_munmap_64 __user *unmap32,
|
||||
struct fastrpc_ioctl_munmap __user *unmap)
|
||||
{
|
||||
compat_u64 p;
|
||||
compat_size_t s;
|
||||
int err;
|
||||
|
||||
err = get_user(p, &unmap32->vaddrout);
|
||||
err |= put_user(p, &unmap->vaddrout);
|
||||
err |= get_user(s, &unmap32->size);
|
||||
err |= put_user(s, &unmap->size);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int compat_get_fastrpc_ioctl_perf(
|
||||
struct compat_fastrpc_ioctl_perf __user *perf32,
|
||||
struct fastrpc_ioctl_perf __user *perf)
|
||||
{
|
||||
compat_uptr_t p;
|
||||
int err;
|
||||
|
||||
err = get_user(p, &perf32->data);
|
||||
err |= put_user(p, &perf->data);
|
||||
err |= get_user(p, &perf32->keys);
|
||||
err |= put_user(p, &perf->keys);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int compat_get_fastrpc_ioctl_control(
|
||||
struct compat_fastrpc_ioctl_control __user *ctrl32,
|
||||
struct fastrpc_ioctl_control __user *ctrl)
|
||||
{
|
||||
compat_uptr_t p;
|
||||
int err;
|
||||
|
||||
err = get_user(p, &ctrl32->req);
|
||||
err |= put_user(p, &ctrl->req);
|
||||
if (p == FASTRPC_CONTROL_LATENCY) {
|
||||
err |= get_user(p, &ctrl32->lp.enable);
|
||||
err |= put_user(p, &ctrl->lp.enable);
|
||||
err |= get_user(p, &ctrl32->lp.level);
|
||||
err |= put_user(p, &ctrl->lp.level);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int compat_get_fastrpc_ioctl_init(
|
||||
struct compat_fastrpc_ioctl_init_attrs __user *init32,
|
||||
struct fastrpc_ioctl_init_attrs __user *init,
|
||||
unsigned int cmd)
|
||||
{
|
||||
compat_uint_t u;
|
||||
compat_uptr_t p;
|
||||
compat_int_t i;
|
||||
int err;
|
||||
|
||||
err = get_user(u, &init32->init.flags);
|
||||
err |= put_user(u, &init->init.flags);
|
||||
err |= get_user(p, &init32->init.file);
|
||||
err |= put_user(p, &init->init.file);
|
||||
err |= get_user(i, &init32->init.filelen);
|
||||
err |= put_user(i, &init->init.filelen);
|
||||
err |= get_user(i, &init32->init.filefd);
|
||||
err |= put_user(i, &init->init.filefd);
|
||||
err |= get_user(p, &init32->init.mem);
|
||||
err |= put_user(p, &init->init.mem);
|
||||
err |= get_user(i, &init32->init.memlen);
|
||||
err |= put_user(i, &init->init.memlen);
|
||||
err |= get_user(i, &init32->init.memfd);
|
||||
err |= put_user(i, &init->init.memfd);
|
||||
|
||||
err |= put_user(0, &init->attrs);
|
||||
if (cmd == COMPAT_FASTRPC_IOCTL_INIT_ATTRS) {
|
||||
err |= get_user(i, &init32->attrs);
|
||||
err |= put_user(i, (compat_uptr_t *)&init->attrs);
|
||||
}
|
||||
|
||||
err |= put_user(0, &init->siglen);
|
||||
if (cmd == COMPAT_FASTRPC_IOCTL_INIT_ATTRS) {
|
||||
err |= get_user(i, &init32->siglen);
|
||||
err |= put_user(i, (compat_uptr_t *)&init->siglen);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if (!filp->f_op || !filp->f_op->unlocked_ioctl)
|
||||
return -ENOTTY;
|
||||
|
||||
switch (cmd) {
|
||||
case COMPAT_FASTRPC_IOCTL_INVOKE:
|
||||
case COMPAT_FASTRPC_IOCTL_INVOKE_FD:
|
||||
case COMPAT_FASTRPC_IOCTL_INVOKE_ATTRS:
|
||||
case COMPAT_FASTRPC_IOCTL_INVOKE_CRC:
|
||||
{
|
||||
struct compat_fastrpc_ioctl_invoke_crc __user *inv32;
|
||||
struct fastrpc_ioctl_invoke_crc __user *inv;
|
||||
|
||||
inv32 = compat_ptr(arg);
|
||||
VERIFY(err, 0 == compat_get_fastrpc_ioctl_invoke(inv32,
|
||||
&inv, cmd));
|
||||
if (err)
|
||||
return err;
|
||||
return filp->f_op->unlocked_ioctl(filp,
|
||||
FASTRPC_IOCTL_INVOKE_CRC, (unsigned long)inv);
|
||||
}
|
||||
case COMPAT_FASTRPC_IOCTL_MMAP:
|
||||
{
|
||||
struct compat_fastrpc_ioctl_mmap __user *map32;
|
||||
struct fastrpc_ioctl_mmap __user *map;
|
||||
long ret;
|
||||
|
||||
map32 = compat_ptr(arg);
|
||||
VERIFY(err, NULL != (map = compat_alloc_user_space(
|
||||
sizeof(*map))));
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
VERIFY(err, 0 == compat_get_fastrpc_ioctl_mmap(map32, map));
|
||||
if (err)
|
||||
return err;
|
||||
ret = filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_MMAP,
|
||||
(unsigned long)map);
|
||||
if (ret)
|
||||
return ret;
|
||||
VERIFY(err, 0 == compat_put_fastrpc_ioctl_mmap(map32, map));
|
||||
return err;
|
||||
}
|
||||
case COMPAT_FASTRPC_IOCTL_MMAP_64:
|
||||
{
|
||||
struct compat_fastrpc_ioctl_mmap_64 __user *map32;
|
||||
struct fastrpc_ioctl_mmap __user *map;
|
||||
long ret;
|
||||
|
||||
map32 = compat_ptr(arg);
|
||||
VERIFY(err, NULL != (map = compat_alloc_user_space(
|
||||
sizeof(*map))));
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
VERIFY(err, 0 == compat_get_fastrpc_ioctl_mmap_64(map32, map));
|
||||
if (err)
|
||||
return err;
|
||||
ret = filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_MMAP_64,
|
||||
(unsigned long)map);
|
||||
if (ret)
|
||||
return ret;
|
||||
VERIFY(err, 0 == compat_put_fastrpc_ioctl_mmap_64(map32, map));
|
||||
return err;
|
||||
}
|
||||
case COMPAT_FASTRPC_IOCTL_MUNMAP:
|
||||
{
|
||||
struct compat_fastrpc_ioctl_munmap __user *unmap32;
|
||||
struct fastrpc_ioctl_munmap __user *unmap;
|
||||
|
||||
unmap32 = compat_ptr(arg);
|
||||
VERIFY(err, NULL != (unmap = compat_alloc_user_space(
|
||||
sizeof(*unmap))));
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
VERIFY(err, 0 == compat_get_fastrpc_ioctl_munmap(unmap32,
|
||||
unmap));
|
||||
if (err)
|
||||
return err;
|
||||
return filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_MUNMAP,
|
||||
(unsigned long)unmap);
|
||||
}
|
||||
case COMPAT_FASTRPC_IOCTL_MUNMAP_64:
|
||||
{
|
||||
struct compat_fastrpc_ioctl_munmap_64 __user *unmap32;
|
||||
struct fastrpc_ioctl_munmap __user *unmap;
|
||||
|
||||
unmap32 = compat_ptr(arg);
|
||||
VERIFY(err, NULL != (unmap = compat_alloc_user_space(
|
||||
sizeof(*unmap))));
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
VERIFY(err, 0 == compat_get_fastrpc_ioctl_munmap_64(unmap32,
|
||||
unmap));
|
||||
if (err)
|
||||
return err;
|
||||
return filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_MUNMAP_64,
|
||||
(unsigned long)unmap);
|
||||
}
|
||||
case COMPAT_FASTRPC_IOCTL_INIT:
|
||||
/* fall through */
|
||||
case COMPAT_FASTRPC_IOCTL_INIT_ATTRS:
|
||||
{
|
||||
struct compat_fastrpc_ioctl_init_attrs __user *init32;
|
||||
struct fastrpc_ioctl_init_attrs __user *init;
|
||||
|
||||
init32 = compat_ptr(arg);
|
||||
VERIFY(err, NULL != (init = compat_alloc_user_space(
|
||||
sizeof(*init))));
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
VERIFY(err, 0 == compat_get_fastrpc_ioctl_init(init32,
|
||||
init, cmd));
|
||||
if (err)
|
||||
return err;
|
||||
return filp->f_op->unlocked_ioctl(filp,
|
||||
FASTRPC_IOCTL_INIT_ATTRS, (unsigned long)init);
|
||||
}
|
||||
case FASTRPC_IOCTL_GETINFO:
|
||||
{
|
||||
compat_uptr_t __user *info32;
|
||||
uint32_t __user *info;
|
||||
compat_uint_t u;
|
||||
long ret;
|
||||
|
||||
info32 = compat_ptr(arg);
|
||||
VERIFY(err, NULL != (info = compat_alloc_user_space(
|
||||
sizeof(*info))));
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
err = get_user(u, info32);
|
||||
err |= put_user(u, info);
|
||||
if (err)
|
||||
return err;
|
||||
ret = filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_GETINFO,
|
||||
(unsigned long)info);
|
||||
if (ret)
|
||||
return ret;
|
||||
err = get_user(u, info);
|
||||
err |= put_user(u, info32);
|
||||
return err;
|
||||
}
|
||||
case FASTRPC_IOCTL_SETMODE:
|
||||
return filp->f_op->unlocked_ioctl(filp, cmd,
|
||||
(unsigned long)compat_ptr(arg));
|
||||
case COMPAT_FASTRPC_IOCTL_CONTROL:
|
||||
{
|
||||
struct compat_fastrpc_ioctl_control __user *ctrl32;
|
||||
struct fastrpc_ioctl_control __user *ctrl;
|
||||
compat_uptr_t p;
|
||||
|
||||
ctrl32 = compat_ptr(arg);
|
||||
VERIFY(err, NULL != (ctrl = compat_alloc_user_space(
|
||||
sizeof(*ctrl))));
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
VERIFY(err, 0 == compat_get_fastrpc_ioctl_control(ctrl32,
|
||||
ctrl));
|
||||
if (err)
|
||||
return err;
|
||||
err = filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_CONTROL,
|
||||
(unsigned long)ctrl);
|
||||
if (err)
|
||||
return err;
|
||||
err = get_user(p, &ctrl32->req);
|
||||
if (err)
|
||||
return err;
|
||||
if (p == FASTRPC_CONTROL_KALLOC) {
|
||||
err = get_user(p, &ctrl->kalloc.kalloc_support);
|
||||
err |= put_user(p, &ctrl32->kalloc.kalloc_support);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
case COMPAT_FASTRPC_IOCTL_GETPERF:
|
||||
{
|
||||
struct compat_fastrpc_ioctl_perf __user *perf32;
|
||||
struct fastrpc_ioctl_perf *perf;
|
||||
compat_uint_t u;
|
||||
long ret;
|
||||
|
||||
perf32 = compat_ptr(arg);
|
||||
VERIFY(err, NULL != (perf = compat_alloc_user_space(
|
||||
sizeof(*perf))));
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
VERIFY(err, 0 == compat_get_fastrpc_ioctl_perf(perf32,
|
||||
perf));
|
||||
if (err)
|
||||
return err;
|
||||
ret = filp->f_op->unlocked_ioctl(filp, FASTRPC_IOCTL_GETPERF,
|
||||
(unsigned long)perf);
|
||||
if (ret)
|
||||
return ret;
|
||||
err = get_user(u, &perf->numkeys);
|
||||
err |= put_user(u, &perf32->numkeys);
|
||||
return err;
|
||||
}
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
}
|
||||
17
drivers/char/adsprpc_compat.h
Normal file
17
drivers/char/adsprpc_compat.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2014, 2018 The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
#ifndef ADSPRPC_COMPAT_H
|
||||
#define ADSPRPC_COMPAT_H
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
||||
long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
#else
|
||||
|
||||
#define compat_fastrpc_device_ioctl NULL
|
||||
|
||||
#endif /* CONFIG_COMPAT */
|
||||
#endif /* ADSPRPC_COMPAT_H */
|
||||
302
drivers/char/adsprpc_shared.h
Normal file
302
drivers/char/adsprpc_shared.h
Normal file
@@ -0,0 +1,302 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
#ifndef ADSPRPC_SHARED_H
|
||||
#define ADSPRPC_SHARED_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#define FASTRPC_IOCTL_INVOKE _IOWR('R', 1, struct fastrpc_ioctl_invoke)
|
||||
#define FASTRPC_IOCTL_MMAP _IOWR('R', 2, struct fastrpc_ioctl_mmap)
|
||||
#define FASTRPC_IOCTL_MUNMAP _IOWR('R', 3, struct fastrpc_ioctl_munmap)
|
||||
#define FASTRPC_IOCTL_MMAP_64 _IOWR('R', 14, struct fastrpc_ioctl_mmap_64)
|
||||
#define FASTRPC_IOCTL_MUNMAP_64 _IOWR('R', 15, struct fastrpc_ioctl_munmap_64)
|
||||
#define FASTRPC_IOCTL_INVOKE_FD _IOWR('R', 4, struct fastrpc_ioctl_invoke_fd)
|
||||
#define FASTRPC_IOCTL_SETMODE _IOWR('R', 5, uint32_t)
|
||||
#define FASTRPC_IOCTL_INIT _IOWR('R', 6, struct fastrpc_ioctl_init)
|
||||
#define FASTRPC_IOCTL_INVOKE_ATTRS \
|
||||
_IOWR('R', 7, struct fastrpc_ioctl_invoke_attrs)
|
||||
#define FASTRPC_IOCTL_GETINFO _IOWR('R', 8, uint32_t)
|
||||
#define FASTRPC_IOCTL_GETPERF _IOWR('R', 9, struct fastrpc_ioctl_perf)
|
||||
#define FASTRPC_IOCTL_INIT_ATTRS _IOWR('R', 10, struct fastrpc_ioctl_init_attrs)
|
||||
#define FASTRPC_IOCTL_INVOKE_CRC _IOWR('R', 11, struct fastrpc_ioctl_invoke_crc)
|
||||
#define FASTRPC_IOCTL_CONTROL _IOWR('R', 12, struct fastrpc_ioctl_control)
|
||||
#define FASTRPC_IOCTL_MUNMAP_FD _IOWR('R', 13, struct fastrpc_ioctl_munmap_fd)
|
||||
|
||||
#define FASTRPC_GLINK_GUID "fastrpcglink-apps-dsp"
|
||||
#define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp"
|
||||
#define DEVICE_NAME "adsprpc-smd"
|
||||
#define DEVICE_NAME_SECURE "adsprpc-smd-secure"
|
||||
|
||||
/* Set for buffers that have no virtual mapping in userspace */
|
||||
#define FASTRPC_ATTR_NOVA 0x1
|
||||
|
||||
/* Set for buffers that are NOT dma coherent */
|
||||
#define FASTRPC_ATTR_NON_COHERENT 0x2
|
||||
|
||||
/* Set for buffers that are dma coherent */
|
||||
#define FASTRPC_ATTR_COHERENT 0x4
|
||||
|
||||
/* Fastrpc attribute for keeping the map persistent */
|
||||
#define FASTRPC_ATTR_KEEP_MAP 0x8
|
||||
|
||||
/* Fastrpc attribute for no mapping of fd */
|
||||
#define FASTRPC_ATTR_NOMAP (16)
|
||||
|
||||
/* Driver should operate in parallel with the co-processor */
|
||||
#define FASTRPC_MODE_PARALLEL 0
|
||||
|
||||
/* Driver should operate in serial mode with the co-processor */
|
||||
#define FASTRPC_MODE_SERIAL 1
|
||||
|
||||
/* Driver should operate in profile mode with the co-processor */
|
||||
#define FASTRPC_MODE_PROFILE 2
|
||||
|
||||
/* Set FastRPC session ID to 1 */
|
||||
#define FASTRPC_MODE_SESSION 4
|
||||
|
||||
/* INIT a new process or attach to guestos */
|
||||
#define FASTRPC_INIT_ATTACH 0
|
||||
#define FASTRPC_INIT_CREATE 1
|
||||
#define FASTRPC_INIT_CREATE_STATIC 2
|
||||
#define FASTRPC_INIT_ATTACH_SENSORS 3
|
||||
|
||||
/* Retrives number of input buffers from the scalars parameter */
|
||||
#define REMOTE_SCALARS_INBUFS(sc) (((sc) >> 16) & 0x0ff)
|
||||
|
||||
/* Retrives number of output buffers from the scalars parameter */
|
||||
#define REMOTE_SCALARS_OUTBUFS(sc) (((sc) >> 8) & 0x0ff)
|
||||
|
||||
/* Retrives number of input handles from the scalars parameter */
|
||||
#define REMOTE_SCALARS_INHANDLES(sc) (((sc) >> 4) & 0x0f)
|
||||
|
||||
/* Retrives number of output handles from the scalars parameter */
|
||||
#define REMOTE_SCALARS_OUTHANDLES(sc) ((sc) & 0x0f)
|
||||
|
||||
#define REMOTE_SCALARS_LENGTH(sc) (REMOTE_SCALARS_INBUFS(sc) +\
|
||||
REMOTE_SCALARS_OUTBUFS(sc) +\
|
||||
REMOTE_SCALARS_INHANDLES(sc) +\
|
||||
REMOTE_SCALARS_OUTHANDLES(sc))
|
||||
|
||||
#define REMOTE_SCALARS_MAKEX(attr, method, in, out, oin, oout) \
|
||||
((((uint32_t) (attr) & 0x7) << 29) | \
|
||||
(((uint32_t) (method) & 0x1f) << 24) | \
|
||||
(((uint32_t) (in) & 0xff) << 16) | \
|
||||
(((uint32_t) (out) & 0xff) << 8) | \
|
||||
(((uint32_t) (oin) & 0x0f) << 4) | \
|
||||
((uint32_t) (oout) & 0x0f))
|
||||
|
||||
#define REMOTE_SCALARS_MAKE(method, in, out) \
|
||||
REMOTE_SCALARS_MAKEX(0, method, in, out, 0, 0)
|
||||
|
||||
|
||||
#ifndef VERIFY_PRINT_ERROR
|
||||
#define VERIFY_EPRINTF(format, args) (void)0
|
||||
#endif
|
||||
|
||||
#ifndef VERIFY_PRINT_INFO
|
||||
#define VERIFY_IPRINTF(args) (void)0
|
||||
#endif
|
||||
|
||||
#ifndef VERIFY
|
||||
#define __STR__(x) #x ":"
|
||||
#define __TOSTR__(x) __STR__(x)
|
||||
#define __FILE_LINE__ __FILE__ ":" __TOSTR__(__LINE__)
|
||||
|
||||
#define VERIFY(err, val) \
|
||||
do {\
|
||||
VERIFY_IPRINTF(__FILE_LINE__"info: calling: " #val "\n");\
|
||||
if ((val) == 0) {\
|
||||
(err) = (err) == 0 ? -1 : (err);\
|
||||
VERIFY_EPRINTF(__FILE_LINE__"error: %d: " #val "\n", (err));\
|
||||
} else {\
|
||||
VERIFY_IPRINTF(__FILE_LINE__"info: passed: " #val "\n");\
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define remote_arg64_t union remote_arg64
|
||||
|
||||
struct remote_buf64 {
|
||||
uint64_t pv;
|
||||
uint64_t len;
|
||||
};
|
||||
|
||||
struct remote_dma_handle64 {
|
||||
int fd;
|
||||
uint32_t offset;
|
||||
uint32_t len;
|
||||
};
|
||||
|
||||
union remote_arg64 {
|
||||
struct remote_buf64 buf;
|
||||
struct remote_dma_handle64 dma;
|
||||
uint32_t h;
|
||||
};
|
||||
|
||||
#define remote_arg_t union remote_arg
|
||||
|
||||
struct remote_buf {
|
||||
void *pv; /* buffer pointer */
|
||||
size_t len; /* length of buffer */
|
||||
};
|
||||
|
||||
struct remote_dma_handle {
|
||||
int fd;
|
||||
uint32_t offset;
|
||||
};
|
||||
|
||||
union remote_arg {
|
||||
struct remote_buf buf; /* buffer info */
|
||||
struct remote_dma_handle dma;
|
||||
uint32_t h; /* remote handle */
|
||||
};
|
||||
|
||||
struct fastrpc_ioctl_invoke {
|
||||
uint32_t handle; /* remote handle */
|
||||
uint32_t sc; /* scalars describing the data */
|
||||
remote_arg_t *pra; /* remote arguments list */
|
||||
};
|
||||
|
||||
struct fastrpc_ioctl_invoke_fd {
|
||||
struct fastrpc_ioctl_invoke inv;
|
||||
int *fds; /* fd list */
|
||||
};
|
||||
|
||||
struct fastrpc_ioctl_invoke_attrs {
|
||||
struct fastrpc_ioctl_invoke inv;
|
||||
int *fds; /* fd list */
|
||||
unsigned int *attrs; /* attribute list */
|
||||
};
|
||||
|
||||
struct fastrpc_ioctl_invoke_crc {
|
||||
struct fastrpc_ioctl_invoke inv;
|
||||
int *fds; /* fd list */
|
||||
unsigned int *attrs; /* attribute list */
|
||||
unsigned int *crc;
|
||||
};
|
||||
|
||||
struct fastrpc_ioctl_init {
|
||||
uint32_t flags; /* one of FASTRPC_INIT_* macros */
|
||||
uintptr_t file; /* pointer to elf file */
|
||||
uint32_t filelen; /* elf file length */
|
||||
int32_t filefd; /* ION fd for the file */
|
||||
uintptr_t mem; /* mem for the PD */
|
||||
uint32_t memlen; /* mem length */
|
||||
int32_t memfd; /* ION fd for the mem */
|
||||
};
|
||||
|
||||
struct fastrpc_ioctl_init_attrs {
|
||||
struct fastrpc_ioctl_init init;
|
||||
int attrs;
|
||||
unsigned int siglen;
|
||||
};
|
||||
|
||||
struct fastrpc_ioctl_munmap {
|
||||
uintptr_t vaddrout; /* address to unmap */
|
||||
size_t size; /* size */
|
||||
};
|
||||
|
||||
struct fastrpc_ioctl_munmap_64 {
|
||||
uint64_t vaddrout; /* address to unmap */
|
||||
size_t size; /* size */
|
||||
};
|
||||
|
||||
struct fastrpc_ioctl_mmap {
|
||||
int fd; /* ion fd */
|
||||
uint32_t flags; /* flags for dsp to map with */
|
||||
uintptr_t vaddrin; /* optional virtual address */
|
||||
size_t size; /* size */
|
||||
uintptr_t vaddrout; /* dsps virtual address */
|
||||
};
|
||||
|
||||
struct fastrpc_ioctl_mmap_64 {
|
||||
int fd; /* ion fd */
|
||||
uint32_t flags; /* flags for dsp to map with */
|
||||
uint64_t vaddrin; /* optional virtual address */
|
||||
size_t size; /* size */
|
||||
uint64_t vaddrout; /* dsps virtual address */
|
||||
};
|
||||
|
||||
struct fastrpc_ioctl_munmap_fd {
|
||||
int fd; /* fd */
|
||||
uint32_t flags; /* control flags */
|
||||
uintptr_t va; /* va */
|
||||
ssize_t len; /* length */
|
||||
};
|
||||
|
||||
struct fastrpc_ioctl_perf { /* kernel performance data */
|
||||
uintptr_t data;
|
||||
uint32_t numkeys;
|
||||
uintptr_t keys;
|
||||
};
|
||||
|
||||
#define FASTRPC_CONTROL_LATENCY (1)
|
||||
struct fastrpc_ctrl_latency {
|
||||
uint32_t enable; /* latency control enable */
|
||||
uint32_t level; /* level of control */
|
||||
};
|
||||
|
||||
#define FASTRPC_CONTROL_KALLOC (3)
|
||||
struct fastrpc_ctrl_kalloc {
|
||||
uint32_t kalloc_support; /* Remote memory allocation from kernel */
|
||||
};
|
||||
/* FASTRPC_CONTROL value 2 is reserved in user space */
|
||||
struct fastrpc_ioctl_control {
|
||||
uint32_t req;
|
||||
union {
|
||||
struct fastrpc_ctrl_latency lp;
|
||||
struct fastrpc_ctrl_kalloc kalloc;
|
||||
};
|
||||
};
|
||||
|
||||
struct smq_null_invoke {
|
||||
uint64_t ctx; /* invoke caller context */
|
||||
uint32_t handle; /* handle to invoke */
|
||||
uint32_t sc; /* scalars structure describing the data */
|
||||
};
|
||||
|
||||
struct smq_phy_page {
|
||||
uint64_t addr; /* physical address */
|
||||
uint64_t size; /* size of contiguous region */
|
||||
};
|
||||
|
||||
struct smq_invoke_buf {
|
||||
int num; /* number of contiguous regions */
|
||||
int pgidx; /* index to start of contiguous region */
|
||||
};
|
||||
|
||||
struct smq_invoke {
|
||||
struct smq_null_invoke header;
|
||||
struct smq_phy_page page; /* remote arg and list of pages address */
|
||||
};
|
||||
|
||||
struct smq_msg {
|
||||
uint32_t pid; /* process group id */
|
||||
uint32_t tid; /* thread id */
|
||||
struct smq_invoke invoke;
|
||||
};
|
||||
|
||||
struct smq_invoke_rsp {
|
||||
uint64_t ctx; /* invoke caller context */
|
||||
int retval; /* invoke return value */
|
||||
};
|
||||
|
||||
static inline struct smq_invoke_buf *smq_invoke_buf_start(remote_arg64_t *pra,
|
||||
uint32_t sc)
|
||||
{
|
||||
unsigned int len = REMOTE_SCALARS_LENGTH(sc);
|
||||
|
||||
return (struct smq_invoke_buf *)(&pra[len]);
|
||||
}
|
||||
|
||||
static inline struct smq_phy_page *smq_phy_page_start(uint32_t sc,
|
||||
struct smq_invoke_buf *buf)
|
||||
{
|
||||
unsigned int nTotal = REMOTE_SCALARS_LENGTH(sc);
|
||||
|
||||
return (struct smq_phy_page *)(&buf[nTotal]);
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user