/*
 * Copyright (c) 2023 Intel Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include "acpi.h"
#include "accommon.h"
#include "acapps.h"
#include <aecommon.h>

#include <zephyr/drivers/pcie/pcie.h>
#include <zephyr/acpi/acpi.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(ACPI, CONFIG_ACPI_LOG_LEVEL);

static struct {
	struct acpi_dev child_dev[CONFIG_ACPI_DEV_MAX];
	int num_dev;
#ifdef CONFIG_PCIE_PRT
	ACPI_PCI_ROUTING_TABLE pci_prt_table[CONFIG_ACPI_MAX_PRT_ENTRY];
#endif
	bool early_init;
	ACPI_STATUS status;
} acpi = {
	.status = AE_NOT_CONFIGURED,
};

static int acpi_init(void);

static int check_init_status(void)
{
	if (acpi.status == AE_NOT_CONFIGURED) {
		acpi.status = acpi_init();
	}

	if (ACPI_SUCCESS(acpi.status)) {
		return 0;
	} else {
		LOG_ERR("ACPI init was not success");
		return -EIO;
	}
}

static void notify_handler(ACPI_HANDLE device, UINT32 value, void *ctx)
{
	ACPI_INFO(("Received a notify 0x%X", value));
}

static ACPI_STATUS install_handlers(void)
{
	ACPI_STATUS status;

	/* Install global notify handler */
	status = AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY, notify_handler,
					  NULL);
	if (ACPI_FAILURE(status)) {
		ACPI_EXCEPTION((AE_INFO, status, "While installing Notify handler"));
		goto exit;
	}

exit:
	return status;
}

static ACPI_STATUS initialize_acpica(void)
{
	ACPI_STATUS status;

	/* Initialize the ACPI subsystem */
	status = AcpiInitializeSubsystem();
	if (ACPI_FAILURE(status)) {
		ACPI_EXCEPTION((AE_INFO, status, "While initializing ACPI"));
		goto exit;
	}

	/* Initialize the ACPI Table Manager and get all ACPI tables */
	if (!acpi.early_init) {
		status = AcpiInitializeTables(NULL, 16, FALSE);
		if (ACPI_FAILURE(status)) {
			ACPI_EXCEPTION((AE_INFO, status, "While initializing Table Manager"));
			goto exit;
		}
	}

	/* Create the ACPI namespace from ACPI tables */
	status = AcpiLoadTables();
	if (ACPI_FAILURE(status)) {
		ACPI_EXCEPTION((AE_INFO, status, "While loading ACPI tables"));
		goto exit;
	}

	/* Install local handlers */
	status = install_handlers();
	if (ACPI_FAILURE(status)) {
		ACPI_EXCEPTION((AE_INFO, status, "While installing handlers"));
		goto exit;
	}

	/* Initialize the ACPI hardware */
	status = AcpiEnableSubsystem(ACPI_FULL_INITIALIZATION);
	if (ACPI_FAILURE(status)) {
		ACPI_EXCEPTION((AE_INFO, status, "While enabling ACPI"));
		goto exit;
	}

	/* Complete the ACPI namespace object initialization */
	status = AcpiInitializeObjects(ACPI_FULL_INITIALIZATION);
	if (ACPI_FAILURE(status)) {
		ACPI_EXCEPTION((AE_INFO, status, "While initializing ACPI objects"));
	}
exit:

	return status;
}

static ACPI_NAMESPACE_NODE *acpi_name_lookup(char *name)
{
	char *path;
	ACPI_STATUS status;
	ACPI_NAMESPACE_NODE *node;

	LOG_DBG("");

	status = AcpiNsInternalizeName(name, &path);
	if (ACPI_FAILURE(status)) {
		LOG_ERR("Invalid namestring: %s", name);
		return NULL;
	}

	status = AcpiNsLookup(NULL, path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
			      ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, NULL, &node);
	if (ACPI_FAILURE(status)) {
		LOG_ERR("Could not locate name: %s, %d", name, status);
		node = NULL;
	}

	ACPI_FREE(path);
	return node;
}

