PageDirectory.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /*
  2. * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Badge.h>
  8. #include <AK/Types.h>
  9. #include <Kernel/Forward.h>
  10. #include <Kernel/PhysicalAddress.h>
  11. namespace Kernel {
  12. class PageDirectoryEntry {
  13. public:
  14. PhysicalPtr page_table_base() const { return PhysicalAddress::physical_page_base(m_raw); }
  15. void set_page_table_base(u32 value)
  16. {
  17. m_raw &= 0x8000000000000fffULL;
  18. m_raw |= PhysicalAddress::physical_page_base(value);
  19. }
  20. bool is_null() const { return m_raw == 0; }
  21. void clear() { m_raw = 0; }
  22. u64 raw() const { return m_raw; }
  23. void copy_from(Badge<Memory::PageDirectory>, const PageDirectoryEntry& other) { m_raw = other.m_raw; }
  24. enum Flags {
  25. Present = 1 << 0,
  26. ReadWrite = 1 << 1,
  27. UserSupervisor = 1 << 2,
  28. WriteThrough = 1 << 3,
  29. CacheDisabled = 1 << 4,
  30. Huge = 1 << 7,
  31. Global = 1 << 8,
  32. NoExecute = 0x8000000000000000ULL,
  33. };
  34. bool is_present() const { return raw() & Present; }
  35. void set_present(bool b) { set_bit(Present, b); }
  36. bool is_user_allowed() const { return raw() & UserSupervisor; }
  37. void set_user_allowed(bool b) { set_bit(UserSupervisor, b); }
  38. bool is_huge() const { return raw() & Huge; }
  39. void set_huge(bool b) { set_bit(Huge, b); }
  40. bool is_writable() const { return raw() & ReadWrite; }
  41. void set_writable(bool b) { set_bit(ReadWrite, b); }
  42. bool is_write_through() const { return raw() & WriteThrough; }
  43. void set_write_through(bool b) { set_bit(WriteThrough, b); }
  44. bool is_cache_disabled() const { return raw() & CacheDisabled; }
  45. void set_cache_disabled(bool b) { set_bit(CacheDisabled, b); }
  46. bool is_global() const { return raw() & Global; }
  47. void set_global(bool b) { set_bit(Global, b); }
  48. bool is_execute_disabled() const { return raw() & NoExecute; }
  49. void set_execute_disabled(bool b) { set_bit(NoExecute, b); }
  50. void set_bit(u64 bit, bool value)
  51. {
  52. if (value)
  53. m_raw |= bit;
  54. else
  55. m_raw &= ~bit;
  56. }
  57. private:
  58. u64 m_raw;
  59. };
  60. class PageTableEntry {
  61. public:
  62. PhysicalPtr physical_page_base() { return PhysicalAddress::physical_page_base(m_raw); }
  63. void set_physical_page_base(PhysicalPtr value)
  64. {
  65. m_raw &= 0x8000000000000fffULL;
  66. m_raw |= PhysicalAddress::physical_page_base(value);
  67. }
  68. u64 raw() const { return (u32)m_raw; }
  69. enum Flags {
  70. Present = 1 << 0,
  71. ReadWrite = 1 << 1,
  72. UserSupervisor = 1 << 2,
  73. WriteThrough = 1 << 3,
  74. CacheDisabled = 1 << 4,
  75. Global = 1 << 8,
  76. NoExecute = 0x8000000000000000ULL,
  77. };
  78. bool is_present() const { return raw() & Present; }
  79. void set_present(bool b) { set_bit(Present, b); }
  80. bool is_user_allowed() const { return raw() & UserSupervisor; }
  81. void set_user_allowed(bool b) { set_bit(UserSupervisor, b); }
  82. bool is_writable() const { return raw() & ReadWrite; }
  83. void set_writable(bool b) { set_bit(ReadWrite, b); }
  84. bool is_write_through() const { return raw() & WriteThrough; }
  85. void set_write_through(bool b) { set_bit(WriteThrough, b); }
  86. bool is_cache_disabled() const { return raw() & CacheDisabled; }
  87. void set_cache_disabled(bool b) { set_bit(CacheDisabled, b); }
  88. bool is_global() const { return raw() & Global; }
  89. void set_global(bool b) { set_bit(Global, b); }
  90. bool is_execute_disabled() const { return raw() & NoExecute; }
  91. void set_execute_disabled(bool b) { set_bit(NoExecute, b); }
  92. bool is_null() const { return m_raw == 0; }
  93. void clear() { m_raw = 0; }
  94. void set_bit(u64 bit, bool value)
  95. {
  96. if (value)
  97. m_raw |= bit;
  98. else
  99. m_raw &= ~bit;
  100. }
  101. private:
  102. u64 m_raw;
  103. };
  104. static_assert(sizeof(PageDirectoryEntry) == 8);
  105. static_assert(sizeof(PageTableEntry) == 8);
  106. class PageDirectoryPointerTable {
  107. public:
  108. PageDirectoryEntry* directory(size_t index)
  109. {
  110. VERIFY(index <= (NumericLimits<size_t>::max() << 30));
  111. return (PageDirectoryEntry*)(PhysicalAddress::physical_page_base(raw[index]));
  112. }
  113. u64 raw[512];
  114. };
  115. }