mm.hpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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. // translate physical address to virtual(mapped) address
  31. void* p_ptr_to_v_ptr(phys_ptr_t p_ptr);
  32. // translate linear address to physical address
  33. phys_ptr_t l_ptr_to_p_ptr(const mm_list* mms, linr_ptr_t v_ptr);
  34. // translate virtual(mapped) address to physical address
  35. phys_ptr_t v_ptr_to_p_ptr(void* v_ptr);
  36. // check if the l_ptr is contained in the area
  37. // @return GB_OK if l_ptr is in the area
  38. // GB_FAILED if not
  39. int is_l_ptr_valid(const mm_list* mms, linr_ptr_t l_ptr);
  40. // find the corresponding page the l_ptr pointing to
  41. // @return the pointer to the struct if found, NULL if not found
  42. struct page* find_page_by_l_ptr(const mm_list* mms, linr_ptr_t l_ptr);
  43. static inline page_t phys_addr_to_page(phys_ptr_t ptr)
  44. {
  45. return ptr >> 12;
  46. }
  47. static inline pd_i_t page_to_pd_i(page_t p)
  48. {
  49. return p >> 10;
  50. }
  51. static inline pt_i_t page_to_pt_i(page_t p)
  52. {
  53. return p & (1024 - 1);
  54. }
  55. static inline phys_ptr_t page_to_phys_addr(page_t p)
  56. {
  57. return p << 12;
  58. }
  59. static inline pd_i_t linr_addr_to_pd_i(linr_ptr_t ptr)
  60. {
  61. return page_to_pd_i(phys_addr_to_page(ptr));
  62. }
  63. static inline pd_i_t linr_addr_to_pt_i(linr_ptr_t ptr)
  64. {
  65. return page_to_pt_i(phys_addr_to_page(ptr));
  66. }
  67. static inline page_directory_entry* mms_get_pd(const mm_list* mms)
  68. {
  69. return mms->begin()->pd;
  70. }
  71. static inline page_directory_entry* lptr_to_pde(const mm_list* mms, linr_ptr_t l_ptr)
  72. {
  73. return mms_get_pd(mms) + linr_addr_to_pd_i((phys_ptr_t)l_ptr);
  74. }
  75. static inline page_table_entry* lptr_to_pte(const mm_list* mms, linr_ptr_t l_ptr)
  76. {
  77. page_directory_entry* pde = lptr_to_pde(mms, l_ptr);
  78. page_table_entry* pte = (page_table_entry*)p_ptr_to_v_ptr(page_to_phys_addr(pde->in.pt_page));
  79. return pte + linr_addr_to_pt_i((phys_ptr_t)l_ptr);
  80. }
  81. static inline page_directory_entry* lp_to_pde(const mm_list* mms, linr_ptr_t l_ptr)
  82. {
  83. phys_ptr_t p_ptr = l_ptr_to_p_ptr(mms, l_ptr);
  84. page_directory_entry* pde = mms_get_pd(mms) + linr_addr_to_pd_i(p_ptr);
  85. return pde;
  86. }
  87. // get the corresponding pte for the linear address
  88. // for example: l_ptr = 0x30001000 will return the pte including the page it is mapped to
  89. static inline page_table_entry* lp_to_pte(const mm_list* mms, linr_ptr_t l_ptr)
  90. {
  91. phys_ptr_t p_ptr = l_ptr_to_p_ptr(mms, l_ptr);
  92. page_directory_entry* pde = lp_to_pde(mms, l_ptr);
  93. phys_ptr_t p_pt = page_to_phys_addr(pde->in.pt_page);
  94. page_table_entry* pte = (page_table_entry*)p_ptr_to_v_ptr(p_pt);
  95. pte += linr_addr_to_pt_i(p_ptr);
  96. return pte;
  97. }
  98. // map the page to the end of the mm_area in pd
  99. int k_map(
  100. mm* mm_area,
  101. const struct page* page,
  102. int read,
  103. int write,
  104. int priv,
  105. int cow);
  106. // allocate a raw page
  107. page_t alloc_raw_page(void);
  108. // allocate a struct page together with the raw page
  109. struct page allocate_page(void);