mm_list.hpp 2.9 KB

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