Beispiel #1
0
static ssize_t nvhost_channelwrite(struct file *filp, const char __user *buf,
				size_t count, loff_t *offp)
{
	struct nvhost_channel_userctx *priv = filp->private_data;
	size_t remaining = count;
	int err = 0;

	while (remaining) {
		size_t consumed;
		if (!priv->hdr.num_relocs &&
		    !priv->hdr.num_cmdbufs &&
		    !priv->hdr.num_waitchks) {
			consumed = sizeof(struct nvhost_submit_hdr);
			if (remaining < consumed)
				break;
			if (copy_from_user(&priv->hdr, buf, consumed)) {
				err = -EFAULT;
				break;
			}
			priv->hdr.submit_version = NVHOST_SUBMIT_VERSION_V0;
			err = set_submit(priv);
			if (err)
				break;
			trace_nvhost_channel_write_submit(priv->ch->desc->name,
			  count, priv->hdr.num_cmdbufs, priv->hdr.num_relocs);
		} else if (priv->hdr.num_cmdbufs) {
			struct nvhost_cmdbuf cmdbuf;
			consumed = sizeof(cmdbuf);
			if (remaining < consumed)
				break;
			if (copy_from_user(&cmdbuf, buf, consumed)) {
				err = -EFAULT;
				break;
			}
			trace_nvhost_channel_write_cmdbuf(priv->ch->desc->name,
			  cmdbuf.mem, cmdbuf.words, cmdbuf.offset);
			add_gather(priv,
				cmdbuf.mem, cmdbuf.words, cmdbuf.offset);
			priv->hdr.num_cmdbufs--;
		} else if (priv->hdr.num_relocs) {
			int numrelocs = remaining / sizeof(struct nvhost_reloc);
			if (!numrelocs)
				break;
			numrelocs = min_t(int, numrelocs, priv->hdr.num_relocs);
			consumed = numrelocs * sizeof(struct nvhost_reloc);
			if (copy_from_user(&priv->pinarray[priv->pinarray_size],
						buf, consumed)) {
				err = -EFAULT;
				break;
			}
			trace_nvhost_channel_write_relocs(priv->ch->desc->name,
			  numrelocs);
			priv->pinarray_size += numrelocs;
			priv->hdr.num_relocs -= numrelocs;
		} else if (priv->hdr.num_waitchks) {
Beispiel #2
0
void Submit_manager::getSummitList(QString data)
{
    QStringList para = api_http->getParsData(data);
    int i = 0;

    listCnt=0;

    for(i=0;i<para.size();)
    {
        if(para.at(i)==PK_REPORTSUBMIT)
        {list[listCnt].pk_reportSubmit = para.at(++i);}

        // 위와 같은 학번이므로 생략
        else if(para.at(i)==FK_STUDENT)
        {list[listCnt].fk_student = para.at(++i);}

        else if(para.at(i)==FK_REPORT)
        {list[listCnt].fk_report = para.at(++i);}

        else if(para.at(i)==TIME)
        {list[listCnt].time = para.at(++i);}

        else if(para.at(i)==FILEURL)
        {list[listCnt].fileURL = para.at(++i);}

        else if(para.at(i)==EXTENSION)
        {list[listCnt].extension = para.at(++i);}

        else if(para.at(i)==MODIFIED)
        {list[listCnt].modified = para.at(++i);}

        else if(para.at(i)==OPENED)
        {list[listCnt++].opened = para.at(++i);}
        i++ ;
    }

    set_submit();
}
static ssize_t nvhost_channelwrite(struct file *filp, const char __user *buf,
				size_t count, loff_t *offp)
{
	struct nvhost_channel_userctx *priv = filp->private_data;
	size_t remaining = count;
	int err = 0;
	struct nvhost_job *job = priv->job;
	struct nvhost_submit_hdr_ext *hdr = &priv->hdr;
	const char *chname = priv->ch->desc->name;

	while (remaining) {
		size_t consumed;
		if (!hdr->num_relocs &&
		    !priv->num_relocshifts &&
		    !hdr->num_cmdbufs &&
		    !hdr->num_waitchks) {
			consumed = sizeof(struct nvhost_submit_hdr);
			if (remaining < consumed)
				break;
			if (copy_from_user(hdr, buf, consumed)) {
				err = -EFAULT;
				break;
			}
			hdr->submit_version = NVHOST_SUBMIT_VERSION_V0;
			err = set_submit(priv);
			if (err)
				break;
			trace_nvhost_channel_write_submit(chname,
			  count, hdr->num_cmdbufs, hdr->num_relocs,
			  hdr->syncpt_id, hdr->syncpt_incrs);
		} else if (hdr->num_cmdbufs) {
			struct nvhost_cmdbuf cmdbuf;
			consumed = sizeof(cmdbuf);
			if (remaining < consumed)
				break;
			if (copy_from_user(&cmdbuf, buf, consumed)) {
				err = -EFAULT;
				break;
			}
			trace_nvhost_channel_write_cmdbuf(chname,
				cmdbuf.mem, cmdbuf.words, cmdbuf.offset);
			nvhost_job_add_gather(job,
				cmdbuf.mem, cmdbuf.words, cmdbuf.offset);
			hdr->num_cmdbufs--;
		} else if (hdr->num_relocs) {
			consumed = sizeof(struct nvhost_reloc);
			if (remaining < consumed)
				break;
			if (copy_from_user(&job->pinarray[job->num_pins],
					buf, consumed)) {
				err = -EFAULT;
				break;
			}
			trace_nvhost_channel_write_reloc(chname);
			job->num_pins++;
			hdr->num_relocs--;
		} else if (hdr->num_waitchks) {
			int numwaitchks =
				(remaining / sizeof(struct nvhost_waitchk));
			if (!numwaitchks)
				break;
			numwaitchks = min_t(int,
				numwaitchks, hdr->num_waitchks);
			consumed = numwaitchks * sizeof(struct nvhost_waitchk);
			if (copy_from_user(&job->waitchk[job->num_waitchk],
					buf, consumed)) {
				err = -EFAULT;
				break;
			}
			trace_nvhost_channel_write_waitchks(
			  chname, numwaitchks,
			  hdr->waitchk_mask);
			job->num_waitchk += numwaitchks;
			hdr->num_waitchks -= numwaitchks;
		} else if (priv->num_relocshifts) {
static ssize_t nvhost_channelwrite(struct file *filp, const char __user *buf,
				size_t count, loff_t *offp)
{
	struct nvhost_channel_userctx *priv = filp->private_data;
	size_t remaining = count;
	int err = 0;
	struct nvhost_job *job;
	struct nvhost_submit_hdr_ext *hdr;
	const char *chname;

	mutex_lock(&priv->mutex);

	job = priv->job;
	hdr = &priv->hdr;
	chname = priv->ch->dev->name;

	if (!job) {
		mutex_unlock(&priv->mutex);
		return -EIO;
	}
	while (remaining) {
		size_t consumed;
		if (!hdr->num_relocs &&
		    !priv->num_relocshifts &&
		    !hdr->num_cmdbufs &&
		    !hdr->num_waitchks) {
			consumed = sizeof(struct nvhost_submit_hdr);
			if (remaining < consumed)
				break;
			if (copy_from_user(hdr, buf, consumed)) {
				err = -EFAULT;
				break;
			}
			hdr->submit_version = NVHOST_SUBMIT_VERSION_V0;
			err = set_submit(priv);
			if (err)
				break;
			trace_nvhost_channel_write_submit(chname,
			  count, hdr->num_cmdbufs, hdr->num_relocs,
			  hdr->syncpt_id, hdr->syncpt_incrs);
		} else if (hdr->num_cmdbufs) {
			struct nvhost_cmdbuf cmdbuf;
			consumed = sizeof(cmdbuf);
			if (remaining < consumed)
				break;
			if (copy_from_user(&cmdbuf, buf, consumed)) {
				err = -EFAULT;
				break;
			}
			trace_nvhost_channel_write_cmdbuf(chname,
				cmdbuf.mem, cmdbuf.words, cmdbuf.offset);
			nvhost_job_add_gather(job,
				cmdbuf.mem, cmdbuf.words, cmdbuf.offset);
			hdr->num_cmdbufs--;
		} else if (hdr->num_relocs) {
			int numrelocs = remaining / sizeof(struct nvhost_reloc);
			if (!numrelocs)
				break;
			numrelocs = min_t(int, numrelocs, priv->hdr.num_relocs);
			consumed = numrelocs * sizeof(struct nvhost_reloc);
			if (copy_from_user(&job->relocarray[job->num_relocs],
					buf, consumed)) {
				err = -EFAULT;
				break;
			}
			while (numrelocs) {
				struct nvhost_reloc *reloc =
					&job->relocarray[job->num_relocs];
				trace_nvhost_channel_write_reloc(chname,
					reloc->cmdbuf_mem,
					reloc->cmdbuf_offset,
					reloc->target,
					reloc->target_offset);
				job->num_relocs++;
				hdr->num_relocs--;
				numrelocs--;
			}
		} else if (hdr->num_waitchks) {
Beispiel #5
0
static long nvhost_channelctl(struct file *filp,
	unsigned int cmd, unsigned long arg)
{
	struct nvhost_channel_userctx *priv = filp->private_data;
	u8 buf[NVHOST_IOCTL_CHANNEL_MAX_ARG_SIZE];
	int err = 0;

	if ((_IOC_TYPE(cmd) != NVHOST_IOCTL_MAGIC) ||
		(_IOC_NR(cmd) == 0) ||
		(_IOC_NR(cmd) > NVHOST_IOCTL_CHANNEL_LAST))
		return -EFAULT;

	BUG_ON(_IOC_SIZE(cmd) > NVHOST_IOCTL_CHANNEL_MAX_ARG_SIZE);

	if (_IOC_DIR(cmd) & _IOC_WRITE) {
		if (copy_from_user(buf, (void __user *)arg, _IOC_SIZE(cmd)))
			return -EFAULT;
	}

	switch (cmd) {
	case NVHOST_IOCTL_CHANNEL_FLUSH:
		err = nvhost_ioctl_channel_flush(priv, (void *)buf, 0);
		break;
	case NVHOST_IOCTL_CHANNEL_NULL_KICKOFF:
		err = nvhost_ioctl_channel_flush(priv, (void *)buf, 1);
		break;
	case NVHOST_IOCTL_CHANNEL_SUBMIT_EXT:
	{
		struct nvhost_submit_hdr_ext *hdr;

		if (priv->hdr.num_relocs ||
		    priv->num_relocshifts ||
		    priv->hdr.num_cmdbufs ||
		    priv->hdr.num_waitchks) {
			reset_submit(priv);
			dev_err(&priv->ch->dev->pdev->dev,
				"channel submit out of sync\n");
			err = -EIO;
			break;
		}

		hdr = (struct nvhost_submit_hdr_ext *)buf;
		if (hdr->submit_version > NVHOST_SUBMIT_VERSION_MAX_SUPPORTED) {
			dev_err(&priv->ch->dev->pdev->dev,
				"submit version %d > max supported %d\n",
				hdr->submit_version,
				NVHOST_SUBMIT_VERSION_MAX_SUPPORTED);
			err = -EINVAL;
			break;
		}
		memcpy(&priv->hdr, hdr, sizeof(struct nvhost_submit_hdr_ext));
		err = set_submit(priv);
		trace_nvhost_ioctl_channel_submit(priv->ch->desc->name,
			priv->hdr.submit_version,
			priv->hdr.num_cmdbufs, priv->hdr.num_relocs,
			priv->hdr.num_waitchks,
			priv->hdr.syncpt_id, priv->hdr.syncpt_incrs);
		break;
	}
	case NVHOST_IOCTL_CHANNEL_GET_SYNCPOINTS:
		/* host syncpt ID is used by the RM (and never be given out) */
		BUG_ON(priv->ch->desc->syncpts & (1 << NVSYNCPT_GRAPHICS_HOST));
		((struct nvhost_get_param_args *)buf)->value =
			priv->ch->desc->syncpts;
		break;
	case NVHOST_IOCTL_CHANNEL_GET_WAITBASES:
		((struct nvhost_get_param_args *)buf)->value =
			priv->ch->desc->waitbases;
		break;
	case NVHOST_IOCTL_CHANNEL_GET_MODMUTEXES:
		((struct nvhost_get_param_args *)buf)->value =
			priv->ch->desc->modulemutexes;
		break;
	case NVHOST_IOCTL_CHANNEL_SET_NVMAP_FD:
	{
		int fd = (int)((struct nvhost_set_nvmap_fd_args *)buf)->fd;
		struct nvmap_client *new_client = nvmap_client_get_file(fd);

		if (IS_ERR(new_client)) {
			err = PTR_ERR(new_client);
			break;
		}

		if (priv->nvmap)
			nvmap_client_put(priv->nvmap);

		priv->nvmap = new_client;
		break;
	}
	case NVHOST_IOCTL_CHANNEL_READ_3D_REG:
		err = nvhost_ioctl_channel_read_3d_reg(priv, (void *)buf);
		break;
	case NVHOST_IOCTL_CHANNEL_GET_CLK_RATE:
	{
		unsigned long rate;
		struct nvhost_clk_rate_args *arg =
				(struct nvhost_clk_rate_args *)buf;

		err = nvhost_module_get_rate(priv->ch->dev,
				&priv->ch->mod, &rate, 0);
		if (err == 0)
			arg->rate = rate;
		break;
	}
	case NVHOST_IOCTL_CHANNEL_SET_CLK_RATE:
	{
		struct nvhost_clk_rate_args *arg =
				(struct nvhost_clk_rate_args *)buf;
		unsigned long rate = (unsigned long)arg->rate;

		err = nvhost_module_set_rate(priv->ch->dev,
				&priv->ch->mod, priv, rate, 0);
		break;
	}
	case NVHOST_IOCTL_CHANNEL_SET_TIMEOUT:
		priv->timeout =
			(u32)((struct nvhost_set_timeout_args *)buf)->timeout;
		dev_dbg(&priv->ch->dev->pdev->dev,
			"%s: setting buffer timeout (%d ms) for userctx 0x%p\n",
			__func__, priv->timeout, priv);
		break;
	case NVHOST_IOCTL_CHANNEL_GET_TIMEDOUT:
		((struct nvhost_get_param_args *)buf)->value =
				priv->hwctx->has_timedout;
		break;
	case NVHOST_IOCTL_CHANNEL_SET_PRIORITY:
		priv->priority =
			(u32)((struct nvhost_set_priority_args *)buf)->priority;
		break;
	default:
		err = -ENOTTY;
		break;
	}

	if ((err == 0) && (_IOC_DIR(cmd) & _IOC_READ))
		err = copy_to_user((void __user *)arg, buf, _IOC_SIZE(cmd));

	return err;
}
Beispiel #6
0
static ssize_t nvhost_channelwrite(struct file *filp, const char __user *buf,
				size_t count, loff_t *offp)
{
	struct nvhost_channel_userctx *priv = filp->private_data;
	size_t remaining = count;
	int err = 0;
	struct nvhost_job *job = priv->job;
	struct nvhost_submit_hdr_ext *hdr = &priv->hdr;
	const char *chname = priv->ch->desc->name;

	if (!job)
		return -ENOMEM;

	while (remaining) {
		size_t consumed;
		if (!hdr->num_relocs &&
		    !priv->num_relocshifts &&
		    !hdr->num_cmdbufs &&
		    !hdr->num_waitchks) {
			consumed = sizeof(struct nvhost_submit_hdr);
			if (remaining < consumed)
				break;
			if (copy_from_user(hdr, buf, consumed)) {
				err = -EFAULT;
				break;
			}
			hdr->submit_version = NVHOST_SUBMIT_VERSION_V0;
			err = set_submit(priv);
			if (err)
				break;
			trace_nvhost_channel_write_submit(chname,
			  count, hdr->num_cmdbufs, hdr->num_relocs,
			  hdr->syncpt_id, hdr->syncpt_incrs);
		} else if (hdr->num_cmdbufs) {
			struct nvhost_cmdbuf cmdbuf;
			consumed = sizeof(cmdbuf);
			if (remaining < consumed)
				break;
			if (copy_from_user(&cmdbuf, buf, consumed)) {
				err = -EFAULT;
				break;
			}
			trace_nvhost_channel_write_cmdbuf(chname,
				cmdbuf.mem, cmdbuf.words, cmdbuf.offset);
			nvhost_job_add_gather(job,
				cmdbuf.mem, cmdbuf.words, cmdbuf.offset);
			hdr->num_cmdbufs--;
		} else if (hdr->num_relocs) {
			struct nvmap_pinarray_elem *elem =
						&job->pinarray[job->num_pins];
			consumed = sizeof(struct nvhost_reloc);
			if (remaining < consumed)
				break;
			if (copy_from_user(elem, buf, consumed)) {
				err = -EFAULT;
				break;
			}
			elem->patch_mem =
				nvmap_convert_handle_u2k(elem->patch_mem);
			elem->pin_mem =
				nvmap_convert_handle_u2k(elem->pin_mem);
			trace_nvhost_channel_write_reloc(chname);
			job->num_pins++;
			hdr->num_relocs--;
		} else if (hdr->num_waitchks) {
			struct nvhost_waitchk *waitchk =
					&job->waitchk[job->num_waitchk];
			consumed = sizeof(struct nvhost_waitchk);
			if (remaining < consumed)
				break;
			if (copy_from_user(waitchk, buf, consumed)) {
				err = -EFAULT;
				break;
			}
			waitchk->mem = nvmap_convert_handle_u2k(waitchk->mem);
			trace_nvhost_channel_write_waitchks(
			  chname, 1,
			  hdr->waitchk_mask);
			job->num_waitchk++;
			hdr->num_waitchks--;
		} else if (priv->num_relocshifts) {
			int next_shift =
				job->num_pins - priv->num_relocshifts;
			consumed = sizeof(struct nvhost_reloc_shift);
			if (remaining < consumed)
				break;
			if (copy_from_user(
					&job->pinarray[next_shift].reloc_shift,
					buf, consumed)) {
				err = -EFAULT;
				break;
			}
			priv->num_relocshifts--;
		} else {
			err = -EFAULT;
			break;
		}
		remaining -= consumed;
		buf += consumed;
	}

	if (err < 0) {
		dev_err(&priv->ch->dev->pdev->dev, "channel write error\n");
		reset_submit(priv);
		return err;
	}

	return count - remaining;
}
Beispiel #7
0
void hexdump_handle(long handle, int offset, int size)
{
	int err;
	void *buf;
	struct nvmap_rw_handle rwh = {
		.handle = handle,
		.offset = offset,
		.elem_size = size,
		.hmem_stride = size,
		.user_stride = size,
		.count = 1
	};
	static int (*ioctl)(int fd, int request, ...) = NULL;

	if (nvmap_fd < 0)
		return;

	if (!ioctl)
		ioctl = libc_dlsym("ioctl");

	buf = malloc(size);
	rwh.addr = (unsigned long)buf;
	if ((err = ioctl(nvmap_fd, NVMAP_IOC_READ, &rwh)) == 0) {
		wrap_log("# handle %lx\n", handle);
		do_hexdump(buf, offset, size);
	} else {
		fprintf(stderr, "FAILED TO NVMAP_IOC_READ = %d!\n", err);
		exit(1);
	}
	free(buf);
}

#include <nvhost_ioctl.h>
#include <stdint.h>
void dump_cmdbuf(struct nvhost_cmdbuf *cmdbuf, struct nvhost_reloc *relocs, struct nvhost_reloc_shift *relocshifts, int num_relocs)
{
	int err;
	uint32_t *buf;
	FILE *fp;
	struct nvmap_rw_handle rwh = {
		.handle = cmdbuf->mem,
		.offset = cmdbuf->offset,
		.elem_size = cmdbuf->words * sizeof(uint32_t),
		.hmem_stride = cmdbuf->words * sizeof(uint32_t),
		.user_stride = cmdbuf->words * sizeof(uint32_t),
		.count = 1
	};
	static int (*ioctl)(int fd, int request, ...) = NULL;

	if (nvmap_fd < 0)
		return;

	if (!ioctl)
		ioctl = libc_dlsym("ioctl");

	buf = malloc(sizeof(uint32_t) * cmdbuf->words);
	if (!buf) {
		perror("malloc");
		exit(1);
	}
/*
	fp = fopen("cmdbufs.txt", "a");
	if (!fp) {
		perror("fopen");
		exit(1);
	}
*/
	rwh.addr = (unsigned long)buf;
	if ((err = ioctl(nvmap_fd, NVMAP_IOC_READ, &rwh)) == 0) {
		int i;
/*		wrap_log("# Handle %lx, offset %lx\n", cmdbuf->mem, cmdbuf->offset); */
		for (i = 0; i < cmdbuf->words; ++i) {
			int j;

			/* find reloc */
			for (j = 0; j < num_relocs; ++j)
				if ((relocs[j].cmdbuf_mem == cmdbuf->mem) &&
				    (relocs[j].cmdbuf_offset == cmdbuf->offset + i * 4))
					break;

			if (j < num_relocs)
				wrap_log("%08X\n# reloc %x@%x >> %d\n", buf[i], relocs[j].target, relocs[j].target_offset, relocshifts[j].shift);
			else if (buf[i] == 0xdeadbeef)
				wrap_log("%08X\n# reloc missing!\n", buf[i]);
			else
				wrap_log("%08X\n", buf[i]);
		}
	} else {
		fprintf(stderr, "FAILED TO NVMAP_IOC_READ = %d!\n", err);
		exit(1);
	}
/*	fclose(fp); */
	free(buf);
}


static struct nvmap_map_caller mappings[100];
static int num_mappings = 0;

#define LOG_NVMAP_IOCTL
static int nvmap_ioctl_pre(int fd, int request, ...)
{
	struct nvmap_create_handle *ch;
	struct nvmap_alloc_handle *ah;
	struct nvmap_rw_handle *rwh;
	struct nvmap_map_caller *mc;
	struct nvmap_handle_param *gp;
	struct nvmap_pin_handle *ph;

	void *ptr = NULL;
	if (_IOC_SIZE(request)) {
		/* find pointer to payload */
		va_list va;
		va_start(va, request);
		ptr = va_arg(va, void *);
		va_end(va);
	}

	switch (request) {
	case NVMAP_IOC_CREATE:
		ch = ptr;
#ifdef LOG_NVMAP_IOCTL
		wrap_log("# struct nvmap_create_handle ch = {\n"
		    "# \t.handle = 0x%x,\n"
		    "# \t.size = 0x%x,\n"
                    "# };\n"
                    "# ioctl(%d, NVMAP_IOC_CREATE, &ch)", ch->handle, ch->size, fd);
#endif
		break;

	case NVMAP_IOC_FREE:
#ifdef LOG_NVMAP_IOCTL
		wrap_log("# ioctl(%d (/dev/nvmap), NVMAP_IOC_FREE, ...)", fd);
#endif
		break;

	case NVMAP_IOC_PIN_MULT:
#ifdef LOG_NVMAP_IOCTL
		ph = ptr;
		if (ph->count > 1) {
			int i;
			hexdump((void *)ph->handles, ph->count * sizeof(unsigned long *));
			wrap_log("# unsigned long pin_handles[%d] = {\n# \t", ph->count);
			for (i = 0; i < ph->count; ++i)
				wrap_log("%s0x%lx", i ? ", " : "", ((unsigned long *)ph->handles)[i]);
			wrap_log("};\n# struct nvmap_pin_handle ph = {\n# \t.handles = pin_handles;\n");
			hexdump((void *)ph->addr, ph->count * sizeof(unsigned long *));
		} else
			wrap_log("# struct nvmap_pin_handle ph = {\n# \t.handles = 0x%lx;\n");
		wrap_log("# \t.count = %d;\n# };\n", ph->count);
		wrap_log("# ioctl(%d, NVMAP_IOC_PIN_MULT, &ph)", fd);
#endif
		break;

	case NVMAP_IOC_ALLOC:
		ah = ptr;
#ifdef LOG_NVMAP_IOCTL
/*		wrap_log("# Alloc(0x%x, 0x%x, 0x%x, %d)", ah->handle,
		    ah->heap_mask, ah->flags, ah->align); */
		wrap_log("# struct nvmap_alloc_handle ah = {\n"
		    "# \t.handle = 0x%x,\n"
		    "# \t.heap_mask = 0x%x,\n"
		    "# \t.flags = 0x%x,\n"
		    "# \t.align = 0x%x\n"
                    "# };\n"
                    "# ioctl(%d, NVMAP_IOC_ALLOC, &ah)", ah->handle, ah->heap_mask, ah->flags, ah->align, fd);

#endif
		break;

	case NVMAP_IOC_MMAP:
		mc = ptr;
		mappings[num_mappings++] = *mc;
/*		wrap_log("MMap(0x%x, 0x%x, %d, 0x%x, %p)", mc->handle, mc->offset, mc->length, mc->flags, mc->addr); */
#ifdef LOG_NVMAP_IOCTL
		wrap_log("# struct nvmap_map_caller mc = {\n"
		    "# \t.handle = 0x%x,\n"
		    "# \t.offset = 0x%x,\n"
		    "# \t.length = %d,\n"
		    "# \t.flags = 0x%x,\n"
		    "# \t.addr = %p\n"
		    "# };\n"
		    "# ioctl(%d, NVMAP_IOC_MMAP, &mc)", mc->handle, mc->offset, mc->length, mc->flags, mc->addr, fd);
#endif
		break;

	case NVMAP_IOC_WRITE:
		rwh = ptr;
#ifdef LOG_NVMAP_IOCTL
		wrap_log("# virtual address: %p:\n", rwh->addr);
		hexdump((void *)rwh->addr, rwh->elem_size);
		wrap_log("# Write(%p, 0x%x, 0x%x, %d, %d, %d, %d)", rwh->addr,
		    rwh->handle, rwh->offset, rwh->elem_size, rwh->hmem_stride,
		    rwh->user_stride, rwh->count);
#endif
		break;

	case NVMAP_IOC_PARAM:
		gp = ptr;
#ifdef LOG_NVMAP_IOCTL
		wrap_log(
		    "# struct nvmap_handle_param gp = {\n"
		    "# \t.handle = 0x%x,\n"
		    "# \t.param = 0x%x,\n"
		    "# };\n"
		    "# ioctl(%d (/dev/nvmap), NVMAP_IOC_PARAM, &gp)", gp->handle, gp->param, fd);
#endif
		break;

	default:
		;
#ifdef LOG_NVMAP_IOCTL
		wrap_log("# ioctl(%d (/dev/nvmap), 0x%x (%d), ...)", fd, request, _IOC_NR(request));
#endif
	}
}

static int nvmap_ioctl_post(int ret, int fd, int request, ...)
{
	struct nvmap_create_handle *ch;
	struct nvmap_pin_handle *ph;
	void *ptr = NULL;

	if (_IOC_SIZE(request)) {
		/* find pointer to payload */
		va_list va;
		va_start(va, request);
		ptr = va_arg(va, void *);
		va_end(va);
	}

#ifdef LOG_NVMAP_IOCTL
	wrap_log(" = %d\n", ret);
#endif

	switch (request) {
	case NVMAP_IOC_CREATE:
		ch = ptr;
#ifdef LOG_NVMAP_IOCTL
		wrap_log("# ch.handle = 0x%x\n", ch->handle);
#endif
		break;

	case NVMAP_IOC_PIN_MULT:
#ifdef LOG_NVMAP_IOCTL
		ph = ptr;
		if (ph->count > 1) {
			int i;
			for (i = 0; i < ph->count; ++i)
				wrap_log("# ((unsigned long *)ph.addr)[%d] = 0x%lx;\n", i, ((unsigned long *)ph->addr)[i]);
		} else
			wrap_log("# ph.addr = 0x%lx;\n", ph->addr);
#endif
		break;

	default:
		;
	}
}

static struct nvhost_submit_hdr_ext hdr;
static struct nvhost_reloc_shift *relocshifts;
static int hdr_num_relocshifts, num_relocshifts;
static struct nvhost_cmdbuf *cmdbufs;
static int num_cmdbufs;
static struct nvhost_reloc *relocs;
static int num_relocs;

static void set_submit(struct nvhost_submit_hdr_ext *hdr)
{
	if (!hdr->num_cmdbufs) {
		wrap_log("# submit should have at least one cmdbuf!\n");
		exit(1);
	}

	wrap_log("# hdr:\n");
	wrap_log("# \thdr.syncpt_id = %d\n", hdr->syncpt_id);
	wrap_log("# \thdr.syncpt_incrs = %d\n", hdr->syncpt_incrs);
	wrap_log("# \thdr.num_cmdbufs = %d\n", hdr->num_cmdbufs);
	wrap_log("# \thdr.num_relocs = %d\n", hdr->num_relocs);

	cmdbufs = realloc(cmdbufs, sizeof(*cmdbufs) * hdr->num_cmdbufs);
	num_cmdbufs = 0;
	relocs = realloc(relocs, sizeof(*relocs) * hdr->num_relocs);
	num_relocs = 0;

	if (hdr->submit_version >= NVHOST_SUBMIT_VERSION_V2)
		hdr_num_relocshifts = hdr->num_relocs;

	relocshifts = realloc(relocshifts, sizeof(*relocshifts) * hdr_num_relocshifts);
	memset(relocshifts, 0, sizeof(*relocshifts) * hdr_num_relocshifts);
	num_relocshifts = 0;
}

static int nvhost_gr3d_ioctl_pre(int fd, int request, ...)
{
	struct nvhost_set_nvmap_fd_args *fdargs;
	struct nvhost_get_param_args *pa;
	void *ptr = NULL;
	if (_IOC_SIZE(request)) {
		/* find pointer to payload */
		va_list va;
		va_start(va, request);
		ptr = va_arg(va, void *);
		va_end(va);
	}

	switch (request) {
	case NVHOST_IOCTL_CHANNEL_FLUSH:
		wrap_log("# ioctl(%d (/dev/nvhost-gr3d), NVHOST_IOCTL_CHANNEL_FLUSH, ...)", fd);
		break;

	case NVHOST_IOCTL_CHANNEL_GET_SYNCPOINTS:
		pa = ptr;
		wrap_log("# struct nvhost_get_param_args pa {\n# \t%d\n# };\n", pa->value);
		wrap_log("# ioctl(%d (/dev/nvhost-gr3d), NVHOST_IOCTL_CHANNEL_GET_SYNCPOINTS, &pa)", fd);
		break;

	case NVHOST_IOCTL_CHANNEL_GET_WAITBASES:
		pa = ptr;
		wrap_log("# struct nvhost_get_param_args pa {\n# \t%d\n# };\n", pa->value);
		wrap_log("# ioctl(%d (/dev/nvhost-gr3d), NVHOST_IOCTL_CHANNEL_GET_WAITBASES, &pa)", fd);
		break;

	case NVHOST_IOCTL_CHANNEL_SET_NVMAP_FD:
		fdargs = ptr;
		nvmap_fd = fdargs->fd;
		wrap_log("# ioctl(%d (/dev/nvhost-gr3d), NVHOST_IOCTL_CHANNEL_SET_NVMAP_FD, %d)", fd, fdargs->fd);
		break;

	case NVHOST_IOCTL_CHANNEL_SUBMIT_EXT:
		memcpy(&hdr, ptr, sizeof(hdr));
		wrap_log("# ioctl(%d (/dev/nvhost-gr3d), NVHOST_IOCTL_CHANNEL_SUBMIT_EXT, ...)", fd);

		set_submit(&hdr);

		break;

	default:
		;
		wrap_log("# ioctl(%d (/dev/nvhost-gr3d), 0x%x (%d), ...)", fd, request, _IOC_NR(request));
	}
}

static int nvhost_gr3d_ioctl_post(int ret, int fd, int request, ...)
{
	void *ptr = NULL;
	struct nvhost_get_param_args *pa;

	if (_IOC_SIZE(request)) {
		/* find pointer to payload */
		va_list va;
		va_start(va, request);
		ptr = va_arg(va, void *);
		va_end(va);
	}

	wrap_log(" = %d\n", ret);

	switch (request) {
	case NVHOST_IOCTL_CHANNEL_GET_SYNCPOINTS:
		pa = ptr;
		wrap_log("# pa.value = 0x%08x\n", pa->value);
		break;

	case NVHOST_IOCTL_CHANNEL_GET_WAITBASES:
		pa = ptr;
		wrap_log("# pa.value = 0x%08x\n", pa->value);
		break;

	default:
		;
	}
}
Beispiel #8
0
ssize_t nvhost_gr3d_write_pre(int fd, const void *ptr, size_t count)
{
	const unsigned char *curr = ptr;
	size_t remaining = count;
	int i;

	static int (*orig_ioctl)(int fd, int request, ...) = NULL;

	if (!orig_ioctl)
		orig_ioctl = libc_dlsym("ioctl");
#if 0
	hexdump(ptr, count);
	wrap_log("write(%d (/dev/nvhost-gr3d), %p, %d)\n", fd, ptr, count);
#endif

	while (1) {
		if (!hdr.num_cmdbufs && !hdr.num_relocs && !hdr_num_relocshifts && !hdr.num_waitchks) {

			inspect_cmdbufs();

			if (remaining < sizeof(struct nvhost_submit_hdr))
				break;

			memcpy(&hdr, curr, sizeof(struct nvhost_submit_hdr));
			hdr.submit_version = NVHOST_SUBMIT_VERSION_V0;
			curr += sizeof(struct nvhost_submit_hdr);
			remaining -= sizeof(struct nvhost_submit_hdr);

			set_submit(&hdr);

		}

		if (hdr.num_cmdbufs) {
			struct nvhost_cmdbuf cmdbuf;

			if (remaining < sizeof(cmdbuf))
				break;

			memcpy(&cmdbuf, curr, sizeof(cmdbuf));
			curr += sizeof(cmdbuf);
			remaining -= sizeof(cmdbuf);
			--hdr.num_cmdbufs;

			cmdbufs[num_cmdbufs++] = cmdbuf;

			wrap_log("# cmdbuf(%d left):\n", hdr.num_cmdbufs);
			wrap_log("# \tcmdbuf.mem = %p\n", cmdbuf.mem);
			wrap_log("# \tcmdbuf.offset = 0x%x\n", cmdbuf.offset);
			wrap_log("# \tcmdbuf.words = 0x%x\n", cmdbuf.words);
#if 0
			for (i = 0; i < num_mappings; ++i) {
				unsigned char *ptr;
				if (mappings[i].handle != cmdbuf.mem)
					continue;
			/*	if (mappings[i].offset > cmdbuf.offset)
					continue; */
				ptr = (unsigned char *)mappings[i].addr;
				/* hexdump(ptr, mappings->length); */
				ptr -= mappings[i].offset;
				ptr += cmdbuf.offset;
				hexdump(ptr, cmdbuf.words * 4);
				break;
			}
			if (i == num_mappings)
#endif

/*			hexdump_handle_words(cmdbuf.mem, cmdbuf.offset, cmdbuf.words * 4); */
		} else if (hdr.num_relocs) {
			struct nvhost_reloc reloc;

			if (remaining < sizeof(reloc))
				break;

			memcpy(&reloc, curr, sizeof(reloc));
			curr += sizeof(reloc);
			remaining -= sizeof(reloc);
			--hdr.num_relocs;

			relocs[num_relocs++] = reloc;

			wrap_log("# reloc:\n");
			wrap_log("# \tcmdbuf_mem = %p\n", reloc.cmdbuf_mem);
			wrap_log("# \tcmdbuf_offset = 0x%x\n", reloc.cmdbuf_offset);
			wrap_log("# \ttarget = %p\n", reloc.target);
			wrap_log("# \ttarget_offset = 0x%x\n", reloc.target_offset);
		} else if (hdr.num_waitchks) {

			if (remaining < sizeof(struct nvhost_waitchk))
				break;

			wrap_log("# waitchks (%d) not supported!\n", hdr.num_waitchks);
			curr += sizeof(struct nvhost_waitchk) * hdr.num_waitchks;
			remaining -= sizeof(struct nvhost_waitchk) * hdr.num_waitchks;
			hdr.num_waitchks = 0;
		} else if (hdr_num_relocshifts) {

			if (remaining < sizeof(struct nvhost_reloc_shift))
				break;

			memcpy(relocshifts + num_relocshifts, curr, sizeof(*relocshifts));

			wrap_log("# reloc_shift: %d\n", relocshifts[num_relocshifts].shift);
			curr += sizeof(struct nvhost_reloc_shift);
			remaining -= sizeof(struct nvhost_reloc_shift);
			--hdr_num_relocshifts;
			++num_relocshifts;
		} else {
			wrap_log("# inconsistent state\n");
			exit(1);
		}
	}