/* SPDX-License-Identifier: GPL-2.0-only */

#include <acpi/acpi_ivrs.h>
#include <amdblocks/acpi.h>
#include <amdblocks/cpu.h>
#include <amdblocks/ioapic.h>
#include <amdblocks/iommu.h>
#include <arch/ioapic.h>
#include <console/console.h>
#include <cpu/amd/cpuid.h>
#include <device/device.h>
#include <device/mmio.h>
#include <device/pci_def.h>
#include <device/pci_ops.h>
#include <soc/data_fabric.h>
#include <soc/iomap.h>
#include <soc/pci_devs.h>

static unsigned long acpi_fill_ivrs_ioapic(unsigned long current, void *ioapic_base,
					    uint16_t src_devid, uint8_t dte_setting)
{
	ivrs_ivhd_special_t *ivhd_ioapic = (ivrs_ivhd_special_t *)current;
	memset(ivhd_ioapic, 0, sizeof(*ivhd_ioapic));

	ivhd_ioapic->type = IVHD_DEV_8_BYTE_EXT_SPECIAL_DEV;
	ivhd_ioapic->dte_setting = dte_setting;
	ivhd_ioapic->handle = get_ioapic_id(ioapic_base);
	ivhd_ioapic->source_dev_id = src_devid;
	ivhd_ioapic->variety = IVHD_SPECIAL_DEV_IOAPIC;
	current += sizeof(ivrs_ivhd_special_t);

	return current;
}

static unsigned long ivhd_describe_hpet(unsigned long current, uint8_t hndl, uint16_t src_devid)
{
	ivrs_ivhd_special_t *ivhd_hpet = (ivrs_ivhd_special_t *)current;
	memset(ivhd_hpet, 0, sizeof(*ivhd_hpet));

	ivhd_hpet->type = IVHD_DEV_8_BYTE_EXT_SPECIAL_DEV;
	ivhd_hpet->handle = hndl;
	ivhd_hpet->source_dev_id = src_devid; /* function 0 of FCH PCI device */
	ivhd_hpet->variety = IVHD_SPECIAL_DEV_HPET;
	current += sizeof(ivrs_ivhd_special_t);

	return current;
}

static unsigned long ivhd_describe_f0_device(unsigned long current, uint16_t dev_id,
					     const char acpi_hid[8], uint8_t datasetting)
{
	ivrs_ivhd_f0_entry_t *ivhd_f0 = (ivrs_ivhd_f0_entry_t *)current;
	memset(ivhd_f0, 0, sizeof(*ivhd_f0));

	ivhd_f0->type = IVHD_DEV_VARIABLE;
	ivhd_f0->dev_id = dev_id;
	ivhd_f0->dte_setting = datasetting;

	memcpy(ivhd_f0->hardware_id, acpi_hid, sizeof(ivhd_f0->hardware_id));

	current += sizeof(ivrs_ivhd_f0_entry_t);
	return current;
}

static unsigned long ivhd_dev_range(unsigned long current, uint16_t start_devid,
				    uint16_t end_devid, uint8_t setting)
{
	/* 4-byte IVHD structures must be aligned to the 4-byte boundary. */
	current = ALIGN_UP(current, 4);
	ivrs_ivhd_generic_t *ivhd_range = (ivrs_ivhd_generic_t *)current;
	memset(ivhd_range, 0, sizeof(*ivhd_range));

	/* Create the start range IVHD entry */
	ivhd_range->type = IVHD_DEV_4_BYTE_START_RANGE;
	ivhd_range->dev_id = start_devid;
	ivhd_range->dte_setting = setting;
	current += sizeof(ivrs_ivhd_generic_t);

	/* Create the end range IVHD entry */
	ivhd_range = (ivrs_ivhd_generic_t *)current;
	ivhd_range->type = IVHD_DEV_4_BYTE_END_RANGE;
	ivhd_range->dev_id = end_devid;
	ivhd_range->dte_setting = setting;
	current += sizeof(ivrs_ivhd_generic_t);

	return current;
}

