From 3bee194f53c141c25ed866431dc198ee12fb0f86 Mon Sep 17 00:00:00 2001 From: Joseph Chen Date: Tue, 7 May 2019 18:45:08 +0800 Subject: [PATCH] lib: sysmem: add sysmem_can_alloc() interface Check if the region can be sysmem allocated. Change-Id: I26a524c1597bee65ab1282da5ec373b9603866ba Signed-off-by: Joseph Chen --- include/sysmem.h | 15 +++++++++++++++ lib/sysmem.c | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/include/sysmem.h b/include/sysmem.h index f32b63a03b..2a51898388 100644 --- a/include/sysmem.h +++ b/include/sysmem.h @@ -93,6 +93,16 @@ void *sysmem_alloc_base_by_name(const char *name, void *sysmem_fdt_reserve_alloc_base(const char *name, phys_addr_t base, phys_size_t size); +/** + * sysmem_can_alloc() - Check if the region can be allocated + * + * @base: region base + * @size: region size + * + * @return true on okay. + */ +bool sysmem_can_alloc(phys_size_t base, phys_size_t size); + /** * sysmem_free() - Free allocated sysmem region * @@ -128,6 +138,11 @@ static inline void *sysmem_alloc(enum memblk_id id, phys_size_t size) return malloc(size); } +static inline bool sysmem_can_alloc(phys_size_t base, phys_size_t size) +{ + return true; +} + static inline void *sysmem_alloc_base(enum memblk_id id, phys_addr_t base, phys_size_t size) { diff --git a/lib/sysmem.c b/lib/sysmem.c index e65a28d60d..9b11e9f4b2 100644 --- a/lib/sysmem.c +++ b/lib/sysmem.c @@ -354,7 +354,7 @@ static void *sysmem_alloc_align_base(enum memblk_id id, name, (ulong)base, (ulong)(base + size), (ulong)paddr, (ulong)(paddr + size)); /* Free what we don't want allocated region */ - if (lmb_free(&sysmem->lmb, paddr, alloc_size)) + if (lmb_free(&sysmem->lmb, paddr, alloc_size) < 0) SYSMEM_E("Failed to free \"%s\"\n", name); goto out; @@ -435,6 +435,38 @@ void *sysmem_fdt_reserve_alloc_base(const char *name, return paddr; } +bool sysmem_can_alloc(phys_size_t base, phys_size_t size) +{ + struct sysmem *sysmem = &plat_sysmem; + phys_addr_t alloc_base; + phys_addr_t paddr; + int ret; + + if (!sysmem_has_init()) + return false; + + /* LMB is align down alloc mechanism */ + alloc_base = base + size; + paddr = __lmb_alloc_base(&sysmem->lmb, + size, + SYSMEM_ALLOC_NO_ALIGN, + alloc_base); + if (paddr) { + /* If free failed, return false */ + ret = lmb_free(&sysmem->lmb, base, size); + if (ret < 0) { + SYSMEM_E("Can't free at 0x%08lx - 0x%08lx, ret=%d\n", + (ulong)base, (ulong)(base + size), ret); + return false; + } + } else { + SYSMEM_D("Can't alloc at 0x%08lx - 0x%08lx\n", + (ulong)base, (ulong)(base + size)); + } + + return (paddr == base) ? true : false; +} + int sysmem_free(phys_addr_t base) { struct sysmem *sysmem = &plat_sysmem;