Xyris  0.5
Memory.i686.hpp
Go to the documentation of this file.
1 /**
2  * @file Memory.i686.hpp
3  * @author Keeton Feavel ([email protected])
4  * @brief i686 memory structures and definitions. C & C++ compatible header.
5  * @version 0.1
6  * @date 2021-10-26
7  *
8  * @copyright Copyright the Xyris Contributors (c) 2021
9  *
10  */
11 #pragma once
12 #include <stdint.h>
13 #include <stddef.h>
14 #ifndef __cplusplus
15  // C needs bool type definition
16  #include <stdbool.h>
17 #endif
18 
19 #define ARCH_PAGE_DIR_ENTRIES 1024
20 #define ARCH_PAGE_TABLE_ENTRIES 1024
21 #define ARCH_PAGE_SIZE 4096
22 #define ARCH_PAGE_ALIGN 0xFFFFF000
23 #define ARCH_PAGE_DIR_ENTRY_SHIFT 22 // Shift to convert address to 0-1023 directory index
24 #define ARCH_PAGE_TABLE_ENTRY_SHIFT 12 // Shift to convert address to page address (2^12 = 4096 = PAGE_SIZE)
25 #define ARCH_PAGE_TABLE_ENTRY_MASK 0x3ff // Mask off top 10 bits to get 0-1023 index
26 
27 /* Only use namespace when including with C++ source so that the
28  bootloader to kernel bootstrap source can access these structs
29  It's a bit hacky since normally C++ includes C headers that have
30  C++ include guards, but because Xyris is primarily C++ with a
31  little bit of C, it makes more sense to do it this way */
32 #ifdef __cplusplus
33 namespace Arch::Memory {
34 #endif
35 
36 /**
37  * @brief Page frame structure. This represents a the
38  * address to a single unit of memory in RAM.
39  * (Chunk of physical memory)
40  *
41  */
42 struct Frame {
43  uint32_t offset : 12; // Page offset address
44  uint32_t index : 20; // Page frame index
45 };
46 
47 /**
48  * @brief Virtual address structure. Represents an address
49  * in virtual memory that redirects to a physical page frame.
50  * (Chunk of virtual memory)
51  */
52 struct Page {
53  uint32_t offset : 12; // Page offset address
54  uint32_t tableIndex : 10; // Page table entry
55  uint32_t dirIndex : 10; // Page directory entry
56 };
57 
58 /**
59  * @brief Page table entry defined in accordance to the
60  * Intel Developer Manual Vol. 3a p. 4-12
61  *
62  */
63 struct TableEntry
64 {
65  uint32_t present : 1; // Page present in memory
66  uint32_t readWrite : 1; // Read-only if clear, readwrite if set
67  uint32_t usermode : 1; // Supervisor level only if clear
68  uint32_t writeThrough : 1; // Page level write through
69  uint32_t cacheDisable : 1; // Disables TLB caching of page entry
70  uint32_t accessed : 1; // Has the page been accessed since last refresh?
71  uint32_t dirty : 1; // Has the page been written to since last refresh?
72  uint32_t pageAttrTable : 1; // Page attribute table (memory cache control)
73  uint32_t global : 1; // Prevents the TLB from updating the address
74  uint32_t unused : 3; // Amalgamation of unused and reserved bits
75  uint32_t frame : 20; // Frame address (shifted right 12 bits)
76 };
77 
78 /**
79  * @brief Page table structure as defined in accordance to the
80  * Intel Developer Manual Vol. 3a p. 4-12
81  *
82  */
83 struct Table
84 {
85  struct TableEntry pages[1024]; // All entries for the table
86 };
87 
88 /**
89  * @brief Page directory entry structure as defined in accordance to the
90  * Intel Developer Manual Vol. 3a p. 4-12
91  *
92  */
94 {
95  uint32_t present : 1; // Is the page present in physical memory?
96  uint32_t readWrite : 1; // Is the page read/write or read-only?
97  uint32_t usermode : 1; // Can the page be accessed in usermode?
98  uint32_t writeThrough : 1; // Is write-through cache enabled?
99  uint32_t cacheDisable : 1; // Can the page be cached?
100  uint32_t accessed : 1; // Has the page been accessed?
101  uint32_t ignoredA : 1; // Ignored
102  uint32_t size : 1; // Is the page 4 Mb (enabled) or 4 Kb (disabled)?
103  uint32_t ignoredB : 4; // Ignored
104  uint32_t tableAddr : 20; // Physical address of the table
105 };
106 
107 /**
108  * @brief Page directory contains pointers to all of the virtual memory addresses for the
109  * page tables along with their corresponding physical memory locations of the page tables.
110  * Page table entry defined in accordance to the Intel Developer Manual Vol. 3a p. 4-12.
111  *
112  */
113 struct Directory
114 {
115  struct DirectoryEntry entries[1024]; // Pointers that the Intel CPU uses to access pages in memory
116 };
117 
118 /* Only provide the Address class to C++ source so that this header can
119  be included by the bootstrap C source */
120 #ifdef __cplusplus
121 /**
122  * @brief Address class. Represents a memory address that can
123  * be used to address a page in virtual memory, a frame in
124  * physical memory. Allows setting the value of these addresses
125  * by also including an uintptr_t representation.
126  *
127  */
128 class Address
129 {
130 public:
131  Address(uintptr_t addr) {
132  m_addr.val = addr;
133  }
134 
135  Address(struct Frame frame) {
136  m_addr.frame = frame;
137  }
138 
139  Address(struct Page page) {
140  m_addr.page = page;
141  }
142 
143  operator struct Page() {
144  return m_addr.page;
145  }
146 
147  operator struct Frame() {
148  return m_addr.frame;
149  }
150 
151  operator uintptr_t() {
152  return m_addr.val;
153  }
154 
155  uintptr_t operator+= (const uintptr_t& val) {
156  m_addr.val += val;
157  return m_addr.val;
158  }
159 
160  uintptr_t operator-= (const uintptr_t& val) {
161  m_addr.val -= val;
162  return m_addr.val;
163  }
164 
165  uintptr_t operator= (const uintptr_t& val) {
166  m_addr.val = val;
167  return m_addr.val;
168  }
169 
170  struct Page page() {
171  return m_addr.page;
172  }
173 
174  struct Frame frame() {
175  return m_addr.frame;
176  }
177 
178  uintptr_t val() {
179  return m_addr.val;
180  }
181 
182 private:
183  union {
184  struct Page page;
185  struct Frame frame;
186  uintptr_t val;
187  } m_addr;
188 };
189 #endif
190 
191 /**
192  * @brief Invalidate the page at the given address. Implementations are architecture
193  * specific.
194  *
195  * @param addr Address of page to be invalidated
196  */
197 static inline void pageInvalidate(void* addr)
198 {
199  asm volatile(
200  "invlpg (%0)"
201  :
202  : "r" (addr)
203  : "memory"
204  );
205 }
206 
207 /**
208  * @brief Writes the address of the page directory to CR3.
209  * Does not enable paging.
210  *
211  * @param pageDirPtr Address of page directory structure to be used
212  */
213 __attribute__((always_inline))
214 static inline void setPageDirectory(uintptr_t pageDirPtr)
215 {
216  asm volatile(
217  "mov %0, %%cr3"
218  :
219  : "b" (pageDirPtr)
220  : "memory"
221  );
222 }
223 
224 /**
225  * @brief Aligns the provided address to the start of its corresponding page address.
226  *
227  * @param addr Address to be aligned
228  * @return uintptr_t Page aligned address value
229  */
230 static inline uintptr_t pageAlign(size_t addr)
231 {
232  return addr & ARCH_PAGE_ALIGN;
233 }
234 
235 /**
236  * @brief Check if an address is aligned to a page boundary.
237  *
238  * @param addr Address to be checked
239  * @return true Address is aligned to page boundary
240  * @return false Address is not aligned to a page boundary
241  */
242 static inline bool pageIsAligned(size_t addr)
243 {
244  return ((addr % ARCH_PAGE_SIZE) == 0);
245 }
246 
247 #ifdef __cplusplus
248 } // !namespace Arch::Memory
249 #endif
DirectoryEntry::ignoredA
uint32_t ignoredA
Definition: Memory.i686.hpp:101
Page::offset
uint32_t offset
Definition: Memory.i686.hpp:53
DirectoryEntry::writeThrough
uint32_t writeThrough
Definition: Memory.i686.hpp:98
Page
Virtual address structure. Represents an address in virtual memory that redirects to a physical page ...
Definition: Memory.i686.hpp:52
ARCH_PAGE_ALIGN
#define ARCH_PAGE_ALIGN
Definition: Memory.i686.hpp:22
TableEntry::unused
uint32_t unused
Definition: Memory.i686.hpp:74
Arch::Memory
Definition: Arch.i686.cpp:92
TableEntry::accessed
uint32_t accessed
Definition: Memory.i686.hpp:70
DirectoryEntry::size
uint32_t size
Definition: Memory.i686.hpp:102
TableEntry::readWrite
uint32_t readWrite
Definition: Memory.i686.hpp:66
DirectoryEntry::readWrite
uint32_t readWrite
Definition: Memory.i686.hpp:96
Frame::index
uint32_t index
Definition: Memory.i686.hpp:44
Directory
Page directory contains pointers to all of the virtual memory addresses for the page tables along wit...
Definition: Memory.i686.hpp:113
DirectoryEntry::accessed
uint32_t accessed
Definition: Memory.i686.hpp:100
DirectoryEntry
Page directory entry structure as defined in accordance to the Intel Developer Manual Vol....
Definition: Memory.i686.hpp:93
TableEntry::frame
uint32_t frame
Definition: Memory.i686.hpp:75
DirectoryEntry::usermode
uint32_t usermode
Definition: Memory.i686.hpp:97
TableEntry
Page table entry defined in accordance to the Intel Developer Manual Vol. 3a p. 4-12.
Definition: Memory.i686.hpp:63
TableEntry::dirty
uint32_t dirty
Definition: Memory.i686.hpp:71
TableEntry::pageAttrTable
uint32_t pageAttrTable
Definition: Memory.i686.hpp:72
Table
Page table structure as defined in accordance to the Intel Developer Manual Vol. 3a p....
Definition: Memory.i686.hpp:83
DirectoryEntry::ignoredB
uint32_t ignoredB
Definition: Memory.i686.hpp:103
Page::tableIndex
uint32_t tableIndex
Definition: Memory.i686.hpp:54
__attribute__
__attribute__((always_inline)) static inline void setPageDirectory(uintptr_t pageDirPtr)
Writes the address of the page directory to CR3. Does not enable paging.
Definition: Memory.i686.hpp:213
TableEntry::writeThrough
uint32_t writeThrough
Definition: Memory.i686.hpp:68
Frame
Page frame structure. This represents a the address to a single unit of memory in RAM....
Definition: Memory.i686.hpp:42
DirectoryEntry::tableAddr
uint32_t tableAddr
Definition: Memory.i686.hpp:104
Page::dirIndex
uint32_t dirIndex
Definition: Memory.i686.hpp:55
TableEntry::global
uint32_t global
Definition: Memory.i686.hpp:73
DirectoryEntry::cacheDisable
uint32_t cacheDisable
Definition: Memory.i686.hpp:99
ARCH_PAGE_SIZE
#define ARCH_PAGE_SIZE
Definition: Memory.i686.hpp:21
TableEntry::present
uint32_t present
Definition: Memory.i686.hpp:65
Frame::offset
uint32_t offset
Definition: Memory.i686.hpp:43
DirectoryEntry::present
uint32_t present
Definition: Memory.i686.hpp:95
TableEntry::usermode
uint32_t usermode
Definition: Memory.i686.hpp:67
TableEntry::cacheDisable
uint32_t cacheDisable
Definition: Memory.i686.hpp:69