static unsigned long add_ivhd_dev_entry(struct device *parent, struct device *dev,
					unsigned long *current, uint8_t type, uint8_t data)
{
	if (type == IVHD_DEV_4_BYTE_SELECT) {
		/* 4-byte IVHD structures must be aligned to the 4-byte boundary. */
		*current = ALIGN_UP(*current, 4);
		ivrs_ivhd_generic_t *ivhd_entry = (ivrs_ivhd_generic_t *)*current;
		memset(ivhd_entry, 0, sizeof(*ivhd_entry));

		ivhd_entry->type = type;
		ivhd_entry->dev_id = dev->path.pci.devfn | (dev->bus->secondary << 8);
		ivhd_entry->dte_setting = data;
		*current += sizeof(ivrs_ivhd_generic_t);
	} else if (type == IVHD_DEV_8_BYTE_ALIAS_SELECT) {
		ivrs_ivhd_alias_t *ivhd_entry = (ivrs_ivhd_alias_t *)*current;
		memset(ivhd_entry, 0, sizeof(*ivhd_entry));

		ivhd_entry->type = type;
		ivhd_entry->dev_id = dev->path.pci.devfn | (dev->bus->secondary << 8);
		ivhd_entry->dte_setting = data;
		ivhd_entry->reserved1 = 0;
		ivhd_entry->reserved2 = 0;
		ivhd_entry->source_dev_id = parent->path.pci.devfn |
					    (parent->bus->secondary << 8);
		*current += sizeof(ivrs_ivhd_alias_t);
	}

	return *current;
}

static void ivrs_add_device_or_bridge(struct device *parent, struct device *dev,
				      unsigned long *current)
{
	unsigned int header_type, is_pcie;

	header_type = dev->hdr_type & 0x7f;
	is_pcie = pci_find_capability(dev, PCI_CAP_ID_PCIE);

	if (((header_type == PCI_HEADER_TYPE_NORMAL) ||
	     (header_type == PCI_HEADER_TYPE_BRIDGE)) && is_pcie) {
		/* Device or Bridge is PCIe */
		add_ivhd_dev_entry(parent, dev, current, IVHD_DEV_4_BYTE_SELECT, 0x0);
	} else if ((header_type == PCI_HEADER_TYPE_NORMAL) && !is_pcie) {
		/* Device is legacy PCI or PCI-X */
		add_ivhd_dev_entry(parent, dev, current, IVHD_DEV_8_BYTE_ALIAS_SELECT, 0x0);

	}
}

static void add_ivhd_device_entries(struct device *parent, struct device *dev,
				    unsigned int depth, int linknum, int8_t *root_level,
				    unsigned long *current, uint16_t nb_bus)
{
	struct device *sibling;

	if (!root_level)
		return;

	if (dev->path.type == DEVICE_PATH_PCI) {
		if ((dev->bus->secondary == nb_bus) &&
		    (dev->path.pci.devfn == 0x0))
			*root_level = depth;

		if ((*root_level != -1) && (dev->enabled))
			if (depth != *root_level)
				ivrs_add_device_or_bridge(parent, dev, current);
	}

	if (!dev->link_list)
		return;
	for (sibling = dev->link_list->children; sibling; sibling = sibling->sibling)
		add_ivhd_device_entries(dev, sibling, depth + 1, depth, root_level, current,
					nb_bus);
}

