Пример #1
0
Файл: lmb.c Проект: 274914765/C
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;
}
Пример #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;
}
Пример #3
0
Файл: lmb.c Проект: 274914765/C
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;
}