/* Copyright (c) 2015 The Regents of the University of California
 * Kevin Klues <klueska@cs.berkeley.edu>
 * See LICENSE for details. */

#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <kmalloc.h>
#include <string.h>
#include <ns.h>
#include <acpi.h>
#include <arch/arch.h>
#include <arch/apic.h>
#include <arch/topology.h>

struct topology_info cpu_topology_info;
int *os_coreid_lookup;

#define num_cpus            (cpu_topology_info.num_cpus)
#define num_sockets         (cpu_topology_info.num_sockets)
#define num_numa            (cpu_topology_info.num_numa)
#define cores_per_numa      (cpu_topology_info.cores_per_numa)
#define cores_per_socket    (cpu_topology_info.cores_per_socket)
#define cores_per_cpu       (cpu_topology_info.cores_per_cpu)
#define cpus_per_socket     (cpu_topology_info.cpus_per_socket)
#define cpus_per_numa       (cpu_topology_info.cpus_per_numa)
#define sockets_per_numa    (cpu_topology_info.sockets_per_numa)
#define max_apic_id         (cpu_topology_info.max_apic_id)
#define core_list           (cpu_topology_info.core_list)

/* Adjust the ids from any given node type to start at 0 and increase from
 * there. We use the id_offset in the core_list to index the proper field. */
static void adjust_ids(int id_offset)
{
	int new_id = 0, old_id = -1;

	for (int i = 0; i < num_cores; i++) {
		for (int j = 0; j < num_cores; j++) {
			int *id_field = ((void*)&core_list[j] + id_offset);
			if (*id_field >= new_id) {
				if (old_id == -1)
					old_id = *id_field;
				if (old_id == *id_field)
					*id_field = new_id;
			}
		}
		old_id=-1;
		new_id++;
	}
}

/* Set the actual socket id from the raw socket id extracted from cpuid.  This
 * algorithm is adapted from the algorithm given at
 * http://wiki.osdev.org/Detecting_CPU_Topology_(80x86) */
static void set_socket_ids(void)
{
	int socket_id, raw_socket_id;

	for (int numa_id = 0; numa_id < num_numa; numa_id++) {
		socket_id = 0;
		for (int i = 0; i < num_cores; i++) {
			if (core_list[i].numa_id == numa_id) {
				if (core_list[i].socket_id == -1) {
					core_list[i].socket_id = socket_id;
					raw_socket_id =
						core_list[i].raw_socket_id;
					for (int j = i; j < num_cores; j++) {
						if (core_list[j].numa_id ==
						    numa_id) {
							if (core_list[j].raw_socket_id == raw_socket_id) {
								core_list[j].socket_id = socket_id;
							}
						}
					}
				}
				socket_id++;
			}
		}
	}
}

/* Loop through our Srat table to find a matching numa domain for the given
 * apid_id. */
static int find_numa_domain(int apic_id)
{
	if (srat == NULL)
		return -1;

	for (int i = 0; i < srat->nchildren; i++) {
		struct Srat *temp = srat->children[i]->tbl;

		if (temp != NULL && temp->type == SRlapic) {
			if (temp->lapic.apic == apic_id)
				return temp->lapic.dom;
		}
	}
	return -1;
}

/* Figure out the maximum number of cores we actually have and set it in our
 * cpu_topology_info struct. */
static void set_num_cores(void)
{
	int old_num_cores = num_cores;

	if (apics == NULL)
		return;

	num_cores = 0;
	for (int i = 0; i < apics->nchildren; i++) {
		struct Apicst *temp = apics->children[i]->tbl;

		if (temp != NULL && temp->type == ASlapic)
			num_cores++;
	}
	if (num_cores < old_num_cores)
		warn("Topology found less cores than early MADT parsing!");
	/* Too many cores will be a problem for some data structures. */
	if (num_cores > old_num_cores)
		panic("Topology found more cores than early MADT parsing!");
}

/* Determine if srat has a unique numa domain compared to to all of the srat
 * records in list_head that are of type SRlapic.
 *
 * Note that this only finds a unique NUMA domain when we're on the last core in
 * the list with that domain.  When we find that one, we'll need to scan the
 * O(n) other cores from the other domains that are ahead of us in the list.
 * It's a little inefficient, but OK for now. */
static bool is_unique_numa(struct Srat *srat, struct Atable **tail,
                           size_t begin, size_t end)
{
	for (int i = begin; i < end; i++) {
		struct Srat *st = tail[i]->tbl;

		if (st && st->type == SRlapic)
			if (srat->lapic.dom == st->lapic.dom)
				return FALSE;
	}
	return TRUE;
}

/* Figure out the maximum number of numa domains we actually have.
 * This code should always return >= 0 domains. */
