page_table.cpp 2.2 KB

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