#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; #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 // kvmalloc() maps physical 0-4 GB as four 1 GB pages and marks the top one // uncached, because that is where PCI BARs and the framebuffer sit. 3 GB is // therefore the most that can be treated as RAM. #define PHYSTOP_MAX 0xC0000000ULL // 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