// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2008-2011
 * Graeme Russ, <graeme.russ@gmail.com>
 *
 * (C) Copyright 2002
 * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se>
 *
 * (C) Copyright 2002
 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Marius Groeger <mgroeger@sysgo.de>
 *
 * (C) Copyright 2002
 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Alex Zuepke <azu@sysgo.de>
 *
 * Part of this file is adapted from coreboot
 * src/arch/x86/lib/cpu.c
 */

#define LOG_CATEGORY	UCLASS_CPU

#include <bootstage.h>
#include <command.h>
#include <cpu_func.h>
#include <dm.h>
#include <errno.h>
#include <event.h>
#include <init.h>
#include <irq.h>
#include <log.h>
#include <malloc.h>
#include <syscon.h>
#include <acpi/acpi_s3.h>
#include <acpi/acpi_table.h>
#include <asm/acpi.h>
#include <asm/control_regs.h>
#include <asm/coreboot_tables.h>
#include <asm/cpu.h>
#include <asm/global_data.h>
#include <asm/lapic.h>
#include <asm/microcode.h>
#include <asm/mp.h>
#include <asm/mrccache.h>
#include <asm/msr.h>
#include <asm/mtrr.h>
#include <asm/post.h>
#include <asm/processor.h>
#include <asm/processor-flags.h>
#include <asm/interrupt.h>
#include <asm/tables.h>
#include <linux/compiler.h>

DECLARE_GLOBAL_DATA_PTR;

#ifndef CONFIG_TPL_BUILD
static const char *const x86_vendor_name[] = {
	[X86_VENDOR_INTEL]     = "Intel",
	[X86_VENDOR_CYRIX]     = "Cyrix",
	[X86_VENDOR_AMD]       = "AMD",
	[X86_VENDOR_UMC]       = "UMC",
	[X86_VENDOR_NEXGEN]    = "NexGen",
	[X86_VENDOR_CENTAUR]   = "Centaur",
	[X86_VENDOR_RISE]      = "Rise",
	[X86_VENDOR_TRANSMETA] = "Transmeta",
	[X86_VENDOR_NSC]       = "NSC",
	[X86_VENDOR_SIS]       = "SiS",
};
#endif

int __weak x86_cleanup_before_linux(void)
{
	int ret;

	ret = mp_park_aps();
	if (ret)
		return log_msg_ret("park", ret);
	bootstage_stash((void *)CONFIG_BOOTSTAGE_STASH_ADDR,
			CONFIG_BOOTSTAGE_STASH_SIZE);

	return 0;
}

int x86_init_cache(void)
{
	enable_caches();

	return 0;
}
int init_cache(void) __attribute__((weak, alias("x86_init_cache")));

void  flush_cache(unsigned long dummy1, unsigned long dummy2)
{
	asm("wbinvd\n");
}

/* Define these functions to allow ehch-hcd to function */
void flush_dcache_range(unsigned long start, unsigned long stop)
{
}

void invalidate_dcache_range(unsigned long start, unsigned long stop)
{
}

void dcache_enable(void)
{
	enable_caches();
}

void dcache_disable(void)
{
	disable_caches();
}

void icache_enable(void)
{
}

void icache_disable(void)
{
}

int icache_status(void)
{
	return 1;
}

#ifndef CONFIG_TPL_BUILD
const char *cpu_vendor_name(int vendor)
{
	const char *name;
	name = "<invalid cpu vendor>";
	if (vendor < ARRAY_SIZE(x86_vendor_name) &&
	    x86_vendor_name[vendor])
		name = x86_vendor_name[vendor];

	return name;
}
#endif

char *cpu_get_name(char *name)
{
	unsigned int *name_as_ints = (unsigned int *)name;
	struct cpuid_result regs;
	char *ptr;
	int i;

	/* This bit adds up to 48 bytes */
	for (i = 0; i < 3; i++) {
		regs = cpuid(0x80000002 + i);
		name_as_ints[i * 4 + 0] = regs.eax;
		name_as_ints[i * 4 + 1] = regs.ebx;
		name_as_ints[i * 4 + 2] = regs.ecx;
		name_as_ints[i * 4 + 3] = regs.edx;
	}
	name[CPU_MAX_NAME_LEN - 1] = '\0';

	/* Skip leading spaces. */
	ptr = name;
	while (*ptr == ' ')
		ptr++;

	return ptr;
}

int default_print_cpuinfo(void)
{
	printf("CPU: %s, vendor %s, device %xh\n",
	       cpu_has_64bit() ? "x86_64" : "x86",
	       cpu_vendor_name(gd->arch.x86_vendor), gd->arch.x86_device);

	if (IS_ENABLED(CONFIG_HAVE_ACPI_RESUME)) {
		debug("ACPI previous sleep state: %s\n",
		      acpi_ss_string(gd->arch.prev_sleep_state));
	}

	return 0;
}

#if CONFIG_IS_ENABLED(SHOW_BOOT_PROGRESS)
void show_boot_progress(int val)
{
	outb(val, POST_PORT);
}
#endif

