Implemented the ioctls which were skipped during nvgfx init. nvgfx init adjustments. Fixed ioctl direction define for nvioctlNvhostAsGpu_MapBufferEx, this now works properly.

This commit is contained in:
yellows8 2017-11-13 23:27:54 -05:00
parent 704ead0d5f
commit 0cc65093e3
3 changed files with 117 additions and 21 deletions

View File

@ -36,10 +36,21 @@ typedef struct {
u64 gr_compbit_store_base_hw; // 0x0 (not supported)
} gpu_characteristics;
typedef struct {
u64 offset;
u32 page_size;
u32 pad;
u64 pages;
} nvioctl_va_region;
Result nvioctlNvhostCtrlGpu_ZCullGetCtxSize(u32 fd, u32 *out);
Result nvioctlNvhostCtrlGpu_ZCullGetInfo(u32 fd, u32 out[40>>2]);
Result nvioctlNvhostCtrlGpu_GetCharacteristics(u32 fd, gpu_characteristics *out);
Result nvioctlNvhostCtrlGpu_GetTpcMasks(u32 fd, u32 inval, u32 out[24>>2]);
Result nvioctlNvhostAsGpu_AllocSpace(u32 fd, u32 pages, u32 page_size, u32 flags, u64 align, u64 *offset);
Result nvioctlNvhostAsGpu_MapBufferEx(u32 fd, u32 flags, u32 kind, u32 nvmap_handle, u32 page_size, u64 buffer_offset, u64 mapping_size, u64 *offset);
Result nvioctlNvhostAsGpu_GetVARegions(u32 fd, nvioctl_va_region regions[2]);
Result nvioctlNvhostAsGpu_InitializeEx(u32 fd, u32 big_page_size);
Result nvioctlNvmap_Create(u32 fd, u32 size, u32 *nvmap_handle);

View File

