Layer malloc/calloc/free/memalign over a basic allocator. The implementation of high-level routines remains the basic one from before, but the callback interface is reduced to a single function. Since alloc.c now contains the physical address allocator only, rename it. Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx> --- arm/Makefile.common | 2 +- lib/alloc.h | 77 ++++++------------------------------------- lib/{alloc.c => alloc_phys.c} | 62 +++------------------------------- lib/alloc_phys.h | 39 ++++++++++++++++++++++ lib/arm/setup.c | 1 + lib/powerpc/setup.c | 1 + powerpc/Makefile.common | 2 +- s390x/Makefile | 2 +- 8 files changed, 59 insertions(+), 127 deletions(-) rename lib/{alloc.c => alloc_phys.c} (68%) create mode 100644 lib/alloc_phys.h diff --git a/arm/Makefile.common b/arm/Makefile.common index 7e5f527..ded620f 100644 --- a/arm/Makefile.common +++ b/arm/Makefile.common @@ -34,7 +34,7 @@ asm-offsets = lib/$(ARCH)/asm-offsets.h include $(SRCDIR)/scripts/asm-offsets.mak cflatobjs += lib/util.o -cflatobjs += lib/alloc.o +cflatobjs += lib/phys_alloc.o cflatobjs += lib/devicetree.o cflatobjs += lib/pci.o cflatobjs += lib/pci-host-generic.o diff --git a/lib/alloc.h b/lib/alloc.h index 81f5369..24f85b4 100644 --- a/lib/alloc.h +++ b/lib/alloc.h @@ -23,33 +23,31 @@ #include "libcflat.h" struct alloc_ops { - void *(*malloc)(size_t size); - void *(*calloc)(size_t nmemb, size_t size); - void (*free)(void *ptr); void *(*memalign)(size_t alignment, size_t size); }; -/* - * alloc_ops is initialized to early_alloc_ops - */ extern struct alloc_ops *alloc_ops; +/* + * Our malloc implementation is currently so simple that it can just + * be inlined. :) + */ static inline void *malloc(size_t size) { - assert(alloc_ops && alloc_ops->malloc); - return alloc_ops->malloc(size); + assert(alloc_ops && alloc_ops->memalign); + return alloc_ops->memalign(sizeof(long), size); } static inline void *calloc(size_t nmemb, size_t size) { - assert(alloc_ops && alloc_ops->calloc); - return alloc_ops->calloc(nmemb, size); + void *ptr = malloc(nmemb * size); + if (ptr) + memset(ptr, 0, nmemb * size); + return ptr; } static inline void free(void *ptr) { - assert(alloc_ops && alloc_ops->free); - alloc_ops->free(ptr); } static inline void *memalign(size_t alignment, size_t size) @@ -58,59 +56,4 @@ static inline void *memalign(size_t alignment, size_t size) return alloc_ops->memalign(alignment, size); } -/* - * phys_alloc is a very simple allocator which allows physical memory - * to be partitioned into regions until all memory is allocated. - * - * Note: This is such a simple allocator that there is no way to free - * a region. For more complicated memory management a single region - * can be allocated, but then have its memory managed by a more - * sophisticated allocator, e.g. a page allocator. - */ -#define DEFAULT_MINIMUM_ALIGNMENT 32 - -/* - * phys_alloc_init creates the initial free memory region of size @size - * at @base. The minimum alignment is set to DEFAULT_MINIMUM_ALIGNMENT. - */ -extern void phys_alloc_init(phys_addr_t base, phys_addr_t size); - -/* - * phys_alloc_set_minimum_alignment sets the minimum alignment to - * @align. - */ -extern void phys_alloc_set_minimum_alignment(phys_addr_t align); - -/* - * phys_alloc_aligned returns the base address of a region of size @size, - * where the address is aligned to @align, or INVALID_PHYS_ADDR if there - * isn't enough free memory to satisfy the request. - */ -extern phys_addr_t phys_alloc_aligned(phys_addr_t size, phys_addr_t align); - -/* - * phys_zalloc_aligned is like phys_alloc_aligned, but zeros the memory - * before returning the address. - */ -extern phys_addr_t phys_zalloc_aligned(phys_addr_t size, phys_addr_t align); - -/* - * phys_alloc returns the base address of a region of size @size, or - * INVALID_PHYS_ADDR if there isn't enough free memory to satisfy the - * request. - */ -extern phys_addr_t phys_alloc(phys_addr_t size); - -/* - * phys_zalloc is like phys_alloc, but zeros the memory before returning. - */ -extern phys_addr_t phys_zalloc(phys_addr_t size); - -/* - * phys_alloc_show outputs all currently allocated regions with the - * following format - * <start_addr>-<end_addr> [<USED|FREE>] - */ -extern void phys_alloc_show(void); - #endif /* _ALLOC_H_ */ diff --git a/lib/alloc.c b/lib/alloc_phys.c similarity index 68% rename from lib/alloc.c rename to lib/alloc_phys.c index d553a7e..3972277 100644 --- a/lib/alloc.c +++ b/lib/alloc_phys.c @@ -2,6 +2,9 @@ * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@xxxxxxxxxx> * * This work is licensed under the terms of the GNU LGPL, version 2. + * + * This is a simple allocator that provides contiguous physical addresses + * with byte granularity. */ #include "alloc.h" #include "asm/spinlock.h" @@ -9,6 +12,8 @@ #define PHYS_ALLOC_NR_REGIONS 256 +#define DEFAULT_MINIMUM_ALIGNMENT 32 + struct phys_alloc_region { phys_addr_t base; phys_addr_t size; @@ -102,60 +107,6 @@ static phys_addr_t phys_alloc_aligned_safe(phys_addr_t size, return addr; } -static phys_addr_t phys_zalloc_aligned_safe(phys_addr_t size, - phys_addr_t align, bool safe) -{ - phys_addr_t addr = phys_alloc_aligned_safe(size, align, safe); - if (addr == INVALID_PHYS_ADDR) - return addr; - - memset(phys_to_virt(addr), 0, size); - return addr; -} - -phys_addr_t phys_alloc_aligned(phys_addr_t size, phys_addr_t align) -{ - return phys_alloc_aligned_safe(size, align, false); -} - -phys_addr_t phys_zalloc_aligned(phys_addr_t size, phys_addr_t align) -{ - return phys_zalloc_aligned_safe(size, align, false); -} - -phys_addr_t phys_alloc(phys_addr_t size) -{ - return phys_alloc_aligned(size, align_min); -} - -phys_addr_t phys_zalloc(phys_addr_t size) -{ - return phys_zalloc_aligned(size, align_min); -} - -static void *early_malloc(size_t size) -{ - phys_addr_t addr = phys_alloc_aligned_safe(size, align_min, true); - if (addr == INVALID_PHYS_ADDR) - return NULL; - - return phys_to_virt(addr); -} - -static void *early_calloc(size_t nmemb, size_t size) -{ - phys_addr_t addr = phys_zalloc_aligned_safe(nmemb * size, - align_min, true); - if (addr == INVALID_PHYS_ADDR) - return NULL; - - return phys_to_virt(addr); -} - -static void early_free(void *ptr __unused) -{ -} - static void *early_memalign(size_t alignment, size_t size) { phys_addr_t addr; @@ -170,9 +121,6 @@ static void *early_memalign(size_t alignment, size_t size) } static struct alloc_ops early_alloc_ops = { - .malloc = early_malloc, - .calloc = early_calloc, - .free = early_free, .memalign = early_memalign, }; diff --git a/lib/alloc_phys.h b/lib/alloc_phys.h new file mode 100644 index 0000000..f09d667 --- /dev/null +++ b/lib/alloc_phys.h @@ -0,0 +1,39 @@ +#ifndef _ALLOC_PHYS_H_ +#define _ALLOC_PHYS_H_ +/* + * phys_alloc is a very simple allocator which allows physical memory + * to be partitioned into regions until all memory is allocated. + * + * Note: This is such a simple allocator that there is no way to free + * a region. For more complicated memory management a single region + * can be allocated, but then have its memory managed by a more + * sophisticated allocator, e.g. a page allocator. + * + * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@xxxxxxxxxx> + * + * This work is licensed under the terms of the GNU LGPL, version 2. + */ +#include "libcflat.h" + +#define DEFAULT_MINIMUM_ALIGNMENT 32 + +/* + * phys_alloc_init creates the initial free memory region of size @size + * at @base. The minimum alignment is set to DEFAULT_MINIMUM_ALIGNMENT. + */ +extern void phys_alloc_init(phys_addr_t base, phys_addr_t size); + +/* + * phys_alloc_set_minimum_alignment sets the minimum alignment to + * @align. + */ +extern void phys_alloc_set_minimum_alignment(phys_addr_t align); + +/* + * phys_alloc_show outputs all currently allocated regions with the + * following format + * <start_addr>-<end_addr> [<USED|FREE>] + */ +extern void phys_alloc_show(void); + +#endif /* _ALLOC_PHYS_H_ */ diff --git a/lib/arm/setup.c b/lib/arm/setup.c index a0b1795..a014c48 100644 --- a/lib/arm/setup.c +++ b/lib/arm/setup.c @@ -14,6 +14,7 @@ #include <libfdt/libfdt.h> #include <devicetree.h> #include <alloc.h> +#include <phys_alloc.h> #include <argv.h> #include <asm/thread_info.h> #include <asm/setup.h> diff --git a/lib/powerpc/setup.c b/lib/powerpc/setup.c index 20a1e37..c0e46bb 100644 --- a/lib/powerpc/setup.c +++ b/lib/powerpc/setup.c @@ -14,6 +14,7 @@ #include <libfdt/libfdt.h> #include <devicetree.h> #include <alloc.h> +#include <phys_alloc.h> #include <argv.h> #include <asm/setup.h> #include <asm/page.h> diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common index c4df2e9..89789fe 100644 --- a/powerpc/Makefile.common +++ b/powerpc/Makefile.common @@ -30,7 +30,7 @@ asm-offsets = lib/$(ARCH)/asm-offsets.h include $(SRCDIR)/scripts/asm-offsets.mak cflatobjs += lib/util.o -cflatobjs += lib/alloc.o +cflatobjs += lib/phys_alloc.o cflatobjs += lib/devicetree.o cflatobjs += lib/powerpc/io.o cflatobjs += lib/powerpc/hcall.o diff --git a/s390x/Makefile b/s390x/Makefile index 573cba2..213abcd 100644 --- a/s390x/Makefile +++ b/s390x/Makefile @@ -21,7 +21,7 @@ asm-offsets = lib/$(ARCH)/asm-offsets.h include $(SRCDIR)/scripts/asm-offsets.mak cflatobjs += lib/util.o -cflatobjs += lib/alloc.o +cflatobjs += lib/phys_alloc.o cflatobjs += lib/s390x/io.o cflatobjs += lib/s390x/stack.o cflatobjs += lib/s390x/sclp-ascii.o -- 2.14.2