1 /* 2 * This work is licensed under the terms of the GNU LGPL, version 2. 3 * 4 * This is a simple allocator that provides contiguous physical addresses 5 * with byte granularity. 6 */ 7 8 #ifndef _ALLOC_PAGE_H_ 9 #define _ALLOC_PAGE_H_ 10 11 #include <stdbool.h> 12 #include <asm/memory_areas.h> 13 14 #define AREA_ANY_NUMBER 0xff 15 16 /* The realmode trampoline gets relocated here during bootup. */ 17 #define RM_TRAMPOLINE_ADDR 0 18 19 #define AREA_ANY 0x00000 20 #define AREA_MASK 0x0ffff 21 22 #define FLAG_DONTZERO 0x10000 23 #define FLAG_FRESH 0x20000 24 25 /* Returns true if the page allocator has been initialized */ 26 bool page_alloc_initialized(void); 27 28 /* 29 * Initializes a memory area. 30 * n is the number of the area to initialize 31 * base_pfn is the physical frame number of the start of the area to initialize 32 * top_pfn is the physical frame number of the first page immediately after 33 * the end of the area to initialize 34 */ 35 void page_alloc_init_area(u8 n, phys_addr_t base_pfn, phys_addr_t top_pfn); 36 37 /* Enables the page allocator. At least one area must have been initialized */ 38 void page_alloc_ops_enable(void); 39 40 /* 41 * Allocate aligned memory with the specified flags. 42 * flags is a bitmap of allowed areas and flags. 43 * alignment must be a power of 2 44 */ 45 void *memalign_pages_flags(size_t alignment, size_t size, unsigned int flags); 46 47 /* 48 * Allocate aligned memory from any area and with default flags. 49 * Equivalent to memalign_pages_flags(alignment, size, AREA_ANY). 50 */ 51 static inline void *memalign_pages(size_t alignment, size_t size) 52 { 53 return memalign_pages_flags(alignment, size, AREA_ANY); 54 } 55 56 /* 57 * Allocate 1ull << order naturally aligned pages with the specified flags. 58 * Equivalent to memalign_pages_flags(1ull << order, 1ull << order, flags). 59 */ 60 void *alloc_pages_flags(unsigned int order, unsigned int flags); 61 62 /* 63 * Allocate 1ull << order naturally aligned pages from any area and with 64 * default flags. 65 * Equivalent to alloc_pages_flags(order, AREA_ANY); 66 */ 67 static inline void *alloc_pages(unsigned int order) 68 { 69 return alloc_pages_flags(order, AREA_ANY); 70 } 71 72 /* 73 * Allocate one page from any area and with default flags. 74 * Equivalent to alloc_pages(0); 75 */ 76 static inline void *alloc_page(void) 77 { 78 return alloc_pages(0); 79 } 80 81 /* 82 * Frees a memory block allocated with any of the memalign_pages* or 83 * alloc_pages* functions. 84 * The pointer must point to the start of the block. 85 */ 86 void free_pages(void *mem); 87 88 /* 89 * Free one page. 90 * Equivalent to free_pages(mem). 91 */ 92 static inline void free_page(void *mem) 93 { 94 free_pages(mem); 95 } 96 97 /* 98 * Free pages by order. 99 * Equivalent to free_pages(mem). 100 */ 101 static inline void free_pages_by_order(void *mem, unsigned int order) 102 { 103 free_pages(mem); 104 } 105 106 /* 107 * Reserves the specified physical memory range if possible. 108 * If the specified range cannot be reserved in its entirety, no action is 109 * performed and -1 is returned. 110 * 111 * Returns 0 in case of success, -1 otherwise. 112 */ 113 int reserve_pages(phys_addr_t addr, size_t npages); 114 115 /* 116 * Frees a reserved memory range that had been reserved with 117 * reserve_pages. 118 * The memory range does not need to match a previous allocation 119 * exactly, it can also be a subset, in which case only the specified 120 * pages will be freed and unreserved. 121 */ 122 void unreserve_pages(phys_addr_t addr, size_t npages); 123 124 #endif 125