Constexpr Maps for NvDevice IOCTLs

This commit is contained in:
◱ PixelyIon 2020-09-18 06:15:57 +05:30 committed by ◱ PixelyIon
parent 20253a9573
commit 70d67ef563
12 changed files with 63 additions and 52 deletions

View File

@ -4,8 +4,6 @@
#include "nvdevice.h" #include "nvdevice.h"
namespace skyline::service::nvdrv::device { namespace skyline::service::nvdrv::device {
NvDevice::NvDevice(const DeviceState &state, std::unordered_map <u32, std::function<void(IoctlData &)>> vTable) : state(state), vTable(vTable) {}
std::string NvDevice::GetName() { std::string NvDevice::GetName() {
int status{}; int status{};
size_t length{}; size_t length{};
@ -19,7 +17,7 @@ namespace skyline::service::nvdrv::device {
void NvDevice::HandleIoctl(u32 cmd, IoctlData &input) { void NvDevice::HandleIoctl(u32 cmd, IoctlData &input) {
std::function<void(IoctlData &)> function; std::function<void(IoctlData &)> function;
try { try {
function = vTable.at(cmd); function = GetServiceFunction(cmd);
} catch (std::out_of_range &) { } catch (std::out_of_range &) {
state.logger->Warn("Cannot find IOCTL for device '{}': 0x{:X}", GetName(), cmd); state.logger->Warn("Cannot find IOCTL for device '{}': 0x{:X}", GetName(), cmd);
input.status = NvStatus::NotImplemented; input.status = NvStatus::NotImplemented;

View File

@ -8,7 +8,13 @@
#include <kernel/ipc.h> #include <kernel/ipc.h>
#include <kernel/types/KEvent.h> #include <kernel/types/KEvent.h>
#define NFUNC(function) std::bind(&function, this, std::placeholders::_1) #define NVFUNC(id, Class, Function) std::pair<u32, std::function<void(Class*, IoctlData &)>>(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<void(IoctlData &)> GetServiceFunction(u32 index) { \
return std::bind(functions.at(index), this, std::placeholders::_1); \
}
namespace skyline::service::nvdrv::device { namespace skyline::service::nvdrv::device {
using namespace kernel; using namespace kernel;
@ -92,17 +98,14 @@ namespace skyline::service::nvdrv::device {
class NvDevice { class NvDevice {
protected: protected:
const DeviceState &state; //!< The state of the device const DeviceState &state; //!< The state of the device
std::unordered_map<u32, std::function<void(IoctlData &)>> vTable; //!< This holds the mapping from an Ioctl to the actual function
public: public:
/** inline NvDevice(const DeviceState &state) : state(state) {}
* @param state The state of the device
* @param vTable The functions in this device
*/
NvDevice(const DeviceState &state, std::unordered_map<u32, std::function<void(IoctlData & )>> vTable);
virtual ~NvDevice() = default; virtual ~NvDevice() = default;
virtual std::function<void(IoctlData &)> GetServiceFunction(u32 index) = 0;
/** /**
* @return The name of the class * @return The name of the class
*/ */

View File

@ -9,15 +9,7 @@
#include "nvhost_as_gpu.h" #include "nvhost_as_gpu.h"
namespace skyline::service::nvdrv::device { namespace skyline::service::nvdrv::device {
NvHostAsGpu::NvHostAsGpu(const DeviceState &state) : NvDevice(state, { 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)},
}) {}
void NvHostAsGpu::BindChannel(IoctlData &buffer) { void NvHostAsGpu::BindChannel(IoctlData &buffer) {
struct Data { struct Data {

View File

@ -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) * @brief Remaps a region of the GPU address space (https://switchbrew.org/wiki/NV_services#NVGPU_AS_IOCTL_REMAP)
*/ */
void Remap(IoctlData &buffer); 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)
)
}; };
} }

View File

@ -8,17 +8,7 @@
#include "nvhost_channel.h" #include "nvhost_channel.h"
namespace skyline::service::nvdrv::device { namespace skyline::service::nvdrv::device {
NvHostChannel::NvHostChannel(const DeviceState &state) : smExceptionBreakpointIntReportEvent(std::make_shared<type::KEvent>(state)), smExceptionBreakpointPauseReportEvent(std::make_shared<type::KEvent>(state)), errorNotifierEvent(std::make_shared<type::KEvent>(state)), NvDevice(state, { NvHostChannel::NvHostChannel(const DeviceState &state) : smExceptionBreakpointIntReportEvent(std::make_shared<type::KEvent>(state)), smExceptionBreakpointPauseReportEvent(std::make_shared<type::KEvent>(state)), errorNotifierEvent(std::make_shared<type::KEvent>(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)},
}) {
auto driver = nvdrv::driver.lock(); auto driver = nvdrv::driver.lock();
auto &hostSyncpoint = driver->hostSyncpoint; auto &hostSyncpoint = driver->hostSyncpoint;

View File

@ -73,5 +73,17 @@ namespace skyline::service::nvdrv::device {
void SetUserData(IoctlData &buffer); void SetUserData(IoctlData &buffer);
std::shared_ptr<type::KEvent> QueryEvent(u32 eventId); std::shared_ptr<type::KEvent> 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)
)
}; };
} }

View File

@ -37,13 +37,7 @@ namespace skyline::service::nvdrv::device {
} }
} }
NvHostCtrl::NvHostCtrl(const DeviceState &state) : NvDevice(state, { 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)},
}) {}
u32 NvHostCtrl::FindFreeEvent(u32 syncpointId) { u32 NvHostCtrl::FindFreeEvent(u32 syncpointId) {
u32 eventIndex{constant::NvHostEventCount}; //!< Holds the index of the last populated event in the event array u32 eventIndex{constant::NvHostEventCount}; //!< Holds the index of the last populated event in the event array

View File

@ -118,6 +118,14 @@ namespace skyline {
void EventRegister(IoctlData &buffer); void EventRegister(IoctlData &buffer);
std::shared_ptr<type::KEvent> QueryEvent(u32 eventId); std::shared_ptr<type::KEvent> 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)
)
}; };
} }
} }

