// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2005 Intel Corporation
 * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
 *
 *	Alex Chiang <achiang@hp.com>
 *	- Unified x86/ia64 implementations
 *
 * I/O APIC hotplug support
 *	Yinghai Lu <yinghai@kernel.org>
 *	Jiang Liu <jiang.liu@intel.com>
 */
#include <linux/export.h>
#include <linux/acpi.h>
#include <acpi/processor.h>

static struct acpi_table_madt *get_madt_table(void)
{
	static struct acpi_table_madt *madt;
	static int read_madt;

	if (!read_madt) {
		if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0,
					(struct acpi_table_header **)&madt)))
			madt = NULL;
		read_madt++;
	}

	return madt;
}

static int map_lapic_id(struct acpi_subtable_header *entry,
		 u32 acpi_id, phys_cpuid_t *apic_id)
{
	struct acpi_madt_local_apic *lapic =
		container_of(entry, struct acpi_madt_local_apic, header);

	if (!(lapic->lapic_flags & ACPI_MADT_ENABLED))
		return -ENODEV;

	if (lapic->processor_id != acpi_id)
		return -EINVAL;

	*apic_id = lapic->id;
	return 0;
}

static int map_x2apic_id(struct acpi_subtable_header *entry,
		int device_declaration, u32 acpi_id, phys_cpuid_t *apic_id)
{
	struct acpi_madt_local_x2apic *apic =
		container_of(entry, struct acpi_madt_local_x2apic, header);

	if (!(apic->lapic_flags & ACPI_MADT_ENABLED))
		return -ENODEV;

	if (device_declaration && (apic->uid == acpi_id)) {
		*apic_id = apic->local_apic_id;
		return 0;
	}

	return -EINVAL;
}

static int map_lsapic_id(struct acpi_subtable_header *entry,
		int device_declaration, u32 acpi_id, phys_cpuid_t *apic_id)
{
	struct acpi_madt_local_sapic *lsapic =
		container_of(entry, struct acpi_madt_local_sapic, header);

	if (!(lsapic->lapic_flags & ACPI_MADT_ENABLED))
		return -ENODEV;

	if (device_declaration) {
		if ((entry->length < 16) || (lsapic->uid != acpi_id))
			return -EINVAL;
	} else if (lsapic->processor_id != acpi_id)
		return -EINVAL;

	*apic_id = (lsapic->id << 8) | lsapic->eid;
	return 0;
}

/*
 * Retrieve the ARM CPU physical identifier (MPIDR)
 */
static int map_gicc_mpidr(struct acpi_subtable_header *entry,
		int device_declaration, u32 acpi_id, phys_cpuid_t *mpidr)
{
	struct acpi_madt_generic_interrupt *gicc =
	    container_of(entry, struct acpi_madt_generic_interrupt, header);

	if (!acpi_gicc_is_usable(gicc))
		return -ENODEV;

	/* device_declaration means Device object in DSDT, in the
	 * GIC interrupt model, logical processors are required to
	 * have a Processor Device object in the DSDT, so we should
	 * check device_declaration here
	 */
	if (device_declaration && (gicc->uid == acpi_id)) {
		*mpidr = gicc->arm_mpidr;
		return 0;
	}

	return -EINVAL;
}

/*
 * Retrieve the RISC-V hartid for the processor
 */
static int map_rintc_hartid(struct acpi_subtable_header *entry,
			    int device_declaration, u32 acpi_id,
			    phys_cpuid_t *hartid)
{
	struct acpi_madt_rintc *rintc =
	    container_of(entry, struct acpi_madt_rintc, header);

	if (!(rintc->flags & ACPI_MADT_ENABLED))
		return -ENODEV;

	/* device_declaration means Device object in DSDT, in the
	 * RISC-V, logical processors are required to
	 * have a Processor Device object in the DSDT, so we should
	 * check device_declaration here
	 */
	if (device_declaration && rintc->uid == acpi_id) {
		*hartid = rintc->hart_id;
		return 0;
	}

	return -EINVAL;
}

/*
 * Retrieve LoongArch CPU physical id
 */
static int map_core_pic_id(struct acpi_subtable_header *entry,
		int device_declaration, u32 acpi_id, phys_cpuid_t *phys_id)
{
	struct acpi_madt_core_pic *core_pic =
		container_of(entry, struct acpi_madt_core_pic, header);

	if (!(core_pic->flags & ACPI_MADT_ENABLED))
		return -ENODEV;

	/* device_declaration means Device object in DSDT, in LoongArch
	 * system, logical processor acpi_id is required in _UID property
	 * of DSDT table, so we should check device_declaration here
	 */
	if (device_declaration && (core_pic->processor_id == acpi_id)) {
		*phys_id = core_pic->core_id;
		return 0;
	}

	return -EINVAL;
}

