const uint64_t pml_xd = 1 << 63; // execution disable (disables code execution in this page)
const uint64_t pml_a = 1 << 5; // determins weather the page has been accessed or not since last clear
const uint64_t pml_pcd = 1 << 4; // disables the chaching of this page
const uint64_t pml_pwt = 1 << 3; // enables write-through cache
const uint64_t pml_us = 1 << 2; // enables access by user mode code
const uint64_t pml_rw = 1 << 1; // enables write privaleges (else if not set the page is read only)
const uint64_t pml_p = 1 << 0; // enable this flag to set a page as present
// in order to allocate a pml4 page entry (note that phys is the physical address of A PML3 PAGE TABLE and must be a multiple of 4096 and must be canonical ie it must be of an address size within 52 bits for pml4 paging and that virt is the virtual address and must be within 48 bits of address space)
uint64_t pml4_index = virt >> 39;
pml4[pml4_index] = phys | pml_rw | pml_p;
// all other consts above are used (i recomending putting them all in a single header file)
const uint64_t pml_ps = 1 << 7; // note: this is the page size. if 1: this entire entry maps a 1 GiB page, if 0: this entry points to another pml2 page table
uint64_t pml3_index = (virt >> 30) & 0b111111111;
pml3[pml3_index] = phys | ATTRIBUTES | pml_p; // ATTRIBUTES = ... attributes ... i don't have to write it out again because from the last one you get the idea.