From f13c3cfaceb94edc724c32308ab0453a719029b9 Mon Sep 17 00:00:00 2001 From: fincs Date: Fri, 17 May 2019 18:05:18 +0200 Subject: [PATCH] Add/correct /dev/nvhost-ctrl-gpu ioctls --- nx/include/switch/nvidia/ioctl.h | 41 +++++++++++--- nx/source/nvidia/ioctl/nvhost-ctrl-gpu.c | 69 +++++++++++++++++++----- 2 files changed, 92 insertions(+), 18 deletions(-) diff --git a/nx/include/switch/nvidia/ioctl.h b/nx/include/switch/nvidia/ioctl.h index bf893004..3fa16d12 100644 --- a/nx/include/switch/nvidia/ioctl.h +++ b/nx/include/switch/nvidia/ioctl.h @@ -44,6 +44,29 @@ #define __nv_out #define __nv_inout +typedef struct { + u32 width_align_pixels; // 0x20 (32) + u32 height_align_pixels; // 0x20 (32) + u32 pixel_squares_by_aliquots; // 0x400 (1024) + u32 aliquot_total; // 0x800 (2048) + u32 region_byte_multiplier; // 0x20 (32) + u32 region_header_size; // 0x20 (32) + u32 subregion_header_size; // 0xC0 (192) + u32 subregion_width_align_pixels; // 0x20 (32) + u32 subregion_height_align_pixels; // 0x40 (64) + u32 subregion_count; // 0x10 (16) +} nvioctl_zcull_info; + +typedef struct { + u32 color_ds[4]; + u32 color_l2[4]; + u32 depth; + u32 ref_cnt; + u32 format; + u32 type; + u32 size; +} nvioctl_zbc_entry; + typedef struct { u32 arch; // 0x120 (NVGPU_GPU_ARCH_GM200) u32 impl; // 0xB (NVGPU_GPU_IMPL_GM20B) @@ -90,9 +113,9 @@ typedef struct { } nvioctl_va_region; typedef struct { - u32 mask; // always 0x07 - u32 flush; // active flush bit field -} nvioctl_l2_state; + u32 slot; // always 0x07 (?) + u32 mask; +} nvioctl_zbc_slot_mask; typedef struct { u32 id; @@ -106,6 +129,10 @@ typedef struct { }; } nvioctl_gpfifo_entry; +#define NVGPU_ZBC_TYPE_INVALID 0 +#define NVGPU_ZBC_TYPE_COLOR 1 +#define NVGPU_ZBC_TYPE_DEPTH 2 + // Used with nvioctlNvmap_Param(). typedef enum nvioctl_map_param { NvMapParam_Size = 1, @@ -181,10 +208,12 @@ Result nvioctlNvhostCtrl_EventRegister(u32 fd, u32 event_id); Result nvioctlNvhostCtrl_EventUnregister(u32 fd, u32 event_id); Result nvioctlNvhostCtrlGpu_ZCullGetCtxSize(u32 fd, u32 *out); -Result nvioctlNvhostCtrlGpu_ZCullGetInfo(u32 fd, u32 out[40>>2]); +Result nvioctlNvhostCtrlGpu_ZCullGetInfo(u32 fd, nvioctl_zcull_info *out); +Result nvioctlNvhostCtrlGpu_ZbcSetTable(u32 fd, const u32 color_ds[4], const u32 color_l2[4], u32 depth, u32 format, u32 type); +Result nvioctlNvhostCtrlGpu_ZbcQueryTable(u32 fd, u32 index, nvioctl_zbc_entry *out); Result nvioctlNvhostCtrlGpu_GetCharacteristics(u32 fd, nvioctl_gpu_characteristics *out); -Result nvioctlNvhostCtrlGpu_GetTpcMasks(u32 fd, u32 inval, u32 out[24>>2]); -Result nvioctlNvhostCtrlGpu_GetL2State(u32 fd, nvioctl_l2_state *out); +Result nvioctlNvhostCtrlGpu_GetTpcMasks(u32 fd, void *buffer, size_t size); +Result nvioctlNvhostCtrlGpu_ZbcGetActiveSlotMask(u32 fd, nvioctl_zbc_slot_mask *out); Result nvioctlNvhostAsGpu_BindChannel(u32 fd, u32 channel_fd); Result nvioctlNvhostAsGpu_AllocSpace(u32 fd, u32 pages, u32 page_size, u32 flags, u64 align_or_offset, u64 *offset); diff --git a/nx/source/nvidia/ioctl/nvhost-ctrl-gpu.c b/nx/source/nvidia/ioctl/nvhost-ctrl-gpu.c index cd5ab979..12dbde84 100644 --- a/nx/source/nvidia/ioctl/nvhost-ctrl-gpu.c +++ b/nx/source/nvidia/ioctl/nvhost-ctrl-gpu.c @@ -22,11 +22,11 @@ Result nvioctlNvhostCtrlGpu_ZCullGetCtxSize(u32 fd, u32 *out) { return rc; } -Result nvioctlNvhostCtrlGpu_ZCullGetInfo(u32 fd, u32 out[40>>2]) { +Result nvioctlNvhostCtrlGpu_ZCullGetInfo(u32 fd, nvioctl_zcull_info *out) { Result rc = 0; struct { - __nv_out u32 out[40>>2]; + __nv_out nvioctl_zcull_info out; } data; memset(&data, 0, sizeof(data)); @@ -34,7 +34,49 @@ Result nvioctlNvhostCtrlGpu_ZCullGetInfo(u32 fd, u32 out[40>>2]) { rc = nvIoctl(fd, _NV_IOR(0x47, 0x02, data), &data); if (R_SUCCEEDED(rc)) { - memcpy(out, data.out, sizeof(data.out)); + *out = data.out; + } + + return rc; +} + +Result nvioctlNvhostCtrlGpu_ZbcSetTable(u32 fd, const u32 color_ds[4], const u32 color_l2[4], u32 depth, u32 format, u32 type) { + Result rc = 0; + + struct { + __nv_in u32 color_ds[4]; + __nv_in u32 color_l2[4]; + __nv_in u32 depth; + __nv_in u32 format; + __nv_in u32 type; // 1=color, 2=depth + } data; + + memset(&data, 0, sizeof(data)); + if (color_ds) memcpy(data.color_ds, color_ds, sizeof(data.color_ds)); + if (color_l2) memcpy(data.color_l2, color_l2, sizeof(data.color_l2)); + data.depth = depth; + data.format = format; + data.type = type; + + rc = nvIoctl(fd, _NV_IOR(0x47, 0x03, data), &data); + + return rc; +} + +Result nvioctlNvhostCtrlGpu_ZbcQueryTable(u32 fd, u32 index, nvioctl_zbc_entry *out) { + Result rc = 0; + + struct { + __nv_inout nvioctl_zbc_entry entry; + } data; + + memset(&data, 0, sizeof(data)); + data.entry.size = index; + + rc = nvIoctl(fd, _NV_IOWR(0x47, 0x04, data), &data); + + if (R_SUCCEEDED(rc)) { + *out = data.entry; } return rc; @@ -62,31 +104,34 @@ Result nvioctlNvhostCtrlGpu_GetCharacteristics(u32 fd, nvioctl_gpu_characteristi return rc; } -Result nvioctlNvhostCtrlGpu_GetTpcMasks(u32 fd, u32 inval, u32 out[24>>2]) { +Result nvioctlNvhostCtrlGpu_GetTpcMasks(u32 fd, void *buffer, size_t size) { Result rc = 0; - // Fixme: This one is wrong. struct { - __nv_inout u32 unk[24>>2]; + __nv_in u32 bufsize; + __nv_in u32 _padding; + __nv_in u64 bufaddr; + __nv_out u8 out[8]; } data; memset(&data, 0, sizeof(data)); - data.unk[0] = inval; - data.unk[2] = 1; //addr? + data.bufsize = size; + data.bufaddr = (u64)buffer; rc = nvIoctl(fd, _NV_IOWR(0x47, 0x06, data), &data); - if (R_FAILED(rc)) return rc; - memcpy(out, &data.unk, sizeof(data.unk)); + if (R_SUCCEEDED(rc)) { + memcpy(buffer, data.out, size); + } return rc; } -Result nvioctlNvhostCtrlGpu_GetL2State(u32 fd, nvioctl_l2_state *out) { +Result nvioctlNvhostCtrlGpu_ZbcGetActiveSlotMask(u32 fd, nvioctl_zbc_slot_mask *out) { Result rc = 0; struct { - __nv_out nvioctl_l2_state out; + __nv_out nvioctl_zbc_slot_mask out; } data; memset(&data, 0, sizeof(data));