/*
 * pSeries NUMA support
 *
 * Copyright (C) 2002 Anton Blanchard <anton@au.ibm.com>, IBM
 *
 * 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/threads.h>
#include <linux/bootmem.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/mmzone.h>
#include <linux/module.h>
#include <linux/nodemask.h>
#include <linux/cpu.h>
#include <linux/notifier.h>
#include <asm/sparsemem.h>
#include <asm/lmb.h>
#include <asm/system.h>
#include <asm/smp.h>

static int numa_enabled = 1;

static int numa_debug;
#define dbg(args...) if (numa_debug) { printk(KERN_INFO args); }

int numa_cpu_lookup_table[NR_CPUS];
cpumask_t numa_cpumask_lookup_table[MAX_NUMNODES];
struct pglist_data *node_data[MAX_NUMNODES];

EXPORT_SYMBOL(numa_cpu_lookup_table);
EXPORT_SYMBOL(numa_cpumask_lookup_table);
EXPORT_SYMBOL(node_data);

static bootmem_data_t __initdata plat_node_bdata[MAX_NUMNODES];
static int min_common_depth;

/*
 * We need somewhere to store start/end/node for each region until we have
 * allocated the real node_data structures.
 */
#define MAX_REGIONS	(MAX_LMB_REGIONS*2)
static struct {
	unsigned long start_pfn;
	unsigned long end_pfn;
	int nid;
} init_node_data[MAX_REGIONS] __initdata;

int __init early_pfn_to_nid(unsigned long pfn)
{
	unsigned int i;

	for (i = 0; init_node_data[i].end_pfn; i++) {
		unsigned long start_pfn = init_node_data[i].start_pfn;
		unsigned long end_pfn = init_node_data[i].end_pfn;

		if ((start_pfn <= pfn) && (pfn < end_pfn))
			return init_node_data[i].nid;
	}

	return -1;
}

void __init add_region(unsigned int nid, unsigned long start_pfn,
		       unsigned long pages)
{
	unsigned int i;

	dbg("add_region nid %d start_pfn 0x%lx pages 0x%lx\n",
		nid, start_pfn, pages);

	for (i = 0; init_node_data[i].end_pfn; i++) {
		if (init_node_data[i].nid != nid)
			continue;
		if (init_node_data[i].end_pfn == start_pfn) {
			init_node_data[i].end_pfn += pages;
			return;
		}
		if (init_node_data[i].start_pfn == (start_pfn + pages)) {
			init_node_data[i].start_pfn -= pages;
			return;
		}
	}

	/*
	 * Leave last entry NULL so we dont iterate off the end (we use
	 * entry.end_pfn to terminate the walk).
	 */
	if (i >= (MAX_REGIONS - 1)) {
		printk(KERN_ERR "WARNING: too many memory regions in "
				"numa code, truncating\n");
		return;
	}

	init_node_data[i].start_pfn = start_pfn;
	init_node_data[i].end_pfn = start_pfn + pages;
	init_node_data[i].nid = nid;
}

/* We assume init_node_data has no overlapping regions */
void __init get_region(unsigned int nid, unsigned long *start_pfn,
		       unsigned long *end_pfn, unsigned long *pages_present)
{
	unsigned int i;

	*start_pfn = -1UL;
	*end_pfn = *pages_present = 0;

	for (i = 0; init_node_data[i].end_pfn; i++) {
		if (init_node_data[i].nid != nid)
			continue;

		*pages_present += init_node_data[i].end_pfn -
			init_node_data[i].start_pfn;

		if (init_node_data[i].start_pfn < *start_pfn)
			*start_pfn = init_node_data[i].start_pfn;

		if (init_node_data[i].end_pfn > *end_pfn)
			*end_pfn = init_node_data[i].end_pfn;
	}

	/* We didnt find a matching region, return start/end as 0 */
	if (*start_pfn == -1UL)
		*start_pfn = 0;
}

static inline void map_cpu_to_node(int cpu, int node)
{
	numa_cpu_lookup_table[cpu] = node;

	if (!(cpu_isset(cpu, numa_cpumask_lookup_table[node])))
		cpu_set(cpu, numa_cpumask_lookup_table[node]);
}

