nvmap.cpp 4.2 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 <algorithm>
  5. #include <cinttypes>
  6. #include "common/assert.h"
  7. #include "common/logging/log.h"
  8. #include "core/hle/service/nvdrv/devices/nvmap.h"
  9. namespace Service {
  10. namespace Nvidia {
  11. namespace Devices {
  12. VAddr nvmap::GetObjectAddress(u32 handle) const {
  13. auto object = GetObject(handle);
  14. ASSERT(object);
  15. ASSERT(object->status == Object::Status::Allocated);
  16. return object->addr;
  17. }
  18. u32 nvmap::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& output) {
  19. switch (static_cast<IoctlCommand>(command.raw)) {
  20. case IoctlCommand::Create:
  21. return IocCreate(input, output);
  22. case IoctlCommand::Alloc:
  23. return IocAlloc(input, output);
  24. case IoctlCommand::GetId:
  25. return IocGetId(input, output);
  26. case IoctlCommand::FromId:
  27. return IocFromId(input, output);
  28. case IoctlCommand::Param:
  29. return IocParam(input, output);
  30. }
  31. UNIMPLEMENTED();
  32. return 0;
  33. }
  34. u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) {
  35. IocCreateParams params;
  36. std::memcpy(&params, input.data(), sizeof(params));
  37. // Create a new nvmap object and obtain a handle to it.
  38. auto object = std::make_shared<Object>();
  39. object->id = next_id++;
  40. object->size = params.size;
  41. object->status = Object::Status::Created;
  42. u32 handle = next_handle++;
  43. handles[handle] = std::move(object);
  44. LOG_DEBUG(Service_NVDRV, "size=0x%08X", params.size);
  45. params.handle = handle;
  46. std::memcpy(output.data(), &params, sizeof(params));
  47. return 0;
  48. }
  49. u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) {
  50. IocAllocParams params;
  51. std::memcpy(&params, input.data(), sizeof(params));
  52. auto object = GetObject(params.handle);
  53. ASSERT(object);
  54. object->flags = params.flags;
  55. object->align = params.align;
  56. object->kind = params.kind;
  57. object->addr = params.addr;
  58. object->status = Object::Status::Allocated;
  59. LOG_DEBUG(Service_NVDRV, "called, addr=0x%" PRIx64, params.addr);
  60. std::memcpy(output.data(), &params, sizeof(params));
  61. return 0;
  62. }
  63. u32 nvmap::IocGetId(const std::vector<u8>& input, std::vector<u8>& output) {
  64. IocGetIdParams params;
  65. std::memcpy(&params, input.data(), sizeof(params));
  66. LOG_WARNING(Service_NVDRV, "called");
  67. auto object = GetObject(params.handle);
  68. ASSERT(object);
  69. params.id = object->id;
  70. std::memcpy(output.data(), &params, sizeof(params));
  71. return 0;
  72. }
  73. u32 nvmap::IocFromId(const std::vector<u8>& input, std::vector<u8>& output) {
  74. IocFromIdParams params;
  75. std::memcpy(&params, input.data(), sizeof(params));
  76. LOG_WARNING(Service_NVDRV, "(STUBBED) called");
  77. auto itr = std::find_if(handles.begin(), handles.end(),
  78. [&](const auto& entry) { return entry.second->id == params.id; });
  79. ASSERT(itr != handles.end());
  80. // Return the existing handle instead of creating a new one.
  81. params.handle = itr->first;
  82. std::memcpy(output.data(), &params, sizeof(params));
  83. return 0;
  84. }
  85. u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) {
  86. enum class ParamTypes { Size = 1, Alignment = 2, Base = 3, Heap = 4, Kind = 5, Compr = 6 };
  87. IocParamParams params;
  88. std::memcpy(&params, input.data(), sizeof(params));
  89. LOG_WARNING(Service_NVDRV, "(STUBBED) called type=%u", params.type);
  90. auto object = GetObject(params.handle);
  91. ASSERT(object);
  92. ASSERT(object->status == Object::Status::Allocated);
  93. switch (static_cast<ParamTypes>(params.type)) {
  94. case ParamTypes::Size:
  95. params.value = object->size;
  96. break;
  97. case ParamTypes::Alignment:
  98. params.value = object->align;
  99. break;
  100. case ParamTypes::Heap:
  101. // TODO(Subv): Seems to be a hardcoded value?
  102. params.value = 0x40000000;
  103. break;
  104. case ParamTypes::Kind:
  105. params.value = object->kind;
  106. break;
  107. default:
  108. UNIMPLEMENTED();
  109. }
  110. std::memcpy(output.data(), &params, sizeof(params));
  111. return 0;
  112. }
  113. } // namespace Devices
  114. } // namespace Nvidia
  115. } // namespace Service