static unsigned long acpi_ivhd_misc(unsigned long current, struct device *dev)
{
	u8 dte_setting = IVHD_DTE_LINT_1_PASS | IVHD_DTE_LINT_0_PASS |
		       IVHD_DTE_SYS_MGT_NO_TRANS | IVHD_DTE_NMI_PASS |
		       IVHD_DTE_EXT_INT_PASS | IVHD_DTE_INIT_PASS;
	int8_t root_level = -1;
	struct resource *res;

	/*
	 * Add all possible PCI devices in the domain that can generate transactions
	 * processed by IOMMU. Start with device <bus>:01.0
	*/
	current = ivhd_dev_range(current, PCI_DEVFN(0, 3) | (dev->link_list->secondary << 8),
				 0xff | (dev->link_list->subordinate << 8), 0);

	add_ivhd_device_entries(NULL, dev, 0, -1, &root_level,
		&current, dev->link_list->secondary);

	res = probe_resource(dev, IOMMU_IOAPIC_IDX);
	if (res) {
		/* Describe IOAPIC associated with the IOMMU */
		current = acpi_fill_ivrs_ioapic(current, (u8 *)(uintptr_t)res->base,
				      PCI_DEVFN(0, 1) | (dev->link_list->secondary << 8), 0);
	}

	/* If the domain has secondary bus as zero then associate HPET & FCH IOAPIC */
	if (dev->link_list->secondary == 0) {
		/* Describe HPET */
		current = ivhd_describe_hpet(current, 0x00, SMBUS_DEVFN);
		/* Describe FCH IOAPICs */
		current = acpi_fill_ivrs_ioapic(current, VIO_APIC_VADDR,
				      SMBUS_DEVFN, dte_setting);
	}

	return current;
}

static unsigned long acpi_fill_ivrs40(unsigned long current, acpi_ivrs_ivhd_t *ivhd,
				       struct device *nb_dev, struct device *iommu_dev)
{
	acpi_ivrs_ivhd40_t *ivhd_40 = (acpi_ivrs_ivhd40_t *)current;
	unsigned long current_backup;

	memset(ivhd_40, 0, sizeof(*ivhd_40));

	/* Enable EFR */
	ivhd_40->type = IVHD_BLOCK_TYPE_FULL__ACPI_HID;
	/* For type 40h bits 6 and 7 are reserved */
	ivhd_40->flags = ivhd->flags & 0x3f;
	ivhd_40->length = sizeof(struct acpi_ivrs_ivhd_40);
	/* BDF <bus>:00.2 */
	ivhd_40->device_id = 0x02 | (nb_dev->bus->secondary << 8);
	ivhd_40->capability_offset = pci_find_capability(iommu_dev, IOMMU_CAP_ID);
	ivhd_40->iommu_base_low = ivhd->iommu_base_low;
	ivhd_40->iommu_base_high = ivhd->iommu_base_high;
	ivhd_40->pci_segment_group = nb_dev->bus->segment_group;
	ivhd_40->iommu_info = ivhd->iommu_info;
	/* For type 40h bits 31:28 and 12:0 are reserved */
	ivhd_40->iommu_attributes = ivhd->iommu_feature_info & 0xfffe000;

	if (pci_read_config32(iommu_dev, ivhd_40->capability_offset) & EFR_FEATURE_SUP) {
		ivhd_40->efr_reg_image_low  = read32p(ivhd_40->iommu_base_low + 0x30);
		ivhd_40->efr_reg_image_high = read32p(ivhd_40->iommu_base_low + 0x34);
	}

	current += sizeof(acpi_ivrs_ivhd40_t);

	/* Now repeat all the device entries from type 10h */
	current_backup = current;
	current = acpi_ivhd_misc(current, nb_dev->bus->dev);

	if (nb_dev->bus->secondary == 0) {
		/* Describe EMMC */
		if (CONFIG(SOC_AMD_COMMON_BLOCK_EMMC)) {
			/* PCI_DEVFN(0x13, 1) doesn't exist in the hardware, but it's what the
			 * reference code uses. Maybe to have a unique PCI device to put into
			 * the field that doesn't collide with any existing device? */
			current = ivhd_describe_f0_device(current, PCI_DEVFN(0x13, 1),
						"AMDI0040",
						IVHD_DTE_LINT_1_PASS | IVHD_DTE_LINT_0_PASS |
						IVHD_DTE_SYS_MGT_TRANS   | IVHD_DTE_NMI_PASS |
						IVHD_DTE_EXT_INT_PASS | IVHD_DTE_INIT_PASS);
		}
	}
	ivhd_40->length += (current - current_backup);

