31MALLOC_DEFINE(M_PMAP,
"pmap",
"physical memory map structure");
33#define PG_PRESENT 0x001
39#define PG_ADDR(e) ((e) & ~(uint32_t) PAGE_MASK)
41#define VDIR(va) (((va) >> 22) & 0x3FF)
42#define VTBL(va) (((va) >> 12) & 0x3FF)
50#define cur_pmap (curcpu()->arch.pmap)
78 panic(
"no memory for the kernel's page tables");
272 vaddr_t first = eva, last = sva;
279 first =
MIN(first, va);
303 for (
int j = 0; j < 1024; ++j)
323 vaddr_t first = eva, last = sva;
330 first =
MIN(first, va);
455 flags |= err & 0x04?
PF_USER : 0;
456 flags |= err & 0x10?
PF_EXEC : 0;
494 size_t len =
PAGE_ROUND(paddr + size) - start;
502 for (
size_t off = 0; off < len; off +=
PAGE_SIZE) {
511 return (
void *) (vaddr + (paddr - start));
520 if (paddr + size <= ARCH_DMAP_SIZE)
static void tlb_flush(void)
Flushes every translation from this CPU's TLB.
void pmap_loaded(struct pmap *from, struct pmap *to)
void tlb_shootdown(struct pmap *pmap, vaddr_t sva, vaddr_t eva, int leave)
static uintptr_t read_cr3(void)
int arch_mm_page_fault(vaddr_t vaddr, int err)
Handles a page fault: turns the CPU's error code into the kernel's PF_* flags, and calls mm_page_faul...
int pmap_is_referenced(struct vm_page *pg)
Not implemented on x86, and nothing uses it.
static vaddr_t phys_window_next
void pmap_page_protect(struct vm_page *pg, uint32_t flags)
Not implemented on x86 (it does nothing), and nothing uses it.
static struct pmap * pmap_alloc(void)
Allocates a struct pmap.
void pmap_update(struct pmap *pmap)
Makes the changes to an address space's page tables take effect.
int pmap_clear_modify(struct vm_page *pg)
Not implemented on x86, and nothing uses it.
static paddr_t table_alloc_boot(void)
Allocates a page table that the kernel can't boot without: it panics if there is no memory.
void pmap_copy(struct pmap *dst_map, struct pmap *src_map, vaddr_t dst_addr, size_t len, vaddr_t src_addr)
Does nothing: the generic pmap_copy() isn't used on x86.
int pmap_is_modified(struct vm_page *pg)
Not implemented on x86, and nothing uses it.
int arch_page_unmap(vaddr_t vaddr)
Unmaps a page of the running CPU's address space.
int pmap_clear_reference(struct vm_page *pg)
Not implemented on x86, and nothing uses it.
static void * phys_window_map(uintptr_t paddr, size_t size, uint32_t flags)
Maps a range of physical memory in the window, with flags.
void mm_page_decref(paddr_t paddr)
Drops a reference to a page of RAM.
struct vm_page * mm_page_alloc(void)
Allocates a free page of physical memory.
int mm_page_fault(vaddr_t vaddr, int flags)
Handles a page fault in the current process's address space.
void mm_page_dealloc(paddr_t paddr)
Frees a page of physical memory, back to the zone it came from.
#define MALLOC_DEFINE(type, _name, _desc)
void * kmalloc(size_t size, struct malloc_type *type, int flags)
Allocates memory for one of the kernel's structures.
void kfree(void *)
Frees an object that kmalloc() gave.
void * memset(void *dst, int c, size_t n)
Sets n bytes to c.
void * memcpy(void *dst, const void *src, size_t n)
Copies n bytes; dst and src must not overlap.
int pmap_add(struct pmap *pmap, vaddr_t va, paddr_t pa, uint32_t flags)
Maps a page in an address space, replacing what was mapped there.
static void table_free(paddr_t paddr)
Frees a page table.
paddr_t arch_page_get_mapping(struct pmap *pmap, vaddr_t vaddr)
Finds the page mapped at a virtual address of an address space.
void pmap_page_copy(paddr_t src, paddr_t dst)
Copies a page of physical memory to another.
void pmap_protect(struct pmap *pmap, vaddr_t sva, vaddr_t eva, uint32_t prot)
Changes the permissions of the mapped pages of a range of an address space.
int pmap_page_read(paddr_t paddr, off_t off, size_t size, void *buf)
Reads from a page of physical memory, through the kernel's mapping.
void pmap_init(void)
Takes over the boot page tables as the kernel's, at boot, and makes the page tables of the kernel's h...
static uint64_t * table(paddr_t paddr)
Returns a page table, through the direct map.
static void pmap_release(struct pmap *pmap)
Frees a pmap whose last reference went.
void * arch_phys_map(uintptr_t paddr, size_t size)
Returns a kernel address for a range of physical memory: its address in the direct map if it's there,...
void pmap_decref(struct pmap *pmap)
Drops a reference to an address space's page tables, freeing them with the last one.
static struct pmap k_pmap
struct pmap * pmap_switch(struct pmap *pmap)
Switches this CPU to an address space's page tables.
static uint64_t pte_flags(uint32_t flags)
Returns the descriptor bits for a page with the VM_* flags flags.
int pmap_page_write(paddr_t paddr, off_t off, size_t size, void *buf)
Writes to a page of physical memory, through the kernel's mapping.
void pmap_incref(struct pmap *pmap)
Adds a reference to an address space's page tables.
void pmap_remove(struct pmap *pmap, vaddr_t sva, vaddr_t eva)
Unmaps the pages of a range of an address space, and flushes them from the TLBs that may have them.
struct pmap * pmap_create(void)
Makes the page tables of a new address space: an empty user half, and the kernel's half,...
static uint64_t * pte_get(struct pmap *pmap, vaddr_t va, int make)
Returns the page table entry that maps va, in pmap or in the kernel's half.
void pmap_remove_all(struct pmap *pmap)
Unmaps the whole user half of an address space, and frees its page tables.
static paddr_t table_alloc(void)
Allocates an empty page table.
void * arch_mmio_map(uintptr_t paddr, size_t size)
Maps a device's registers into the kernel's address space, uncached (memory-mapped I/O).
An address space's page tables, on x86.
A page of physical memory (pages[] has one for every page of RAM).
paddr_t paddr
its physical address
struct pmap * pmap
its page tables (the architecture's)
#define VM_URWX
user read/write/execute
#define VM_KW
kernel write
#define VM_NOCACHE
not cached (device memory)
struct vm_space kvm_space
#define VM_KRW
kernel read/write