1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
#pragma once
#include "mm/page.h"
#include "vm/vmmap.h"
#define PT_PRESENT 0x001
#define PT_WRITE 0x002
#define PT_USER 0x004
#define PT_WRITE_THROUGH 0x008
#define PT_CACHE_DISABLED 0x010
#define PT_ACCESSED 0x020
#define PT_DIRTY 0x040
#define PT_SIZE 0x080
#define PT_GLOBAL 0x100
#define PT_ENTRY_COUNT (PAGE_SIZE / sizeof(uintptr_t))
typedef struct page
{
uint8_t data[PAGE_SIZE];
} page_t;
// Generalized structure for all directory like entries
typedef struct pt
{
uintptr_t phys[PT_ENTRY_COUNT];
} pt_t, pd_t, pdp_t, pml4_t;
#define INDEX_MASK 0b111111111
#define PML4E(x) ((((uintptr_t)(x)) >> 39) & INDEX_MASK)
#define PDPE(x) ((((uintptr_t)(x)) >> 30) & INDEX_MASK)
#define PDE(x) ((((uintptr_t)(x)) >> 21) & INDEX_MASK)
#define PTE(x) ((((uintptr_t)(x)) >> 12) & INDEX_MASK)
#define PT_ENTRY_COUNT (PAGE_SIZE / sizeof(uintptr_t))
#define PT_VADDR_SIZE (PAGE_SIZE * PT_ENTRY_COUNT)
#define PD_VADDR_SIZE (PAGE_SIZE * PT_ENTRY_COUNT * PT_ENTRY_COUNT)
#define PDP_VADDR_SIZE \
(PAGE_SIZE * PT_ENTRY_COUNT * PT_ENTRY_COUNT * PT_ENTRY_COUNT)
#define PML4_VADDR_SIZE \
(PAGE_SIZE * PT_ENTRY_COUNT * PT_ENTRY_COUNT * PT_ENTRY_COUNT * \
PT_ENTRY_COUNT)
#define IS_PRESENT(n) ((n)&PT_PRESENT)
#define IS_2MB_PAGE(n) ((n)&PT_SIZE)
#define IS_1GB_PAGE IS_2MB_PAGE
#define GDB_PT_PHYSADDR(pt, v) (pt->phys[PTE(v)] & PAGE_MASK)
#define GDB_PD_PHYSADDR(pd, v) (pd->phys[PDE(v)] & PAGE_MASK)
#define GDB_PDP_PHYSADDR(pdp, v) (pdp->phys[PDPE(v)] & PAGE_MASK)
#define GDB_PML4_PHYSADDR(pml4, v) (pml4->phys[PML4E(v)] & PAGE_MASK)
#define GDB_PHYSADDR(pml4, v) \
(GDB_PT_PHYSADDR( \
GDB_PD_PHYSADDR( \
GDB_PDP_PHYSADDR(GDB_PML4_PHYSADDR(pml4, (v)) + PHYS_OFFSET, \
(v)) + \
PHYS_OFFSET, \
(v)) + \
PHYS_OFFSET, \
(v)) + \
PHYS_OFFSET)
#define GDB_CUR_PHYSADDR(v) GDB_PHYSADDR(curproc->p_pml4, (v))
uintptr_t pt_virt_to_phys_helper(pml4_t *pml4, uintptr_t vaddr);
uintptr_t pt_virt_to_phys(uintptr_t vaddr);
void pt_init(void);
/* Currently unused. */
void pt_template_init(void);
pml4_t *pt_get();
void pt_set(pml4_t *pml4);
pml4_t *clone_pml4(pml4_t *pml4, long include_user_mappings);
pml4_t *pt_create();
void pt_destroy(pml4_t *pml4);
long pt_map(pml4_t *pml4, uintptr_t paddr, uintptr_t vaddr, uint32_t pdflags,
uint32_t ptflags);
long pt_map_range(pml4_t *pml4, uintptr_t paddr, uintptr_t vaddr,
uintptr_t vmax, uint32_t pdflags, uint32_t ptflags);
void pt_unmap(pml4_t *pml4, uintptr_t vaddr);
void pt_unmap_range(pml4_t *pml4, uintptr_t vaddr, uintptr_t vmax);
void check_invalid_mappings(pml4_t *pml4, vmmap_t *vmmap, char *prompt);
|