#ifdef CONFIG_HOTPLUG_CPU
static void unmap_cpu_from_node(unsigned long cpu)
{
	int node = numa_cpu_lookup_table[cpu];

	dbg("removing cpu %lu from node %d\n", cpu, node);

	if (cpu_isset(cpu, numa_cpumask_lookup_table[node])) {
		cpu_clear(cpu, numa_cpumask_lookup_table[node]);
	} else {
		printk(KERN_ERR "WARNING: cpu %lu not found in node %d\n",
		       cpu, node);
	}
}
#endif /* CONFIG_HOTPLUG_CPU */

static struct device_node *find_cpu_node(unsigned int cpu)
{
	unsigned int hw_cpuid = get_hard_smp_processor_id(cpu);
	struct device_node *cpu_node = NULL;
	unsigned int *interrupt_server, *reg;
	int len;

	while ((cpu_node = of_find_node_by_type(cpu_node, "cpu")) != NULL) {
		/* Try interrupt server first */
		interrupt_server = (unsigned int *)get_property(cpu_node,
					"ibm,ppc-interrupt-server#s", &len);

		len = len / sizeof(u32);

		if (interrupt_server && (len > 0)) {
			while (len--) {
				if (interrupt_server[len] == hw_cpuid)
					return cpu_node;
			}
		} else {
			reg = (unsigned int *)get_property(cpu_node,
							   "reg", &len);
			if (reg && (len > 0) && (reg[0] == hw_cpuid))
				return cpu_node;
		}
	}

	return NULL;
}

/* must hold reference to node during call */
static int *of_get_associativity(struct device_node *dev)
{
	return (unsigned int *)get_property(dev, "ibm,associativity", NULL);
}

static int of_node_numa_domain(struct device_node *device)
{
	int numa_domain;
	unsigned int *tmp;

	if (min_common_depth == -1)
		return 0;

	tmp = of_get_associativity(device);
	if (tmp && (tmp[0] >= min_common_depth)) {
		numa_domain = tmp[min_common_depth];
	} else {
		dbg("WARNING: no NUMA information for %s\n",
		    device->full_name);
		numa_domain = 0;
	}
	return numa_domain;
}

/*
 * In theory, the "ibm,associativity" property may contain multiple
 * associativity lists because a resource may be multiply connected
 * into the machine.  This resource then has different associativity
 * characteristics relative to its multiple connections.  We ignore
 * this for now.  We also assume that all cpu and memory sets have
 * their distances represented at a common level.  This won't be
 * true for heirarchical NUMA.
 *
 * In any case the ibm,associativity-reference-points should give
 * the correct depth for a normal NUMA system.
 *
 * - Dave Hansen <haveblue@us.ibm.com>
 */
static int __init find_min_common_depth(void)
{
	int depth;
	unsigned int *ref_points;
	struct device_node *rtas_root;
	unsigned int len;

	rtas_root = of_find_node_by_path("/rtas");

	if (!rtas_root)
		return -1;

	/*
	 * this property is 2 32-bit integers, each representing a level of
	 * depth in the associativity nodes.  The first is for an SMP
	 * configuration (should be all 0's) and the second is for a normal
	 * NUMA configuration.
	 */
	ref_points = (unsigned int *)get_property(rtas_root,
			"ibm,associativity-reference-points", &len);

	if ((len >= 1) && ref_points) {
		depth = ref_points[1];
	} else {
		dbg("WARNING: could not find NUMA "
		    "associativity reference point\n");
		depth = -1;
	}
	of_node_put(rtas_root);

	return depth;
}

static int __init get_mem_addr_cells(void)
{
	struct device_node *memory = NULL;
	int rc;

	memory = of_find_node_by_type(memory, "memory");
	if (!memory)
		return 0; /* it won't matter */

	rc = prom_n_addr_cells(memory);
	return rc;
}

static int __init get_mem_size_cells(void)
{
	struct device_node *memory = NULL;
	int rc;

	memory = of_find_node_by_type(memory, "memory");
	if (!memory)
		return 0; /* it won't matter */
	rc = prom_n_size_cells(memory);
	return rc;
}

static unsigned long __init read_n_cells(int n, unsigned int **buf)
{
	unsigned long result = 0;

	while (n--) {
		result = (result << 32) | **buf;
		(*buf)++;
	}
	return result;
}

/*
 * Figure out to which domain a cpu belongs and stick it there.
 * Return the id of the domain used.
 */
