page_table.cpp 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "common/page_table.h"
  4. #include "common/scope_exit.h"
  5. namespace Common {
  6. PageTable::PageTable() = default;
  7. PageTable::~PageTable() noexcept = default;
  8. bool PageTable::BeginTraversal(TraversalEntry* out_entry, TraversalContext* out_context,
  9. Common::ProcessAddress address) const {
  10. out_context->next_offset = GetInteger(address);
  11. out_context->next_page = address / page_size;
  12. return this->ContinueTraversal(out_entry, out_context);
  13. }
  14. bool PageTable::ContinueTraversal(TraversalEntry* out_entry, TraversalContext* context) const {
  15. // Setup invalid defaults.
  16. out_entry->phys_addr = 0;
  17. out_entry->block_size = page_size;
  18. // Regardless of whether the page was mapped, advance on exit.
  19. SCOPE_EXIT {
  20. context->next_page += 1;
  21. context->next_offset += page_size;
  22. };
  23. // Validate that we can read the actual entry.
  24. const auto page = context->next_page;
  25. if (page >= backing_addr.size()) {
  26. return false;
  27. }
  28. // Validate that the entry is mapped.
  29. const auto phys_addr = backing_addr[page];
  30. if (phys_addr == 0) {
  31. return false;
  32. }
  33. // Populate the results.
  34. out_entry->phys_addr = phys_addr + context->next_offset;
  35. return true;
  36. }
  37. void PageTable::Resize(std::size_t address_space_width_in_bits, std::size_t page_size_in_bits) {
  38. const std::size_t num_page_table_entries{1ULL
  39. << (address_space_width_in_bits - page_size_in_bits)};
  40. pointers.resize(num_page_table_entries);
  41. backing_addr.resize(num_page_table_entries);
  42. blocks.resize(num_page_table_entries);
  43. current_address_space_width_in_bits = address_space_width_in_bits;
  44. page_size = 1ULL << page_size_in_bits;
  45. }
  46. } // namespace Common