Exemple #1
0
u64 __init __lmb_alloc_base(u64 size, u64 align, u64 max_addr)
{
    long i, j;
    u64 base = 0;
    u64 res_base;

    BUG_ON(0 == size);

    size = lmb_align_up(size, align);

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

    for (i = lmb.memory.cnt - 1; i >= 0; i--) {
        u64 lmbbase = lmb.memory.region[i].base;
        u64 lmbsize = lmb.memory.region[i].size;

        if (lmbsize < size)
            continue;
        if (max_addr == LMB_ALLOC_ANYWHERE)
            base = lmb_align_down(lmbbase + lmbsize - size, align);
        else if (lmbbase < max_addr) {
            base = min(lmbbase + lmbsize, max_addr);
            base = lmb_align_down(base - size, align);
        } else
            continue;

        while (base && lmbbase <= base) {
            j = lmb_overlaps_region(&lmb.reserved, base, size);
            if (j < 0) {
                /* this area isn't reserved, take it */
                if (lmb_add_region(&lmb.reserved, base, size) < 0)
                    return 0;
                return base;
            }
            res_base = lmb.reserved.region[j].base;
            if (res_base < size)
                break;
            base = lmb_align_down(res_base - size, align);
        }
    }
    return 0;
}
Exemple #2
0
phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phys_addr_t max_addr)
{
	long i, j;
	phys_addr_t base = 0;
	phys_addr_t res_base;

	for (i = lmb->memory.cnt-1; i >= 0; i--) {
		phys_addr_t lmbbase = lmb->memory.region[i].base;
		phys_size_t lmbsize = lmb->memory.region[i].size;

		if (lmbsize < size)
			continue;
		if (max_addr == LMB_ALLOC_ANYWHERE)
			base = lmb_align_down(lmbbase + lmbsize - size, align);
		else if (lmbbase < max_addr) {
			base = lmbbase + lmbsize;
			if (base < lmbbase)
				base = -1;
			base = min(base, max_addr);
			base = lmb_align_down(base - size, align);
		} else
			continue;

		while (base && lmbbase <= base) {
			j = lmb_overlaps_region(&lmb->reserved, base, size);
			if (j < 0) {
				/* This area isn't reserved, take it */
				if (lmb_add_region(&lmb->reserved, base,
							lmb_align_up(size,
								align)) < 0)
					return 0;
				return base;
			}
			res_base = lmb->reserved.region[j].base;
			if (res_base < size)
				break;
			base = lmb_align_down(res_base - size, align);
		}
	}
	return 0;
}
Exemple #3
0
unsigned long __init __lmb_alloc_base(unsigned long size, unsigned long align,
				    unsigned long max_addr)
{
	long i, j;
	unsigned long base = 0;

	BUG_ON(0 == size);

#ifdef CONFIG_PPC32
	/* On 32-bit, make sure we allocate lowmem */
	if (max_addr == LMB_ALLOC_ANYWHERE)
		max_addr = __max_low_memory;
#endif
	for (i = lmb.memory.cnt-1; i >= 0; i--) {
		unsigned long lmbbase = lmb.memory.region[i].base;
		unsigned long lmbsize = lmb.memory.region[i].size;

		if (max_addr == LMB_ALLOC_ANYWHERE)
			base = _ALIGN_DOWN(lmbbase + lmbsize - size, align);
		else if (lmbbase < max_addr) {
			base = min(lmbbase + lmbsize, max_addr);
			base = _ALIGN_DOWN(base - size, align);
		} else
			continue;

		while ((lmbbase <= base) &&
		       ((j = lmb_overlaps_region(&lmb.reserved, base, size)) >= 0) )
			base = _ALIGN_DOWN(lmb.reserved.region[j].base - size,
					   align);

		if ((base != 0) && (lmbbase <= base))
			break;
	}

	if (i < 0)
		return 0;

	lmb_add_region(&lmb.reserved, base, size);

	return base;
}
Exemple #4
0
static u64 __init lmb_alloc_nid_unreserved(u64 start, u64 end,
                       u64 size, u64 align)
{
    u64 base, res_base;
    long j;

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

    return ~(u64)0;
}
Exemple #5
0
u64
lmb_alloc_base(u64 size, u64 align, u64 max_addr)
{
	long i, j;
	u64 base = 0;
	u64 offset = reloc_offset();
	struct lmb *_lmb = PTRRELOC(&lmb);
	struct lmb_region *_mem = &(_lmb->memory);
	struct lmb_region *_rsv = &(_lmb->reserved);

	for (i=_mem->cnt-1; i >= 0; i--) {
		u64 lmbbase = _mem->region[i].base;
		u64 lmbsize = _mem->region[i].size;

		if ( max_addr == LMB_ALLOC_ANYWHERE )
			base = _ALIGN_DOWN(lmbbase+lmbsize-size, align);
		else if ( lmbbase < max_addr )
			base = _ALIGN_DOWN(min(lmbbase+lmbsize,max_addr)-size, align);
		else
			continue;

		while ( (lmbbase <= base) &&
			((j = lmb_overlaps_region(_rsv,base,size)) >= 0) ) {
			base = _ALIGN_DOWN(_rsv->region[j].base-size, align);
		}

		if ( (base != 0) && (lmbbase <= base) )
			break;
	}

	if ( i < 0 )
		return 0;

	lmb_add_region(_rsv, base, size);

	return base;
}