PhysicalRegion.cpp 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #include <AK/Bitmap.h>
  2. #include <AK/Retained.h>
  3. #include <AK/RetainPtr.h>
  4. #include <Kernel/Assertions.h>
  5. #include <Kernel/PhysicalAddress.h>
  6. #include <Kernel/VM/PhysicalPage.h>
  7. #include <Kernel/VM/PhysicalRegion.h>
  8. Retained<PhysicalRegion> PhysicalRegion::create(PhysicalAddress lower, PhysicalAddress upper)
  9. {
  10. return adopt(*new PhysicalRegion(lower, upper));
  11. }
  12. PhysicalRegion::PhysicalRegion(PhysicalAddress lower, PhysicalAddress upper)
  13. : m_lower(lower)
  14. , m_upper(upper)
  15. , m_bitmap(Bitmap::create())
  16. {
  17. }
  18. void PhysicalRegion::expand(PhysicalAddress lower, PhysicalAddress upper)
  19. {
  20. ASSERT(!m_pages);
  21. m_lower = lower;
  22. m_upper = upper;
  23. }
  24. unsigned PhysicalRegion::finalize_capacity()
  25. {
  26. ASSERT(!m_pages);
  27. m_pages = (m_upper.get() - m_lower.get()) / PAGE_SIZE;
  28. m_bitmap.grow(m_pages, false);
  29. return size();
  30. }
  31. RetainPtr<PhysicalPage> PhysicalRegion::take_free_page(bool supervisor)
  32. {
  33. ASSERT(m_pages);
  34. if (m_used == m_pages)
  35. return nullptr;
  36. for (unsigned page = m_last; page < m_pages; page++) {
  37. if (!m_bitmap.get(page)) {
  38. m_bitmap.set(page, true);
  39. m_used++;
  40. m_last = page + 1;
  41. return PhysicalPage::create(m_lower.offset(page * PAGE_SIZE), supervisor);
  42. }
  43. }
  44. ASSERT_NOT_REACHED();
  45. return nullptr;
  46. }
  47. void PhysicalRegion::return_page_at(PhysicalAddress addr)
  48. {
  49. ASSERT(m_pages);
  50. if (m_used == 0) {
  51. ASSERT_NOT_REACHED();
  52. }
  53. int local_offset = addr.get() - m_lower.get();
  54. ASSERT(local_offset >= 0);
  55. ASSERT(local_offset < m_pages * PAGE_SIZE);
  56. auto page = local_offset / PAGE_SIZE;
  57. if (page < m_last) m_last = page;
  58. m_bitmap.set(page, false);
  59. m_used--;
  60. }