/*
 * Procedures for maintaining information about logical memory blocks.
 *
 * Peter Bergner, IBM Corp.	June 2001.
 * Copyright (C) 2001 Peter Bergner.
 * 
 *      This program is free software; you can redistribute it and/or
 *      modify it under the terms of the GNU General Public License
 *      as published by the Free Software Foundation; either version
 *      2 of the License, or (at your option) any later version.
 */

#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/bitops.h>
#include <asm/types.h>
#include <asm/page.h>
#include <asm/prom.h>
#include <asm/lmb.h>
#ifdef CONFIG_PPC32
#include "mmu_decl.h"		/* for __max_low_memory */
#endif

struct lmb lmb;

#undef DEBUG

void lmb_dump_all(void)
{
#ifdef DEBUG
	unsigned long i;

	udbg_printf("lmb_dump_all:\n");
	udbg_printf("    memory.cnt		  = 0x%lx\n",
		    lmb.memory.cnt);
	udbg_printf("    memory.size		  = 0x%lx\n",
		    lmb.memory.size);
	for (i=0; i < lmb.memory.cnt ;i++) {
		udbg_printf("    memory.region[0x%x].base       = 0x%lx\n",
			    i, lmb.memory.region[i].base);
		udbg_printf("		      .size     = 0x%lx\n",
			    lmb.memory.region[i].size);
	}

	udbg_printf("\n    reserved.cnt	  = 0x%lx\n",
		    lmb.reserved.cnt);
	udbg_printf("    reserved.size	  = 0x%lx\n",
		    lmb.reserved.size);
	for (i=0; i < lmb.reserved.cnt ;i++) {
		udbg_printf("    reserved.region[0x%x].base       = 0x%lx\n",
			    i, lmb.reserved.region[i].base);
		udbg_printf("		      .size     = 0x%lx\n",
			    lmb.reserved.region[i].size);
	}
#endif /* DEBUG */
}

static unsigned long __init lmb_addrs_overlap(unsigned long base1,
		unsigned long size1, unsigned long base2, unsigned long size2)
{
	return ((base1 < (base2+size2)) && (base2 < (base1+size1)));
}

static long __init lmb_addrs_adjacent(unsigned long base1, unsigned long size1,
		unsigned long base2, unsigned long size2)
{
	if (base2 == base1 + size1)
		return 1;
	else if (base1 == base2 + size2)
		return -1;

	return 0;
}

static long __init lmb_regions_adjacent(struct lmb_region *rgn,
		unsigned long r1, unsigned long r2)
{
	unsigned long base1 = rgn->region[r1].base;
	unsigned long size1 = rgn->region[r1].size;
	unsigned long base2 = rgn->region[r2].base;
	unsigned long size2 = rgn->region[r2].size;

	return lmb_addrs_adjacent(base1, size1, base2, size2);
}

/* Assumption: base addr of region 1 < base addr of region 2 */
static void __init lmb_coalesce_regions(struct lmb_region *rgn,
		unsigned long r1, unsigned long r2)
{
	unsigned long i;

	rgn->region[r1].size += rgn->region[r2].size;
	for (i=r2; i < rgn->cnt-1; i++) {
		rgn->region[i].base = rgn->region[i+1].base;
		rgn->region[i].size = rgn->region[i+1].size;
	}
	rgn->cnt--;
}

/* This routine called with relocation disabled. */
void __init lmb_init(void)
{
	/* Create a dummy zero size LMB which will get coalesced away later.
	 * This simplifies the lmb_add() code below...
	 */
	lmb.memory.region[0].base = 0;
	lmb.memory.region[0].size = 0;
	lmb.memory.cnt = 1;

	/* Ditto. */
	lmb.reserved.region[0].base = 0;
	lmb.reserved.region[0].size = 0;
	lmb.reserved.cnt = 1;
}

/* This routine may be called with relocation disabled. */
void __init lmb_analyze(void)
{
	int i;

	lmb.memory.size = 0;

	for (i = 0; i < lmb.memory.cnt; i++)
		lmb.memory.size += lmb.memory.region[i].size;
}

/* This routine called with relocation disabled. */
static long __init lmb_add_region(struct lmb_region *rgn, unsigned long base,
				  unsigned long size)
{
	unsigned long i, coalesced = 0;
	long adjacent;

	/* First try and coalesce this LMB with another. */
	for (i=0; i < rgn->cnt; i++) {
		unsigned long rgnbase = rgn->region[i].base;
		unsigned long rgnsize = rgn->region[i].size;

		adjacent = lmb_addrs_adjacent(base,size,rgnbase,rgnsize);
		if ( adjacent > 0 ) {
			rgn->region[i].base -= size;
			rgn->region[i].size += size;
			coalesced++;
			break;
		}
		else if ( adjacent < 0 ) {
			rgn->region[i].size += size;
			coalesced++;
			break;
		}
	}

	if ((i < rgn->cnt-1) && lmb_regions_adjacent(rgn, i, i+1) ) {
		lmb_coalesce_regions(rgn, i, i+1);
		coalesced++;
	}

	if (coalesced)
		return coalesced;
	if (rgn->cnt >= MAX_LMB_REGIONS)
		return -1;

	/* Couldn't coalesce the LMB, so add it to the sorted table. */
	for (i = rgn->cnt-1; i >= 0; i--) {
		if (base < rgn->region[i].base) {
			rgn->region[i+1].base = rgn->region[i].base;
			rgn->region[i+1].size = rgn->region[i].size;
		} else {
			rgn->region[i+1].base = base;
			rgn->region[i+1].size = size;
			break;
		}
	}
	rgn->cnt++;

	return 0;
}

/* This routine may be called with relocation disabled. */
long __init lmb_add(unsigned long base, unsigned long size)
{
	struct lmb_region *_rgn = &(lmb.memory);

	/* On pSeries LPAR systems, the first LMB is our RMO region. */
	if (base == 0)
		lmb.rmo_size = size;

	return lmb_add_region(_rgn, base, size);

}

long __init lmb_reserve(unsigned long base, unsigned long size)
{
	struct lmb_region *_rgn = &(lmb.reserved);

	return lmb_add_region(_rgn, base, size);
}

long __init lmb_overlaps_region(struct lmb_region *rgn, unsigned long base,
				unsigned long size)
{
	unsigned long i;

	for (i=0; i < rgn->cnt; i++) {
		unsigned long rgnbase = rgn->region[i].base;
		unsigned long rgnsize = rgn->region[i].size;
		if ( lmb_addrs_overlap(base,size,rgnbase,rgnsize) ) {
			break;
		}
	}

	return (i < rgn->cnt) ? i : -1;
}

unsigned long __init lmb_alloc(unsigned long size, unsigned long align)
{
	return lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE);
}

unsigned long __init lmb_alloc_base(unsigned long size, unsigned long align,
				    unsigned long max_addr)
{
	long i, j;
	unsigned long base = 0;

#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;
}

/* You must call lmb_analyze() before this. */
unsigned long __init lmb_phys_mem_size(void)
{
	return lmb.memory.size;
}

unsigned long __init lmb_end_of_DRAM(void)
{
	int idx = lmb.memory.cnt - 1;

	return (lmb.memory.region[idx].base + lmb.memory.region[idx].size);
}

/*
 * Truncate the lmb list to memory_limit if it's set
 * You must call lmb_analyze() after this.
 */
void __init lmb_enforce_memory_limit(unsigned long memory_limit)
{
	unsigned long i, limit;

	if (! memory_limit)
		return;

	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;
	}
}
