/*
 * 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);

#if defined(CONFIG_ACPI_POWEROFF)

/* PM1_CNT register */
#if (defined(CONFIG_BOARD_QEMU_X86_64) || defined(CONFIG_BOARD_QEMU_X86))
#define PM1_CNT_SLP_TYP_S5 0x00 /* S5 SLP_TYP is 0 in QEMU */
#elif defined(CONFIG_ACRN_COMMON)
#define PM1_CNT_SLP_TYP_S5 0x05 /* S5 SLP_TYP is 5 in ACRN */
#else
#define PM1_CNT_SLP_TYP_S5 0x07 /* S5 SLP_TYP is 7 in other platforms*/
#endif

#define PM1_CNT_SLP_TYP_SHFT 0x0A /* SLP_TYP bits(10-12) in PM1_CNT */

#define PM1_CNT_SLP_EN BIT(13) /* Sets SLP_EN bit13 */

#endif /* CONFIG_ACPI_POWEROFF */

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_FAILURE(acpi.status)) {
		LOG_ERR("ACPI init was not success");
		return -EIO;
	}

	return 0;
}

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;
	}

	if (!(dev_info->Valid & ACPI_VALID_HID)) {
		goto exit;
	}

	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 AE_OK;
}

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;
	}

	*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
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;
}

int acpi_legacy_irq_init(const char *hid, const char *uid)
{
	struct acpi_dev *child_dev = acpi_device_get(hid, uid);
	ACPI_PCI_ROUTING_TABLE *rt_table = acpi.pci_prt_table;
	ACPI_BUFFER rt_buffer;
	ACPI_NAMESPACE_NODE *node;
	ACPI_STATUS status;

	if (!child_dev) {
		LOG_ERR("no such PCI bus device %s %s", hid, uid);
		return -ENODEV;
	}

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

	rt_buffer.Pointer = rt_table;
	rt_buffer.Length = ARRAY_SIZE(acpi.pci_prt_table) * sizeof(ACPI_PCI_ROUTING_TABLE);

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

	if (rt_table->Source[0]) {
		/*
		 * If Name path exist then PCI interrupts are configurable and are not hardwired to
		 * any specific interrupt inputs on the interrupt controller. OSPM can uses
		 * _PRS/_CRS/_SRS to configure interrupts. But currently leave existing PCI bus
		 * driver with arch_irq_allocate() method for allocate and configure interrupts
		 * without conflicting.
		 */
		return -ENOENT;
	}

	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;
}
#endif /* CONFIG_PCIE_PRT */

