Exemple #1
0
long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size)
{
	struct lmb_region *rgn = &(lmb->reserved);
	phys_addr_t rgnbegin, rgnend;
	phys_addr_t end = base + size;
	int i;

	rgnbegin = rgnend = 0; /* supress gcc warnings */

	/* Find the region where (base, size) belongs to */
	for (i=0; i < rgn->cnt; i++) {
		rgnbegin = rgn->region[i].base;
		rgnend = rgnbegin + rgn->region[i].size;

		if ((rgnbegin <= base) && (end <= rgnend))
			break;
	}

	/* Didn't find the region */
	if (i == rgn->cnt)
		return -1;

	/* Check to see if we are removing entire region */
	if ((rgnbegin == base) && (rgnend == end)) {
		lmb_remove_region(rgn, i);
		return 0;
	}

	/* Check to see if region is matching at the front */
	if (rgnbegin == base) {
		rgn->region[i].base = end;
		rgn->region[i].size -= size;
		return 0;
	}

	/* Check to see if the region is matching at the end */
	if (rgnend == end) {
		rgn->region[i].size -= size;
		return 0;
	}

	/*
	 * We need to split the entry -  adjust the current one to the
	 * beginging of the hole and add the region after hole.
	 */
	rgn->region[i].size = base - rgn->region[i].base;
	return lmb_add_region(rgn, end, rgnend - end);
}
Exemple #2
0
/* You must call lmb_analyze() after this. */
void __init lmb_enforce_memory_limit(u64 memory_limit)
{
    unsigned long i;
    u64 limit;
    struct lmb_property *p;

    if (!memory_limit)
        return;

    /* Truncate the lmb regions to satisfy the memory limit. */
    limit = memory_limit;
    for (i = 0; i < lmb.memory.cnt; i++) {
        if (limit > lmb.memory.region[i].size) {
            limit -= lmb.memory.region[i].size;
            continue;
        }

        lmb.memory.region[i].size = limit;
        lmb.memory.cnt = i + 1;
        break;
    }

    if (lmb.memory.region[0].size < lmb.rmo_size)
        lmb.rmo_size = lmb.memory.region[0].size;

    /* And truncate any reserves above the limit also. */
    for (i = 0; i < lmb.reserved.cnt; i++) {
        p = &lmb.reserved.region[i];

        if (p->base > memory_limit)
            p->size = 0;
        else if ((p->base + p->size) > memory_limit)
            p->size = memory_limit - p->base;

        if (p->size == 0) {
            lmb_remove_region(&lmb.reserved, i);
            i--;
        }
    }
}
Exemple #3
0
/* Assumption: base addr of region 1 < base addr of region 2 */
static void lmb_coalesce_regions(struct lmb_region *rgn,
		unsigned long r1, unsigned long r2)
{
	rgn->region[r1].size += rgn->region[r2].size;
	lmb_remove_region(rgn, r2);
}