#if !defined(CONFIG_SYS_COREBOOT) && !defined(CONFIG_EFI_STUB) && \
	!defined(CONFIG_SPL_BUILD)
/*
 * Implement a weak default function for boards that need to do some final init
 * before the system is ready.
 */
__weak void board_final_init(void)
{
}

/*
 * Implement a weak default function for boards that need to do some final
 * processing before booting the OS.
 */
__weak void board_final_cleanup(void)
{
}

static int last_stage_init(void)
{
	struct acpi_fadt __maybe_unused *fadt;
	int ret;

	board_final_init();

	if (IS_ENABLED(CONFIG_HAVE_ACPI_RESUME)) {
		fadt = acpi_find_fadt();

		if (fadt && gd->arch.prev_sleep_state == ACPI_S3)
			acpi_resume(fadt);
	}

	ret = write_tables();
	if (ret) {
		log_err("Failed to write tables\n");
		return log_msg_ret("table", ret);
	}

	if (IS_ENABLED(CONFIG_GENERATE_ACPI_TABLE)) {
		fadt = acpi_find_fadt();

		/* Don't touch ACPI hardware on HW reduced platforms */
		if (fadt && !(fadt->flags & ACPI_FADT_HW_REDUCED_ACPI)) {
			/*
			 * Other than waiting for OSPM to request us to switch
			 * to ACPI * mode, do it by ourselves, since SMI will
			 * not be triggered.
			 */
			enter_acpi_mode(fadt->pm1a_cnt_blk);
		}
	}

	/*
	 * TODO(sjg@chromium.org): Move this to bootm_announce_and_cleanup()
	 * once APL FSP-S at 0x200000 does not overlap with the bzimage at
	 * 0x100000.
	 */
	board_final_cleanup();

	return 0;
}
EVENT_SPY_SIMPLE(EVT_LAST_STAGE_INIT, last_stage_init);

#endif  /* !SYS_COREBOOT && !EFI_STUB && !SPL_BUILD */

static int x86_init_cpus(void)
{
	if (IS_ENABLED(CONFIG_SMP)) {
		debug("Init additional CPUs\n");
		x86_mp_init();
	} else {
		struct udevice *dev;

		/*
		 * This causes the cpu-x86 driver to be probed.
		 * We don't check return value here as we want to allow boards
		 * which have not been converted to use cpu uclass driver to
		 * boot.
		 */
		uclass_first_device(UCLASS_CPU, &dev);
	}

	return 0;
}

int cpu_init_r(void)
{
	struct udevice *dev;
	int ret;

	if (!ll_boot_init()) {
		uclass_first_device(UCLASS_PCI, &dev);
		return 0;
	}

	ret = x86_init_cpus();
	if (ret)
		return ret;

	/*
	 * Set up the northbridge, PCH and LPC if available. Note that these
	 * may have had some limited pre-relocation init if they were probed
	 * before relocation, but this is post relocation.
	 */
	uclass_first_device(UCLASS_NORTHBRIDGE, &dev);
	uclass_first_device(UCLASS_PCH, &dev);
	uclass_first_device(UCLASS_LPC, &dev);

	/* Set up pin control if available */
	ret = syscon_get_by_driver_data(X86_SYSCON_PINCONF, &dev);
	debug("%s, pinctrl=%p, ret=%d\n", __func__, dev, ret);

	return 0;
}

#ifndef CONFIG_EFI_STUB
int reserve_arch(void)
{
	struct udevice *itss;
	int ret;

	if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE))
		mrccache_reserve();

	if (IS_ENABLED(CONFIG_SEABIOS))
		high_table_reserve();

	if (IS_ENABLED(CONFIG_HAVE_ACPI_RESUME)) {
		acpi_s3_reserve();

		if (IS_ENABLED(CONFIG_HAVE_FSP)) {
			/*
			 * Save stack address to CMOS so that at next S3 boot,
			 * we can use it as the stack address for fsp_continue()
			 */
			fsp_save_s3_stack();
		}
	}
	ret = irq_first_device_type(X86_IRQT_ITSS, &itss);
	if (!ret) {
		/*
		 * Snapshot the current GPIO IRQ polarities. FSP-S is about to
		 * run and will set a default policy that doesn't honour boards'
		 * requirements
		 */
		irq_snapshot_polarities(itss);
	}

	return 0;
}
#endif

long detect_coreboot_table_at(ulong start, ulong size)
{
	u32 *ptr, *end;

	size /= 4;
	for (ptr = (void *)start, end = ptr + size; ptr < end; ptr += 4) {
		if (*ptr == 0x4f49424c) /* "LBIO" */
			return (long)ptr;
	}

	return -ENOENT;
}

long locate_coreboot_table(void)
{
	long addr;

	/* We look for LBIO from addresses 1K-4K and again at 960KB */
	addr = detect_coreboot_table_at(0x400, 0xc00);
	if (addr < 0)
		addr = detect_coreboot_table_at(0xf0000, 0x1000);

	return addr;
}