static int numa_setup_cpu(unsigned long lcpu)
{
	int numa_domain = 0;
	struct device_node *cpu = find_cpu_node(lcpu);

	if (!cpu) {
		WARN_ON(1);
		goto out;
	}

	numa_domain = of_node_numa_domain(cpu);

	if (numa_domain >= num_online_nodes()) {
		/*
		 * POWER4 LPAR uses 0xffff as invalid node,
		 * dont warn in this case.
		 */
		if (numa_domain != 0xffff)
			printk(KERN_ERR "WARNING: cpu %ld "
			       "maps to invalid NUMA node %d\n",
			       lcpu, numa_domain);
		numa_domain = 0;
	}
out:
	node_set_online(numa_domain);

	map_cpu_to_node(lcpu, numa_domain);

	of_node_put(cpu);

	return numa_domain;
}

static int cpu_numa_callback(struct notifier_block *nfb,
			     unsigned long action,
			     void *hcpu)
{
	unsigned long lcpu = (unsigned long)hcpu;
	int ret = NOTIFY_DONE;

	switch (action) {
	case CPU_UP_PREPARE:
		if (min_common_depth == -1 || !numa_enabled)
			map_cpu_to_node(lcpu, 0);
		else
			numa_setup_cpu(lcpu);
		ret = NOTIFY_OK;
		break;
#ifdef CONFIG_HOTPLUG_CPU
	case CPU_DEAD:
	case CPU_UP_CANCELED:
		unmap_cpu_from_node(lcpu);
		break;
		ret = NOTIFY_OK;
#endif
	}
	return ret;
}

/*
 * Check and possibly modify a memory region to enforce the memory limit.
 *
 * Returns the size the region should have to enforce the memory limit.
 * This will either be the original value of size, a truncated value,
 * or zero. If the returned value of size is 0 the region should be
 * discarded as it lies wholy above the memory limit.
 */
static unsigned long __init numa_enforce_memory_limit(unsigned long start,
						      unsigned long size)
{
	/*
	 * We use lmb_end_of_DRAM() in here instead of memory_limit because
	 * we've already adjusted it for the limit and it takes care of
	 * having memory holes below the limit.
	 */

	if (! memory_limit)
		return size;

	if (start + size <= lmb_end_of_DRAM())
		return size;

	if (start >= lmb_end_of_DRAM())
		return 0;

	return lmb_end_of_DRAM() - start;
}

static int __init parse_numa_properties(void)
{
	struct device_node *cpu = NULL;
	struct device_node *memory = NULL;
	int addr_cells, size_cells;
	int max_domain;
	unsigned long i;

	if (numa_enabled == 0) {
		printk(KERN_WARNING "NUMA disabled by user\n");
		return -1;
	}

	min_common_depth = find_min_common_depth();

	dbg("NUMA associativity depth for CPU/Memory: %d\n", min_common_depth);
	if (min_common_depth < 0)
		return min_common_depth;

	max_domain = numa_setup_cpu(boot_cpuid);

	/*
	 * Even though we connect cpus to numa domains later in SMP init,
	 * we need to know the maximum node id now. This is because each
	 * node id must have NODE_DATA etc backing it.
	 * As a result of hotplug we could still have cpus appear later on
	 * with larger node ids. In that case we force the cpu into node 0.
	 */
	for_each_cpu(i) {
		int numa_domain;

		cpu = find_cpu_node(i);

		if (cpu) {
			numa_domain = of_node_numa_domain(cpu);
			of_node_put(cpu);

			if (numa_domain < MAX_NUMNODES &&
			    max_domain < numa_domain)
				max_domain = numa_domain;
		}
	}

	addr_cells = get_mem_addr_cells();
	size_cells = get_mem_size_cells();
	memory = NULL;
	while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
		unsigned long start;
		unsigned long size;
		int numa_domain;
		int ranges;
		unsigned int *memcell_buf;
		unsigned int len;

		memcell_buf = (unsigned int *)get_property(memory, "reg", &len);
		if (!memcell_buf || len <= 0)
			continue;

		ranges = memory->n_addrs;
new_range:
		/* these are order-sensitive, and modify the buffer pointer */
		start = read_n_cells(addr_cells, &memcell_buf);
		size = read_n_cells(size_cells, &memcell_buf);

		numa_domain = of_node_numa_domain(memory);

		if (numa_domain >= MAX_NUMNODES) {
			if (numa_domain != 0xffff)
				printk(KERN_ERR "WARNING: memory at %lx maps "
				       "to invalid NUMA node %d\n", start,
				       numa_domain);
			numa_domain = 0;
		}

		if (max_domain < numa_domain)
			max_domain = numa_domain;

		if (!(size = numa_enforce_memory_limit(start, size))) {
			if (--ranges)
				goto new_range;
			else
				continue;
		}

		add_region(numa_domain, start >> PAGE_SHIFT,
			   size >> PAGE_SHIFT);

		if (--ranges)
			goto new_range;
	}

	for (i = 0; i <= max_domain; i++)
		node_set_online(i);

	return 0;
}

