multi_level_page_table.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. // SPDX-FileCopyrightText: 2021 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <type_traits>
  5. #include <utility>
  6. #include <vector>
  7. #include "common/common_types.h"
  8. namespace Common {
  9. template <typename BaseAddr>
  10. class MultiLevelPageTable final {
  11. public:
  12. constexpr MultiLevelPageTable() = default;
  13. explicit MultiLevelPageTable(std::size_t address_space_bits, std::size_t first_level_bits,
  14. std::size_t page_bits);
  15. ~MultiLevelPageTable() noexcept;
  16. MultiLevelPageTable(const MultiLevelPageTable&) = delete;
  17. MultiLevelPageTable& operator=(const MultiLevelPageTable&) = delete;
  18. MultiLevelPageTable(MultiLevelPageTable&& other) noexcept
  19. : address_space_bits{std::exchange(other.address_space_bits, 0)},
  20. first_level_bits{std::exchange(other.first_level_bits, 0)}, page_bits{std::exchange(
  21. other.page_bits, 0)},
  22. first_level_shift{std::exchange(other.first_level_shift, 0)},
  23. first_level_chunk_size{std::exchange(other.first_level_chunk_size, 0)},
  24. first_level_map{std::move(other.first_level_map)}, base_ptr{std::exchange(other.base_ptr,
  25. nullptr)} {}
  26. MultiLevelPageTable& operator=(MultiLevelPageTable&& other) noexcept {
  27. address_space_bits = std::exchange(other.address_space_bits, 0);
  28. first_level_bits = std::exchange(other.first_level_bits, 0);
  29. page_bits = std::exchange(other.page_bits, 0);
  30. first_level_shift = std::exchange(other.first_level_shift, 0);
  31. first_level_chunk_size = std::exchange(other.first_level_chunk_size, 0);
  32. alloc_size = std::exchange(other.alloc_size, 0);
  33. first_level_map = std::move(other.first_level_map);
  34. base_ptr = std::exchange(other.base_ptr, nullptr);
  35. return *this;
  36. }
  37. void ReserveRange(u64 start, std::size_t size);
  38. [[nodiscard]] const BaseAddr& operator[](std::size_t index) const {
  39. return base_ptr[index];
  40. }
  41. [[nodiscard]] BaseAddr& operator[](std::size_t index) {
  42. return base_ptr[index];
  43. }
  44. [[nodiscard]] BaseAddr* data() {
  45. return base_ptr;
  46. }
  47. [[nodiscard]] const BaseAddr* data() const {
  48. return base_ptr;
  49. }
  50. private:
  51. void AllocateLevel(u64 level);
  52. std::size_t address_space_bits{};
  53. std::size_t first_level_bits{};
  54. std::size_t page_bits{};
  55. std::size_t first_level_shift{};
  56. std::size_t first_level_chunk_size{};
  57. std::size_t alloc_size{};
  58. std::vector<void*> first_level_map{};
  59. BaseAddr* base_ptr{};
  60. };
  61. } // namespace Common