#pragma once // Memory layout #define EXTMEM 0x100000 // Start of extended memory // Top of usable physical memory. A *variable*, read from the firmware's E820 // map at boot -- see kernel/arch/x86_64/e820.c. It used to be the constant // below, which was not a limit on what the kernel used but an assertion that // exactly 224 MB existed: less and the allocator walked off the end of RAM, // more and it was invisible. // // The macro spelling is kept so that the twenty-odd call sites read the same as // they always did. It must not be used before e820_init(), which runs first // thing in main() for that reason. #ifndef __ASSEMBLER__ extern uint64 phystop; #define PHYSTOP phystop #endif // PHYSTOP alone describes memory as one run ending at a top address, which is // what a BIOS map usually looks like and what UEFI never does: OVMF drops an // ACPI NVS region at 0x800000, so the run containing the kernel ends at 8 MB // and everything above the hole was invisible. The usable regions are // therefore kept as a list as well, and kinit1() frees each one rather than // walking a single range from the kernel's end to the top. // // PHYSTOP still means what it always did -- the top of what kalloc may hand // out, and the bound kfree() rejects pages above -- so every existing call // site is unaffected. #define MEMREGION_MAX 32 #ifndef __ASSEMBLER__ struct memregion { uint64 base; // first byte, page aligned uint64 end; // one past the last byte, page aligned }; extern struct memregion mem_usable[MEMREGION_MAX]; extern int nmem_usable; // The top of the low region: where the DMA arena is carved from, and the // ceiling for kinit1(). Always below DIRECTMAP_BOOT, and separate from // `phystop` because a device is not obliged to be able to reach the top of // memory -- an RTL8139's buffer address register is thirty-two bits wide. extern uint64 lowtop; #endif // What to assume when the firmware gives us nothing usable: the old constant, // so that path behaves exactly as the kernel always did. #define PHYSTOP_FALLBACK 0xE000000ULL // The most RAM the kernel will use. // // This was 0xC0000000 -- three gigabytes -- because kvmalloc() mapped exactly // four 1 GB pages and the fourth was marked uncached for the PCI hole. On a // laptop with sixteen gigabytes that threw away thirteen of them, silently. // // kvmalloc() now maps as many 1 GB pages as the machine has RAM, so the limit // is the page table rather than a constant: the kernel PDPT has 512 entries // and ioremap takes what the direct map does not, so 64 GB of RAM still leaves // 448 GB of device window. A machine with more than this gets the rest // ignored, with a line saying so. #define PHYSTOP_MAX (64ULL << 30) // What the *loader's* page tables cover, and therefore the ceiling on anything // that runs before kvmalloc() builds the kernel's own. // // kinit1() frees pages by writing a free-list pointer into each one, so every // page it touches has to be mapped at the time. Before kvmalloc that means the // low four gigabytes and nothing else, which is why freeing memory happens in // two passes -- see kinit_high(). #define DIRECTMAP_BOOT (4ULL << 30) // Below this the kernel image, its page tables and the DMA arena do not fit. #define PHYSTOP_MIN (24ULL * 1024 * 1024) // Key addresses for address space layout #define KERNBASE 0xFFFF800000000000 // First kernel virtual address #define KERNLINK (KERNBASE+EXTMEM) // Address where kernel is linked #ifndef __ASSEMBLER__ static inline addr_t v2p(void *a) { return ((addr_t)(a)) - ((addr_t)KERNBASE); } static inline void *p2v(addr_t a) { return (void *)((a) + ((addr_t)KERNBASE)); } #endif #define V2P(a) (((addr_t) (a)) - KERNBASE) #define P2V(a) (((void *) (a)) + KERNBASE) #define V2P_WO(x) ((x) - KERNBASE) // same as V2P, but without casts #define P2V_WO(x) ((x) + KERNBASE) // same as P2V, but without casts