paging.hpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #pragma once
  2. #include <bit>
  3. #include <tuple>
  4. #include <cstddef>
  5. #include <stdint.h>
  6. #include <types/types.h>
  7. #include <kernel/mem/phys.hpp>
  8. namespace kernel::mem::paging {
  9. constexpr int idx_p5(uintptr_t vaddr) noexcept { return (vaddr >> 48) & 0x1ff; }
  10. constexpr int idx_p4(uintptr_t vaddr) noexcept { return (vaddr >> 39) & 0x1ff; }
  11. constexpr int idx_p3(uintptr_t vaddr) noexcept { return (vaddr >> 30) & 0x1ff; }
  12. constexpr int idx_p2(uintptr_t vaddr) noexcept { return (vaddr >> 21) & 0x1ff; }
  13. constexpr int idx_p1(uintptr_t vaddr) noexcept { return (vaddr >> 12) & 0x1ff; }
  14. constexpr std::tuple<int, int, int, int, int> idx_all(uintptr_t vaddr) noexcept
  15. {
  16. return {idx_p5(vaddr), idx_p4(vaddr), idx_p3(vaddr), idx_p2(vaddr), idx_p1(vaddr)};
  17. }
  18. // page frame number
  19. // since we have large pages now, pfns are not shifted right
  20. using pfn_t = uintptr_t;
  21. // paging structure attributes
  22. using psattr_t = uintptr_t;
  23. constexpr psattr_t PA_P = 0x0000000000000001ULL;
  24. constexpr psattr_t PA_RW = 0x0000000000000002ULL;
  25. constexpr psattr_t PA_US = 0x0000000000000004ULL;
  26. constexpr psattr_t PA_PWT = 0x0000000000000008ULL;
  27. constexpr psattr_t PA_PCD = 0x0000000000000010ULL;
  28. constexpr psattr_t PA_A = 0x0000000000000020ULL;
  29. constexpr psattr_t PA_D = 0x0000000000000040ULL;
  30. constexpr psattr_t PA_PS = 0x0000000000000080ULL;
  31. constexpr psattr_t PA_G = 0x0000000000000100ULL;
  32. constexpr psattr_t PA_COW = 0x0000000000000200ULL; // copy on write
  33. constexpr psattr_t PA_MMAP = 0x0000000000000400ULL; // memory mapped
  34. constexpr psattr_t PA_FRE = 0x0000000000000800ULL; // unused flag
  35. constexpr psattr_t PA_NXE = 0x8000000000000000ULL;
  36. constexpr psattr_t PA_MASK = 0xfff0000000000fffULL;
  37. namespace __inner {
  38. using pse_t = uint64_t;
  39. } // namespace __inner
  40. class PSE {
  41. physaddr<__inner::pse_t> m_ptrbase;
  42. public:
  43. explicit constexpr PSE(uintptr_t pptr) noexcept : m_ptrbase{pptr} {}
  44. constexpr void clear() noexcept
  45. {
  46. *m_ptrbase = 0;
  47. }
  48. constexpr void set(psattr_t attributes, pfn_t pfn)
  49. {
  50. *m_ptrbase = (attributes & PA_MASK) | (pfn & ~PA_MASK);
  51. }
  52. constexpr PSE operator[](std::size_t nth) const noexcept
  53. {
  54. return PSE{m_ptrbase.phys() + 8 * nth};
  55. }
  56. constexpr PSE parse() const noexcept
  57. {
  58. return PSE{*m_ptrbase & ~PA_MASK};
  59. }
  60. };
  61. constexpr PSE KERNEL_PAGE_TABLE{0x100000};
  62. constexpr unsigned long PAGE_PRESENT = 0x00000001;
  63. constexpr unsigned long PAGE_BUDDY = 0x00000002;
  64. struct page {
  65. refcount_t refcount;
  66. unsigned long flags;
  67. page* next;
  68. // padding
  69. uint64_t padding;
  70. };
  71. inline page* PAGE_ARRAY;
  72. void create_zone(uintptr_t start, uintptr_t end);
  73. // order represents power of 2
  74. page* alloc_page();
  75. page* alloc_pages(int order);
  76. void free_page(page* page, int order);
  77. pfn_t page_to_pfn(page* page);
  78. page* pfn_to_page(pfn_t pfn);
  79. } // namespace kernel::mem::paging