// SPDX-License-Identifier: GPL-2.0
/*
 * Jailhouse paravirt_ops implementation
 *
 * Copyright (c) Siemens AG, 2015-2017
 *
 * Authors:
 *  Jan Kiszka <jan.kiszka@siemens.com>
 */

#include <linux/acpi_pmtmr.h>
#include <linux/kernel.h>
#include <linux/reboot.h>
#include <linux/serial_8250.h>
#include <asm/apic.h>
#include <asm/io_apic.h>
#include <asm/acpi.h>
#include <asm/cpu.h>
#include <asm/hypervisor.h>
#include <asm/i8259.h>
#include <asm/irqdomain.h>
#include <asm/pci_x86.h>
#include <asm/reboot.h>
#include <asm/setup.h>
#include <asm/jailhouse_para.h>

static struct jailhouse_setup_data setup_data;
#define SETUP_DATA_V1_LEN	(sizeof(setup_data.hdr) + sizeof(setup_data.v1))
#define SETUP_DATA_V2_LEN	(SETUP_DATA_V1_LEN + sizeof(setup_data.v2))

static unsigned int precalibrated_tsc_khz;

static void jailhouse_setup_irq(unsigned int irq)
{
	struct mpc_intsrc mp_irq = {
		.type		= MP_INTSRC,
		.irqtype	= mp_INT,
		.irqflag	= MP_IRQPOL_ACTIVE_HIGH | MP_IRQTRIG_EDGE,
		.srcbusirq	= irq,
		.dstirq		= irq,
	};
	mp_save_irq(&mp_irq);
}

static uint32_t jailhouse_cpuid_base(void)
{
	if (boot_cpu_data.cpuid_level < 0 ||
	    !boot_cpu_has(X86_FEATURE_HYPERVISOR))
		return 0;

	return hypervisor_cpuid_base("Jailhouse\0\0\0", 0);
}

static uint32_t __init jailhouse_detect(void)
{
	return jailhouse_cpuid_base();
}

static void jailhouse_get_wallclock(struct timespec64 *now)
{
	memset(now, 0, sizeof(*now));
}

static void __init jailhouse_timer_init(void)
{
	lapic_timer_period = setup_data.v1.apic_khz * (1000 / HZ);
}

static unsigned long jailhouse_get_tsc(void)
{
	return precalibrated_tsc_khz;
}

static void __init jailhouse_x2apic_init(void)
{
#ifdef CONFIG_X86_X2APIC
	if (!x2apic_enabled())
		return;
	/*
	 * We do not have access to IR inside Jailhouse non-root cells.  So
	 * we have to run in physical mode.
	 */
	x2apic_phys = 1;
	/*
	 * This will trigger the switch to apic_x2apic_phys.  Empty OEM IDs
	 * ensure that only this APIC driver picks up the call.
	 */
	default_acpi_madt_oem_check("", "");
#endif
}

static void __init jailhouse_get_smp_config(unsigned int early)
{
	struct ioapic_domain_cfg ioapic_cfg = {
		.type = IOAPIC_DOMAIN_STRICT,
		.ops = &mp_ioapic_irqdomain_ops,
	};
	unsigned int cpu;

	jailhouse_x2apic_init();

	register_lapic_address(0xfee00000);

	for (cpu = 0; cpu < setup_data.v1.num_cpus; cpu++) {
		generic_processor_info(setup_data.v1.cpu_ids[cpu],
				       boot_cpu_apic_version);
	}

	smp_found_config = 1;

	if (setup_data.v1.standard_ioapic) {
		mp_register_ioapic(0, 0xfec00000, gsi_top, &ioapic_cfg);

		if (IS_ENABLED(CONFIG_SERIAL_8250) &&
		    setup_data.hdr.version < 2) {
			/* Register 1:1 mapping for legacy UART IRQs 3 and 4 */
			jailhouse_setup_irq(3);
			jailhouse_setup_irq(4);
		}
	}
}

static void jailhouse_no_restart(void)
{
	pr_notice("Jailhouse: Restart not supported, halting\n");
	machine_halt();
}

static int __init jailhouse_pci_arch_init(void)
{
	pci_direct_init(1);

	/*
	 * There are no bridges on the virtual PCI root bus under Jailhouse,
	 * thus no other way to discover all devices than a full scan.
	 * Respect any overrides via the command line, though.
	 */
	if (pcibios_last_bus < 0)
		pcibios_last_bus = 0xff;

#ifdef CONFIG_PCI_MMCONFIG
	if (setup_data.v1.pci_mmconfig_base) {
		pci_mmconfig_add(0, 0, pcibios_last_bus,
				 setup_data.v1.pci_mmconfig_base);
		pci_mmcfg_arch_init();
	}
#endif

	return 0;
}

#ifdef CONFIG_SERIAL_8250
static inline bool jailhouse_uart_enabled(unsigned int uart_nr)
{
	return setup_data.v2.flags & BIT(uart_nr);
}

