示例#1
0
int etna_queue_alloc(struct etna_queue *queue, struct _gcsHAL_INTERFACE **cmd_out)
{
    int rv;
    if(queue == NULL)
        return ETNA_INVALID_ADDR;
    if(queue->count == queue->max_count)
    {
        /* Queue is full, flush context. Assert that there is a one-to-one relationship
         * between queue and etna context so that flushing the context flushes this queue.
         */
        assert(queue->ctx->queue == queue);
        if((rv = etna_flush(queue->ctx)) != ETNA_OK)
            return rv;
        assert(queue->count == 0);
    }
    struct _gcsQUEUE *cmd = &queue->queue[queue->count++];
    cmd->next = PTR_TO_VIV(NULL);
    /* update next pointer of previous record */
    if(queue->last != NULL)
    {
        queue->last->next = PTR_TO_VIV(cmd);
    }
    queue->last = cmd;
    *cmd_out = &cmd->iface;
    return ETNA_OK;
}
示例#2
0
int etna_queue_free_contiguous(struct etna_queue *queue, size_t bytes, viv_addr_t physical, void *logical)
{
    struct _gcsHAL_INTERFACE *cmd = NULL;
    int rv;
    if((rv=etna_queue_alloc(queue, &cmd)) != ETNA_OK)
        return rv;
    cmd->command = gcvHAL_FREE_CONTIGUOUS_MEMORY;
    cmd->u.FreeContiguousMemory.bytes = bytes;
    cmd->u.FreeContiguousMemory.physical = PTR_TO_VIV((gctPHYS_ADDR)physical);
    cmd->u.FreeContiguousMemory.logical = PTR_TO_VIV(logical);
    return ETNA_OK;
}
示例#3
0
int etna_queue_signal(struct etna_queue *queue, int sig_id, enum viv_where fromWhere)
{
    struct _gcsHAL_INTERFACE *cmd = NULL;
    int rv;
    if((rv=etna_queue_alloc(queue, &cmd)) != ETNA_OK)
        return rv;
    cmd->command = gcvHAL_SIGNAL;
    cmd->u.Signal.signal = PTR_TO_VIV((void*)sig_id);
    cmd->u.Signal.auxSignal = PTR_TO_VIV((void*)0x0);
    cmd->u.Signal.process = HANDLE_TO_VIV(queue->ctx->conn->process);
    cmd->u.Signal.fromWhere = convert_where(fromWhere);
    return ETNA_OK;
}
示例#4
0
int etna_queue_unmap_user_memory(struct etna_queue *queue, void *memory, size_t size, viv_usermem_t info, viv_addr_t address)
{
    struct _gcsHAL_INTERFACE *cmd = NULL;
    int rv;
    if((rv=etna_queue_alloc(queue, &cmd)) != ETNA_OK)
        return rv;
    cmd->command = gcvHAL_UNMAP_USER_MEMORY;
    cmd->u.UnmapUserMemory.memory = PTR_TO_VIV(memory);
    cmd->u.UnmapUserMemory.size = size;
    cmd->u.UnmapUserMemory.info = HANDLE_TO_VIV(info);
    cmd->u.UnmapUserMemory.address = address;
    return ETNA_OK;
}
示例#5
0
int etna_create(struct viv_conn *conn, struct etna_ctx **ctx_out)
{
    int rv;
    if(ctx_out == NULL) return ETNA_INVALID_ADDR;
    struct etna_ctx *ctx = ETNA_CALLOC_STRUCT(etna_ctx);
    if(ctx == NULL) return ETNA_OUT_OF_MEMORY;
    ctx->conn = conn;

    if(gpu_context_initialize(ctx) != ETNA_OK)
    {
        ETNA_FREE(ctx);
        return ETNA_INTERNAL_ERROR;
    }

    /* Create synchronization signal */
    if(viv_user_signal_create(conn, 0, &ctx->sig_id) != 0) /* automatic resetting signal */
    {
#ifdef DEBUG
        fprintf(stderr, "Cannot create user signal\n");
#endif
        return ETNA_INTERNAL_ERROR;
    }
#ifdef DEBUG
    fprintf(stderr, "Created user signal %i\n", ctx->sig_id);
#endif

    /* Allocate command buffers, and create a synchronization signal for each.
     * Also signal the synchronization signal for the buffers to tell that the buffers are ready for use.
     */
    for(int x=0; x<NUM_COMMAND_BUFFERS; ++x)
    {
        ctx->cmdbuf[x] = ETNA_CALLOC_STRUCT(_gcoCMDBUF);
        if((ctx->cmdbufi[x].bo = etna_bo_new(conn, COMMAND_BUFFER_SIZE, DRM_ETNA_GEM_TYPE_CMD))==NULL)
        {
#ifdef DEBUG
            fprintf(stderr, "Error allocating host memory for command buffer\n");
#endif
            return ETNA_OUT_OF_MEMORY;
        }
        ctx->cmdbuf[x]->object.type = gcvOBJ_COMMANDBUFFER;
#ifdef GCABI_CMDBUF_HAS_PHYSICAL
        ctx->cmdbuf[x]->physical = PTR_TO_VIV((void*)etna_bo_gpu_address(ctx->cmdbufi[x].bo));
        ctx->cmdbuf[x]->bytes = ctx->cmdbufi[x].bytes;
#endif
        ctx->cmdbuf[x]->logical = PTR_TO_VIV((void*)etna_bo_map(ctx->cmdbufi[x].bo));

        if(viv_user_signal_create(conn, 0, &ctx->cmdbufi[x].sig_id) != 0 ||
           viv_user_signal_signal(conn, ctx->cmdbufi[x].sig_id, 1) != 0)
        {
#ifdef DEBUG
            fprintf(stderr, "Cannot create user signal\n");
#endif
            return ETNA_INTERNAL_ERROR;
        }
#ifdef DEBUG
        fprintf(stderr, "Allocated buffer %i: phys=%08x log=%08x bytes=%08x [signal %i]\n", x,
                (uint32_t)buf0_physical, (uint32_t)buf0_logical, buf0_bytes, ctx->cmdbufi[x].sig);
#endif
    }

    /* Allocate command queue */
    if((rv = etna_queue_create(ctx, &ctx->queue)) != ETNA_OK)
    {
#ifdef DEBUG
        fprintf(stderr, "Error allocating kernel command queue\n");
#endif
        return rv;
    }

    /* Set current buffer to ETNA_NO_BUFFER, to signify that we need to switch to buffer 0 before
     * queueing of commands can be started.
     */
    ctx->cur_buf = ETNA_NO_BUFFER;

    *ctx_out = ctx;
    return ETNA_OK;
}
示例#6
0
文件: viv.c 项目: jluebbe/etna_viv
#define munmap my_munmap
#define ioctl my_ioctl
#endif
//#define DEBUG

const char *galcore_device[] = {"/dev/gal3d", "/dev/galcore", "/dev/graphics/galcore", NULL};
#define INTERFACE_SIZE (sizeof(gcsHAL_INTERFACE))

/* Call ioctl interface with structure cmd as input and output.
 * @returns status (VIV_STATUS_xxx)
 */
int viv_invoke(struct viv_conn *conn, struct _gcsHAL_INTERFACE *cmd)
{
    vivante_ioctl_data_t ic = {
#ifdef GCABI_UINT64_IOCTL_DATA
        .in_buf = PTR_TO_VIV(cmd),
        .in_buf_size = INTERFACE_SIZE,
        .out_buf = PTR_TO_VIV(cmd),
        .out_buf_size = INTERFACE_SIZE
#else
        .in_buf = (void*)cmd,
        .in_buf_size = INTERFACE_SIZE,
        .out_buf = (void*)cmd,
        .out_buf_size = INTERFACE_SIZE
#endif
    };
#ifdef GCABI_HAS_HARDWARE_TYPE
    cmd->hardwareType = (gceHARDWARE_TYPE)conn->hw_type;
#endif
    if(ioctl(conn->fd, IOCTL_GCHAL_INTERFACE, &ic) < 0)
        return -1;