mm_list.hpp 2.9 KB

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