|
|
@ -11,6 +11,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
namespace Service::Nvidia::Devices {
|
|
|
|
namespace Service::Nvidia::Devices {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace NvErrCodes {
|
|
|
|
|
|
|
|
enum {
|
|
|
|
|
|
|
|
OperationNotPermitted = -1,
|
|
|
|
|
|
|
|
InvalidValue = -22,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nvmap::nvmap() = default;
|
|
|
|
nvmap::nvmap() = default;
|
|
|
|
nvmap::~nvmap() = default;
|
|
|
|
nvmap::~nvmap() = default;
|
|
|
|
|
|
|
|
|
|
|
@ -44,7 +51,11 @@ u32 nvmap::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& o
|
|
|
|
u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) {
|
|
|
|
u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) {
|
|
|
|
IocCreateParams params;
|
|
|
|
IocCreateParams params;
|
|
|
|
std::memcpy(¶ms, input.data(), sizeof(params));
|
|
|
|
std::memcpy(¶ms, input.data(), sizeof(params));
|
|
|
|
|
|
|
|
LOG_DEBUG(Service_NVDRV, "size=0x{:08X}", params.size);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!params.size) {
|
|
|
|
|
|
|
|
return static_cast<u32>(NvErrCodes::InvalidValue);
|
|
|
|
|
|
|
|
}
|
|
|
|
// Create a new nvmap object and obtain a handle to it.
|
|
|
|
// Create a new nvmap object and obtain a handle to it.
|
|
|
|
auto object = std::make_shared<Object>();
|
|
|
|
auto object = std::make_shared<Object>();
|
|
|
|
object->id = next_id++;
|
|
|
|
object->id = next_id++;
|
|
|
@ -55,8 +66,6 @@ u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) {
|
|
|
|
u32 handle = next_handle++;
|
|
|
|
u32 handle = next_handle++;
|
|
|
|
handles[handle] = std::move(object);
|
|
|
|
handles[handle] = std::move(object);
|
|
|
|
|
|
|
|
|
|
|
|
LOG_DEBUG(Service_NVDRV, "size=0x{:08X}", params.size);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
params.handle = handle;
|
|
|
|
params.handle = handle;
|
|
|
|
|
|
|
|
|
|
|
|
std::memcpy(output.data(), ¶ms, sizeof(params));
|
|
|
|
std::memcpy(output.data(), ¶ms, sizeof(params));
|
|
|
@ -66,9 +75,29 @@ u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) {
|
|
|
|
u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) {
|
|
|
|
u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) {
|
|
|
|
IocAllocParams params;
|
|
|
|
IocAllocParams params;
|
|
|
|
std::memcpy(¶ms, input.data(), sizeof(params));
|
|
|
|
std::memcpy(¶ms, input.data(), sizeof(params));
|
|
|
|
|
|
|
|
LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.addr);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!params.handle) {
|
|
|
|
|
|
|
|
return static_cast<u32>(NvErrCodes::InvalidValue);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((params.align - 1) & params.align) {
|
|
|
|
|
|
|
|
return static_cast<u32>(NvErrCodes::InvalidValue);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const u32 min_alignment = 0x1000;
|
|
|
|
|
|
|
|
if (params.align < min_alignment) {
|
|
|
|
|
|
|
|
params.align = min_alignment;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
auto object = GetObject(params.handle);
|
|
|
|
auto object = GetObject(params.handle);
|
|
|
|
ASSERT(object);
|
|
|
|
if (!object) {
|
|
|
|
|
|
|
|
return static_cast<u32>(NvErrCodes::InvalidValue);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (object->status == Object::Status::Allocated) {
|
|
|
|
|
|
|
|
return static_cast<u32>(NvErrCodes::OperationNotPermitted);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
object->flags = params.flags;
|
|
|
|
object->flags = params.flags;
|
|
|
|
object->align = params.align;
|
|
|
|
object->align = params.align;
|
|
|
@ -76,8 +105,6 @@ u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) {
|
|
|
|
object->addr = params.addr;
|
|
|
|
object->addr = params.addr;
|
|
|
|
object->status = Object::Status::Allocated;
|
|
|
|
object->status = Object::Status::Allocated;
|
|
|
|
|
|
|
|
|
|
|
|
LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.addr);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::memcpy(output.data(), ¶ms, sizeof(params));
|
|
|
|
std::memcpy(output.data(), ¶ms, sizeof(params));
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -88,8 +115,14 @@ u32 nvmap::IocGetId(const std::vector<u8>& input, std::vector<u8>& output) {
|
|
|
|
|
|
|
|
|
|
|
|
LOG_WARNING(Service_NVDRV, "called");
|
|
|
|
LOG_WARNING(Service_NVDRV, "called");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!params.handle) {
|
|
|
|
|
|
|
|
return static_cast<u32>(NvErrCodes::InvalidValue);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
auto object = GetObject(params.handle);
|
|
|
|
auto object = GetObject(params.handle);
|
|
|
|
ASSERT(object);
|
|
|
|
if (!object) {
|
|
|
|
|
|
|
|
return static_cast<u32>(NvErrCodes::OperationNotPermitted);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
params.id = object->id;
|
|
|
|
params.id = object->id;
|
|
|
|
|
|
|
|
|
|
|
@ -105,7 +138,14 @@ u32 nvmap::IocFromId(const std::vector<u8>& input, std::vector<u8>& output) {
|
|
|
|
|
|
|
|
|
|
|
|
auto itr = std::find_if(handles.begin(), handles.end(),
|
|
|
|
auto itr = std::find_if(handles.begin(), handles.end(),
|
|
|
|
[&](const auto& entry) { return entry.second->id == params.id; });
|
|
|
|
[&](const auto& entry) { return entry.second->id == params.id; });
|
|
|
|
ASSERT(itr != handles.end());
|
|
|
|
if (itr == handles.end()) {
|
|
|
|
|
|
|
|
return static_cast<u32>(NvErrCodes::InvalidValue);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto& object = itr->second;
|
|
|
|
|
|
|
|
if (object->status != Object::Status::Allocated) {
|
|
|
|
|
|
|
|
return static_cast<u32>(NvErrCodes::InvalidValue);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
itr->second->refcount++;
|
|
|
|
itr->second->refcount++;
|
|
|
|
|
|
|
|
|
|
|
@ -125,8 +165,13 @@ u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) {
|
|
|
|
LOG_WARNING(Service_NVDRV, "(STUBBED) called type={}", params.param);
|
|
|
|
LOG_WARNING(Service_NVDRV, "(STUBBED) called type={}", params.param);
|
|
|
|
|
|
|
|
|
|
|
|
auto object = GetObject(params.handle);
|
|
|
|
auto object = GetObject(params.handle);
|
|
|
|
ASSERT(object);
|
|
|
|
if (!object) {
|
|
|
|
ASSERT(object->status == Object::Status::Allocated);
|
|
|
|
return static_cast<u32>(NvErrCodes::InvalidValue);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (object->status != Object::Status::Allocated) {
|
|
|
|
|
|
|
|
return static_cast<u32>(NvErrCodes::OperationNotPermitted);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch (static_cast<ParamTypes>(params.param)) {
|
|
|
|
switch (static_cast<ParamTypes>(params.param)) {
|
|
|
|
case ParamTypes::Size:
|
|
|
|
case ParamTypes::Size:
|
|
|
@ -163,9 +208,12 @@ u32 nvmap::IocFree(const std::vector<u8>& input, std::vector<u8>& output) {
|
|
|
|
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
|
|
|
LOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
|
|
|
|
|
|
|
|
|
|
|
auto itr = handles.find(params.handle);
|
|
|
|
auto itr = handles.find(params.handle);
|
|
|
|
ASSERT(itr != handles.end());
|
|
|
|
if (itr == handles.end()) {
|
|
|
|
|
|
|
|
return static_cast<u32>(NvErrCodes::InvalidValue);
|
|
|
|
ASSERT(itr->second->refcount > 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!itr->second->refcount) {
|
|
|
|
|
|
|
|
return static_cast<u32>(NvErrCodes::InvalidValue);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
itr->second->refcount--;
|
|
|
|
itr->second->refcount--;
|
|
|
|
|
|
|
|
|
|
|
|