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 8*9f0ae301SCornelia Huck #ifndef _ALLOC_PAGE_H_ 9*9f0ae301SCornelia 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 16550b4683SClaudio Imbrenda #define AREA_ANY 0x00000 17550b4683SClaudio Imbrenda #define AREA_MASK 0x0ffff 18550b4683SClaudio Imbrenda 19550b4683SClaudio Imbrenda #define FLAG_DONTZERO 0x10000 20550b4683SClaudio Imbrenda #define FLAG_FRESH 0x20000 21550b4683SClaudio Imbrenda 228131e91aSClaudio Imbrenda /* Returns true if the page allocator has been initialized */ 23bf62a925SAndrew Jones bool page_alloc_initialized(void); 248131e91aSClaudio Imbrenda 258131e91aSClaudio Imbrenda /* 268131e91aSClaudio Imbrenda * Initializes a memory area. 278131e91aSClaudio Imbrenda * n is the number of the area to initialize 288131e91aSClaudio Imbrenda * base_pfn is the physical frame number of the start of the area to initialize 298131e91aSClaudio Imbrenda * top_pfn is the physical frame number of the first page immediately after 308131e91aSClaudio Imbrenda * the end of the area to initialize 318131e91aSClaudio Imbrenda */ 3201d8952bSClaudio Imbrenda void page_alloc_init_area(u8 n, phys_addr_t base_pfn, phys_addr_t top_pfn); 338131e91aSClaudio Imbrenda 348131e91aSClaudio Imbrenda /* Enables the page allocator. At least one area must have been initialized */ 35be60de6fSAndrew Jones void page_alloc_ops_enable(void); 368131e91aSClaudio Imbrenda 378131e91aSClaudio Imbrenda /* 38550b4683SClaudio Imbrenda * Allocate aligned memory with the specified flags. 39550b4683SClaudio Imbrenda * flags is a bitmap of allowed areas and flags. 408131e91aSClaudio Imbrenda * alignment must be a power of 2 418131e91aSClaudio Imbrenda */ 42550b4683SClaudio Imbrenda void *memalign_pages_flags(size_t alignment, size_t size, unsigned int flags); 438131e91aSClaudio Imbrenda 448131e91aSClaudio Imbrenda /* 45550b4683SClaudio Imbrenda * Allocate aligned memory from any area and with default flags. 46550b4683SClaudio Imbrenda * Equivalent to memalign_pages_flags(alignment, size, AREA_ANY). 478131e91aSClaudio Imbrenda */ 4801d8952bSClaudio Imbrenda static inline void *memalign_pages(size_t alignment, size_t size) 4901d8952bSClaudio Imbrenda { 50550b4683SClaudio Imbrenda return memalign_pages_flags(alignment, size, AREA_ANY); 5101d8952bSClaudio Imbrenda } 528131e91aSClaudio Imbrenda 538131e91aSClaudio Imbrenda /* 54550b4683SClaudio Imbrenda * Allocate 1ull << order naturally aligned pages with the specified flags. 55550b4683SClaudio Imbrenda * Equivalent to memalign_pages_flags(1ull << order, 1ull << order, flags). 568131e91aSClaudio Imbrenda */ 57550b4683SClaudio Imbrenda void *alloc_pages_flags(unsigned int order, unsigned int flags); 588131e91aSClaudio Imbrenda 598131e91aSClaudio Imbrenda /* 60550b4683SClaudio Imbrenda * Allocate 1ull << order naturally aligned pages from any area and with 61550b4683SClaudio Imbrenda * default flags. 62550b4683SClaudio Imbrenda * Equivalent to alloc_pages_flags(order, AREA_ANY); 6301d8952bSClaudio Imbrenda */ 6401d8952bSClaudio Imbrenda static inline void *alloc_pages(unsigned int order) 6501d8952bSClaudio Imbrenda { 66550b4683SClaudio Imbrenda return alloc_pages_flags(order, AREA_ANY); 6701d8952bSClaudio Imbrenda } 6801d8952bSClaudio Imbrenda 6901d8952bSClaudio Imbrenda /* 70550b4683SClaudio Imbrenda * Allocate one page from any area and with default flags. 718131e91aSClaudio Imbrenda * Equivalent to alloc_pages(0); 728131e91aSClaudio Imbrenda */ 7301d8952bSClaudio Imbrenda static inline void *alloc_page(void) 7401d8952bSClaudio Imbrenda { 7501d8952bSClaudio Imbrenda return alloc_pages(0); 7601d8952bSClaudio Imbrenda } 778131e91aSClaudio Imbrenda 788131e91aSClaudio Imbrenda /* 798131e91aSClaudio Imbrenda * Frees a memory block allocated with any of the memalign_pages* or 808131e91aSClaudio Imbrenda * alloc_pages* functions. 818131e91aSClaudio Imbrenda * The pointer must point to the start of the block. 828131e91aSClaudio Imbrenda */ 83f90ddba3SClaudio Imbrenda void free_pages(void *mem); 848131e91aSClaudio Imbrenda 8501d8952bSClaudio Imbrenda /* 8601d8952bSClaudio Imbrenda * Free one page. 8701d8952bSClaudio Imbrenda * Equivalent to free_pages(mem). 8801d8952bSClaudio Imbrenda */ 898131e91aSClaudio Imbrenda static inline void free_page(void *mem) 908131e91aSClaudio Imbrenda { 91550b4683SClaudio Imbrenda free_pages(mem); 928131e91aSClaudio Imbrenda } 938131e91aSClaudio Imbrenda 9401d8952bSClaudio Imbrenda /* 9501d8952bSClaudio Imbrenda * Free pages by order. 9601d8952bSClaudio Imbrenda * Equivalent to free_pages(mem). 9701d8952bSClaudio Imbrenda */ 988131e91aSClaudio Imbrenda static inline void free_pages_by_order(void *mem, unsigned int order) 998131e91aSClaudio Imbrenda { 100f90ddba3SClaudio Imbrenda free_pages(mem); 1018131e91aSClaudio Imbrenda } 1025aca024eSPaolo Bonzini 10334c95065SClaudio Imbrenda /* 10401d8952bSClaudio Imbrenda * Reserves the specified physical memory range if possible. 10501d8952bSClaudio Imbrenda * If the specified range cannot be reserved in its entirety, no action is 10601d8952bSClaudio Imbrenda * performed and -1 is returned. 10701d8952bSClaudio Imbrenda * 10801d8952bSClaudio Imbrenda * Returns 0 in case of success, -1 otherwise. 10934c95065SClaudio Imbrenda */ 11001d8952bSClaudio Imbrenda int reserve_pages(phys_addr_t addr, size_t npages); 11134c95065SClaudio Imbrenda 11234c95065SClaudio Imbrenda /* 11334c95065SClaudio Imbrenda * Frees a reserved memory range that had been reserved with 11401d8952bSClaudio Imbrenda * reserve_pages. 11534c95065SClaudio Imbrenda * The memory range does not need to match a previous allocation 11634c95065SClaudio Imbrenda * exactly, it can also be a subset, in which case only the specified 11734c95065SClaudio Imbrenda * pages will be freed and unreserved. 11834c95065SClaudio Imbrenda */ 11901d8952bSClaudio Imbrenda void unreserve_pages(phys_addr_t addr, size_t npages); 12034c95065SClaudio Imbrenda 1215aca024eSPaolo Bonzini #endif 122