// Allocate memory for segment:
std::size_t nb_pages = (std::uint64_t(program_header.p_vaddr) % 0x1000 + program_header.p_memsz + 0x1000 - 1) / 0x1000;
for (std::size_t i = 0; i < nb_pages; i++) {
- os::paging::setup_page(PML4T, program_header.p_vaddr + i * 0x1000, (program_header.flags & 2) >> 1, 1, true);
+ os::paging::setup_page(PML4T, program_header.p_vaddr + i * 0x1000, (program_header.flags & 2) >> 1, 1);
}
// Initialise memory for segment:
for (std::size_t i = 0; i < program_header.p_filesz; i++) {
constexpr std::size_t stack_size = 16 * 0x1000 /* 64KiB */;
std::byte * const stack = (std::byte*)0x0000'8000'0000'0000 - stack_size;
for (std::size_t i = 0; i < stack_size / 0x1000 /* 64KiB */; i++) {
- os::paging::setup_page(PML4T, stack + i * 0x1000, 1, 1, true);
+ os::paging::setup_page(PML4T, stack + i * 0x1000, 1, 1);
}
os::print("Loading ring 3 interrupts stack.\n");
#include "paging.hpp"
#include "serial.hpp"
-void os::paging::setup_page(os::paging::PML4T& PML4T, const void* vaddr, bool R_W, bool U_S, bool must_be_unmapped) {
+void os::paging::setup_page(os::paging::PML4T& PML4T, const void* vaddr, bool R_W, bool U_S) {
const auto indices = os::paging::calc_page_table_indices(vaddr);
if (PML4T.contents[indices.pml4e].P == 0) {
PML4T.contents[indices.pml4e] = {.P = 1, .R_W = 1, .U_S = U_S, .PWT = 0, .PCD = 0, .base_address = 0, .NX = 0};
PDPT.contents[indices.pdpe] = {.non_page = {.P = 1, .R_W = 1, .U_S = U_S, .PWT = 0, .PCD = 0, .base_address = 0, .NX = 0}};
const auto PDT_alloc = os::paging::page_allocator.allocate(1);
set_base_address(PDPT.contents[indices.pdpe], os::phys_ptr<os::paging::PDT>(PDT_alloc.ptr.get_phys_addr()));
+ } else {
+ assert(PDPT.contents[indices.pdpe].non_page.zero == 0,
+ "Cannot map memory address 0x{} because it is inside a 1GiB page", std::uintptr_t(vaddr));
}
os::paging::PDT& PDT = *get_base_address(PDPT.contents[indices.pdpe]);
if (PDT.contents[indices.pde].non_page.P == 0) {
PDT.contents[indices.pde] = {.non_page = {.P = 1, .R_W = 1, .U_S = U_S, .PWT = 0, .PCD = 0, .base_address = 0, .NX = 0}};
const auto PT_alloc = os::paging::page_allocator.allocate(1);
set_base_address(PDT.contents[indices.pde], os::phys_ptr<os::paging::PT>(PT_alloc.ptr.get_phys_addr()));
- }
- os::paging::PT& PT = *get_base_address(PDT.contents[indices.pde]);
- if (PT.contents[indices.pe].P == 0) {
- PT.contents[indices.pe] = {.P = 1, .R_W = R_W, .U_S = U_S, .PWT = 0, .PCD = 0, .PAT = 0, .G = 0, .base_address = 0, .NX = 0};
- const auto page_alloc = os::paging::page_allocator.allocate(1);
- set_page_base_address(PT.contents[indices.pe], os::phys_ptr<os::paging::page>(page_alloc.ptr.get_phys_addr()));
- invlpg(vaddr);
} else {
- os::assert(!must_be_unmapped, "Memory at address 0x{} has already been mapped.", std::uintptr_t(vaddr));
+ assert(PDT.contents[indices.pde].non_page.zero == 0,
+ "Cannot map memory address 0x{} because it is inside a 2MiB page", std::uintptr_t(vaddr));
}
+ os::paging::PT& PT = *get_base_address(PDT.contents[indices.pde]);
+ os::assert(PT.contents[indices.pe].P == 0, "Memory at address 0x{} has already been mapped.", std::uintptr_t(vaddr));
+ PT.contents[indices.pe] =
+ {.P = 1, .R_W = R_W, .U_S = U_S, .PWT = 0, .PCD = 0, .PAT = 0, .G = (indices.pml4e < 128) ? 0ul : 1ul, .base_address = 0, .NX = 0};
+ const auto page_alloc = os::paging::page_allocator.allocate(1);
+ set_page_base_address(PT.contents[indices.pe], os::phys_ptr<os::paging::page>(page_alloc.ptr.get_phys_addr()));
+ invlpg(vaddr);
}
namespace {