162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci#include "alloc_api.h" 362306a36Sopenharmony_ci 462306a36Sopenharmony_cistatic int alloc_test_flags = TEST_F_NONE; 562306a36Sopenharmony_ci 662306a36Sopenharmony_cistatic inline const char * const get_memblock_alloc_name(int flags) 762306a36Sopenharmony_ci{ 862306a36Sopenharmony_ci if (flags & TEST_F_RAW) 962306a36Sopenharmony_ci return "memblock_alloc_raw"; 1062306a36Sopenharmony_ci return "memblock_alloc"; 1162306a36Sopenharmony_ci} 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_cistatic inline void *run_memblock_alloc(phys_addr_t size, phys_addr_t align) 1462306a36Sopenharmony_ci{ 1562306a36Sopenharmony_ci if (alloc_test_flags & TEST_F_RAW) 1662306a36Sopenharmony_ci return memblock_alloc_raw(size, align); 1762306a36Sopenharmony_ci return memblock_alloc(size, align); 1862306a36Sopenharmony_ci} 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci/* 2162306a36Sopenharmony_ci * A simple test that tries to allocate a small memory region. 2262306a36Sopenharmony_ci * Expect to allocate an aligned region near the end of the available memory. 2362306a36Sopenharmony_ci */ 2462306a36Sopenharmony_cistatic int alloc_top_down_simple_check(void) 2562306a36Sopenharmony_ci{ 2662306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[0]; 2762306a36Sopenharmony_ci void *allocated_ptr = NULL; 2862306a36Sopenharmony_ci phys_addr_t size = SZ_2; 2962306a36Sopenharmony_ci phys_addr_t expected_start; 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci PREFIX_PUSH(); 3262306a36Sopenharmony_ci setup_memblock(); 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci expected_start = memblock_end_of_DRAM() - SMP_CACHE_BYTES; 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc(size, SMP_CACHE_BYTES); 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 3962306a36Sopenharmony_ci assert_mem_content(allocated_ptr, size, alloc_test_flags); 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci ASSERT_EQ(rgn->size, size); 4262306a36Sopenharmony_ci ASSERT_EQ(rgn->base, expected_start); 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 4562306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, size); 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci test_pass_pop(); 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci return 0; 5062306a36Sopenharmony_ci} 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci/* 5362306a36Sopenharmony_ci * A test that tries to allocate memory next to a reserved region that starts at 5462306a36Sopenharmony_ci * the misaligned address. Expect to create two separate entries, with the new 5562306a36Sopenharmony_ci * entry aligned to the provided alignment: 5662306a36Sopenharmony_ci * 5762306a36Sopenharmony_ci * + 5862306a36Sopenharmony_ci * | +--------+ +--------| 5962306a36Sopenharmony_ci * | | rgn2 | | rgn1 | 6062306a36Sopenharmony_ci * +------------+--------+---------+--------+ 6162306a36Sopenharmony_ci * ^ 6262306a36Sopenharmony_ci * | 6362306a36Sopenharmony_ci * Aligned address boundary 6462306a36Sopenharmony_ci * 6562306a36Sopenharmony_ci * The allocation direction is top-down and region arrays are sorted from lower 6662306a36Sopenharmony_ci * to higher addresses, so the new region will be the first entry in 6762306a36Sopenharmony_ci * memory.reserved array. The previously reserved region does not get modified. 6862306a36Sopenharmony_ci * Region counter and total size get updated. 6962306a36Sopenharmony_ci */ 7062306a36Sopenharmony_cistatic int alloc_top_down_disjoint_check(void) 7162306a36Sopenharmony_ci{ 7262306a36Sopenharmony_ci /* After allocation, this will point to the "old" region */ 7362306a36Sopenharmony_ci struct memblock_region *rgn1 = &memblock.reserved.regions[1]; 7462306a36Sopenharmony_ci struct memblock_region *rgn2 = &memblock.reserved.regions[0]; 7562306a36Sopenharmony_ci struct region r1; 7662306a36Sopenharmony_ci void *allocated_ptr = NULL; 7762306a36Sopenharmony_ci phys_addr_t r2_size = SZ_16; 7862306a36Sopenharmony_ci /* Use custom alignment */ 7962306a36Sopenharmony_ci phys_addr_t alignment = SMP_CACHE_BYTES * 2; 8062306a36Sopenharmony_ci phys_addr_t total_size; 8162306a36Sopenharmony_ci phys_addr_t expected_start; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci PREFIX_PUSH(); 8462306a36Sopenharmony_ci setup_memblock(); 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci r1.base = memblock_end_of_DRAM() - SZ_2; 8762306a36Sopenharmony_ci r1.size = SZ_2; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci total_size = r1.size + r2_size; 9062306a36Sopenharmony_ci expected_start = memblock_end_of_DRAM() - alignment; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci memblock_reserve(r1.base, r1.size); 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc(r2_size, alignment); 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 9762306a36Sopenharmony_ci assert_mem_content(allocated_ptr, r2_size, alloc_test_flags); 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci ASSERT_EQ(rgn1->size, r1.size); 10062306a36Sopenharmony_ci ASSERT_EQ(rgn1->base, r1.base); 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci ASSERT_EQ(rgn2->size, r2_size); 10362306a36Sopenharmony_ci ASSERT_EQ(rgn2->base, expected_start); 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 2); 10662306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, total_size); 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci test_pass_pop(); 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci return 0; 11162306a36Sopenharmony_ci} 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci/* 11462306a36Sopenharmony_ci * A test that tries to allocate memory when there is enough space at the end 11562306a36Sopenharmony_ci * of the previously reserved block (i.e. first fit): 11662306a36Sopenharmony_ci * 11762306a36Sopenharmony_ci * | +--------+--------------| 11862306a36Sopenharmony_ci * | | r1 | r2 | 11962306a36Sopenharmony_ci * +--------------+--------+--------------+ 12062306a36Sopenharmony_ci * 12162306a36Sopenharmony_ci * Expect a merge of both regions. Only the region size gets updated. 12262306a36Sopenharmony_ci */ 12362306a36Sopenharmony_cistatic int alloc_top_down_before_check(void) 12462306a36Sopenharmony_ci{ 12562306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[0]; 12662306a36Sopenharmony_ci void *allocated_ptr = NULL; 12762306a36Sopenharmony_ci /* 12862306a36Sopenharmony_ci * The first region ends at the aligned address to test region merging 12962306a36Sopenharmony_ci */ 13062306a36Sopenharmony_ci phys_addr_t r1_size = SMP_CACHE_BYTES; 13162306a36Sopenharmony_ci phys_addr_t r2_size = SZ_512; 13262306a36Sopenharmony_ci phys_addr_t total_size = r1_size + r2_size; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci PREFIX_PUSH(); 13562306a36Sopenharmony_ci setup_memblock(); 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci memblock_reserve(memblock_end_of_DRAM() - total_size, r1_size); 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc(r2_size, SMP_CACHE_BYTES); 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 14262306a36Sopenharmony_ci assert_mem_content(allocated_ptr, r2_size, alloc_test_flags); 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci ASSERT_EQ(rgn->size, total_size); 14562306a36Sopenharmony_ci ASSERT_EQ(rgn->base, memblock_end_of_DRAM() - total_size); 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 14862306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, total_size); 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci test_pass_pop(); 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci return 0; 15362306a36Sopenharmony_ci} 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci/* 15662306a36Sopenharmony_ci * A test that tries to allocate memory when there is not enough space at the 15762306a36Sopenharmony_ci * end of the previously reserved block (i.e. second fit): 15862306a36Sopenharmony_ci * 15962306a36Sopenharmony_ci * | +-----------+------+ | 16062306a36Sopenharmony_ci * | | r2 | r1 | | 16162306a36Sopenharmony_ci * +------------+-----------+------+-----+ 16262306a36Sopenharmony_ci * 16362306a36Sopenharmony_ci * Expect a merge of both regions. Both the base address and size of the region 16462306a36Sopenharmony_ci * get updated. 16562306a36Sopenharmony_ci */ 16662306a36Sopenharmony_cistatic int alloc_top_down_after_check(void) 16762306a36Sopenharmony_ci{ 16862306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[0]; 16962306a36Sopenharmony_ci struct region r1; 17062306a36Sopenharmony_ci void *allocated_ptr = NULL; 17162306a36Sopenharmony_ci phys_addr_t r2_size = SZ_512; 17262306a36Sopenharmony_ci phys_addr_t total_size; 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci PREFIX_PUSH(); 17562306a36Sopenharmony_ci setup_memblock(); 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci /* 17862306a36Sopenharmony_ci * The first region starts at the aligned address to test region merging 17962306a36Sopenharmony_ci */ 18062306a36Sopenharmony_ci r1.base = memblock_end_of_DRAM() - SMP_CACHE_BYTES; 18162306a36Sopenharmony_ci r1.size = SZ_8; 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci total_size = r1.size + r2_size; 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci memblock_reserve(r1.base, r1.size); 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc(r2_size, SMP_CACHE_BYTES); 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 19062306a36Sopenharmony_ci assert_mem_content(allocated_ptr, r2_size, alloc_test_flags); 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci ASSERT_EQ(rgn->size, total_size); 19362306a36Sopenharmony_ci ASSERT_EQ(rgn->base, r1.base - r2_size); 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 19662306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, total_size); 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci test_pass_pop(); 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci return 0; 20162306a36Sopenharmony_ci} 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci/* 20462306a36Sopenharmony_ci * A test that tries to allocate memory when there are two reserved regions with 20562306a36Sopenharmony_ci * a gap too small to fit the new region: 20662306a36Sopenharmony_ci * 20762306a36Sopenharmony_ci * | +--------+----------+ +------| 20862306a36Sopenharmony_ci * | | r3 | r2 | | r1 | 20962306a36Sopenharmony_ci * +-------+--------+----------+---+------+ 21062306a36Sopenharmony_ci * 21162306a36Sopenharmony_ci * Expect to allocate a region before the one that starts at the lower address, 21262306a36Sopenharmony_ci * and merge them into one. The region counter and total size fields get 21362306a36Sopenharmony_ci * updated. 21462306a36Sopenharmony_ci */ 21562306a36Sopenharmony_cistatic int alloc_top_down_second_fit_check(void) 21662306a36Sopenharmony_ci{ 21762306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[0]; 21862306a36Sopenharmony_ci struct region r1, r2; 21962306a36Sopenharmony_ci void *allocated_ptr = NULL; 22062306a36Sopenharmony_ci phys_addr_t r3_size = SZ_1K; 22162306a36Sopenharmony_ci phys_addr_t total_size; 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci PREFIX_PUSH(); 22462306a36Sopenharmony_ci setup_memblock(); 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci r1.base = memblock_end_of_DRAM() - SZ_512; 22762306a36Sopenharmony_ci r1.size = SZ_512; 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci r2.base = r1.base - SZ_512; 23062306a36Sopenharmony_ci r2.size = SZ_256; 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci total_size = r1.size + r2.size + r3_size; 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci memblock_reserve(r1.base, r1.size); 23562306a36Sopenharmony_ci memblock_reserve(r2.base, r2.size); 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc(r3_size, SMP_CACHE_BYTES); 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 24062306a36Sopenharmony_ci assert_mem_content(allocated_ptr, r3_size, alloc_test_flags); 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci ASSERT_EQ(rgn->size, r2.size + r3_size); 24362306a36Sopenharmony_ci ASSERT_EQ(rgn->base, r2.base - r3_size); 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 2); 24662306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, total_size); 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci test_pass_pop(); 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci return 0; 25162306a36Sopenharmony_ci} 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci/* 25462306a36Sopenharmony_ci * A test that tries to allocate memory when there are two reserved regions with 25562306a36Sopenharmony_ci * a gap big enough to accommodate the new region: 25662306a36Sopenharmony_ci * 25762306a36Sopenharmony_ci * | +--------+--------+--------+ | 25862306a36Sopenharmony_ci * | | r2 | r3 | r1 | | 25962306a36Sopenharmony_ci * +-----+--------+--------+--------+-----+ 26062306a36Sopenharmony_ci * 26162306a36Sopenharmony_ci * Expect to merge all of them, creating one big entry in memblock.reserved 26262306a36Sopenharmony_ci * array. The region counter and total size fields get updated. 26362306a36Sopenharmony_ci */ 26462306a36Sopenharmony_cistatic int alloc_in_between_generic_check(void) 26562306a36Sopenharmony_ci{ 26662306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[0]; 26762306a36Sopenharmony_ci struct region r1, r2; 26862306a36Sopenharmony_ci void *allocated_ptr = NULL; 26962306a36Sopenharmony_ci phys_addr_t gap_size = SMP_CACHE_BYTES; 27062306a36Sopenharmony_ci phys_addr_t r3_size = SZ_64; 27162306a36Sopenharmony_ci /* 27262306a36Sopenharmony_ci * Calculate regions size so there's just enough space for the new entry 27362306a36Sopenharmony_ci */ 27462306a36Sopenharmony_ci phys_addr_t rgn_size = (MEM_SIZE - (2 * gap_size + r3_size)) / 2; 27562306a36Sopenharmony_ci phys_addr_t total_size; 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci PREFIX_PUSH(); 27862306a36Sopenharmony_ci setup_memblock(); 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci r1.size = rgn_size; 28162306a36Sopenharmony_ci r1.base = memblock_end_of_DRAM() - (gap_size + rgn_size); 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci r2.size = rgn_size; 28462306a36Sopenharmony_ci r2.base = memblock_start_of_DRAM() + gap_size; 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci total_size = r1.size + r2.size + r3_size; 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci memblock_reserve(r1.base, r1.size); 28962306a36Sopenharmony_ci memblock_reserve(r2.base, r2.size); 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc(r3_size, SMP_CACHE_BYTES); 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 29462306a36Sopenharmony_ci assert_mem_content(allocated_ptr, r3_size, alloc_test_flags); 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci ASSERT_EQ(rgn->size, total_size); 29762306a36Sopenharmony_ci ASSERT_EQ(rgn->base, r1.base - r2.size - r3_size); 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 30062306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, total_size); 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ci test_pass_pop(); 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci return 0; 30562306a36Sopenharmony_ci} 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci/* 30862306a36Sopenharmony_ci * A test that tries to allocate memory when the memory is filled with reserved 30962306a36Sopenharmony_ci * regions with memory gaps too small to fit the new region: 31062306a36Sopenharmony_ci * 31162306a36Sopenharmony_ci * +-------+ 31262306a36Sopenharmony_ci * | new | 31362306a36Sopenharmony_ci * +--+----+ 31462306a36Sopenharmony_ci * | +-----+ +-----+ +-----+ | 31562306a36Sopenharmony_ci * | | res | | res | | res | | 31662306a36Sopenharmony_ci * +----+-----+----+-----+----+-----+----+ 31762306a36Sopenharmony_ci * 31862306a36Sopenharmony_ci * Expect no allocation to happen. 31962306a36Sopenharmony_ci */ 32062306a36Sopenharmony_cistatic int alloc_small_gaps_generic_check(void) 32162306a36Sopenharmony_ci{ 32262306a36Sopenharmony_ci void *allocated_ptr = NULL; 32362306a36Sopenharmony_ci phys_addr_t region_size = SZ_1K; 32462306a36Sopenharmony_ci phys_addr_t gap_size = SZ_256; 32562306a36Sopenharmony_ci phys_addr_t region_end; 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci PREFIX_PUSH(); 32862306a36Sopenharmony_ci setup_memblock(); 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci region_end = memblock_start_of_DRAM(); 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci while (region_end < memblock_end_of_DRAM()) { 33362306a36Sopenharmony_ci memblock_reserve(region_end + gap_size, region_size); 33462306a36Sopenharmony_ci region_end += gap_size + region_size; 33562306a36Sopenharmony_ci } 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc(region_size, SMP_CACHE_BYTES); 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci ASSERT_EQ(allocated_ptr, NULL); 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci test_pass_pop(); 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ci return 0; 34462306a36Sopenharmony_ci} 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci/* 34762306a36Sopenharmony_ci * A test that tries to allocate memory when all memory is reserved. 34862306a36Sopenharmony_ci * Expect no allocation to happen. 34962306a36Sopenharmony_ci */ 35062306a36Sopenharmony_cistatic int alloc_all_reserved_generic_check(void) 35162306a36Sopenharmony_ci{ 35262306a36Sopenharmony_ci void *allocated_ptr = NULL; 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci PREFIX_PUSH(); 35562306a36Sopenharmony_ci setup_memblock(); 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci /* Simulate full memory */ 35862306a36Sopenharmony_ci memblock_reserve(memblock_start_of_DRAM(), MEM_SIZE); 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc(SZ_256, SMP_CACHE_BYTES); 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci ASSERT_EQ(allocated_ptr, NULL); 36362306a36Sopenharmony_ci 36462306a36Sopenharmony_ci test_pass_pop(); 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci return 0; 36762306a36Sopenharmony_ci} 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_ci/* 37062306a36Sopenharmony_ci * A test that tries to allocate memory when the memory is almost full, 37162306a36Sopenharmony_ci * with not enough space left for the new region: 37262306a36Sopenharmony_ci * 37362306a36Sopenharmony_ci * +-------+ 37462306a36Sopenharmony_ci * | new | 37562306a36Sopenharmony_ci * +-------+ 37662306a36Sopenharmony_ci * |-----------------------------+ | 37762306a36Sopenharmony_ci * | reserved | | 37862306a36Sopenharmony_ci * +-----------------------------+---+ 37962306a36Sopenharmony_ci * 38062306a36Sopenharmony_ci * Expect no allocation to happen. 38162306a36Sopenharmony_ci */ 38262306a36Sopenharmony_cistatic int alloc_no_space_generic_check(void) 38362306a36Sopenharmony_ci{ 38462306a36Sopenharmony_ci void *allocated_ptr = NULL; 38562306a36Sopenharmony_ci phys_addr_t available_size = SZ_256; 38662306a36Sopenharmony_ci phys_addr_t reserved_size = MEM_SIZE - available_size; 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ci PREFIX_PUSH(); 38962306a36Sopenharmony_ci setup_memblock(); 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ci /* Simulate almost-full memory */ 39262306a36Sopenharmony_ci memblock_reserve(memblock_start_of_DRAM(), reserved_size); 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc(SZ_1K, SMP_CACHE_BYTES); 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ci ASSERT_EQ(allocated_ptr, NULL); 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci test_pass_pop(); 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci return 0; 40162306a36Sopenharmony_ci} 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_ci/* 40462306a36Sopenharmony_ci * A test that tries to allocate memory when the memory is almost full, 40562306a36Sopenharmony_ci * but there is just enough space left: 40662306a36Sopenharmony_ci * 40762306a36Sopenharmony_ci * |---------------------------+---------| 40862306a36Sopenharmony_ci * | reserved | new | 40962306a36Sopenharmony_ci * +---------------------------+---------+ 41062306a36Sopenharmony_ci * 41162306a36Sopenharmony_ci * Expect to allocate memory and merge all the regions. The total size field 41262306a36Sopenharmony_ci * gets updated. 41362306a36Sopenharmony_ci */ 41462306a36Sopenharmony_cistatic int alloc_limited_space_generic_check(void) 41562306a36Sopenharmony_ci{ 41662306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[0]; 41762306a36Sopenharmony_ci void *allocated_ptr = NULL; 41862306a36Sopenharmony_ci phys_addr_t available_size = SZ_256; 41962306a36Sopenharmony_ci phys_addr_t reserved_size = MEM_SIZE - available_size; 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci PREFIX_PUSH(); 42262306a36Sopenharmony_ci setup_memblock(); 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci /* Simulate almost-full memory */ 42562306a36Sopenharmony_ci memblock_reserve(memblock_start_of_DRAM(), reserved_size); 42662306a36Sopenharmony_ci 42762306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc(available_size, SMP_CACHE_BYTES); 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 43062306a36Sopenharmony_ci assert_mem_content(allocated_ptr, available_size, alloc_test_flags); 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_ci ASSERT_EQ(rgn->size, MEM_SIZE); 43362306a36Sopenharmony_ci ASSERT_EQ(rgn->base, memblock_start_of_DRAM()); 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 43662306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, MEM_SIZE); 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_ci test_pass_pop(); 43962306a36Sopenharmony_ci 44062306a36Sopenharmony_ci return 0; 44162306a36Sopenharmony_ci} 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ci/* 44462306a36Sopenharmony_ci * A test that tries to allocate memory when there is no available memory 44562306a36Sopenharmony_ci * registered (i.e. memblock.memory has only a dummy entry). 44662306a36Sopenharmony_ci * Expect no allocation to happen. 44762306a36Sopenharmony_ci */ 44862306a36Sopenharmony_cistatic int alloc_no_memory_generic_check(void) 44962306a36Sopenharmony_ci{ 45062306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[0]; 45162306a36Sopenharmony_ci void *allocated_ptr = NULL; 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_ci PREFIX_PUSH(); 45462306a36Sopenharmony_ci 45562306a36Sopenharmony_ci reset_memblock_regions(); 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc(SZ_1K, SMP_CACHE_BYTES); 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_ci ASSERT_EQ(allocated_ptr, NULL); 46062306a36Sopenharmony_ci ASSERT_EQ(rgn->size, 0); 46162306a36Sopenharmony_ci ASSERT_EQ(rgn->base, 0); 46262306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, 0); 46362306a36Sopenharmony_ci 46462306a36Sopenharmony_ci test_pass_pop(); 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_ci return 0; 46762306a36Sopenharmony_ci} 46862306a36Sopenharmony_ci 46962306a36Sopenharmony_ci/* 47062306a36Sopenharmony_ci * A test that tries to allocate a region that is larger than the total size of 47162306a36Sopenharmony_ci * available memory (memblock.memory): 47262306a36Sopenharmony_ci * 47362306a36Sopenharmony_ci * +-----------------------------------+ 47462306a36Sopenharmony_ci * | new | 47562306a36Sopenharmony_ci * +-----------------------------------+ 47662306a36Sopenharmony_ci * | | 47762306a36Sopenharmony_ci * | | 47862306a36Sopenharmony_ci * +---------------------------------+ 47962306a36Sopenharmony_ci * 48062306a36Sopenharmony_ci * Expect no allocation to happen. 48162306a36Sopenharmony_ci */ 48262306a36Sopenharmony_cistatic int alloc_too_large_generic_check(void) 48362306a36Sopenharmony_ci{ 48462306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[0]; 48562306a36Sopenharmony_ci void *allocated_ptr = NULL; 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_ci PREFIX_PUSH(); 48862306a36Sopenharmony_ci setup_memblock(); 48962306a36Sopenharmony_ci 49062306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc(MEM_SIZE + SZ_2, SMP_CACHE_BYTES); 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_ci ASSERT_EQ(allocated_ptr, NULL); 49362306a36Sopenharmony_ci ASSERT_EQ(rgn->size, 0); 49462306a36Sopenharmony_ci ASSERT_EQ(rgn->base, 0); 49562306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, 0); 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_ci test_pass_pop(); 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_ci return 0; 50062306a36Sopenharmony_ci} 50162306a36Sopenharmony_ci 50262306a36Sopenharmony_ci/* 50362306a36Sopenharmony_ci * A simple test that tries to allocate a small memory region. 50462306a36Sopenharmony_ci * Expect to allocate an aligned region at the beginning of the available 50562306a36Sopenharmony_ci * memory. 50662306a36Sopenharmony_ci */ 50762306a36Sopenharmony_cistatic int alloc_bottom_up_simple_check(void) 50862306a36Sopenharmony_ci{ 50962306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[0]; 51062306a36Sopenharmony_ci void *allocated_ptr = NULL; 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_ci PREFIX_PUSH(); 51362306a36Sopenharmony_ci setup_memblock(); 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc(SZ_2, SMP_CACHE_BYTES); 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 51862306a36Sopenharmony_ci assert_mem_content(allocated_ptr, SZ_2, alloc_test_flags); 51962306a36Sopenharmony_ci 52062306a36Sopenharmony_ci ASSERT_EQ(rgn->size, SZ_2); 52162306a36Sopenharmony_ci ASSERT_EQ(rgn->base, memblock_start_of_DRAM()); 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 52462306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, SZ_2); 52562306a36Sopenharmony_ci 52662306a36Sopenharmony_ci test_pass_pop(); 52762306a36Sopenharmony_ci 52862306a36Sopenharmony_ci return 0; 52962306a36Sopenharmony_ci} 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_ci/* 53262306a36Sopenharmony_ci * A test that tries to allocate memory next to a reserved region that starts at 53362306a36Sopenharmony_ci * the misaligned address. Expect to create two separate entries, with the new 53462306a36Sopenharmony_ci * entry aligned to the provided alignment: 53562306a36Sopenharmony_ci * 53662306a36Sopenharmony_ci * + 53762306a36Sopenharmony_ci * | +----------+ +----------+ | 53862306a36Sopenharmony_ci * | | rgn1 | | rgn2 | | 53962306a36Sopenharmony_ci * +----+----------+---+----------+-----+ 54062306a36Sopenharmony_ci * ^ 54162306a36Sopenharmony_ci * | 54262306a36Sopenharmony_ci * Aligned address boundary 54362306a36Sopenharmony_ci * 54462306a36Sopenharmony_ci * The allocation direction is bottom-up, so the new region will be the second 54562306a36Sopenharmony_ci * entry in memory.reserved array. The previously reserved region does not get 54662306a36Sopenharmony_ci * modified. Region counter and total size get updated. 54762306a36Sopenharmony_ci */ 54862306a36Sopenharmony_cistatic int alloc_bottom_up_disjoint_check(void) 54962306a36Sopenharmony_ci{ 55062306a36Sopenharmony_ci struct memblock_region *rgn1 = &memblock.reserved.regions[0]; 55162306a36Sopenharmony_ci struct memblock_region *rgn2 = &memblock.reserved.regions[1]; 55262306a36Sopenharmony_ci struct region r1; 55362306a36Sopenharmony_ci void *allocated_ptr = NULL; 55462306a36Sopenharmony_ci phys_addr_t r2_size = SZ_16; 55562306a36Sopenharmony_ci /* Use custom alignment */ 55662306a36Sopenharmony_ci phys_addr_t alignment = SMP_CACHE_BYTES * 2; 55762306a36Sopenharmony_ci phys_addr_t total_size; 55862306a36Sopenharmony_ci phys_addr_t expected_start; 55962306a36Sopenharmony_ci 56062306a36Sopenharmony_ci PREFIX_PUSH(); 56162306a36Sopenharmony_ci setup_memblock(); 56262306a36Sopenharmony_ci 56362306a36Sopenharmony_ci r1.base = memblock_start_of_DRAM() + SZ_2; 56462306a36Sopenharmony_ci r1.size = SZ_2; 56562306a36Sopenharmony_ci 56662306a36Sopenharmony_ci total_size = r1.size + r2_size; 56762306a36Sopenharmony_ci expected_start = memblock_start_of_DRAM() + alignment; 56862306a36Sopenharmony_ci 56962306a36Sopenharmony_ci memblock_reserve(r1.base, r1.size); 57062306a36Sopenharmony_ci 57162306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc(r2_size, alignment); 57262306a36Sopenharmony_ci 57362306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 57462306a36Sopenharmony_ci assert_mem_content(allocated_ptr, r2_size, alloc_test_flags); 57562306a36Sopenharmony_ci 57662306a36Sopenharmony_ci ASSERT_EQ(rgn1->size, r1.size); 57762306a36Sopenharmony_ci ASSERT_EQ(rgn1->base, r1.base); 57862306a36Sopenharmony_ci 57962306a36Sopenharmony_ci ASSERT_EQ(rgn2->size, r2_size); 58062306a36Sopenharmony_ci ASSERT_EQ(rgn2->base, expected_start); 58162306a36Sopenharmony_ci 58262306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 2); 58362306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, total_size); 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_ci test_pass_pop(); 58662306a36Sopenharmony_ci 58762306a36Sopenharmony_ci return 0; 58862306a36Sopenharmony_ci} 58962306a36Sopenharmony_ci 59062306a36Sopenharmony_ci/* 59162306a36Sopenharmony_ci * A test that tries to allocate memory when there is enough space at 59262306a36Sopenharmony_ci * the beginning of the previously reserved block (i.e. first fit): 59362306a36Sopenharmony_ci * 59462306a36Sopenharmony_ci * |------------------+--------+ | 59562306a36Sopenharmony_ci * | r1 | r2 | | 59662306a36Sopenharmony_ci * +------------------+--------+---------+ 59762306a36Sopenharmony_ci * 59862306a36Sopenharmony_ci * Expect a merge of both regions. Only the region size gets updated. 59962306a36Sopenharmony_ci */ 60062306a36Sopenharmony_cistatic int alloc_bottom_up_before_check(void) 60162306a36Sopenharmony_ci{ 60262306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[0]; 60362306a36Sopenharmony_ci void *allocated_ptr = NULL; 60462306a36Sopenharmony_ci phys_addr_t r1_size = SZ_512; 60562306a36Sopenharmony_ci phys_addr_t r2_size = SZ_128; 60662306a36Sopenharmony_ci phys_addr_t total_size = r1_size + r2_size; 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_ci PREFIX_PUSH(); 60962306a36Sopenharmony_ci setup_memblock(); 61062306a36Sopenharmony_ci 61162306a36Sopenharmony_ci memblock_reserve(memblock_start_of_DRAM() + r1_size, r2_size); 61262306a36Sopenharmony_ci 61362306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc(r1_size, SMP_CACHE_BYTES); 61462306a36Sopenharmony_ci 61562306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 61662306a36Sopenharmony_ci assert_mem_content(allocated_ptr, r1_size, alloc_test_flags); 61762306a36Sopenharmony_ci 61862306a36Sopenharmony_ci ASSERT_EQ(rgn->size, total_size); 61962306a36Sopenharmony_ci ASSERT_EQ(rgn->base, memblock_start_of_DRAM()); 62062306a36Sopenharmony_ci 62162306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 62262306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, total_size); 62362306a36Sopenharmony_ci 62462306a36Sopenharmony_ci test_pass_pop(); 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_ci return 0; 62762306a36Sopenharmony_ci} 62862306a36Sopenharmony_ci 62962306a36Sopenharmony_ci/* 63062306a36Sopenharmony_ci * A test that tries to allocate memory when there is not enough space at 63162306a36Sopenharmony_ci * the beginning of the previously reserved block (i.e. second fit): 63262306a36Sopenharmony_ci * 63362306a36Sopenharmony_ci * | +--------+--------------+ | 63462306a36Sopenharmony_ci * | | r1 | r2 | | 63562306a36Sopenharmony_ci * +----+--------+--------------+---------+ 63662306a36Sopenharmony_ci * 63762306a36Sopenharmony_ci * Expect a merge of both regions. Only the region size gets updated. 63862306a36Sopenharmony_ci */ 63962306a36Sopenharmony_cistatic int alloc_bottom_up_after_check(void) 64062306a36Sopenharmony_ci{ 64162306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[0]; 64262306a36Sopenharmony_ci struct region r1; 64362306a36Sopenharmony_ci void *allocated_ptr = NULL; 64462306a36Sopenharmony_ci phys_addr_t r2_size = SZ_512; 64562306a36Sopenharmony_ci phys_addr_t total_size; 64662306a36Sopenharmony_ci 64762306a36Sopenharmony_ci PREFIX_PUSH(); 64862306a36Sopenharmony_ci setup_memblock(); 64962306a36Sopenharmony_ci 65062306a36Sopenharmony_ci /* 65162306a36Sopenharmony_ci * The first region starts at the aligned address to test region merging 65262306a36Sopenharmony_ci */ 65362306a36Sopenharmony_ci r1.base = memblock_start_of_DRAM() + SMP_CACHE_BYTES; 65462306a36Sopenharmony_ci r1.size = SZ_64; 65562306a36Sopenharmony_ci 65662306a36Sopenharmony_ci total_size = r1.size + r2_size; 65762306a36Sopenharmony_ci 65862306a36Sopenharmony_ci memblock_reserve(r1.base, r1.size); 65962306a36Sopenharmony_ci 66062306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc(r2_size, SMP_CACHE_BYTES); 66162306a36Sopenharmony_ci 66262306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 66362306a36Sopenharmony_ci assert_mem_content(allocated_ptr, r2_size, alloc_test_flags); 66462306a36Sopenharmony_ci 66562306a36Sopenharmony_ci ASSERT_EQ(rgn->size, total_size); 66662306a36Sopenharmony_ci ASSERT_EQ(rgn->base, r1.base); 66762306a36Sopenharmony_ci 66862306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 1); 66962306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, total_size); 67062306a36Sopenharmony_ci 67162306a36Sopenharmony_ci test_pass_pop(); 67262306a36Sopenharmony_ci 67362306a36Sopenharmony_ci return 0; 67462306a36Sopenharmony_ci} 67562306a36Sopenharmony_ci 67662306a36Sopenharmony_ci/* 67762306a36Sopenharmony_ci * A test that tries to allocate memory when there are two reserved regions, the 67862306a36Sopenharmony_ci * first one starting at the beginning of the available memory, with a gap too 67962306a36Sopenharmony_ci * small to fit the new region: 68062306a36Sopenharmony_ci * 68162306a36Sopenharmony_ci * |------------+ +--------+--------+ | 68262306a36Sopenharmony_ci * | r1 | | r2 | r3 | | 68362306a36Sopenharmony_ci * +------------+-----+--------+--------+--+ 68462306a36Sopenharmony_ci * 68562306a36Sopenharmony_ci * Expect to allocate after the second region, which starts at the higher 68662306a36Sopenharmony_ci * address, and merge them into one. The region counter and total size fields 68762306a36Sopenharmony_ci * get updated. 68862306a36Sopenharmony_ci */ 68962306a36Sopenharmony_cistatic int alloc_bottom_up_second_fit_check(void) 69062306a36Sopenharmony_ci{ 69162306a36Sopenharmony_ci struct memblock_region *rgn = &memblock.reserved.regions[1]; 69262306a36Sopenharmony_ci struct region r1, r2; 69362306a36Sopenharmony_ci void *allocated_ptr = NULL; 69462306a36Sopenharmony_ci phys_addr_t r3_size = SZ_1K; 69562306a36Sopenharmony_ci phys_addr_t total_size; 69662306a36Sopenharmony_ci 69762306a36Sopenharmony_ci PREFIX_PUSH(); 69862306a36Sopenharmony_ci setup_memblock(); 69962306a36Sopenharmony_ci 70062306a36Sopenharmony_ci r1.base = memblock_start_of_DRAM(); 70162306a36Sopenharmony_ci r1.size = SZ_512; 70262306a36Sopenharmony_ci 70362306a36Sopenharmony_ci r2.base = r1.base + r1.size + SZ_512; 70462306a36Sopenharmony_ci r2.size = SZ_256; 70562306a36Sopenharmony_ci 70662306a36Sopenharmony_ci total_size = r1.size + r2.size + r3_size; 70762306a36Sopenharmony_ci 70862306a36Sopenharmony_ci memblock_reserve(r1.base, r1.size); 70962306a36Sopenharmony_ci memblock_reserve(r2.base, r2.size); 71062306a36Sopenharmony_ci 71162306a36Sopenharmony_ci allocated_ptr = run_memblock_alloc(r3_size, SMP_CACHE_BYTES); 71262306a36Sopenharmony_ci 71362306a36Sopenharmony_ci ASSERT_NE(allocated_ptr, NULL); 71462306a36Sopenharmony_ci assert_mem_content(allocated_ptr, r3_size, alloc_test_flags); 71562306a36Sopenharmony_ci 71662306a36Sopenharmony_ci ASSERT_EQ(rgn->size, r2.size + r3_size); 71762306a36Sopenharmony_ci ASSERT_EQ(rgn->base, r2.base); 71862306a36Sopenharmony_ci 71962306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.cnt, 2); 72062306a36Sopenharmony_ci ASSERT_EQ(memblock.reserved.total_size, total_size); 72162306a36Sopenharmony_ci 72262306a36Sopenharmony_ci test_pass_pop(); 72362306a36Sopenharmony_ci 72462306a36Sopenharmony_ci return 0; 72562306a36Sopenharmony_ci} 72662306a36Sopenharmony_ci 72762306a36Sopenharmony_ci/* Test case wrappers */ 72862306a36Sopenharmony_cistatic int alloc_simple_check(void) 72962306a36Sopenharmony_ci{ 73062306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 73162306a36Sopenharmony_ci memblock_set_bottom_up(false); 73262306a36Sopenharmony_ci alloc_top_down_simple_check(); 73362306a36Sopenharmony_ci memblock_set_bottom_up(true); 73462306a36Sopenharmony_ci alloc_bottom_up_simple_check(); 73562306a36Sopenharmony_ci 73662306a36Sopenharmony_ci return 0; 73762306a36Sopenharmony_ci} 73862306a36Sopenharmony_ci 73962306a36Sopenharmony_cistatic int alloc_disjoint_check(void) 74062306a36Sopenharmony_ci{ 74162306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 74262306a36Sopenharmony_ci memblock_set_bottom_up(false); 74362306a36Sopenharmony_ci alloc_top_down_disjoint_check(); 74462306a36Sopenharmony_ci memblock_set_bottom_up(true); 74562306a36Sopenharmony_ci alloc_bottom_up_disjoint_check(); 74662306a36Sopenharmony_ci 74762306a36Sopenharmony_ci return 0; 74862306a36Sopenharmony_ci} 74962306a36Sopenharmony_ci 75062306a36Sopenharmony_cistatic int alloc_before_check(void) 75162306a36Sopenharmony_ci{ 75262306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 75362306a36Sopenharmony_ci memblock_set_bottom_up(false); 75462306a36Sopenharmony_ci alloc_top_down_before_check(); 75562306a36Sopenharmony_ci memblock_set_bottom_up(true); 75662306a36Sopenharmony_ci alloc_bottom_up_before_check(); 75762306a36Sopenharmony_ci 75862306a36Sopenharmony_ci return 0; 75962306a36Sopenharmony_ci} 76062306a36Sopenharmony_ci 76162306a36Sopenharmony_cistatic int alloc_after_check(void) 76262306a36Sopenharmony_ci{ 76362306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 76462306a36Sopenharmony_ci memblock_set_bottom_up(false); 76562306a36Sopenharmony_ci alloc_top_down_after_check(); 76662306a36Sopenharmony_ci memblock_set_bottom_up(true); 76762306a36Sopenharmony_ci alloc_bottom_up_after_check(); 76862306a36Sopenharmony_ci 76962306a36Sopenharmony_ci return 0; 77062306a36Sopenharmony_ci} 77162306a36Sopenharmony_ci 77262306a36Sopenharmony_cistatic int alloc_in_between_check(void) 77362306a36Sopenharmony_ci{ 77462306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 77562306a36Sopenharmony_ci run_top_down(alloc_in_between_generic_check); 77662306a36Sopenharmony_ci run_bottom_up(alloc_in_between_generic_check); 77762306a36Sopenharmony_ci 77862306a36Sopenharmony_ci return 0; 77962306a36Sopenharmony_ci} 78062306a36Sopenharmony_ci 78162306a36Sopenharmony_cistatic int alloc_second_fit_check(void) 78262306a36Sopenharmony_ci{ 78362306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 78462306a36Sopenharmony_ci memblock_set_bottom_up(false); 78562306a36Sopenharmony_ci alloc_top_down_second_fit_check(); 78662306a36Sopenharmony_ci memblock_set_bottom_up(true); 78762306a36Sopenharmony_ci alloc_bottom_up_second_fit_check(); 78862306a36Sopenharmony_ci 78962306a36Sopenharmony_ci return 0; 79062306a36Sopenharmony_ci} 79162306a36Sopenharmony_ci 79262306a36Sopenharmony_cistatic int alloc_small_gaps_check(void) 79362306a36Sopenharmony_ci{ 79462306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 79562306a36Sopenharmony_ci run_top_down(alloc_small_gaps_generic_check); 79662306a36Sopenharmony_ci run_bottom_up(alloc_small_gaps_generic_check); 79762306a36Sopenharmony_ci 79862306a36Sopenharmony_ci return 0; 79962306a36Sopenharmony_ci} 80062306a36Sopenharmony_ci 80162306a36Sopenharmony_cistatic int alloc_all_reserved_check(void) 80262306a36Sopenharmony_ci{ 80362306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 80462306a36Sopenharmony_ci run_top_down(alloc_all_reserved_generic_check); 80562306a36Sopenharmony_ci run_bottom_up(alloc_all_reserved_generic_check); 80662306a36Sopenharmony_ci 80762306a36Sopenharmony_ci return 0; 80862306a36Sopenharmony_ci} 80962306a36Sopenharmony_ci 81062306a36Sopenharmony_cistatic int alloc_no_space_check(void) 81162306a36Sopenharmony_ci{ 81262306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 81362306a36Sopenharmony_ci run_top_down(alloc_no_space_generic_check); 81462306a36Sopenharmony_ci run_bottom_up(alloc_no_space_generic_check); 81562306a36Sopenharmony_ci 81662306a36Sopenharmony_ci return 0; 81762306a36Sopenharmony_ci} 81862306a36Sopenharmony_ci 81962306a36Sopenharmony_cistatic int alloc_limited_space_check(void) 82062306a36Sopenharmony_ci{ 82162306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 82262306a36Sopenharmony_ci run_top_down(alloc_limited_space_generic_check); 82362306a36Sopenharmony_ci run_bottom_up(alloc_limited_space_generic_check); 82462306a36Sopenharmony_ci 82562306a36Sopenharmony_ci return 0; 82662306a36Sopenharmony_ci} 82762306a36Sopenharmony_ci 82862306a36Sopenharmony_cistatic int alloc_no_memory_check(void) 82962306a36Sopenharmony_ci{ 83062306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 83162306a36Sopenharmony_ci run_top_down(alloc_no_memory_generic_check); 83262306a36Sopenharmony_ci run_bottom_up(alloc_no_memory_generic_check); 83362306a36Sopenharmony_ci 83462306a36Sopenharmony_ci return 0; 83562306a36Sopenharmony_ci} 83662306a36Sopenharmony_ci 83762306a36Sopenharmony_cistatic int alloc_too_large_check(void) 83862306a36Sopenharmony_ci{ 83962306a36Sopenharmony_ci test_print("\tRunning %s...\n", __func__); 84062306a36Sopenharmony_ci run_top_down(alloc_too_large_generic_check); 84162306a36Sopenharmony_ci run_bottom_up(alloc_too_large_generic_check); 84262306a36Sopenharmony_ci 84362306a36Sopenharmony_ci return 0; 84462306a36Sopenharmony_ci} 84562306a36Sopenharmony_ci 84662306a36Sopenharmony_cistatic int memblock_alloc_checks_internal(int flags) 84762306a36Sopenharmony_ci{ 84862306a36Sopenharmony_ci const char *func = get_memblock_alloc_name(flags); 84962306a36Sopenharmony_ci 85062306a36Sopenharmony_ci alloc_test_flags = flags; 85162306a36Sopenharmony_ci prefix_reset(); 85262306a36Sopenharmony_ci prefix_push(func); 85362306a36Sopenharmony_ci test_print("Running %s tests...\n", func); 85462306a36Sopenharmony_ci 85562306a36Sopenharmony_ci reset_memblock_attributes(); 85662306a36Sopenharmony_ci dummy_physical_memory_init(); 85762306a36Sopenharmony_ci 85862306a36Sopenharmony_ci alloc_simple_check(); 85962306a36Sopenharmony_ci alloc_disjoint_check(); 86062306a36Sopenharmony_ci alloc_before_check(); 86162306a36Sopenharmony_ci alloc_after_check(); 86262306a36Sopenharmony_ci alloc_second_fit_check(); 86362306a36Sopenharmony_ci alloc_small_gaps_check(); 86462306a36Sopenharmony_ci alloc_in_between_check(); 86562306a36Sopenharmony_ci alloc_all_reserved_check(); 86662306a36Sopenharmony_ci alloc_no_space_check(); 86762306a36Sopenharmony_ci alloc_limited_space_check(); 86862306a36Sopenharmony_ci alloc_no_memory_check(); 86962306a36Sopenharmony_ci alloc_too_large_check(); 87062306a36Sopenharmony_ci 87162306a36Sopenharmony_ci dummy_physical_memory_cleanup(); 87262306a36Sopenharmony_ci 87362306a36Sopenharmony_ci prefix_pop(); 87462306a36Sopenharmony_ci 87562306a36Sopenharmony_ci return 0; 87662306a36Sopenharmony_ci} 87762306a36Sopenharmony_ci 87862306a36Sopenharmony_ciint memblock_alloc_checks(void) 87962306a36Sopenharmony_ci{ 88062306a36Sopenharmony_ci memblock_alloc_checks_internal(TEST_F_NONE); 88162306a36Sopenharmony_ci memblock_alloc_checks_internal(TEST_F_RAW); 88262306a36Sopenharmony_ci 88362306a36Sopenharmony_ci return 0; 88462306a36Sopenharmony_ci} 885