Improve NvDevice Registration + Access

This commit is contained in:
◱ PixelyIon 2020-09-18 02:08:23 +05:30 committed by ◱ PixelyIon
parent 4cc3a3b2e8
commit 20253a9573
18 changed files with 149 additions and 166 deletions

3
.gitmodules vendored
View File

@ -14,3 +14,6 @@
[submodule "app/libraries/lz4"]
path = app/libraries/lz4
url = https://github.com/lz4/lz4.git
[submodule "app/libraries/frozen"]
path = app/libraries/frozen
url = https://github.com/serge-sans-paille/frozen

View File

@ -7,6 +7,22 @@
<option name="FORMATTER_OFF_TAG" value="@fmt:off" />
<option name="SOFT_MARGINS" value="80,140" />
<JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
<value>
<package name="java.util" alias="false" withSubpackages="false" />
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
<package name="io.ktor" alias="false" withSubpackages="true" />
</value>
</option>
<option name="PACKAGES_IMPORT_LAYOUT">
<value>
<package name="" alias="false" withSubpackages="true" />
<package name="java" alias="false" withSubpackages="true" />
<package name="javax" alias="false" withSubpackages="true" />
<package name="kotlin" alias="false" withSubpackages="true" />
<package name="" alias="true" withSubpackages="true" />
</value>
</option>
<option name="SPACE_BEFORE_TYPE_COLON" value="true" />
</JetCodeStyleSettings>
<Objective-C>

3
.idea/vcs.xml generated
View File

@ -3,9 +3,10 @@
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$/app/libraries/fmt" vcs="Git" />
<mapping directory="$PROJECT_DIR$/app/libraries/frozen" vcs="Git" />
<mapping directory="$PROJECT_DIR$/app/libraries/lz4" vcs="Git" />
<mapping directory="$PROJECT_DIR$/app/libraries/oboe" vcs="Git" />
<mapping directory="$PROJECT_DIR$/app/libraries/tinyxml2" vcs="Git" />
<mapping directory="$PROJECT_DIR$/app/libraries/vkhpp" vcs="Git" />
</component>
</project>
</project>

View File

