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 */
memalign_pages(size_t alignment,size_t size)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 */
alloc_pages(unsigned int order)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 */
alloc_page(void)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 */
free_page(void * mem)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 */
free_pages_by_order(void * mem,unsigned int order)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