	return current;
}

static unsigned long acpi_fill_ivrs11(unsigned long current, acpi_ivrs_ivhd_t *ivhd,
				       struct device *nb_dev, struct device *iommu_dev)
{
	acpi_ivrs_ivhd11_t *ivhd_11 = (acpi_ivrs_ivhd11_t *)current;
	ivhd11_iommu_attr_t *ivhd11_attr_ptr;
	unsigned long current_backup;

	/*
	 * In order to utilize all features, firmware should expose type 11h
	 * IVHD which supersedes the type 10h.
	 */
	memset(ivhd_11, 0, sizeof(*ivhd_11));

	/* Enable EFR */
	ivhd_11->type = IVHD_BLOCK_TYPE_FULL__FIXED;
	/* For type 11h bits 6 and 7 are reserved */
	ivhd_11->flags = ivhd->flags & 0x3f;
	ivhd_11->length = sizeof(struct acpi_ivrs_ivhd_11);
	/* BDF <bus>:00.2 */
	ivhd_11->device_id = 0x02 | (nb_dev->bus->secondary << 8);
	ivhd_11->capability_offset = pci_find_capability(iommu_dev, IOMMU_CAP_ID);
	ivhd_11->iommu_base_low = ivhd->iommu_base_low;
	ivhd_11->iommu_base_high = ivhd->iommu_base_high;
	ivhd_11->pci_segment_group = nb_dev->bus->segment_group;
	ivhd_11->iommu_info = ivhd->iommu_info;
	ivhd11_attr_ptr = (ivhd11_iommu_attr_t *)&ivhd->iommu_feature_info;
	ivhd_11->iommu_attributes.perf_counters = ivhd11_attr_ptr->perf_counters;
	ivhd_11->iommu_attributes.perf_counter_banks = ivhd11_attr_ptr->perf_counter_banks;
	ivhd_11->iommu_attributes.msi_num_ppr = ivhd11_attr_ptr->msi_num_ppr;

	if (pci_read_config32(iommu_dev, ivhd_11->capability_offset) & EFR_FEATURE_SUP) {
		ivhd_11->efr_reg_image_low  = read32p(ivhd_11->iommu_base_low + 0x30);
		ivhd_11->efr_reg_image_high = read32p(ivhd_11->iommu_base_low + 0x34);
	}

	current += sizeof(acpi_ivrs_ivhd11_t);

	/* Now repeat all the device entries from type 10h */
	current_backup = current;
	current = acpi_ivhd_misc(current, nb_dev->bus->dev);
	ivhd_11->length += (current - current_backup);

	return acpi_fill_ivrs40(current, ivhd, nb_dev, iommu_dev);
}

