|
|
@@ -22,6 +22,18 @@ u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, const std::ve
|
|
|
switch (static_cast<IoctlCommand>(command.raw)) {
|
|
|
case IoctlCommand::IocSetNVMAPfdCommand:
|
|
|
return SetNVMAPfd(input, output);
|
|
|
+ case IoctlCommand::IocSubmit:
|
|
|
+ return Submit(input, output);
|
|
|
+ case IoctlCommand::IocGetSyncpoint:
|
|
|
+ return GetSyncpoint(input, output);
|
|
|
+ case IoctlCommand::IocGetWaitbase:
|
|
|
+ return GetWaitbase(input, output);
|
|
|
+ case IoctlCommand::IocMapBuffer:
|
|
|
+ return MapBuffer(input, output);
|
|
|
+ case IoctlCommand::IocMapBufferEx:
|
|
|
+ return MapBuffer(input, output);
|
|
|
+ case IoctlCommand::IocUnmapBufferEx:
|
|
|
+ return UnmapBufferEx(input, output);
|
|
|
}
|
|
|
|
|
|
UNIMPLEMENTED_MSG("Unimplemented ioctl");
|
|
|
@@ -30,11 +42,71 @@ u32 nvhost_vic::ioctl(Ioctl command, const std::vector<u8>& input, const std::ve
|
|
|
|
|
|
u32 nvhost_vic::SetNVMAPfd(const std::vector<u8>& input, std::vector<u8>& output) {
|
|
|
IoctlSetNvmapFD params{};
|
|
|
- std::memcpy(¶ms, input.data(), input.size());
|
|
|
+ std::memcpy(¶ms, input.data(), sizeof(IoctlSetNvmapFD));
|
|
|
LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
|
|
|
|
|
|
nvmap_fd = params.nvmap_fd;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+u32 nvhost_vic::Submit(const std::vector<u8>& input, std::vector<u8>& output) {
|
|
|
+ IoctlSubmit params{};
|
|
|
+ std::memcpy(¶ms, input.data(), sizeof(IoctlSubmit));
|
|
|
+ LOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
|
|
+
|
|
|
+ // Workaround for Luigi's Mansion 3, as nvhost_vic is not implemented for asynch GPU
|
|
|
+ params.command_buffer = {};
|
|
|
+
|
|
|
+ std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit));
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+u32 nvhost_vic::GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output) {
|
|
|
+ IoctlGetSyncpoint params{};
|
|
|
+ std::memcpy(¶ms, input.data(), sizeof(IoctlGetSyncpoint));
|
|
|
+ LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
|
|
|
+ params.value = 0; // Seems to be hard coded at 0
|
|
|
+ std::memcpy(output.data(), ¶ms, sizeof(IoctlGetSyncpoint));
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+u32 nvhost_vic::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) {
|
|
|
+ IoctlGetWaitbase params{};
|
|
|
+ std::memcpy(¶ms, input.data(), sizeof(IoctlGetWaitbase));
|
|
|
+ LOG_INFO(Service_NVDRV, "called, unknown=0x{:X}", params.unknown);
|
|
|
+ params.value = 0; // Seems to be hard coded at 0
|
|
|
+ std::memcpy(output.data(), ¶ms, sizeof(IoctlGetWaitbase));
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+u32 nvhost_vic::MapBuffer(const std::vector<u8>& input, std::vector<u8>& output) {
|
|
|
+ IoctlMapBuffer params{};
|
|
|
+ std::memcpy(¶ms, input.data(), sizeof(IoctlMapBuffer));
|
|
|
+ LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
|
|
|
+ params.address_1);
|
|
|
+ params.address_1 = 0;
|
|
|
+ params.address_2 = 0;
|
|
|
+ std::memcpy(output.data(), ¶ms, sizeof(IoctlMapBuffer));
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+u32 nvhost_vic::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
|
|
|
+ IoctlMapBufferEx params{};
|
|
|
+ std::memcpy(¶ms, input.data(), sizeof(IoctlMapBufferEx));
|
|
|
+ LOG_WARNING(Service_NVDRV, "(STUBBED) called with address={:08X}{:08X}", params.address_2,
|
|
|
+ params.address_1);
|
|
|
+ params.address_1 = 0;
|
|
|
+ params.address_2 = 0;
|
|
|
+ std::memcpy(output.data(), ¶ms, sizeof(IoctlMapBufferEx));
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+u32 nvhost_vic::UnmapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
|
|
|
+ IoctlUnmapBufferEx params{};
|
|
|
+ std::memcpy(¶ms, input.data(), sizeof(IoctlUnmapBufferEx));
|
|
|
+ LOG_WARNING(Service_NVDRV, "(STUBBED) called");
|
|
|
+ std::memcpy(output.data(), ¶ms, sizeof(IoctlUnmapBufferEx));
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
} // namespace Service::Nvidia::Devices
|