View File

@ -5,13 +5,7 @@
#include "nvhost_ctrl_gpu.h" #include "nvhost_ctrl_gpu.h"
namespace skyline::service::nvdrv::device { namespace skyline::service::nvdrv::device {
NvHostCtrlGpu::NvHostCtrlGpu(const DeviceState &state) : errorNotifierEvent(std::make_shared<type::KEvent>(state)), unknownEvent(std::make_shared<type::KEvent>(state)), NvDevice(state, { NvHostCtrlGpu::NvHostCtrlGpu(const DeviceState &state) : errorNotifierEvent(std::make_shared<type::KEvent>(state)), unknownEvent(std::make_shared<type::KEvent>(state)), NvDevice(state) {}
{0x4701, NFUNC(NvHostCtrlGpu::ZCullGetCtxSize)},
{0x4702, NFUNC(NvHostCtrlGpu::ZCullGetInfo)},
{0x4706, NFUNC(NvHostCtrlGpu::GetTpcMasks)},
{0x4705, NFUNC(NvHostCtrlGpu::GetCharacteristics)},
{0x4714, NFUNC(NvHostCtrlGpu::GetActiveSlotMask)},
}) {}
void NvHostCtrlGpu::ZCullGetCtxSize(IoctlData &buffer) { void NvHostCtrlGpu::ZCullGetCtxSize(IoctlData &buffer) {
u32 size = 0x1; u32 size = 0x1;

View File

@ -43,5 +43,13 @@ namespace skyline::service::nvdrv::device {
void GetActiveSlotMask(IoctlData &buffer); void GetActiveSlotMask(IoctlData &buffer);
std::shared_ptr<type::KEvent> QueryEvent(u32 eventId); std::shared_ptr<type::KEvent> 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)
)
}; };
} }

View File

@ -7,14 +7,7 @@
namespace skyline::service::nvdrv::device { namespace skyline::service::nvdrv::device {
NvMap::NvMapObject::NvMapObject(u32 id, u32 size) : id(id), size(size) {} NvMap::NvMapObject::NvMapObject(u32 id, u32 size) : id(id), size(size) {}
NvMap::NvMap(const DeviceState &state) : NvDevice(state, { 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)}
}) {}
void NvMap::Create(IoctlData &buffer) { void NvMap::Create(IoctlData &buffer) {
struct Data { struct Data {

View File

@ -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) * @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); 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)
)
}; };
} }