// SPDX-License-Identifier: GPL-2.0
#include <linux/cpu.h>

#include <xen/xen.h>

#include <asm/apic.h>
#include <asm/processor.h>
#include <asm/smp.h>

#include "cpu.h"

struct x86_topology_system x86_topo_system __ro_after_init;
EXPORT_SYMBOL_GPL(x86_topo_system);

unsigned int __amd_nodes_per_pkg __ro_after_init;
EXPORT_SYMBOL_GPL(__amd_nodes_per_pkg);

void topology_set_dom(struct topo_scan *tscan, enum x86_topology_domains dom,
		      unsigned int shift, unsigned int ncpus)
{
	topology_update_dom(tscan, dom, shift, ncpus);

	/* Propagate to the upper levels */
	for (dom++; dom < TOPO_MAX_DOMAIN; dom++) {
		tscan->dom_shifts[dom] = tscan->dom_shifts[dom - 1];
		tscan->dom_ncpus[dom] = tscan->dom_ncpus[dom - 1];
	}
}

static unsigned int __maybe_unused parse_num_cores_legacy(struct cpuinfo_x86 *c)
{
	struct {
		u32	cache_type	:  5,
			unused		: 21,
			ncores		:  6;
	} eax;

	if (c->cpuid_level < 4)
		return 1;

	cpuid_subleaf_reg(4, 0, CPUID_EAX, &eax);
	if (!eax.cache_type)
		return 1;

	return eax.ncores + 1;
}

static void parse_legacy(struct topo_scan *tscan)
{
	unsigned int cores, core_shift, smt_shift = 0;
	struct cpuinfo_x86 *c = tscan->c;

	cores = parse_num_cores_legacy(c);
	core_shift = get_count_order(cores);

	if (cpu_has(c, X86_FEATURE_HT)) {
		if (!WARN_ON_ONCE(tscan->ebx1_nproc_shift < core_shift))
			smt_shift = tscan->ebx1_nproc_shift - core_shift;
		/*
		 * The parser expects leaf 0xb/0x1f format, which means
		 * the number of logical processors at core level is
		 * counting threads.
		 */
		core_shift += smt_shift;
		cores <<= smt_shift;
	}

	topology_set_dom(tscan, TOPO_SMT_DOMAIN, smt_shift, 1U << smt_shift);
	topology_set_dom(tscan, TOPO_CORE_DOMAIN, core_shift, cores);
}

static bool fake_topology(struct topo_scan *tscan)
{
	/*
	 * Preset the CORE level shift for CPUID less systems and XEN_PV,
	 * which has useless CPUID information.
	 */
	topology_set_dom(tscan, TOPO_SMT_DOMAIN, 0, 1);
	topology_set_dom(tscan, TOPO_CORE_DOMAIN, 0, 1);

	return tscan->c->cpuid_level < 1;
}

static void parse_topology(struct topo_scan *tscan, bool early)
{
	const struct cpuinfo_topology topo_defaults = {
		.cu_id			= 0xff,
		.llc_id			= BAD_APICID,
		.l2c_id			= BAD_APICID,
	};
	struct cpuinfo_x86 *c = tscan->c;
	struct {
		u32	unused0		: 16,
			nproc		:  8,
			apicid		:  8;
	} ebx;

	c->topo = topo_defaults;

	if (fake_topology(tscan))
		return;

	/* Preset Initial APIC ID from CPUID leaf 1 */
	cpuid_leaf_reg(1, CPUID_EBX, &ebx);
	c->topo.initial_apicid = ebx.apicid;

	/*
	 * The initial invocation from early_identify_cpu() happens before
	 * the APIC is mapped or X2APIC enabled. For establishing the
	 * topology, that's not required. Use the initial APIC ID.
	 */
	if (early)
		c->topo.apicid = c->topo.initial_apicid;
	else
		c->topo.apicid = read_apic_id();

	/* The above is sufficient for UP */
	if (!IS_ENABLED(CONFIG_SMP))
		return;

	tscan->ebx1_nproc_shift = get_count_order(ebx.nproc);

	switch (c->x86_vendor) {
	case X86_VENDOR_AMD:
		if (IS_ENABLED(CONFIG_CPU_SUP_AMD))
			cpu_parse_topology_amd(tscan);
		break;
	case X86_VENDOR_CENTAUR:
	case X86_VENDOR_ZHAOXIN:
		parse_legacy(tscan);
		break;
	case X86_VENDOR_INTEL:
		if (!IS_ENABLED(CONFIG_CPU_SUP_INTEL) || !cpu_parse_topology_ext(tscan))
			parse_legacy(tscan);
		break;
	case X86_VENDOR_HYGON:
		if (IS_ENABLED(CONFIG_CPU_SUP_HYGON))
			cpu_parse_topology_amd(tscan);
		break;
	}
}

