Use semantic wrapping for nvdrv where appropriate

This commit is contained in:
Billy Laws 2021-10-24 16:36:29 +01:00 committed by PixelyIon
parent 830a800d9e
commit 1e7347bf72
10 changed files with 71 additions and 35 deletions

View File

@ -16,7 +16,10 @@
} (x) } (x)
namespace skyline::service::nvdrv { 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}) {} INvDrvServices::INvDrvServices(const DeviceState &state, ServiceManager &manager, Driver &driver, const SessionPermissions &perms)
: BaseService(state, manager),
driver(driver),
ctx(SessionContext{.perms = perms}) {}
Result INvDrvServices::Open(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { Result INvDrvServices::Open(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
constexpr FileDescriptor SessionFdLimit{std::numeric_limits<u64>::digits * 2}; //!< Nvdrv uses two 64 bit variables to store a bitset constexpr FileDescriptor SessionFdLimit{std::numeric_limits<u64>::digits * 2}; //!< Nvdrv uses two 64 bit variables to store a bitset
@ -59,7 +62,9 @@ namespace skyline::service::nvdrv {
auto fd{request.Pop<FileDescriptor>()}; auto fd{request.Pop<FileDescriptor>()};
auto ioctl{request.Pop<IoctlDescriptor>()}; auto ioctl{request.Pop<IoctlDescriptor>()};
auto buf{GetMainIoctlBuffer(ioctl, !request.inputBuf.empty() ? request.inputBuf.at(0) : span<u8>{}, !request.outputBuf.empty() ? request.outputBuf.at(0) : span<u8>{})}; auto buf{GetMainIoctlBuffer(ioctl,
!request.inputBuf.empty() ? request.inputBuf.at(0) : span<u8>{},
!request.outputBuf.empty() ? request.outputBuf.at(0) : span<u8>{})};
if (!buf) if (!buf)
return NVRESULT(buf); return NVRESULT(buf);
else else
@ -104,7 +109,9 @@ namespace skyline::service::nvdrv {
// Inline buffer is optional // Inline buffer is optional
auto inlineBuf{request.inputBuf.size() > 1 ? request.inputBuf.at(1) : span<u8>{}}; auto inlineBuf{request.inputBuf.size() > 1 ? request.inputBuf.at(1) : span<u8>{}};
auto buf{GetMainIoctlBuffer(ioctl, !request.inputBuf.empty() ? request.inputBuf.at(0) : span<u8>{}, !request.outputBuf.empty() ? request.outputBuf.at(0) : span<u8>{})}; auto buf{GetMainIoctlBuffer(ioctl,
!request.inputBuf.empty() ? request.inputBuf.at(0) : span<u8>{},
!request.outputBuf.empty() ? request.outputBuf.at(0) : span<u8>{})};
if (!buf) if (!buf)
return NVRESULT(buf); return NVRESULT(buf);
else else
@ -118,7 +125,9 @@ namespace skyline::service::nvdrv {
// Inline buffer is optional // Inline buffer is optional
auto inlineBuf{request.outputBuf.size() > 1 ? request.outputBuf.at(1) : span<u8>{}}; auto inlineBuf{request.outputBuf.size() > 1 ? request.outputBuf.at(1) : span<u8>{}};
auto buf{GetMainIoctlBuffer(ioctl, !request.inputBuf.empty() ? request.inputBuf.at(0) : span<u8>{}, !request.outputBuf.empty() ? request.outputBuf.at(0) : span<u8>{})}; auto buf{GetMainIoctlBuffer(ioctl,
!request.inputBuf.empty() ? request.inputBuf.at(0) : span<u8>{},
!request.outputBuf.empty() ? request.outputBuf.at(0) : span<u8>{})};
if (!buf) if (!buf)
return NVRESULT(buf); return NVRESULT(buf);
else else

View File

@ -5,11 +5,11 @@
#include "nvdevice.h" #include "nvdevice.h"
namespace skyline::service::nvdrv::device { namespace skyline::service::nvdrv::device {
NvDevice::NvDevice(const DeviceState &state, Driver &driver, Core &core, const SessionContext &ctx) : NvDevice::NvDevice(const DeviceState &state, Driver &driver, Core &core, const SessionContext &ctx)
state(state), : state(state),
driver(driver), driver(driver),
core(core), core(core),
ctx(ctx) {} ctx(ctx) {}
const std::string &NvDevice::GetName() { const std::string &NvDevice::GetName() {
if (name.empty()) { if (name.empty()) {

View File

@ -170,7 +170,9 @@ namespace skyline::service::nvdrv::device::nvhost {
return PosixResult::Success; return PosixResult::Success;
} }
PosixResult AsGpu::MapBufferEx(In<MappingFlags> flags, In<u32> kind, In<core::NvMap::Handle::Id> handle, In<u64> bufferOffset, In<u64> mappingSize, InOut<u64> offset) { PosixResult AsGpu::MapBufferEx(In<MappingFlags> flags, In<u32> kind,
In<core::NvMap::Handle::Id> handle, In<u64> bufferOffset,
In<u64> mappingSize, InOut<u64> offset) {
state.logger->Debug("flags: ( fixed: {}, remap: {} ), kind: {}, handle: {}, bufferOffset: 0x{:X}, mappingSize: 0x{:X}, offset: 0x{:X}", state.logger->Debug("flags: ( fixed: {}, remap: {} ), kind: {}, handle: {}, bufferOffset: 0x{:X}, mappingSize: 0x{:X}, offset: 0x{:X}",
flags.fixed, flags.remap, kind, handle, bufferOffset, mappingSize, offset); flags.fixed, flags.remap, kind, handle, bufferOffset, mappingSize, offset);
@ -271,7 +273,10 @@ namespace skyline::service::nvdrv::device::nvhost {
return GetVaRegions(bufAddr, bufSize, vaRegions); return GetVaRegions(bufAddr, bufSize, vaRegions);
} }
PosixResult AsGpu::AllocAsEx(In<u32> flags, In<FileDescriptor> asFd, In<u32> bigPageSize, In<u64> vaRangeStart, In<u64> vaRangeEnd, In<u64> vaRangeSplit) { PosixResult AsGpu::AllocAsEx(In<u32> flags,
In<FileDescriptor> asFd,
In<u32> bigPageSize,
In<u64> vaRangeStart, In<u64> vaRangeEnd, In<u64> vaRangeSplit) {
std::scoped_lock lock(mutex); std::scoped_lock lock(mutex);
if (vm.initialised) if (vm.initialised)

View File

@ -131,7 +131,9 @@ namespace skyline::service::nvdrv::device::nvhost {
* @brief Maps a region into this address space with extra parameters * @brief Maps a region into this address space with extra parameters
* @url https://switchbrew.org/wiki/NV_services#NVGPU_AS_IOCTL_MAP_BUFFER_EX * @url https://switchbrew.org/wiki/NV_services#NVGPU_AS_IOCTL_MAP_BUFFER_EX
*/ */
PosixResult MapBufferEx(In<MappingFlags> flags, In<u32> kind, In<core::NvMap::Handle::Id> handle, In<u64> bufferOffset, In<u64> mappingSize, InOut<u64> offset); PosixResult MapBufferEx(In<MappingFlags> flags, In<u32> kind,
In<core::NvMap::Handle::Id> handle, In<u64> bufferOffset,
In<u64> mappingSize, InOut<u64> offset);
/** /**
* @brief Returns info about the address space and its page sizes * @brief Returns info about the address space and its page sizes
@ -148,7 +150,10 @@ namespace skyline::service::nvdrv::device::nvhost {
* @brief Allocates this address space with the given parameters * @brief Allocates this address space with the given parameters
* @url https://switchbrew.org/wiki/NV_services#NVGPU_AS_IOCTL_ALLOC_AS_EX * @url https://switchbrew.org/wiki/NV_services#NVGPU_AS_IOCTL_ALLOC_AS_EX
*/ */
PosixResult AllocAsEx(In<u32> flags, In<FileDescriptor> asFd, In<u32> bigPageSize, In<u64> vaRangeStart, In<u64> vaRangeEnd, In<u64> vaRangeSplit); PosixResult AllocAsEx(In<u32> flags,
In<FileDescriptor> asFd,
In<u32> bigPageSize,
In<u64> vaRangeStart, In<u64> vaRangeEnd, In<u64> vaRangeSplit);
/** /**
* @brief Remaps a region of the GPU address space * @brief Remaps a region of the GPU address space

View File

@ -5,10 +5,10 @@
#include "ctrl_gpu.h" #include "ctrl_gpu.h"
namespace skyline::service::nvdrv::device::nvhost { namespace skyline::service::nvdrv::device::nvhost {
CtrlGpu::CtrlGpu(const DeviceState &state, Driver &driver, Core &core, const SessionContext &ctx) : CtrlGpu::CtrlGpu(const DeviceState &state, Driver &driver, Core &core, const SessionContext &ctx)
NvDevice(state, driver, core, ctx), : NvDevice(state, driver, core, ctx),
errorNotifierEvent(std::make_shared<type::KEvent>(state, false)), errorNotifierEvent(std::make_shared<type::KEvent>(state, false)),
unknownEvent(std::make_shared<type::KEvent>(state, false)) {} unknownEvent(std::make_shared<type::KEvent>(state, false)) {}
PosixResult CtrlGpu::ZCullGetCtxSize(Out<u32> size) { PosixResult CtrlGpu::ZCullGetCtxSize(Out<u32> size) {
size = 0x1; size = 0x1;

View File

@ -6,11 +6,11 @@
#include "gpu_channel.h" #include "gpu_channel.h"
namespace skyline::service::nvdrv::device::nvhost { namespace skyline::service::nvdrv::device::nvhost {
GpuChannel::GpuChannel(const DeviceState &state, Driver &driver, Core &core, const SessionContext &ctx) : GpuChannel::GpuChannel(const DeviceState &state, Driver &driver, Core &core, const SessionContext &ctx)
NvDevice(state, driver, core, ctx), : NvDevice(state, driver, core, ctx),
smExceptionBreakpointIntReportEvent(std::make_shared<type::KEvent>(state, false)), smExceptionBreakpointIntReportEvent(std::make_shared<type::KEvent>(state, false)),
smExceptionBreakpointPauseReportEvent(std::make_shared<type::KEvent>(state, false)), smExceptionBreakpointPauseReportEvent(std::make_shared<type::KEvent>(state, false)),
errorNotifierEvent(std::make_shared<type::KEvent>(state, false)) { errorNotifierEvent(std::make_shared<type::KEvent>(state, false)) {
channelSyncpoint = core.syncpointManager.AllocateSyncpoint(false); channelSyncpoint = core.syncpointManager.AllocateSyncpoint(false);
} }
@ -75,7 +75,10 @@ namespace skyline::service::nvdrv::device::nvhost {
return PosixResult::Success; return PosixResult::Success;
} }
PosixResult GpuChannel::SubmitGpfifo(In<u64> userAddress, In<u32> numEntries, InOut<SubmitGpfifoFlags> flags, InOut<Fence> fence, span<soc::gm20b::GpEntry> gpEntries) { PosixResult GpuChannel::SubmitGpfifo(In<u64> userAddress, In<u32> numEntries,
InOut<SubmitGpfifoFlags> flags,
InOut<Fence> fence,
span<soc::gm20b::GpEntry> gpEntries) {
state.logger->Debug("userAddress: 0x{:X}, numEntries: {}," state.logger->Debug("userAddress: 0x{:X}, numEntries: {},"
"flags ( fenceWait: {}, fenceIncrement: {}, hwFormat: {}, suppressWfi: {}, incrementWithValue: {})," "flags ( fenceWait: {}, fenceIncrement: {}, hwFormat: {}, suppressWfi: {}, incrementWithValue: {}),"
"fence ( id: {}, threshold: {} )", "fence ( id: {}, threshold: {} )",

View File

@ -69,12 +69,17 @@ namespace skyline::service::nvdrv::device::nvhost {
* @brief Submits GPFIFO entries for this channel * @brief Submits GPFIFO entries for this channel
* @url https://switchbrew.org/wiki/NV_services#NVGPU_IOCTL_CHANNEL_SUBMIT_GPFIFO * @url https://switchbrew.org/wiki/NV_services#NVGPU_IOCTL_CHANNEL_SUBMIT_GPFIFO
*/ */
PosixResult SubmitGpfifo(In<u64> userAddress, In<u32> numEntries, InOut<SubmitGpfifoFlags> flags, InOut<Fence> fence, span<soc::gm20b::GpEntry> gpEntries); PosixResult SubmitGpfifo(In<u64> userAddress, In<u32> numEntries,
InOut<SubmitGpfifoFlags> flags,
InOut<Fence> fence,
span<soc::gm20b::GpEntry> gpEntries);
/** /**
* @brief Ioctl2 variant of SubmitGpfifo * @brief Ioctl2 variant of SubmitGpfifo
*/ */
PosixResult SubmitGpfifo2(span<u8> inlineBuffer, In<u64> userAddress, In<u32> numEntries, InOut<SubmitGpfifoFlags> flags, InOut<Fence> fence); PosixResult SubmitGpfifo2(span<u8> inlineBuffer, In<u64> userAddress, In<u32> numEntries,
InOut<SubmitGpfifoFlags> flags,
InOut<Fence> fence);
/** /**
* @brief Allocates a graphic context object * @brief Allocates a graphic context object

View File

@ -38,8 +38,11 @@ namespace skyline::service::nvdrv::device {
return result; return result;
} }
PosixResult NvMap::Alloc(In<NvMapCore::Handle::Id> handle, In<u32> heapMask, In<NvMapCore::Handle::Flags> flags, InOut<u32> align, In<u8> kind, In<u64> address) { PosixResult NvMap::Alloc(In<NvMapCore::Handle::Id> handle,
state.logger->Debug("handle: {}, flags: ( mapUncached: {}, keepUncachedAfterFree: {} ), align: 0x{:X}, kind: {}, address: 0x{:X}", handle, flags.mapUncached, flags.keepUncachedAfterFree, align, kind, address); In<u32> heapMask, In<NvMapCore::Handle::Flags> flags,
InOut<u32> align, In<u8> kind, In<u64> address) {
state.logger->Debug("handle: {}, flags: ( mapUncached: {}, keepUncachedAfterFree: {} ), align: 0x{:X}, kind: {}, address: 0x{:X}",
handle, flags.mapUncached, flags.keepUncachedAfterFree, align, kind, address);
if (!handle) [[unlikely]] if (!handle) [[unlikely]]
return PosixResult::InvalidArgument; return PosixResult::InvalidArgument;
@ -58,7 +61,9 @@ namespace skyline::service::nvdrv::device {
return handleDesc->Alloc(flags, align, kind, address); return handleDesc->Alloc(flags, align, kind, address);
} }
PosixResult NvMap::Free(In<NvMapCore::Handle::Id> handle, Out<u64> address, Out<u32> size, Out<NvMapCore::Handle::Flags> flags) { PosixResult NvMap::Free(In<NvMapCore::Handle::Id> handle,
Out<u64> address, Out<u32> size,
Out<NvMapCore::Handle::Flags> flags) {
state.logger->Debug("handle: {}", handle); state.logger->Debug("handle: {}", handle);
if (!handle) [[unlikely]] if (!handle) [[unlikely]]

View File

@ -41,13 +41,17 @@ namespace skyline::service::nvdrv::device {
* @brief Adds the given backing memory to the nvmap handle * @brief Adds the given backing memory to the nvmap handle
* @url https://switchbrew.org/wiki/NV_services#NVMAP_IOC_ALLOC * @url https://switchbrew.org/wiki/NV_services#NVMAP_IOC_ALLOC
*/ */
PosixResult Alloc(In<NvMapCore::Handle::Id> handle, In<u32> heapMask, In<NvMapCore::Handle::Flags> flags, InOut<u32> align, In<u8> kind, In<u64> address); PosixResult Alloc(In<NvMapCore::Handle::Id> handle,
In<u32> heapMask, In<NvMapCore::Handle::Flags> flags,
InOut<u32> align, In<u8> kind, In<u64> address);
/** /**
* @brief Attempts to free a handle and unpin it from SMMU memory * @brief Attempts to free a handle and unpin it from SMMU memory
* @url https://switchbrew.org/wiki/NV_services#NVMAP_IOC_FREE * @url https://switchbrew.org/wiki/NV_services#NVMAP_IOC_FREE
*/ */
PosixResult Free(In<NvMapCore::Handle::Id> handle, Out<u64> address, Out<u32> size, Out<NvMapCore::Handle::Flags> flags); PosixResult Free(In<NvMapCore::Handle::Id> handle,
Out<u64> address, Out<u32> size,
Out<NvMapCore::Handle::Flags> flags);
/** /**
* @brief Returns info about a property of the nvmap handle * @brief Returns info about a property of the nvmap handle

View File

@ -81,7 +81,7 @@ namespace skyline::service::nvdrv {
std::shared_lock lock(deviceMutex); std::shared_lock lock(deviceMutex);
return ConvertResult(devices.at(fd)->Ioctl(cmd, buffer)); return ConvertResult(devices.at(fd)->Ioctl(cmd, buffer));
} catch (const std::out_of_range &) { } catch (const std::out_of_range &) {
throw exception("Ioctl was called with invalid file descriptor: {}", fd); throw exception("Ioctl was called with invalid fd: {}", fd);
} }
} }
@ -92,7 +92,7 @@ namespace skyline::service::nvdrv {
std::shared_lock lock(deviceMutex); std::shared_lock lock(deviceMutex);
return ConvertResult(devices.at(fd)->Ioctl2(cmd, buffer, inlineBuffer)); return ConvertResult(devices.at(fd)->Ioctl2(cmd, buffer, inlineBuffer));
} catch (const std::out_of_range &) { } catch (const std::out_of_range &) {
throw exception("Ioctl2 was called with invalid file descriptor: 0x{:X}", fd); throw exception("Ioctl2 was called with invalid fd: {}", fd);
} }
} }
@ -103,7 +103,7 @@ namespace skyline::service::nvdrv {
std::shared_lock lock(deviceMutex); std::shared_lock lock(deviceMutex);
return ConvertResult(devices.at(fd)->Ioctl3(cmd, buffer, inlineBuffer)); return ConvertResult(devices.at(fd)->Ioctl3(cmd, buffer, inlineBuffer));
} catch (const std::out_of_range &) { } catch (const std::out_of_range &) {
throw exception("Ioctl3 was called with invalid file descriptor: {}", fd); throw exception("Ioctl3 was called with invalid fd: {}", fd);
} }
} }
@ -112,7 +112,7 @@ namespace skyline::service::nvdrv {
std::unique_lock lock(deviceMutex); std::unique_lock lock(deviceMutex);
devices.erase(fd); devices.erase(fd);
} catch (const std::out_of_range &) { } catch (const std::out_of_range &) {
state.logger->Warn("Trying to close non-existent file descriptor: {}"); state.logger->Warn("Trying to close invalid fd: {}");
} }
} }
@ -123,7 +123,7 @@ namespace skyline::service::nvdrv {
std::shared_lock lock(deviceMutex); std::shared_lock lock(deviceMutex);
return devices.at(fd)->QueryEvent(eventId); return devices.at(fd)->QueryEvent(eventId);
} catch (const std::exception &) { } catch (const std::exception &) {
throw exception("QueryEvent was called with invalid file descriptor: {}", fd); throw exception("QueryEvent was called with invalid fd: {}", fd);
} }
} }
} }