page_table.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. // Copyright 2019 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <vector>
  6. #include <boost/icl/interval_map.hpp>
  7. #include "common/common_types.h"
  8. #include "common/memory_hook.h"
  9. namespace Common {
  10. enum class PageType : u8 {
  11. /// Page is unmapped and should cause an access error.
  12. Unmapped,
  13. /// Page is mapped to regular memory. This is the only type you can get pointers to.
  14. Memory,
  15. /// Page is mapped to regular memory, but also needs to check for rasterizer cache flushing and
  16. /// invalidation
  17. RasterizerCachedMemory,
  18. /// Page is mapped to a I/O region. Writing and reading to this page is handled by functions.
  19. Special,
  20. /// Page is allocated for use.
  21. Allocated,
  22. };
  23. struct SpecialRegion {
  24. enum class Type {
  25. DebugHook,
  26. IODevice,
  27. } type;
  28. MemoryHookPointer handler;
  29. bool operator<(const SpecialRegion& other) const {
  30. return std::tie(type, handler) < std::tie(other.type, other.handler);
  31. }
  32. bool operator==(const SpecialRegion& other) const {
  33. return std::tie(type, handler) == std::tie(other.type, other.handler);
  34. }
  35. };
  36. /**
  37. * A (reasonably) fast way of allowing switchable and remappable process address spaces. It loosely
  38. * mimics the way a real CPU page table works.
  39. */
  40. struct PageTable {
  41. explicit PageTable(std::size_t page_size_in_bits);
  42. ~PageTable();
  43. /**
  44. * Resizes the page table to be able to accomodate enough pages within
  45. * a given address space.
  46. *
  47. * @param address_space_width_in_bits The address size width in bits.
  48. */
  49. void Resize(std::size_t address_space_width_in_bits);
  50. /**
  51. * Vector of memory pointers backing each page. An entry can only be non-null if the
  52. * corresponding entry in the `attributes` vector is of type `Memory`.
  53. */
  54. std::vector<u8*> pointers;
  55. /**
  56. * Contains MMIO handlers that back memory regions whose entries in the `attribute` vector is
  57. * of type `Special`.
  58. */
  59. boost::icl::interval_map<u64, std::set<SpecialRegion>> special_regions;
  60. /**
  61. * Vector of fine grained page attributes. If it is set to any value other than `Memory`, then
  62. * the corresponding entry in `pointers` MUST be set to null.
  63. */
  64. std::vector<PageType> attributes;
  65. std::vector<u64> backing_addr;
  66. const std::size_t page_size_in_bits{};
  67. };
  68. } // namespace Common