MonkOS  v0.1
A simple 64-bit operating system (x86_64)
paging.h
Go to the documentation of this file.
1 //============================================================================
2 /// @file paging.h
3 /// @brief Paged memory management.
4 //
5 // Copyright 2016 Brett Vickers.
6 // Use of this source code is governed by a BSD-style license that can
7 // be found in the MonkOS LICENSE file.
8 //============================================================================
9 
10 #pragma once
11 
12 #include <core.h>
13 
14 // Pag size constants
15 #define PAGE_SIZE 0x1000
16 #define PAGE_SIZE_LARGE 0x200000
17 #define PAGE_SIZE_HUGE 0x40000000
18 
19 // Page table entry flags
20 #define PF_PRESENT (1 << 0) // Page is present in the table
21 #define PF_RW (1 << 1) // Read-write
22 #define PF_USER (1 << 2) // User-mode (CPL==3) access allowed
23 #define PF_PWT (1 << 3) // Page write-thru
24 #define PF_PCD (1 << 4) // Cache disable
25 #define PF_ACCESS (1 << 5) // Indicates whether page was accessed
26 #define PF_DIRTY (1 << 6) // Indicates whether 4K page was written
27 #define PF_PS (1 << 7) // Page size (valid for PD and PDPT only)
28 #define PF_GLOBAL (1 << 8) // Indicates the page is globally cached
29 #define PF_SYSTEM (1 << 9) // Page used by the kernel
30 
31 // Virtual address bitmasks and shifts
32 #define PGSHIFT_PML4E 39
33 #define PGSHIFT_PDPTE 30
34 #define PGSHIFT_PDE 21
35 #define PGSHIFT_PTE 12
36 #define PGMASK_ENTRY 0x1ff
37 #define PGMASK_OFFSET 0x3ff
38 
39 // Virtual address subfield accessors
40 #define PML4E(a) (((a) >> PGSHIFT_PML4E) & PGMASK_ENTRY)
41 #define PDPTE(a) (((a) >> PGSHIFT_PDPTE) & PGMASK_ENTRY)
42 #define PDE(a) (((a) >> PGSHIFT_PDE) & PGMASK_ENTRY)
43 #define PTE(a) (((a) >> PGSHIFT_PTE) & PGMASK_ENTRY)
44 
45 // Page table entry helpers
46 #define PGPTR(pte) ((page_t *)((pte) & ~PGMASK_OFFSET))
47 
48 //----------------------------------------------------------------------------
49 // @union page_t
50 /// @brief A pagetable page record.
51 /// @details Contains 512 page table entries if the page holds a page
52 /// table. Otherwise it contains 4096 bytes of memory.
53 //----------------------------------------------------------------------------
54 typedef union page
55 {
56  uint64_t entry[PAGE_SIZE / sizeof(uint64_t)];
57  uint8_t memory[PAGE_SIZE];
58 } page_t;
59 
60 //----------------------------------------------------------------------------
61 // @struct pagetable_t
62 /// @brief A pagetable structure.
63 /// @details Holds all the page table entries that map virtual addresses to
64 /// physical addresses.
65 //----------------------------------------------------------------------------
66 typedef struct pagetable
67 {
68  uint64_t proot; ///< Physical address of root page table (PML4T) entry
69  uint64_t vroot; ///< Virtual address of root page table (PML4T) entry
70  uint64_t vnext; ///< Virtual address to use for table's next page
71  uint64_t vterm; ///< Boundary of pages used to store the table
72 } pagetable_t;
73 
74 //----------------------------------------------------------------------------
75 // @function page_init
76 /// @brief Initialize the page frame database.
77 /// @details The page frame database manages the physical memory used by
78 /// all memory pages known to the kernel.
79 //----------------------------------------------------------------------------
80 void
81 page_init();
82 
83 //----------------------------------------------------------------------------
84 // @function pagetable_create
85 /// @brief Create a new page table that can be used to associate virtual
86 /// addresses with physical addresses. The page table includes
87 /// protected mappings for kernel memory.
88 /// @param[in] pt A pointer to the pagetable structure that will hold
89 /// the page table.
90 /// @param[in] vaddr The virtual address within the new page table where
91 /// the page table will be mapped.
92 /// @param[in] size Maximum size of the page table in bytes. Must be a
93 /// multiple of PAGE_SIZE.
94 /// @returns A handle to the created page table.
95 //----------------------------------------------------------------------------
96 void
97 pagetable_create(pagetable_t *pt, void *vaddr, uint64_t size);
98 
99 //----------------------------------------------------------------------------
100 // @function pagetable_destroy
101 /// @brief Destroy a page table.
102 /// @param[in] pt A handle to the page table to destroy.
103 //----------------------------------------------------------------------------
104 void
106 
107 //----------------------------------------------------------------------------
108 // @function pagetable_activate
109 /// @brief Activate a page table on the CPU, so all virtual memory
110 /// operations are performed relative to the page table.
111 /// @param[in] pt A handle to the activated page table. Pass NULL to
112 /// activate the kernel page table.
113 //----------------------------------------------------------------------------
114 void
116 
117 //----------------------------------------------------------------------------
118 // @function page_alloc
119 /// @brief Allocate one or more pages contiguous in virtual memory.
120 /// @param[in] pt Handle to the page table from which to allocate the
121 /// page(s).
122 /// @param[in] vaddr The virtual address of the first allocated page.
123 /// @param[in] count The number of contiguous virtual memory pages to
124 /// allocate.
125 /// @returns A virtual memory pointer to the first page allocated.
126 //----------------------------------------------------------------------------
127 void *
128 page_alloc(pagetable_t *pt, void *vaddr, int count);
129 
130 //----------------------------------------------------------------------------
131 // @function page_free
132 /// @brief Free one or more contiguous pages from virtual memory.
133 /// @param[in] pt Handle to ehte page table from which to free the
134 /// page(s).
135 /// @param[in] vaddr The virtual address of the first allocated page.
136 /// @param[in] count The number of contiguous virtual memory pages to free.
137 //----------------------------------------------------------------------------
138 void
139 page_free(pagetable_t *pt, void *vaddr, int count);
Core include file.
A pagetable structure.
Definition: paging.h:66
void * page_alloc(pagetable_t *pt, void *vaddr, int count)
Allocate one or more pages contiguous in virtual memory.
Definition: paging.c:415
A pagetable page record.
Definition: paging.h:54
#define PAGE_SIZE
Definition: paging.h:15
uint64_t proot
Physical address of root page table (PML4T) entry.
Definition: paging.h:68
void pagetable_create(pagetable_t *pt, void *vaddr, uint64_t size)
Create a new page table that can be used to associate virtual addresses with physical addresses...
Definition: paging.c:364
uint64_t vnext
Virtual address to use for table&#39;s next page.
Definition: paging.h:70
void page_free(pagetable_t *pt, void *vaddr, int count)
Free one or more contiguous pages from virtual memory.
Definition: paging.c:425
void pagetable_destroy(pagetable_t *pt)
Destroy a page table.
Definition: paging.c:383
uint64_t vterm
Boundary of pages used to store the table.
Definition: paging.h:71
uint64_t vroot
Virtual address of root page table (PML4T) entry.
Definition: paging.h:69
void pagetable_activate(pagetable_t *pt)
Activate a page table on the CPU, so all virtual memory operations are performed relative to the page...
Definition: paging.c:403
void page_init()
Initialize the page frame database.
Definition: paging.c:107