summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar bunnei2018-04-23 15:23:55 -0400
committerGravatar GitHub2018-04-23 15:23:55 -0400
commitbf25299272b210c11e68036e2e8b22f25256429b (patch)
treeca070bc9b2493d4291a1c556eb82d600a4cd8334 /src/core
parentMerge pull request #385 from Subv/unimpl_ioctls (diff)
parentNvDrv/nvhost-as-gpu: Ensure that the object passed to MapBufferEx has already... (diff)
downloadyuzu-bf25299272b210c11e68036e2e8b22f25256429b.tar.gz
yuzu-bf25299272b210c11e68036e2e8b22f25256429b.tar.xz
yuzu-bf25299272b210c11e68036e2e8b22f25256429b.zip
Merge pull request #384 from Subv/nvhost-remap
Nvdrv/nvhost-as-gpu: Implemented the ioctl REMAP command.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp45
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h12
2 files changed, 57 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..8e7ca6123 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
64u32 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
59u32 nvhost_as_gpu::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) { 94u32 nvhost_as_gpu::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
60 IoctlMapBufferEx params{}; 95 IoctlMapBufferEx params{};
61 std::memcpy(&params, input.data(), input.size()); 96 std::memcpy(&params, input.data(), input.size());
@@ -73,6 +108,16 @@ u32 nvhost_as_gpu::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& ou
73 auto object = nvmap_dev->GetObject(params.nvmap_handle); 108 auto object = nvmap_dev->GetObject(params.nvmap_handle);
74 ASSERT(object); 109 ASSERT(object);
75 110
111 // We can only map objects that have already been assigned a CPU address.
112 ASSERT(object->status == nvmap::Object::Status::Allocated);
113
114 ASSERT(params.buffer_offset == 0);
115
116 // The real nvservices doesn't make a distinction between handles and ids, and
117 // object can only have one handle and it will be the same as its id. Assert that this is the
118 // case to prevent unexpected behavior.
119 ASSERT(object->id == params.nvmap_handle);
120
76 auto& gpu = Core::System::GetInstance().GPU(); 121 auto& gpu = Core::System::GetInstance().GPU();
77 122
78 if (params.flags & 1) { 123 if (params.flags & 1) {
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);