hle: service: nvdrv: Implement nvhost_as_gpu::FreeSpace.

- This is used by Super Mario 3D All-Stars.
merge-requests/60/head
bunnei 2020-10-12 17:36:52 +07:00
parent 4c348f4069
commit b260847218
2 changed files with 25 additions and 0 deletions

@ -46,6 +46,8 @@ u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector<u8>& input, const std:
return GetVARegions(input, output); return GetVARegions(input, output);
case IoctlCommand::IocUnmapBufferCommand: case IoctlCommand::IocUnmapBufferCommand:
return UnmapBuffer(input, output); return UnmapBuffer(input, output);
case IoctlCommand::IocFreeSpaceCommand:
return FreeSpace(input, output);
default: default:
break; break;
} }
@ -91,6 +93,20 @@ u32 nvhost_as_gpu::AllocateSpace(const std::vector<u8>& input, std::vector<u8>&
return result; return result;
} }
u32 nvhost_as_gpu::FreeSpace(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlFreeSpace params{};
std::memcpy(&params, input.data(), input.size());
LOG_DEBUG(Service_NVDRV, "called, offset={:X}, pages={:X}, page_size={:X}", params.offset,
params.pages, params.page_size);
system.GPU().MemoryManager().Unmap(params.offset,
static_cast<std::size_t>(params.pages) * params.page_size);
std::memcpy(output.data(), &params, output.size());
return NvErrCodes::Success;
}
u32 nvhost_as_gpu::Remap(const std::vector<u8>& input, std::vector<u8>& output) { u32 nvhost_as_gpu::Remap(const std::vector<u8>& input, std::vector<u8>& output) {
const auto num_entries = input.size() / sizeof(IoctlRemapEntry); const auto num_entries = input.size() / sizeof(IoctlRemapEntry);

@ -82,6 +82,7 @@ private:
IocBindChannelCommand = 0x40044101, IocBindChannelCommand = 0x40044101,
IocGetVaRegionsCommand = 0xC0404108, IocGetVaRegionsCommand = 0xC0404108,
IocUnmapBufferCommand = 0xC0084105, IocUnmapBufferCommand = 0xC0084105,
IocFreeSpaceCommand = 0xC0104103,
}; };
struct IoctlInitalizeEx { struct IoctlInitalizeEx {
@ -107,6 +108,13 @@ private:
}; };
static_assert(sizeof(IoctlAllocSpace) == 24, "IoctlInitalizeEx is incorrect size"); static_assert(sizeof(IoctlAllocSpace) == 24, "IoctlInitalizeEx is incorrect size");
struct IoctlFreeSpace {
u64_le offset;
u32_le pages;
u32_le page_size;
};
static_assert(sizeof(IoctlFreeSpace) == 16, "IoctlFreeSpace is incorrect size");
struct IoctlRemapEntry { struct IoctlRemapEntry {
u16_le flags; u16_le flags;
u16_le kind; u16_le kind;
@ -162,6 +170,7 @@ private:
u32 Remap(const std::vector<u8>& input, std::vector<u8>& output); u32 Remap(const std::vector<u8>& input, std::vector<u8>& output);
u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output); u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output);
u32 UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& output); u32 UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& output);
u32 FreeSpace(const std::vector<u8>& input, std::vector<u8>& output);
u32 BindChannel(const std::vector<u8>& input, std::vector<u8>& output); u32 BindChannel(const std::vector<u8>& input, std::vector<u8>& output);
u32 GetVARegions(const std::vector<u8>& input, std::vector<u8>& output); u32 GetVARegions(const std::vector<u8>& input, std::vector<u8>& output);