mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-23 21:32:39 +02:00
NvAddressSpace: major overhaul, see details:
- Now contains a 'page_size' field, used throughout the functions - Removed NvPageSize - Removed nvAddressSpaceReserveAlign/AtFixedAddr/Full - Added nvAddressSpaceAlloc/AllocFixed/Free (replacing above functions) - Removed nvAddressSpaceMapBuffer/UnmapBuffer - Added nvAddressSpaceMap/MapFixed/Modify/Unmap (replacing above functions) - Adapted NvBuffer/NvGpu to use the new functions
This commit is contained in:
parent
22499d8ddf
commit
85a20f43dc
@ -3,23 +3,21 @@
|
||||
|
||||
typedef struct NvAddressSpace {
|
||||
u32 fd;
|
||||
u32 page_size;
|
||||
bool has_init;
|
||||
} NvAddressSpace;
|
||||
|
||||
typedef enum {
|
||||
NvPageSize_4K = 0x1000,
|
||||
NvPageSize_64K = 0x10000
|
||||
} NvPageSize;
|
||||
|
||||
Result nvAddressSpaceCreate(NvAddressSpace* a);
|
||||
Result nvAddressSpaceCreate(NvAddressSpace* a, u32 page_size);
|
||||
void nvAddressSpaceClose(NvAddressSpace* a);
|
||||
|
||||
Result nvAddressSpaceReserveAlign(NvAddressSpace* a, NvPageSize align, u32 pages, NvPageSize page_sz, iova_t* iova_out);
|
||||
Result nvAddressSpaceReserveAtFixedAddr(NvAddressSpace* a, iova_t addr, u32 pages, NvPageSize page_sz);
|
||||
Result nvAddressSpaceReserveFull(NvAddressSpace* a);
|
||||
Result nvAddressSpaceAlloc(NvAddressSpace* a, bool sparse, u64 size, iova_t* iova_out);
|
||||
Result nvAddressSpaceAllocFixed(NvAddressSpace* a, bool sparse, u64 size, iova_t iova);
|
||||
Result nvAddressSpaceFree(NvAddressSpace* a, iova_t iova, u64 size);
|
||||
|
||||
Result nvAddressSpaceMapBuffer(NvAddressSpace* a, u32 fd, u32 flags, NvKind kind, iova_t* iova_out);
|
||||
Result nvAddressSpaceUnmapBuffer(NvAddressSpace* a, iova_t iova);
|
||||
Result nvAddressSpaceMap(NvAddressSpace* a, u32 nvmap_handle, bool is_gpu_cacheable, NvKind kind, iova_t* iova_out);
|
||||
Result nvAddressSpaceMapFixed(NvAddressSpace* a, u32 nvmap_handle, bool is_gpu_cacheable, NvKind kind, iova_t iova);
|
||||
Result nvAddressSpaceModify(NvAddressSpace* a, iova_t iova, u64 offset, u64 size, NvKind kind);
|
||||
Result nvAddressSpaceUnmap(NvAddressSpace* a, iova_t iova);
|
||||
|
||||
struct NvChannel;
|
||||
Result nvAddressSpaceBindToChannel(NvAddressSpace* a, struct NvChannel* channel);
|
||||
|
@ -9,11 +9,12 @@
|
||||
#include "nvidia/channel.h"
|
||||
#include "nvidia/address_space.h"
|
||||
|
||||
Result nvAddressSpaceCreate(NvAddressSpace* a)
|
||||
Result nvAddressSpaceCreate(NvAddressSpace* a, u32 page_size)
|
||||
{
|
||||
Result rc;
|
||||
|
||||
a->has_init = true;
|
||||
a->page_size = page_size;
|
||||
|
||||
rc = nvOpen(&a->fd, "/dev/nvhost-as-gpu");
|
||||
|
||||
@ -21,7 +22,7 @@ Result nvAddressSpaceCreate(NvAddressSpace* a)
|
||||
a->fd = -1;
|
||||
|
||||
if (R_SUCCEEDED(rc))
|
||||
rc = nvioctlNvhostAsGpu_InitializeEx(a->fd, 1, 0x10000);
|
||||
rc = nvioctlNvhostAsGpu_InitializeEx(a->fd, 1, 0x10000); // Official sw uses hardcoded size
|
||||
|
||||
if (R_FAILED(rc))
|
||||
nvAddressSpaceClose(a);
|
||||
@ -38,34 +39,65 @@ void nvAddressSpaceClose(NvAddressSpace* a)
|
||||
nvClose(a->fd);
|
||||
|
||||
a->fd = -1;
|
||||
a->has_init = false;
|
||||
}
|
||||
|
||||
Result nvAddressSpaceReserveAlign(
|
||||
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 nvAddressSpaceAlloc(NvAddressSpace* a, bool sparse, u64 size, iova_t* iova_out)
|
||||
{
|
||||
u32 num_pages = (size + a->page_size - 1) / a->page_size; // Round up to page size
|
||||
return nvioctlNvhostAsGpu_AllocSpace(a->fd, num_pages, a->page_size,
|
||||
sparse ? NvAllocSpaceFlags_Sparse : 0, a->page_size, iova_out);
|
||||
}
|
||||
|
||||
Result nvAddressSpaceReserveAtFixedAddr(
|
||||
NvAddressSpace* a, iova_t addr, u32 pages, NvPageSize page_sz) {
|
||||
return nvioctlNvhostAsGpu_AllocSpace(a->fd, pages, page_sz, 1, addr, NULL);
|
||||
Result nvAddressSpaceAllocFixed(NvAddressSpace* a, bool sparse, u64 size, iova_t iova)
|
||||
{
|
||||
if (iova & (a->page_size - 1))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||
u32 num_pages = size / a->page_size; // Round down
|
||||
return nvioctlNvhostAsGpu_AllocSpace(a->fd, num_pages, a->page_size,
|
||||
NvMapBufferFlags_FixedOffset | (sparse ? NvAllocSpaceFlags_Sparse : 0), iova, NULL);
|
||||
}
|
||||
|
||||
Result nvAddressSpaceReserveFull(NvAddressSpace* a) {
|
||||
return nvAddressSpaceReserveAlign(a, NvPageSize_64K, 0x10000, NvPageSize_64K, NULL);
|
||||
Result nvAddressSpaceFree(NvAddressSpace* a, iova_t iova, u64 size)
|
||||
{
|
||||
if (iova & (a->page_size - 1))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||
u32 num_pages = size / a->page_size; // Round down
|
||||
return nvioctlNvhostAsGpu_FreeSpace(a->fd, iova, num_pages, a->page_size);
|
||||
}
|
||||
|
||||
Result nvAddressSpaceMapBuffer(
|
||||
NvAddressSpace* a, u32 fd, u32 flags, NvKind kind,
|
||||
iova_t* iova_out) {
|
||||
return nvioctlNvhostAsGpu_MapBufferEx(
|
||||
a->fd, flags, kind, fd, 0x10000, 0, 0, 0, iova_out);
|
||||
Result nvAddressSpaceMap(NvAddressSpace* a, u32 nvmap_handle, bool is_gpu_cacheable, NvKind kind, iova_t* iova_out)
|
||||
{
|
||||
return nvioctlNvhostAsGpu_MapBufferEx(a->fd,
|
||||
is_gpu_cacheable ? NvMapBufferFlags_IsCacheable : 0, kind,
|
||||
nvmap_handle, a->page_size, 0, 0, 0, iova_out);
|
||||
}
|
||||
|
||||
Result nvAddressSpaceUnmapBuffer(NvAddressSpace* a, iova_t iova) {
|
||||
Result nvAddressSpaceMapFixed(NvAddressSpace* a, u32 nvmap_handle, bool is_gpu_cacheable, NvKind kind, iova_t iova)
|
||||
{
|
||||
if (iova & (a->page_size - 1))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||
return nvioctlNvhostAsGpu_MapBufferEx(a->fd,
|
||||
NvMapBufferFlags_FixedOffset | (is_gpu_cacheable ? NvMapBufferFlags_IsCacheable : 0), kind,
|
||||
nvmap_handle, a->page_size, 0, 0, iova, NULL);
|
||||
}
|
||||
|
||||
Result nvAddressSpaceModify(NvAddressSpace* a, iova_t iova, u64 offset, u64 size, NvKind kind)
|
||||
{
|
||||
if (iova & (a->page_size - 1))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||
u64 end_offset = (offset + size + a->page_size - 1) &~ (a->page_size - 1);
|
||||
offset &= a->page_size - 1;
|
||||
size = end_offset - offset;
|
||||
return nvioctlNvhostAsGpu_MapBufferEx(a->fd, NvMapBufferFlags_Modify, kind, 0, 0, offset, size, iova, NULL);
|
||||
}
|
||||
|
||||
Result nvAddressSpaceUnmap(NvAddressSpace* a, iova_t iova)
|
||||
{
|
||||
return nvioctlNvhostAsGpu_UnmapBuffer(a->fd, iova);
|
||||
}
|
||||
|
||||
Result nvAddressSpaceBindToChannel(NvAddressSpace* a, NvChannel* channel) {
|
||||
Result nvAddressSpaceBindToChannel(NvAddressSpace* a, NvChannel* channel)
|
||||
{
|
||||
return nvioctlNvhostAsGpu_BindChannel(a->fd, channel->fd);
|
||||
}
|
||||
|
@ -76,8 +76,7 @@ Result nvBufferCreate(
|
||||
}
|
||||
|
||||
if (R_SUCCEEDED(rc))
|
||||
rc = nvAddressSpaceMapBuffer(as, m->fd,
|
||||
is_gpu_cacheable ? NvMapBufferFlags_IsCacheable : 0, NvKind_Pitch, &m->gpu_addr);
|
||||
rc = nvAddressSpaceMap(as, m->fd, is_gpu_cacheable, NvKind_Pitch, &m->gpu_addr);
|
||||
|
||||
if (R_FAILED(rc))
|
||||
nvBufferFree(m);
|
||||
@ -91,12 +90,12 @@ void nvBufferFree(NvBuffer* m)
|
||||
return;
|
||||
|
||||
if (m->gpu_addr_texture) {
|
||||
nvAddressSpaceUnmapBuffer(m->addr_space, m->gpu_addr_texture);
|
||||
nvAddressSpaceUnmap(m->addr_space, m->gpu_addr_texture);
|
||||
m->gpu_addr_texture = 0;
|
||||
}
|
||||
|
||||
if (m->gpu_addr) {
|
||||
nvAddressSpaceUnmapBuffer(m->addr_space, m->gpu_addr);
|
||||
nvAddressSpaceUnmap(m->addr_space, m->gpu_addr);
|
||||
m->gpu_addr = 0;
|
||||
}
|
||||
|
||||
@ -125,8 +124,7 @@ iova_t nvBufferGetGpuAddr(NvBuffer* m) {
|
||||
}
|
||||
|
||||
Result nvBufferMapAsTexture(NvBuffer* m, NvKind kind) {
|
||||
return nvAddressSpaceMapBuffer(m->addr_space, m->fd,
|
||||
m->is_gpu_cacheable ? NvMapBufferFlags_IsCacheable : 0, kind, &m->gpu_addr_texture);
|
||||
return nvAddressSpaceMap(m->addr_space, m->fd, m->is_gpu_cacheable, kind, &m->gpu_addr_texture);
|
||||
}
|
||||
|
||||
iova_t nvBufferGetGpuAddrTexture(NvBuffer* m) {
|
||||
|
@ -33,10 +33,7 @@ Result nvGpuCreate(NvGpu* g)
|
||||
rc = nvChannelCreate(&g->gpu_channel, "/dev/nvhost-gpu");
|
||||
|
||||
if (R_SUCCEEDED(rc))
|
||||
rc = nvAddressSpaceCreate(&g->addr_space);
|
||||
|
||||
if (R_SUCCEEDED(rc))
|
||||
rc = nvAddressSpaceReserveFull(&g->addr_space);
|
||||
rc = nvAddressSpaceCreate(&g->addr_space, nvInfoGetGpuCharacteristics()->big_page_size);
|
||||
|
||||
if (R_SUCCEEDED(rc))
|
||||
rc = nvAddressSpaceBindToChannel(&g->addr_space, &g->gpu_channel);
|
||||
|
Loading…
Reference in New Issue
Block a user