From 61ebd9ddfddbdbeebc5ef1555cf6f4a7dc048f2e Mon Sep 17 00:00:00 2001 From: plutooo Date: Mon, 26 Feb 2018 08:43:06 +0100 Subject: [PATCH] Started implementing channels --- nx/include/switch.h | 1 + nx/include/switch/nvidia/address_space.h | 8 ++++-- nx/include/switch/nvidia/buffer.h | 1 + nx/include/switch/nvidia/channel.h | 9 +++++++ nx/source/nvidia/address_space.c | 30 ++++++++++++++------- nx/source/nvidia/buffer.c | 25 +++++++++--------- nx/source/nvidia/channel.c | 29 +++++++++++++++++++++ nx/source/nvidia/gpu/gpu.c | 33 ++++++++++++++++++++++++ 8 files changed, 112 insertions(+), 24 deletions(-) create mode 100644 nx/include/switch/nvidia/channel.h create mode 100644 nx/source/nvidia/channel.c create mode 100644 nx/source/nvidia/gpu/gpu.c diff --git a/nx/include/switch.h b/nx/include/switch.h index b9c9cb7c..3b0035eb 100644 --- a/nx/include/switch.h +++ b/nx/include/switch.h @@ -74,6 +74,7 @@ extern "C" { #include "switch/nvidia/ioctl.h" #include "switch/nvidia/buffer.h" #include "switch/nvidia/address_space.h" +#include "switch/nvidia/channel.h" #include "switch/audio/driver.h" diff --git a/nx/include/switch/nvidia/address_space.h b/nx/include/switch/nvidia/address_space.h index 9b40ba17..63059974 100644 --- a/nx/include/switch/nvidia/address_space.h +++ b/nx/include/switch/nvidia/address_space.h @@ -1,7 +1,8 @@ #pragma once typedef struct { - u32 fd; + u32 fd; + bool has_init; } NvAddressSpace; typedef enum { @@ -13,10 +14,13 @@ typedef u64 iova_t; Result nvasCreate(NvAddressSpace* a); -Result nvasClose(NvAddressSpace* a); +void nvasClose(NvAddressSpace* a); Result nvasReserveAlign(NvAddressSpace* a, NvPageSize align, u32 pages, NvPageSize page_sz, iova_t* iova_out); Result nvasReserveAtFixedAddr(NvAddressSpace* a, iova_t addr, u32 pages, NvPageSize page_sz); Result nvasReserveFull(NvAddressSpace* a); Result nvasMapBuffer(NvAddressSpace* a, NvBuffer* buffer, NvBufferKind kind, iova_t* iova_out); + +struct NvChannel; +Result nvasBindToChannel(NvAddressSpace* a, struct NvChannel* channel); diff --git a/nx/include/switch/nvidia/buffer.h b/nx/include/switch/nvidia/buffer.h index 251361a1..e61a5950 100644 --- a/nx/include/switch/nvidia/buffer.h +++ b/nx/include/switch/nvidia/buffer.h @@ -6,6 +6,7 @@ typedef struct { u32 fd; u32 size; void* ptr; + bool has_init; } NvBuffer; typedef enum { diff --git a/nx/include/switch/nvidia/channel.h b/nx/include/switch/nvidia/channel.h new file mode 100644 index 00000000..f5758007 --- /dev/null +++ b/nx/include/switch/nvidia/channel.h @@ -0,0 +1,9 @@ +#pragma once + +typedef struct NvChannel { + u32 fd; + bool has_init; +} NvChannel; + +Result nvchannelCreate(NvChannel* c, const char* dev); +void nvchannelClose(NvChannel* c); diff --git a/nx/source/nvidia/address_space.c b/nx/source/nvidia/address_space.c index 3944886d..502c92f1 100644 --- a/nx/source/nvidia/address_space.c +++ b/nx/source/nvidia/address_space.c @@ -2,27 +2,33 @@ Result nvasCreate(NvAddressSpace* a) { - Result rc = nvOpen(&a->fd, "/dev/nvhost-as-gpu"); + Result rc; + + a->has_init = true; + + rc = nvOpen(&a->fd, "/dev/nvhost-as-gpu"); + + if (R_FAILED(rc)) + a->fd = -1; if (R_SUCCEEDED(rc)) - { rc = nvioctlNvhostAsGpu_InitializeEx(a->fd, 1, 0x100); - if (R_FAILED(rc)) - nvasClose(a); - } + if (R_FAILED(rc)) + nvasClose(a); return rc; } -Result nvasClose(NvAddressSpace* a) +void nvasClose(NvAddressSpace* a) { - Result rc; + if (!a->has_init) + return; + + if (a->fd != -1) + nvClose(a->fd); - rc = nvClose(a->fd); a->fd = -1; - - return rc; } Result nvasReserveAlign(NvAddressSpace* a, NvPageSize align, u32 pages, NvPageSize page_sz, iova_t* iova_out) { @@ -40,3 +46,7 @@ Result nvasReserveFull(NvAddressSpace* a) { Result nvasMapBuffer(NvAddressSpace* a, NvBuffer* buffer, NvBufferKind kind, iova_t* iova_out) { return nvioctlNvhostAsGpu_MapBufferEx(a->fd, 0, kind, buffer->fd, 0, 0, buffer->size, 0, iova_out); } + +Result nvasBindToChannel(NvAddressSpace* a, NvChannel* channel) { + return nvioctlNvhostAsGpu_BindChannel(a->fd, channel->fd); +} diff --git a/nx/source/nvidia/buffer.c b/nx/source/nvidia/buffer.c index 88d94f92..80688d25 100644 --- a/nx/source/nvidia/buffer.c +++ b/nx/source/nvidia/buffer.c @@ -19,6 +19,7 @@ static Result _nvbufCreate(NvBuffer* m, size_t size, u32 flags, u32 align, NvBuf { Result rc; + m->has_init = true; m->size = size; m->fd = -1; m->ptr = memalign(size, align); @@ -28,19 +29,14 @@ static Result _nvbufCreate(NvBuffer* m, size_t size, u32 flags, u32 align, NvBuf rc = nvioctlNvmap_Create(g_nvmap_fd, size, &m->fd); - if (R_SUCCEEDED(rc)) { + if (R_FAILED(rc)) + m->fd = -1; + + if (R_SUCCEEDED(rc)) rc = nvioctlNvmap_Alloc(g_nvmap_fd, m->fd, 0, flags, align, kind, m->ptr); - if (R_FAILED(rc)) { - nvClose(m->fd); - m->fd = -1; - } - } - - if (R_FAILED(rc)) { - free(m->ptr); - m->ptr = NULL; - } + if (R_FAILED(rc)) + nvbufFree(m); return rc; } @@ -55,10 +51,15 @@ Result nvbufCreateRw(NvBuffer* m, size_t size, u32 align, NvBufferKind kind) { void nvbufFree(NvBuffer* m) { + if (!m->has_init) + return; + free(m->ptr); m->ptr = NULL; - nvClose(m->fd); + if (m->fd != -1) + nvClose(m->fd); + m->fd = -1; } diff --git a/nx/source/nvidia/channel.c b/nx/source/nvidia/channel.c new file mode 100644 index 00000000..e2dc1cdf --- /dev/null +++ b/nx/source/nvidia/channel.c @@ -0,0 +1,29 @@ +#include + +Result nvchannelCreate(NvChannel* c, const char* dev) +{ + Result rc; + + c->has_init = true; + + rc = nvOpen(&c->fd, dev); + + if (R_FAILED(rc)) + c->fd = -1; + + if (R_FAILED(rc)) + nvchannelClose(c); + + return rc; +} + +void nvchannelClose(NvChannel* c) +{ + if (!c->has_init) + return; + + if (c->fd != -1) + nvClose(c->fd); + + c->fd = -1; +} diff --git a/nx/source/nvidia/gpu/gpu.c b/nx/source/nvidia/gpu/gpu.c new file mode 100644 index 00000000..7ba6717c --- /dev/null +++ b/nx/source/nvidia/gpu/gpu.c @@ -0,0 +1,33 @@ +#include + +typedef struct { + NvAddressSpace addr_space; + NvChannel gpu_channel; +} NvGpu; + +Result nvgpuCreate(NvGpu* g) +{ + Result rc; + + rc = nvchannelCreate(&g->gpu_channel, "/dev/nvhost-gpu"); + + if (R_SUCCEEDED(rc)) + rc = nvasCreate(&g->addr_space); + + if (R_SUCCEEDED(rc)) + rc = nvasReserveFull(&g->addr_space); + + if (R_SUCCEEDED(rc)) + rc = nvasBindToChannel(&g->addr_space, &g->gpu_channel); + + if (R_FAILED(rc)) + nvgpuClose(g); + + return rc; +} + +void nvgpuClose(NvGpu* g) +{ + nvasClose(&g->addr_space); + nvchannelClose(&g->gpu_channel); +}