diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp | 35 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h | 12 |
2 files changed, 47 insertions, 0 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index 71e844959..8c56fa150 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp | |||
| @@ -27,6 +27,11 @@ u32 nvhost_as_gpu::ioctl(Ioctl command, const std::vector<u8>& input, std::vecto | |||
| 27 | case IoctlCommand::IocGetVaRegionsCommand: | 27 | case IoctlCommand::IocGetVaRegionsCommand: |
| 28 | return GetVARegions(input, output); | 28 | return GetVARegions(input, output); |
| 29 | } | 29 | } |
| 30 | |||
| 31 | if (static_cast<IoctlCommand>(command.cmd.Value()) == IoctlCommand::IocRemapCommand) | ||
| 32 | return Remap(input, output); | ||
| 33 | |||
| 34 | UNIMPLEMENTED_MSG("Unimplemented ioctl command"); | ||
| 30 | return 0; | 35 | return 0; |
| 31 | } | 36 | } |
| 32 | 37 | ||
| @@ -56,6 +61,36 @@ u32 nvhost_as_gpu::AllocateSpace(const std::vector<u8>& input, std::vector<u8>& | |||
| 56 | return 0; | 61 | return 0; |
| 57 | } | 62 | } |
| 58 | 63 | ||
| 64 | u32 nvhost_as_gpu::Remap(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 65 | size_t num_entries = input.size() / sizeof(IoctlRemapEntry); | ||
| 66 | |||
| 67 | NGLOG_WARNING(Service_NVDRV, "(STUBBED) called, num_entries=0x{:X}", num_entries); | ||
| 68 | |||
| 69 | std::vector<IoctlRemapEntry> entries(num_entries); | ||
| 70 | std::memcpy(entries.data(), input.data(), input.size()); | ||
| 71 | |||
| 72 | auto& gpu = Core::System::GetInstance().GPU(); | ||
| 73 | |||
| 74 | for (const auto& entry : entries) { | ||
| 75 | NGLOG_WARNING(Service_NVDRV, "remap entry, offset=0x{:X} handle=0x{:X} pages=0x{:X}", | ||
| 76 | entry.offset, entry.nvmap_handle, entry.pages); | ||
| 77 | Tegra::GPUVAddr offset = static_cast<Tegra::GPUVAddr>(entry.offset) << 0x10; | ||
| 78 | |||
| 79 | auto object = nvmap_dev->GetObject(entry.nvmap_handle); | ||
| 80 | ASSERT(object); | ||
| 81 | |||
| 82 | ASSERT(object->status == nvmap::Object::Status::Allocated); | ||
| 83 | |||
| 84 | u64 size = static_cast<u64>(entry.pages) << 0x10; | ||
| 85 | ASSERT(size <= object->size); | ||
| 86 | |||
| 87 | Tegra::GPUVAddr returned = gpu.memory_manager->MapBufferEx(object->addr, offset, size); | ||
| 88 | ASSERT(returned == offset); | ||
| 89 | } | ||
| 90 | std::memcpy(output.data(), entries.data(), output.size()); | ||
| 91 | return 0; | ||
| 92 | } | ||
| 93 | |||
| 59 | u32 nvhost_as_gpu::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) { | 94 | u32 nvhost_as_gpu::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) { |
| 60 | IoctlMapBufferEx params{}; | 95 | IoctlMapBufferEx params{}; |
| 61 | std::memcpy(¶ms, input.data(), input.size()); | 96 | std::memcpy(¶ms, input.data(), input.size()); |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h index d86c3ebd9..f2dd0c3b3 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h | |||
| @@ -26,6 +26,7 @@ private: | |||
| 26 | enum class IoctlCommand : u32_le { | 26 | enum class IoctlCommand : u32_le { |
| 27 | IocInitalizeExCommand = 0x40284109, | 27 | IocInitalizeExCommand = 0x40284109, |
| 28 | IocAllocateSpaceCommand = 0xC0184102, | 28 | IocAllocateSpaceCommand = 0xC0184102, |
| 29 | IocRemapCommand = 0x00000014, | ||
| 29 | IocMapBufferExCommand = 0xC0284106, | 30 | IocMapBufferExCommand = 0xC0284106, |
| 30 | IocBindChannelCommand = 0x40044101, | 31 | IocBindChannelCommand = 0x40044101, |
| 31 | IocGetVaRegionsCommand = 0xC0404108, | 32 | IocGetVaRegionsCommand = 0xC0404108, |
| @@ -54,6 +55,16 @@ private: | |||
| 54 | }; | 55 | }; |
| 55 | static_assert(sizeof(IoctlAllocSpace) == 24, "IoctlInitalizeEx is incorrect size"); | 56 | static_assert(sizeof(IoctlAllocSpace) == 24, "IoctlInitalizeEx is incorrect size"); |
| 56 | 57 | ||
| 58 | struct IoctlRemapEntry { | ||
| 59 | u16_le flags; | ||
| 60 | u16_le kind; | ||
| 61 | u32_le nvmap_handle; | ||
| 62 | INSERT_PADDING_WORDS(1); | ||
| 63 | u32_le offset; | ||
| 64 | u32_le pages; | ||
| 65 | }; | ||
| 66 | static_assert(sizeof(IoctlRemapEntry) == 20, "IoctlRemapEntry is incorrect size"); | ||
| 67 | |||
| 57 | struct IoctlMapBufferEx { | 68 | struct IoctlMapBufferEx { |
| 58 | u32_le flags; // bit0: fixed_offset, bit2: cacheable | 69 | u32_le flags; // bit0: fixed_offset, bit2: cacheable |
| 59 | u32_le kind; // -1 is default | 70 | u32_le kind; // -1 is default |
| @@ -91,6 +102,7 @@ private: | |||
| 91 | 102 | ||
| 92 | u32 InitalizeEx(const std::vector<u8>& input, std::vector<u8>& output); | 103 | u32 InitalizeEx(const std::vector<u8>& input, std::vector<u8>& output); |
| 93 | u32 AllocateSpace(const std::vector<u8>& input, std::vector<u8>& output); | 104 | u32 AllocateSpace(const std::vector<u8>& input, std::vector<u8>& output); |
| 105 | u32 Remap(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 94 | u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output); | 106 | u32 MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output); |
| 95 | u32 BindChannel(const std::vector<u8>& input, std::vector<u8>& output); | 107 | u32 BindChannel(const std::vector<u8>& input, std::vector<u8>& output); |
| 96 | u32 GetVARegions(const std::vector<u8>& input, std::vector<u8>& output); | 108 | u32 GetVARegions(const std::vector<u8>& input, std::vector<u8>& output); |