host_memory.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include <catch2/catch_test_macros.hpp>
  4. #include "common/host_memory.h"
  5. #include "common/literals.h"
  6. using Common::HostMemory;
  7. using namespace Common::Literals;
  8. static constexpr size_t VIRTUAL_SIZE = 1ULL << 39;
  9. static constexpr size_t BACKING_SIZE = 4_GiB;
  10. static constexpr auto PERMS = Common::MemoryPermission::ReadWrite;
  11. TEST_CASE("HostMemory: Initialize and deinitialize", "[common]") {
  12. { HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE); }
  13. { HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE); }
  14. }
  15. TEST_CASE("HostMemory: Simple map", "[common]") {
  16. HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE);
  17. mem.Map(0x5000, 0x8000, 0x1000, PERMS);
  18. volatile u8* const data = mem.VirtualBasePointer() + 0x5000;
  19. data[0] = 50;
  20. REQUIRE(data[0] == 50);
  21. }
  22. TEST_CASE("HostMemory: Simple mirror map", "[common]") {
  23. HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE);
  24. mem.Map(0x5000, 0x3000, 0x2000, PERMS);
  25. mem.Map(0x8000, 0x4000, 0x1000, PERMS);
  26. volatile u8* const mirror_a = mem.VirtualBasePointer() + 0x5000;
  27. volatile u8* const mirror_b = mem.VirtualBasePointer() + 0x8000;
  28. mirror_b[0] = 76;
  29. REQUIRE(mirror_a[0x1000] == 76);
  30. }
  31. TEST_CASE("HostMemory: Simple unmap", "[common]") {
  32. HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE);
  33. mem.Map(0x5000, 0x3000, 0x2000, PERMS);
  34. volatile u8* const data = mem.VirtualBasePointer() + 0x5000;
  35. data[75] = 50;
  36. REQUIRE(data[75] == 50);
  37. mem.Unmap(0x5000, 0x2000);
  38. }
  39. TEST_CASE("HostMemory: Simple unmap and remap", "[common]") {
  40. HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE);
  41. mem.Map(0x5000, 0x3000, 0x2000, PERMS);
  42. volatile u8* const data = mem.VirtualBasePointer() + 0x5000;
  43. data[0] = 50;
  44. REQUIRE(data[0] == 50);
  45. mem.Unmap(0x5000, 0x2000);
  46. mem.Map(0x5000, 0x3000, 0x2000, PERMS);
  47. REQUIRE(data[0] == 50);
  48. mem.Map(0x7000, 0x2000, 0x5000, PERMS);
  49. REQUIRE(data[0x3000] == 50);
  50. }
  51. TEST_CASE("HostMemory: Nieche allocation", "[common]") {
  52. HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE);
  53. mem.Map(0x0000, 0, 0x20000, PERMS);
  54. mem.Unmap(0x0000, 0x4000);
  55. mem.Map(0x1000, 0, 0x2000, PERMS);
  56. mem.Map(0x3000, 0, 0x1000, PERMS);
  57. mem.Map(0, 0, 0x1000, PERMS);
  58. }
  59. TEST_CASE("HostMemory: Full unmap", "[common]") {
  60. HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE);
  61. mem.Map(0x8000, 0, 0x4000, PERMS);
  62. mem.Unmap(0x8000, 0x4000);
  63. mem.Map(0x6000, 0, 0x16000, PERMS);
  64. }
  65. TEST_CASE("HostMemory: Right out of bounds unmap", "[common]") {
  66. HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE);
  67. mem.Map(0x0000, 0, 0x4000, PERMS);
  68. mem.Unmap(0x2000, 0x4000);
  69. mem.Map(0x2000, 0x80000, 0x4000, PERMS);
  70. }
  71. TEST_CASE("HostMemory: Left out of bounds unmap", "[common]") {
  72. HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE);
  73. mem.Map(0x8000, 0, 0x4000, PERMS);
  74. mem.Unmap(0x6000, 0x4000);
  75. mem.Map(0x8000, 0, 0x2000, PERMS);
  76. }
  77. TEST_CASE("HostMemory: Multiple placeholder unmap", "[common]") {
  78. HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE);
  79. mem.Map(0x0000, 0, 0x4000, PERMS);
  80. mem.Map(0x4000, 0, 0x1b000, PERMS);
  81. mem.Unmap(0x3000, 0x1c000);
  82. mem.Map(0x3000, 0, 0x20000, PERMS);
  83. }
  84. TEST_CASE("HostMemory: Unmap between placeholders", "[common]") {
  85. HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE);
  86. mem.Map(0x0000, 0, 0x4000, PERMS);
  87. mem.Map(0x4000, 0, 0x4000, PERMS);
  88. mem.Unmap(0x2000, 0x4000);
  89. mem.Map(0x2000, 0, 0x4000, PERMS);
  90. }
  91. TEST_CASE("HostMemory: Unmap to origin", "[common]") {
  92. HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE);
  93. mem.Map(0x4000, 0, 0x4000, PERMS);
  94. mem.Map(0x8000, 0, 0x4000, PERMS);
  95. mem.Unmap(0x4000, 0x4000);
  96. mem.Map(0, 0, 0x4000, PERMS);
  97. mem.Map(0x4000, 0, 0x4000, PERMS);
  98. }
  99. TEST_CASE("HostMemory: Unmap to right", "[common]") {
  100. HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE);
  101. mem.Map(0x4000, 0, 0x4000, PERMS);
  102. mem.Map(0x8000, 0, 0x4000, PERMS);
  103. mem.Unmap(0x8000, 0x4000);
  104. mem.Map(0x8000, 0, 0x4000, PERMS);
  105. }
  106. TEST_CASE("HostMemory: Partial right unmap check bindings", "[common]") {
  107. HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE);
  108. mem.Map(0x4000, 0x10000, 0x4000, PERMS);
  109. volatile u8* const ptr = mem.VirtualBasePointer() + 0x4000;
  110. ptr[0x1000] = 17;
  111. mem.Unmap(0x6000, 0x2000);
  112. REQUIRE(ptr[0x1000] == 17);
  113. }
  114. TEST_CASE("HostMemory: Partial left unmap check bindings", "[common]") {
  115. HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE);
  116. mem.Map(0x4000, 0x10000, 0x4000, PERMS);
  117. volatile u8* const ptr = mem.VirtualBasePointer() + 0x4000;
  118. ptr[0x3000] = 19;
  119. ptr[0x3fff] = 12;
  120. mem.Unmap(0x4000, 0x2000);
  121. REQUIRE(ptr[0x3000] == 19);
  122. REQUIRE(ptr[0x3fff] == 12);
  123. }
  124. TEST_CASE("HostMemory: Partial middle unmap check bindings", "[common]") {
  125. HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE);
  126. mem.Map(0x4000, 0x10000, 0x4000, PERMS);
  127. volatile u8* const ptr = mem.VirtualBasePointer() + 0x4000;
  128. ptr[0x0000] = 19;
  129. ptr[0x3fff] = 12;
  130. mem.Unmap(0x1000, 0x2000);
  131. REQUIRE(ptr[0x0000] == 19);
  132. REQUIRE(ptr[0x3fff] == 12);
  133. }
  134. TEST_CASE("HostMemory: Partial sparse middle unmap and check bindings", "[common]") {
  135. HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE);
  136. mem.Map(0x4000, 0x10000, 0x2000, PERMS);
  137. mem.Map(0x6000, 0x20000, 0x2000, PERMS);
  138. volatile u8* const ptr = mem.VirtualBasePointer() + 0x4000;
  139. ptr[0x0000] = 19;
  140. ptr[0x3fff] = 12;
  141. mem.Unmap(0x5000, 0x2000);
  142. REQUIRE(ptr[0x0000] == 19);
  143. REQUIRE(ptr[0x3fff] == 12);
  144. }