static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt,
				   int type, u32 acpi_id)
{
	unsigned long madt_end, entry;
	phys_cpuid_t phys_id = PHYS_CPUID_INVALID;	/* CPU hardware ID */

	if (!madt)
		return phys_id;

	entry = (unsigned long)madt;
	madt_end = entry + madt->header.length;

	/* Parse all entries looking for a match. */

	entry += sizeof(struct acpi_table_madt);
	while (entry + sizeof(struct acpi_subtable_header) < madt_end) {
		struct acpi_subtable_header *header =
			(struct acpi_subtable_header *)entry;
		if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) {
			if (!map_lapic_id(header, acpi_id, &phys_id))
				break;
		} else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) {
			if (!map_x2apic_id(header, type, acpi_id, &phys_id))
				break;
		} else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
			if (!map_lsapic_id(header, type, acpi_id, &phys_id))
				break;
		} else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) {
			if (!map_gicc_mpidr(header, type, acpi_id, &phys_id))
				break;
		} else if (header->type == ACPI_MADT_TYPE_RINTC) {
			if (!map_rintc_hartid(header, type, acpi_id, &phys_id))
				break;
		} else if (header->type == ACPI_MADT_TYPE_CORE_PIC) {
			if (!map_core_pic_id(header, type, acpi_id, &phys_id))
				break;
		}
		entry += header->length;
	}
	return phys_id;
}

phys_cpuid_t __init acpi_map_madt_entry(u32 acpi_id)
{
	struct acpi_table_madt *madt = NULL;
	phys_cpuid_t rv;

	acpi_get_table(ACPI_SIG_MADT, 0,
		       (struct acpi_table_header **)&madt);
	if (!madt)
		return PHYS_CPUID_INVALID;

	rv = map_madt_entry(madt, 1, acpi_id);

	acpi_put_table((struct acpi_table_header *)madt);

	return rv;
}

static phys_cpuid_t map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
{
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	union acpi_object *obj;
	struct acpi_subtable_header *header;
	phys_cpuid_t phys_id = PHYS_CPUID_INVALID;

	if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer)))
		goto exit;

	if (!buffer.length || !buffer.pointer)
		goto exit;

	obj = buffer.pointer;
	if (obj->type != ACPI_TYPE_BUFFER ||
	    obj->buffer.length < sizeof(struct acpi_subtable_header)) {
		goto exit;
	}

	header = (struct acpi_subtable_header *)obj->buffer.pointer;
	if (header->type == ACPI_MADT_TYPE_LOCAL_APIC)
		map_lapic_id(header, acpi_id, &phys_id);
	else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC)
		map_lsapic_id(header, type, acpi_id, &phys_id);
	else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC)
		map_x2apic_id(header, type, acpi_id, &phys_id);
	else if (header->type == ACPI_MADT_TYPE_GENERIC_INTERRUPT)
		map_gicc_mpidr(header, type, acpi_id, &phys_id);
	else if (header->type == ACPI_MADT_TYPE_CORE_PIC)
		map_core_pic_id(header, type, acpi_id, &phys_id);

exit:
	kfree(buffer.pointer);
	return phys_id;
}

phys_cpuid_t acpi_get_phys_id(acpi_handle handle, int type, u32 acpi_id)
{
	phys_cpuid_t phys_id;

	phys_id = map_mat_entry(handle, type, acpi_id);
	if (invalid_phys_cpuid(phys_id))
		phys_id = map_madt_entry(get_madt_table(), type, acpi_id);

	return phys_id;
}
EXPORT_SYMBOL_GPL(acpi_get_phys_id);