static void __init setup_nonnuma(void)
{
	unsigned long top_of_ram = lmb_end_of_DRAM();
	unsigned long total_ram = lmb_phys_mem_size();
	unsigned int i;

	printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
	       top_of_ram, total_ram);
	printk(KERN_INFO "Memory hole size: %ldMB\n",
	       (top_of_ram - total_ram) >> 20);

	map_cpu_to_node(boot_cpuid, 0);
	for (i = 0; i < lmb.memory.cnt; ++i)
		add_region(0, lmb.memory.region[i].base >> PAGE_SHIFT,
			   lmb_size_pages(&lmb.memory, i));
	node_set_online(0);
}

static void __init dump_numa_topology(void)
{
	unsigned int node;
	unsigned int count;

	if (min_common_depth == -1 || !numa_enabled)
		return;

	for_each_online_node(node) {
		unsigned long i;

		printk(KERN_INFO "Node %d Memory:", node);

		count = 0;

		for (i = 0; i < lmb_end_of_DRAM();
		     i += (1 << SECTION_SIZE_BITS)) {
			if (early_pfn_to_nid(i >> PAGE_SHIFT) == node) {
				if (count == 0)
					printk(" 0x%lx", i);
				++count;
			} else {
				if (count > 0)
					printk("-0x%lx", i);
				count = 0;
			}
		}

		if (count > 0)
			printk("-0x%lx", i);
		printk("\n");
	}
	return;
}

/*
 * Allocate some memory, satisfying the lmb or bootmem allocator where
 * required. nid is the preferred node and end is the physical address of
 * the highest address in the node.
 *
 * Returns the physical address of the memory.
 */
static void __init *careful_allocation(int nid, unsigned long size,
				       unsigned long align,
				       unsigned long end_pfn)
{
	int new_nid;
	unsigned long ret = lmb_alloc_base(size, align, end_pfn << PAGE_SHIFT);

	/* retry over all memory */
	if (!ret)
		ret = lmb_alloc_base(size, align, lmb_end_of_DRAM());

	if (!ret)
		panic("numa.c: cannot allocate %lu bytes on node %d",
		      size, nid);

	/*
	 * If the memory came from a previously allocated node, we must
	 * retry with the bootmem allocator.
	 */
	new_nid = early_pfn_to_nid(ret >> PAGE_SHIFT);
	if (new_nid < nid) {
		ret = (unsigned long)__alloc_bootmem_node(NODE_DATA(new_nid),
				size, align, 0);

		if (!ret)
			panic("numa.c: cannot allocate %lu bytes on node %d",
			      size, new_nid);

		ret = __pa(ret);

		dbg("alloc_bootmem %lx %lx\n", ret, size);
	}

	return (void *)ret;
}

