xref: /kvm-unit-tests/lib/alloc_page.h (revision 14b54ed754c8a8cae7a22895e4a0b745a3227a4b)
15aca024eSPaolo Bonzini /*
25aca024eSPaolo Bonzini  * This work is licensed under the terms of the GNU LGPL, version 2.
35aca024eSPaolo Bonzini  *
45aca024eSPaolo Bonzini  * This is a simple allocator that provides contiguous physical addresses
55aca024eSPaolo Bonzini  * with byte granularity.
65aca024eSPaolo Bonzini  */
75aca024eSPaolo Bonzini 
89f0ae301SCornelia Huck #ifndef _ALLOC_PAGE_H_
99f0ae301SCornelia Huck #define _ALLOC_PAGE_H_
105aca024eSPaolo Bonzini 
1101d8952bSClaudio Imbrenda #include <stdbool.h>
128131e91aSClaudio Imbrenda #include <asm/memory_areas.h>
138131e91aSClaudio Imbrenda 
14322cdd64SClaudio Imbrenda #define AREA_ANY_NUMBER	0xff
15322cdd64SClaudio Imbrenda 
16*d36b378fSVarad Gautam /* The realmode trampoline gets relocated here during bootup. */
17*d36b378fSVarad Gautam #define RM_TRAMPOLINE_ADDR 0
18*d36b378fSVarad Gautam 
19550b4683SClaudio Imbrenda #define AREA_ANY	0x00000
20550b4683SClaudio Imbrenda #define AREA_MASK	0x0ffff
21550b4683SClaudio Imbrenda 
22550b4683SClaudio Imbrenda #define FLAG_DONTZERO	0x10000
23550b4683SClaudio Imbrenda #define FLAG_FRESH	0x20000
24550b4683SClaudio Imbrenda 
258131e91aSClaudio Imbrenda /* Returns true if the page allocator has been initialized */
26bf62a925SAndrew Jones bool page_alloc_initialized(void);
278131e91aSClaudio Imbrenda 
288131e91aSClaudio Imbrenda /*
298131e91aSClaudio Imbrenda  * Initializes a memory area.
308131e91aSClaudio Imbrenda  * n is the number of the area to initialize
318131e91aSClaudio Imbrenda  * base_pfn is the physical frame number of the start of the area to initialize
328131e91aSClaudio Imbrenda  * top_pfn is the physical frame number of the first page immediately after
338131e91aSClaudio Imbrenda  * the end of the area to initialize
348131e91aSClaudio Imbrenda  */
3501d8952bSClaudio Imbrenda void page_alloc_init_area(u8 n, phys_addr_t base_pfn, phys_addr_t top_pfn);
368131e91aSClaudio Imbrenda 
378131e91aSClaudio Imbrenda /* Enables the page allocator. At least one area must have been initialized */
38be60de6fSAndrew Jones void page_alloc_ops_enable(void);
398131e91aSClaudio Imbrenda 
408131e91aSClaudio Imbrenda /*
41550b4683SClaudio Imbrenda  * Allocate aligned memory with the specified flags.
42550b4683SClaudio Imbrenda  * flags is a bitmap of allowed areas and flags.
438131e91aSClaudio Imbrenda  * alignment must be a power of 2
448131e91aSClaudio Imbrenda  */
45550b4683SClaudio Imbrenda void *memalign_pages_flags(size_t alignment, size_t size, unsigned int flags);
468131e91aSClaudio Imbrenda 
478131e91aSClaudio Imbrenda /*
48550b4683SClaudio Imbrenda  * Allocate aligned memory from any area and with default flags.
49550b4683SClaudio Imbrenda  * Equivalent to memalign_pages_flags(alignment, size, AREA_ANY).
508131e91aSClaudio Imbrenda  */
memalign_pages(size_t alignment,size_t size)5101d8952bSClaudio Imbrenda static inline void *memalign_pages(size_t alignment, size_t size)
5201d8952bSClaudio Imbrenda {
53550b4683SClaudio Imbrenda 	return memalign_pages_flags(alignment, size, AREA_ANY);
5401d8952bSClaudio Imbrenda }
558131e91aSClaudio Imbrenda 
568131e91aSClaudio Imbrenda /*
57550b4683SClaudio Imbrenda  * Allocate 1ull << order naturally aligned pages with the specified flags.
58550b4683SClaudio Imbrenda  * Equivalent to memalign_pages_flags(1ull << order, 1ull << order, flags).
598131e91aSClaudio Imbrenda  */
60550b4683SClaudio Imbrenda void *alloc_pages_flags(unsigned int order, unsigned int flags);
618131e91aSClaudio Imbrenda 
628131e91aSClaudio Imbrenda /*
63550b4683SClaudio Imbrenda  * Allocate 1ull << order naturally aligned pages from any area and with
64550b4683SClaudio Imbrenda  * default flags.
65550b4683SClaudio Imbrenda  * Equivalent to alloc_pages_flags(order, AREA_ANY);
6601d8952bSClaudio Imbrenda  */
alloc_pages(unsigned int order)6701d8952bSClaudio Imbrenda static inline void *alloc_pages(unsigned int order)
6801d8952bSClaudio Imbrenda {
69550b4683SClaudio Imbrenda 	return alloc_pages_flags(order, AREA_ANY);
7001d8952bSClaudio Imbrenda }
7101d8952bSClaudio Imbrenda 
7201d8952bSClaudio Imbrenda /*
73550b4683SClaudio Imbrenda  * Allocate one page from any area and with default flags.
748131e91aSClaudio Imbrenda  * Equivalent to alloc_pages(0);
758131e91aSClaudio Imbrenda  */
alloc_page(void)7601d8952bSClaudio Imbrenda static inline void *alloc_page(void)
7701d8952bSClaudio Imbrenda {
7801d8952bSClaudio Imbrenda 	return alloc_pages(0);
7901d8952bSClaudio Imbrenda }
808131e91aSClaudio Imbrenda 
818131e91aSClaudio Imbrenda /*
828131e91aSClaudio Imbrenda  * Frees a memory block allocated with any of the memalign_pages* or
838131e91aSClaudio Imbrenda  * alloc_pages* functions.
848131e91aSClaudio Imbrenda  * The pointer must point to the start of the block.
858131e91aSClaudio Imbrenda  */
86f90ddba3SClaudio Imbrenda void free_pages(void *mem);
878131e91aSClaudio Imbrenda 
8801d8952bSClaudio Imbrenda /*
8901d8952bSClaudio Imbrenda  * Free one page.
9001d8952bSClaudio Imbrenda  * Equivalent to free_pages(mem).
9101d8952bSClaudio Imbrenda  */
free_page(void * mem)928131e91aSClaudio Imbrenda static inline void free_page(void *mem)
938131e91aSClaudio Imbrenda {
94550b4683SClaudio Imbrenda 	free_pages(mem);
958131e91aSClaudio Imbrenda }
968131e91aSClaudio Imbrenda 
9701d8952bSClaudio Imbrenda /*
9801d8952bSClaudio Imbrenda  * Free pages by order.
9901d8952bSClaudio Imbrenda  * Equivalent to free_pages(mem).
10001d8952bSClaudio Imbrenda  */
free_pages_by_order(void * mem,unsigned int order)1018131e91aSClaudio Imbrenda static inline void free_pages_by_order(void *mem, unsigned int order)
1028131e91aSClaudio Imbrenda {
103f90ddba3SClaudio Imbrenda 	free_pages(mem);
1048131e91aSClaudio Imbrenda }
1055aca024eSPaolo Bonzini 
10634c95065SClaudio Imbrenda /*
10701d8952bSClaudio Imbrenda  * Reserves the specified physical memory range if possible.
10801d8952bSClaudio Imbrenda  * If the specified range cannot be reserved in its entirety, no action is
10901d8952bSClaudio Imbrenda  * performed and -1 is returned.
11001d8952bSClaudio Imbrenda  *
11101d8952bSClaudio Imbrenda  * Returns 0 in case of success, -1 otherwise.
11234c95065SClaudio Imbrenda  */
11301d8952bSClaudio Imbrenda int reserve_pages(phys_addr_t addr, size_t npages);
11434c95065SClaudio Imbrenda 
11534c95065SClaudio Imbrenda /*
11634c95065SClaudio Imbrenda  * Frees a reserved memory range that had been reserved with
11701d8952bSClaudio Imbrenda  * reserve_pages.
11834c95065SClaudio Imbrenda  * The memory range does not need to match a previous allocation
11934c95065SClaudio Imbrenda  * exactly, it can also be a subset, in which case only the specified
12034c95065SClaudio Imbrenda  * pages will be freed and unreserved.
12134c95065SClaudio Imbrenda  */
12201d8952bSClaudio Imbrenda void unreserve_pages(phys_addr_t addr, size_t npages);
12334c95065SClaudio Imbrenda 
1245aca024eSPaolo Bonzini #endif
125