static ACPI_NAMESPACE_NODE *acpi_evaluate_method(char *bus_name, char *method)
{
	ACPI_NAMESPACE_NODE *node;
	ACPI_NAMESPACE_NODE *handle;
	ACPI_NAMESPACE_NODE *prt_node = NULL;

	LOG_DBG("%s", bus_name);

	handle = acpi_name_lookup(bus_name);
	if (!handle) {
		LOG_ERR("No ACPI node with given name: %s", bus_name);
		goto exit;
	}

	if (handle->Type != ACPI_TYPE_DEVICE) {
		LOG_ERR("No ACPI node foud with given name: %s", bus_name);
		goto exit;
	}

	node = ACPI_CAST_PTR(ACPI_NAMESPACE_NODE, handle);

	(void)AcpiGetHandle(node, method, ACPI_CAST_PTR(ACPI_HANDLE, &prt_node));

	if (!prt_node) {
		LOG_ERR("No entry for the ACPI node with given name: %s", bus_name);
		goto exit;
	}
	return node;
exit:
	return NULL;
}

static ACPI_STATUS acpi_enable_pic_mode(void)
{
	ACPI_STATUS status;
	ACPI_OBJECT_LIST arg_list;
	ACPI_OBJECT arg[1];

	arg_list.Count = 1;
	arg_list.Pointer = arg;

	arg[0].Type = ACPI_TYPE_INTEGER;
	arg[0].Integer.Value = 1;

	status = AcpiEvaluateObject(NULL, "\\_PIC", &arg_list, NULL);
	if (ACPI_FAILURE(status)) {
		LOG_WRN("error While executing \\_pic method: %d", status);
	}

	return status;
}

static ACPI_STATUS dev_resource_enum_callback(ACPI_HANDLE obj_handle, UINT32 level, void *ctx,
					      void **ret_value)
{
	ACPI_NAMESPACE_NODE *node;
	ACPI_BUFFER rt_buffer;
	struct acpi_dev *child_dev;

	node = ACPI_CAST_PTR(ACPI_NAMESPACE_NODE, obj_handle);
	char *path_name;
	ACPI_STATUS status;
	ACPI_DEVICE_INFO *dev_info;

	LOG_DBG("%s %p", __func__, node);

	/* get device info such as HID, Class ID etc. */
	status = AcpiGetObjectInfo(obj_handle, &dev_info);
	if (ACPI_FAILURE(status)) {
		LOG_ERR("AcpiGetObjectInfo failed: %s", AcpiFormatException(status));
		goto exit;
	}

	if (acpi.num_dev >= CONFIG_ACPI_DEV_MAX) {
		return AE_NO_MEMORY;
	}

	child_dev = (struct acpi_dev *)&acpi.child_dev[acpi.num_dev++];
	child_dev->handle = obj_handle;
	child_dev->dev_info = dev_info;

	path_name = AcpiNsGetNormalizedPathname(node, TRUE);
	if (!path_name) {
		LOG_ERR("No memory for path_name");
		goto exit;
	} else {
		LOG_DBG("Device path: %s", path_name);
		child_dev->path = path_name;
	}

	rt_buffer.Pointer = NULL;
	rt_buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;

	status = AcpiGetCurrentResources(node, &rt_buffer);
	if (ACPI_FAILURE(status)) {
		LOG_DBG("AcpiGetCurrentResources failed: %s", AcpiFormatException(status));
	} else {
		child_dev->res_lst = rt_buffer.Pointer;
	}

exit:

	return status;
}

static int acpi_enum_devices(void)
{
	LOG_DBG("");

	AcpiWalkNamespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
			  dev_resource_enum_callback, NULL, NULL, NULL);

	return 0;
}

