Exemple #1
0
static phys_addr_t __init_memblock memblock_find_region(phys_addr_t start, phys_addr_t end,
					  phys_addr_t size, phys_addr_t align)
{
	phys_addr_t base, res_base;
	long j;

	/* In case, huge size is requested */
	if (end < size)
		return MEMBLOCK_ERROR;

	base = memblock_align_down((end - size), align);

	/* Prevent allocations returning 0 as it's also used to
	 * indicate an allocation failure
	 */
	if (start == 0)
		start = PAGE_SIZE;

	while (start <= base) {
		j = memblock_overlaps_region(&memblock.reserved, base, size);
		if (j < 0)
			return base;
		res_base = memblock.reserved.regions[j].base;
		if (res_base < size)
			break;
		base = memblock_align_down(res_base - size, align);
	}

	return MEMBLOCK_ERROR;
}
Exemple #2
0
u64 __init __memblock_alloc_base(u64 size, u64 align, u64 max_addr)
{
	long i, j;
	u64 base = 0;
	u64 res_base;

	BUG_ON(0 == size);

	size = memblock_align_up(size, align);

	/* On some platforms, make sure we allocate lowmem */
	/* Note that MEMBLOCK_REAL_LIMIT may be MEMBLOCK_ALLOC_ANYWHERE */
	if (max_addr == MEMBLOCK_ALLOC_ANYWHERE)
		max_addr = MEMBLOCK_REAL_LIMIT;

	for (i = memblock.memory.cnt - 1; i >= 0; i--) {
		u64 memblockbase = memblock.memory.region[i].base;
		u64 memblocksize = memblock.memory.region[i].size;

		if (memblocksize < size)
			continue;
		if (max_addr == MEMBLOCK_ALLOC_ANYWHERE)
			base = memblock_align_down(memblockbase + memblocksize - size, align);
		else if (memblockbase < max_addr) {
			base = min(memblockbase + memblocksize, max_addr);
			base = memblock_align_down(base - size, align);
		} else
			continue;

		while (base && memblockbase <= base) {
			j = memblock_overlaps_region(&memblock.reserved, base, size);
			if (j < 0) {
				/* this area isn't reserved, take it */
				if (memblock_add_region(&memblock.reserved, base, size) < 0)
					return 0;
				return base;
			}
			res_base = memblock.reserved.region[j].base;
			if (res_base < size)
				break;
			base = memblock_align_down(res_base - size, align);
		}
	}
	return 0;
}
Exemple #3
0
static u64 __init memblock_alloc_nid_unreserved(u64 start, u64 end,
					   u64 size, u64 align)
{
	u64 base, res_base;
	long j;

	base = memblock_align_down((end - size), align);
	while (start <= base) {
		j = memblock_overlaps_region(&memblock.reserved, base, size);
		if (j < 0) {
			/* this area isn't reserved, take it */
			if (memblock_add_region(&memblock.reserved, base, size) < 0)
				base = ~(u64)0;
			return base;
		}
		res_base = memblock.reserved.region[j].base;
		if (res_base < size)
			break;
		base = memblock_align_down(res_base - size, align);
	}

	return ~(u64)0;
}