memory_manager.h 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // Copyright 2018 yuzu emulator team
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <array>
  6. #include <memory>
  7. #include <optional>
  8. #include <vector>
  9. #include "common/common_types.h"
  10. namespace Tegra {
  11. /// Virtual addresses in the GPU's memory map are 64 bit.
  12. using GPUVAddr = u64;
  13. class MemoryManager final {
  14. public:
  15. MemoryManager();
  16. GPUVAddr AllocateSpace(u64 size, u64 align);
  17. GPUVAddr AllocateSpace(GPUVAddr gpu_addr, u64 size, u64 align);
  18. GPUVAddr MapBufferEx(VAddr cpu_addr, u64 size);
  19. GPUVAddr MapBufferEx(VAddr cpu_addr, GPUVAddr gpu_addr, u64 size);
  20. GPUVAddr UnmapBuffer(GPUVAddr gpu_addr, u64 size);
  21. GPUVAddr GetRegionEnd(GPUVAddr region_start) const;
  22. std::optional<VAddr> GpuToCpuAddress(GPUVAddr gpu_addr);
  23. static constexpr u64 PAGE_BITS = 16;
  24. static constexpr u64 PAGE_SIZE = 1 << PAGE_BITS;
  25. static constexpr u64 PAGE_MASK = PAGE_SIZE - 1;
  26. u8 Read8(GPUVAddr addr);
  27. u16 Read16(GPUVAddr addr);
  28. u32 Read32(GPUVAddr addr);
  29. u64 Read64(GPUVAddr addr);
  30. void Write8(GPUVAddr addr, u8 data);
  31. void Write16(GPUVAddr addr, u16 data);
  32. void Write32(GPUVAddr addr, u32 data);
  33. void Write64(GPUVAddr addr, u64 data);
  34. u8* GetPointer(GPUVAddr vaddr);
  35. void ReadBlock(GPUVAddr src_addr, void* dest_buffer, std::size_t size);
  36. void WriteBlock(GPUVAddr dest_addr, const void* src_buffer, std::size_t size);
  37. void CopyBlock(VAddr dest_addr, VAddr src_addr, std::size_t size);
  38. private:
  39. enum class PageStatus : u64 {
  40. Unmapped = 0xFFFFFFFFFFFFFFFFULL,
  41. Allocated = 0xFFFFFFFFFFFFFFFEULL,
  42. Reserved = 0xFFFFFFFFFFFFFFFDULL,
  43. };
  44. std::optional<GPUVAddr> FindFreeBlock(GPUVAddr region_start, u64 size, u64 align,
  45. PageStatus status);
  46. VAddr& PageSlot(GPUVAddr gpu_addr);
  47. static constexpr u64 MAX_ADDRESS{0x10000000000ULL};
  48. static constexpr u64 PAGE_TABLE_BITS{10};
  49. static constexpr u64 PAGE_TABLE_SIZE{1 << PAGE_TABLE_BITS};
  50. static constexpr u64 PAGE_TABLE_MASK{PAGE_TABLE_SIZE - 1};
  51. static constexpr u64 PAGE_BLOCK_BITS{14};
  52. static constexpr u64 PAGE_BLOCK_SIZE{1 << PAGE_BLOCK_BITS};
  53. static constexpr u64 PAGE_BLOCK_MASK{PAGE_BLOCK_SIZE - 1};
  54. using PageBlock = std::array<VAddr, PAGE_BLOCK_SIZE>;
  55. std::array<std::unique_ptr<PageBlock>, PAGE_TABLE_SIZE> page_table{};
  56. struct MappedRegion {
  57. VAddr cpu_addr;
  58. GPUVAddr gpu_addr;
  59. u64 size;
  60. };
  61. std::vector<MappedRegion> mapped_regions;
  62. };
  63. } // namespace Tegra