static int acpi_early_init(void)
{
	ACPI_STATUS status;

	LOG_DBG("");

	if (acpi.early_init) {
		LOG_DBG("acpi early init already done");
		return 0;
	}

	status = AcpiInitializeTables(NULL, 16, FALSE);
	if (ACPI_FAILURE(status)) {
		LOG_ERR("Error in acpi table init:%d", status);
		return -EIO;
	}

	acpi.early_init = true;

	return 0;
}

int acpi_current_resource_get(char *dev_name, ACPI_RESOURCE **res)
{
	ACPI_BUFFER rt_buffer;
	ACPI_NAMESPACE_NODE *node;
	ACPI_STATUS status;

	LOG_DBG("%s", dev_name);

	status = check_init_status();
	if (status) {
		return -EAGAIN;
	}

	node = acpi_evaluate_method(dev_name, METHOD_NAME__CRS);
	if (!node) {
		LOG_ERR("Evaluation failed for given device: %s", dev_name);
		return -ENOTSUP;
	}

	rt_buffer.Pointer = NULL;
	rt_buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;

	status = AcpiGetCurrentResources(node, &rt_buffer);
	if (ACPI_FAILURE(status)) {
		LOG_ERR("AcpiGetCurrentResources failed: %s", AcpiFormatException(status));
		return -ENOTSUP;
	} else {
		*res = rt_buffer.Pointer;
	}

	return 0;
}

int acpi_possible_resource_get(char *dev_name, ACPI_RESOURCE **res)
{
	ACPI_BUFFER rt_buffer;
	ACPI_NAMESPACE_NODE *node;
	ACPI_STATUS status;

	LOG_DBG("%s", dev_name);

	status = check_init_status();
	if (status) {
		return -EAGAIN;
	}

	node = acpi_evaluate_method(dev_name, METHOD_NAME__PRS);
	if (!node) {
		LOG_ERR("Evaluation failed for given device: %s", dev_name);
		return -ENOTSUP;
	}

	rt_buffer.Pointer = NULL;
	rt_buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;

	AcpiGetPossibleResources(node, &rt_buffer);
	*res = rt_buffer.Pointer;

	return 0;
}

int acpi_current_resource_free(ACPI_RESOURCE *res)
{
	ACPI_FREE(res);

	return 0;
}

#ifdef CONFIG_PCIE_PRT
static int acpi_get_irq_table(char *bus_name, ACPI_PCI_ROUTING_TABLE *rt_table, uint32_t rt_size)
{
	ACPI_BUFFER rt_buffer;
	ACPI_NAMESPACE_NODE *node;
	ACPI_STATUS status;

	LOG_DBG("%s", bus_name);

	node = acpi_evaluate_method(bus_name, METHOD_NAME__PRT);
	if (!node) {
		LOG_ERR("Evaluation failed for given device: %s", bus_name);
		return -ENODEV;
	}

	rt_buffer.Pointer = rt_table;
	rt_buffer.Length = rt_size * sizeof(ACPI_PCI_ROUTING_TABLE);

	status = AcpiGetIrqRoutingTable(node, &rt_buffer);
	if (ACPI_FAILURE(status)) {
		LOG_ERR("unable to retrieve IRQ Routing Table: %s", bus_name);
		return -EIO;
	}

	return 0;
}

static int acpi_retrieve_legacy_irq(void)
{
	int ret;

	/* TODO: assume platform have only one PCH with single PCI bus (bus 0). */
	ret = acpi_get_irq_table(CONFIG_ACPI_PRT_BUS_NAME,
				 acpi.pci_prt_table, ARRAY_SIZE(acpi.pci_prt_table));
	if (ret) {
		return ret;
	}

	for (size_t i = 0; i < ARRAY_SIZE(acpi.pci_prt_table); i++) {
		if (!acpi.pci_prt_table[i].SourceIndex) {
			break;
		}
		if (IS_ENABLED(CONFIG_X86_64)) {
			/* mark the PRT irq numbers as reserved. */
			arch_irq_set_used(acpi.pci_prt_table[i].SourceIndex);
		}
	}

	return 0;

}