int acpi_map_cpuid(phys_cpuid_t phys_id, u32 acpi_id)
{
#ifdef CONFIG_SMP
	int i;
#endif

	if (invalid_phys_cpuid(phys_id)) {
		/*
		 * On UP processor, there is no _MAT or MADT table.
		 * So above phys_id is always set to PHYS_CPUID_INVALID.
		 *
		 * BIOS may define multiple CPU handles even for UP processor.
		 * For example,
		 *
		 * Scope (_PR)
		 * {
		 *     Processor (CPU0, 0x00, 0x00000410, 0x06) {}
		 *     Processor (CPU1, 0x01, 0x00000410, 0x06) {}
		 *     Processor (CPU2, 0x02, 0x00000410, 0x06) {}
		 *     Processor (CPU3, 0x03, 0x00000410, 0x06) {}
		 * }
		 *
		 * Ignores phys_id and always returns 0 for the processor
		 * handle with acpi id 0 if nr_cpu_ids is 1.
		 * This should be the case if SMP tables are not found.
		 * Return -EINVAL for other CPU's handle.
		 */
		if (nr_cpu_ids <= 1 && acpi_id == 0)
			return acpi_id;
		else
			return -EINVAL;
	}

#ifdef CONFIG_SMP
	for_each_possible_cpu(i) {
		if (cpu_physical_id(i) == phys_id)
			return i;
	}
#else
	/* In UP kernel, only processor 0 is valid */
	if (phys_id == 0)
		return phys_id;
#endif
	return -ENODEV;
}

int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
{
	phys_cpuid_t phys_id;

	phys_id = acpi_get_phys_id(handle, type, acpi_id);

	return acpi_map_cpuid(phys_id, acpi_id);
}
EXPORT_SYMBOL_GPL(acpi_get_cpuid);

#ifdef CONFIG_ACPI_HOTPLUG_IOAPIC
static int get_ioapic_id(struct acpi_subtable_header *entry, u32 gsi_base,
			 u64 *phys_addr, int *ioapic_id)
{
	struct acpi_madt_io_apic *ioapic = (struct acpi_madt_io_apic *)entry;

	if (ioapic->global_irq_base != gsi_base)
		return 0;

	*phys_addr = ioapic->address;
	*ioapic_id = ioapic->id;
	return 1;
}

static int parse_madt_ioapic_entry(u32 gsi_base, u64 *phys_addr)
{
	struct acpi_subtable_header *hdr;
	unsigned long madt_end, entry;
	struct acpi_table_madt *madt;
	int apic_id = -1;

	madt = get_madt_table();
	if (!madt)
		return apic_id;

	entry = (unsigned long)madt;
	madt_end = entry + madt->header.length;

	/* Parse all entries looking for a match. */
	entry += sizeof(struct acpi_table_madt);
	while (entry + sizeof(struct acpi_subtable_header) < madt_end) {
		hdr = (struct acpi_subtable_header *)entry;
		if (hdr->type == ACPI_MADT_TYPE_IO_APIC &&
		    get_ioapic_id(hdr, gsi_base, phys_addr, &apic_id))
			break;
		else
			entry += hdr->length;
	}

	return apic_id;
}

static int parse_mat_ioapic_entry(acpi_handle handle, u32 gsi_base,
				  u64 *phys_addr)
{
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	struct acpi_subtable_header *header;
	union acpi_object *obj;
	int apic_id = -1;

	if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer)))
		goto exit;

	if (!buffer.length || !buffer.pointer)
		goto exit;

	obj = buffer.pointer;
	if (obj->type != ACPI_TYPE_BUFFER ||
	    obj->buffer.length < sizeof(struct acpi_subtable_header))
		goto exit;

	header = (struct acpi_subtable_header *)obj->buffer.pointer;
	if (header->type == ACPI_MADT_TYPE_IO_APIC)
		get_ioapic_id(header, gsi_base, phys_addr, &apic_id);

exit:
	kfree(buffer.pointer);
	return apic_id;
}

/**
 * acpi_get_ioapic_id - Get IOAPIC ID and physical address matching @gsi_base
 * @handle:	ACPI object for IOAPIC device
 * @gsi_base:	GSI base to match with
 * @phys_addr:	Pointer to store physical address of matching IOAPIC record
 *
 * Walk resources returned by ACPI_MAT method, then ACPI MADT table, to search
 * for an ACPI IOAPIC record matching @gsi_base.
 * Return IOAPIC id and store physical address in @phys_addr if found a match,
 * otherwise return <0.
 */
int acpi_get_ioapic_id(acpi_handle handle, u32 gsi_base, u64 *phys_addr)
{
	int apic_id;

	apic_id = parse_mat_ioapic_entry(handle, gsi_base, phys_addr);
	if (apic_id == -1)
		apic_id = parse_madt_ioapic_entry(gsi_base, phys_addr);

	return apic_id;
}
#endif /* CONFIG_ACPI_HOTPLUG_IOAPIC */
