31MALLOC_DEFINE(M_PMAP,
"pmap",
"physical memory map structure");
35#define PG_PRESENT 0x001
41#define PG_GLOBAL 0x100
43#define PG_ADDR(e) ((e) & 0x000FFFFFFFFFF000ULL)
46#define IDX(va, level) (((va) >> (12 + 9 * (level))) & 0x1FF)
48#define KERNEL_PML4E 256
49#define LARGE_SIZE 0x200000ULL
58#define cur_pmap (curcpu()->arch.pmap)
86 panic(
"no memory for the kernel's page tables");
106 for (
int level = 3; level > 0; --level) {
125 return &t[
IDX(va, 0)];
186 for (
int level = 3; level > 1; --level) {
208 printk(
"x86_64: %ld MiB in the direct map\n", (
uint64_t) (end >> 20));
331 vaddr_t first = eva, last = sva;
338 first =
MIN(first, va);
354 for (
int i = 0; i < 512; ++i) {
395 vaddr_t first = eva, last = sva;
402 first =
MIN(first, va);
493 flags |= err & 0x04?
PF_USER : 0;
494 flags |= err & 0x10?
PF_EXEC : 0;
533 size_t len =
PAGE_ROUND(paddr + size) - start;
541 for (
size_t off = 0; off < len; off +=
PAGE_SIZE) {
550 return (
void *) (vaddr + (paddr - start));
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.
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.
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 paddr_t ram_end(void)
Returns the end of the RAM that the boot loader found.
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.
static void tables_free(paddr_t paddr, int level)
Frees a table of the user half at level and the tables under it.
static void * window_map(uintptr_t paddr, size_t size, uint32_t flags)
Maps physical memory in the window, with flags.
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).
int printk(const char *fmt,...)
Writes a kernel message, to the message buffer and the consoles.
unsigned long long int uint64_t
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