|
|
|
@ -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
|