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) {
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) {
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; }
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; }
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: ; } }
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); } }