ACPI_RESOURCE *acpi_resource_parse(ACPI_RESOURCE *res, int res_type)
{
	do {
		if (!res->Length) {
			LOG_DBG("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;
}

int acpi_device_irq_get(struct acpi_dev *child_dev, struct acpi_irq_resource *irq_res)
{
	ACPI_RESOURCE *res = acpi_resource_parse(child_dev->res_lst, ACPI_RESOURCE_TYPE_IRQ);

	if (!res) {
		res = acpi_resource_parse(child_dev->res_lst, ACPI_RESOURCE_TYPE_EXTENDED_IRQ);
		if (!res) {
			return -ENODEV;
		}

		if (res->Data.ExtendedIrq.InterruptCount > irq_res->irq_vector_max) {
			return -ENOMEM;
		}

		irq_res->irq_vector_max = res->Data.ExtendedIrq.InterruptCount;
		for (int i = 0; i < irq_res->irq_vector_max; i++) {
			irq_res->irqs[i] = (uint16_t)res->Data.ExtendedIrq.Interrupts[i];
		}

		irq_res->flags = arch_acpi_encode_irq_flags(res->Data.ExtendedIrq.Polarity,
							    res->Data.ExtendedIrq.Triggering);
	} else {
		if (res->Data.Irq.InterruptCount > irq_res->irq_vector_max) {
			return -ENOMEM;
		}

		irq_res->irq_vector_max = res->Data.Irq.InterruptCount;
		for (int i = 0; i < irq_res->irq_vector_max; i++) {
			irq_res->irqs[i] = (uint16_t)res->Data.Irq.Interrupts[i];
		}

		irq_res->flags = arch_acpi_encode_irq_flags(res->Data.ExtendedIrq.Polarity,
							    res->Data.ExtendedIrq.Triggering);
	}

	return 0;
}

int acpi_device_mmio_get(struct acpi_dev *child_dev, struct acpi_mmio_resource *mmio_res)
{
	ACPI_RESOURCE *res = child_dev->res_lst;
	struct acpi_reg_base *reg_base = mmio_res->reg_base;
	int mmio_cnt = 0;

	do {
		if (!res->Length) {
			LOG_DBG("Found Acpi resource with zero length!");
			break;
		}

		switch (res->Type) {
		case ACPI_RESOURCE_TYPE_IO:
			reg_base[mmio_cnt].type = ACPI_RES_TYPE_IO;
			reg_base[mmio_cnt].port = (uint32_t)res->Data.Io.Minimum;
			reg_base[mmio_cnt++].length = res->Data.Io.AddressLength;
			break;

		case ACPI_RESOURCE_TYPE_FIXED_IO:
			reg_base[mmio_cnt].type = ACPI_RES_TYPE_IO;
			reg_base[mmio_cnt].port = (uint32_t)res->Data.FixedIo.Address;
			reg_base[mmio_cnt++].length = res->Data.FixedIo.AddressLength;
			break;

		case ACPI_RESOURCE_TYPE_MEMORY24:
			reg_base[mmio_cnt].type = ACPI_RES_TYPE_MEM;
			reg_base[mmio_cnt].mmio = (uintptr_t)res->Data.Memory24.Minimum;
			reg_base[mmio_cnt++].length = res->Data.Memory24.AddressLength;
			break;

		case ACPI_RESOURCE_TYPE_MEMORY32:
			reg_base[mmio_cnt].type = ACPI_RES_TYPE_MEM;
			reg_base[mmio_cnt].mmio = (uintptr_t)res->Data.Memory32.Minimum;
			reg_base[mmio_cnt++].length = res->Data.Memory32.AddressLength;
			break;

		case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
			reg_base[mmio_cnt].type = ACPI_RES_TYPE_MEM;
			reg_base[mmio_cnt].mmio = (uintptr_t)res->Data.FixedMemory32.Address;
			reg_base[mmio_cnt++].length = res->Data.FixedMemory32.AddressLength;
			break;
		case ACPI_RESOURCE_TYPE_ADDRESS64:
			reg_base[mmio_cnt].type = ACPI_RES_TYPE_MEM;
			reg_base[mmio_cnt].mmio = (uintptr_t)res->Data.Address64.Address.Minimum;
			reg_base[mmio_cnt++].length = res->Data.Address64.Address.AddressLength;
			break;
		}

		res = ACPI_NEXT_RESOURCE(res);
		if (mmio_cnt >= mmio_res->mmio_max &&
			 res->Type != ACPI_RESOURCE_TYPE_END_TAG) {
			return -ENOMEM;
		}
	} while (res->Type != ACPI_RESOURCE_TYPE_END_TAG);

	if (!mmio_cnt) {
		return -ENODEV;
	}

	mmio_res->mmio_max = mmio_cnt;

	return 0;
}

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(const char *hid, const char *uid)
{
	struct acpi_dev *child_dev;
	int i = 0;

	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 (uid && child_dev->dev_info->UniqueId.Length) {
				if (!strcmp(child_dev->dev_info->UniqueId.String, uid)) {
					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;
}

void acpi_dmar_foreach_subtable(ACPI_TABLE_DMAR *dmar,
				dmar_foreach_subtable_func_t func, void *arg)
{
	uint16_t length = dmar->Header.Length;
	uintptr_t offset = sizeof(ACPI_TABLE_DMAR);

	__ASSERT_NO_MSG(length >= offset);

	while (offset < length) {
		ACPI_DMAR_HEADER *subtable = ACPI_ADD_PTR(ACPI_DMAR_HEADER, dmar, offset);

		__ASSERT_NO_MSG(subtable->Length >= sizeof(*subtable));
		__ASSERT_NO_MSG(subtable->Length <= length - offset);

		func(subtable, arg);

		offset += subtable->Length;
	}
}

void acpi_dmar_foreach_devscope(ACPI_DMAR_HARDWARE_UNIT *hu,
				dmar_foreach_devscope_func_t func, void *arg)
{
	uint16_t length = hu->Header.Length;
	uintptr_t offset = sizeof(ACPI_DMAR_HARDWARE_UNIT);

	__ASSERT_NO_MSG(length >= offset);

	while (offset < length) {
		ACPI_DMAR_DEVICE_SCOPE *devscope = ACPI_ADD_PTR(ACPI_DMAR_DEVICE_SCOPE,
								hu, offset);

		__ASSERT_NO_MSG(devscope->Length >= sizeof(*devscope));
		__ASSERT_NO_MSG(devscope->Length <= length - offset);

		func(devscope, arg);

		offset += devscope->Length;
	}
}

static void devscope_handler(ACPI_DMAR_DEVICE_SCOPE *devscope, void *arg)
{
	ACPI_DMAR_PCI_PATH *dev_path;
	union acpi_dmar_id pci_path;

	ARG_UNUSED(arg); /* may be unused */

	if (devscope->EntryType == ACPI_DMAR_SCOPE_TYPE_IOAPIC) {
		uint16_t *ioapic_id = arg;

		dev_path = ACPI_ADD_PTR(ACPI_DMAR_PCI_PATH, devscope,
					sizeof(ACPI_DMAR_DEVICE_SCOPE));

		/* Get first entry */
		pci_path.bits.bus = devscope->Bus;
		pci_path.bits.device = dev_path->Device;
		pci_path.bits.function = dev_path->Function;

		*ioapic_id = pci_path.raw;
	}
}

static void subtable_handler(ACPI_DMAR_HEADER *subtable, void *arg)
{
	ARG_UNUSED(arg); /* may be unused */

	if (subtable->Type == ACPI_DMAR_TYPE_HARDWARE_UNIT) {
		ACPI_DMAR_HARDWARE_UNIT *hu;

		hu = CONTAINER_OF(subtable, ACPI_DMAR_HARDWARE_UNIT, Header);
		acpi_dmar_foreach_devscope(hu, devscope_handler, arg);
	}
}

int acpi_dmar_ioapic_get(uint16_t *ioapic_id)
{
	ACPI_TABLE_DMAR *dmar = acpi_table_get("DMAR", 0);
	uint16_t found_ioapic = USHRT_MAX;

	if (dmar == NULL) {
		return -ENODEV;
	}

	acpi_dmar_foreach_subtable(dmar, subtable_handler, &found_ioapic);
	if (found_ioapic != USHRT_MAX) {
		*ioapic_id = found_ioapic;
		return 0;
	}

	return -ENOENT;
}

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;
}

int acpi_invoke_method(char *path, ACPI_OBJECT_LIST *arg_list, ACPI_OBJECT *ret_obj)
{
	ACPI_STATUS status;
	ACPI_BUFFER ret_buff;

	ret_buff.Length = sizeof(*ret_obj);
	ret_buff.Pointer = ret_obj;

	status = AcpiEvaluateObject(NULL, path, arg_list, &ret_buff);
	if (ACPI_FAILURE(status)) {
		LOG_ERR("error While executing %s method: %d", path, status);
		return -EIO;
	}

	return 0;
}

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);
	}

	acpi_enum_devices();

exit:
	return status;
}

#if defined(CONFIG_ACPI_POWEROFF)

int acpi_poweroff(void)
{
	ACPI_STATUS status;
	uintptr_t pm1_cnt_addr;
	uint32_t pm1_cnt;

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

	if (!AcpiGbl_FADT.Pm1aControlBlock) {
		return -EINVAL;
	}

	pm1_cnt_addr = AcpiGbl_FADT.Pm1aControlBlock;

	pm1_cnt = sys_in16(pm1_cnt_addr);
	pm1_cnt |= ((PM1_CNT_SLP_TYP_S5 << PM1_CNT_SLP_TYP_SHFT) | PM1_CNT_SLP_EN);
	sys_out16(pm1_cnt, pm1_cnt_addr);

	return 0;
}

#endif /* CONFIG_ACPI_POWEROFF */
