mm.hpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #pragma once
  2. #include <kernel/mem.h>
  3. #include <types/allocator.hpp>
  4. #include <types/list.hpp>
  5. #include <types/types.h>
  6. #include <types/vector.hpp>
  7. struct page_attr {
  8. uint32_t cow : 1;
  9. };
  10. struct page {
  11. page_t phys_page_id;
  12. size_t* ref_count;
  13. struct page_attr attr;
  14. };
  15. using page_arr = types::vector<page, types::kernel_ident_allocator>;
  16. struct mm_attr {
  17. uint32_t read : 1;
  18. uint32_t write : 1;
  19. uint32_t system : 1;
  20. };
  21. struct mm {
  22. linr_ptr_t start;
  23. struct mm_attr attr;
  24. page_arr* pgs;
  25. page_directory_entry* pd;
  26. };
  27. using mm_list = types::list<mm, types::kernel_ident_allocator>;
  28. // in mem.cpp
  29. extern mm_list* kernel_mms;
  30. extern page empty_page;
  31. // translate physical address to virtual(mapped) address
  32. void* p_ptr_to_v_ptr(phys_ptr_t p_ptr);
  33. // translate linear address to physical address
  34. phys_ptr_t l_ptr_to_p_ptr(const mm_list* mms, linr_ptr_t v_ptr);
  35. // translate virtual(mapped) address to physical address
  36. phys_ptr_t v_ptr_to_p_ptr(void* v_ptr);
  37. // check if the l_ptr is contained in the area
  38. // @return GB_OK if l_ptr is in the area
  39. // GB_FAILED if not
  40. int is_l_ptr_valid(const mm_list* mms, linr_ptr_t l_ptr);
  41. // find the corresponding page the l_ptr pointing to
  42. // @return the pointer to the struct if found, NULL if not found
  43. struct page* find_page_by_l_ptr(const mm_list* mms, linr_ptr_t l_ptr);
  44. static inline page_t phys_addr_to_page(phys_ptr_t ptr)
  45. {
  46. return ptr >> 12;
  47. }
  48. static inline pd_i_t page_to_pd_i(page_t p)
  49. {
  50. return p >> 10;
  51. }
  52. static inline pt_i_t page_to_pt_i(page_t p)
  53. {
  54. return p & (1024 - 1);
  55. }
  56. static inline phys_ptr_t page_to_phys_addr(page_t p)
  57. {
  58. return p << 12;
  59. }
  60. static inline pd_i_t linr_addr_to_pd_i(linr_ptr_t ptr)
  61. {
  62. return page_to_pd_i(phys_addr_to_page(ptr));
  63. }
  64. static inline pd_i_t linr_addr_to_pt_i(linr_ptr_t ptr)
  65. {
  66. return page_to_pt_i(phys_addr_to_page(ptr));
  67. }
  68. static inline page_directory_entry* mms_get_pd(const mm_list* mms)
  69. {
  70. return mms->begin()->pd;
  71. }
  72. static inline page_directory_entry* lptr_to_pde(const mm_list* mms, linr_ptr_t l_ptr)
  73. {
  74. return mms_get_pd(mms) + linr_addr_to_pd_i((phys_ptr_t)l_ptr);
  75. }
  76. static inline page_table_entry* lptr_to_pte(const mm_list* mms, linr_ptr_t l_ptr)
  77. {
  78. page_directory_entry* pde = lptr_to_pde(mms, l_ptr);
  79. page_table_entry* pte = (page_table_entry*)p_ptr_to_v_ptr(page_to_phys_addr(pde->in.pt_page));
  80. return pte + linr_addr_to_pt_i((phys_ptr_t)l_ptr);
  81. }
  82. static inline page_directory_entry* lp_to_pde(const mm_list* mms, linr_ptr_t l_ptr)
  83. {
  84. phys_ptr_t p_ptr = l_ptr_to_p_ptr(mms, l_ptr);
  85. page_directory_entry* pde = mms_get_pd(mms) + linr_addr_to_pd_i(p_ptr);
  86. return pde;
  87. }
  88. // get the corresponding pte for the linear address
  89. // for example: l_ptr = 0x30001000 will return the pte including the page it is mapped to
  90. static inline page_table_entry* lp_to_pte(const mm_list* mms, linr_ptr_t l_ptr)
  91. {
  92. phys_ptr_t p_ptr = l_ptr_to_p_ptr(mms, l_ptr);
  93. page_directory_entry* pde = lp_to_pde(mms, l_ptr);
  94. phys_ptr_t p_pt = page_to_phys_addr(pde->in.pt_page);
  95. page_table_entry* pte = (page_table_entry*)p_ptr_to_v_ptr(p_pt);
  96. pte += linr_addr_to_pt_i(p_ptr);
  97. return pte;
  98. }
  99. // map the page to the end of the mm_area in pd
  100. int k_map(
  101. mm* mm_area,
  102. const struct page* page,
  103. int read,
  104. int write,
  105. int priv,
  106. int cow);
  107. // allocate a raw page
  108. page_t alloc_raw_page(void);
  109. // allocate a struct page together with the raw page
  110. struct page allocate_page(void);
  111. page_directory_entry* alloc_pd(void);
  112. page_table_entry* alloc_pt(void);