/*
 * NUMA support for s390
 *
 * Implement NUMA core code.
 *
 * Copyright IBM Corp. 2015
 */

#define KMSG_COMPONENT "numa"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt

#include <linux/kernel.h>
#include <linux/mmzone.h>
#include <linux/cpumask.h>
#include <linux/bootmem.h>
#include <linux/memblock.h>
#include <linux/slab.h>
#include <linux/node.h>

#include <asm/numa.h>
#include "numa_mode.h"

pg_data_t *node_data[MAX_NUMNODES];
EXPORT_SYMBOL(node_data);

cpumask_t node_to_cpumask_map[MAX_NUMNODES];
EXPORT_SYMBOL(node_to_cpumask_map);

const struct numa_mode numa_mode_plain = {
	.name = "plain",
};

static const struct numa_mode *mode = &numa_mode_plain;

int numa_pfn_to_nid(unsigned long pfn)
{
	return mode->__pfn_to_nid ? mode->__pfn_to_nid(pfn) : 0;
}

void numa_update_cpu_topology(void)
{
	if (mode->update_cpu_topology)
		mode->update_cpu_topology();
}

int __node_distance(int a, int b)
{
	return mode->distance ? mode->distance(a, b) : 0;
}

int numa_debug_enabled;

/*
 * alloc_node_data() - Allocate node data
 */
static __init pg_data_t *alloc_node_data(void)
{
	pg_data_t *res;

	res = (pg_data_t *) memblock_alloc(sizeof(pg_data_t), 8);
	memset(res, 0, sizeof(pg_data_t));
	return res;
}

/*
 * numa_setup_memory() - Assign bootmem to nodes
 *
 * The memory is first added to memblock without any respect to nodes.
 * This is fixed before remaining memblock memory is handed over to the
 * buddy allocator.
 * An important side effect is that large bootmem allocations might easily
 * cross node boundaries, which can be needed for large allocations with
 * smaller memory stripes in each node (i.e. when using NUMA emulation).
 *
 * Memory defines nodes:
 * Therefore this routine also sets the nodes online with memory.
 */
static void __init numa_setup_memory(void)
{
	unsigned long cur_base, align, end_of_dram;
	int nid = 0;

	end_of_dram = memblock_end_of_DRAM();
	align = mode->align ? mode->align() : ULONG_MAX;

	/*
	 * Step through all available memory and assign it to the nodes
	 * indicated by the mode implementation.
	 * All nodes which are seen here will be set online.
	 */
	cur_base = 0;
	do {
		nid = numa_pfn_to_nid(PFN_DOWN(cur_base));
		node_set_online(nid);
		memblock_set_node(cur_base, align, &memblock.memory, nid);
		cur_base += align;
	} while (cur_base < end_of_dram);

	/* Allocate and fill out node_data */
	for (nid = 0; nid < MAX_NUMNODES; nid++)
		NODE_DATA(nid) = alloc_node_data();

	for_each_online_node(nid) {
		unsigned long start_pfn, end_pfn;
		unsigned long t_start, t_end;
		int i;

		start_pfn = ULONG_MAX;
		end_pfn = 0;
		for_each_mem_pfn_range(i, nid, &t_start, &t_end, NULL) {
			if (t_start < start_pfn)
				start_pfn = t_start;
			if (t_end > end_pfn)
				end_pfn = t_end;
		}
		NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn;
		NODE_DATA(nid)->node_id = nid;
	}
}

/*
 * numa_setup() - Earliest initialization
 *
 * Assign the mode and call the mode's setup routine.
 */
void __init numa_setup(void)
{
	pr_info("NUMA mode: %s\n", mode->name);
	if (mode->setup)
		mode->setup();
	numa_setup_memory();
	memblock_dump_all();
}


/*
 * numa_init_early() - Initialization initcall
 *
 * This runs when only one CPU is online and before the first
 * topology update is called for by the scheduler.
 */
static int __init numa_init_early(void)
{
	/* Attach all possible CPUs to node 0 for now. */
	cpumask_copy(&node_to_cpumask_map[0], cpu_possible_mask);
	return 0;
}
early_initcall(numa_init_early);

/*
 * numa_init_late() - Initialization initcall
 *
 * Register NUMA nodes.
 */
static int __init numa_init_late(void)
{
	int nid;

	for_each_online_node(nid)
		register_one_node(nid);
	return 0;
}
arch_initcall(numa_init_late);

static int __init parse_debug(char *parm)
{
	numa_debug_enabled = 1;
	return 0;
}
early_param("numa_debug", parse_debug);

static int __init parse_numa(char *parm)
{
	if (strcmp(parm, numa_mode_plain.name) == 0)
		mode = &numa_mode_plain;
#ifdef CONFIG_NUMA_EMU
	if (strcmp(parm, numa_mode_emu.name) == 0)
		mode = &numa_mode_emu;
#endif
	return 0;
}
early_param("numa", parse_numa);
