1 #ifndef _ALLOC_H_ 2 #define _ALLOC_H_ 3 /* 4 * alloc supplies three ingredients to the test framework that are all 5 * related to the support of dynamic memory allocation. 6 * 7 * The first is a set of alloc function wrappers for malloc and its 8 * friends. Using wrappers allows test code and common code to use the 9 * same interface for memory allocation at all stages, even though the 10 * implementations may change with the stage, e.g. pre/post paging. 11 * 12 * The second is a set of implementations for the alloc function 13 * interfaces. These implementations are named early_*, as they can be 14 * used almost immediately by the test framework. 15 * 16 * The third is a very simple physical memory allocator, which the 17 * early_* alloc functions build on. 18 * 19 * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com> 20 * 21 * This work is licensed under the terms of the GNU LGPL, version 2. 22 */ 23 #include "libcflat.h" 24 25 struct alloc_ops { 26 void *(*malloc)(size_t size); 27 void *(*calloc)(size_t nmemb, size_t size); 28 void (*free)(void *ptr); 29 void *(*memalign)(size_t alignment, size_t size); 30 }; 31 32 /* 33 * alloc_ops is initialized to early_alloc_ops 34 */ 35 extern struct alloc_ops *alloc_ops; 36 37 static inline void *malloc(size_t size) 38 { 39 assert(alloc_ops && alloc_ops->malloc); 40 return alloc_ops->malloc(size); 41 } 42 43 static inline void *calloc(size_t nmemb, size_t size) 44 { 45 assert(alloc_ops && alloc_ops->calloc); 46 return alloc_ops->calloc(nmemb, size); 47 } 48 49 static inline void free(void *ptr) 50 { 51 assert(alloc_ops && alloc_ops->free); 52 alloc_ops->free(ptr); 53 } 54 55 static inline void *memalign(size_t alignment, size_t size) 56 { 57 assert(alloc_ops && alloc_ops->memalign); 58 return alloc_ops->memalign(alignment, size); 59 } 60 61 #ifdef PHYS32 62 typedef u32 phys_addr_t; 63 #else 64 typedef u64 phys_addr_t; 65 #endif 66 #define INVALID_PHYS_ADDR (~(phys_addr_t)0) 67 68 /* 69 * phys_alloc is a very simple allocator which allows physical memory 70 * to be partitioned into regions until all memory is allocated. 71 * 72 * Note: This is such a simple allocator that there is no way to free 73 * a region. For more complicated memory management a single region 74 * can be allocated, but then have its memory managed by a more 75 * sophisticated allocator, e.g. a page allocator. 76 */ 77 #define DEFAULT_MINIMUM_ALIGNMENT 32 78 79 /* 80 * phys_alloc_init creates the initial free memory region of size @size 81 * at @base. The minimum alignment is set to DEFAULT_MINIMUM_ALIGNMENT. 82 */ 83 extern void phys_alloc_init(phys_addr_t base, phys_addr_t size); 84 85 /* 86 * phys_alloc_set_minimum_alignment sets the minimum alignment to 87 * @align. 88 */ 89 extern void phys_alloc_set_minimum_alignment(phys_addr_t align); 90 91 /* 92 * phys_alloc_aligned returns the base address of a region of size @size, 93 * where the address is aligned to @align, or INVALID_PHYS_ADDR if there 94 * isn't enough free memory to satisfy the request. 95 */ 96 extern phys_addr_t phys_alloc_aligned(phys_addr_t size, phys_addr_t align); 97 98 /* 99 * phys_zalloc_aligned is like phys_alloc_aligned, but zeros the memory 100 * before returning the address. 101 */ 102 extern phys_addr_t phys_zalloc_aligned(phys_addr_t size, phys_addr_t align); 103 104 /* 105 * phys_alloc returns the base address of a region of size @size, or 106 * INVALID_PHYS_ADDR if there isn't enough free memory to satisfy the 107 * request. 108 */ 109 extern phys_addr_t phys_alloc(phys_addr_t size); 110 111 /* 112 * phys_zalloc is like phys_alloc, but zeros the memory before returning. 113 */ 114 extern phys_addr_t phys_zalloc(phys_addr_t size); 115 116 /* 117 * phys_alloc_show outputs all currently allocated regions with the 118 * following format 119 * <start_addr>-<end_addr> [<USED|FREE>] 120 */ 121 extern void phys_alloc_show(void); 122 123 #endif /* _ALLOC_H_ */ 124