int acpi_get_irq_routing_table(char *bus_name,
			       ACPI_PCI_ROUTING_TABLE *rt_table, size_t rt_size)
{
	int ret;

	ret = check_init_status();
	if (ret) {
		return ret;
	}

	return acpi_get_irq_table(bus_name, rt_table, rt_size);
}

uint32_t acpi_legacy_irq_get(pcie_bdf_t bdf)
{
	uint32_t slot = PCIE_BDF_TO_DEV(bdf), pin;

	LOG_DBG("");

	if (check_init_status()) {
		return UINT_MAX;
	}

	pin = (pcie_conf_read(bdf, PCIE_CONF_INTR) >> 8) & 0x3;

	LOG_DBG("Device irq info: slot:%d pin:%d", slot, pin);

	for (int i = 0; i < CONFIG_ACPI_MAX_PRT_ENTRY; i++) {
		if (((acpi.pci_prt_table[i].Address >> 16) & 0xffff) == slot &&
		    acpi.pci_prt_table[i].Pin + 1 == pin) {
			LOG_DBG("[%d]Device irq info: slot:%d pin:%d irq:%d", i, slot, pin,
				acpi.pci_prt_table[i].SourceIndex);
			return acpi.pci_prt_table[i].SourceIndex;
		}
	}

	return UINT_MAX;
}
#endif /* CONFIG_PCIE_PRT */

ACPI_RESOURCE *acpi_resource_parse(ACPI_RESOURCE *res, int res_type)
{
	do {
		if (!res->Length) {
			LOG_DBG("Error: zero length found!");
			break;
		} else if (res->Type == res_type) {
			break;
		}
		res = ACPI_NEXT_RESOURCE(res);
	} while (res->Type != ACPI_RESOURCE_TYPE_END_TAG);

	if (res->Type == ACPI_RESOURCE_TYPE_END_TAG) {
		return NULL;
	}

	return res;
}

static int acpi_res_type(ACPI_RESOURCE *res)
{
	int type;

	switch (res->Type) {
	case ACPI_RESOURCE_TYPE_IO:
		type = ACPI_RESOURCE_TYPE_IO;
		break;
	case ACPI_RESOURCE_TYPE_FIXED_IO:
		type = ACPI_RESOURCE_TYPE_FIXED_IO;
		break;
	case ACPI_RESOURCE_TYPE_MEMORY24:
		type = ACPI_RESOURCE_TYPE_MEMORY24;
		break;
	case ACPI_RESOURCE_TYPE_MEMORY32:
		type = ACPI_RESOURCE_TYPE_MEMORY32;
		break;
	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
		type = ACPI_RESOURCE_TYPE_FIXED_MEMORY32;
		break;
	case ACPI_RESOURCE_TYPE_ADDRESS16:
		type = ACPI_RESOURCE_TYPE_ADDRESS16;
		break;
	case ACPI_RESOURCE_TYPE_ADDRESS32:
		type = ACPI_RESOURCE_TYPE_ADDRESS32;
		break;
	case ACPI_RESOURCE_TYPE_ADDRESS64:
		type = ACPI_RESOURCE_TYPE_ADDRESS64;
		break;
	case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
		type = ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64;
		break;
	default:
		type = ACPI_RESOURCE_TYPE_MAX;
	}

	return type;
}

int acpi_device_type_get(ACPI_RESOURCE *res)
{
	int type = ACPI_RESOURCE_TYPE_MAX;

	do {
		if (!res->Length) {
			LOG_ERR("Error: zero length found!");
			break;
		}
		type = acpi_res_type(res);
		if (type != ACPI_RESOURCE_TYPE_MAX) {
			break;
		}
		res = ACPI_NEXT_RESOURCE(res);
	} while (res->Type != ACPI_RESOURCE_TYPE_END_TAG);

	return type;
}

struct acpi_dev *acpi_device_get(char *hid, int inst)
{
	struct acpi_dev *child_dev;
	int i = 0, inst_id;

	LOG_DBG("");

	if (check_init_status()) {
		return NULL;
	}

