#include "paging.hpp"
+#include "serial.hpp"
+
+// void os::paging::unmap(phys_ptr<PML4T> PLM4T, page* virt, std::uint64_t length) { }
+// void os::paging::map(phys_ptr<PML4T> PLM4T, page* virt, std::uint64_t length, phys_ptr<page> phys) { }
+template<int order> void print_mapping(os::phys_ptr<os::paging::paging_table<order>> table, std::uint64_t virt_address) {
+ for (std::size_t i = 0; i < 512; i++) {
+ const auto& page = table->contents[i];
+ if (!page.P()) { continue; }
+ std::uint64_t new_virt = virt_address + i * (4096ul << (order * 9));
+ new_virt |= ((new_virt & 0x0000800000000000) != 0 ? 0xFFFF000000000000 : 0);
+ if (page.is_page()) {
+ os::print(new_virt);
+ os::print(" -> ");
+ os::print(page.base_address().get_phys_addr());
+ os::print(" (order ");
+ os::printc(order + '0');
+ os::print(")\n");
+ } else {
+ if constexpr (order > 0) { // Will never be false when !page.is_page().
+ print_mapping<order - 1>(page.base_address(), new_virt);
+ }
+ }
+ }
+}
+void os::paging::print_mapping(phys_ptr<PML4T> PML4T) {
+ ::print_mapping(PML4T, 0);
+}
os::paging::page one_past_end_page_for_page_allocator;
os::paging::page_allocator_t os::paging::page_allocator(os::phys_ptr<os::paging::page>(reinterpret_cast<uintptr_t>(&one_past_end_page_for_page_allocator) - 0xFFFFFFFF80000000));
data |= 1 << 7; // Mark as smallest page.
}
}
- inline bool is_page() {
+ inline bool is_page() const {
return order == 0 || (data & (1 << 7)) != 0;
}
- inline bool NX() {
+ inline bool NX() const {
return (data & (1ul << 63)) != 0;
}
inline void NX(bool v) {
data = (data & ~(1ul << 63)) | (v ? (1ul << 63) : 0);
}
- inline unsigned PK() {
+ inline unsigned PK() const {
os::assert(is_page(), "read protection key of non-page.");
return (data >> 52) & 0xF;
}
os::assert((v & 0xF) == v, "incorrect protection key.");
data = (data & ~(0xFul << 59)) | (std::uint64_t(v) << 59);
}
- inline unsigned AVL_high() {
+ inline unsigned AVL_high() const {
return (data >> 52) & (is_page() ? 0x7F : 0x7FF);
}
inline void AVL_high(unsigned v) {
os::assert((v & (is_page() ? 0x7F : 0x7FF)) == v, "incorrect AVL high bits.");
data = (data & ~((is_page() ? 0x7Ful : 0x7FFul) << 52)) | (std::uint64_t(v) << 52);
}
- inline phys_ptr<paging_table<order - 1>> base_address() {
- return {data & 0x000FFFFFFFFFF000 & ~(order != 0 && is_page() ? 1ul << 12 : 0ul)};
+ inline phys_ptr<paging_table<order - 1>> base_address() const {
+ return phys_ptr<paging_table<order - 1>>{data & 0x000FFFFFFFFFF000 & ~(order != 0 && is_page() ? 1ul << 12 : 0ul)};
}
inline void base_address(phys_ptr<paging_table<order - 1>> v) {
const std::uint64_t v_int = v.get_phys_addr();
os::assert((v_int & 0x000FFFFFFFFFF000 & (0xFFFFFFFFFFFFF000 << (is_page() ? 9 * order : 0))) == v_int, "incorrect base address.");
data = (data & ~0x000FFFFFFFFFF000ul & ~(order != 0 && is_page() ? 1ul << 12 : 0ul)) | v_int;
}
- inline unsigned AVL_low() {
+ inline unsigned AVL_low() const {
return (data >> 9) & 0x7;
}
inline void AVL_low(unsigned v) {
os::assert((v & 0x7) == v, "incorrect AVL low bits");
data = (data & ~(0x7ul << 9)) | (v << 9);
}
- inline bool G() {
+ inline bool G() const {
os::assert(is_page(), "read global bit of non-page.");
return (data & (1 << 8)) != 0;
}
os::assert(is_page(), "write to global bit of non-page.");
data = (data & ~(1ul << 8)) | (v ? 1 << 8 : 0);
}
- inline bool PAT() {
+ inline bool PAT() const {
os::assert(is_page(), "read PAT bit of non-page.");
return (data & (1 << (order == 0 ? 7 : 12))) != 0;
}
os::assert(is_page(), "write to PAT bit of non-page.");
data = (data & ~(1ul << (order == 0 ? 7 : 12))) | (v ? 1 << (order == 0 ? 7 : 12) : 0);
}
- inline bool D() {
+ inline bool D() const {
os::assert(is_page(), "read dirty bit of non-page.");
return (data & (1 << 6)) != 0;
}
os::assert(is_page(), "write to dirty bit of non-page.");
data = (data & ~(1ul << 6)) | (v ? 1 << 6 : 0);
}
- inline bool A() {
+ inline bool A() const {
return (data & (1 << 5)) != 0;
}
inline void A(bool v) {
data = (data & ~(1ul << 5)) | (v ? 1 << 5 : 0);
}
- inline bool PCD() {
+ inline bool PCD() const {
return (data & (1 << 4)) != 0;
}
inline void PCD(bool v) {
data = (data & ~(1ul << 4)) | (v ? 1 << 4 : 0);
}
- inline bool PWT() {
+ inline bool PWT() const {
return (data & (1 << 3)) != 0;
}
inline void PWT(bool v) {
data = (data & ~(1ul << 3)) | (v ? 1 << 3 : 0);
}
- inline bool U_S() {
+ inline bool U_S() const {
return (data & (1 << 2)) != 0;
}
inline void U_S(bool v) {
data = (data & ~(1ul << 2)) | (v ? 1 << 2 : 0);
}
- inline bool R_W() {
+ inline bool R_W() const {
return (data & (1 << 1)) != 0;
}
inline void R_W(bool v) {
data = (data & ~(1ul << 1)) | (v ? 1 << 1 : 0);
}
- inline bool P() {
+ inline bool P() const {
return (data & (1 << 0)) != 0;
}
inline void P(bool v) {
using PE = paging_entry<0>;
using page = paging_table<-1>;
+void unmap(phys_ptr<PML4T> PLM4T, page* virt, std::uint64_t length);
+void map(phys_ptr<PML4T> PLM4T, page* virt, std::uint64_t length, phys_ptr<page> phys);
+void print_mapping(phys_ptr<PML4T> PML4T);
+
class page_allocator_t;
extern page_allocator_t page_allocator;