diff options
Diffstat (limited to 'src/core/hle/service/nvdrv/devices/nvmap.cpp')
-rw-r--r-- | src/core/hle/service/nvdrv/devices/nvmap.cpp | 65 |
1 files changed, 48 insertions, 17 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index b3842eb4c..23fe98190 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp @@ -9,9 +9,7 @@ #include "common/logging/log.h" #include "core/hle/service/nvdrv/devices/nvmap.h" -namespace Service { -namespace Nvidia { -namespace Devices { +namespace Service::Nvidia::Devices { VAddr nvmap::GetObjectAddress(u32 handle) const { auto object = GetObject(handle); @@ -32,9 +30,11 @@ u32 nvmap::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& o return IocFromId(input, output); case IoctlCommand::Param: return IocParam(input, output); + case IoctlCommand::Free: + return IocFree(input, output); } - UNIMPLEMENTED(); + UNIMPLEMENTED_MSG("Unimplemented ioctl"); return 0; } @@ -47,11 +47,12 @@ u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) { object->id = next_id++; object->size = params.size; object->status = Object::Status::Created; + object->refcount = 1; u32 handle = next_handle++; handles[handle] = std::move(object); - LOG_DEBUG(Service_NVDRV, "size=0x%08X", params.size); + NGLOG_DEBUG(Service_NVDRV, "size=0x{:08X}", params.size); params.handle = handle; @@ -72,7 +73,7 @@ u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) { object->addr = params.addr; object->status = Object::Status::Allocated; - LOG_DEBUG(Service_NVDRV, "called, addr=0x%" PRIx64, params.addr); + NGLOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.addr); std::memcpy(output.data(), ¶ms, sizeof(params)); return 0; @@ -82,7 +83,7 @@ u32 nvmap::IocGetId(const std::vector<u8>& input, std::vector<u8>& output) { IocGetIdParams params; std::memcpy(¶ms, input.data(), sizeof(params)); - LOG_WARNING(Service_NVDRV, "called"); + NGLOG_WARNING(Service_NVDRV, "called"); auto object = GetObject(params.handle); ASSERT(object); @@ -97,12 +98,14 @@ u32 nvmap::IocFromId(const std::vector<u8>& input, std::vector<u8>& output) { IocFromIdParams params; std::memcpy(¶ms, input.data(), sizeof(params)); - LOG_WARNING(Service_NVDRV, "(STUBBED) called"); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called"); auto itr = std::find_if(handles.begin(), handles.end(), [&](const auto& entry) { return entry.second->id == params.id; }); ASSERT(itr != handles.end()); + itr->second->refcount++; + // Return the existing handle instead of creating a new one. params.handle = itr->first; @@ -116,25 +119,25 @@ u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) { IocParamParams params; std::memcpy(¶ms, input.data(), sizeof(params)); - LOG_WARNING(Service_NVDRV, "(STUBBED) called type=%u", params.type); + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called type={}", params.param); auto object = GetObject(params.handle); ASSERT(object); ASSERT(object->status == Object::Status::Allocated); - switch (static_cast<ParamTypes>(params.type)) { + switch (static_cast<ParamTypes>(params.param)) { case ParamTypes::Size: - params.value = object->size; + params.result = object->size; break; case ParamTypes::Alignment: - params.value = object->align; + params.result = object->align; break; case ParamTypes::Heap: // TODO(Subv): Seems to be a hardcoded value? - params.value = 0x40000000; + params.result = 0x40000000; break; case ParamTypes::Kind: - params.value = object->kind; + params.result = object->kind; break; default: UNIMPLEMENTED(); @@ -144,6 +147,34 @@ u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) { return 0; } -} // namespace Devices -} // namespace Nvidia -} // namespace Service +u32 nvmap::IocFree(const std::vector<u8>& input, std::vector<u8>& output) { + enum FreeFlags { + Freed = 0, + NotFreedYet = 1, + }; + + IocFreeParams params; + std::memcpy(¶ms, input.data(), sizeof(params)); + + NGLOG_WARNING(Service_NVDRV, "(STUBBED) called"); + + auto itr = handles.find(params.handle); + ASSERT(itr != handles.end()); + + itr->second->refcount--; + + params.refcount = itr->second->refcount; + params.size = itr->second->size; + + if (itr->second->refcount == 0) + params.flags = Freed; + else + params.flags = NotFreedYet; + + handles.erase(params.handle); + + std::memcpy(output.data(), ¶ms, sizeof(params)); + return 0; +} + +} // namespace Service::Nvidia::Devices |