static unsigned long acpi_fill_ivrs(acpi_ivrs_t *ivrs, unsigned long current)
{
	unsigned long current_backup;
	uint64_t mmio_x30_value;
	uint64_t mmio_x18_value;
	uint64_t mmio_x4000_value;
	uint32_t cap_offset_0;
	uint32_t cap_offset_10;
	struct acpi_ivrs_ivhd *ivhd;
	struct device *iommu_dev;
	struct device *nb_dev;
	struct device *dev = NULL;

	if (ivrs == NULL) {
		printk(BIOS_WARNING, "%s: ivrs is NULL\n", __func__);
		return current;
	}

	ivhd = &ivrs->ivhd;

	while ((dev = dev_find_path(dev, DEVICE_PATH_DOMAIN)) != NULL) {

		nb_dev = pcidev_path_behind(dev->link_list, PCI_DEVFN(0, 0));
		iommu_dev = pcidev_path_behind(dev->link_list, PCI_DEVFN(0, 2));
		if (!nb_dev) {
			printk(BIOS_WARNING, "%s: Northbridge device not present!\n", __func__);
			printk(BIOS_WARNING, "%s: IVRS table not generated...\n", __func__);
			return (unsigned long)ivrs;
		}

		if (!iommu_dev) {
			printk(BIOS_WARNING, "%s: IOMMU device not found\n", __func__);
			return (unsigned long)ivrs;
		}

		ivhd->type = IVHD_BLOCK_TYPE_LEGACY__FIXED;
		ivhd->length = sizeof(struct acpi_ivrs_ivhd);

		/* BDF <bus>:00.2 */
		ivhd->device_id = 0x02 | (nb_dev->bus->secondary << 8);
		ivhd->capability_offset = pci_find_capability(iommu_dev, IOMMU_CAP_ID);
		ivhd->iommu_base_low = pci_read_config32(iommu_dev, IOMMU_CAP_BASE_LO) & 0xffffc000;
		ivhd->iommu_base_high = pci_read_config32(iommu_dev, IOMMU_CAP_BASE_HI);

		cap_offset_0 = pci_read_config32(iommu_dev, ivhd->capability_offset);
		cap_offset_10 = pci_read_config32(iommu_dev,
						ivhd->capability_offset + 0x10);
		mmio_x18_value = read64p(ivhd->iommu_base_low + 0x18);
		mmio_x30_value = read64p(ivhd->iommu_base_low + 0x30);
		mmio_x4000_value = read64p(ivhd->iommu_base_low + 0x4000);

		ivhd->flags |= ((mmio_x30_value & MMIO_EXT_FEATURE_PPR_SUP) ?
							IVHD_FLAG_PPE_SUP : 0);
		ivhd->flags |= ((mmio_x30_value & MMIO_EXT_FEATURE_PRE_F_SUP) ?
							IVHD_FLAG_PREF_SUP : 0);
		ivhd->flags |= ((mmio_x18_value & MMIO_CTRL_COHERENT) ?
							IVHD_FLAG_COHERENT : 0);
		ivhd->flags |= ((cap_offset_0 & CAP_OFFSET_0_IOTLB_SP) ?
							IVHD_FLAG_IOTLB_SUP : 0);
		ivhd->flags |= ((mmio_x18_value & MMIO_CTRL_ISOC) ?
							IVHD_FLAG_ISOC : 0);
		ivhd->flags |= ((mmio_x18_value & MMIO_CTRL_RES_PASS_PW) ?
							IVHD_FLAG_RES_PASS_PW : 0);
		ivhd->flags |= ((mmio_x18_value & MMIO_CTRL_PASS_PW) ?
							IVHD_FLAG_PASS_PW : 0);
		ivhd->flags |= ((mmio_x18_value & MMIO_CTRL_HT_TUN_EN) ?
							IVHD_FLAG_HT_TUN_EN : 0);

		ivhd->pci_segment_group = nb_dev->bus->segment_group;

		ivhd->iommu_info = pci_read_config16(iommu_dev,
			ivhd->capability_offset + 0x10) & 0x1F;
		ivhd->iommu_info |= (pci_read_config16(iommu_dev,
			ivhd->capability_offset + 0xC) & 0x1F) << IOMMU_INFO_UNIT_ID_SHIFT;

		ivhd->iommu_feature_info = 0;
		ivhd->iommu_feature_info |= (mmio_x30_value & MMIO_EXT_FEATURE_HATS_MASK)
			<< (IOMMU_FEATURE_HATS_SHIFT - MMIO_EXT_FEATURE_HATS_SHIFT);

		ivhd->iommu_feature_info |= (mmio_x30_value & MMIO_EXT_FEATURE_GATS_MASK)
			<< (IOMMU_FEATURE_GATS_SHIFT - MMIO_EXT_FEATURE_GATS_SHIFT);

		ivhd->iommu_feature_info |= (cap_offset_10 & CAP_OFFSET_10_MSI_NUM_PPR)
			>> (CAP_OFFSET_10_MSI_NUM_PPR_SHIFT
				- IOMMU_FEATURE_MSI_NUM_PPR_SHIFT);

		ivhd->iommu_feature_info |= (mmio_x4000_value &
			MMIO_CNT_CFG_N_COUNTER_BANKS)
			<< (IOMMU_FEATURE_PN_BANKS_SHIFT - MMIO_CNT_CFG_N_CNT_BANKS_SHIFT);

		ivhd->iommu_feature_info |= (mmio_x4000_value & MMIO_CNT_CFG_N_COUNTER)
			<< (IOMMU_FEATURE_PN_COUNTERS_SHIFT - MMIO_CNT_CFG_N_COUNTER_SHIFT);
		ivhd->iommu_feature_info |= (mmio_x30_value &
			MMIO_EXT_FEATURE_PAS_MAX_MASK)
			>> (MMIO_EXT_FEATURE_PAS_MAX_SHIFT - IOMMU_FEATURE_PA_SMAX_SHIFT);
		ivhd->iommu_feature_info |= ((mmio_x30_value & MMIO_EXT_FEATURE_HE_SUP)
			? IOMMU_FEATURE_HE_SUP : 0);
		ivhd->iommu_feature_info |= ((mmio_x30_value & MMIO_EXT_FEATURE_GA_SUP)
			? IOMMU_FEATURE_GA_SUP : 0);
		ivhd->iommu_feature_info |= ((mmio_x30_value & MMIO_EXT_FEATURE_IA_SUP)
			? IOMMU_FEATURE_IA_SUP : 0);
		ivhd->iommu_feature_info |= (mmio_x30_value &
			MMIO_EXT_FEATURE_GLX_SUP_MASK)
			>> (MMIO_EXT_FEATURE_GLX_SHIFT - IOMMU_FEATURE_GLX_SHIFT);
		ivhd->iommu_feature_info |= ((mmio_x30_value & MMIO_EXT_FEATURE_GT_SUP)
			? IOMMU_FEATURE_GT_SUP : 0);
		ivhd->iommu_feature_info |= ((mmio_x30_value & MMIO_EXT_FEATURE_NX_SUP)
			? IOMMU_FEATURE_NX_SUP : 0);
		ivhd->iommu_feature_info |= ((mmio_x30_value & MMIO_EXT_FEATURE_XT_SUP)
			? IOMMU_FEATURE_XT_SUP : 0);

		/* Enable EFR if supported */
		ivrs->iv_info = pci_read_config32(iommu_dev,
					ivhd->capability_offset + 0x10) & 0x007fffe0;
		if (pci_read_config32(iommu_dev,
					ivhd->capability_offset) & EFR_FEATURE_SUP)
			ivrs->iv_info |= IVINFO_EFR_SUPPORTED;


		current_backup = current;
		current = acpi_ivhd_misc(current, dev);
		ivhd->length += (current - current_backup);

		/* If EFR is not supported, IVHD type 11h is reserved */
		if (!(ivrs->iv_info & IVINFO_EFR_SUPPORTED))
			return current;

		current = acpi_fill_ivrs11(current, ivhd, nb_dev, iommu_dev);

		ivhd = (struct acpi_ivrs_ivhd *)current;
		current += sizeof(struct acpi_ivrs_ivhd);
	}
	current -= sizeof(struct acpi_ivrs_ivhd);

	return current;
}

unsigned long acpi_add_ivrs_table(unsigned long current, acpi_rsdp_t *rsdp)
{
	acpi_ivrs_t *ivrs;

	current = acpi_align_current(current);
	ivrs = (acpi_ivrs_t *)current;
	acpi_create_ivrs(ivrs, acpi_fill_ivrs);
	current += ivrs->header.length;
	acpi_add_table(rsdp, ivrs);

	return current;
}
