Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 56701ce3 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: adsprpc: API to get DSP capability"

parents 9018c921 3357850e
Loading
Loading
Loading
Loading
+158 −13
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@
#include <soc/qcom/ramdump.h>
#include <linux/debugfs.h>
#include <linux/pm_qos.h>
#include <linux/stat.h>

#define TZ_PIL_PROTECT_MEM_SUBSYS_ID 0x0C
#define TZ_PIL_CLEAR_PROTECT_MEM_SUBSYS_ID 0x0D
@@ -99,7 +100,8 @@

#define PERF_KEYS \
	"count:flush:map:copy:rpmsg:getargs:putargs:invalidate:invoke:tid:ptr"
#define FASTRPC_STATIC_HANDLE_KERNEL (1)
#define FASTRPC_STATIC_HANDLE_PROCESS_GROUP (1)
#define FASTRPC_STATIC_HANDLE_DSP_UTILITIES (2)
#define FASTRPC_STATIC_HANDLE_LISTENER (3)
#define FASTRPC_STATIC_HANDLE_MAX (20)
#define FASTRPC_LATENCY_CTRL_ENB  (1)
@@ -287,6 +289,7 @@ struct fastrpc_channel_ctx {
	void *remoteheap_ramdump_dev;
	/* Indicates, if channel is restricted to secure node only */
	int secure;
	struct fastrpc_dsp_capabilities dsp_cap_kernel;
};

struct fastrpc_apps {
@@ -1856,10 +1859,13 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode,
		getnstimeofday(&invoket);

	if (!kernel) {
		VERIFY(err, invoke->handle != FASTRPC_STATIC_HANDLE_KERNEL);
		VERIFY(err, invoke->handle !=
			FASTRPC_STATIC_HANDLE_PROCESS_GROUP);
		VERIFY(err, invoke->handle !=
			FASTRPC_STATIC_HANDLE_DSP_UTILITIES);
		if (err) {
			pr_err("adsprpc: ERROR: %s: user application %s trying to send a kernel RPC message to channel %d",
				__func__, current->comm, cid);
			pr_err("adsprpc: ERROR: %s: user application %s trying to send a kernel RPC message to channel %d, handle 0x%x",
				__func__, current->comm, cid, invoke->handle);
			goto bail;
		}
	}
@@ -2002,7 +2008,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl,

		ra[0].buf.pv = (void *)&tgid;
		ra[0].buf.len = sizeof(tgid);
		ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
		ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
		ioctl.inv.sc = REMOTE_SCALARS_MAKE(0, 1, 0);
		ioctl.inv.pra = ra;
		ioctl.fds = NULL;
@@ -2099,7 +2105,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl,
		ra[5].buf.len = sizeof(inbuf.siglen);
		fds[5] = 0;

		ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
		ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
		ioctl.inv.sc = REMOTE_SCALARS_MAKE(6, 4, 0);
		if (uproc->attrs)
			ioctl.inv.sc = REMOTE_SCALARS_MAKE(7, 6, 0);
@@ -2188,7 +2194,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl,
		ra[2].buf.pv = (void *)pages;
		ra[2].buf.len = sizeof(*pages);
		fds[2] = 0;
		ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
		ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;

		ioctl.inv.sc = REMOTE_SCALARS_MAKE(8, 3, 0);
		ioctl.inv.pra = ra;
@@ -2227,6 +2233,137 @@ static int fastrpc_init_process(struct fastrpc_file *fl,
	return err;
}

static int fastrpc_kstat(const char *filename, struct kstat *stat)
{
	int result;
	mm_segment_t fs_old;

	fs_old = get_fs();
	set_fs(KERNEL_DS);
	result = vfs_stat((const char __user *)filename, stat);
	set_fs(fs_old);

	return result;
}

static int fastrpc_get_info_from_dsp(struct fastrpc_file *fl,
				uint32_t *dsp_attr, uint32_t dsp_attr_size,
				uint32_t domain)
{
	int err = 0, dsp_cap_buff_size, dsp_support = 0;
	struct fastrpc_ioctl_invoke_crc ioctl;
	remote_arg_t ra[2];
	struct kstat sb;

	// Querying device about DSP support
	switch (domain) {
	case ADSP_DOMAIN_ID:
		if (!fastrpc_kstat("/dev/subsys_adsp", &sb))
			dsp_support = 1;
		break;
	case MDSP_DOMAIN_ID:
		//Modem not supported for fastRPC
		break;
	case SDSP_DOMAIN_ID:
		if (!fastrpc_kstat("/dev/subsys_slpi", &sb))
			dsp_support = 1;
		break;
	case CDSP_DOMAIN_ID:
		if (!fastrpc_kstat("/dev/subsys_cdsp", &sb))
			dsp_support = 1;
		break;
	default:
		dsp_support = 0;
		break;
	}
	dsp_attr[0] = dsp_support;

	// If domain not supported, skip querying capabilities
	if (dsp_support == 0)
		goto bail;

	err = fastrpc_channel_open(fl);
	if (err)
		goto bail;

	dsp_cap_buff_size = dsp_attr_size - sizeof(uint32_t);
	ra[0].buf.pv = (void *)&dsp_cap_buff_size;
	ra[0].buf.len = sizeof(dsp_cap_buff_size);
	ra[1].buf.pv = (void *)(&dsp_attr[1]);
	ra[1].buf.len = dsp_cap_buff_size * sizeof(uint32_t);
	ioctl.inv.handle = FASTRPC_STATIC_HANDLE_DSP_UTILITIES;
	ioctl.inv.sc = REMOTE_SCALARS_MAKE(0, 1, 1);
	ioctl.inv.pra = ra;
	ioctl.fds = NULL;
	ioctl.attrs = NULL;
	ioctl.crc = NULL;
	fl->pd = 1;

	// Querying DSP about capabilities support
	err = fastrpc_internal_invoke(fl, FASTRPC_MODE_PARALLEL, 1, &ioctl);
bail:
	if (err)
		pr_err("adsprpc: %s: %s: could not obtain dsp information, err val 0x%x",
				current->comm, __func__, err);
	return err;
}

static int fastrpc_get_info_from_kernel(
		struct fastrpc_dsp_capabilities *dsp_cap,
		struct fastrpc_file *fl)
{
	int err = 0;
	uint32_t domain_support;
	uint32_t domain = dsp_cap->domain;