	do {
		child_dev = &acpi.child_dev[i];
		if (!child_dev->path) {
			LOG_DBG("NULL device path found");
			continue;
		}

		if (!child_dev->res_lst || !child_dev->dev_info ||
		    !child_dev->dev_info->HardwareId.Length) {
			continue;
		}

		if (!strcmp(hid, child_dev->dev_info->HardwareId.String)) {
			if (child_dev->dev_info->UniqueId.Length) {
				inst_id = atoi(child_dev->dev_info->UniqueId.String);
				if (inst_id == inst) {
					return child_dev;
				}
			} else {
				return child_dev;
			}
		}
	} while (i++ < acpi.num_dev);

	return NULL;
}

struct acpi_dev *acpi_device_by_index_get(int index)
{
	return index < acpi.num_dev ? &acpi.child_dev[index] : NULL;
}

void *acpi_table_get(char *signature, int inst)
{
	ACPI_STATUS status;
	ACPI_TABLE_HEADER *table;

	if (!acpi.early_init) {
		status = acpi_early_init();
		if (status) {
			LOG_ERR("ACPI early init failed");
			return NULL;
		}
	}

	status = AcpiGetTable(signature, inst, &table);
	if (ACPI_FAILURE(status)) {
		LOG_ERR("ACPI get table failed: %d", status);
		return NULL;
	}

	return (void *)table;
}

static uint32_t acpi_get_subtable_entry_num(int type, ACPI_SUBTABLE_HEADER *subtable,
					    uintptr_t offset, uintptr_t base, uint32_t madt_len)
{
	uint32_t subtable_cnt = 0;

	while (offset < madt_len) {
		if (type == subtable->Type) {
			subtable_cnt++;
		}
		offset += subtable->Length;
		subtable = ACPI_ADD_PTR(ACPI_SUBTABLE_HEADER, base, offset);

		if (!subtable->Length) {
			break;
		}
	}

	return subtable_cnt;
}

int acpi_madt_entry_get(int type, ACPI_SUBTABLE_HEADER **tables, int *num_inst)
{
	ACPI_TABLE_HEADER *madt = acpi_table_get("APIC", 0);
	uintptr_t base = POINTER_TO_UINT(madt);
	uintptr_t offset = sizeof(ACPI_TABLE_MADT);
	ACPI_SUBTABLE_HEADER *subtable;

	if (!madt) {
		return -EIO;
	}

	subtable = ACPI_ADD_PTR(ACPI_SUBTABLE_HEADER, base, offset);
	while (offset < madt->Length) {

		if (type == subtable->Type) {
			*tables = subtable;
			*num_inst = acpi_get_subtable_entry_num(type, subtable, offset, base,
								madt->Length);
			return 0;
		}

		offset += subtable->Length;
		subtable = ACPI_ADD_PTR(ACPI_SUBTABLE_HEADER, base, offset);
	}

	return -ENODEV;
}

int acpi_dmar_entry_get(enum AcpiDmarType type, ACPI_SUBTABLE_HEADER **tables)
{
	struct acpi_table_dmar *dmar = acpi_table_get("DMAR", 0);
	uintptr_t base = POINTER_TO_UINT(dmar);
	uintptr_t offset = sizeof(ACPI_TABLE_DMAR);
	ACPI_DMAR_HEADER *subtable;

	if (!dmar) {
		LOG_ERR("error on get DMAR table");
		return -EIO;
	}

	subtable = ACPI_ADD_PTR(ACPI_DMAR_HEADER, base, offset);
	while (offset < dmar->Header.Length) {
		if (type == subtable->Type) {
			*tables = (struct acpi_subtable_header *)subtable;
			return 0;
		}
		offset += subtable->Length;
		subtable = ACPI_ADD_PTR(ACPI_DMAR_HEADER, base, offset);
	}

	return -ENODEV;
}