@ -22,6 +22,7 @@ add_subdirectory("libraries/lz4/contrib/cmake_unofficial")
include_directories("libraries/lz4/lib")
include_directories("libraries/oboe/include")
include_directories("libraries/vkhpp/include")
include_directories("libraries/frozen/include")
set(CMAKE_POLICY_DEFAULT_CMP0048 NEW)
find_package(mbedtls REQUIRED CONFIG)
@ -114,6 +115,7 @@ add_library(skyline SHARED
${source_DIR}/skyline/services/fssrv/IStorage.cpp
${source_DIR}/skyline/services/nvdrv/INvDrvServices.cpp
${source_DIR}/skyline/services/nvdrv/driver.cpp
${source_DIR}/skyline/services/nvdrv/devices/nvdevice.cpp
${source_DIR}/skyline/services/nvdrv/devices/nvmap.cpp
${source_DIR}/skyline/services/nvdrv/devices/nvhost_ctrl_gpu.cpp
${source_DIR}/skyline/services/nvdrv/devices/nvhost_ctrl.cpp

View File

@ -4,11 +4,11 @@ apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 30
buildToolsVersion '30.0.0'
buildToolsVersion '30.0.2'
defaultConfig {
applicationId "skyline.emu"
minSdkVersion 26
targetSdkVersion 29
targetSdkVersion 30
versionCode 3
versionName "0.3"
ndk {
@ -59,7 +59,7 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
implementation 'androidx.preference:preference:1.1.1'
implementation 'com.google.android.material:material:1.3.0-alpha02'
implementation "androidx.core:core-ktx:1.3.1"

1
app/libraries/frozen Submodule

@ -0,0 +1 @@
Subproject commit 30b475274c044f456c37b6d15de3d04c85112698

View File

@ -8,21 +8,24 @@
#include <span>
#include <vector>
#include <fstream>
#include <syslog.h>
#include <mutex>
#include <thread>
#include <string>
#include <sstream>
#include <memory>
#include <fmt/format.h>
#include <sys/mman.h>
#include <cstdint>
#include <stdexcept>
#include <string>
#include <sstream>
#include <memory>
#include <syslog.h>
#include <sys/mman.h>
#include <fmt/format.h>
#include <frozen/unordered_map.h>
#include <frozen/string.h>
#include <jni.h>
#include "nce/guest_common.h"
namespace skyline {
namespace frz = frozen;
using KHandle = u32; //!< The type of a kernel handle
/**
@ -194,6 +197,10 @@ namespace skyline {
}
return result;
}
constexpr std::size_t Hash(const std::string_view& view) {
return frz::elsa<frz::string>{}(frz::string(view.data(), view.size()), 0);
}
}
/**

View File

@ -124,7 +124,7 @@ namespace skyline::service::hosbinder {
std::shared_ptr<nvdrv::device::NvMap::NvMapObject> nvBuffer{};
auto driver = nvdrv::driver.lock();
auto nvmap = driver->GetDevice<nvdrv::device::NvMap>(nvdrv::device::NvDeviceType::nvmap);
auto nvmap = driver->nvMap.lock();
if (gbpBuffer.nvmapHandle) {
nvBuffer = nvmap->handleTable.at(gbpBuffer.nvmapHandle);

View File

@ -0,0 +1,34 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#include "nvdevice.h"
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() {
int status{};
size_t length{};
auto mangledName{typeid(*this).name()};
std::unique_ptr<char, decltype(&std::free)> demangled{ abi::__cxa_demangle(mangledName, nullptr, &length, &status), std::free};
return (status == 0) ? std::string(demangled.get() + std::char_traits<char>::length("skyline::service::nvdrv::device")) : mangledName;
}
void NvDevice::HandleIoctl(u32 cmd, IoctlData &input) {
std::function<void(IoctlData &)> function;
try {
function = vTable.at(cmd);
} catch (std::out_of_range &) {
state.logger->Warn("Cannot find IOCTL for device '{}': 0x{:X}", GetName(), cmd);
input.status = NvStatus::NotImplemented;
return;
}
try {
function(input);
} catch (std::exception &e) {
throw exception("{} (Device: {})", e.what(), GetName());
}
}
}

View File

@ -3,6 +3,7 @@
#pragma once
#include <cxxabi.h>
#include <common.h>
#include <kernel/ipc.h>
#include <kernel/types/KEvent.h>
@ -12,54 +13,6 @@
namespace skyline::service::nvdrv::device {
using namespace kernel;
/**
* @brief An enumeration of all the devices that can be opened by nvdrv
*/
enum class NvDeviceType {
nvhost_ctrl, //!< https://switchbrew.org/wiki/NV_services#.2Fdev.2Fnvhost-ctrl
nvhost_gpu, //!< https://switchbrew.org/wiki/NV_services#Channels
nvhost_nvdec, //!< https://switchbrew.org/wiki/NV_services#Channels
nvhost_vic, //!< https://switchbrew.org/wiki/NV_services#Channels
nvmap, //!< https://switchbrew.org/wiki/NV_services#.2Fdev.2Fnvmap
nvdisp_ctrl, //!< https://switchbrew.org/wiki/NV_services#.2Fdev.2Fnvdisp-ctrl
nvdisp_disp0, //!< https://switchbrew.org/wiki/NV_services#.2Fdev.2Fnvdisp-disp0.2C_.2Fdev.2Fnvdisp-disp1
nvdisp_disp1, //!< https://switchbrew.org/wiki/NV_services#.2Fdev.2Fnvdisp-disp0.2C_.2Fdev.2Fnvdisp-disp1
nvcec_ctrl, //!< https://switchbrew.org/wiki/NV_services#.2Fdev.2Fnvcec-ctrl
nvhdcp_up_ctrl, //!< https://switchbrew.org/wiki/NV_services#.2Fdev.2Fnvhdcp_up-ctrl
nvdcutil_disp0, //!< https://switchbrew.org/wiki/NV_services#.2Fdev.2Fnvdcutil-disp0.2C_.2Fdev.2Fnvdcutil-disp1
nvdcutil_disp1, //!< https://switchbrew.org/wiki/NV_services#.2Fdev.2Fnvdcutil-disp0.2C_.2Fdev.2Fnvdcutil-disp1
nvsched_ctrl, //!< https://switchbrew.org/wiki/NV_services#.2Fdev.2Fnvsched-ctrl
nverpt_ctrl, //!< https://switchbrew.org/wiki/NV_services#.2Fdev.2Fnverpt-ctrl
nvhost_as_gpu, //!< https://switchbrew.org/wiki/NV_services#.2Fdev.2Fnvhost-as-gpu
nvhost_dbg_gpu, //!< https://switchbrew.org/wiki/NV_services#.2Fdev.2Fnvhost-dbg-gpu
nvhost_prof_gpu, //!< https://switchbrew.org/wiki/NV_services#.2Fdev.2Fnvhost-prof-gpu
nvhost_ctrl_gpu //!< https://switchbrew.org/wiki/NV_services#.2Fdev.2Fnvhost-ctrl-gpu
};
/**
* @brief A mapping from a device's path to it's nvDevice entry
*/
const static std::unordered_map<std::string, NvDeviceType> nvDeviceMap{
{"/dev/nvhost-ctrl", NvDeviceType::nvhost_ctrl},
{"/dev/nvhost-gpu", NvDeviceType::nvhost_gpu},
{"/dev/nvhost-nvdec", NvDeviceType::nvhost_nvdec},
{"/dev/nvhost-vic", NvDeviceType::nvhost_vic},
{"/dev/nvmap", NvDeviceType::nvmap},
{"/dev/nvdisp-ctrl", NvDeviceType::nvdisp_ctrl},
{"/dev/nvdisp-disp0", NvDeviceType::nvdisp_disp0},
{"/dev/nvdisp-disp1", NvDeviceType::nvdisp_disp1},
{"/dev/nvcec-ctrl", NvDeviceType::nvcec_ctrl},
{"/dev/nvhdcp_up-ctrl", NvDeviceType::nvhdcp_up_ctrl},
{"/dev/nvdcutil-disp0", NvDeviceType::nvdcutil_disp0},
{"/dev/nvdcutil-disp1", NvDeviceType::nvdcutil_disp1},
{"/dev/nvsched-ctrl", NvDeviceType::nvsched_ctrl},
{"/dev/nverpt-ctrl", NvDeviceType::nverpt_ctrl},
{"/dev/nvhost-as-gpu", NvDeviceType::nvhost_as_gpu},
{"/dev/nvhost-dbg-gpu", NvDeviceType::nvhost_dbg_gpu},
{"/dev/nvhost-prof-gpu", NvDeviceType::nvhost_prof_gpu},
{"/dev/nvhost-ctrl-gpu", NvDeviceType::nvhost_ctrl_gpu},
};
/**
* @brief This enumerates all the possible error codes returned by the Nvidia driver (https://switchbrew.org/wiki/NV_services#Errors)
*/
@ -134,7 +87,7 @@ namespace skyline::service::nvdrv::device {
};
/**
* @brief NvDevice is the base class all /dev/nv* devices inherit from
* @brief NvDevice is the base class that all /dev/nv* devices inherit from
*/
class NvDevice {
protected:
@ -142,53 +95,27 @@ namespace skyline::service::nvdrv::device {
std::unordered_map<u32, std::function<void(IoctlData &)>> vTable; //!< This holds the mapping from an Ioctl to the actual function
public:
u16 refCount{1}; //!< The amount of handles to the device
NvDeviceType deviceType; //!< The type of the device
/**
* @param state The state of the device
* @param deviceType The type of the device
* @param vTable The functions in this device
*/
NvDevice(const DeviceState &state, NvDeviceType deviceType, std::unordered_map<u32, std::function<void(IoctlData &)>> vTable) : state(state), deviceType(deviceType), vTable(vTable) {}
NvDevice(const DeviceState &state, std::unordered_map<u32, std::function<void(IoctlData & )>> vTable);
virtual ~NvDevice() = default;
/**
* @brief This returns the name of the current service
* @note It may not return the exact name the service was initialized with if there are multiple entries in ServiceString
* @return The name of the service
* @return The name of the class
*/
std::string getName() {
std::string serviceName;
for (const auto&[name, type] : nvDeviceMap)
if (type == deviceType)
serviceName = name;
return serviceName;
}
std::string GetName();
/**
* @brief This handles IOCTL calls for devices
* @param cmd The IOCTL command that was called
* @param input The input to the IOCTL call
*/
void HandleIoctl(u32 cmd, IoctlData &input) {
std::function<void(IoctlData &)> function;
try {
function = vTable.at(cmd);
} catch (std::out_of_range &) {
state.logger->Warn("Cannot find IOCTL for device '{}': 0x{:X}", getName(), cmd);
input.status = NvStatus::NotImplemented;
return;
}
try {
function(input);
} catch (std::exception &e) {
throw exception("{} (Device: {})", e.what(), getName());
}
}
void HandleIoctl(u32 cmd, IoctlData &input);
virtual std::shared_ptr<kernel::type::KEvent> QueryEvent(u32 eventId) {
inline virtual std::shared_ptr<kernel::type::KEvent> QueryEvent(u32 eventId) {
return nullptr;
}
};

View File

@ -9,7 +9,7 @@
#include "nvhost_as_gpu.h"
namespace skyline::service::nvdrv::device {
NvHostAsGpu::NvHostAsGpu(const DeviceState &state) : NvDevice(state, NvDeviceType::nvhost_as_gpu, {
NvHostAsGpu::NvHostAsGpu(const DeviceState &state) : NvDevice(state, {
{0x4101, NFUNC(NvHostAsGpu::BindChannel)},
{0x4102, NFUNC(NvHostAsGpu::AllocSpace)},
{0x4105, NFUNC(NvHostAsGpu::UnmapBuffer)},
@ -71,10 +71,11 @@ namespace skyline::service::nvdrv::device {
return;
auto driver = nvdrv::driver.lock();
auto nvmap = driver->GetDevice<nvdrv::device::NvMap>(nvdrv::device::NvDeviceType::nvmap)->handleTable.at(region.nvmapHandle);
auto nvmap = driver->nvMap.lock();
auto mapping = nvmap->handleTable.at(region.nvmapHandle);
u64 mapPhysicalAddress = region.bufferOffset + nvmap->address;
u64 mapSize = region.mappingSize ? region.mappingSize : nvmap->size;
u64 mapPhysicalAddress = region.bufferOffset + mapping->address;
u64 mapSize = region.mappingSize ? region.mappingSize : mapping->size;
if (region.flags & 1)
region.offset = state.gpu->memoryManager.MapFixed(region.offset, mapPhysicalAddress, mapSize);
@ -135,10 +136,11 @@ namespace skyline::service::nvdrv::device {
for (auto entry : entries) {
try {
auto driver = nvdrv::driver.lock();
auto nvmap = driver->GetDevice<nvdrv::device::NvMap>(nvdrv::device::NvDeviceType::nvmap)->handleTable.at(entry.nvmapHandle);
auto nvmap = driver->nvMap.lock();
auto mapping = nvmap->handleTable.at(entry.nvmapHandle);
u64 mapAddress = static_cast<u64>(entry.gpuOffset) << MinAlignmentShift;
u64 mapPhysicalAddress = nvmap->address + (static_cast<u64>(entry.mapOffset) << MinAlignmentShift);
u64 mapPhysicalAddress = mapping->address + (static_cast<u64>(entry.mapOffset) << MinAlignmentShift);
u64 mapSize = static_cast<u64>(entry.pages) << MinAlignmentShift;
state.gpu->memoryManager.MapFixed(mapAddress, mapPhysicalAddress, mapSize);

View File

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

View File

@ -25,7 +25,7 @@ namespace skyline::service::nvdrv::device {
std::shared_ptr<type::KEvent> errorNotifierEvent;
public:
NvHostChannel(const DeviceState &state, NvDeviceType type);
NvHostChannel(const DeviceState &state);
/**
* @brief This sets the nvmap file descriptor (https://switchbrew.org/wiki/NV_services#NVGPU_IOCTL_CHANNEL_SET_NVMAP_FD)

View File

@ -37,7 +37,7 @@ namespace skyline::service::nvdrv::device {
}
}
NvHostCtrl::NvHostCtrl(const DeviceState &state) : NvDevice(state, NvDeviceType::nvhost_ctrl, {
NvHostCtrl::NvHostCtrl(const DeviceState &state) : NvDevice(state, {
{0x001B, NFUNC(NvHostCtrl::GetConfig)},
{0x001C, NFUNC(NvHostCtrl::EventSignal)},
{0x001D, NFUNC(NvHostCtrl::EventWait)},

View File

@ -5,7 +5,7 @@
#include "nvhost_ctrl_gpu.h"
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, NvDeviceType::nvhost_ctrl_gpu, {
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)},

View File

@ -7,7 +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, NvDeviceType::nvmap, {
NvMap::NvMap(const DeviceState &state) : NvDevice(state, {
{0x0101, NFUNC(NvMap::Create)},
{0x0103, NFUNC(NvMap::FromId)},
{0x0104, NFUNC(NvMap::Alloc)},

View File

@ -13,56 +13,45 @@ namespace skyline::service::nvdrv {
u32 Driver::OpenDevice(const std::string &path) {
state.logger->Debug("Opening NVDRV device ({}): {}", fdIndex, path);
auto type = device::nvDeviceMap.at(path);
for (const auto &device : fdMap) {
if (device.second->deviceType == type) {
device.second->refCount++;
fdMap[fdIndex] = device.second;
return fdIndex++;
}
}
std::shared_ptr<device::NvDevice> object;
switch (type) {
case device::NvDeviceType::nvhost_ctrl:
object = std::make_shared<device::NvHostCtrl>(state);
break;
case device::NvDeviceType::nvhost_gpu:
case device::NvDeviceType::nvhost_vic:
case device::NvDeviceType::nvhost_nvdec:
object = std::make_shared<device::NvHostChannel>(state, type);
break;
case device::NvDeviceType::nvhost_ctrl_gpu:
object = std::make_shared<device::NvHostCtrlGpu>(state);
break;
case device::NvDeviceType::nvmap:
object = std::make_shared<device::NvMap>(state);
break;
case device::NvDeviceType::nvhost_as_gpu:
object = std::make_shared<device::NvHostAsGpu>(state);
break;
switch (util::Hash(path)) {
#define NVDEVICE(type, name, devicePath) \
case util::Hash(devicePath): { \
std::shared_ptr<device::type> device{}; \
if (name.expired()) { \
device = device.make_shared(state); \
name = device; \
} else { \
device = name.lock(); \
} \
devices.push_back(device); \
break; \
}
NVDEVICE_LIST
#undef NVDEVICE
default:
throw exception("Cannot find NVDRV device");
}
deviceMap[type] = object;
fdMap[fdIndex] = object;
return fdIndex++;
}
void Driver::CloseDevice(skyline::u32 fd) {
std::shared_ptr<device::NvDevice> Driver::GetDevice(u32 fd) {
try {
auto& device = fdMap.at(fd);
if (!--device->refCount)
deviceMap.erase(device->deviceType);
auto item = devices.at(fd);
if (!item)
throw exception("GetDevice was called with a closed file descriptor: 0x{:X}", fd);
return item;
} catch (std::out_of_range) {
throw exception("GetDevice was called with invalid file descriptor: 0x{:X}", fd);
}
}
fdMap.erase(fd);
void Driver::CloseDevice(u32 fd) {
try {
auto &device = devices.at(fd);
device.reset();
} catch (const std::out_of_range &) {
state.logger->Warn("Trying to close non-existent FD");
}

View File

@ -5,10 +5,22 @@
#include "devices/nvhost_syncpoint.h"
#define NVDEVICE_LIST \
NVDEVICE(NvHostCtrl, nvHostCtrl, "/dev/nvhost-ctrl") \
NVDEVICE(NvHostChannel, nvHostGpu, "/dev/nvhost-gpu") \
NVDEVICE(NvHostChannel, nvHostNvdec, "/dev/nvhost-nvdec") \
NVDEVICE(NvHostChannel, nvHostVic, "/dev/nvhost-vic") \
NVDEVICE(NvMap, nvMap, "/dev/nvmap") \
NVDEVICE(NvHostAsGpu, nvHostAsGpu, "/dev/nvhost-as-gpu") \
NVDEVICE(NvHostCtrlGpu, nvHostCtrlGpu, "/dev/nvhost-ctrl-gpu")
namespace skyline::service::nvdrv {
namespace device {
class NvDevice;
enum class NvDeviceType;
#define NVDEVICE(type, name, path) class type;
NVDEVICE_LIST
#undef NVDEVICE
}
/**
@ -17,13 +29,16 @@ namespace skyline::service::nvdrv {
class Driver {
private:
const DeviceState &state;
std::unordered_map<device::NvDeviceType, std::shared_ptr<device::NvDevice>> deviceMap; //!< A map from a NvDeviceType to the NvDevice object
std::unordered_map<u32, std::shared_ptr<device::NvDevice>> fdMap; //!< A map from an FD to a shared pointer to it's NvDevice object
std::vector<std::shared_ptr<device::NvDevice>> devices; //!< A map from an FD to a shared pointer to it's NvDevice object
u32 fdIndex{}; //!< The index of a file descriptor
public:
NvHostSyncpoint hostSyncpoint;
#define NVDEVICE(type, name, path) std::weak_ptr<device::type> name;
NVDEVICE_LIST
#undef NVDEVICE
Driver(const DeviceState &state);
/**
@ -34,9 +49,11 @@ namespace skyline::service::nvdrv {
u32 OpenDevice(const std::string &path);
/**
* @brief Closes the specified device with it's file descriptor
* @brief Returns a particular device with a specific FD
* @param fd The file descriptor to retrieve
* @return A shared pointer to the device
*/
void CloseDevice(u32 fd);
std::shared_ptr<device::NvDevice> GetDevice(u32 fd);
/**
* @brief Returns a particular device with a specific FD
@ -44,31 +61,15 @@ namespace skyline::service::nvdrv {
* @param fd The file descriptor to retrieve
* @return A shared pointer to the device
*/
template<typename objectClass = device::NvDevice>
std::shared_ptr<objectClass> GetDevice(u32 fd) {
try {
auto item = fdMap.at(fd);
return std::static_pointer_cast<objectClass>(item);
} catch (std::out_of_range) {
throw exception("GetDevice was called with invalid file descriptor: 0x{:X}", fd);
}
template<typename objectClass>
inline std::shared_ptr<objectClass> GetDevice(u32 fd) {
return std::static_pointer_cast<objectClass>(GetDevice(fd));
}
/**
* @brief Returns a particular device with a specific type
* @tparam objectClass The class of the device to return
* @param type The type of the device to return
* @return A shared pointer to the device
* @brief Closes the specified device with it's file descriptor
*/
template<typename objectClass = device::NvDevice>
std::shared_ptr<objectClass> GetDevice(device::NvDeviceType type) {
try {
auto item = deviceMap.at(type);
return std::static_pointer_cast<objectClass>(item);
} catch (std::out_of_range) {
throw exception("GetDevice was called with invalid type: 0x{:X}", type);
}
}
void CloseDevice(u32 fd);
};
extern std::weak_ptr<Driver> driver; //!< A globally shared instance of the Driver