paging.hpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #pragma once
  2. #include <cstddef>
  3. #include <tuple>
  4. #include <stdint.h>
  5. #include <kernel/mem/paging_asm.h>
  6. #include <kernel/mem/phys.hpp>
  7. namespace kernel::mem::paging {
  8. constexpr int idx_p5(uintptr_t vaddr) noexcept {
  9. return (vaddr >> 48) & 0x1ff;
  10. }
  11. constexpr int idx_p4(uintptr_t vaddr) noexcept {
  12. return (vaddr >> 39) & 0x1ff;
  13. }
  14. constexpr int idx_p3(uintptr_t vaddr) noexcept {
  15. return (vaddr >> 30) & 0x1ff;
  16. }
  17. constexpr int idx_p2(uintptr_t vaddr) noexcept {
  18. return (vaddr >> 21) & 0x1ff;
  19. }
  20. constexpr int idx_p1(uintptr_t vaddr) noexcept {
  21. return (vaddr >> 12) & 0x1ff;
  22. }
  23. constexpr std::tuple<int, int, int, int, int> idx_all(uintptr_t vaddr) noexcept {
  24. return {idx_p5(vaddr), idx_p4(vaddr), idx_p3(vaddr), idx_p2(vaddr), idx_p1(vaddr)};
  25. }
  26. // page frame number
  27. // since we have large pages now, pfns are not shifted right
  28. using pfn_t = uintptr_t;
  29. // paging structure attributes
  30. using psattr_t = uintptr_t;
  31. constexpr psattr_t PA_DATA = PA_P | PA_RW | PA_NXE;
  32. constexpr psattr_t PA_KERNEL_DATA = PA_DATA | PA_G;
  33. constexpr psattr_t PA_USER_DATA = PA_DATA | PA_G | PA_US;
  34. constexpr psattr_t PA_PAGE_TABLE = PA_P | PA_RW;
  35. constexpr psattr_t PA_KERNEL_PAGE_TABLE = PA_PAGE_TABLE | PA_G;
  36. constexpr psattr_t PA_DATA_HUGE = PA_DATA | PA_PS;
  37. constexpr psattr_t PA_KERNEL_DATA_HUGE = PA_DATA_HUGE | PA_G;
  38. constexpr psattr_t PA_USER_DATA_HUGE = PA_DATA_HUGE | PA_US;
  39. namespace __inner {
  40. using pse_t = uint64_t;
  41. } // namespace __inner
  42. class PSE {
  43. physaddr<__inner::pse_t> m_ptrbase;
  44. public:
  45. explicit constexpr PSE(uintptr_t pptr) noexcept : m_ptrbase{pptr} {}
  46. constexpr void clear() noexcept { *m_ptrbase = 0; }
  47. constexpr void set(psattr_t attributes, pfn_t pfn) {
  48. *m_ptrbase = (attributes & PA_MASK) | (pfn & ~PA_MASK);
  49. }
  50. constexpr pfn_t pfn() const noexcept { return *m_ptrbase & ~PA_MASK; }
  51. constexpr psattr_t attributes() const noexcept { return *m_ptrbase & PA_MASK; }
  52. constexpr PSE operator[](std::size_t nth) const noexcept {
  53. return PSE{m_ptrbase.phys() + 8 * nth};
  54. }
  55. constexpr PSE parse() const noexcept { return PSE{*m_ptrbase & ~PA_MASK}; }
  56. };
  57. constexpr physaddr<void> KERNEL_PAGE_TABLE_PHYS_ADDR{KERNEL_PML4};
  58. constexpr PSE KERNEL_PAGE_TABLE{KERNEL_PML4};
  59. constexpr unsigned long PAGE_PRESENT = 0x00010000;
  60. constexpr unsigned long PAGE_BUDDY = 0x00020000;
  61. constexpr unsigned long PAGE_SLAB = 0x00040000;
  62. struct page {
  63. // TODO: use atomic
  64. unsigned long refcount;
  65. unsigned long flags;
  66. page* next;
  67. page* prev;
  68. };
  69. inline page* PAGE_ARRAY;
  70. constexpr unsigned long PAGE_FAULT_P = 0x00000001;
  71. constexpr unsigned long PAGE_FAULT_W = 0x00000002;
  72. constexpr unsigned long PAGE_FAULT_U = 0x00000004;
  73. constexpr unsigned long PAGE_FAULT_R = 0x00000008;
  74. constexpr unsigned long PAGE_FAULT_I = 0x00000010;
  75. constexpr unsigned long PAGE_FAULT_PK = 0x00000020;
  76. constexpr unsigned long PAGE_FAULT_SS = 0x00000040;
  77. constexpr unsigned long PAGE_FAULT_SGX = 0x00008000;
  78. } // namespace kernel::mem::paging
  79. struct Page;
  80. extern "C" Page* c_alloc_page();
  81. extern "C" Page* c_alloc_pages(uint32_t order);
  82. extern "C" uintptr_t c_alloc_page_table();
  83. extern "C" uintptr_t page_to_pfn(Page* page);