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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
/*
* ========================================================
*
* HCore
* Copyright Mahrouss Logic, all rights reserved.
*
* ========================================================
*/
#include <KernelKit/DebugOutput.hpp>
#include <NewKit/PageManager.hpp>
namespace HCore {
PTEWrapper::PTEWrapper(Boolean Rw, Boolean User, Boolean ExecDisable,
UIntPtr VirtAddr)
: m_Rw(Rw),
m_User(User),
m_ExecDisable(ExecDisable),
m_VirtAddr(VirtAddr),
m_Cache(false),
m_Shareable(false),
m_Wt(false),
m_Present(true),
m_Accessed(false) {
// special case for the null region.
if (VirtAddr == 0) {
m_Wt = false;
m_Rw = false;
m_Cache = false;
m_Shareable = false;
}
}
PTEWrapper::~PTEWrapper() {
PTE *raw = reinterpret_cast<PTE *>(m_VirtAddr);
MUST_PASS(raw);
MUST_PASS(!raw->Accessed);
if (raw->Present) raw->Present = false;
}
void PTEWrapper::FlushTLB(Ref<PageManager> &pm) {
pm.Leak().FlushTLB(this->m_VirtAddr);
}
void PageManager::FlushTLB(UIntPtr VirtAddr) {
if (VirtAddr == kBadAddress) return;
flush_tlb(VirtAddr);
}
bool PTEWrapper::Reclaim() {
if (!this->m_Present) {
this->m_Present = true;
return true;
}
return false;
}
PTEWrapper *PageManager::Request(Boolean Rw, Boolean User,
Boolean ExecDisable) {
PTEWrapper *PageTableEntry = reinterpret_cast<PTEWrapper *>(
HCore::HAL::hal_alloc_page(sizeof(PTEWrapper), Rw, User));
if (PageTableEntry == nullptr) {
kcout << "PTEWrapper : Page table is nullptr!, ke_new_ke_heap failed!";
return nullptr;
}
*PageTableEntry =
PTEWrapper{Rw, User, ExecDisable, Detail::create_page_wrapper(Rw, User)};
return PageTableEntry;
}
bool PageManager::Free(Ref<PTEWrapper *> &wrapper) {
if (wrapper) {
if (!Detail::page_disable(wrapper->VirtualAddress())) return false;
this->FlushTLB(wrapper->VirtualAddress());
return true;
}
return false;
}
const UIntPtr &PTEWrapper::VirtualAddress() { return m_VirtAddr; }
bool PTEWrapper::Shareable() {
auto raw = reinterpret_cast<PTE *>(m_VirtAddr);
if (raw->Present) {
m_Shareable = raw->Shared;
return m_Shareable;
} else {
kcout << "[PTEWrapper::Shareable] page is not present!";
return false;
}
}
bool PTEWrapper::Present() {
auto raw = reinterpret_cast<PTE *>(m_VirtAddr);
if (raw->Present) {
m_Present = raw->Present;
return m_Present;
} else {
kcout << "[PTEWrapper::Present] page is not present!";
return false;
}
}
bool PTEWrapper::Access() {
auto raw = reinterpret_cast<PTE *>(m_VirtAddr);
if (raw->Present) {
m_Accessed = raw->Accessed;
}
return m_Accessed;
}
} // namespace HCore
|