mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 15:31:52 +01:00
Improve NvDevice Registration + Access
This commit is contained in:
parent
4cc3a3b2e8
commit
20253a9573
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -14,3 +14,6 @@
|
|||||||
[submodule "app/libraries/lz4"]
|
[submodule "app/libraries/lz4"]
|
||||||
path = app/libraries/lz4
|
path = app/libraries/lz4
|
||||||
url = https://github.com/lz4/lz4.git
|
url = https://github.com/lz4/lz4.git
|
||||||
|
[submodule "app/libraries/frozen"]
|
||||||
|
path = app/libraries/frozen
|
||||||
|
url = https://github.com/serge-sans-paille/frozen
|
||||||
|
16
.idea/codeStyles/Project.xml
generated
16
.idea/codeStyles/Project.xml
generated
@ -7,6 +7,22 @@
|
|||||||
<option name="FORMATTER_OFF_TAG" value="@fmt:off" />
|
<option name="FORMATTER_OFF_TAG" value="@fmt:off" />
|
||||||
<option name="SOFT_MARGINS" value="80,140" />
|
<option name="SOFT_MARGINS" value="80,140" />
|
||||||
<JetCodeStyleSettings>
|
<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" />
|
<option name="SPACE_BEFORE_TYPE_COLON" value="true" />
|
||||||
</JetCodeStyleSettings>
|
</JetCodeStyleSettings>
|
||||||
<Objective-C>
|
<Objective-C>
|
||||||
|
1
.idea/vcs.xml
generated
1
.idea/vcs.xml
generated
@ -3,6 +3,7 @@
|
|||||||
<component name="VcsDirectoryMappings">
|
<component name="VcsDirectoryMappings">
|
||||||
<mapping directory="" vcs="Git" />
|
<mapping directory="" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/app/libraries/fmt" 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/lz4" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/app/libraries/oboe" 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/tinyxml2" vcs="Git" />
|
||||||
|
@ -22,6 +22,7 @@ add_subdirectory("libraries/lz4/contrib/cmake_unofficial")
|
|||||||
include_directories("libraries/lz4/lib")
|
include_directories("libraries/lz4/lib")
|
||||||
include_directories("libraries/oboe/include")
|
include_directories("libraries/oboe/include")
|
||||||
include_directories("libraries/vkhpp/include")
|
include_directories("libraries/vkhpp/include")
|
||||||
|
include_directories("libraries/frozen/include")
|
||||||
set(CMAKE_POLICY_DEFAULT_CMP0048 NEW)
|
set(CMAKE_POLICY_DEFAULT_CMP0048 NEW)
|
||||||
|
|
||||||
find_package(mbedtls REQUIRED CONFIG)
|
find_package(mbedtls REQUIRED CONFIG)
|
||||||
@ -114,6 +115,7 @@ add_library(skyline SHARED
|
|||||||
${source_DIR}/skyline/services/fssrv/IStorage.cpp
|
${source_DIR}/skyline/services/fssrv/IStorage.cpp
|
||||||
${source_DIR}/skyline/services/nvdrv/INvDrvServices.cpp
|
${source_DIR}/skyline/services/nvdrv/INvDrvServices.cpp
|
||||||
${source_DIR}/skyline/services/nvdrv/driver.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/nvmap.cpp
|
||||||
${source_DIR}/skyline/services/nvdrv/devices/nvhost_ctrl_gpu.cpp
|
${source_DIR}/skyline/services/nvdrv/devices/nvhost_ctrl_gpu.cpp
|
||||||
${source_DIR}/skyline/services/nvdrv/devices/nvhost_ctrl.cpp
|
${source_DIR}/skyline/services/nvdrv/devices/nvhost_ctrl.cpp
|
||||||
|
@ -4,11 +4,11 @@ apply plugin: 'kotlin-android-extensions'
|
|||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 30
|
compileSdkVersion 30
|
||||||
buildToolsVersion '30.0.0'
|
buildToolsVersion '30.0.2'
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "skyline.emu"
|
applicationId "skyline.emu"
|
||||||
minSdkVersion 26
|
minSdkVersion 26
|
||||||
targetSdkVersion 29
|
targetSdkVersion 30
|
||||||
versionCode 3
|
versionCode 3
|
||||||
versionName "0.3"
|
versionName "0.3"
|
||||||
ndk {
|
ndk {
|
||||||
@ -59,7 +59,7 @@ android {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
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 'androidx.preference:preference:1.1.1'
|
||||||
implementation 'com.google.android.material:material:1.3.0-alpha02'
|
implementation 'com.google.android.material:material:1.3.0-alpha02'
|
||||||
implementation "androidx.core:core-ktx:1.3.1"
|
implementation "androidx.core:core-ktx:1.3.1"
|
||||||
|
1
app/libraries/frozen
Submodule
1
app/libraries/frozen
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 30b475274c044f456c37b6d15de3d04c85112698
|
@ -8,21 +8,24 @@
|
|||||||
#include <span>
|
#include <span>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <syslog.h>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
|
||||||
#include <memory>
|
|
||||||
#include <fmt/format.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#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 <jni.h>
|
||||||
#include "nce/guest_common.h"
|
#include "nce/guest_common.h"
|
||||||
|
|
||||||
namespace skyline {
|
namespace skyline {
|
||||||
|
namespace frz = frozen;
|
||||||
using KHandle = u32; //!< The type of a kernel handle
|
using KHandle = u32; //!< The type of a kernel handle
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -194,6 +197,10 @@ namespace skyline {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr std::size_t Hash(const std::string_view& view) {
|
||||||
|
return frz::elsa<frz::string>{}(frz::string(view.data(), view.size()), 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -124,7 +124,7 @@ namespace skyline::service::hosbinder {
|
|||||||
std::shared_ptr<nvdrv::device::NvMap::NvMapObject> nvBuffer{};
|
std::shared_ptr<nvdrv::device::NvMap::NvMapObject> nvBuffer{};
|
||||||
|
|
||||||
auto driver = nvdrv::driver.lock();
|
auto driver = nvdrv::driver.lock();
|
||||||
auto nvmap = driver->GetDevice<nvdrv::device::NvMap>(nvdrv::device::NvDeviceType::nvmap);
|
auto nvmap = driver->nvMap.lock();
|
||||||
|
|
||||||
if (gbpBuffer.nvmapHandle) {
|
if (gbpBuffer.nvmapHandle) {
|
||||||
nvBuffer = nvmap->handleTable.at(gbpBuffer.nvmapHandle);
|
nvBuffer = nvmap->handleTable.at(gbpBuffer.nvmapHandle);
|
||||||
|
34
app/src/main/cpp/skyline/services/nvdrv/devices/nvdevice.cpp
Normal file
34
app/src/main/cpp/skyline/services/nvdrv/devices/nvdevice.cpp
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cxxabi.h>
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <kernel/ipc.h>
|
#include <kernel/ipc.h>
|
||||||
#include <kernel/types/KEvent.h>
|
#include <kernel/types/KEvent.h>
|
||||||
@ -12,54 +13,6 @@
|
|||||||
namespace skyline::service::nvdrv::device {
|
namespace skyline::service::nvdrv::device {
|
||||||
using namespace kernel;
|
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)
|
* @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 {
|
class NvDevice {
|
||||||
protected:
|
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
|
std::unordered_map<u32, std::function<void(IoctlData &)>> vTable; //!< This holds the mapping from an Ioctl to the actual function
|
||||||
|
|
||||||
public:
|
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 state The state of the device
|
||||||
* @param deviceType The type of the device
|
|
||||||
* @param vTable The functions in this 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;
|
virtual ~NvDevice() = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This returns the name of the current service
|
* @return The name of the class
|
||||||
* @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
|
|
||||||
*/
|
*/
|
||||||
std::string getName() {
|
std::string GetName();
|
||||||
std::string serviceName;
|
|
||||||
for (const auto&[name, type] : nvDeviceMap)
|
|
||||||
if (type == deviceType)
|
|
||||||
serviceName = name;
|
|
||||||
return serviceName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This handles IOCTL calls for devices
|
* @brief This handles IOCTL calls for devices
|
||||||
* @param cmd The IOCTL command that was called
|
* @param cmd The IOCTL command that was called
|
||||||
* @param input The input to the IOCTL call
|
* @param input The input to the IOCTL call
|
||||||
*/
|
*/
|
||||||
void HandleIoctl(u32 cmd, IoctlData &input) {
|
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual std::shared_ptr<kernel::type::KEvent> QueryEvent(u32 eventId) {
|
inline virtual std::shared_ptr<kernel::type::KEvent> QueryEvent(u32 eventId) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -9,7 +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, NvDeviceType::nvhost_as_gpu, {
|
NvHostAsGpu::NvHostAsGpu(const DeviceState &state) : NvDevice(state, {
|
||||||
{0x4101, NFUNC(NvHostAsGpu::BindChannel)},
|
{0x4101, NFUNC(NvHostAsGpu::BindChannel)},
|
||||||
{0x4102, NFUNC(NvHostAsGpu::AllocSpace)},
|
{0x4102, NFUNC(NvHostAsGpu::AllocSpace)},
|
||||||
{0x4105, NFUNC(NvHostAsGpu::UnmapBuffer)},
|
{0x4105, NFUNC(NvHostAsGpu::UnmapBuffer)},
|
||||||
@ -71,10 +71,11 @@ namespace skyline::service::nvdrv::device {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
auto driver = nvdrv::driver.lock();
|
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 mapPhysicalAddress = region.bufferOffset + mapping->address;
|
||||||
u64 mapSize = region.mappingSize ? region.mappingSize : nvmap->size;
|
u64 mapSize = region.mappingSize ? region.mappingSize : mapping->size;
|
||||||
|
|
||||||
if (region.flags & 1)
|
if (region.flags & 1)
|
||||||
region.offset = state.gpu->memoryManager.MapFixed(region.offset, mapPhysicalAddress, mapSize);
|
region.offset = state.gpu->memoryManager.MapFixed(region.offset, mapPhysicalAddress, mapSize);
|
||||||
@ -135,10 +136,11 @@ namespace skyline::service::nvdrv::device {
|
|||||||
for (auto entry : entries) {
|
for (auto entry : entries) {
|
||||||
try {
|
try {
|
||||||
auto driver = nvdrv::driver.lock();
|
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 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;
|
u64 mapSize = static_cast<u64>(entry.pages) << MinAlignmentShift;
|
||||||
|
|
||||||
state.gpu->memoryManager.MapFixed(mapAddress, mapPhysicalAddress, mapSize);
|
state.gpu->memoryManager.MapFixed(mapAddress, mapPhysicalAddress, mapSize);
|
||||||
|
@ -8,7 +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, 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)},
|
{0x4801, NFUNC(NvHostChannel::SetNvmapFd)},
|
||||||
{0x4803, NFUNC(NvHostChannel::SetSubmitTimeout)},
|
{0x4803, NFUNC(NvHostChannel::SetSubmitTimeout)},
|
||||||
{0x4808, NFUNC(NvHostChannel::SubmitGpfifo)},
|
{0x4808, NFUNC(NvHostChannel::SubmitGpfifo)},
|
||||||
|
@ -25,7 +25,7 @@ namespace skyline::service::nvdrv::device {
|
|||||||
std::shared_ptr<type::KEvent> errorNotifierEvent;
|
std::shared_ptr<type::KEvent> errorNotifierEvent;
|
||||||
|
|
||||||
public:
|
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)
|
* @brief This sets the nvmap file descriptor (https://switchbrew.org/wiki/NV_services#NVGPU_IOCTL_CHANNEL_SET_NVMAP_FD)
|
||||||
|
@ -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)},
|
{0x001B, NFUNC(NvHostCtrl::GetConfig)},
|
||||||
{0x001C, NFUNC(NvHostCtrl::EventSignal)},
|
{0x001C, NFUNC(NvHostCtrl::EventSignal)},
|
||||||
{0x001D, NFUNC(NvHostCtrl::EventWait)},
|
{0x001D, NFUNC(NvHostCtrl::EventWait)},
|
||||||
|
@ -5,7 +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, 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)},
|
{0x4701, NFUNC(NvHostCtrlGpu::ZCullGetCtxSize)},
|
||||||
{0x4702, NFUNC(NvHostCtrlGpu::ZCullGetInfo)},
|
{0x4702, NFUNC(NvHostCtrlGpu::ZCullGetInfo)},
|
||||||
{0x4706, NFUNC(NvHostCtrlGpu::GetTpcMasks)},
|
{0x4706, NFUNC(NvHostCtrlGpu::GetTpcMasks)},
|
||||||
|
@ -7,7 +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, NvDeviceType::nvmap, {
|
NvMap::NvMap(const DeviceState &state) : NvDevice(state, {
|
||||||
{0x0101, NFUNC(NvMap::Create)},
|
{0x0101, NFUNC(NvMap::Create)},
|
||||||
{0x0103, NFUNC(NvMap::FromId)},
|
{0x0103, NFUNC(NvMap::FromId)},
|
||||||
{0x0104, NFUNC(NvMap::Alloc)},
|
{0x0104, NFUNC(NvMap::Alloc)},
|
||||||
|
@ -13,56 +13,45 @@ namespace skyline::service::nvdrv {
|
|||||||
|
|
||||||
u32 Driver::OpenDevice(const std::string &path) {
|
u32 Driver::OpenDevice(const std::string &path) {
|
||||||
state.logger->Debug("Opening NVDRV device ({}): {}", fdIndex, path);
|
state.logger->Debug("Opening NVDRV device ({}): {}", fdIndex, path);
|
||||||
auto type = device::nvDeviceMap.at(path);
|
|
||||||
for (const auto &device : fdMap) {
|
switch (util::Hash(path)) {
|
||||||
if (device.second->deviceType == type) {
|
#define NVDEVICE(type, name, devicePath) \
|
||||||
device.second->refCount++;
|
case util::Hash(devicePath): { \
|
||||||
fdMap[fdIndex] = device.second;
|
std::shared_ptr<device::type> device{}; \
|
||||||
return fdIndex++;
|
if (name.expired()) { \
|
||||||
|
device = device.make_shared(state); \
|
||||||
|
name = device; \
|
||||||
|
} else { \
|
||||||
|
device = name.lock(); \
|
||||||
|
} \
|
||||||
|
devices.push_back(device); \
|
||||||
|
break; \
|
||||||
}
|
}
|
||||||
}
|
NVDEVICE_LIST
|
||||||
|
#undef NVDEVICE
|
||||||
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;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw exception("Cannot find NVDRV device");
|
throw exception("Cannot find NVDRV device");
|
||||||
}
|
}
|
||||||
|
|
||||||
deviceMap[type] = object;
|
|
||||||
fdMap[fdIndex] = object;
|
|
||||||
|
|
||||||
return fdIndex++;
|
return fdIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Driver::CloseDevice(skyline::u32 fd) {
|
std::shared_ptr<device::NvDevice> Driver::GetDevice(u32 fd) {
|
||||||
try {
|
try {
|
||||||
auto& device = fdMap.at(fd);
|
auto item = devices.at(fd);
|
||||||
if (!--device->refCount)
|
if (!item)
|
||||||
deviceMap.erase(device->deviceType);
|
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 &) {
|
} catch (const std::out_of_range &) {
|
||||||
state.logger->Warn("Trying to close non-existent FD");
|
state.logger->Warn("Trying to close non-existent FD");
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,22 @@
|
|||||||
|
|
||||||
#include "devices/nvhost_syncpoint.h"
|
#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 skyline::service::nvdrv {
|
||||||
namespace device {
|
namespace device {
|
||||||
class NvDevice;
|
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 {
|
class Driver {
|
||||||
private:
|
private:
|
||||||
const DeviceState &state;
|
const DeviceState &state;
|
||||||
std::unordered_map<device::NvDeviceType, std::shared_ptr<device::NvDevice>> deviceMap; //!< A map from a NvDeviceType to the NvDevice object
|
std::vector<std::shared_ptr<device::NvDevice>> devices; //!< A map from an FD to a shared pointer to it's 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
|
|
||||||
u32 fdIndex{}; //!< The index of a file descriptor
|
u32 fdIndex{}; //!< The index of a file descriptor
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NvHostSyncpoint hostSyncpoint;
|
NvHostSyncpoint hostSyncpoint;
|
||||||
|
|
||||||
|
#define NVDEVICE(type, name, path) std::weak_ptr<device::type> name;
|
||||||
|
NVDEVICE_LIST
|
||||||
|
#undef NVDEVICE
|
||||||
|
|
||||||
Driver(const DeviceState &state);
|
Driver(const DeviceState &state);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -34,9 +49,11 @@ namespace skyline::service::nvdrv {
|
|||||||
u32 OpenDevice(const std::string &path);
|
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
|
* @brief Returns a particular device with a specific FD
|
||||||
@ -44,31 +61,15 @@ namespace skyline::service::nvdrv {
|
|||||||
* @param fd The file descriptor to retrieve
|
* @param fd The file descriptor to retrieve
|
||||||
* @return A shared pointer to the device
|
* @return A shared pointer to the device
|
||||||
*/
|
*/
|
||||||
template<typename objectClass = device::NvDevice>
|
template<typename objectClass>
|
||||||
std::shared_ptr<objectClass> GetDevice(u32 fd) {
|
inline std::shared_ptr<objectClass> GetDevice(u32 fd) {
|
||||||
try {
|
return std::static_pointer_cast<objectClass>(GetDevice(fd));
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns a particular device with a specific type
|
* @brief Closes the specified device with it's file descriptor
|
||||||
* @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
|
|
||||||
*/
|
*/
|
||||||
template<typename objectClass = device::NvDevice>
|
void CloseDevice(u32 fd);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern std::weak_ptr<Driver> driver; //!< A globally shared instance of the Driver
|
extern std::weak_ptr<Driver> driver; //!< A globally shared instance of the Driver
|
||||||
|
Loading…
Reference in New Issue
Block a user