void __init do_init_bootmem(void)
{
	int nid;
	unsigned int i;
	static struct notifier_block ppc64_numa_nb = {
		.notifier_call = cpu_numa_callback,
		.priority = 1 /* Must run before sched domains notifier. */
	};

	min_low_pfn = 0;
	max_low_pfn = lmb_end_of_DRAM() >> PAGE_SHIFT;
	max_pfn = max_low_pfn;

	if (parse_numa_properties())
		setup_nonnuma();
	else
		dump_numa_topology();

	register_cpu_notifier(&ppc64_numa_nb);

	for_each_online_node(nid) {
		unsigned long start_pfn, end_pfn, pages_present;
		unsigned long bootmem_paddr;
		unsigned long bootmap_pages;

		get_region(nid, &start_pfn, &end_pfn, &pages_present);

		/* Allocate the node structure node local if possible */
		NODE_DATA(nid) = careful_allocation(nid,
					sizeof(struct pglist_data),
					SMP_CACHE_BYTES, end_pfn);
		NODE_DATA(nid) = __va(NODE_DATA(nid));
		memset(NODE_DATA(nid), 0, sizeof(struct pglist_data));

  		dbg("node %d\n", nid);
		dbg("NODE_DATA() = %p\n", NODE_DATA(nid));

		NODE_DATA(nid)->bdata = &plat_node_bdata[nid];
		NODE_DATA(nid)->node_start_pfn = start_pfn;
		NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn;

		if (NODE_DATA(nid)->node_spanned_pages == 0)
  			continue;

  		dbg("start_paddr = %lx\n", start_pfn << PAGE_SHIFT);
  		dbg("end_paddr = %lx\n", end_pfn << PAGE_SHIFT);

		bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
		bootmem_paddr = (unsigned long)careful_allocation(nid,
					bootmap_pages << PAGE_SHIFT,
					PAGE_SIZE, end_pfn);
		memset(__va(bootmem_paddr), 0, bootmap_pages << PAGE_SHIFT);

		dbg("bootmap_paddr = %lx\n", bootmem_paddr);

		init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT,
				  start_pfn, end_pfn);

		/* Add free regions on this node */
		for (i = 0; init_node_data[i].end_pfn; i++) {
			unsigned long start, end;

			if (init_node_data[i].nid != nid)
				continue;

			start = init_node_data[i].start_pfn << PAGE_SHIFT;
			end = init_node_data[i].end_pfn << PAGE_SHIFT;

			dbg("free_bootmem %lx %lx\n", start, end - start);
  			free_bootmem_node(NODE_DATA(nid), start, end - start);
		}

		/* Mark reserved regions on this node */
		for (i = 0; i < lmb.reserved.cnt; i++) {
			unsigned long physbase = lmb.reserved.region[i].base;
			unsigned long size = lmb.reserved.region[i].size;
			unsigned long start_paddr = start_pfn << PAGE_SHIFT;
			unsigned long end_paddr = end_pfn << PAGE_SHIFT;

			if (early_pfn_to_nid(physbase >> PAGE_SHIFT) != nid &&
			    early_pfn_to_nid((physbase+size-1) >> PAGE_SHIFT) != nid)
				continue;

			if (physbase < end_paddr &&
			    (physbase+size) > start_paddr) {
				/* overlaps */
				if (physbase < start_paddr) {
					size -= start_paddr - physbase;
					physbase = start_paddr;
				}

				if (size > end_paddr - physbase)
					size = end_paddr - physbase;

				dbg("reserve_bootmem %lx %lx\n", physbase,
				    size);
				reserve_bootmem_node(NODE_DATA(nid), physbase,
						     size);
			}
		}

		/* Add regions into sparsemem */
		for (i = 0; init_node_data[i].end_pfn; i++) {
			unsigned long start, end;

			if (init_node_data[i].nid != nid)
				continue;

			start = init_node_data[i].start_pfn;
			end = init_node_data[i].end_pfn;

			memory_present(nid, start, end);
		}
	}
}

void __init paging_init(void)
{
	unsigned long zones_size[MAX_NR_ZONES];
	unsigned long zholes_size[MAX_NR_ZONES];
	int nid;

	memset(zones_size, 0, sizeof(zones_size));
	memset(zholes_size, 0, sizeof(zholes_size));

	for_each_online_node(nid) {
		unsigned long start_pfn, end_pfn, pages_present;

		get_region(nid, &start_pfn, &end_pfn, &pages_present);

		zones_size[ZONE_DMA] = end_pfn - start_pfn;
		zholes_size[ZONE_DMA] = zones_size[ZONE_DMA] - pages_present;

		dbg("free_area_init node %d %lx %lx (hole: %lx)\n", nid,
		    zones_size[ZONE_DMA], start_pfn, zholes_size[ZONE_DMA]);

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

static int __init early_numa(char *p)
{
	if (!p)
		return 0;

	if (strstr(p, "off"))
		numa_enabled = 0;

	if (strstr(p, "debug"))
		numa_debug = 1;

	return 0;
}
early_param("numa", early_numa);