@ -6,10 +6,14 @@ static bool g_nvgfxInitialized = 0;
static u32 g_nvgfx_fd_nvhostctrlgpu;
static u32 g_nvgfx_fd_nvhostasgpu;
static u32 g_nvgfx_fd_nvmap;
static u32 g_nvgfx_nvmapobj;
static u32 g_nvgfx_nvmapobj0;
static gpu_characteristics g_nvgfx_gpu_characteristics;
static u64 g_nvgfx_nvhostasgpu_allocspace_offset;
static u32 g_nvgfx_tpcmasks[24>>2];
static u32 g_nvgfx_zcullctxsize;
static u32 g_nvgfx_zcullinfo[40>>2];
static nvioctl_va_region g_nvgfx_nvhostasgpu_varegions[2];
static u8 *g_nvgfx_nvmap_mem;
size_t g_nvgfx_nvmap_mem_size;
@ -21,16 +25,21 @@ Result nvgfxInitialize(void) {
g_nvgfx_fd_nvhostctrlgpu = 0;
g_nvgfx_fd_nvhostasgpu = 0;
g_nvgfx_fd_nvmap = 0;
g_nvgfx_nvmapobj = 0;
g_nvgfx_nvmapobj0 = 0;
memset(&g_nvgfx_gpu_characteristics, 0, sizeof(gpu_characteristics));
memset(g_nvgfx_tpcmasks, 0, sizeof(g_nvgfx_tpcmasks));
memset(g_nvgfx_zcullinfo, 0, sizeof(g_nvgfx_zcullinfo));
memset(g_nvgfx_nvhostasgpu_varegions, 0, sizeof(g_nvgfx_nvhostasgpu_varegions));
g_nvgfx_nvhostasgpu_allocspace_offset = 0;
g_nvgfx_zcullctxsize = 0;
g_nvgfx_nvmap_mem_size = 0x10000;
g_nvgfx_nvmap_mem_size = 0x1000;
if (R_SUCCEEDED(rc)) {
g_nvgfx_nvmap_mem = memalign(0x1000, g_nvgfx_nvmap_mem_size);
if (g_nvgfx_nvmap_mem==NULL) rc = MAKERESULT(MODULE_LIBNX, LIBNX_OUTOFMEM);
if (R_SUCCEEDED(rc)) memset(g_nvgfx_nvmap_mem, 0, g_nvgfx_nvmap_mem_size);
}
//Officially NVHOST_IOCTL_CTRL_GET_CONFIG is used a lot (here and later), skip that.
@ -38,36 +47,38 @@ Result nvgfxInitialize(void) {
if (R_SUCCEEDED(rc)) rc = nvOpen(&g_nvgfx_fd_nvhostctrlgpu, "/dev/nvhost-ctrl-gpu");
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostCtrlGpu_GetCharacteristics(g_nvgfx_fd_nvhostctrlgpu, &g_nvgfx_gpu_characteristics);
//Officially NVGPU_GPU_IOCTL_GET_TPC_MASKS is used here.
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostCtrlGpu_GetTpcMasks(g_nvgfx_fd_nvhostctrlgpu, 4, g_nvgfx_tpcmasks);
//Officially NVGPU_GPU_IOCTL_ZCULL_GET_CTX_SIZE and NVGPU_GPU_IOCTL_ZCULL_GET_INFO are used here.
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostCtrlGpu_ZCullGetCtxSize(g_nvgfx_fd_nvhostctrlgpu, &g_nvgfx_zcullctxsize);
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostCtrlGpu_ZCullGetInfo(g_nvgfx_fd_nvhostctrlgpu, g_nvgfx_zcullinfo);
if (R_SUCCEEDED(rc)) rc = nvOpen(&g_nvgfx_fd_nvhostasgpu, "/dev/nvhost-as-gpu");
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostAsGpu_InitializeEx(g_nvgfx_fd_nvhostasgpu, 1);
//NVGPU_AS_IOCTL_GET_VA_REGIONS twice
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostAsGpu_AllocSpace(g_nvgfx_fd_nvhostasgpu, 0x10000, 0x1000, 0, 0x1000, &g_nvgfx_nvhostasgpu_allocspace_offset);
//Officially this is used twice here - only use it once here.
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostAsGpu_GetVARegions(g_nvgfx_fd_nvhostasgpu, g_nvgfx_nvhostasgpu_varegions);
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostAsGpu_AllocSpace(g_nvgfx_fd_nvhostasgpu, 0x10000, 0x20000, 0, 0x10000, &g_nvgfx_nvhostasgpu_allocspace_offset);
if (R_SUCCEEDED(rc)) rc = nvOpen(&g_nvgfx_fd_nvmap, "/dev/nvmap");
if (R_SUCCEEDED(rc)) rc = nvioctlNvmap_Create(g_nvgfx_fd_nvmap, g_nvgfx_nvmap_mem_size, &g_nvgfx_nvmapobj);
if (R_SUCCEEDED(rc)) rc = nvioctlNvmap_Create(g_nvgfx_fd_nvmap, g_nvgfx_nvmap_mem_size, &g_nvgfx_nvmapobj0);
if (R_SUCCEEDED(rc)) rc = nvioctlNvmap_Alloc(g_nvgfx_fd_nvmap, g_nvgfx_nvmapobj, 0, 0, 0x20000, 0, g_nvgfx_nvmap_mem);
if (R_SUCCEEDED(rc)) rc = nvioctlNvmap_Alloc(g_nvgfx_fd_nvmap, g_nvgfx_nvmapobj0, 0, 0, 0x20000, 0, g_nvgfx_nvmap_mem);
//Currently broken.
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostAsGpu_MapBufferEx(g_nvgfx_fd_nvhostasgpu, 4, 0, g_nvgfx_nvmapobj, 0x1000, 0, g_nvgfx_nvmap_mem_size, NULL);
if (R_SUCCEEDED(rc)) rc = -1;
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostAsGpu_MapBufferEx(g_nvgfx_fd_nvhostasgpu, 4, 0xfe, g_nvgfx_nvmapobj, 0x1000, 0, g_nvgfx_nvmap_mem_size, NULL);
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostAsGpu_MapBufferEx(g_nvgfx_fd_nvhostasgpu, 0, 0, g_nvgfx_nvmapobj0, 0x10000, 0, 0, NULL);
if (R_SUCCEEDED(rc)) rc = nvioctlNvhostAsGpu_MapBufferEx(g_nvgfx_fd_nvhostasgpu, 0, 0xfe, g_nvgfx_nvmapobj0, 0x10000, 0, 0, NULL);
//if (R_SUCCEEDED(rc)) rc = -1;
if (R_FAILED(rc)) nvClose(g_nvgfx_fd_nvmap);
if (R_FAILED(rc)) nvClose(g_nvgfx_fd_nvhostasgpu);
if (R_FAILED(rc)) nvClose(g_nvgfx_fd_nvhostctrlgpu);
if (R_FAILED(rc)) {
nvClose(g_nvgfx_fd_nvmap);
nvClose(g_nvgfx_fd_nvhostasgpu);
nvClose(g_nvgfx_fd_nvhostctrlgpu);
if (g_nvgfx_nvmap_mem) {
free(g_nvgfx_nvmap_mem);
g_nvgfx_nvmap_mem = NULL;
if (g_nvgfx_nvmap_mem) {
free(g_nvgfx_nvmap_mem);
g_nvgfx_nvmap_mem = NULL;
}
}
if (R_SUCCEEDED(rc)) g_nvgfxInitialized = 1;

View File

@ -1,6 +1,40 @@
#include <string.h>
#include <switch.h>
Result nvioctlNvhostCtrlGpu_ZCullGetCtxSize(u32 fd, u32 *out) {
Result rc = 0;
struct {
u32 out;
} data;
memset(&data, 0, sizeof(data));
rc = nvIoctl(fd, _IOR(0x47, 0x01, data), &data);
if (R_FAILED(rc)) return rc;
*out = data.out;
return rc;
}
Result nvioctlNvhostCtrlGpu_ZCullGetInfo(u32 fd, u32 out[40>>2]) {
Result rc = 0;
struct {
u32 out[40>>2];
} data;
memset(&data, 0, sizeof(data));
rc = nvIoctl(fd, _IOR(0x47, 0x02, data), &data);
if (R_FAILED(rc)) return rc;
memcpy(out, data.out, sizeof(data.out));
return rc;
}
Result nvioctlNvhostCtrlGpu_GetCharacteristics(u32 fd, gpu_characteristics *out) {
Result rc = 0;
@ -22,6 +56,25 @@ Result nvioctlNvhostCtrlGpu_GetCharacteristics(u32 fd, gpu_characteristics *out)
return rc;
}
Result nvioctlNvhostCtrlGpu_GetTpcMasks(u32 fd, u32 inval, u32 out[24>>2]) {
Result rc = 0;
struct {
u32 unk[24>>2];
} data;
memset(&data, 0, sizeof(data));
data.unk[0] = inval;
data.unk[2] = 1;//addr?
rc = nvIoctl(fd, _IOWR(0x47, 0x06, data), &data);
if (R_FAILED(rc)) return rc;
memcpy(out, &data.unk, sizeof(data.unk));
return rc;
}
Result nvioctlNvhostAsGpu_AllocSpace(u32 fd, u32 pages, u32 page_size, u32 flags, u64 align, u64 *offset) {
Result rc=0;
@ -71,7 +124,7 @@ Result nvioctlNvhostAsGpu_MapBufferEx(u32 fd, u32 flags, u32 kind, u32 nvmap_han
data.buffer_offset = buffer_offset;
data.mapping_size = mapping_size;
rc = nvIoctl(fd, _IOW(0x41, 0x06, data), &data);
rc = nvIoctl(fd, _IOWR(0x41, 0x06, data), &data);
if (R_FAILED(rc)) return rc;
if (offset) *offset = data.offset;
@ -79,6 +132,27 @@ Result nvioctlNvhostAsGpu_MapBufferEx(u32 fd, u32 flags, u32 kind, u32 nvmap_han
return rc;
}
Result nvioctlNvhostAsGpu_GetVARegions(u32 fd, nvioctl_va_region regions[2]) {
Result rc=0;
struct {
u64 not_used; // (contained output user ptr on linux, ignored)
u32 bufsize; //inout forced to 2*sizeof(struct va_region)
u32 pad;
nvioctl_va_region regions[2];//out
} data;
memset(&data, 0, sizeof(data));
data.bufsize = sizeof(data.regions);
rc = nvIoctl(fd, _IOWR(0x41, 0x08, data), &data);
if (R_FAILED(rc)) return rc;
memcpy(regions, data.regions, sizeof(data.regions));
return rc;
}
Result nvioctlNvhostAsGpu_InitializeEx(u32 fd, u32 big_page_size) {
struct {
u32 big_page_size; // depends on GPU's available_big_page_sizes; 0=default