20 #define CONTAINS_TABLE (1 << 0) 23 #define PAGE_SHIFT 12 // 1<<12 = 4KiB 24 #define PAGE_SHIFT_LARGE 21 // 1<<21 = 2MiB 27 #define PFN_INVALID ((uint32_t)-1) 30 #define PADDR_TO_PF(a) ((pf_t *)(pfdb.pf + ((a) >> PAGE_SHIFT))) 31 #define PF_TO_PADDR(pf) ((uint64_t)((pf) - pfdb.pf) << PAGE_SHIFT) 32 #define PFN_TO_PF(pfn) ((pf_t *)((pfn) + pfdb.pf)) 33 #define PF_TO_PFN(pf) ((uint32_t)((pf) - pfdb.pf)) 34 #define PTE_TO_PADDR(pte) ((pte) & ~PGMASK_OFFSET) 80 const pmapregion_t *r = map->region;
81 const pmapregion_t *t = map->region + map->count;
91 uint64_t paddr = r->addr + (1 << alignshift) - 1;
96 if (paddr + size > r->addr + r->size)
101 return (
void *)paddr;
111 if (map->last_usable == 0)
146 for (uint64_t r = 0; r < map->count; r++) {
147 const pmapregion_t *region = &map->region[r];
155 uint64_t pfnN = (region->addr + region->size) >>
PAGE_SHIFT;
156 for (uint64_t pfn = pfn0; pfn < pfnN; pfn++) {
249 for (uint64_t e = 0; e < 512; e++) {
262 for (uint64_t e = 0; e < 512; e++) {
289 uint32_t pml4e =
PML4E(vaddr);
290 uint32_t pdpte =
PDPTE(vaddr);
291 uint32_t pde =
PDE(vaddr);
292 uint32_t pte =
PTE(vaddr);
298 if (pml4t->
entry[pml4e] == 0) {
300 added[count++] = pgaddr;
311 if (pdpt->
entry[pdpte] == 0) {
313 added[count++] = pgaddr;
318 if (pdt->
entry[pde] == 0) {
320 added[count++] = pgaddr;
326 ptt->
entry[pte] = paddr | pflags;
330 for (
int i = 0; i <
count; i++) {
340 uint32_t pml4e =
PML4E(vaddr);
341 uint32_t pdpte =
PDPTE(vaddr);
342 uint32_t pde =
PDE(vaddr);
343 uint32_t pte =
PTE(vaddr);
371 pt->
vroot = (uint64_t)vaddr;
373 pt->
vterm = (uint64_t)vaddr + size;
378 for (
int i = 0; i < 512; i++)
379 dst->entry[i] = src->
entry[i];
392 if (pt == active_pt) {
393 for (uint64_t vaddr = pt->
vroot; vaddr < pt->vterm;
417 for (uint64_t vaddr = (uint64_t)vaddr_in; count--; vaddr +=
PAGE_SIZE) {
427 for (uint64_t vaddr = (uint64_t)vaddr_in; count--; vaddr +=
PAGE_SIZE) {
uint32_t head
Index of available frame list head.
const pmap_t * pmap()
Return a pointer to the current physical memory map.
uint32_t tail
Index of available frame list tail.
uint32_t avail
Available number of frames in the pfdb.
Physical memory map describing usable and reserved regions of physical memory.
String and memory operations.
void pagetable_create(pagetable_t *pt, void *vaddr, uint64_t size)
Create a new page table that can be used to associate virtual addresses with physical addresses...
static void add_pte(pagetable_t *pt, uint64_t vaddr, uint64_t paddr, uint32_t pflags, uint32_t addflags)
Add to the page table an entry mapping a virtual address to a physical address.
__forceinline void set_pagetable(uint64_t paddr)
void page_init()
Initialize the page frame database.
static void * reserve_region(const pmap_t *map, uint64_t size, uint32_t alignshift)
Reserve an aligned region of memory managed by the memory table module.
Kernel physical (and virtual) memory map.
void pagetable_destroy(pagetable_t *pt)
Destroy a page table.
uint32_t prev
Index of prev pfn on available list.
void kmem_init(pagetable_t *pt)
Using the contents of the physical memory map, identity map all physical memory into the kernel's pag...
STATIC_ASSERT(sizeof(pf_t)==32,"Unexpected page frame size")
Reported usable by the BIOS.
void * page_alloc(pagetable_t *pt, void *vaddr_in, int count)
Allocate one or more pages contiguous in virtual memory.
static void pgfree_recurse(page_t *page, int level)
void pagetable_activate(pagetable_t *pt)
Activate a page table on the CPU, so all virtual memory operations are performed relative to the page...
__forceinline void fatal()
static uint64_t pgalloc()
The pfdb describes the state of the page frame database.
static void pffree(pf_t *pf)
void pmap_add(uint64_t addr, uint64_t size, enum pmemtype type)
Add a region of memory to the physical memory map.
uint64_t entry[PAGE_SIZE/sizeof(uint64_t)]
uint64_t proot
Physical address of root page table (PML4T) entry.
The pf structure represents a record in the page frame database.
Interrupt handling operations.
x86 CPU-specific function implementations.
__forceinline void invalidate_page(void *vaddr)
uint16_t sharecount
Number of processes sharing page.
Reported (or inferred) to be reserved.
pf_t * pf
Pointer to array of page frames.
static pagetable_t * active_pt
uint64_t vnext
Virtual address to use for table's next page.
void * memzero(void *dst, size_t num)
Fill a region of memory with zeroes.
#define PTE_TO_PADDR(pte)
General utilities library.
uint64_t vterm
Boundary of pages used to store the table.
void page_free(pagetable_t *pt, void *vaddr_in, int count)
Free one or more contiguous pages from virtual memory.
uint64_t vroot
Virtual address of root page table (PML4T) entry.
uint16_t refcount
Number of references to this page.
static void pgfree(uint64_t paddr)
uint32_t next
Index of next pfn on available list.
uint32_t count
Total number of frames in the pfdb.
static uint64_t remove_pte(pagetable_t *pt, uint64_t vaddr)
uint8_t type
PFTYPE of page frame.