GPU: Implemented the nvmap Free ioctl.
It releases a reference to an nvmap object
This commit is contained in:
parent
72b5c448cf
commit
525492428d
|
@ -30,6 +30,8 @@ u32 nvmap::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& o
|
||||||
return IocFromId(input, output);
|
return IocFromId(input, output);
|
||||||
case IoctlCommand::Param:
|
case IoctlCommand::Param:
|
||||||
return IocParam(input, output);
|
return IocParam(input, output);
|
||||||
|
case IoctlCommand::Free:
|
||||||
|
return IocFree(input, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
UNIMPLEMENTED_MSG("Unimplemented ioctl");
|
UNIMPLEMENTED_MSG("Unimplemented ioctl");
|
||||||
|
@ -45,6 +47,7 @@ u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||||
object->id = next_id++;
|
object->id = next_id++;
|
||||||
object->size = params.size;
|
object->size = params.size;
|
||||||
object->status = Object::Status::Created;
|
object->status = Object::Status::Created;
|
||||||
|
object->refcount = 1;
|
||||||
|
|
||||||
u32 handle = next_handle++;
|
u32 handle = next_handle++;
|
||||||
handles[handle] = std::move(object);
|
handles[handle] = std::move(object);
|
||||||
|
@ -101,6 +104,8 @@ u32 nvmap::IocFromId(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||||
[&](const auto& entry) { return entry.second->id == params.id; });
|
[&](const auto& entry) { return entry.second->id == params.id; });
|
||||||
ASSERT(itr != handles.end());
|
ASSERT(itr != handles.end());
|
||||||
|
|
||||||
|
itr->second->refcount++;
|
||||||
|
|
||||||
// Return the existing handle instead of creating a new one.
|
// Return the existing handle instead of creating a new one.
|
||||||
params.handle = itr->first;
|
params.handle = itr->first;
|
||||||
|
|
||||||
|
@ -142,4 +147,34 @@ u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
} // namespace Service::Nvidia::Devices
|
||||||
|
|
|
@ -34,6 +34,7 @@ public:
|
||||||
u8 kind;
|
u8 kind;
|
||||||
VAddr addr;
|
VAddr addr;
|
||||||
Status status;
|
Status status;
|
||||||
|
u32 refcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<Object> GetObject(u32 handle) const {
|
std::shared_ptr<Object> GetObject(u32 handle) const {
|
||||||
|
@ -59,7 +60,8 @@ private:
|
||||||
FromId = 0xC0080103,
|
FromId = 0xC0080103,
|
||||||
Alloc = 0xC0200104,
|
Alloc = 0xC0200104,
|
||||||
Param = 0xC00C0109,
|
Param = 0xC00C0109,
|
||||||
GetId = 0xC008010E
|
GetId = 0xC008010E,
|
||||||
|
Free = 0xC0180105,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IocCreateParams {
|
struct IocCreateParams {
|
||||||
|
@ -102,11 +104,21 @@ private:
|
||||||
u32_le value;
|
u32_le value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct IocFreeParams {
|
||||||
|
u32_le handle;
|
||||||
|
INSERT_PADDING_BYTES(4);
|
||||||
|
u64_le refcount;
|
||||||
|
u32_le size;
|
||||||
|
u32_le flags;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(IocFreeParams) == 24, "IocFreeParams has wrong size");
|
||||||
|
|
||||||
u32 IocCreate(const std::vector<u8>& input, std::vector<u8>& output);
|
u32 IocCreate(const std::vector<u8>& input, std::vector<u8>& output);
|
||||||
u32 IocAlloc(const std::vector<u8>& input, std::vector<u8>& output);
|
u32 IocAlloc(const std::vector<u8>& input, std::vector<u8>& output);
|
||||||
u32 IocGetId(const std::vector<u8>& input, std::vector<u8>& output);
|
u32 IocGetId(const std::vector<u8>& input, std::vector<u8>& output);
|
||||||
u32 IocFromId(const std::vector<u8>& input, std::vector<u8>& output);
|
u32 IocFromId(const std::vector<u8>& input, std::vector<u8>& output);
|
||||||
u32 IocParam(const std::vector<u8>& input, std::vector<u8>& output);
|
u32 IocParam(const std::vector<u8>& input, std::vector<u8>& output);
|
||||||
|
u32 IocFree(const std::vector<u8>& input, std::vector<u8>& output);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::Nvidia::Devices
|
} // namespace Service::Nvidia::Devices
|
||||||
|
|
Reference in New Issue