static void topo_set_ids(struct topo_scan *tscan)
{
	struct cpuinfo_x86 *c = tscan->c;
	u32 apicid = c->topo.apicid;

	c->topo.pkg_id = topo_shift_apicid(apicid, TOPO_PKG_DOMAIN);
	c->topo.die_id = topo_shift_apicid(apicid, TOPO_DIE_DOMAIN);

	c->topo.logical_pkg_id = topology_get_logical_id(apicid, TOPO_PKG_DOMAIN);
	c->topo.logical_die_id = topology_get_logical_id(apicid, TOPO_DIE_DOMAIN);

	/* Package relative core ID */
	c->topo.core_id = (apicid & topo_domain_mask(TOPO_PKG_DOMAIN)) >>
		x86_topo_system.dom_shifts[TOPO_SMT_DOMAIN];

	c->topo.amd_node_id = tscan->amd_node_id;

	if (c->x86_vendor == X86_VENDOR_AMD)
		cpu_topology_fixup_amd(tscan);
}

void cpu_parse_topology(struct cpuinfo_x86 *c)
{
	unsigned int dom, cpu = smp_processor_id();
	struct topo_scan tscan = { .c = c, };

	parse_topology(&tscan, false);

	if (IS_ENABLED(CONFIG_X86_LOCAL_APIC)) {
		if (c->topo.initial_apicid != c->topo.apicid) {
			pr_err(FW_BUG "CPU%4u: APIC ID mismatch. CPUID: 0x%04x APIC: 0x%04x\n",
			       cpu, c->topo.initial_apicid, c->topo.apicid);
		}

		if (c->topo.apicid != cpuid_to_apicid[cpu]) {
			pr_err(FW_BUG "CPU%4u: APIC ID mismatch. Firmware: 0x%04x APIC: 0x%04x\n",
			       cpu, cpuid_to_apicid[cpu], c->topo.apicid);
		}
	}

	for (dom = TOPO_SMT_DOMAIN; dom < TOPO_MAX_DOMAIN; dom++) {
		if (tscan.dom_shifts[dom] == x86_topo_system.dom_shifts[dom])
			continue;
		pr_err(FW_BUG "CPU%d: Topology domain %u shift %u != %u\n", cpu, dom,
		       tscan.dom_shifts[dom], x86_topo_system.dom_shifts[dom]);
	}

	topo_set_ids(&tscan);
}

void __init cpu_init_topology(struct cpuinfo_x86 *c)
{
	struct topo_scan tscan = { .c = c, };
	unsigned int dom, sft;

	parse_topology(&tscan, true);

	/* Copy the shift values and calculate the unit sizes. */
	memcpy(x86_topo_system.dom_shifts, tscan.dom_shifts, sizeof(x86_topo_system.dom_shifts));

	dom = TOPO_SMT_DOMAIN;
	x86_topo_system.dom_size[dom] = 1U << x86_topo_system.dom_shifts[dom];

	for (dom++; dom < TOPO_MAX_DOMAIN; dom++) {
		sft = x86_topo_system.dom_shifts[dom] - x86_topo_system.dom_shifts[dom - 1];
		x86_topo_system.dom_size[dom] = 1U << sft;
	}

	topo_set_ids(&tscan);

	/*
	 * AMD systems have Nodes per package which cannot be mapped to
	 * APIC ID.
	 */
	__amd_nodes_per_pkg = tscan.amd_nodes_per_pkg;
}
