@@ -13,6 +13,8 @@
* Copyright (C) 2001 Peter Bergner, IBM Corp.
*/
+struct alist;
+
/**
* enum lmb_flags - definition of memory region attributes
* @LMB_NONE: no special request
@@ -90,16 +92,34 @@ void arch_lmb_reserve_generic(ulong sp, ulong end, ulong align);
/**
* lmb_mem_regions_init() - Initialise the LMB memory
+ * @mem_lst: Pointer to store location of free memory list
+ * @used_lst: Pointer to store location of used memory list
+ * @add_rsv_mem: flag to indicate if memory is to be added and reserved
*
* Initialise the LMB subsystem related data structures. There are two
* alloced lists that are initialised, one for the free memory, and one
* for the used memory.
*
- * Initialise the two lists as part of board init.
+ * Initialise the two lists as part of board init during boot. When called
+ * from a test, passes the pointers to the two lists to the caller. The
+ * caller is then required to call the corresponding function to uninit
+ * the lists.
*
* Return: 0 if OK, -ve on failure.
*/
-int lmb_mem_regions_init(void);
+int lmb_mem_regions_init(struct alist **mem_lst, struct alist **used_lst,
+ bool add_rsv_mem);
+
+/**
+ * lmb_mem_regions_uninit() - Unitialise the lmb lists
+ * @mem_lst: Pointer to store location of free memory list
+ * @used_lst: Pointer to store location of used memory list
+ *
+ * Unitialise the LMB lists for free and used memory that was
+ * initialised as part of the init function. Called when running
+ * lmb test routines.
+ */
+void lmb_mem_regions_uninit(struct alist *mem_lst, struct alist *used_lst);
#endif /* __KERNEL__ */
@@ -740,16 +740,23 @@ __weak void arch_lmb_reserve(void)
/**
* lmb_mem_regions_init() - Initialise the LMB memory
+ * @mem_lst: Pointer to store location of free memory list
+ * @used_lst: Pointer to store location of used memory list
+ * @add_rsv_mem: flag to indicate if memory is to be added and reserved
*
* Initialise the LMB subsystem related data structures. There are two
* alloced lists that are initialised, one for the free memory, and one
* for the used memory.
*
- * Initialise the two lists as part of board init.
+ * Initialise the two lists as part of board init during boot. When called
+ * from a test, passes the pointers to the two lists to the caller. The
+ * caller is then required to call the corresponding function to uninit
+ * the lists.
*
* Return: 0 if OK, -ve on failure.
*/
-int lmb_mem_regions_init(void)
+int lmb_mem_regions_init(struct alist **mem_lst, struct alist **used_lst,
+ bool add_rsv_mem)
{
bool ret;
@@ -767,6 +774,15 @@ int lmb_mem_regions_init(void)
return -1;
}
+ if (mem_lst)
+ *mem_lst = &lmb_free_mem;
+
+ if (used_lst)
+ *used_lst = &lmb_used_mem;
+
+ if (!add_rsv_mem)
+ return 0;
+
lmb_add_memory();
/* Reserve the U-Boot image region once U-Boot has relocated */
@@ -778,6 +794,22 @@ int lmb_mem_regions_init(void)
return 0;
}
+/**
+ * lmb_mem_regions_uninit() - Unitialise the lmb lists
+ * @mem_lst: Pointer to store location of free memory list
+ * @used_lst: Pointer to store location of used memory list
+ *
+ * Unitialise the LMB lists for free and used memory that was
+ * initialised as part of the init function. Called when running
+ * lmb test routines.
+ */
+void __maybe_unused lmb_mem_regions_uninit(struct alist *mem_lst,
+ struct alist *used_lst)
+{
+ alist_uninit(mem_lst);
+ alist_uninit(used_lst);
+}
+
/**
* initr_lmb() - Initialise the LMB lists
*
@@ -791,7 +823,7 @@ int initr_lmb(void)
{
int ret;
- ret = lmb_mem_regions_init();
+ ret = lmb_mem_regions_init(NULL, NULL, true);
if (ret)
printf("Unable to initialise the LMB data structures\n");
@@ -3,6 +3,7 @@
* (C) Copyright 2018 Simon Goldschmidt
*/
+#include <alist.h>
#include <dm.h>
#include <lmb.h>
#include <log.h>
@@ -12,52 +13,51 @@
#include <test/test.h>
#include <test/ut.h>
-extern struct lmb lmb;
-
-static inline bool lmb_is_nomap(struct lmb_property *m)
+static inline bool lmb_is_nomap(struct lmb_region *m)
{
return m->flags & LMB_NOMAP;
}
-static int check_lmb(struct unit_test_state *uts, struct lmb *lmb,
- phys_addr_t ram_base, phys_size_t ram_size,
- unsigned long num_reserved,
+static int check_lmb(struct unit_test_state *uts, struct alist *mem_lst,
+ struct alist *used_lst, phys_addr_t ram_base,
+ phys_size_t ram_size, unsigned long num_reserved,
phys_addr_t base1, phys_size_t size1,
phys_addr_t base2, phys_size_t size2,
phys_addr_t base3, phys_size_t size3)
{
+ struct lmb_region *mem, *used;
+
+ mem = mem_lst->data;
+ used = used_lst->data;
+
if (ram_size) {
- ut_asserteq(lmb->memory.cnt, 1);
- ut_asserteq(lmb->memory.region[0].base, ram_base);
- ut_asserteq(lmb->memory.region[0].size, ram_size);
+ ut_asserteq(mem_lst->count, 1);
+ ut_asserteq(mem[0].base, ram_base);
+ ut_asserteq(mem[0].size, ram_size);
}
- ut_asserteq(lmb->reserved.cnt, num_reserved);
+ ut_asserteq(used_lst->count, num_reserved);
if (num_reserved > 0) {
- ut_asserteq(lmb->reserved.region[0].base, base1);
- ut_asserteq(lmb->reserved.region[0].size, size1);
+ ut_asserteq(used[0].base, base1);
+ ut_asserteq(used[0].size, size1);
}
if (num_reserved > 1) {
- ut_asserteq(lmb->reserved.region[1].base, base2);
- ut_asserteq(lmb->reserved.region[1].size, size2);
+ ut_asserteq(used[1].base, base2);
+ ut_asserteq(used[1].size, size2);
}
if (num_reserved > 2) {
- ut_asserteq(lmb->reserved.region[2].base, base3);
- ut_asserteq(lmb->reserved.region[2].size, size3);
+ ut_asserteq(used[2].base, base3);
+ ut_asserteq(used[2].size, size3);
}
return 0;
}
-#define ASSERT_LMB(lmb, ram_base, ram_size, num_reserved, base1, size1, \
+#define ASSERT_LMB(mem_lst, used_lst, ram_base, ram_size, num_reserved, base1, size1, \
base2, size2, base3, size3) \
- ut_assert(!check_lmb(uts, lmb, ram_base, ram_size, \
+ ut_assert(!check_lmb(uts, mem_lst, used_lst, ram_base, ram_size, \
num_reserved, base1, size1, base2, size2, base3, \
size3))
-/*
- * Test helper function that reserves 64 KiB somewhere in the simulated RAM and
- * then does some alloc + free tests.
- */
static int test_multi_alloc(struct unit_test_state *uts, const phys_addr_t ram,
const phys_size_t ram_size, const phys_addr_t ram0,
const phys_size_t ram0_size,
@@ -67,6 +67,8 @@ static int test_multi_alloc(struct unit_test_state *uts, const phys_addr_t ram,
const phys_addr_t alloc_64k_end = alloc_64k_addr + 0x10000;
long ret;
+ struct alist *mem_lst, *used_lst;
+ struct lmb_region *mem, *used;
phys_addr_t a, a2, b, b2, c, d;
/* check for overflow */
@@ -76,6 +78,10 @@ static int test_multi_alloc(struct unit_test_state *uts, const phys_addr_t ram,
ut_assert(alloc_64k_addr >= ram + 8);
ut_assert(alloc_64k_end <= ram_end - 8);
+ ut_asserteq(lmb_mem_regions_init(&mem_lst, &used_lst, false), 0);
+ mem = mem_lst->data;
+ used = used_lst->data;
+
if (ram0_size) {
ret = lmb_add(ram0, ram0_size, LMB_NONE);
ut_asserteq(ret, 0);
@@ -85,95 +91,97 @@ static int test_multi_alloc(struct unit_test_state *uts, const phys_addr_t ram,
ut_asserteq(ret, 0);
if (ram0_size) {
- ut_asserteq(lmb.memory.cnt, 2);
- ut_asserteq(lmb.memory.region[0].base, ram0);
- ut_asserteq(lmb.memory.region[0].size, ram0_size);
- ut_asserteq(lmb.memory.region[1].base, ram);
- ut_asserteq(lmb.memory.region[1].size, ram_size);
+ ut_asserteq(mem_lst->count, 2);
+ ut_asserteq(mem[0].base, ram0);
+ ut_asserteq(mem[0].size, ram0_size);
+ ut_asserteq(mem[1].base, ram);
+ ut_asserteq(mem[1].size, ram_size);
} else {
- ut_asserteq(lmb.memory.cnt, 1);
- ut_asserteq(lmb.memory.region[0].base, ram);
- ut_asserteq(lmb.memory.region[0].size, ram_size);
+ ut_asserteq(mem_lst->count, 1);
+ ut_asserteq(mem[0].base, ram);
+ ut_asserteq(mem[0].size, ram_size);
}
/* reserve 64KiB somewhere */
ret = lmb_reserve(alloc_64k_addr, 0x10000, LMB_NONE);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, 0, 0, 1, alloc_64k_addr, 0x10000,
+ ASSERT_LMB(mem_lst, used_lst, 0, 0, 1, alloc_64k_addr, 0x10000,
0, 0, 0, 0);
/* allocate somewhere, should be at the end of RAM */
a = lmb_alloc(4, 1, LMB_NONE);
ut_asserteq(a, ram_end - 4);
- ASSERT_LMB(&lmb, 0, 0, 2, alloc_64k_addr, 0x10000,
+ ASSERT_LMB(mem_lst, used_lst, 0, 0, 2, alloc_64k_addr, 0x10000,
ram_end - 4, 4, 0, 0);
/* alloc below end of reserved region -> below reserved region */
b = lmb_alloc_base(4, 1, alloc_64k_end, LMB_NONE);
ut_asserteq(b, alloc_64k_addr - 4);
- ASSERT_LMB(&lmb, 0, 0, 2,
+ ASSERT_LMB(mem_lst, used_lst, 0, 0, 2,
alloc_64k_addr - 4, 0x10000 + 4, ram_end - 4, 4, 0, 0);
/* 2nd time */
c = lmb_alloc(4, 1, LMB_NONE);
ut_asserteq(c, ram_end - 8);
- ASSERT_LMB(&lmb, 0, 0, 2,
+ ASSERT_LMB(mem_lst, used_lst, 0, 0, 2,
alloc_64k_addr - 4, 0x10000 + 4, ram_end - 8, 8, 0, 0);
d = lmb_alloc_base(4, 1, alloc_64k_end, LMB_NONE);
ut_asserteq(d, alloc_64k_addr - 8);
- ASSERT_LMB(&lmb, 0, 0, 2,
+ ASSERT_LMB(mem_lst, used_lst, 0, 0, 2,
alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 8, 0, 0);
ret = lmb_free(a, 4, LMB_NONE);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, 0, 0, 2,
+ ASSERT_LMB(mem_lst, used_lst, 0, 0, 2,
alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0);
/* allocate again to ensure we get the same address */
a2 = lmb_alloc(4, 1, LMB_NONE);
ut_asserteq(a, a2);
- ASSERT_LMB(&lmb, 0, 0, 2,
+ ASSERT_LMB(mem_lst, used_lst, 0, 0, 2,
alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 8, 0, 0);
ret = lmb_free(a2, 4, LMB_NONE);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, 0, 0, 2,
+ ASSERT_LMB(mem_lst, used_lst, 0, 0, 2,
alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0);
ret = lmb_free(b, 4, LMB_NONE);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, 0, 0, 3,
+ ASSERT_LMB(mem_lst, used_lst, 0, 0, 3,
alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000,
ram_end - 8, 4);
/* allocate again to ensure we get the same address */
b2 = lmb_alloc_base(4, 1, alloc_64k_end, LMB_NONE);
ut_asserteq(b, b2);
- ASSERT_LMB(&lmb, 0, 0, 2,
+ ASSERT_LMB(mem_lst, used_lst, 0, 0, 2,
alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0);
ret = lmb_free(b2, 4, LMB_NONE);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, 0, 0, 3,
+ ASSERT_LMB(mem_lst, used_lst, 0, 0, 3,
alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000,
ram_end - 8, 4);
ret = lmb_free(c, 4, LMB_NONE);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, 0, 0, 2,
+ ASSERT_LMB(mem_lst, used_lst, 0, 0, 2,
alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000, 0, 0);
ret = lmb_free(d, 4, LMB_NONE);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, 0, 0, 1, alloc_64k_addr, 0x10000,
+ ASSERT_LMB(mem_lst, used_lst, 0, 0, 1, alloc_64k_addr, 0x10000,
0, 0, 0, 0);
if (ram0_size) {
- ut_asserteq(lmb.memory.cnt, 2);
- ut_asserteq(lmb.memory.region[0].base, ram0);
- ut_asserteq(lmb.memory.region[0].size, ram0_size);
- ut_asserteq(lmb.memory.region[1].base, ram);
- ut_asserteq(lmb.memory.region[1].size, ram_size);
+ ut_asserteq(mem_lst->count, 2);
+ ut_asserteq(mem[0].base, ram0);
+ ut_asserteq(mem[0].size, ram0_size);
+ ut_asserteq(mem[1].base, ram);
+ ut_asserteq(mem[1].size, ram_size);
} else {
- ut_asserteq(lmb.memory.cnt, 1);
- ut_asserteq(lmb.memory.region[0].base, ram);
- ut_asserteq(lmb.memory.region[0].size, ram_size);
+ ut_asserteq(mem_lst->count, 1);
+ ut_asserteq(mem[0].base, ram);
+ ut_asserteq(mem[0].size, ram_size);
}
+ lmb_mem_regions_uninit(mem_lst, used_lst);
+
return 0;
}
@@ -228,45 +236,53 @@ static int test_bigblock(struct unit_test_state *uts, const phys_addr_t ram)
const phys_size_t big_block_size = 0x10000000;
const phys_addr_t ram_end = ram + ram_size;
const phys_addr_t alloc_64k_addr = ram + 0x10000000;
+ struct alist *mem_lst, *used_lst;
+ struct lmb_region *mem, *used;
long ret;
phys_addr_t a, b;
/* check for overflow */
ut_assert(ram_end == 0 || ram_end > ram);
+ ut_asserteq(lmb_mem_regions_init(&mem_lst, &used_lst, false), 0);
+ mem = mem_lst->data;
+ used = used_lst->data;
+
ret = lmb_add(ram, ram_size, LMB_NONE);
ut_asserteq(ret, 0);
/* reserve 64KiB in the middle of RAM */
ret = lmb_reserve(alloc_64k_addr, 0x10000, LMB_NONE);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, alloc_64k_addr, 0x10000,
0, 0, 0, 0);
/* allocate a big block, should be below reserved */
a = lmb_alloc(big_block_size, 1, LMB_NONE);
ut_asserteq(a, ram);
- ASSERT_LMB(&lmb, ram, ram_size, 1, a,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, a,
big_block_size + 0x10000, 0, 0, 0, 0);
/* allocate 2nd big block */
/* This should fail, printing an error */
b = lmb_alloc(big_block_size, 1, LMB_NONE);
ut_asserteq(b, 0);
- ASSERT_LMB(&lmb, ram, ram_size, 1, a,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, a,
big_block_size + 0x10000, 0, 0, 0, 0);
ret = lmb_free(a, big_block_size, LMB_NONE);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, alloc_64k_addr, 0x10000,
0, 0, 0, 0);
/* allocate too big block */
/* This should fail, printing an error */
a = lmb_alloc(ram_size, 1, LMB_NONE);
ut_asserteq(a, 0);
- ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, alloc_64k_addr, 0x10000,
0, 0, 0, 0);
+ lmb_mem_regions_uninit(mem_lst, used_lst);
+
return 0;
}
@@ -292,51 +308,62 @@ static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram,
const phys_addr_t ram_end = ram + ram_size;
long ret;
phys_addr_t a, b;
+ struct alist *mem_lst, *used_lst;
+ struct lmb_region *mem, *used;
const phys_addr_t alloc_size_aligned = (alloc_size + align - 1) &
~(align - 1);
/* check for overflow */
ut_assert(ram_end == 0 || ram_end > ram);
+ ut_asserteq(lmb_mem_regions_init(&mem_lst, &used_lst, false), 0);
+ mem = mem_lst->data;
+ used = used_lst->data;
+
ret = lmb_add(ram, ram_size, LMB_NONE);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
/* allocate a block */
a = lmb_alloc(alloc_size, align, LMB_NONE);
ut_assert(a != 0);
- ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - alloc_size_aligned,
- alloc_size, 0, 0, 0, 0);
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1,
+ ram + ram_size - alloc_size_aligned, alloc_size, 0, 0, 0, 0);
+
/* allocate another block */
b = lmb_alloc(alloc_size, align, LMB_NONE);
ut_assert(b != 0);
if (alloc_size == alloc_size_aligned) {
- ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size -
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram + ram_size -
(alloc_size_aligned * 2), alloc_size * 2, 0, 0, 0,
0);
} else {
- ASSERT_LMB(&lmb, ram, ram_size, 2, ram + ram_size -
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, ram + ram_size -
(alloc_size_aligned * 2), alloc_size, ram + ram_size
- alloc_size_aligned, alloc_size, 0, 0);
}
/* and free them */
ret = lmb_free(b, alloc_size, LMB_NONE);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - alloc_size_aligned,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1,
+ ram + ram_size - alloc_size_aligned,
alloc_size, 0, 0, 0, 0);
ret = lmb_free(a, alloc_size, LMB_NONE);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
/* allocate a block with base*/
b = lmb_alloc_base(alloc_size, align, ram_end, LMB_NONE);
ut_assert(a == b);
- ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - alloc_size_aligned,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1,
+ ram + ram_size - alloc_size_aligned,
alloc_size, 0, 0, 0, 0);
/* and free it */
ret = lmb_free(b, alloc_size, LMB_NONE);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
+
+ lmb_mem_regions_uninit(mem_lst, used_lst);
return 0;
}
@@ -378,33 +405,41 @@ static int lib_test_lmb_at_0(struct unit_test_state *uts)
{
const phys_addr_t ram = 0;
const phys_size_t ram_size = 0x20000000;
+ struct alist *mem_lst, *used_lst;
+ struct lmb_region *mem, *used;
long ret;
phys_addr_t a, b;
+ ut_asserteq(lmb_mem_regions_init(&mem_lst, &used_lst, false), 0);
+ mem = mem_lst->data;
+ used = used_lst->data;
+
ret = lmb_add(ram, ram_size, LMB_NONE);
ut_asserteq(ret, 0);
/* allocate nearly everything */
a = lmb_alloc(ram_size - 4, 1, LMB_NONE);
ut_asserteq(a, ram + 4);
- ASSERT_LMB(&lmb, ram, ram_size, 1, a, ram_size - 4,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, a, ram_size - 4,
0, 0, 0, 0);
/* allocate the rest */
/* This should fail as the allocated address would be 0 */
b = lmb_alloc(4, 1, LMB_NONE);
ut_asserteq(b, 0);
/* check that this was an error by checking lmb */
- ASSERT_LMB(&lmb, ram, ram_size, 1, a, ram_size - 4,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, a, ram_size - 4,
0, 0, 0, 0);
/* check that this was an error by freeing b */
ret = lmb_free(b, 4, LMB_NONE);
ut_asserteq(ret, -1);
- ASSERT_LMB(&lmb, ram, ram_size, 1, a, ram_size - 4,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, a, ram_size - 4,
0, 0, 0, 0);
ret = lmb_free(a, ram_size - 4, LMB_NONE);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
+
+ lmb_mem_regions_uninit(mem_lst, used_lst);
return 0;
}
@@ -415,42 +450,52 @@ static int lib_test_lmb_overlapping_reserve(struct unit_test_state *uts)
{
const phys_addr_t ram = 0x40000000;
const phys_size_t ram_size = 0x20000000;
+ struct alist *mem_lst, *used_lst;
+ struct lmb_region *mem, *used;
long ret;
+ ut_asserteq(lmb_mem_regions_init(&mem_lst, &used_lst, false), 0);
+ mem = mem_lst->data;
+ used = used_lst->data;
+
ret = lmb_add(ram, ram_size, LMB_NONE);
ut_asserteq(ret, 0);
ret = lmb_reserve(0x40010000, 0x10000, LMB_NONE);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, 0x40010000, 0x10000,
0, 0, 0, 0);
- /* allocate overlapping region should fail */
+
+ /* allocate overlapping region should return the coalesced count */
ret = lmb_reserve(0x40011000, 0x10000, LMB_NONE);
- ut_asserteq(ret, -1);
- ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000,
+ ut_asserteq(ret, 1);
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, 0x40010000, 0x11000,
0, 0, 0, 0);
/* allocate 3nd region */
ret = lmb_reserve(0x40030000, 0x10000, LMB_NONE);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, ram, ram_size, 2, 0x40010000, 0x10000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, 0x40010000, 0x11000,
0x40030000, 0x10000, 0, 0);
/* allocate 2nd region , This should coalesced all region into one */
ret = lmb_reserve(0x40020000, 0x10000, LMB_NONE);
ut_assert(ret >= 0);
- ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x30000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, 0x40010000, 0x30000,
0, 0, 0, 0);
/* allocate 2nd region, which should be added as first region */
ret = lmb_reserve(0x40000000, 0x8000, LMB_NONE);
ut_assert(ret >= 0);
- ASSERT_LMB(&lmb, ram, ram_size, 2, 0x40000000, 0x8000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, 0x40000000, 0x8000,
0x40010000, 0x30000, 0, 0);
/* allocate 3rd region, coalesce with first and overlap with second */
ret = lmb_reserve(0x40008000, 0x10000, LMB_NONE);
ut_assert(ret >= 0);
- ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40000000, 0x40000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, 0x40000000, 0x40000,
0, 0, 0, 0);
+
+ lmb_mem_regions_uninit(mem_lst, used_lst);
+
return 0;
}
LIB_TEST(lib_test_lmb_overlapping_reserve, 0);
@@ -461,6 +506,8 @@ LIB_TEST(lib_test_lmb_overlapping_reserve, 0);
*/
static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram)
{
+ struct lmb_region *mem, *used;
+ struct alist *mem_lst, *used_lst;
const phys_size_t ram_size = 0x20000000;
const phys_addr_t ram_end = ram + ram_size;
const phys_size_t alloc_addr_a = ram + 0x8000000;
@@ -472,6 +519,10 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram)
/* check for overflow */
ut_assert(ram_end == 0 || ram_end > ram);
+ ut_asserteq(lmb_mem_regions_init(&mem_lst, &used_lst, false), 0);
+ mem = mem_lst->data;
+ used = used_lst->data;
+
ret = lmb_add(ram, ram_size, LMB_NONE);
ut_asserteq(ret, 0);
@@ -482,34 +533,34 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram)
ut_asserteq(ret, 0);
ret = lmb_reserve(alloc_addr_c, 0x10000, LMB_NONE);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, ram, ram_size, 3, alloc_addr_a, 0x10000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 3, alloc_addr_a, 0x10000,
alloc_addr_b, 0x10000, alloc_addr_c, 0x10000);
/* allocate blocks */
a = lmb_alloc_addr(ram, alloc_addr_a - ram, LMB_NONE);
ut_asserteq(a, ram);
- ASSERT_LMB(&lmb, ram, ram_size, 3, ram, 0x8010000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 3, ram, 0x8010000,
alloc_addr_b, 0x10000, alloc_addr_c, 0x10000);
b = lmb_alloc_addr(alloc_addr_a + 0x10000,
alloc_addr_b - alloc_addr_a - 0x10000, LMB_NONE);
ut_asserteq(b, alloc_addr_a + 0x10000);
- ASSERT_LMB(&lmb, ram, ram_size, 2, ram, 0x10010000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, ram, 0x10010000,
alloc_addr_c, 0x10000, 0, 0);
c = lmb_alloc_addr(alloc_addr_b + 0x10000,
alloc_addr_c - alloc_addr_b - 0x10000, LMB_NONE);
ut_asserteq(c, alloc_addr_b + 0x10000);
- ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, 0x18010000,
0, 0, 0, 0);
d = lmb_alloc_addr(alloc_addr_c + 0x10000,
ram_end - alloc_addr_c - 0x10000, LMB_NONE);
ut_asserteq(d, alloc_addr_c + 0x10000);
- ASSERT_LMB(&lmb, ram, ram_size, 1, ram, ram_size,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, ram_size,
0, 0, 0, 0);
/* allocating anything else should fail */
e = lmb_alloc(1, 1, LMB_NONE);
ut_asserteq(e, 0);
- ASSERT_LMB(&lmb, ram, ram_size, 1, ram, ram_size,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, ram_size,
0, 0, 0, 0);
ret = lmb_free(d, ram_end - alloc_addr_c - 0x10000, LMB_NONE);
@@ -519,39 +570,40 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram)
d = lmb_alloc_addr(ram_end - 4, 4, LMB_NONE);
ut_asserteq(d, ram_end - 4);
- ASSERT_LMB(&lmb, ram, ram_size, 2, ram, 0x18010000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, ram, 0x18010000,
d, 4, 0, 0);
ret = lmb_free(d, 4, LMB_NONE);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, 0x18010000,
0, 0, 0, 0);
d = lmb_alloc_addr(ram_end - 128, 4, LMB_NONE);
ut_asserteq(d, ram_end - 128);
- ASSERT_LMB(&lmb, ram, ram_size, 2, ram, 0x18010000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, ram, 0x18010000,
d, 4, 0, 0);
ret = lmb_free(d, 4, LMB_NONE);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, 0x18010000,
0, 0, 0, 0);
d = lmb_alloc_addr(alloc_addr_c + 0x10000, 4, LMB_NONE);
ut_asserteq(d, alloc_addr_c + 0x10000);
- ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010004,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, 0x18010004,
0, 0, 0, 0);
ret = lmb_free(d, 4, LMB_NONE);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, 0x18010000,
0, 0, 0, 0);
/* allocate at the bottom */
ret = lmb_free(a, alloc_addr_a - ram, LMB_NONE);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, ram, ram_size, 1, ram + 0x8000000, 0x10010000,
- 0, 0, 0, 0);
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram + 0x8000000,
+ 0x10010000, 0, 0, 0, 0);
+
d = lmb_alloc_addr(ram, 4, LMB_NONE);
ut_asserteq(d, ram);
- ASSERT_LMB(&lmb, ram, ram_size, 2, d, 4,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, d, 4,
ram + 0x8000000, 0x10010000, 0, 0);
/* check that allocating outside memory fails */
@@ -564,6 +616,8 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram)
ut_asserteq(ret, 0);
}
+ lmb_mem_regions_uninit(mem_lst, used_lst);
+
return 0;
}
@@ -585,6 +639,8 @@ LIB_TEST(lib_test_lmb_alloc_addr, 0);
static int test_get_unreserved_size(struct unit_test_state *uts,
const phys_addr_t ram)
{
+ struct lmb_region *mem, *used;
+ struct alist *mem_lst, *used_lst;
const phys_size_t ram_size = 0x20000000;
const phys_addr_t ram_end = ram + ram_size;
const phys_size_t alloc_addr_a = ram + 0x8000000;
@@ -596,6 +652,10 @@ static int test_get_unreserved_size(struct unit_test_state *uts,
/* check for overflow */
ut_assert(ram_end == 0 || ram_end > ram);
+ ut_asserteq(lmb_mem_regions_init(&mem_lst, &used_lst, false), 0);
+ mem = mem_lst->data;
+ used = used_lst->data;
+
ret = lmb_add(ram, ram_size, LMB_NONE);
ut_asserteq(ret, 0);
@@ -606,7 +666,7 @@ static int test_get_unreserved_size(struct unit_test_state *uts,
ut_asserteq(ret, 0);
ret = lmb_reserve(alloc_addr_c, 0x10000, LMB_NONE);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, ram, ram_size, 3, alloc_addr_a, 0x10000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 3, alloc_addr_a, 0x10000,
alloc_addr_b, 0x10000, alloc_addr_c, 0x10000);
/* check addresses in between blocks */
@@ -631,6 +691,8 @@ static int test_get_unreserved_size(struct unit_test_state *uts,
s = lmb_get_free_size(ram_end - 4);
ut_asserteq(s, 4);
+ lmb_mem_regions_uninit(mem_lst, used_lst);
+
return 0;
}
@@ -650,83 +712,91 @@ LIB_TEST(lib_test_lmb_get_free_size, 0);
static int lib_test_lmb_flags(struct unit_test_state *uts)
{
+ struct lmb_region *mem, *used;
+ struct alist *mem_lst, *used_lst;
const phys_addr_t ram = 0x40000000;
const phys_size_t ram_size = 0x20000000;
long ret;
+ ut_asserteq(lmb_mem_regions_init(&mem_lst, &used_lst, false), 0);
+ mem = mem_lst->data;
+ used = used_lst->data;
+
ret = lmb_add(ram, ram_size, LMB_NONE);
ut_asserteq(ret, 0);
/* reserve, same flag */
ret = lmb_reserve(0x40010000, 0x10000, LMB_NOMAP);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, 0x40010000, 0x10000,
0, 0, 0, 0);
/* reserve again, same flag */
ret = lmb_reserve(0x40010000, 0x10000, LMB_NOMAP);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, 0x40010000, 0x10000,
0, 0, 0, 0);
/* reserve again, new flag */
ret = lmb_reserve(0x40010000, 0x10000, LMB_NONE);
ut_asserteq(ret, -1);
- ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, 0x40010000, 0x10000,
0, 0, 0, 0);
- ut_asserteq(lmb_is_nomap(&lmb.reserved.region[0]), 1);
+ ut_asserteq(lmb_is_nomap(&used[0]), 1);
/* merge after */
ret = lmb_reserve(0x40020000, 0x10000, LMB_NOMAP);
ut_asserteq(ret, 1);
- ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x20000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, 0x40010000, 0x20000,
0, 0, 0, 0);
/* merge before */
ret = lmb_reserve(0x40000000, 0x10000, LMB_NOMAP);
ut_asserteq(ret, 1);
- ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40000000, 0x30000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, 0x40000000, 0x30000,
0, 0, 0, 0);
- ut_asserteq(lmb_is_nomap(&lmb.reserved.region[0]), 1);
+ ut_asserteq(lmb_is_nomap(&used[0]), 1);
ret = lmb_reserve(0x40030000, 0x10000, LMB_NONE);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, ram, ram_size, 2, 0x40000000, 0x30000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, 0x40000000, 0x30000,
0x40030000, 0x10000, 0, 0);
- ut_asserteq(lmb_is_nomap(&lmb.reserved.region[0]), 1);
- ut_asserteq(lmb_is_nomap(&lmb.reserved.region[1]), 0);
+ ut_asserteq(lmb_is_nomap(&used[0]), 1);
+ ut_asserteq(lmb_is_nomap(&used[1]), 0);
/* test that old API use LMB_NONE */
ret = lmb_reserve(0x40040000, 0x10000, LMB_NONE);
ut_asserteq(ret, 1);
- ASSERT_LMB(&lmb, ram, ram_size, 2, 0x40000000, 0x30000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, 0x40000000, 0x30000,
0x40030000, 0x20000, 0, 0);
- ut_asserteq(lmb_is_nomap(&lmb.reserved.region[0]), 1);
- ut_asserteq(lmb_is_nomap(&lmb.reserved.region[1]), 0);
+ ut_asserteq(lmb_is_nomap(&used[0]), 1);
+ ut_asserteq(lmb_is_nomap(&used[1]), 0);
ret = lmb_reserve(0x40070000, 0x10000, LMB_NOMAP);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, ram, ram_size, 3, 0x40000000, 0x30000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 3, 0x40000000, 0x30000,
0x40030000, 0x20000, 0x40070000, 0x10000);
ret = lmb_reserve(0x40050000, 0x10000, LMB_NOMAP);
ut_asserteq(ret, 0);
- ASSERT_LMB(&lmb, ram, ram_size, 4, 0x40000000, 0x30000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 4, 0x40000000, 0x30000,
0x40030000, 0x20000, 0x40050000, 0x10000);
/* merge with 2 adjacent regions */
ret = lmb_reserve(0x40060000, 0x10000, LMB_NOMAP);
ut_asserteq(ret, 2);
- ASSERT_LMB(&lmb, ram, ram_size, 3, 0x40000000, 0x30000,
+ ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 3, 0x40000000, 0x30000,
0x40030000, 0x20000, 0x40050000, 0x30000);
- ut_asserteq(lmb_is_nomap(&lmb.reserved.region[0]), 1);
- ut_asserteq(lmb_is_nomap(&lmb.reserved.region[1]), 0);
- ut_asserteq(lmb_is_nomap(&lmb.reserved.region[2]), 1);
+ ut_asserteq(lmb_is_nomap(&used[0]), 1);
+ ut_asserteq(lmb_is_nomap(&used[1]), 0);
+ ut_asserteq(lmb_is_nomap(&used[2]), 1);
+
+ lmb_mem_regions_uninit(mem_lst, used_lst);
return 0;
}
The LMB memory maps are now persistent, with alloced lists being used to keep track of the available and free memory. Make corresponding changes in the test functions so that the list information can be accessed by the tests for checking against expected values. Also introduce functions to initialise and cleanup the lists. These functions will be invoked from every test to start the memory map from a clean slate. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> --- Changes since rfc: * Change the lmb_mem_regions_init() function to have it called from the lmb tests as well. include/lmb.h | 24 +++- lib/lmb.c | 38 ++++++- test/lib/lmb.c | 294 ++++++++++++++++++++++++++++++------------------- 3 files changed, 239 insertions(+), 117 deletions(-)