int acpi_drhd_get(enum AcpiDmarScopeType scope, ACPI_DMAR_DEVICE_SCOPE *dev_scope,
		  union acpi_dmar_id *dmar_id, int *num_inst, int max_inst)
{
	uintptr_t offset = sizeof(ACPI_DMAR_HARDWARE_UNIT);
	uint32_t i = 0;
	ACPI_DMAR_HEADER *drdh;
	ACPI_DMAR_DEVICE_SCOPE *subtable;
	ACPI_DMAR_PCI_PATH *dev_path;
	int ret;
	uintptr_t base;
	int scope_size;

	ret = acpi_dmar_entry_get(ACPI_DMAR_TYPE_HARDWARE_UNIT,
				  (ACPI_SUBTABLE_HEADER **)&drdh);
	if (ret) {
		LOG_ERR("Error on retrieve DMAR table");
		return ret;
	}

	scope_size = drdh->Length - sizeof(ACPI_DMAR_HARDWARE_UNIT);
	base = (uintptr_t)((uintptr_t)drdh + offset);

	offset = 0;

	while (scope_size) {
		int num_path;

		subtable = ACPI_ADD_PTR(ACPI_DMAR_DEVICE_SCOPE, base, offset);
		if (!subtable->Length) {
			break;
		}

		if (scope == subtable->EntryType) {
			num_path = (subtable->Length - 6u) / 2u;
			dev_path = ACPI_ADD_PTR(ACPI_DMAR_PCI_PATH, subtable,
				sizeof(ACPI_DMAR_DEVICE_SCOPE));

			while (num_path--) {
				if (i >= max_inst) {
					LOG_ERR("DHRD not enough buffer size");
					return -ENOBUFS;
				}
				dmar_id[i].bits.bus = subtable->Bus;
				dmar_id[i].bits.device = dev_path[i].Device;
				dmar_id[i].bits.function = dev_path[i].Function;
				i++;
			}
			break;
		}

		offset += subtable->Length;

		if (scope_size < subtable->Length) {
			break;
		}
		scope_size -= subtable->Length;
	}

	*num_inst = i;
	if (!i) {
		LOG_ERR("Error on retrieve DRHD Info");
		return -ENODEV;
	}

	if (dev_scope && subtable) {
		memcpy(dev_scope, subtable, sizeof(struct acpi_dmar_device_scope));
	}

	return 0;
}

#define ACPI_CPU_FLAGS_ENABLED 0x01u

ACPI_MADT_LOCAL_APIC *acpi_local_apic_get(int cpu_num)
{
	ACPI_MADT_LOCAL_APIC *lapic;
	int cpu_cnt;
	int idx;

	if (acpi_madt_entry_get(ACPI_MADT_TYPE_LOCAL_APIC, (ACPI_SUBTABLE_HEADER **)&lapic,
				&cpu_cnt)) {
		/* Error on MAD table. */
		return NULL;
	}

	for (idx = 0; cpu_num >= 0 && idx < cpu_cnt; idx++) {
		if (lapic[idx].LapicFlags & ACPI_CPU_FLAGS_ENABLED) {
			if (cpu_num == 0) {
				return &lapic[idx];
			}

			cpu_num--;
		}
	}

	return NULL;
}

static int acpi_init(void)
{
	ACPI_STATUS status;

	LOG_DBG("");

	/* For debug version only */
	ACPI_DEBUG_INITIALIZE();

	status = initialize_acpica();
	if (ACPI_FAILURE(status)) {
		LOG_ERR("Error in ACPI init:%d", status);
		goto exit;
	}

	/* Enable IO APIC mode */
	status = acpi_enable_pic_mode();
	if (ACPI_FAILURE(status)) {
		LOG_WRN("Error in enable pic mode acpi method:%d", status);
	}

#ifdef CONFIG_PCIE_PRT
	int ret = acpi_retrieve_legacy_irq();

	if (ret) {
		LOG_ERR("Error in retrieve legacy interrupt info:%d", ret);
		status = AE_ERROR;
		goto exit;
	}
#endif

	acpi_enum_devices();

exit:
	return status;
}
