/*
 *  linux/arch/m32r/mm/discontig.c
 *
 *  Discontig memory support
 *
 *  Copyright (c) 2003  Hitoshi Yamamoto
 */

#include <linux/config.h>
#include <linux/mm.h>
#include <linux/bootmem.h>
#include <linux/mmzone.h>
#include <linux/initrd.h>
#include <linux/nodemask.h>
#include <linux/module.h>

#include <asm/setup.h>

extern char _end[];

struct pglist_data *node_data[MAX_NUMNODES];
EXPORT_SYMBOL(node_data);
static bootmem_data_t node_bdata[MAX_NUMNODES] __initdata;

pg_data_t m32r_node_data[MAX_NUMNODES];

/* Memory profile */
typedef struct {
	unsigned long start_pfn;
	unsigned long pages;
	unsigned long holes;
	unsigned long free_pfn;
} mem_prof_t;
static mem_prof_t mem_prof[MAX_NUMNODES];

static void __init mem_prof_init(void)
{
	unsigned long start_pfn, holes, free_pfn;
	const unsigned long zone_alignment = 1UL << (MAX_ORDER - 1);
	unsigned long ul;
	mem_prof_t *mp;

	/* Node#0 SDRAM */
	mp = &mem_prof[0];
	mp->start_pfn = PFN_UP(CONFIG_MEMORY_START);
	mp->pages = PFN_DOWN(CONFIG_MEMORY_SIZE);
	mp->holes = 0;
	mp->free_pfn = PFN_UP(__pa(_end));

	/* Node#1 internal SRAM */
	mp = &mem_prof[1];
	start_pfn = free_pfn = PFN_UP(CONFIG_IRAM_START);
	holes = 0;
	if (start_pfn & (zone_alignment - 1)) {
		ul = zone_alignment;
		while (start_pfn >= ul)
			ul += zone_alignment;

		start_pfn = ul - zone_alignment;
		holes = free_pfn - start_pfn;
	}

	mp->start_pfn = start_pfn;
	mp->pages = PFN_DOWN(CONFIG_IRAM_SIZE) + holes;
	mp->holes = holes;
	mp->free_pfn = PFN_UP(CONFIG_IRAM_START);
}

unsigned long __init setup_memory(void)
{
	unsigned long bootmap_size;
	unsigned long min_pfn;
	int nid;
	mem_prof_t *mp;

	max_low_pfn = 0;
	min_low_pfn = -1;

	mem_prof_init();

	for_each_online_node(nid) {
		mp = &mem_prof[nid];
		NODE_DATA(nid)=(pg_data_t *)&m32r_node_data[nid];
		NODE_DATA(nid)->bdata = &node_bdata[nid];
		min_pfn = mp->start_pfn;
		max_pfn = mp->start_pfn + mp->pages;
		bootmap_size = init_bootmem_node(NODE_DATA(nid), mp->free_pfn,
			mp->start_pfn, max_pfn);

		free_bootmem_node(NODE_DATA(nid), PFN_PHYS(mp->start_pfn),
			PFN_PHYS(mp->pages));

		reserve_bootmem_node(NODE_DATA(nid), PFN_PHYS(mp->start_pfn),
			PFN_PHYS(mp->free_pfn - mp->start_pfn) + bootmap_size);

		if (max_low_pfn < max_pfn)
			max_low_pfn = max_pfn;

		if (min_low_pfn > min_pfn)
			min_low_pfn = min_pfn;
	}

#ifdef CONFIG_BLK_DEV_INITRD
	if (LOADER_TYPE && INITRD_START) {
		if (INITRD_START + INITRD_SIZE <= PFN_PHYS(max_low_pfn)) {
			reserve_bootmem_node(NODE_DATA(0), INITRD_START,
				INITRD_SIZE);
			initrd_start = INITRD_START ?
				INITRD_START + PAGE_OFFSET : 0;

			initrd_end = initrd_start + INITRD_SIZE;
			printk("initrd:start[%08lx],size[%08lx]\n",
				initrd_start, INITRD_SIZE);
		} else {
			printk("initrd extends beyond end of memory "
				"(0x%08lx > 0x%08lx)\ndisabling initrd\n",
				INITRD_START + INITRD_SIZE,
				PFN_PHYS(max_low_pfn));

			initrd_start = 0;
		}
	}
#endif	/* CONFIG_BLK_DEV_INITRD */

	return max_low_pfn;
}

#define START_PFN(nid)	\
	(NODE_DATA(nid)->bdata->node_boot_start >> PAGE_SHIFT)
#define MAX_LOW_PFN(nid)	(NODE_DATA(nid)->bdata->node_low_pfn)

unsigned long __init zone_sizes_init(void)
{
	unsigned long zones_size[MAX_NR_ZONES], zholes_size[MAX_NR_ZONES];
	unsigned long low, start_pfn;
	unsigned long holes = 0;
	int nid, i;
	mem_prof_t *mp;

	pgdat_list = NULL;
	for (nid = num_online_nodes() - 1 ; nid >= 0 ; nid--) {
		NODE_DATA(nid)->pgdat_next = pgdat_list;
		pgdat_list = NODE_DATA(nid);
	}

	for_each_online_node(nid) {
		mp = &mem_prof[nid];
		for (i = 0 ; i < MAX_NR_ZONES ; i++) {
			zones_size[i] = 0;
			zholes_size[i] = 0;
		}
		start_pfn = START_PFN(nid);
		low = MAX_LOW_PFN(nid);
		zones_size[ZONE_DMA] = low - start_pfn;
		zholes_size[ZONE_DMA] = mp->holes;
		holes += zholes_size[ZONE_DMA];

		free_area_init_node(nid, NODE_DATA(nid), zones_size,
			start_pfn, zholes_size);
	}

	/*
	 * For test
	 *  Use all area of internal RAM.
	 *  see __alloc_pages()
	 */
	NODE_DATA(1)->node_zones->pages_min = 0;
	NODE_DATA(1)->node_zones->pages_low = 0;
	NODE_DATA(1)->node_zones->pages_high = 0;

	return holes;
}