	if (!gcinfo[domain].dsp_cap_kernel.is_cached) {
		/*
		 * Information not on kernel, query device for information
		 * and cache on kernel
		 */
		err = fastrpc_get_info_from_dsp(fl, dsp_cap->dsp_attributes,
				sizeof(dsp_cap->dsp_attributes),
				domain);
		if (err)
			goto bail;

		domain_support = dsp_cap->dsp_attributes[0];
		switch (domain_support) {
		case 0:
			memset(dsp_cap->dsp_attributes, 0,
				sizeof(dsp_cap->dsp_attributes));
			memset(&gcinfo[domain].dsp_cap_kernel.dsp_attributes,
				0, sizeof(dsp_cap->dsp_attributes));
			break;
		case 1:
			memcpy(&gcinfo[domain].dsp_cap_kernel.dsp_attributes,
				dsp_cap->dsp_attributes,
				sizeof(dsp_cap->dsp_attributes));
			break;
		default:
			err = -1;
			/*
			 * Reset is_cached flag to 0 so subsequent calls
			 * can try to query dsp again
			 */
			gcinfo[domain].dsp_cap_kernel.is_cached = 0;
			pr_warn("adsprpc: %s: %s: returned bad domain support value %d",
					current->comm,
					__func__,
					domain_support);
			goto bail;
		}
		gcinfo[domain].dsp_cap_kernel.is_cached = 1;
	} else {
		// Information on Kernel, pass it to user
		memcpy(dsp_cap->dsp_attributes,
			&gcinfo[domain].dsp_cap_kernel.dsp_attributes,
			sizeof(dsp_cap->dsp_attributes));
	}
bail:
	return err;
}

static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl)
{
	int err = 0;
@@ -2249,7 +2386,7 @@ static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl)
	tgid = fl->tgid;
	ra[0].buf.pv = (void *)&tgid;
	ra[0].buf.len = sizeof(tgid);
	ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
	ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
	ioctl.inv.sc = REMOTE_SCALARS_MAKE(1, 1, 0);
	ioctl.inv.pra = ra;
	ioctl.fds = NULL;
