forked from suyu/suyu
GPU: Implemented the nvmap Free ioctl.
It releases a reference to an nvmap object
This commit is contained in:
parent
72b5c448cf
commit
525492428d
2 changed files with 48 additions and 1 deletions
|
@ -30,6 +30,8 @@ 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_MSG("Unimplemented ioctl");
|
||||
|
@ -45,6 +47,7 @@ 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);
|
||||
|
@ -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; });
|
||||
ASSERT(itr != handles.end());
|
||||
|
||||
itr->second->refcount++;
|
||||
|
||||
// Return the existing handle instead of creating a new one.
|
||||
params.handle = itr->first;
|
||||
|
||||
|
@ -142,4 +147,34 @@ u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) {
|
|||
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
|
||||
|
|
|
@ -34,6 +34,7 @@ public:
|
|||
u8 kind;
|
||||
VAddr addr;
|
||||
Status status;
|
||||
u32 refcount;
|
||||
};
|
||||
|
||||
std::shared_ptr<Object> GetObject(u32 handle) const {
|
||||
|
@ -59,7 +60,8 @@ private:
|
|||
FromId = 0xC0080103,
|
||||
Alloc = 0xC0200104,
|
||||
Param = 0xC00C0109,
|
||||
GetId = 0xC008010E
|
||||
GetId = 0xC008010E,
|
||||
Free = 0xC0180105,
|
||||
};
|
||||
|
||||
struct IocCreateParams {
|
||||
|
@ -102,11 +104,21 @@ private:
|
|||
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 IocAlloc(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 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
|
||||
|
|
Loading…
Reference in a new issue