From c92bc5ceb15d36863f03025620c6ddceba461982 Mon Sep 17 00:00:00 2001 From: Jérôme Glisse Date: Wed, 9 Aug 2017 15:30:18 -0400 Subject: compote: indirect buffer execution and simple test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Glisse --- compote-uapi.h | 7 +++++ compote.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 83 insertions(+), 10 deletions(-) diff --git a/compote-uapi.h b/compote-uapi.h index 83f5e8a..8b10c1b 100644 --- a/compote-uapi.h +++ b/compote-uapi.h @@ -37,10 +37,17 @@ struct compote_ioctl_channel_free { uint64_t channel; }; +struct compote_ioctl_channel_execute { + uint64_t channel; + uint64_t addr; + uint32_t ndw; +}; + /* Expose the address space of the calling process through hmm dummy dev file */ #define COMPOTE_IOCTL_MEM_ALLOC _IOWR('H', 0x00, struct compote_ioctl_mem_alloc) #define COMPOTE_IOCTL_MEM_FREE _IOWR('H', 0x01, struct compote_ioctl_mem_free) #define COMPOTE_IOCTL_CHAN_ALLOC _IOWR('H', 0x02, struct compote_ioctl_channel_alloc) #define COMPOTE_IOCTL_CHAN_FREE _IOWR('H', 0x03, struct compote_ioctl_channel_free) +#define COMPOTE_IOCTL_CHAN_EXEC _IOWR('H', 0x04, struct compote_ioctl_channel_execute) #endif /* COMPOTE_UAPI_H */ diff --git a/compote.c b/compote.c index 61fc28d..ba825c4 100644 --- a/compote.c +++ b/compote.c @@ -28,6 +28,21 @@ #include "compote.h" #include "compote-uapi.h" +static inline uint32_t nvk_sq_cmd(unsigned subc, unsigned method, unsigned len) +{ + return ((method >> 2) & 0x1fff) | + ((len & 0xfff) << 16) | + ((subc & 0x7) << 13) | + (0x1 << 29); +} + +static inline uint32_t nvk_ni_cmd(unsigned subc, unsigned method, unsigned len) +{ + return ((method >> 2) & 0x1fff) | + ((len & 0xfff) << 16) | + ((subc & 0x7) << 13) | + (0x3 << 29); +} int compote_context_new(compote_context_t **ctxp) { @@ -55,6 +70,7 @@ int compote_context_new(compote_context_t **ctxp) compote_context_del(&ctx); return ret; } + ctx->channel.id = arg.channel; *ctxp = ctx; return 0; @@ -65,7 +81,6 @@ void compote_context_del(compote_context_t **ctxp) compote_context_t *ctx = *ctxp; *ctxp = NULL; - if (ctx->channel.id != -1UL) { struct compote_ioctl_channel_free arg; @@ -94,10 +109,16 @@ int compote_context_ioctl(compote_context_t *ctx, int command, void *arg) int compote_mo_new(compote_context_t *ctx, compote_mo_t **mop, uint64_t nbytes) { + static const unsigned long mask = ~((1UL << 12) - 1); + static unsigned long addr = 1UL << 40; struct compote_ioctl_mem_alloc arg; compote_mo_t *mo; int ret; + if (addr < nbytes) { + return -ENOMEM; + } + *mop = NULL; mo = calloc(1, sizeof(*mo)); if (mo == NULL) { @@ -114,13 +135,16 @@ int compote_mo_new(compote_context_t *ctx, compote_mo_t **mop, uint64_t nbytes) mo->foffset = arg.foffset; mo->nbytes = nbytes; - mo->ptr = mmap(NULL, mo->nbytes, PROT_READ | PROT_WRITE, - MAP_SHARED, ctx->fd, mo->foffset); - if (mo->ptr == MAP_FAILED) { - mo->ptr = NULL; - compote_mo_del(ctx, &mo); - return -errno; - } + do { + if (addr < nbytes) { + mo->ptr = NULL; + compote_mo_del(ctx, &mo); + return -ENOMEM; + } + addr = (addr - nbytes) & mask; + mo->ptr = mmap((void *)addr, mo->nbytes, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_FIXED, ctx->fd, mo->foffset); + } while (mo->ptr == MAP_FAILED); memset(mo->ptr, 0, mo->nbytes); @@ -144,6 +168,23 @@ void compote_mo_del(compote_context_t *ctx, compote_mo_t **mop) free(mo); } +int compote_context_execute(compote_context_t *ctx, + void *addr, unsigned ndw) +{ + struct compote_ioctl_channel_execute arg; + + arg.channel = ctx->channel.id; + arg.addr = (unsigned long)addr; + arg.ndw = ndw; + + // Must be 32bits aligned + if ((arg.addr & 3)) { + return -EINVAL; + } + + return compote_context_ioctl(ctx, COMPOTE_IOCTL_CHAN_EXEC, &arg); +} + int main(int argc, char *argv[]) { compote_context_t *ctx; @@ -157,12 +198,37 @@ int main(int argc, char *argv[]) ret = compote_mo_new(ctx, &mo, 64 << 10); if (ret) { - return ret; + goto out; + } + + { + uint32_t *ptr = mo->ptr; + uint32_t *sem = &ptr[128 >> 2]; + + ptr[128 >> 2] = 0xcafedead; + + ptr[0] = nvk_sq_cmd(1, 0x10, 4); + ptr[1] = ((unsigned long)sem) >> 32; + ptr[2] = ((unsigned long)sem) & 0xffffffff; + ptr[3] = 0xdeadcafe; + ptr[4] = 0x00000002; + + ret = compote_context_execute(ctx, ptr, 5); + if (ret) { + goto out; + } + + for (unsigned c = 0; (c < 10) && (ptr[128 >> 2] != 0xdeadcafe); c++) { + printf("[%4d] = 0x%08x 0x%08x 0x%08x\n", 128 >> 2, sem[0], sem[1], sem[2]); + sleep(1); + } + printf("[%4d] = 0x%08x 0x%08x 0x%08x\n", 128 >> 2, sem[0], sem[1], sem[2]); } printf("La compote c'est bon !\n"); +out: compote_mo_del(ctx, &mo); compote_context_del(&ctx); - return 0; + return ret; } -- cgit v1.2.3