@@ -2298,7 +2435,7 @@ static int fastrpc_mmap_on_dsp(struct fastrpc_file *fl, uint32_t flags,
	ra[2].buf.pv = (void *)&routargs;
	ra[2].buf.len = sizeof(routargs);

	ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
	ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
	if (fl->apps->compat)
		ioctl.inv.sc = REMOTE_SCALARS_MAKE(4, 2, 1);
	else
@@ -2361,7 +2498,7 @@ static int fastrpc_munmap_on_dsp_rh(struct fastrpc_file *fl, uint64_t phys,
		ra[1].buf.pv = (void *)&routargs;
		ra[1].buf.len = sizeof(routargs);

		ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
		ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
		ioctl.inv.sc = REMOTE_SCALARS_MAKE(9, 1, 1);
		ioctl.inv.pra = ra;
		ioctl.fds = NULL;
@@ -2413,7 +2550,7 @@ static int fastrpc_munmap_on_dsp(struct fastrpc_file *fl, uintptr_t raddr,
	ra[0].buf.pv = (void *)&inargs;
	ra[0].buf.len = sizeof(inargs);

	ioctl.inv.handle = FASTRPC_STATIC_HANDLE_KERNEL;
	ioctl.inv.handle = FASTRPC_STATIC_HANDLE_PROCESS_GROUP;
	if (fl->apps->compat)
		ioctl.inv.sc = REMOTE_SCALARS_MAKE(5, 1, 0);
	else
@@ -3347,6 +3484,14 @@ static int fastrpc_internal_control(struct fastrpc_file *fl,
	case FASTRPC_CONTROL_KALLOC:
		cp->kalloc.kalloc_support = 1;
		break;
	case FASTRPC_GET_DSP_INFO:
		VERIFY(err, cp->dsp_cap.domain < NUM_CHANNELS);
		if (err)
			goto bail;
		err = fastrpc_get_info_from_kernel(&cp->dsp_cap, fl);
		if (err)
			goto bail;
		break;
	default:
		err = -ENOTTY;
		break;
@@ -3533,7 +3678,8 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
		VERIFY(err, 0 == (err = fastrpc_internal_control(fl, &p.cp)));
		if (err)
			goto bail;
		if (p.cp.req == FASTRPC_CONTROL_KALLOC) {
		if (p.cp.req == FASTRPC_CONTROL_KALLOC ||
				p.cp.req == FASTRPC_GET_DSP_INFO) {
			K_COPY_TO_USER(err, 0, param, &p.cp, sizeof(p.cp));
			if (err)
				goto bail;
@@ -3573,7 +3719,6 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int ioctl_num,
		if (err)
			goto bail;
		break;

	default:
		err = -ENOTTY;
		pr_info("bad ioctl: %d\n", ioctl_num);
+31 −2
Original line number Diff line number Diff line
/*
 * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -137,11 +137,18 @@ struct compat_fastrpc_ctrl_kalloc {
	compat_uint_t kalloc_support; /* Remote memory allocation from kernel */
};

#define FASTRPC_GET_DSP_INFO		(4)
struct compat_fastrpc_dsp_capabilities {
	compat_uint_t domain;	/* DSP domain to query capabilities */
	compat_uint_t dsp_attributes[FASTRPC_MAX_DSP_ATTRIBUTES];
};

struct compat_fastrpc_ioctl_control {
	compat_uint_t req;
	union {
		struct compat_fastrpc_ctrl_latency lp;
		struct compat_fastrpc_ctrl_kalloc kalloc;
		struct compat_fastrpc_dsp_capabilities dsp_cap;
	};
};

@@ -338,6 +345,9 @@ static int compat_get_fastrpc_ioctl_control(
		err |= put_user(p, &ctrl->lp.enable);
		err |= get_user(p, &ctrl32->lp.level);
		err |= put_user(p, &ctrl->lp.level);
	} else if (p == FASTRPC_GET_DSP_INFO) {
		err |= get_user(p, &ctrl32->dsp_cap.domain);
		err |= put_user(p, &ctrl->dsp_cap.domain);
	}

	return err;
@@ -383,6 +393,23 @@ static int compat_get_fastrpc_ioctl_init(
	return err;
}

static int compat_put_fastrpc_get_dsp_info(
		struct compat_fastrpc_ioctl_control __user *ctrl32,
		struct fastrpc_ioctl_control __user *ctrl)
{
	compat_uint_t u, *dsp_attr, *dsp_attr_32;
	int err, ii;

	dsp_attr = ctrl->dsp_cap.dsp_attributes;
	dsp_attr_32 = ctrl32->dsp_cap.dsp_attributes;
	for (ii = 0, err = 0; ii < FASTRPC_MAX_DSP_ATTRIBUTES; ii++) {
		err |= get_user(u, dsp_attr++);
		err |= put_user(u, dsp_attr_32++);
	}

	return err;
}

long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd,
				unsigned long arg)
{
@@ -555,7 +582,9 @@ long compat_fastrpc_device_ioctl(struct file *filp, unsigned int cmd,
		if (p == FASTRPC_CONTROL_KALLOC) {
			err = get_user(p, &ctrl->kalloc.kalloc_support);
			err |= put_user(p, &ctrl32->kalloc.kalloc_support);
		}
		} else if (p == FASTRPC_GET_DSP_INFO)
			err |= compat_put_fastrpc_get_dsp_info(ctrl32, ctrl);

		return err;
	}
	case COMPAT_FASTRPC_IOCTL_GETPERF:
+13 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -241,6 +241,8 @@ struct fastrpc_ioctl_perf { /* kernel performance data */
	uintptr_t keys;
};

#define FASTRPC_MAX_DSP_ATTRIBUTES	(7)

#define FASTRPC_CONTROL_LATENCY	(1)
struct fastrpc_ctrl_latency {
	uint32_t enable;	/* latency control enable */
@@ -252,11 +254,21 @@ struct fastrpc_ctrl_kalloc {
	uint32_t kalloc_support;  /* Remote memory allocation from kernel */
};
/* FASTRPC_CONTROL value 2 is reserved in user space */

#define FASTRPC_GET_DSP_INFO	(4)
struct fastrpc_dsp_capabilities {
	union {
		uint32_t is_cached;	//! Flag if dsp attributes are cached
		uint32_t domain;	//! DSP domain to query capabilities
	};
	uint32_t dsp_attributes[FASTRPC_MAX_DSP_ATTRIBUTES];
};
struct fastrpc_ioctl_control {
	uint32_t req;
	union {
		struct fastrpc_ctrl_latency lp;
		struct fastrpc_ctrl_kalloc kalloc;
		struct fastrpc_dsp_capabilities dsp_cap;
	};
};