static void jailhouse_serial_fixup(int port, struct uart_port *up,
				   u32 *capabilities)
{
	static const u16 pcuart_base[] = {0x3f8, 0x2f8, 0x3e8, 0x2e8};
	unsigned int n;

	for (n = 0; n < ARRAY_SIZE(pcuart_base); n++) {
		if (pcuart_base[n] != up->iobase)
			continue;

		if (jailhouse_uart_enabled(n)) {
			pr_info("Enabling UART%u (port 0x%lx)\n", n,
				up->iobase);
			jailhouse_setup_irq(up->irq);
		} else {
			/* Deactivate UART if access isn't allowed */
			up->iobase = 0;
		}
		break;
	}
}

static void __init jailhouse_serial_workaround(void)
{
	/*
	 * There are flags inside setup_data that indicate availability of
	 * platform UARTs since setup data version 2.
	 *
	 * In case of version 1, we don't know which UARTs belong Linux. In
	 * this case, unconditionally register 1:1 mapping for legacy UART IRQs
	 * 3 and 4.
	 */
	if (setup_data.hdr.version > 1)
		serial8250_set_isa_configurator(jailhouse_serial_fixup);
}
#else /* !CONFIG_SERIAL_8250 */
static inline void jailhouse_serial_workaround(void)
{
}
#endif /* CONFIG_SERIAL_8250 */

static void __init jailhouse_init_platform(void)
{
	u64 pa_data = boot_params.hdr.setup_data;
	unsigned long setup_data_len;
	struct setup_data header;
	void *mapping;

	x86_init.irqs.pre_vector_init	= x86_init_noop;
	x86_init.timers.timer_init	= jailhouse_timer_init;
	x86_init.mpparse.get_smp_config	= jailhouse_get_smp_config;
	x86_init.pci.arch_init		= jailhouse_pci_arch_init;

	x86_platform.calibrate_cpu	= jailhouse_get_tsc;
	x86_platform.calibrate_tsc	= jailhouse_get_tsc;
	x86_platform.get_wallclock	= jailhouse_get_wallclock;
	x86_platform.legacy.rtc		= 0;
	x86_platform.legacy.warm_reset	= 0;
	x86_platform.legacy.i8042	= X86_LEGACY_I8042_PLATFORM_ABSENT;

	legacy_pic			= &null_legacy_pic;

	machine_ops.emergency_restart	= jailhouse_no_restart;

	while (pa_data) {
		mapping = early_memremap(pa_data, sizeof(header));
		memcpy(&header, mapping, sizeof(header));
		early_memunmap(mapping, sizeof(header));

		if (header.type == SETUP_JAILHOUSE)
			break;

		pa_data = header.next;
	}

	if (!pa_data)
		panic("Jailhouse: No valid setup data found");

	/* setup data must at least contain the header */
	if (header.len < sizeof(setup_data.hdr))
		goto unsupported;

	pa_data += offsetof(struct setup_data, data);
	setup_data_len = min_t(unsigned long, sizeof(setup_data),
			       (unsigned long)header.len);
	mapping = early_memremap(pa_data, setup_data_len);
	memcpy(&setup_data, mapping, setup_data_len);
	early_memunmap(mapping, setup_data_len);

	if (setup_data.hdr.version == 0 ||
	    setup_data.hdr.compatible_version !=
		JAILHOUSE_SETUP_REQUIRED_VERSION ||
	    (setup_data.hdr.version == 1 && header.len < SETUP_DATA_V1_LEN) ||
	    (setup_data.hdr.version >= 2 && header.len < SETUP_DATA_V2_LEN))
		goto unsupported;

	pmtmr_ioport = setup_data.v1.pm_timer_address;
	pr_debug("Jailhouse: PM-Timer IO Port: %#x\n", pmtmr_ioport);

	precalibrated_tsc_khz = setup_data.v1.tsc_khz;
	setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);

	pci_probe = 0;

	/*
	 * Avoid that the kernel complains about missing ACPI tables - there
	 * are none in a non-root cell.
	 */
	disable_acpi();

	jailhouse_serial_workaround();
	return;

unsupported:
	panic("Jailhouse: Unsupported setup data structure");
}

bool jailhouse_paravirt(void)
{
	return jailhouse_cpuid_base() != 0;
}

static bool __init jailhouse_x2apic_available(void)
{
	/*
	 * The x2APIC is only available if the root cell enabled it. Jailhouse
	 * does not support switching between xAPIC and x2APIC.
	 */
	return x2apic_enabled();
}

const struct hypervisor_x86 x86_hyper_jailhouse __refconst = {
	.name			= "Jailhouse",
	.detect			= jailhouse_detect,
	.init.init_platform	= jailhouse_init_platform,
	.init.x2apic_available	= jailhouse_x2apic_available,
	.ignore_nopv		= true,
};
