/*
 * SPDX-License-Identifier: Apache-2.0
 * Copyright (c) 2019 Intel Corp.
 */

#include <zephyr.h>
#include <arch/x86/acpi.h>

static void vtd_dev_scope_info(struct acpi_dmar_dev_scope *dev_scope)
{
	struct acpi_dmar_dev_path *path;
	int n_path;

	printk("\t\t\t. Type: ");

	switch (dev_scope->type) {
	case ACPI_DRHD_DEV_SCOPE_PCI_EPD:
		printk("PCI Endpoint");
		break;
	case ACPI_DRHD_DEV_SCOPE_PCI_SUB_H:
		printk("PCI Sub-hierarchy");
		break;
	case ACPI_DRHD_DEV_SCOPE_IOAPIC:
		printk("IOAPIC");
		break;
	case ACPI_DRHD_DEV_SCOPE_MSI_CAP_HPET:
		printk("MSI Capable HPET");
		break;
	case ACPI_DRHD_DEV_SCOPE_NAMESPACE_DEV:
		printk("ACPI name-space enumerated");
		break;
	default:
		printk("unknown\n");
		return;
	}

	printk("\n");

	printk("\t\t\t. Enumeration ID %u\n", dev_scope->enumeration_id);
	printk("\t\t\t. PCI Bus %u\n", dev_scope->start_bus_num);

	path = z_acpi_get_dev_scope_paths(dev_scope, &n_path);
	for (; n_path > 0; n_path--) {
		printk("\t\t\t. Path D:%u F:%u\n",
		       path->device, path->function);
		path = (struct acpi_dmar_dev_path *)(POINTER_TO_UINT(path) +
						     ACPI_DMAR_DEV_PATH_SIZE);
	}

	printk("\n");
}

static void vtd_drhd_info(struct acpi_drhd *drhd)
{
	struct acpi_dmar_dev_scope *dev_scope;
	int n_ds, i;

	if (drhd->flags & ACPI_DRHD_FLAG_INCLUDE_PCI_ALL) {
		printk("\t\t- Includes all PCI devices");
	} else {
		printk("\t\t- Includes only listed PCI devices");
	}

	printk(" under given Segment\n");

	printk("\t\t- Segment number %u\n", drhd->segment_num);
	printk("\t\t- Base Address 0x%llx\n", drhd->base_address);

	dev_scope = z_acpi_get_drhd_dev_scopes(drhd, &n_ds);
	if (dev_scope == NULL) {
		printk("\t\t- No device scopes\n");
		return;
	}

	printk("\t\t- Device Scopes:\n");
	for (i = 0; i < n_ds; i++) {
		vtd_dev_scope_info(dev_scope);
		dev_scope = (struct acpi_dmar_dev_scope *)(
			POINTER_TO_UINT(dev_scope) + dev_scope->length);
	}

	printk("\n");
}

static void vtd_info(void)
{
	struct acpi_dmar *dmar;

	dmar = z_acpi_find_dmar();
	if (dmar == NULL) {
		printk("\tIntel VT-D not supported or exposed\n");
		return;
	}

	printk("\tIntel VT-D Supported:\n");

	printk("\t-> X2APIC ");
	if (dmar->flags & ACPI_DMAR_FLAG_X2APIC_OPT_OUT) {
		printk("should be opted out\n");
	} else {
		printk("does not need to be opted out\n");
	}

	if (dmar->flags & ACPI_DMAR_FLAG_INTR_REMAP) {
		struct acpi_drhd *drhd;
		int hw_n, i;

		printk("\t-> Interrupt remapping supported\n");

		drhd = z_acpi_find_drhds(&hw_n);
		printk("\t-> %u remapping hardware found:\n", hw_n);

		for (i = 0; i < hw_n; i++) {
			printk("\t\tDRHD %u:\n", i);
			vtd_drhd_info(drhd);
			drhd = (struct acpi_drhd *)(POINTER_TO_UINT(drhd) +
						    drhd->entry.length);
		}
	} else {
		printk("\t-> Interrupt remapping not supported\n");
	}
}

void acpi(void)
{
	int nr_cpus;

	for (nr_cpus = 0; z_acpi_get_cpu(nr_cpus); ++nr_cpus) {
		/* count number of CPUs present */
	}

	if (nr_cpus == 0) {
		printk("ACPI: no RSDT/MADT found\n\n");
	} else {
		printk("ACPI: %d CPUs found\n", nr_cpus);

		for (int i = 0; i < nr_cpus; ++i) {
			struct acpi_cpu *cpu = z_acpi_get_cpu(i);
			printk("\tCPU #%d: APIC ID 0x%02x\n", i, cpu->apic_id);
		}
	}

	printk("\n");

	vtd_info();

	printk("\n");
}
