mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 20:42:44 +02:00
Stylechanges to binder, and implemented gpu address space
This commit is contained in:
parent
cd753b1b58
commit
04751087ca
@ -69,10 +69,12 @@ extern "C" {
|
||||
#include "switch/display/binder.h"
|
||||
#include "switch/display/parcel.h"
|
||||
#include "switch/display/buffer_producer.h"
|
||||
#include "switch/display/ioctl.h"
|
||||
#include "switch/display/nvioctl.h"
|
||||
#include "switch/display/nvgfx.h"
|
||||
|
||||
#include "switch/nvidia/ioctl.h"
|
||||
#include "switch/nvidia/nvmap.h"
|
||||
#include "switch/nvidia/address_space.h"
|
||||
|
||||
#include "switch/audio/driver.h"
|
||||
|
||||
#include "switch/runtime/env.h"
|
||||
|
@ -6,24 +6,25 @@
|
||||
typedef struct {
|
||||
bool created;
|
||||
bool initialized;
|
||||
Handle sessionHandle;
|
||||
Handle session_handle;
|
||||
s32 id;
|
||||
Handle nativeHandle;
|
||||
size_t ipcBufferSize;
|
||||
bool hasTransactAuto;
|
||||
Handle native_handle;
|
||||
size_t ipc_buffer_size;
|
||||
bool has_transact_auto;
|
||||
} Binder;
|
||||
|
||||
// binderExitSession will not close the sessionHandle since it's user-specified via binderCreateSession and may be used elsewhere.
|
||||
void binderCreateSession(Binder *session, Handle sessionHandle, s32 ID);
|
||||
Result binderInitSession(Binder *session, u32 unk0);
|
||||
void binderExitSession(Binder *session);
|
||||
// Note: binderClose will not close the session_handle provided to binderCreate.
|
||||
void binderCreate(Binder* b, Handle session_handle, s32 id);
|
||||
void binderClose(Binder* b);
|
||||
|
||||
Result binderInitSession(Binder* b, u32 unk0);
|
||||
|
||||
Result binderTransactParcel(
|
||||
Binder *session, u32 code,
|
||||
Binder* b, u32 code,
|
||||
void* parcel_data, size_t parcel_data_size,
|
||||
void* parcel_reply, size_t parcel_reply_size,
|
||||
u32 flags);
|
||||
|
||||
Result binderAdjustRefcount(Binder *session, s32 addval, s32 type);
|
||||
Result binderGetNativeHandle(Binder *session, u32 unk0, Handle *handle_out);
|
||||
Result binderAdjustRefcount(Binder* b, s32 addval, s32 type);
|
||||
Result binderGetNativeHandle(Binder* b, u32 unk0, Handle *handle_out);
|
||||
|
||||
|
@ -14,7 +14,7 @@ typedef struct {
|
||||
u32 pos;
|
||||
} Parcel;
|
||||
|
||||
void parcelInitialize(Parcel *ctx);
|
||||
void parcelCreate(Parcel *ctx);
|
||||
Result parcelTransact(Binder *session, u32 code, Parcel *in_parcel, Parcel *reply_parcel);
|
||||
|
||||
void* parcelWriteData(Parcel *ctx, void* data, size_t data_size);
|
||||
|
22
nx/include/switch/nvidia/address_space.h
Normal file
22
nx/include/switch/nvidia/address_space.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct {
|
||||
u32 fd;
|
||||
} NvAddressSpace;
|
||||
|
||||
typedef enum {
|
||||
NvPageSize_4K = 0x1000,
|
||||
NvPageSize_64K = 0x10000
|
||||
} NvPageSize;
|
||||
|
||||
typedef u64 iova_t;
|
||||
|
||||
|
||||
Result nvasCreate(NvAddressSpace* a);
|
||||
Result 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, Nvmap* buffer, NvmapKind kind, iova_t* iova_out);
|
@ -5,94 +5,99 @@
|
||||
#include "kernel/detect.h"
|
||||
#include "display/binder.h"
|
||||
|
||||
void binderCreateSession(Binder *session, Handle sessionHandle, s32 id)
|
||||
void binderCreate(Binder* b, Handle session_handle, s32 id)
|
||||
{
|
||||
memset(session, 0, sizeof(Binder));
|
||||
session->created = 1;
|
||||
session->sessionHandle = sessionHandle;
|
||||
session->id = id;
|
||||
session->nativeHandle = INVALID_HANDLE;
|
||||
session->hasTransactAuto = 0;
|
||||
memset(b, 0, sizeof(Binder));
|
||||
b->created = true;
|
||||
b->session_handle = session_handle;
|
||||
b->id = id;
|
||||
b->native_handle = INVALID_HANDLE;
|
||||
b->has_transact_auto = false;
|
||||
}
|
||||
|
||||
Result binderInitSession(Binder *session, u32 unk0)
|
||||
Result binderInitSession(Binder* b, u32 unk0)
|
||||
{
|
||||
Result rc = 0;
|
||||
|
||||
if (!session->created) return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
if (session->initialized) return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized);
|
||||
if (!b->created)
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
rc = binderAdjustRefcount(session, 1, 0);
|
||||
if (b->initialized)
|
||||
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized);
|
||||
|
||||
rc = binderAdjustRefcount(b, 1, 0);
|
||||
|
||||
if (R_FAILED(rc))
|
||||
return rc;
|
||||
|
||||
rc = binderAdjustRefcount(session, 1, 1);
|
||||
rc = binderAdjustRefcount(b, 1, 1);
|
||||
|
||||
if (R_FAILED(rc)) {
|
||||
binderAdjustRefcount(session, -1, 0);
|
||||
binderAdjustRefcount(b, -1, 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = binderGetNativeHandle(session, unk0, &session->nativeHandle);
|
||||
rc = binderGetNativeHandle(b, unk0, &b->native_handle);
|
||||
|
||||
if (R_FAILED(rc)) {
|
||||
binderAdjustRefcount(session, -1, 1);
|
||||
binderAdjustRefcount(session, -1, 0);
|
||||
binderAdjustRefcount(b, -1, 1);
|
||||
binderAdjustRefcount(b, -1, 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// When the output nativeHandle is 0 the Binder ID is probably invalid.
|
||||
if (session->nativeHandle == 0) {
|
||||
binderAdjustRefcount(session, -1, 1);
|
||||
binderAdjustRefcount(session, -1, 0);
|
||||
// When the output native_handle is 0 the Binder ID is probably invalid.
|
||||
if (b->native_handle == 0) {
|
||||
binderAdjustRefcount(b, -1, 1);
|
||||
binderAdjustRefcount(b, -1, 0);
|
||||
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||
}
|
||||
|
||||
session->initialized = 1;
|
||||
b->initialized = true;
|
||||
|
||||
rc = ipcQueryPointerBufferSize(session->sessionHandle, &session->ipcBufferSize);
|
||||
rc = ipcQueryPointerBufferSize(b->session_handle, &b->ipc_buffer_size);
|
||||
|
||||
if (R_FAILED(rc)) {
|
||||
binderExitSession(session);
|
||||
binderClose(b);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Use TransactParcelAuto when available.
|
||||
if (kernelAbove300())
|
||||
session->hasTransactAuto = 1;
|
||||
b->has_transact_auto = true;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void binderExitSession(Binder *session)
|
||||
void binderExitSession(Binder* b)
|
||||
{
|
||||
if (!session->created) return;
|
||||
if (!b->created)
|
||||
return;
|
||||
|
||||
if (session->initialized) {
|
||||
binderAdjustRefcount(session, -1, 1);
|
||||
binderAdjustRefcount(session, -1, 0);
|
||||
if (b->initialized) {
|
||||
binderAdjustRefcount(b, -1, 1);
|
||||
binderAdjustRefcount(b, -1, 0);
|
||||
|
||||
if (session->nativeHandle != INVALID_HANDLE) {
|
||||
svcCloseHandle(session->nativeHandle);
|
||||
session->nativeHandle = INVALID_HANDLE;
|
||||
if (b->native_handle != INVALID_HANDLE) {
|
||||
svcCloseHandle(b->native_handle);
|
||||
b->native_handle = INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
session->sessionHandle = INVALID_HANDLE;
|
||||
session->id = 0;
|
||||
b->session_handle = INVALID_HANDLE;
|
||||
b->id = 0;
|
||||
|
||||
session->created = 0;
|
||||
session->initialized = 0;
|
||||
b->created = false;
|
||||
b->initialized = false;
|
||||
}
|
||||
|
||||
static Result _binderTransactParcel(
|
||||
Binder *session, u32 code,
|
||||
Binder* b, u32 code,
|
||||
void* parcel_data, size_t parcel_data_size,
|
||||
void* parcel_reply, size_t parcel_reply_size,
|
||||
u32 flags)
|
||||
{
|
||||
if (!session->created || !session->initialized) return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
if (!b->created || !b->initialized)
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
@ -111,11 +116,11 @@ static Result _binderTransactParcel(
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 0;
|
||||
raw->session_id = session->id;
|
||||
raw->session_id = b->id;
|
||||
raw->code = code;
|
||||
raw->flags = flags;
|
||||
|
||||
Result rc = ipcDispatch(session->sessionHandle);
|
||||
Result rc = ipcDispatch(b->session_handle);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
@ -133,12 +138,13 @@ static Result _binderTransactParcel(
|
||||
}
|
||||
|
||||
static Result _binderTransactParcelAuto(
|
||||
Binder *session, u32 code,
|
||||
Binder* b, u32 code,
|
||||
void* parcel_data, size_t parcel_data_size,
|
||||
void* parcel_reply, size_t parcel_reply_size,
|
||||
u32 flags)
|
||||
{
|
||||
if (!session->created || !session->initialized) return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
if (!b->created || !b->initialized)
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
@ -151,17 +157,17 @@ static Result _binderTransactParcelAuto(
|
||||
u32 flags;
|
||||
} *raw;
|
||||
|
||||
ipcAddSendSmart(&c, session->ipcBufferSize, parcel_data, parcel_data_size, 0);
|
||||
ipcAddRecvSmart(&c, session->ipcBufferSize, parcel_reply, parcel_reply_size, 0);
|
||||
ipcAddSendSmart(&c, b->ipc_buffer_size, parcel_data, parcel_data_size, 0);
|
||||
ipcAddRecvSmart(&c, b->ipc_buffer_size, parcel_reply, parcel_reply_size, 0);
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 3;
|
||||
raw->session_id = session->id;
|
||||
raw->session_id = b->id;
|
||||
raw->code = code;
|
||||
raw->flags = flags;
|
||||
|
||||
Result rc = ipcDispatch(session->sessionHandle);
|
||||
Result rc = ipcDispatch(b->session_handle);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
@ -179,24 +185,25 @@ static Result _binderTransactParcelAuto(
|
||||
}
|
||||
|
||||
Result binderTransactParcel(
|
||||
Binder *session, u32 code,
|
||||
Binder* b, u32 code,
|
||||
void* parcel_data, size_t parcel_data_size,
|
||||
void* parcel_reply, size_t parcel_reply_size,
|
||||
u32 flags)
|
||||
{
|
||||
Result rc = 0;
|
||||
|
||||
if (session->hasTransactAuto)
|
||||
rc = _binderTransactParcelAuto(session, code, parcel_data, parcel_data_size, parcel_reply, parcel_reply_size, flags);
|
||||
if (b->has_transact_auto)
|
||||
rc = _binderTransactParcelAuto(b, code, parcel_data, parcel_data_size, parcel_reply, parcel_reply_size, flags);
|
||||
else
|
||||
rc = _binderTransactParcel(session, code, parcel_data, parcel_data_size, parcel_reply, parcel_reply_size, flags);
|
||||
rc = _binderTransactParcel(b, code, parcel_data, parcel_data_size, parcel_reply, parcel_reply_size, flags);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result binderAdjustRefcount(Binder *session, s32 addval, s32 type)
|
||||
Result binderAdjustRefcount(Binder* b, s32 addval, s32 type)
|
||||
{
|
||||
if (!session->created) return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
if (!b->created)
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
@ -212,11 +219,11 @@ Result binderAdjustRefcount(Binder *session, s32 addval, s32 type)
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 1;
|
||||
raw->session_id = session->id;
|
||||
raw->session_id = b->id;
|
||||
raw->addval = addval;
|
||||
raw->type = type;
|
||||
|
||||
Result rc = ipcDispatch(session->sessionHandle);
|
||||
Result rc = ipcDispatch(b->session_handle);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
@ -233,9 +240,10 @@ Result binderAdjustRefcount(Binder *session, s32 addval, s32 type)
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result binderGetNativeHandle(Binder *session, u32 inval, Handle *handle_out)
|
||||
Result binderGetNativeHandle(Binder* b, u32 inval, Handle *handle_out)
|
||||
{
|
||||
if (!session->created) return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
if (!b->created)
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
@ -251,10 +259,10 @@ Result binderGetNativeHandle(Binder *session, u32 inval, Handle *handle_out)
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 2;
|
||||
raw->session_id = session->id;
|
||||
raw->session_id = b->id;
|
||||
raw->inval = inval;
|
||||
|
||||
Result rc = ipcDispatch(session->sessionHandle);
|
||||
Result rc = ipcDispatch(b->session_handle);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
|
@ -50,8 +50,8 @@ Result bqRequestBuffer(s32 bufferIdx, BqGraphicBuffer *buf)
|
||||
if (g_bqBinderSession == NULL)
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
parcelInitialize(&parcel);
|
||||
parcelInitialize(&parcel_reply);
|
||||
parcelCreate(&parcel);
|
||||
parcelCreate(&parcel_reply);
|
||||
|
||||
parcelWriteInterfaceToken(&parcel, g_bq_InterfaceDescriptor);
|
||||
parcelWriteInt32(&parcel, bufferIdx);
|
||||
@ -91,8 +91,8 @@ Result bqDequeueBuffer(bool async, u32 width, u32 height, s32 format, u32 usage,
|
||||
if (g_bqBinderSession == NULL)
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
parcelInitialize(&parcel);
|
||||
parcelInitialize(&parcel_reply);
|
||||
parcelCreate(&parcel);
|
||||
parcelCreate(&parcel_reply);
|
||||
|
||||
parcelWriteInterfaceToken(&parcel, g_bq_InterfaceDescriptor);
|
||||
|
||||
@ -135,8 +135,8 @@ Result bqDetachBuffer(s32 slot)
|
||||
if (g_bqBinderSession == NULL)
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
parcelInitialize(&parcel);
|
||||
parcelInitialize(&parcel_reply);
|
||||
parcelCreate(&parcel);
|
||||
parcelCreate(&parcel_reply);
|
||||
|
||||
parcelWriteInterfaceToken(&parcel, g_bq_InterfaceDescriptor);
|
||||
parcelWriteInt32(&parcel, slot);
|
||||
@ -158,8 +158,8 @@ Result bqQueueBuffer(s32 buf, BqQueueBufferInput *input, BqQueueBufferOutput *ou
|
||||
if (g_bqBinderSession == NULL)
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
parcelInitialize(&parcel);
|
||||
parcelInitialize(&parcel_reply);
|
||||
parcelCreate(&parcel);
|
||||
parcelCreate(&parcel_reply);
|
||||
|
||||
parcelWriteInterfaceToken(&parcel, g_bq_InterfaceDescriptor);
|
||||
parcelWriteInt32(&parcel, buf);
|
||||
@ -187,8 +187,8 @@ Result bqQuery(s32 what, s32* value)
|
||||
if (g_bqBinderSession == NULL)
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
parcelInitialize(&parcel);
|
||||
parcelInitialize(&parcel_reply);
|
||||
parcelCreate(&parcel);
|
||||
parcelCreate(&parcel_reply);
|
||||
|
||||
parcelWriteInterfaceToken(&parcel, g_bq_InterfaceDescriptor);
|
||||
parcelWriteInt32(&parcel, what);
|
||||
@ -214,8 +214,8 @@ Result bqConnect(s32 api, bool producerControlledByApp, BqQueueBufferOutput *out
|
||||
if (g_bqBinderSession == NULL)
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
parcelInitialize(&parcel);
|
||||
parcelInitialize(&parcel_reply);
|
||||
parcelCreate(&parcel);
|
||||
parcelCreate(&parcel_reply);
|
||||
|
||||
parcelWriteInterfaceToken(&parcel, g_bq_InterfaceDescriptor);
|
||||
|
||||
@ -246,8 +246,8 @@ Result bqDisconnect(s32 api)
|
||||
if (g_bqBinderSession == NULL)
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
parcelInitialize(&parcel);
|
||||
parcelInitialize(&parcel_reply);
|
||||
parcelCreate(&parcel);
|
||||
parcelCreate(&parcel_reply);
|
||||
|
||||
parcelWriteInterfaceToken(&parcel, g_bq_InterfaceDescriptor);
|
||||
parcelWriteInt32(&parcel, api);
|
||||
@ -270,8 +270,8 @@ Result bqGraphicBufferInit(s32 buf, BqGraphicBuffer *input)
|
||||
if (g_bqBinderSession == NULL)
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
parcelInitialize(&parcel);
|
||||
parcelInitialize(&parcel_reply);
|
||||
parcelCreate(&parcel);
|
||||
parcelCreate(&parcel_reply);
|
||||
|
||||
parcelWriteInterfaceToken(&parcel, g_bq_InterfaceDescriptor);
|
||||
parcelWriteInt32(&parcel, buf);
|
||||
|
@ -235,7 +235,7 @@ static Result _gfxInit(ViServiceType servicetype, const char *DisplayName, u32 L
|
||||
if (R_SUCCEEDED(rc)) rc = _gfxGetNativeWindowID(g_gfxNativeWindow, g_gfxNativeWindow_Size, &g_gfxNativeWindow_ID);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
binderCreateSession(&g_gfxBinderSession, viGetSession_IHOSBinderDriverRelay()->handle, g_gfxNativeWindow_ID);
|
||||
binderCreate(&g_gfxBinderSession, viGetSession_IHOSBinderDriverRelay()->handle, g_gfxNativeWindow_ID);
|
||||
rc = binderInitSession(&g_gfxBinderSession, 0x0f);
|
||||
}
|
||||
|
||||
@ -291,7 +291,7 @@ static Result _gfxInit(ViServiceType servicetype, const char *DisplayName, u32 L
|
||||
|
||||
nvgfxExit();
|
||||
bqExit();
|
||||
binderExitSession(&g_gfxBinderSession);
|
||||
binderClose(&g_gfxBinderSession);
|
||||
nvExit();
|
||||
|
||||
viCloseLayer(&g_gfxLayer);
|
||||
@ -361,7 +361,7 @@ void gfxExit(void)
|
||||
nvgfxExit();
|
||||
|
||||
bqExit();
|
||||
binderExitSession(&g_gfxBinderSession);
|
||||
binderClose(&g_gfxBinderSession);
|
||||
|
||||
nvExit();
|
||||
|
||||
|
@ -11,7 +11,7 @@ typedef struct {
|
||||
u32 objects_off;
|
||||
} ParcelHeader;
|
||||
|
||||
void parcelInitialize(Parcel *ctx)
|
||||
void parcelCreate(Parcel *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(Parcel));
|
||||
ctx->capacity = sizeof(ctx->payload);
|
||||
|
38
nx/source/nvidia/address_space.c
Normal file
38
nx/source/nvidia/address_space.c
Normal file
@ -0,0 +1,38 @@
|
||||
#include <switch.h>
|
||||
|
||||
Result nvasCreate(NvAddressSpace* a)
|
||||
{
|
||||
Result rc = nvOpen(&a->fd, "/dev/nvhost-as-gpu");
|
||||
|
||||
if (R_SUCCEEDED(rc))
|
||||
{
|
||||
rc = nvioctlNvhostAsGpu_InitializeEx(a->fd, 1, 0x100);
|
||||
|
||||
if (R_FAILED(rc))
|
||||
nvasClose(a);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result nvasClose(NvAddressSpace* a)
|
||||
{
|
||||
nvClose(a->fd);
|
||||
a->fd = -1;
|
||||
}
|
||||
|
||||
Result nvasReserveAlign(NvAddressSpace* a, NvPageSize align, u32 pages, NvPageSize page_sz, iova_t* iova_out) {
|
||||
return nvioctlNvhostAsGpu_AllocSpace(a->fd, pages, page_sz, 0, align, iova_out);
|
||||
}
|
||||
|
||||
Result nvasReserveAtFixedAddr(NvAddressSpace* a, iova_t addr, u32 pages, NvPageSize page_sz) {
|
||||
return nvioctlNvhostAsGpu_AllocSpace(a->fd, pages, page_sz, 1, addr, NULL);
|
||||
}
|
||||
|
||||
Result nvasReserveFull(NvAddressSpace* a) {
|
||||
return nvasReserveAlign(a, NvPageSize_64K, 0x10000, NvPageSize_64K, NULL);
|
||||
}
|
||||
|
||||
Result nvasMapBuffer(NvAddressSpace* a, Nvmap* buffer, NvmapKind kind, iova_t* iova_out) {
|
||||
return nvioctlNvhostAsGpu_MapBufferEx(a->fd, 0, kind, buffer->fd, 0, 0, buffer->size, 0, iova_out);
|
||||
}
|
@ -15,7 +15,7 @@ Result nvioctlNvhostAsGpu_BindChannel(u32 fd, u32 channel_fd) {
|
||||
return nvIoctl(fd, _NV_IOW(0x41, 0x01, data), &data);
|
||||
}
|
||||
|
||||
Result nvioctlNvhostAsGpu_AllocSpace(u32 fd, u32 pages, u32 page_size, u32 flags, u64 align, u64 *offset) {
|
||||
Result nvioctlNvhostAsGpu_AllocSpace(u32 fd, u32 pages, u32 page_size, u32 flags, u64 align_or_offset, u64 *offset) {
|
||||
Result rc = 0;
|
||||
|
||||
struct {
|
||||
@ -33,11 +33,12 @@ Result nvioctlNvhostAsGpu_AllocSpace(u32 fd, u32 pages, u32 page_size, u32 flags
|
||||
data.pages = pages;
|
||||
data.page_size = page_size;
|
||||
data.flags = flags;
|
||||
data.align = align;
|
||||
data.align = align_or_offset;
|
||||
|
||||
rc = nvIoctl(fd, _NV_IOWR(0x41, 0x02, data), &data);
|
||||
if (R_FAILED(rc)) return rc;
|
||||
|
||||
if (offset != NULL)
|
||||
*offset = data.offset;
|
||||
|
||||
return rc;
|
||||
|
Loading…
Reference in New Issue
Block a user