static int get_num_numa(void)
{
	int numa = 0;

	if (srat == NULL)
		return 0;

	for (int i = 0; i < srat->nchildren; i++) {
		struct Srat *temp = srat->children[i]->tbl;

		if (temp != NULL && temp->type == SRlapic)
			if (is_unique_numa(temp, srat->children, i + 1,
					   srat->nchildren))
				numa++;
	}

	return numa;
}

/* Set num_numa in our topology struct */
static void set_num_numa(void)
{
	num_numa = get_num_numa();
}

/* Figure out what the max apic_id we will ever have is and set it in our
 * cpu_topology_info struct. */
static void set_max_apic_id(void)
{
	for (int i = 0; i < apics->nchildren; i++) {
		struct Apicst *temp = apics->children[i]->tbl;

		if (temp->type == ASlapic) {
			if (temp->lapic.id > max_apic_id)
				max_apic_id = temp->lapic.id;
		}
	}
}

static void init_os_coreid_lookup(void)
{
	/* Allocate (max_apic_id+1) entries in our os_coreid_lookup table.
	 * There may be holes in this table because of the way apic_ids work,
	 * but a little wasted space is OK for a constant time lookup of apic_id
	 * -> logical core id (from the OS's perspective). Memset the array to
	 *  -1 to to represent invalid entries (which it's very possible we
	 *  might have if the apic_id space has holes in it).  */
	os_coreid_lookup = kmalloc((max_apic_id + 1) * sizeof(int), 0);
	memset(os_coreid_lookup, -1, (max_apic_id + 1) * sizeof(int));

	/* Loop through and set all valid entries to 0 to start with (making
	 * them temporarily valid, but not yet set to the correct value). This
	 * step is necessary because there is no ordering to the linked list we
	 * are
	 * pulling these ids from. After this, loop back through and set the
	 * mapping appropriately. */
	for (int i = 0; i < apics->nchildren; i++) {
		struct Apicst *temp = apics->children[i]->tbl;

		if (temp->type == ASlapic)
			os_coreid_lookup[temp->lapic.id] = 0;
	}
	int os_coreid = 0;

	for (int i = 0; i <= max_apic_id; i++)
		if (os_coreid_lookup[i] == 0)
			os_coreid_lookup[i] = os_coreid++;
}

static void init_core_list(uint32_t core_bits, uint32_t cpu_bits)
{
	/* Assuming num_cores and max_apic_id have been set, we can allocate our
	 * core_list to the proper size. Initialize all entries to 0s to being
	 * with. */
	core_list = kzmalloc(num_cores * sizeof(struct core_info), 0);

	/* Loop through all possible apic_ids and fill in the core_list array
	 * with *relative* topology info. We will change this relative info to
	 * absolute info in a future step. As part of this step, we update our
	 * os_coreid_lookup array to contain the proper value. */
	int os_coreid = 0;
	int max_cpus = (1 << cpu_bits);
	int max_cores_per_cpu = (1 << core_bits);
	int max_logical_cores = (1 << (core_bits + cpu_bits));
	int raw_socket_id = 0, cpu_id = 0, core_id = 0;

	for (int apic_id = 0; apic_id <= max_apic_id; apic_id++) {
		if (os_coreid_lookup[apic_id] != -1) {
			raw_socket_id = apic_id & ~(max_logical_cores - 1);
			cpu_id = (apic_id >> core_bits) & (max_cpus - 1);
			core_id = apic_id & (max_cores_per_cpu - 1);

			core_list[os_coreid].numa_id =
				find_numa_domain(apic_id);
			core_list[os_coreid].raw_socket_id = raw_socket_id;
			core_list[os_coreid].socket_id = -1;
			core_list[os_coreid].cpu_id = cpu_id;
			core_list[os_coreid].core_id = core_id;
			core_list[os_coreid].apic_id = apic_id;
			os_coreid++;
		}
	}

	/* In general, the various id's set in the previous step are all unique
	 * in terms of representing the topology (i.e. all cores under the same
	 * socket have the same socket_id set), but these id's are not
	 * necessarily contiguous, and are only relative to the level of the
	 * hierarchy they exist at (e.g.  cpu_id 4 may exist under *both*
	 * socket_id 0 and socket_id 1). In this step, we squash these id's down
	 * so they are contiguous. In a following step, we will make them all
	 * absolute instead of relative. */
	adjust_ids(offsetof(struct core_info, numa_id));
	adjust_ids(offsetof(struct core_info, raw_socket_id));
	adjust_ids(offsetof(struct core_info, cpu_id));
	adjust_ids(offsetof(struct core_info, core_id));

	/* We haven't yet set the socket id of each core yet. So far, all we've
	 * extracted is a "raw" socket id from the top bits in our apic id, but
	 * we need to condense these down into something workable for a socket
	 * id, per numa domain. OSDev has an algorithm for doing so
	 * (http://wiki.osdev.org/Detecting_CPU_Topology_%2880x86%29).
	 * We adapt it for our setup. */
	set_socket_ids();
}

