mm.hpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #pragma once
  2. #include "types/size.h"
  3. #include <kernel/mem.h>
  4. #include <kernel/vfs.hpp>
  5. #include <types/allocator.hpp>
  6. #include <types/list.hpp>
  7. #include <types/types.h>
  8. #include <types/vector.hpp>
  9. constexpr size_t THREAD_KERNEL_STACK_SIZE = 2 * PAGE_SIZE;
  10. struct page {
  11. page_t phys_page_id;
  12. pte_t* pte;
  13. size_t* ref_count;
  14. union {
  15. uint32_t v;
  16. struct {
  17. uint32_t cow : 1;
  18. } in;
  19. } attr;
  20. };
  21. using page_arr = types::vector<page, types::kernel_ident_allocator>;
  22. class mm {
  23. public:
  24. void* start;
  25. union {
  26. uint32_t v;
  27. struct {
  28. uint32_t read : 1;
  29. uint32_t write : 1;
  30. uint32_t system : 1;
  31. } in;
  32. } attr;
  33. pd_t pd;
  34. page_arr* pgs;
  35. fs::inode* mapped_file;
  36. size_t file_offset;
  37. public:
  38. mm(const mm& val);
  39. mm(void* start, pd_t pd, bool write, bool system);
  40. };
  41. using mm_list = types::list<mm, types::kernel_ident_allocator>;
  42. // in mem.cpp
  43. extern mm_list* kernel_mms;
  44. extern page empty_page;
  45. // translate physical address to virtual(mapped) address
  46. void* ptovp(pptr_t p_ptr);
  47. // @return the pointer to the mm_area containing l_ptr
  48. // nullptr if not
  49. mm* find_mm_area(mm_list* mms, void* l_ptr);
  50. inline constexpr size_t vptrdiff(void* p1, void* p2)
  51. {
  52. return (uint8_t*)p1 - (uint8_t*)p2;
  53. }
  54. inline constexpr page* lto_page(const mm* mm_area, void* l_ptr)
  55. {
  56. size_t offset = vptrdiff(l_ptr, mm_area->start);
  57. return &mm_area->pgs->at(offset / PAGE_SIZE);
  58. }
  59. inline constexpr page_t to_page(pptr_t ptr)
  60. {
  61. return ptr >> 12;
  62. }
  63. inline constexpr size_t to_pdi(page_t pg)
  64. {
  65. return pg >> 10;
  66. }
  67. inline constexpr size_t to_pti(page_t pg)
  68. {
  69. return pg & (1024 - 1);
  70. }
  71. inline constexpr pptr_t to_pp(page_t p)
  72. {
  73. return p << 12;
  74. }
  75. inline constexpr size_t lto_pdi(pptr_t ptr)
  76. {
  77. return to_pdi(to_page(ptr));
  78. }
  79. inline constexpr size_t lto_pti(pptr_t ptr)
  80. {
  81. return to_pti(to_page(ptr));
  82. }
  83. inline constexpr pte_t* to_pte(pt_t pt, page_t pg)
  84. {
  85. return *pt + to_pti(pg);
  86. }
  87. inline pd_t mms_get_pd(const mm_list* mms)
  88. {
  89. return mms->begin()->pd;
  90. }
  91. inline void* to_vp(page_t pg)
  92. {
  93. return ptovp(to_pp(pg));
  94. }
  95. inline pd_t to_pd(page_t pg)
  96. {
  97. return reinterpret_cast<pd_t>(to_vp(pg));
  98. }
  99. inline pt_t to_pt(page_t pg)
  100. {
  101. return reinterpret_cast<pt_t>(to_vp(pg));
  102. }
  103. inline pt_t to_pt(pde_t* pde)
  104. {
  105. return to_pt(pde->in.pt_page);
  106. }
  107. inline pde_t* to_pde(pd_t pd, void* addr)
  108. {
  109. return *pd + lto_pdi((pptr_t)addr);
  110. }
  111. inline pte_t* to_pte(pt_t pt, void* addr)
  112. {
  113. return *pt + lto_pti((pptr_t)addr);
  114. }
  115. inline pte_t* to_pte(pde_t* pde, void* addr)
  116. {
  117. return to_pte(to_pt(pde), addr);
  118. }
  119. inline pte_t* to_pte(pd_t pd, void* addr)
  120. {
  121. return to_pte(to_pde(pd, addr), addr);
  122. }
  123. inline pte_t* to_pte(pde_t* pde, page_t pg)
  124. {
  125. return to_pte(to_pt(pde), pg);
  126. }
  127. inline constexpr void* mmend(const mm* mm_area)
  128. {
  129. return (char*)mm_area->start + mm_area->pgs->size() * PAGE_SIZE;
  130. }
  131. // map the page to the end of the mm_area in pd
  132. int k_map(
  133. mm* mm_area,
  134. page* page,
  135. int read,
  136. int write,
  137. int priv,
  138. int cow);
  139. // @param len is aligned to 4kb boundary automatically, exceeding part will
  140. // be filled with '0's and not written back to the file
  141. int mmap(
  142. void* hint,
  143. size_t len,
  144. fs::inode* file,
  145. size_t offset,
  146. int write,
  147. int priv);
  148. // allocate a raw page
  149. page_t alloc_raw_page(void);
  150. // allocate n raw page(s)
  151. // @return the id of the first page allocated
  152. page_t alloc_n_raw_pages(size_t n);
  153. // allocate a struct page together with the raw page
  154. struct page allocate_page(void);
  155. pd_t alloc_pd(void);
  156. pt_t alloc_pt(void);