interface.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // Copyright 2018 yuzu emulator team
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <cinttypes>
  5. #include "common/logging/log.h"
  6. #include "core/core.h"
  7. #include "core/hle/ipc_helpers.h"
  8. #include "core/hle/kernel/kernel.h"
  9. #include "core/hle/kernel/readable_event.h"
  10. #include "core/hle/kernel/writable_event.h"
  11. #include "core/hle/service/nvdrv/interface.h"
  12. #include "core/hle/service/nvdrv/nvdata.h"
  13. #include "core/hle/service/nvdrv/nvdrv.h"
  14. namespace Service::Nvidia {
  15. void NVDRV::SignalGPUInterrupt(const u32 event_id) {
  16. nvdrv->SignalEvent(event_id);
  17. }
  18. void NVDRV::Open(Kernel::HLERequestContext& ctx) {
  19. LOG_DEBUG(Service_NVDRV, "called");
  20. const auto& buffer = ctx.ReadBuffer();
  21. std::string device_name(buffer.begin(), buffer.end());
  22. u32 fd = nvdrv->Open(device_name);
  23. IPC::ResponseBuilder rb{ctx, 4};
  24. rb.Push(RESULT_SUCCESS);
  25. rb.Push<u32>(fd);
  26. rb.Push<u32>(0);
  27. }
  28. void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) {
  29. LOG_DEBUG(Service_NVDRV, "called");
  30. IPC::RequestParser rp{ctx};
  31. u32 fd = rp.Pop<u32>();
  32. u32 command = rp.Pop<u32>();
  33. std::vector<u8> output(ctx.GetWriteBufferSize());
  34. IPC::ResponseBuilder rb{ctx, 3};
  35. rb.Push(RESULT_SUCCESS);
  36. rb.Push(nvdrv->Ioctl(fd, command, ctx.ReadBuffer(), output));
  37. ctx.WriteBuffer(output);
  38. }
  39. void NVDRV::Close(Kernel::HLERequestContext& ctx) {
  40. LOG_DEBUG(Service_NVDRV, "called");
  41. IPC::RequestParser rp{ctx};
  42. u32 fd = rp.Pop<u32>();
  43. auto result = nvdrv->Close(fd);
  44. IPC::ResponseBuilder rb{ctx, 2};
  45. rb.Push(result);
  46. }
  47. void NVDRV::Initialize(Kernel::HLERequestContext& ctx) {
  48. LOG_WARNING(Service_NVDRV, "(STUBBED) called");
  49. IPC::ResponseBuilder rb{ctx, 3};
  50. rb.Push(RESULT_SUCCESS);
  51. rb.Push<u32>(0);
  52. }
  53. void NVDRV::QueryEvent(Kernel::HLERequestContext& ctx) {
  54. IPC::RequestParser rp{ctx};
  55. u32 fd = rp.Pop<u32>();
  56. // TODO(Blinkhawk): Figure the meaning of the flag at bit 16
  57. u32 event_id = rp.Pop<u32>() & 0x000000FF;
  58. LOG_WARNING(Service_NVDRV, "(STUBBED) called, fd={:X}, event_id={:X}", fd, event_id);
  59. IPC::ResponseBuilder rb{ctx, 3, 1};
  60. rb.Push(RESULT_SUCCESS);
  61. if (event_id < 64) {
  62. rb.PushCopyObjects(nvdrv->GetEvent(event_id));
  63. rb.Push<u32>(NvResult::Success);
  64. } else {
  65. rb.Push<u32>(0);
  66. rb.Push<u32>(NvResult::BadParameter);
  67. }
  68. }
  69. void NVDRV::SetClientPID(Kernel::HLERequestContext& ctx) {
  70. IPC::RequestParser rp{ctx};
  71. pid = rp.Pop<u64>();
  72. LOG_WARNING(Service_NVDRV, "(STUBBED) called, pid=0x{:X}", pid);
  73. IPC::ResponseBuilder rb{ctx, 3};
  74. rb.Push(RESULT_SUCCESS);
  75. rb.Push<u32>(0);
  76. }
  77. void NVDRV::FinishInitialize(Kernel::HLERequestContext& ctx) {
  78. LOG_WARNING(Service_NVDRV, "(STUBBED) called");
  79. IPC::ResponseBuilder rb{ctx, 2};
  80. rb.Push(RESULT_SUCCESS);
  81. }
  82. void NVDRV::GetStatus(Kernel::HLERequestContext& ctx) {
  83. LOG_WARNING(Service_NVDRV, "(STUBBED) called");
  84. IPC::ResponseBuilder rb{ctx, 2};
  85. rb.Push(RESULT_SUCCESS);
  86. }
  87. void NVDRV::DumpGraphicsMemoryInfo(Kernel::HLERequestContext& ctx) {
  88. // According to SwitchBrew, this has no inputs and no outputs, so effectively does nothing on
  89. // retail hardware.
  90. LOG_DEBUG(Service_NVDRV, "called");
  91. IPC::ResponseBuilder rb{ctx, 2};
  92. rb.Push(RESULT_SUCCESS);
  93. }
  94. NVDRV::NVDRV(std::shared_ptr<Module> nvdrv, const char* name)
  95. : ServiceFramework(name), nvdrv(std::move(nvdrv)) {
  96. static const FunctionInfo functions[] = {
  97. {0, &NVDRV::Open, "Open"},
  98. {1, &NVDRV::Ioctl, "Ioctl"},
  99. {2, &NVDRV::Close, "Close"},
  100. {3, &NVDRV::Initialize, "Initialize"},
  101. {4, &NVDRV::QueryEvent, "QueryEvent"},
  102. {5, nullptr, "MapSharedMem"},
  103. {6, &NVDRV::GetStatus, "GetStatus"},
  104. {7, nullptr, "ForceSetClientPID"},
  105. {8, &NVDRV::SetClientPID, "SetClientPID"},
  106. {9, &NVDRV::DumpGraphicsMemoryInfo, "DumpGraphicsMemoryInfo"},
  107. {10, nullptr, "InitializeDevtools"},
  108. {11, &NVDRV::Ioctl, "Ioctl2"},
  109. {12, nullptr, "Ioctl3"},
  110. {13, &NVDRV::FinishInitialize, "FinishInitialize"},
  111. };
  112. RegisterHandlers(functions);
  113. auto& kernel = Core::System::GetInstance().Kernel();
  114. query_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
  115. "NVDRV::query_event");
  116. }
  117. NVDRV::~NVDRV() = default;
  118. } // namespace Service::Nvidia