From 70d67ef563cd9b9d83de1072fa8bbb33c686823b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=97=B1=20PixelyIon?= Date: Fri, 18 Sep 2020 06:15:57 +0530 Subject: [PATCH] Constexpr Maps for NvDevice IOCTLs --- .../skyline/services/nvdrv/devices/nvdevice.cpp | 4 +--- .../skyline/services/nvdrv/devices/nvdevice.h | 17 ++++++++++------- .../services/nvdrv/devices/nvhost_as_gpu.cpp | 10 +--------- .../services/nvdrv/devices/nvhost_as_gpu.h | 10 ++++++++++ .../services/nvdrv/devices/nvhost_channel.cpp | 12 +----------- .../services/nvdrv/devices/nvhost_channel.h | 12 ++++++++++++ .../services/nvdrv/devices/nvhost_ctrl.cpp | 8 +------- .../services/nvdrv/devices/nvhost_ctrl.h | 8 ++++++++ .../services/nvdrv/devices/nvhost_ctrl_gpu.cpp | 8 +------- .../services/nvdrv/devices/nvhost_ctrl_gpu.h | 8 ++++++++ .../skyline/services/nvdrv/devices/nvmap.cpp | 9 +-------- .../cpp/skyline/services/nvdrv/devices/nvmap.h | 9 +++++++++ 12 files changed, 63 insertions(+), 52 deletions(-) diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvdevice.cpp b/app/src/main/cpp/skyline/services/nvdrv/devices/nvdevice.cpp index 745f5a8a..12874204 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvdevice.cpp +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvdevice.cpp @@ -4,8 +4,6 @@ #include "nvdevice.h" namespace skyline::service::nvdrv::device { - NvDevice::NvDevice(const DeviceState &state, std::unordered_map > vTable) : state(state), vTable(vTable) {} - std::string NvDevice::GetName() { int status{}; size_t length{}; @@ -19,7 +17,7 @@ namespace skyline::service::nvdrv::device { void NvDevice::HandleIoctl(u32 cmd, IoctlData &input) { std::function function; try { - function = vTable.at(cmd); + function = GetServiceFunction(cmd); } catch (std::out_of_range &) { state.logger->Warn("Cannot find IOCTL for device '{}': 0x{:X}", GetName(), cmd); input.status = NvStatus::NotImplemented; diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvdevice.h b/app/src/main/cpp/skyline/services/nvdrv/devices/nvdevice.h index 1a9bb7d0..fb698aa6 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvdevice.h +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvdevice.h @@ -8,7 +8,13 @@ #include #include -#define NFUNC(function) std::bind(&function, this, std::placeholders::_1) +#define NVFUNC(id, Class, Function) std::pair>(id, &Class::Function) +#define NVDEVICE_DECL_AUTO(name, value) decltype(value) name = value +#define NVDEVICE_DECL(...) \ +NVDEVICE_DECL_AUTO(functions, frz::make_unordered_map({__VA_ARGS__})); \ +std::function GetServiceFunction(u32 index) { \ + return std::bind(functions.at(index), this, std::placeholders::_1); \ +} namespace skyline::service::nvdrv::device { using namespace kernel; @@ -92,17 +98,14 @@ namespace skyline::service::nvdrv::device { class NvDevice { protected: const DeviceState &state; //!< The state of the device - std::unordered_map> vTable; //!< This holds the mapping from an Ioctl to the actual function public: - /** - * @param state The state of the device - * @param vTable The functions in this device - */ - NvDevice(const DeviceState &state, std::unordered_map> vTable); + inline NvDevice(const DeviceState &state) : state(state) {} virtual ~NvDevice() = default; + virtual std::function GetServiceFunction(u32 index) = 0; + /** * @return The name of the class */ diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_as_gpu.cpp b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_as_gpu.cpp index c0aba4f9..fdcb961d 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_as_gpu.cpp +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_as_gpu.cpp @@ -9,15 +9,7 @@ #include "nvhost_as_gpu.h" namespace skyline::service::nvdrv::device { - NvHostAsGpu::NvHostAsGpu(const DeviceState &state) : NvDevice(state, { - {0x4101, NFUNC(NvHostAsGpu::BindChannel)}, - {0x4102, NFUNC(NvHostAsGpu::AllocSpace)}, - {0x4105, NFUNC(NvHostAsGpu::UnmapBuffer)}, - {0x4106, NFUNC(NvHostAsGpu::Modify)}, - {0x4108, NFUNC(NvHostAsGpu::GetVaRegions)}, - {0x4109, NFUNC(NvHostAsGpu::InitializeEx)}, - {0x4114, NFUNC(NvHostAsGpu::Remap)}, - }) {} + NvHostAsGpu::NvHostAsGpu(const DeviceState &state) : NvDevice(state) {} void NvHostAsGpu::BindChannel(IoctlData &buffer) { struct Data { diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_as_gpu.h b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_as_gpu.h index 5e99590e..b9dfe140 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_as_gpu.h +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_as_gpu.h @@ -47,5 +47,15 @@ namespace skyline::service::nvdrv::device { * @brief Remaps a region of the GPU address space (https://switchbrew.org/wiki/NV_services#NVGPU_AS_IOCTL_REMAP) */ void Remap(IoctlData &buffer); + + NVDEVICE_DECL( + NVFUNC(0x4101, NvHostAsGpu, BindChannel), + NVFUNC(0x4102, NvHostAsGpu, AllocSpace), + NVFUNC(0x4105, NvHostAsGpu, UnmapBuffer), + NVFUNC(0x4106, NvHostAsGpu, Modify), + NVFUNC(0x4108, NvHostAsGpu, GetVaRegions), + NVFUNC(0x4109, NvHostAsGpu, InitializeEx), + NVFUNC(0x4114, NvHostAsGpu, Remap) + ) }; } diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_channel.cpp b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_channel.cpp index a73285ff..ff298628 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_channel.cpp +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_channel.cpp @@ -8,17 +8,7 @@ #include "nvhost_channel.h" namespace skyline::service::nvdrv::device { - NvHostChannel::NvHostChannel(const DeviceState &state) : smExceptionBreakpointIntReportEvent(std::make_shared(state)), smExceptionBreakpointPauseReportEvent(std::make_shared(state)), errorNotifierEvent(std::make_shared(state)), NvDevice(state, { - {0x4801, NFUNC(NvHostChannel::SetNvmapFd)}, - {0x4803, NFUNC(NvHostChannel::SetSubmitTimeout)}, - {0x4808, NFUNC(NvHostChannel::SubmitGpfifo)}, - {0x4809, NFUNC(NvHostChannel::AllocObjCtx)}, - {0x480B, NFUNC(NvHostChannel::ZcullBind)}, - {0x480C, NFUNC(NvHostChannel::SetErrorNotifier)}, - {0x480D, NFUNC(NvHostChannel::SetPriority)}, - {0x481A, NFUNC(NvHostChannel::AllocGpfifoEx2)}, - {0x4714, NFUNC(NvHostChannel::SetUserData)}, - }) { + NvHostChannel::NvHostChannel(const DeviceState &state) : smExceptionBreakpointIntReportEvent(std::make_shared(state)), smExceptionBreakpointPauseReportEvent(std::make_shared(state)), errorNotifierEvent(std::make_shared(state)), NvDevice(state) { auto driver = nvdrv::driver.lock(); auto &hostSyncpoint = driver->hostSyncpoint; diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_channel.h b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_channel.h index 2c959fcb..da58fcbb 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_channel.h +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_channel.h @@ -73,5 +73,17 @@ namespace skyline::service::nvdrv::device { void SetUserData(IoctlData &buffer); std::shared_ptr QueryEvent(u32 eventId); + + NVDEVICE_DECL( + NVFUNC(0x4801, NvHostChannel, SetNvmapFd), + NVFUNC(0x4803, NvHostChannel, SetSubmitTimeout), + NVFUNC(0x4808, NvHostChannel, SubmitGpfifo), + NVFUNC(0x4809, NvHostChannel, AllocObjCtx), + NVFUNC(0x480B, NvHostChannel, ZcullBind), + NVFUNC(0x480C, NvHostChannel, SetErrorNotifier), + NVFUNC(0x480D, NvHostChannel, SetPriority), + NVFUNC(0x481A, NvHostChannel, AllocGpfifoEx2), + NVFUNC(0x4714, NvHostChannel, SetUserData) + ) }; } diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl.cpp b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl.cpp index 908b7ac5..dee771e1 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl.cpp +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl.cpp @@ -37,13 +37,7 @@ namespace skyline::service::nvdrv::device { } } - NvHostCtrl::NvHostCtrl(const DeviceState &state) : NvDevice(state, { - {0x001B, NFUNC(NvHostCtrl::GetConfig)}, - {0x001C, NFUNC(NvHostCtrl::EventSignal)}, - {0x001D, NFUNC(NvHostCtrl::EventWait)}, - {0x001E, NFUNC(NvHostCtrl::EventWaitAsync)}, - {0x001F, NFUNC(NvHostCtrl::EventRegister)}, - }) {} + NvHostCtrl::NvHostCtrl(const DeviceState &state) : NvDevice(state) {} u32 NvHostCtrl::FindFreeEvent(u32 syncpointId) { u32 eventIndex{constant::NvHostEventCount}; //!< Holds the index of the last populated event in the event array diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl.h b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl.h index 86dc2767..c96fdcad 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl.h +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl.h @@ -118,6 +118,14 @@ namespace skyline { void EventRegister(IoctlData &buffer); std::shared_ptr QueryEvent(u32 eventId); + + NVDEVICE_DECL( + NVFUNC(0x001B, NvHostCtrl, GetConfig), + NVFUNC(0x001C, NvHostCtrl, EventSignal), + NVFUNC(0x001D, NvHostCtrl, EventWait), + NVFUNC(0x001E, NvHostCtrl, EventWaitAsync), + NVFUNC(0x001F, NvHostCtrl, EventRegister) + ) }; } } diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl_gpu.cpp b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl_gpu.cpp index 43700840..ba211e31 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl_gpu.cpp @@ -5,13 +5,7 @@ #include "nvhost_ctrl_gpu.h" namespace skyline::service::nvdrv::device { - NvHostCtrlGpu::NvHostCtrlGpu(const DeviceState &state) : errorNotifierEvent(std::make_shared(state)), unknownEvent(std::make_shared(state)), NvDevice(state, { - {0x4701, NFUNC(NvHostCtrlGpu::ZCullGetCtxSize)}, - {0x4702, NFUNC(NvHostCtrlGpu::ZCullGetInfo)}, - {0x4706, NFUNC(NvHostCtrlGpu::GetTpcMasks)}, - {0x4705, NFUNC(NvHostCtrlGpu::GetCharacteristics)}, - {0x4714, NFUNC(NvHostCtrlGpu::GetActiveSlotMask)}, - }) {} + NvHostCtrlGpu::NvHostCtrlGpu(const DeviceState &state) : errorNotifierEvent(std::make_shared(state)), unknownEvent(std::make_shared(state)), NvDevice(state) {} void NvHostCtrlGpu::ZCullGetCtxSize(IoctlData &buffer) { u32 size = 0x1; diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl_gpu.h b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl_gpu.h index cbccfb72..eb3bc6f5 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl_gpu.h +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl_gpu.h @@ -43,5 +43,13 @@ namespace skyline::service::nvdrv::device { void GetActiveSlotMask(IoctlData &buffer); std::shared_ptr QueryEvent(u32 eventId); + + NVDEVICE_DECL( + NVFUNC(0x4701, NvHostCtrlGpu, ZCullGetCtxSize), + NVFUNC(0x4702, NvHostCtrlGpu, ZCullGetInfo), + NVFUNC(0x4706, NvHostCtrlGpu, GetTpcMasks), + NVFUNC(0x4705, NvHostCtrlGpu, GetCharacteristics), + NVFUNC(0x4714, NvHostCtrlGpu, GetActiveSlotMask) + ) }; } diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvmap.cpp b/app/src/main/cpp/skyline/services/nvdrv/devices/nvmap.cpp index aec8e350..bcde19ee 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvmap.cpp +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvmap.cpp @@ -7,14 +7,7 @@ namespace skyline::service::nvdrv::device { NvMap::NvMapObject::NvMapObject(u32 id, u32 size) : id(id), size(size) {} - NvMap::NvMap(const DeviceState &state) : NvDevice(state, { - {0x0101, NFUNC(NvMap::Create)}, - {0x0103, NFUNC(NvMap::FromId)}, - {0x0104, NFUNC(NvMap::Alloc)}, - {0x0105, NFUNC(NvMap::Free)}, - {0x0109, NFUNC(NvMap::Param)}, - {0x010E, NFUNC(NvMap::GetId)} - }) {} + NvMap::NvMap(const DeviceState &state) : NvDevice(state) {} void NvMap::Create(IoctlData &buffer) { struct Data { diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvmap.h b/app/src/main/cpp/skyline/services/nvdrv/devices/nvmap.h index aadc3283..a465e3e5 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvmap.h +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvmap.h @@ -70,5 +70,14 @@ namespace skyline::service::nvdrv::device { * @brief This returns the ID of an NvMapObject from it's handle (https://switchbrew.org/wiki/NV_services#NVMAP_IOC_GET_ID) */ void GetId(IoctlData &buffer); + + NVDEVICE_DECL( + NVFUNC(0x0101, NvMap, Create), + NVFUNC(0x0103, NvMap, FromId), + NVFUNC(0x0104, NvMap, Alloc), + NVFUNC(0x0105, NvMap, Free), + NVFUNC(0x0109, NvMap, Param), + NVFUNC(0x010E, NvMap, GetId) + ) }; }