static void init_core_list_flat(void)
{
	/* Assuming num_cores and max_apic_id have been set, we can allocate our
	 * core_list to the proper size. Initialize all entries to 0s to being
	 * with. */
	core_list = kzmalloc(num_cores * sizeof(struct core_info), 0);

	/* Loop through all possible apic_ids and fill in the core_list array
	 * with flat topology info. */
	int os_coreid = 0;

	for (int apic_id = 0; apic_id <= max_apic_id; apic_id++) {
		if (os_coreid_lookup[apic_id] != -1) {
			core_list[os_coreid].numa_id = 0;
			core_list[os_coreid].raw_socket_id = 0;
			core_list[os_coreid].socket_id = 0;
			core_list[os_coreid].cpu_id = 0;
			core_list[os_coreid].core_id = os_coreid;
			core_list[os_coreid].apic_id = apic_id;
			os_coreid++;
		}
	}
}

static void set_remaining_topology_info(void)
{
	/* Assuming we have our core_list set up with relative topology info,
	 * loop through our core_list and calculate the other statistics that we
	 * hold in our cpu_topology_info struct. */
	int last_numa = -1, last_socket = -1, last_cpu = -1, last_core = -1;
	for (int i = 0; i < num_cores; i++) {
		if (core_list[i].socket_id > last_socket) {
			last_socket = core_list[i].socket_id;
			sockets_per_numa++;
		}
		if (core_list[i].cpu_id > last_cpu) {
			last_cpu = core_list[i].cpu_id;
			cpus_per_socket++;
		}
		if (core_list[i].core_id > last_core) {
			last_core = core_list[i].core_id;
			cores_per_cpu++;
		}
	}
	cores_per_socket = cpus_per_socket * cores_per_cpu;
	cores_per_numa = sockets_per_numa * cores_per_socket;
	cpus_per_numa = sockets_per_numa * cpus_per_socket;
	num_sockets = sockets_per_numa * num_numa;
	num_cpus = cpus_per_socket * num_sockets;
}

static void update_core_list_with_absolute_ids(void)
{
	/* Fix up our core_list to have absolute id's at every level. */
	for (int i = 0; i < num_cores; i++) {
		struct core_info *c = &core_list[i];
		c->socket_id = num_sockets/num_numa * c->numa_id + c->socket_id;
		c->cpu_id = num_cpus/num_sockets * c->socket_id + c->cpu_id;
		c->core_id = num_cores/num_cpus * c->cpu_id + c->core_id;
	}
}

static void build_topology(uint32_t core_bits, uint32_t cpu_bits)
{
	set_num_cores();
	set_num_numa();
	set_max_apic_id();
	init_os_coreid_lookup();
	init_core_list(core_bits, cpu_bits);
	set_remaining_topology_info();
	update_core_list_with_absolute_ids();
}

static void build_flat_topology(void)
{
	set_num_cores();
	num_numa = 1;
	set_max_apic_id();
	init_os_coreid_lookup();
	init_core_list_flat();
	set_remaining_topology_info();
}

void topology_init(void)
{
	uint32_t eax, ebx, ecx, edx;
	int smt_leaf, core_leaf;
	uint32_t core_bits = 0, cpu_bits = 0;

	eax = 0x0000000b;
	ecx = 1;
	cpuid(eax, ecx, &eax, &ebx, &ecx, &edx);
	core_leaf = (ecx >> 8) & 0x00000002;
	if (core_leaf == 2) {
		cpu_bits = eax;
		eax = 0x0000000b;
		ecx = 0;
		cpuid(eax, ecx, &eax, &ebx, &ecx, &edx);
		smt_leaf = (ecx >> 8) & 0x00000001;
		if (smt_leaf == 1) {
			core_bits = eax;
			cpu_bits = cpu_bits - core_bits;
		}
	}
	/* BIOSes are not strictly required to put NUMA information
	 * into the ACPI table. If there is no information the safest
	 * thing to do is assume it's a non-NUMA system, i.e. flat. */
	if (cpu_bits && get_num_numa())
		build_topology(core_bits, cpu_bits);
	else
		build_flat_topology();
}

void print_cpu_topology(void)
{
	printk("num_numa: %d, num_sockets: %d, num_cpus: %d, num_cores: %d\n",
	       num_numa, num_sockets, num_cpus, num_cores);
	for (int i = 0; i < num_cores; i++) {
		printk("OScoreid: %3d, HWcoreid: %3d, RawSocketid: %3d, "
		       "Numa Domain: %3d, Socket: %3d, Cpu: %3d, Core: %3d\n",
		       i,
		       core_list[i].apic_id,
		       core_list[i].numa_id,
		       core_list[i].raw_socket_id,
		       core_list[i].socket_id,
		       core_list[i].cpu_id,
		       core_list[i].core_id);
	}
}
