GPU: Implemented the nvmap Free ioctl.
It releases a reference to an nvmap object
This commit is contained in:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user