mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-27 15:55:29 +03:00
Add support for Ioctl2/3 and improve debug logging
This commit is contained in:
parent
7468003381
commit
b9098ac14a
@ -6,7 +6,13 @@
|
||||
#include "driver.h"
|
||||
#include "devices/nvdevice.h"
|
||||
|
||||
#define NVRESULT(x) [&response](NvResult err) { response.Push<NvResult>(err); return Result{}; }(x)
|
||||
#define NVRESULT(x) [&response, this](NvResult err) { \
|
||||
if (err != NvResult::Success) \
|
||||
state.logger->Debug("IOCTL Failed: {}", err); \
|
||||
\
|
||||
response.Push<NvResult>(err); \
|
||||
return Result{}; \
|
||||
} (x)
|
||||
|
||||
namespace skyline::service::nvdrv {
|
||||
INvDrvServices::INvDrvServices(const DeviceState &state, ServiceManager &manager, Driver &driver, const SessionPermissions &perms) : BaseService(state, manager), driver(driver), ctx(SessionContext{.perms = perms}) {}
|
||||
@ -29,29 +35,34 @@ namespace skyline::service::nvdrv {
|
||||
return NVRESULT(NvResult::Success);
|
||||
}
|
||||
|
||||
Result INvDrvServices::Ioctl(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||
auto fd{request.Pop<FileDescriptor>()};
|
||||
auto ioctl{request.Pop<IoctlDescriptor>()};
|
||||
|
||||
auto inBuf{request.inputBuf.at(0)};
|
||||
auto outBuf{request.outputBuf.at(0)};
|
||||
|
||||
static NvResultValue<span<u8>> GetMainIoctlBuffer(IoctlDescriptor ioctl, span<u8> inBuf, span<u8> outBuf) {
|
||||
if (ioctl.in && inBuf.size() < ioctl.size)
|
||||
return NVRESULT(NvResult::InvalidSize);
|
||||
return NvResult::InvalidSize;
|
||||
|
||||
if (ioctl.out && outBuf.size() < ioctl.size)
|
||||
return NVRESULT(NvResult::InvalidSize);
|
||||
return NvResult::InvalidSize;
|
||||
|
||||
if (ioctl.in && ioctl.out) {
|
||||
if (outBuf.size() < inBuf.size())
|
||||
return NVRESULT(NvResult::InvalidSize);
|
||||
return NvResult::InvalidSize;
|
||||
|
||||
// Copy in buf to out buf for inout ioctls to avoid needing to pass around two buffers everywhere
|
||||
if (outBuf.data() != inBuf.data())
|
||||
outBuf.copy_from(inBuf, ioctl.size);
|
||||
}
|
||||
|
||||
return NVRESULT(driver.Ioctl(fd, ioctl, ioctl.out ? outBuf : inBuf));
|
||||
return ioctl.out ? outBuf : inBuf;
|
||||
}
|
||||
|
||||
Result INvDrvServices::Ioctl(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||
auto fd{request.Pop<FileDescriptor>()};
|
||||
auto ioctl{request.Pop<IoctlDescriptor>()};
|
||||
|
||||
auto buf{GetMainIoctlBuffer(ioctl, request.inputBuf.at(0), request.outputBuf.at(0))};
|
||||
if (!buf)
|
||||
return NVRESULT(buf);
|
||||
else
|
||||
return NVRESULT(driver.Ioctl(fd, ioctl, *buf));
|
||||
}
|
||||
|
||||
Result INvDrvServices::Close(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||
@ -85,6 +96,34 @@ namespace skyline::service::nvdrv {
|
||||
}
|
||||
}
|
||||
|
||||
Result INvDrvServices::Ioctl2(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||
auto fd{request.Pop<FileDescriptor>()};
|
||||
auto ioctl{request.Pop<IoctlDescriptor>()};
|
||||
|
||||
// The inline buffer is technically not required
|
||||
auto inlineBuf{request.inputBuf.size() > 1 ? request.inputBuf.at(1) : span<u8>{}};
|
||||
|
||||
auto buf{GetMainIoctlBuffer(ioctl, request.inputBuf.at(0), request.outputBuf.at(0))};
|
||||
if (!buf)
|
||||
return NVRESULT(buf);
|
||||
else
|
||||
return NVRESULT(driver.Ioctl2(fd, ioctl, *buf, inlineBuf));
|
||||
}
|
||||
|
||||
Result INvDrvServices::Ioctl3(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||
auto fd{request.Pop<FileDescriptor>()};
|
||||
auto ioctl{request.Pop<IoctlDescriptor>()};
|
||||
|
||||
// The inline buffer is technically not required
|
||||
auto inlineBuf{request.outputBuf.size() > 1 ? request.outputBuf.at(1) : span<u8>{}};
|
||||
|
||||
auto buf{GetMainIoctlBuffer(ioctl, request.inputBuf.at(0), request.outputBuf.at(0))};
|
||||
if (!buf)
|
||||
return NVRESULT(buf);
|
||||
else
|
||||
return NVRESULT(driver.Ioctl3(fd, ioctl, *buf, inlineBuf));
|
||||
}
|
||||
|
||||
Result INvDrvServices::SetAruid(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
|
||||
return NVRESULT(NvResult::Success);
|
||||
}
|
||||
|
@ -63,13 +63,13 @@ namespace skyline::service::nvdrv {
|
||||
* @brief Perform an IOCTL on the specified FD with an extra input buffer
|
||||
* @url https://switchbrew.org/wiki/NV_services#Ioctl2
|
||||
*/
|
||||
// Result Ioctl2(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
||||
Result Ioctl2(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
||||
|
||||
/**
|
||||
* @brief Perform an IOCTL on the specified FD with an extra output buffer
|
||||
* @url https://switchbrew.org/wiki/NV_services#Ioctl3
|
||||
*/
|
||||
// Result Ioctl3(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
||||
Result Ioctl3(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
||||
|
||||
/**
|
||||
* @brief Enables the graphics firmware memory margin
|
||||
@ -84,7 +84,8 @@ namespace skyline::service::nvdrv {
|
||||
SFUNC(0x3, INvDrvServices, Initialize),
|
||||
SFUNC(0x4, INvDrvServices, QueryEvent),
|
||||
SFUNC(0x8, INvDrvServices, SetAruid),
|
||||
|
||||
SFUNC(0xB, INvDrvServices, Ioctl2),
|
||||
SFUNC(0xC, INvDrvServices, Ioctl3),
|
||||
SFUNC(0xD, INvDrvServices, SetGraphicsFirmwareMemoryMarginEnabled)
|
||||
)
|
||||
};
|
||||
|
@ -3,6 +3,16 @@
|
||||
|
||||
#include "deserialisation.h"
|
||||
|
||||
#define INLINE_IOCTL_HANDLER_FUNC(type, name, cases) \
|
||||
PosixResult name::type(IoctlDescriptor cmd, span<u8> buffer, span<u8> inlineBuffer) { \
|
||||
using className = name; \
|
||||
switch (cmd.raw) { \
|
||||
cases; \
|
||||
default: \
|
||||
return PosixResult::InappropriateIoctlForDevice; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define VARIABLE_IOCTL_HANDLER_FUNC(name, cases, variableCases) \
|
||||
PosixResult name::Ioctl(IoctlDescriptor cmd, span<u8> buffer) { \
|
||||
using className = name; \
|
||||
@ -28,11 +38,11 @@
|
||||
} \
|
||||
}
|
||||
|
||||
#define IOCTL_CASE_ARGS_I(out, in, size, magic, function, name, ...) \
|
||||
case MetaIoctlDescriptor<out, in, size, magic, function>::Raw(): { \
|
||||
using IoctlType = MetaIoctlDescriptor< out, in, size, magic, function>; \
|
||||
auto args = DecodeArguments<IoctlType, __VA_ARGS__>(buffer.subspan<0, size>()); \
|
||||
return std::apply(&className::name, std::tuple_cat(std::make_tuple(this), args)); \
|
||||
#define IOCTL_CASE_ARGS_I(out, in, size, magic, function, name, ...) \
|
||||
case MetaIoctlDescriptor<out, in, size, magic, function>::Raw(): { \
|
||||
using IoctlType = MetaIoctlDescriptor< out, in, size, magic, function>; \
|
||||
auto args = DecodeArguments<IoctlType, __VA_ARGS__>(buffer.subspan<0, size>()); \
|
||||
return std::apply(&className::name, std::tuple_cat(std::make_tuple(this), args)); \
|
||||
}
|
||||
|
||||
#define IOCTL_CASE_NOARGS_I(out, in, size, magic, function, name) \
|
||||
@ -47,6 +57,7 @@
|
||||
#define IOCTL_CASE_NOARGS(...) IOCTL_CASE_NOARGS_I(__VA_ARGS__)
|
||||
#define IOCTL_CASE_RESULT(...) IOCTL_CASE_RESULT_I(__VA_ARGS__)
|
||||
|
||||
|
||||
#define VARIABLE_IOCTL_CASE_ARGS_I(out, in, magic, function, name, ...) \
|
||||
case MetaVariableIoctlDescriptor<out, in, magic, function>::Raw(): { \
|
||||
using IoctlType = MetaVariableIoctlDescriptor<out, in, magic, function>; \
|
||||
@ -56,6 +67,16 @@
|
||||
|
||||
#define VARIABLE_IOCTL_CASE_ARGS(...) VARIABLE_IOCTL_CASE_ARGS_I(__VA_ARGS__)
|
||||
|
||||
|
||||
#define INLINE_IOCTL_CASE_ARGS_I(out, in, size, magic, function, name, ...) \
|
||||
case MetaIoctlDescriptor<out, in, size, magic, function>::Raw(): { \
|
||||
using IoctlType = MetaIoctlDescriptor< out, in, size, magic, function>; \
|
||||
auto args = DecodeArguments<IoctlType, __VA_ARGS__>(buffer.subspan<0, size>()); \
|
||||
return std::apply(&className::name, std::tuple_cat(std::make_tuple(this, inlineBuffer), args)); \
|
||||
}
|
||||
|
||||
#define INLINE_IOCTL_CASE_ARGS(...) INLINE_IOCTL_CASE_ARGS_I(__VA_ARGS__)
|
||||
|
||||
#define IN false, true
|
||||
#define OUT true, false
|
||||
#define INOUT true, true
|
||||
|
@ -3,14 +3,21 @@
|
||||
|
||||
#undef IOCTL_HANDLER_FUNC
|
||||
#undef VARIABLE_IOCTL_HANDLER_FUNC
|
||||
#undef INLINE_IOCTL_HANDLER_FUNC
|
||||
|
||||
#undef IOCTL_CASE_ARGS_I
|
||||
#undef IOCTL_CASE_NOARGS_I
|
||||
#undef IOCTL_CASE_RESULT_I
|
||||
#undef IOCTL_CASE_ARGS
|
||||
#undef IOCTL_CASE_NOARGS
|
||||
#undef IOCTL_CASE_RESULT
|
||||
|
||||
#undef VARIABLE_IOCTL_CASE_ARGS_I
|
||||
#undef VARIABLE_IOCTL_CASE_ARGS
|
||||
|
||||
#undef INLINE_IOCTL_CASE_ARGS_I
|
||||
#undef INLINE_IOCTL_CASE_ARGS
|
||||
|
||||
#undef IN
|
||||
#undef OUT
|
||||
#undef INOUT
|
||||
|
@ -40,9 +40,13 @@ namespace skyline::service::nvdrv::device {
|
||||
|
||||
virtual PosixResult Ioctl(IoctlDescriptor cmd, span<u8> buffer) = 0;
|
||||
|
||||
virtual PosixResult Ioctl2(IoctlDescriptor cmd, span<u8> buffer, span<u8> inlineOutput) { return PosixResult::NotSupported; }
|
||||
virtual PosixResult Ioctl2(IoctlDescriptor cmd, span<u8> buffer, span<u8> inlineOutput) {
|
||||
return PosixResult::InappropriateIoctlForDevice;
|
||||
}
|
||||
|
||||
virtual PosixResult Ioctl3(IoctlDescriptor cmd, span<u8> buffer, span<u8> inlineInput) { return PosixResult::NotSupported; }
|
||||
virtual PosixResult Ioctl3(IoctlDescriptor cmd, span<u8> buffer, span<u8> inlineInput) {
|
||||
return PosixResult::InappropriateIoctlForDevice;
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<kernel::type::KEvent> QueryEvent(u32 eventId) {
|
||||
return nullptr;
|
||||
|
@ -54,6 +54,8 @@ namespace skyline::service::nvdrv::device::nvhost {
|
||||
}
|
||||
|
||||
PosixResult AsGpu::MapBufferEx(In<MappingFlags> flags, In<u32> kind, In<core::NvMap::Handle::Id> handle, InOut<u32> pageSize, In<u64> bufferOffset, In<u64> mappingSize, InOut<u64> offset) {
|
||||
state.logger->Debug("flags: ( fixed: {}, remap: {} ), kind: {}, handle: {}, pageSize: 0x{:X}, bufferOffset: 0x{:X}, mappingSize: 0x{:X}, offset: 0x{:X}", flags.fixed, flags.remap, kind, handle, pageSize, bufferOffset, mappingSize, offset);
|
||||
|
||||
if (flags.remap) {
|
||||
auto region{regionMap.lower_bound(offset)};
|
||||
if (region == regionMap.end()) {
|
||||
@ -95,8 +97,11 @@ namespace skyline::service::nvdrv::device::nvhost {
|
||||
if (offset == 0) {
|
||||
state.logger->Warn("Failed to map GPU address space region!");
|
||||
return PosixResult::InvalidArgument;
|
||||
|
||||
}
|
||||
|
||||
state.logger->Debug("Mapped to 0x{:X}", offset);
|
||||
|
||||
regionMap[offset] = {cpuPtr, size, flags.fixed};
|
||||
|
||||
return PosixResult::Success;
|
||||
@ -107,6 +112,10 @@ namespace skyline::service::nvdrv::device::nvhost {
|
||||
return PosixResult::Success;
|
||||
}
|
||||
|
||||
PosixResult AsGpu::GetVaRegions3(span<u8> inlineBufer, In<u64> bufAddr, InOut<u32> bufSize, Out<std::array<VaRegion, 2>> vaRegions) {
|
||||
return GetVaRegions(bufAddr, bufSize, vaRegions);
|
||||
}
|
||||
|
||||
PosixResult AsGpu::AllocAsEx(In<u32> bigPageSize, In<FileDescriptor> asFd, In<u32> flags, In<u64> vaRangeStart, In<u64> vaRangeEnd, In<u64> vaRangeSplit) {
|
||||
// TODO: create the allocator here
|
||||
return PosixResult::Success;
|
||||
@ -152,5 +161,10 @@ namespace skyline::service::nvdrv::device::nvhost {
|
||||
VARIABLE_IOCTL_CASE_ARGS(INOUT, MAGIC(AsGpuMagic), FUNC(0x14),
|
||||
Remap, ARGS(AutoSizeSpan<RemapEntry>))
|
||||
}))
|
||||
|
||||
INLINE_IOCTL_HANDLER_FUNC(Ioctl3, AsGpu, ({
|
||||
INLINE_IOCTL_CASE_ARGS(INOUT, SIZE(0x40), MAGIC(AsGpuMagic), FUNC(0x8),
|
||||
GetVaRegions3, ARGS(In<u64>, InOut<u32>, Pad<u32>, Out<std::array<VaRegion, 2>>))
|
||||
}))
|
||||
#include <services/nvdrv/devices/deserialisation/macro_undef.h>
|
||||
}
|
||||
|
@ -85,6 +85,11 @@ namespace skyline::service::nvdrv::device::nvhost {
|
||||
*/
|
||||
PosixResult GetVaRegions(In<u64> bufAddr, InOut<u32> bufSize, Out<std::array<VaRegion, 2>> vaRegions);
|
||||
|
||||
/**
|
||||
* @brief Ioctl3 variant of GetVaRegions
|
||||
*/
|
||||
PosixResult GetVaRegions3(span<u8> inlineBuffer, In<u64> bufAddr, InOut<u32> bufSize, Out<std::array<VaRegion, 2>> vaRegions);
|
||||
|
||||
/**
|
||||
* @brief Allocates this address space with the given parameters
|
||||
* @url https://switchbrew.org/wiki/NV_services#NVGPU_AS_IOCTL_ALLOC_AS_EX
|
||||
@ -98,5 +103,7 @@ namespace skyline::service::nvdrv::device::nvhost {
|
||||
PosixResult Remap(span<RemapEntry> entries);
|
||||
|
||||
PosixResult Ioctl(IoctlDescriptor cmd, span<u8> buffer) override;
|
||||
|
||||
PosixResult Ioctl3(IoctlDescriptor cmd, span<u8> buffer, span<u8> inlineBuffer) override;
|
||||
};
|
||||
}
|
||||
|
@ -26,9 +26,22 @@ namespace skyline::service::nvdrv::device::nvhost {
|
||||
return PosixResult::Success;
|
||||
}
|
||||
|
||||
PosixResult CtrlGpu::GetTpcMasks(In<u32> bufSize, Out<u64> maskBuf) {
|
||||
// TODO
|
||||
maskBuf = 0x3;
|
||||
PosixResult CtrlGpu::GetCharacteristics3(span<u8> inlineBuffer, InOut<u64> size, In<u64> userAddress, Out<GpuCharacteristics> characteristics) {
|
||||
inlineBuffer.as<GpuCharacteristics>() = {};
|
||||
return GetCharacteristics(size, userAddress, characteristics);
|
||||
}
|
||||
|
||||
PosixResult CtrlGpu::GetTpcMasks(In<u32> bufSize, Out<u32> mask) {
|
||||
if (bufSize)
|
||||
mask = 0x3;
|
||||
|
||||
return PosixResult::Success;
|
||||
}
|
||||
|
||||
PosixResult CtrlGpu::GetTpcMasks3(span<u8> inlineBuffer, In<u32> bufSize, Out<u32> mask) {
|
||||
if (bufSize)
|
||||
mask = inlineBuffer.as<u32>() = 0x3;
|
||||
|
||||
return PosixResult::Success;
|
||||
}
|
||||
|
||||
@ -60,7 +73,7 @@ namespace skyline::service::nvdrv::device::nvhost {
|
||||
IOCTL_CASE_ARGS(INOUT, SIZE(0xB0), MAGIC(CtrlGpuMagic), FUNC(0x5),
|
||||
GetCharacteristics, ARGS(InOut<u64>, In<u64>, Out<GpuCharacteristics>))
|
||||
IOCTL_CASE_ARGS(INOUT, SIZE(0x18), MAGIC(CtrlGpuMagic), FUNC(0x6),
|
||||
GetTpcMasks, ARGS(In<u32>, Pad<u32, 3>, Out<u64>))
|
||||
GetTpcMasks, ARGS(In<u32>, Pad<u32, 3>, Out<u32>))
|
||||
IOCTL_CASE_ARGS(OUT, SIZE(0x8), MAGIC(CtrlGpuMagic), FUNC(0x14),
|
||||
GetActiveSlotMask, ARGS(Out<u32>, Out<u32>))
|
||||
}))
|
||||
|
@ -93,11 +93,21 @@ namespace skyline::service::nvdrv::device::nvhost {
|
||||
*/
|
||||
PosixResult GetCharacteristics(InOut<u64> size, In<u64> userAddress, Out<GpuCharacteristics> characteristics);
|
||||
|
||||
/**
|
||||
* @brief Ioctl3 variant of GetTpcMasks
|
||||
*/
|
||||
PosixResult GetCharacteristics3(span<u8> inlineBuffer, InOut<u64> size, In<u64> userAddress, Out<GpuCharacteristics> characteristics);
|
||||
|
||||
/**
|
||||
* @brief Returns the TPC mask value for each GPC
|
||||
* @url https://switchbrew.org/wiki/NV_services#NVGPU_GPU_IOCTL_GET_TPC_MASKS
|
||||
*/
|
||||
PosixResult GetTpcMasks(In<u32> bufSize, Out<u64> maskBuf);
|
||||
PosixResult GetTpcMasks(In<u32> bufSize, Out<u32> mask);
|
||||
|
||||
/**
|
||||
* @brief Ioctl3 variant of GetTpcMasks
|
||||
*/
|
||||
PosixResult GetTpcMasks3(span<u8> inlineBuffer, In<u32> bufSize, Out<u32> mask);
|
||||
|
||||
/**
|
||||
* @brief Returns the mask value for a ZBC slot
|
||||
|
@ -23,7 +23,7 @@ namespace skyline::service::nvdrv::device::nvhost {
|
||||
}
|
||||
|
||||
PosixResult GpuChannel::SubmitGpfifo(In<u64> userAddress, In<u32> numEntries, InOut<SubmitGpfifoFlags> flags, InOut<Fence> fence, span<soc::gm20b::GpEntry> gpEntries) {
|
||||
if (numEntries != gpEntries.size())
|
||||
if (numEntries > gpEntries.size())
|
||||
throw exception("GpEntry size mismatch!");
|
||||
|
||||
if (flags.fenceWait) {
|
||||
@ -34,7 +34,7 @@ namespace skyline::service::nvdrv::device::nvhost {
|
||||
throw exception("Waiting on a fence through SubmitGpfifo is unimplemented");
|
||||
}
|
||||
|
||||
state.soc->gm20b.gpfifo.Push(gpEntries);
|
||||
state.soc->gm20b.gpfifo.Push(gpEntries.subspan(0, numEntries));
|
||||
|
||||
fence.id = channelSyncpoint;
|
||||
|
||||
@ -49,6 +49,10 @@ namespace skyline::service::nvdrv::device::nvhost {
|
||||
return PosixResult::Success;
|
||||
}
|
||||
|
||||
PosixResult GpuChannel::SubmitGpfifo2(span<u8> inlineBuffer, In<u64> userAddress, In<u32> numEntries, InOut<GpuChannel::SubmitGpfifoFlags> flags, InOut<Fence> fence) {
|
||||
return SubmitGpfifo(userAddress, numEntries, flags, fence, inlineBuffer.cast<soc::gm20b::GpEntry>());
|
||||
}
|
||||
|
||||
PosixResult GpuChannel::AllocObjCtx(In<u32> classId, In<u32> flags, Out<u64> objId) {
|
||||
return PosixResult::Success;
|
||||
}
|
||||
@ -129,5 +133,10 @@ namespace skyline::service::nvdrv::device::nvhost {
|
||||
VARIABLE_IOCTL_CASE_ARGS(INOUT, MAGIC(GpuChannelMagic), FUNC(0x8),
|
||||
SubmitGpfifo, ARGS(In<u64>, In<u32>, InOut<SubmitGpfifoFlags>, InOut<Fence>, AutoSizeSpan<soc::gm20b::GpEntry>))
|
||||
}))
|
||||
|
||||
INLINE_IOCTL_HANDLER_FUNC(Ioctl2, GpuChannel, ({
|
||||
INLINE_IOCTL_CASE_ARGS(INOUT, SIZE(0x18), MAGIC(GpuChannelMagic), FUNC(0x1B),
|
||||
SubmitGpfifo2, ARGS(In<u64>, In<u32>, InOut<SubmitGpfifoFlags>, InOut<Fence>))
|
||||
}))
|
||||
#include <services/nvdrv/devices/deserialisation/macro_undef.h>
|
||||
}
|
||||
|
@ -57,6 +57,11 @@ namespace skyline::service::nvdrv::device::nvhost {
|
||||
*/
|
||||
PosixResult SubmitGpfifo(In<u64> userAddress, In<u32> numEntries, InOut<SubmitGpfifoFlags> flags, InOut<Fence> fence, span<soc::gm20b::GpEntry> gpEntries);
|
||||
|
||||
/**
|
||||
* @brief Ioctl2 variant of SubmitGpfifo
|
||||
*/
|
||||
PosixResult SubmitGpfifo2(span<u8> inlineBuffer, In<u64> userAddress, In<u32> numEntries, InOut<SubmitGpfifoFlags> flags, InOut<Fence> fence);
|
||||
|
||||
/**
|
||||
* @brief Allocates a graphic context object
|
||||
* @url https://switchbrew.org/wiki/NV_services#NVGPU_IOCTL_CHANNEL_ALLOC_OBJ_CTX
|
||||
@ -108,5 +113,7 @@ namespace skyline::service::nvdrv::device::nvhost {
|
||||
std::shared_ptr<type::KEvent> QueryEvent(u32 eventId) override;
|
||||
|
||||
PosixResult Ioctl(IoctlDescriptor cmd, span<u8> buffer) override;
|
||||
|
||||
PosixResult Ioctl2(IoctlDescriptor cmd, span<u8> buffer, span<u8> inlineBuffer) override;
|
||||
};
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ namespace skyline::service::nvdrv::device {
|
||||
if (h) {
|
||||
(*h)->origSize = size; // Orig size is the unaligned size
|
||||
handle = (*h)->id;
|
||||
state.logger->Debug("handle: {}, size: 0x{:X}", (*h)->id, size);
|
||||
}
|
||||
|
||||
return h;
|
||||
@ -47,6 +48,8 @@ namespace skyline::service::nvdrv::device {
|
||||
if (!h) [[unlikely]]
|
||||
return PosixResult::InvalidArgument;
|
||||
|
||||
state.logger->Debug("handle: {}, flags: ( mapUncached: {}, keepUncachedAfterFree: {} ), align: 0x{:X}, kind: {}, address: 0x{:X}", handle, flags.mapUncached, flags.keepUncachedAfterFree, align, kind, address);
|
||||
|
||||
return h->Alloc(flags, align, kind, address);
|
||||
}
|
||||
|
||||
|
@ -95,11 +95,34 @@ namespace skyline::service::nvdrv {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NvResult Driver::Ioctl(u32 fd, IoctlDescriptor cmd, span<u8> buffer) {
|
||||
state.logger->Debug("fd: {}, cmd: 0x{:X}, device: {}", fd, cmd.raw, devices.at(fd)->GetName());
|
||||
|
||||
try {
|
||||
return ConvertResult(devices.at(fd)->Ioctl(cmd, buffer));
|
||||
} catch (const std::out_of_range &) {
|
||||
throw exception("GetDevice was called with invalid file descriptor: 0x{:X}", fd);
|
||||
throw exception("Ioctl was called with invalid file descriptor: 0x{:X}", fd);
|
||||
}
|
||||
}
|
||||
|
||||
NvResult Driver::Ioctl2(u32 fd, IoctlDescriptor cmd, span<u8> buffer, span<u8> inlineBuffer) {
|
||||
state.logger->Debug("fd: {}, cmd: 0x{:X}, device: {}", fd, cmd.raw, devices.at(fd)->GetName());
|
||||
|
||||
try {
|
||||
return ConvertResult(devices.at(fd)->Ioctl2(cmd, buffer, inlineBuffer));
|
||||
} catch (const std::out_of_range &) {
|
||||
throw exception("Ioctl2 was called with invalid file descriptor: 0x{:X}", fd);
|
||||
}
|
||||
}
|
||||
|
||||
NvResult Driver::Ioctl3(u32 fd, IoctlDescriptor cmd, span<u8> buffer, span<u8> inlineBuffer) {
|
||||
state.logger->Debug("fd: {}, cmd: 0x{:X}, device: {}", fd, cmd.raw, devices.at(fd)->GetName());
|
||||
|
||||
try {
|
||||
return ConvertResult(devices.at(fd)->Ioctl3(cmd, buffer, inlineBuffer));
|
||||
} catch (const std::out_of_range &) {
|
||||
throw exception("Ioctl3 was called with invalid file descriptor: 0x{:X}", fd);
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,6 +135,8 @@ namespace skyline::service::nvdrv {
|
||||
}
|
||||
|
||||
std::shared_ptr<kernel::type::KEvent> Driver::QueryEvent(u32 fd, u32 eventId) {
|
||||
state.logger->Debug("fd: {}, eventId: 0x{:X}, device: {}", fd, eventId, devices.at(fd)->GetName());
|
||||
|
||||
try {
|
||||
return devices.at(fd)->QueryEvent(eventId);
|
||||
} catch (const std::exception &) {
|
||||
|
@ -32,6 +32,16 @@ namespace skyline::service::nvdrv {
|
||||
*/
|
||||
NvResult Ioctl(u32 fd, IoctlDescriptor cmd, span<u8> buffer);
|
||||
|
||||
/**
|
||||
* @brief Calls an IOCTL on the device specified by `fd` using the given inline input buffer
|
||||
*/
|
||||
NvResult Ioctl2(u32 fd, IoctlDescriptor cmd, span<u8> buffer, span<u8> inlineBuffer);
|
||||
|
||||
/**
|
||||
* @brief Calls an IOCTL on the device specified by `fd` using the given inline output buffer
|
||||
*/
|
||||
NvResult Ioctl3(u32 fd, IoctlDescriptor cmd, span<u8> buffer, span<u8> inlineBuffer);
|
||||
|
||||
/**
|
||||
* @brief Queries a KEvent for the given `eventId` for the device specified by `fd`
|
||||
*/
|
||||
|
@ -90,4 +90,7 @@ namespace skyline::service::nvdrv {
|
||||
AccessDenied = 0x30010,
|
||||
IoctlFailed = 0x3000F
|
||||
};
|
||||
|
||||
template<typename ValueType>
|
||||
using NvResultValue = ResultValue<ValueType, NvResult>;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user