mm_list.hpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #pragma once
  2. #include <set>
  3. #include <stdint.h>
  4. #include "vm_area.hpp"
  5. #include "paging.hpp"
  6. namespace kernel::mem {
  7. constexpr uintptr_t KERNEL_SPACE_START = 0x8000000000000000ULL;
  8. constexpr uintptr_t USER_SPACE_MEMORY_TOP = 0x0000800000000000ULL;
  9. constexpr uintptr_t MMAP_MIN_ADDR = 0x0000000000001000ULL;
  10. constexpr uintptr_t STACK_MIN_ADDR = 0x0000700000000000ULL;
  11. class mm_list {
  12. private:
  13. struct comparator {
  14. constexpr bool operator()(const vm_area& lhs, const vm_area& rhs) const noexcept
  15. { return lhs < rhs; }
  16. constexpr bool operator()(const vm_area& lhs, uintptr_t rhs) const noexcept
  17. { return lhs < rhs; }
  18. constexpr bool operator()(uintptr_t lhs, const vm_area& rhs) const noexcept
  19. { return lhs < rhs; }
  20. };
  21. public:
  22. using list_type = std::set<vm_area, comparator>;
  23. using iterator = list_type::iterator;
  24. using const_iterator = list_type::const_iterator;
  25. struct map_args {
  26. // MUSE BE aligned to 4kb boundary
  27. uintptr_t vaddr;
  28. // MUSE BE aligned to 4kb boundary
  29. std::size_t length;
  30. unsigned long flags;
  31. fs::inode* file_inode;
  32. // MUSE BE aligned to 4kb boundary
  33. std::size_t file_offset;
  34. };
  35. private:
  36. list_type m_areas;
  37. paging::pfn_t m_pt;
  38. iterator m_brk {};
  39. public:
  40. // default constructor copies kernel_mms
  41. explicit mm_list();
  42. // copies kernel_mms and mirrors user space
  43. explicit mm_list(const mm_list& other);
  44. constexpr mm_list(mm_list&& v)
  45. : m_areas(std::move(v.m_areas))
  46. , m_pt(std::exchange(v.m_pt, 0))
  47. , m_brk{std::move(v.m_brk)} { }
  48. ~mm_list();
  49. void switch_pd() const noexcept;
  50. int register_brk(uintptr_t addr);
  51. uintptr_t set_brk(uintptr_t addr);
  52. void clear();
  53. // split the memory block at the specified address
  54. // return: iterator to the new block
  55. iterator split(iterator area, uintptr_t at);
  56. bool is_avail(uintptr_t addr) const;
  57. bool is_avail(uintptr_t start, std::size_t length) const noexcept;
  58. uintptr_t find_avail(uintptr_t hint, size_t length) const;
  59. int unmap(iterator area, bool should_invalidate_tlb);
  60. int unmap(uintptr_t start, std::size_t length, bool should_invalidate_tlb);
  61. int mmap(const map_args& args);
  62. constexpr vm_area* find(uintptr_t lp)
  63. {
  64. auto iter = m_areas.find(lp);
  65. if (iter == m_areas.end())
  66. return nullptr;
  67. return &iter;
  68. }
  69. constexpr const vm_area* find(uintptr_t lp) const
  70. {
  71. auto iter = m_areas.find(lp);
  72. if (iter == m_areas.end())
  73. return nullptr;
  74. return &iter;
  75. }
  76. constexpr paging::PSE get_page_table() const noexcept
  77. {
  78. return paging::PSE {m_pt};
  79. }
  80. };
  81. } // namespace kernel::mem