mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 04:22:50 +02:00
nv: Added nvIoctl3, updated _nvGetSessionForRequest, and:
* Check hosver in nvIoctl2.
This commit is contained in:
parent
3d9e1a9c7b
commit
04aa28c436
@ -32,7 +32,8 @@ typedef enum {
|
|||||||
|
|
||||||
Result nvOpen(u32 *fd, const char *devicepath);
|
Result nvOpen(u32 *fd, const char *devicepath);
|
||||||
Result nvIoctl(u32 fd, u32 request, void* argp);
|
Result nvIoctl(u32 fd, u32 request, void* argp);
|
||||||
Result nvIoctl2(u32 fd, u32 request, void* argp, const void* inbuf, size_t inbuf_size);
|
Result nvIoctl2(u32 fd, u32 request, void* argp, const void* inbuf, size_t inbuf_size); ///< [3.0.0+]
|
||||||
|
Result nvIoctl3(u32 fd, u32 request, void* argp, void* outbuf, size_t outbuf_size); ///< [3.0.0+]
|
||||||
Result nvClose(u32 fd);
|
Result nvClose(u32 fd);
|
||||||
Result nvQueryEvent(u32 fd, u32 event_id, Event *event_out);
|
Result nvQueryEvent(u32 fd, u32 event_id, Event *event_out);
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "service_guard.h"
|
#include "service_guard.h"
|
||||||
#include "kernel/tmem.h"
|
#include "kernel/tmem.h"
|
||||||
#include "services/applet.h"
|
#include "services/applet.h"
|
||||||
|
#include "runtime/hosversion.h"
|
||||||
#include "services/nv.h"
|
#include "services/nv.h"
|
||||||
#include "nvidia/ioctl.h"
|
#include "nvidia/ioctl.h"
|
||||||
|
|
||||||
@ -112,11 +113,19 @@ Result nvOpen(u32 *fd, const char *devicepath) {
|
|||||||
|
|
||||||
// Get the appropriate session for the specified request (same logic as official sw)
|
// Get the appropriate session for the specified request (same logic as official sw)
|
||||||
static inline Service* _nvGetSessionForRequest(u32 request) {
|
static inline Service* _nvGetSessionForRequest(u32 request) {
|
||||||
|
u32 tmp = request & 0xC000FFFF;
|
||||||
if (
|
if (
|
||||||
(request & 0xC000FFFF) == 0xC0004808 || // NVGPU_IOCTL_CHANNEL_SUBMIT_GPFIFO
|
tmp == 0xC0004402 || // NVGPU_DBG_GPU_IOCTL_REG_OPS
|
||||||
|
tmp == 0xC000471C || // NVGPU_GPU_IOCTL_GET_GPU_TIME
|
||||||
|
tmp == 0xC0004808 || // NVGPU_IOCTL_CHANNEL_SUBMIT_GPFIFO
|
||||||
|
tmp == 0xC0000024 || // NVHOST_IOCTL_CHANNEL_SUBMIT_EX
|
||||||
|
tmp == 0xC0000025 || // NVHOST_IOCTL_CHANNEL_MAP_CMD_BUFFER_EX
|
||||||
|
tmp == 0xC0000026 || // NVHOST_IOCTL_CHANNEL_UNMAP_CMD_BUFFER_EX
|
||||||
request == 0xC018481B || // NVGPU_IOCTL_CHANNEL_KICKOFF_PB
|
request == 0xC018481B || // NVGPU_IOCTL_CHANNEL_KICKOFF_PB
|
||||||
request == 0xC004001C || // NVHOST_IOCTL_CTRL_EVENT_SIGNAL
|
request == 0xC004001C || // NVHOST_IOCTL_CTRL_EVENT_SIGNAL
|
||||||
request == 0xC010001E // NVHOST_IOCTL_CTRL_EVENT_WAIT_ASYNC
|
request == 0xC010001E || // NVHOST_IOCTL_CTRL_EVENT_WAIT_ASYNC
|
||||||
|
request == 0xC4C80203 || // NVDISP_FLIP
|
||||||
|
request == 0x400C060E // NVSCHED_CTRL_PUT_CONDUCTOR_FLIP_FENCE
|
||||||
)
|
)
|
||||||
return &g_nvSrvClone;
|
return &g_nvSrvClone;
|
||||||
return &g_nvSrv;
|
return &g_nvSrv;
|
||||||
@ -163,6 +172,9 @@ Result nvIoctl(u32 fd, u32 request, void* argp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result nvIoctl2(u32 fd, u32 request, void* argp, const void* inbuf, size_t inbuf_size) {
|
Result nvIoctl2(u32 fd, u32 request, void* argp, const void* inbuf, size_t inbuf_size) {
|
||||||
|
if (hosversionBefore(3,0,0))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||||
|
|
||||||
size_t bufsize = _NV_IOC_SIZE(request);
|
size_t bufsize = _NV_IOC_SIZE(request);
|
||||||
u32 dir = _NV_IOC_DIR(request);
|
u32 dir = _NV_IOC_DIR(request);
|
||||||
|
|
||||||
@ -204,6 +216,51 @@ Result nvIoctl2(u32 fd, u32 request, void* argp, const void* inbuf, size_t inbuf
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result nvIoctl3(u32 fd, u32 request, void* argp, void* outbuf, size_t outbuf_size) {
|
||||||
|
if (hosversionBefore(3,0,0))
|
||||||
|
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||||
|
|
||||||
|
size_t bufsize = _NV_IOC_SIZE(request);
|
||||||
|
u32 dir = _NV_IOC_DIR(request);
|
||||||
|
|
||||||
|
void *buf_send = NULL, *buf_recv = NULL;
|
||||||
|
size_t buf_send_size = 0, buf_recv_size = 0;
|
||||||
|
|
||||||
|
if (dir & _NV_IOC_WRITE) {
|
||||||
|
buf_send = argp;
|
||||||
|
buf_send_size = bufsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir & _NV_IOC_READ) {
|
||||||
|
buf_recv = argp;
|
||||||
|
buf_recv_size = bufsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct {
|
||||||
|
u32 fd;
|
||||||
|
u32 request;
|
||||||
|
} in = { fd, request };
|
||||||
|
|
||||||
|
u32 error = 0;
|
||||||
|
Result rc = serviceDispatchInOut(_nvGetSessionForRequest(request), 12, in, error,
|
||||||
|
.buffer_attrs = {
|
||||||
|
SfBufferAttr_HipcAutoSelect | SfBufferAttr_In,
|
||||||
|
SfBufferAttr_HipcAutoSelect | SfBufferAttr_Out,
|
||||||
|
SfBufferAttr_HipcAutoSelect | SfBufferAttr_Out,
|
||||||
|
},
|
||||||
|
.buffers = {
|
||||||
|
{ buf_send, buf_send_size },
|
||||||
|
{ buf_recv, buf_recv_size },
|
||||||
|
{ outbuf, outbuf_size },
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc))
|
||||||
|
rc = nvConvertError(error);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
Result nvClose(u32 fd) {
|
Result nvClose(u32 fd) {
|
||||||
u32 error = 0;
|
u32 error = 0;
|
||||||
Result rc = serviceDispatchInOut(&g_nvSrv, 2, fd, error);
|
Result rc = serviceDispatchInOut(&g_nvSrv, 2, fd, error);
|
||||||
|
Loading…
Reference in New Issue
Block a user