/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * coreboot ACPI Table support
 */

/*
 * Each system port implementing ACPI has to provide two functions:
 *
 *   write_acpi_tables()
 *   acpi_dump_apics()
 *
 * See Kontron 986LCD-M port for a good example of an ACPI implementation
 * in coreboot.
 */

#include <acpi/acpi.h>
#include <acpi/acpi_iort.h>
#include <acpi/acpi_ivrs.h>
#include <acpi/acpigen.h>
#include <cbfs.h>
#include <cbmem.h>
#include <commonlib/helpers.h>
#include <console/console.h>
#include <cpu/cpu.h>
#include <device/device.h>
#include <device/mmio.h>
#include <device/pci.h>
#include <drivers/uart/pl011.h>
#include <string.h>
#include <types.h>
#include <version.h>

static acpi_rsdp_t *valid_rsdp(acpi_rsdp_t *rsdp);

u8 acpi_checksum(u8 *table, u32 length)
{
	u8 ret = 0;
	while (length--) {
		ret += *table;
		table++;
	}
	return -ret;
}

/**
 * Add an ACPI table to the RSDT (and XSDT) structure, recalculate length
 * and checksum.
 */
void acpi_add_table(acpi_rsdp_t *rsdp, void *table)
{
	int i, entries_num;
	acpi_rsdt_t *rsdt;
	acpi_xsdt_t *xsdt;

	/* The 32bit RSDT may not be valid if tables live above 4GiB */
	rsdt = (acpi_rsdt_t *)(uintptr_t)rsdp->rsdt_address;
	xsdt = (acpi_xsdt_t *)(uintptr_t)rsdp->xsdt_address;

	/* This should always be MAX_ACPI_TABLES. */
	entries_num = ARRAY_SIZE(xsdt->entry);

	for (i = 0; i < entries_num; i++) {
		if (xsdt->entry[i] == 0)
			break;
	}

	if (i >= entries_num) {
		printk(BIOS_ERR, "ACPI: Error: Could not add ACPI table, "
			"too many tables.\n");
		return;
	}

	/* Add table to the XSDT. */
	xsdt->entry[i] = (u64)(uintptr_t)table;

	/* Fix XSDT length or the kernel will assume invalid entries. */
	xsdt->header.length = sizeof(acpi_header_t) + (sizeof(u64) * (i + 1));

	/* Re-calculate checksum. */
	xsdt->header.checksum = 0; /* Hope this won't get optimized away */
	xsdt->header.checksum = acpi_checksum((u8 *)xsdt, xsdt->header.length);

	/*
	 * And now the same thing for the RSDT. We use the same index as for
	 * now we want the XSDT and RSDT to always be in sync in coreboot.
	 */
	if (rsdt && (uintptr_t)table < UINT32_MAX) {
		/* Add table to the RSDT. */
		rsdt->entry[i] = (u32)(uintptr_t)table;

		/* Fix RSDT length. */
		rsdt->header.length = sizeof(acpi_header_t) + (sizeof(u32) * (i + 1));

		/* Re-calculate checksum. */
		rsdt->header.checksum = 0;
		rsdt->header.checksum = acpi_checksum((u8 *)rsdt, rsdt->header.length);
	}

	printk(BIOS_DEBUG, "ACPI: added table %d/%d, length now %d\n",
		i + 1, entries_num, xsdt->header.length);
}

static enum cb_err acpi_fill_header(acpi_header_t *header, const char name[4],
				    enum acpi_tables table, uint32_t size)
{
	if (!header)
		return CB_ERR;

	/* Fill out header fields. */
	memcpy(header->signature, name, 4);
	memcpy(header->oem_id, OEM_ID, 6);
	memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
	memcpy(header->asl_compiler_id, ASLC, 4);

	header->asl_compiler_revision = asl_revision;
	header->revision = get_acpi_table_revision(table);
	header->length = size;

	return CB_SUCCESS;
}

static int acpi_create_mcfg_mmconfig(acpi_mcfg_mmconfig_t *mmconfig, u64 base,
				u16 seg_nr, u8 start, u8 end)
{
	memset(mmconfig, 0, sizeof(*mmconfig));
	mmconfig->base_address = base;
	mmconfig->pci_segment_group_number = seg_nr;
	mmconfig->start_bus_number = start;
	mmconfig->end_bus_number = end;

	return sizeof(acpi_mcfg_mmconfig_t);
}

static void acpi_create_madt(acpi_header_t *header, void *unused)
{
	acpi_madt_t *madt = (acpi_madt_t *)header;
	unsigned long current = (unsigned long)madt + sizeof(acpi_madt_t);

	if (acpi_fill_header(header, "APIC", MADT, sizeof(acpi_madt_t)) != CB_SUCCESS)
		return;

	current = acpi_arch_fill_madt(madt, current);

	if (CONFIG(ACPI_CUSTOM_MADT))
		current = acpi_fill_madt(current);

	/* (Re)calculate length . */
	header->length = current - (unsigned long)madt;
}

static unsigned long acpi_fill_mcfg(unsigned long current)
{
	for (int i = 0; i < PCI_SEGMENT_GROUP_COUNT; i++) {
		current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *)current,
			CONFIG_ECAM_MMCONF_BASE_ADDRESS + i * PCI_PER_SEGMENT_GROUP_ECAM_SIZE,
			i,
			0,
			PCI_BUSES_PER_SEGMENT_GROUP - 1);
	}

	return current;
}

/* MCFG is defined in the PCI Firmware Specification 3.0. */
static void acpi_create_mcfg(acpi_header_t *header, void *unused)
{
	acpi_mcfg_t *mcfg = (acpi_mcfg_t *)header;
	unsigned long current = (unsigned long)mcfg + sizeof(acpi_mcfg_t);


	if (acpi_fill_header(header, "MCFG", MCFG, sizeof(acpi_mcfg_t)) != CB_SUCCESS)
		return;

	if (CONFIG(ECAM_MMCONF_SUPPORT))
		current = acpi_fill_mcfg(current);

	/* (Re)calculate length */
	header->length = current - (unsigned long)mcfg;
}

static void *get_tcpa_log(u32 *size)
{
	const struct cbmem_entry *ce;
	const u32 tcpa_default_log_len = 0x10000;
	void *lasa;
	ce = cbmem_entry_find(CBMEM_ID_TCPA_TCG_LOG);
	if (ce) {
		lasa = cbmem_entry_start(ce);
		*size = cbmem_entry_size(ce);
		printk(BIOS_DEBUG, "TCPA log found at %p\n", lasa);
		return lasa;
	}
	lasa = cbmem_add(CBMEM_ID_TCPA_TCG_LOG, tcpa_default_log_len);
	if (!lasa) {
		printk(BIOS_ERR, "TCPA log creation failed\n");
		return NULL;
	}

	printk(BIOS_DEBUG, "TCPA log created at %p\n", lasa);
	memset(lasa, 0, tcpa_default_log_len);

	*size = tcpa_default_log_len;
	return lasa;
}

static void acpi_create_tcpa(acpi_header_t *header, void *unused)
{
	if (!CONFIG(TPM1))
		return;

	acpi_tcpa_t *tcpa = (acpi_tcpa_t *)header;
	u32 tcpa_log_len;
	void *lasa;

	lasa = get_tcpa_log(&tcpa_log_len);
	if (!lasa)
		return;

	if (acpi_fill_header(header, "TCPA", TCPA, sizeof(acpi_tcpa_t)) != CB_SUCCESS)
		return;

	tcpa->platform_class = 0;
	tcpa->laml = tcpa_log_len;
	tcpa->lasa = (uintptr_t)lasa;
}

static void *get_tpm2_log(u32 *size)
{
	const struct cbmem_entry *ce;
	const u32 tpm2_default_log_len = 0x10000;
	void *lasa;
	ce = cbmem_entry_find(CBMEM_ID_TPM2_TCG_LOG);
	if (ce) {
		lasa = cbmem_entry_start(ce);
		*size = cbmem_entry_size(ce);
		printk(BIOS_DEBUG, "TPM2 log found at %p\n", lasa);
		return lasa;
	}
	lasa = cbmem_add(CBMEM_ID_TPM2_TCG_LOG, tpm2_default_log_len);
	if (!lasa) {
		printk(BIOS_ERR, "TPM2 log creation failed\n");
		return NULL;
	}

	printk(BIOS_DEBUG, "TPM2 log created at %p\n", lasa);
	memset(lasa, 0, tpm2_default_log_len);

	*size = tpm2_default_log_len;
	return lasa;
}

static void acpi_create_tpm2(acpi_header_t *header, void *unused)
{
	if (!CONFIG(TPM2))
		return;

	acpi_tpm2_t *tpm2 = (acpi_tpm2_t *)header;
	u32 tpm2_log_len;
	void *lasa;

	/*
	 * Some payloads like SeaBIOS depend on log area to use TPM2.
	 * Get the memory size and address of TPM2 log area or initialize it.
	 */
	lasa = get_tpm2_log(&tpm2_log_len);
	if (!lasa)
		tpm2_log_len = 0;

	if (acpi_fill_header(header, "TPM2", TPM2, sizeof(acpi_tpm2_t)) != CB_SUCCESS)
		return;

	/* Hard to detect for coreboot. Just set it to 0 */
	tpm2->platform_class = 0;
	if (CONFIG(CRB_TPM)) {
		/* Must be set to 7 for CRB Support */
		tpm2->control_area = CONFIG_CRB_TPM_BASE_ADDRESS + 0x40;
		tpm2->start_method = 7;
	} else {
		/* Must be set to 0 for FIFO interface support */
		tpm2->control_area = 0;
		tpm2->start_method = 6;
	}
	memset(tpm2->msp, 0, sizeof(tpm2->msp));

	/* Fill the log area size and start address fields. */
	tpm2->laml = tpm2_log_len;
	tpm2->lasa = (uintptr_t)lasa;
}

static void acpi_ssdt_write_cbtable(void)
{
	const struct cbmem_entry *cbtable;
	uintptr_t base;
	uint32_t size;

	cbtable = cbmem_entry_find(CBMEM_ID_CBTABLE);
	if (!cbtable)
		return;
	base = (uintptr_t)cbmem_entry_start(cbtable);
	size = cbmem_entry_size(cbtable);

	acpigen_write_device("CTBL");
	acpigen_write_coreboot_hid(COREBOOT_ACPI_ID_CBTABLE);
	acpigen_write_name_integer("_UID", 0);
	acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON);
	acpigen_write_name("_CRS");
	acpigen_write_resourcetemplate_header();
	acpigen_resource_consumer_mmio(base, base + size - 1,
				       MEM_RSRC_FLAG_MEM_READ_ONLY
				       | MEM_RSRC_FLAG_MEM_ATTR_CACHE);
	acpigen_write_resourcetemplate_footer();
	acpigen_pop_len();
}

static void acpi_create_ssdt_generator(acpi_header_t *ssdt, void *unused)
{
	unsigned long current = (unsigned long)ssdt + sizeof(acpi_header_t);

	if (acpi_fill_header(ssdt, "SSDT", SSDT, sizeof(acpi_header_t)) != CB_SUCCESS)
		return;

	acpigen_set_current((char *)current);

	/* Write object to declare coreboot tables */
	acpi_ssdt_write_cbtable();

	{
		struct device *dev;
		for (dev = all_devices; dev; dev = dev->next)
			if (dev->enabled && dev->ops && dev->ops->acpi_fill_ssdt)
				dev->ops->acpi_fill_ssdt(dev);
		current = (unsigned long)acpigen_get_current();
	}

	/* (Re)calculate length and checksum. */
	ssdt->length = current - (unsigned long)ssdt;
}

int acpi_create_srat_mem(acpi_srat_mem_t *mem, u8 node, u32 basek, u32 sizek,
				u32 flags)
{
	mem->type = 1; /* Memory affinity structure */
	mem->length = sizeof(acpi_srat_mem_t);
	mem->base_address_low = (basek << 10);
	mem->base_address_high = (basek >> (32 - 10));
	mem->length_low = (sizek << 10);
	mem->length_high = (sizek >> (32 - 10));
	mem->proximity_domain = node;
	mem->flags = flags;

	return mem->length;
}

int acpi_create_srat_gia_pci(acpi_srat_gia_t *gia, u32 proximity_domain,
				u16 seg, u8 bus, u8 dev, u8 func, u32 flags)
{
	gia->type = ACPI_SRAT_STRUCTURE_GIA;
	gia->length = sizeof(acpi_srat_gia_t);
	gia->proximity_domain = proximity_domain;
	gia->dev_handle_type = ACPI_SRAT_GIA_DEV_HANDLE_PCI;
	/* First two bytes has segment number */
	memcpy(gia->dev_handle, &seg, 2);
	gia->dev_handle[2] = bus; /* Byte 2 has bus number */
	/* Byte 3 has bits 7:3 for dev, bits 2:0 for func */
	gia->dev_handle[3] = PCI_SLOT(dev) | PCI_FUNC(func);
	gia->flags = flags;

	return gia->length;
}

/* http://www.microsoft.com/whdc/system/sysinternals/sratdwn.mspx */
void acpi_create_srat(acpi_srat_t *srat,
		      unsigned long (*acpi_fill_srat)(unsigned long current))
{
	acpi_header_t *header = &(srat->header);
	unsigned long current = (unsigned long)srat + sizeof(acpi_srat_t);

	memset((void *)srat, 0, sizeof(acpi_srat_t));

	if (acpi_fill_header(header, "SRAT", SRAT, sizeof(acpi_srat_t)) != CB_SUCCESS)
		return;

	srat->resv = 1; /* Spec: Reserved to 1 for backwards compatibility. */

	current = acpi_fill_srat(current);

	/* (Re)calculate length and checksum. */
	header->length = current - (unsigned long)srat;
	header->checksum = acpi_checksum((void *)srat, header->length);
}

int acpi_create_cedt_chbs(acpi_cedt_chbs_t *chbs, u32 uid, u32 cxl_ver, u64 base)
{
	memset((void *)chbs, 0, sizeof(acpi_cedt_chbs_t));

	chbs->type = ACPI_CEDT_STRUCTURE_CHBS;
	chbs->length = sizeof(acpi_cedt_chbs_t);
	chbs->uid = uid;
	chbs->cxl_ver = cxl_ver;
	chbs->base = base;

	/*
	 * CXL spec 2.0 section 9.14.1.2 "CXL CHBS"
	 * CXL 1.1 spec compliant host bridge: 8KB
	 * CXL 2.0 spec compliant host bridge: 64KB
	 */
	if (cxl_ver == ACPI_CEDT_CHBS_CXL_VER_1_1)
		chbs->len = 8 * KiB;
	else if (cxl_ver == ACPI_CEDT_CHBS_CXL_VER_2_0)
		chbs->len = 64 * KiB;
	else
		printk(BIOS_ERR, "ACPI(%s:%s): Incorrect CXL version:%d\n", __FILE__, __func__,
		       cxl_ver);

	return chbs->length;
}

int acpi_create_cedt_cfmws(acpi_cedt_cfmws_t *cfmws, u64 base_hpa, u64 window_size, u8 eniw,
			   u32 hbig, u16 restriction, u16 qtg_id, const u32 *interleave_target)
{
	memset((void *)cfmws, 0, sizeof(acpi_cedt_cfmws_t));

	cfmws->type = ACPI_CEDT_STRUCTURE_CFMWS;

	u8 niw = 0;
	if (eniw >= 8)
		printk(BIOS_ERR, "ACPI(%s:%s): Incorrect eniw::%d\n", __FILE__, __func__, eniw);
	else
		/* NIW = 2 ** ENIW */
		niw = 0x1 << eniw;
	/* 36 + 4 * NIW */
	cfmws->length = sizeof(acpi_cedt_cfmws_t) + 4 * niw;

	cfmws->base_hpa = base_hpa;
	cfmws->window_size = window_size;
	cfmws->eniw = eniw;

	// 0: Standard Modulo Arithmetic. Other values reserved.
	cfmws->interleave_arithmetic = 0;

	cfmws->hbig = hbig;
	cfmws->restriction = restriction;
	cfmws->qtg_id = qtg_id;
	memcpy(&cfmws->interleave_target, interleave_target, 4 * niw);

	return cfmws->length;
}

void acpi_create_cedt(acpi_cedt_t *cedt, unsigned long (*acpi_fill_cedt)(unsigned long current))
{
	acpi_header_t *header = &(cedt->header);
	unsigned long current = (unsigned long)cedt + sizeof(acpi_cedt_t);

	memset((void *)cedt, 0, sizeof(acpi_cedt_t));

	if (acpi_fill_header(header, "CEDT", CEDT, sizeof(acpi_cedt_t)) != CB_SUCCESS)
		return;

	current = acpi_fill_cedt(current);

	/* (Re)calculate length and checksum. */
	header->length = current - (unsigned long)cedt;
	header->checksum = acpi_checksum((void *)cedt, header->length);
}

int acpi_create_hmat_mpda(acpi_hmat_mpda_t *mpda, u32 initiator, u32 memory)
{
	memset((void *)mpda, 0, sizeof(acpi_hmat_mpda_t));

	mpda->type = 0; /* Memory Proximity Domain Attributes structure */
	mpda->length = sizeof(acpi_hmat_mpda_t);
	/*
	 * Proximity Domain for Attached Initiator field is valid.
	 * Bit 1 and bit 2 are reserved since HMAT revision 2.
	 */
	mpda->flags = (1 << 0);
	mpda->proximity_domain_initiator = initiator;
	mpda->proximity_domain_memory = memory;

	return mpda->length;
}

void acpi_create_hmat(acpi_hmat_t *hmat,
		 unsigned long (*acpi_fill_hmat)(unsigned long current))
{
	acpi_header_t *header = &(hmat->header);
	unsigned long current = (unsigned long)hmat + sizeof(acpi_hmat_t);

	memset((void *)hmat, 0, sizeof(acpi_hmat_t));

	if (acpi_fill_header(header, "HMAT", HMAT, sizeof(acpi_hmat_t)) != CB_SUCCESS)
		return;

	current = acpi_fill_hmat(current);

	/* (Re)calculate length and checksum. */
	header->length = current - (unsigned long)hmat;
	header->checksum = acpi_checksum((void *)hmat, header->length);
}

/* http://h21007.www2.hp.com/portal/download/files/unprot/Itanium/slit.pdf */
void acpi_create_slit(acpi_slit_t *slit,
		      unsigned long (*acpi_fill_slit)(unsigned long current))
{
	acpi_header_t *header = &(slit->header);
	unsigned long current = (unsigned long)slit + sizeof(acpi_slit_t);

	memset((void *)slit, 0, sizeof(acpi_slit_t));

	if (acpi_fill_header(header, "SLIT", SLIT, sizeof(acpi_slit_t)) != CB_SUCCESS)
		return;

	current = acpi_fill_slit(current);

	/* (Re)calculate length and checksum. */
	header->length = current - (unsigned long)slit;
	header->checksum = acpi_checksum((void *)slit, header->length);
}

/*
 * This method adds the ACPI error injection capability. It fills the default information.
 * HW dependent code (caller) can modify the defaults upon return. If no changes are necessary
 * and the defaults are acceptable then caller can simply add the table (acpi_add_table).
 * INPUTS:
 * einj - ptr to the starting location of EINJ table
 * actions - number of actions to trigger an error (HW dependent)
 * addr - address of trigger action table. This should be ACPI reserved memory and it will be
 *        shared between OS and FW.
 */
void acpi_create_einj(acpi_einj_t *einj, uintptr_t addr, u8 actions)
{
	int i;
	acpi_header_t *header = &(einj->header);
	acpi_injection_header_t *inj_header = &(einj->inj_header);
	acpi_einj_smi_t *einj_smi = (acpi_einj_smi_t *)addr;
	acpi_einj_trigger_table_t *tat;
	if (!header)
		return;

	printk(BIOS_DEBUG, "%s einj_smi = %p\n", __func__, einj_smi);
	memset(einj_smi, 0, sizeof(acpi_einj_smi_t));
	tat = (acpi_einj_trigger_table_t *)((uint8_t *)einj_smi + sizeof(acpi_einj_smi_t));
	tat->header_size =  16;
	tat->revision =  0;
	tat->table_size =  sizeof(acpi_einj_trigger_table_t) +
		sizeof(acpi_einj_action_table_t) * actions - 1;
	tat->entry_count = actions;
	printk(BIOS_DEBUG, "%s trigger_action_table = %p\n", __func__, tat);

	for (i = 0; i < actions; i++) {
		tat->trigger_action[i].action = TRIGGER_ERROR;
		tat->trigger_action[i].instruction = NO_OP;
		tat->trigger_action[i].flags = FLAG_IGNORE;
		tat->trigger_action[i].reg.space_id = ACPI_ADDRESS_SPACE_MEMORY;
		tat->trigger_action[i].reg.bit_width = 64;
		tat->trigger_action[i].reg.bit_offset = 0;
		tat->trigger_action[i].reg.access_size = ACPI_ACCESS_SIZE_QWORD_ACCESS;
		tat->trigger_action[i].reg.addr = 0;
		tat->trigger_action[i].value = 0;
		tat->trigger_action[i].mask = 0xFFFFFFFF;
	}

	acpi_einj_action_table_t default_actions[ACTION_COUNT] = {
		[0] = {
			.action = BEGIN_INJECT_OP,
			.instruction = WRITE_REGISTER_VALUE,
			.flags = FLAG_PRESERVE,
			.reg = EINJ_REG_MEMORY((u64)(uintptr_t)&einj_smi->op_state),
			.value = 0,
			.mask = 0xFFFFFFFF
		},
		[1] = {
			.action = GET_TRIGGER_ACTION_TABLE,
			.instruction = READ_REGISTER,
			.flags = FLAG_IGNORE,
			.reg = EINJ_REG_MEMORY((u64)(uintptr_t)&einj_smi->trigger_action_table),
			.value = 0,
			.mask = 0xFFFFFFFFFFFFFFFF
		},
		[2] = {
			.action = SET_ERROR_TYPE,
			.instruction = WRITE_REGISTER,
			.flags = FLAG_PRESERVE,
			.reg = EINJ_REG_MEMORY((u64)(uintptr_t)&einj_smi->err_inject[0]),
			.value = 0,
			.mask = 0xFFFFFFFF
		},
		[3] = {
			.action = GET_ERROR_TYPE,
			.instruction = READ_REGISTER,
			.flags = FLAG_IGNORE,
			.reg = EINJ_REG_MEMORY((u64)(uintptr_t)&einj_smi->err_inj_cap),
			.value = 0,
			.mask = 0xFFFFFFFF
		},
		[4] = {
			.action = END_INJECT_OP,
			.instruction = WRITE_REGISTER_VALUE,
			.flags = FLAG_PRESERVE,
			.reg = EINJ_REG_MEMORY((u64)(uintptr_t)&einj_smi->op_state),
			.value = 0,
			.mask = 0xFFFFFFFF

		},
		[5] = {
			.action = EXECUTE_INJECT_OP,
			.instruction = WRITE_REGISTER_VALUE,
			.flags = FLAG_PRESERVE,
			.reg = EINJ_REG_IO(),
			.value = 0x9a,
			.mask = 0xFFFF,
		},
		[6] = {
			.action = CHECK_BUSY_STATUS,
			.instruction = READ_REGISTER_VALUE,
			.flags = FLAG_IGNORE,
			.reg = EINJ_REG_MEMORY((u64)(uintptr_t)&einj_smi->op_status),
			.value = 1,
			.mask = 1,
		},
		[7] = {
			.action = GET_CMD_STATUS,
			.instruction = READ_REGISTER,
			.flags = FLAG_PRESERVE,
			.reg = EINJ_REG_MEMORY((u64)(uintptr_t)&einj_smi->cmd_sts),
			.value = 0,
			.mask = 0x1fe,
		},
		[8] = {
			.action = SET_ERROR_TYPE_WITH_ADDRESS,
			.instruction = WRITE_REGISTER,
			.flags = FLAG_PRESERVE,
			.reg = EINJ_REG_MEMORY((u64)(uintptr_t)&einj_smi->setaddrtable),
			.value = 1,
			.mask = 0xffffffff
		}
	};

	einj_smi->err_inj_cap = ACPI_EINJ_DEFAULT_CAP;
	einj_smi->trigger_action_table = (u64)(uintptr_t)tat;

	for (i = 0; i < ACTION_COUNT; i++)
		printk(BIOS_DEBUG, "default_actions[%d].reg.addr is %llx\n", i,
			default_actions[i].reg.addr);

	memset((void *)einj, 0, sizeof(*einj));

	if (acpi_fill_header(header, "EINJ", EINJ, sizeof(acpi_einj_t)) != CB_SUCCESS)
		return;

	inj_header->einj_header_size = sizeof(acpi_injection_header_t);
	inj_header->entry_count = ACTION_COUNT;

	printk(BIOS_DEBUG, "%s einj->action_table = %p\n",
		 __func__, einj->action_table);
	memcpy((void *)einj->action_table, (void *)default_actions, sizeof(einj->action_table));
	header->checksum = acpi_checksum((void *)einj, sizeof(*einj));
}

void acpi_create_vfct(const struct device *device,
		      acpi_vfct_t *vfct,
		      unsigned long (*acpi_fill_vfct)(const struct device *device,
		      acpi_vfct_t *vfct_struct, unsigned long current))
{
	acpi_header_t *header = &(vfct->header);
	unsigned long current = (unsigned long)vfct + sizeof(acpi_vfct_t);

	memset((void *)vfct, 0, sizeof(acpi_vfct_t));

	if (acpi_fill_header(header, "VFCT", VFCT, sizeof(acpi_vfct_t)) != CB_SUCCESS)
		return;

	current = acpi_fill_vfct(device, vfct, current);

	/* If no BIOS image, return with header->length == 0. */
	if (!vfct->VBIOSImageOffset)
		return;

	/* (Re)calculate length and checksum. */
	header->length = current - (unsigned long)vfct;
	header->checksum = acpi_checksum((void *)vfct, header->length);
}

void acpi_create_ipmi(const struct device *device,
		      struct acpi_spmi *spmi,
		      const u16 ipmi_revision,
		      const acpi_addr_t *addr,
		      const enum acpi_ipmi_interface_type type,
		      const s8 gpe_interrupt,
		      const u32 apic_interrupt,
		      const u32 uid)
{
	acpi_header_t *header = &(spmi->header);
	memset((void *)spmi, 0, sizeof(struct acpi_spmi));

	if (acpi_fill_header(header, "SPMI", SPMI, sizeof(struct acpi_spmi)) != CB_SUCCESS)
		return;

	spmi->reserved = 1;

	if (device->path.type == DEVICE_PATH_PCI) {
		spmi->pci_device_flag = ACPI_IPMI_PCI_DEVICE_FLAG;
		spmi->pci_segment_group = device->bus->segment_group;
		spmi->pci_bus = device->bus->secondary;
		spmi->pci_device = device->path.pci.devfn >> 3;
		spmi->pci_function = device->path.pci.devfn & 0x7;
	} else if (type != IPMI_INTERFACE_SSIF) {
		memcpy(spmi->uid, &uid, sizeof(spmi->uid));
	}

	spmi->base_address = *addr;
	spmi->specification_revision = ipmi_revision;

	spmi->interface_type = type;

	if (gpe_interrupt >= 0 && gpe_interrupt < 32) {
		spmi->gpe = gpe_interrupt;
		spmi->interrupt_type |= ACPI_IPMI_INT_TYPE_SCI;
	}
	if (apic_interrupt > 0) {
		spmi->global_system_interrupt = apic_interrupt;
		spmi->interrupt_type |= ACPI_IPMI_INT_TYPE_APIC;
	}

	/* Calculate checksum. */
	header->checksum = acpi_checksum((void *)spmi, header->length);
}

void acpi_create_ivrs(acpi_ivrs_t *ivrs,
		      unsigned long (*acpi_fill_ivrs)(acpi_ivrs_t *ivrs_struct,
		      unsigned long current))
{
	acpi_header_t *header = &(ivrs->header);
	unsigned long current = (unsigned long)ivrs + sizeof(acpi_ivrs_t);

	memset((void *)ivrs, 0, sizeof(acpi_ivrs_t));

	if (acpi_fill_header(header, "IVRS", IVRS, sizeof(acpi_ivrs_t)) != CB_SUCCESS)
		return;

	current = acpi_fill_ivrs(ivrs, current);

	/* (Re)calculate length and checksum. */
	header->length = current - (unsigned long)ivrs;
	header->checksum = acpi_checksum((void *)ivrs, header->length);
}

void acpi_create_crat(struct acpi_crat_header *crat,
		      unsigned long (*acpi_fill_crat)(struct acpi_crat_header *crat_struct,
		      unsigned long current))
{
	acpi_header_t *header = &(crat->header);
	unsigned long current = (unsigned long)crat + sizeof(struct acpi_crat_header);

	memset((void *)crat, 0, sizeof(struct acpi_crat_header));

	if (acpi_fill_header(header, "CRAT", CRAT, sizeof(struct acpi_crat_header)) != CB_SUCCESS)
		return;

	current = acpi_fill_crat(crat, current);

	/* (Re)calculate length and checksum. */
	header->length = current - (unsigned long)crat;
	header->checksum = acpi_checksum((void *)crat, header->length);
}

static void acpi_create_dbg2(acpi_dbg2_header_t *dbg2,
		      int port_type, int port_subtype,
		      acpi_addr_t *address, uint32_t address_size,
		      const char *device_path)
{
	uintptr_t current;
	acpi_dbg2_device_t *device;
	uint32_t *dbg2_addr_size;
	acpi_header_t *header;
	size_t path_len;
	const char *path;
	char *namespace;

	/* Fill out header fields. */
	current = (uintptr_t)dbg2;
	memset(dbg2, 0, sizeof(acpi_dbg2_header_t));
	header = &(dbg2->header);

	if (acpi_fill_header(header, "DBG2", DBG2, sizeof(acpi_dbg2_header_t)) != CB_SUCCESS)
		return;

	/* One debug device defined */
	dbg2->devices_offset = sizeof(acpi_dbg2_header_t);
	dbg2->devices_count = 1;
	current += sizeof(acpi_dbg2_header_t);

	/* Device comes after the header */
	device = (acpi_dbg2_device_t *)current;
	memset(device, 0, sizeof(acpi_dbg2_device_t));
	current += sizeof(acpi_dbg2_device_t);

	device->revision = 0;
	device->address_count = 1;
	device->port_type = port_type;
	device->port_subtype = port_subtype;

	/* Base Address comes after device structure */
	memcpy((void *)current, address, sizeof(acpi_addr_t));
	device->base_address_offset = current - (uintptr_t)device;
	current += sizeof(acpi_addr_t);

	/* Address Size comes after address structure */
	dbg2_addr_size = (uint32_t *)current;
	device->address_size_offset = current - (uintptr_t)device;
	*dbg2_addr_size = address_size;
	current += sizeof(uint32_t);

	/* Namespace string comes last, use '.' if not provided */
	path = device_path ? : ".";
	/* Namespace string length includes NULL terminator */
	path_len = strlen(path) + 1;
	namespace = (char *)current;
	device->namespace_string_length = path_len;
	device->namespace_string_offset = current - (uintptr_t)device;
	strncpy(namespace, path, path_len);
	current += path_len;

	/* Update structure lengths and checksum */
	device->length = current - (uintptr_t)device;
	header->length = current - (uintptr_t)dbg2;
	header->checksum = acpi_checksum((uint8_t *)dbg2, header->length);
}

static unsigned long acpi_write_dbg2_uart(acpi_rsdp_t *rsdp, unsigned long current,
					  int space_id, uint64_t base, uint32_t size,
					  int access_size, const char *name)
{
	acpi_dbg2_header_t *dbg2 = (acpi_dbg2_header_t *)current;
	acpi_addr_t address;

	memset(&address, 0, sizeof(address));

	address.space_id = space_id;
	address.addrl = (uint32_t)base;
	address.addrh = (uint32_t)((base >> 32) & 0xffffffff);
	address.access_size = access_size;

	int subtype;
	/* 16550-compatible with parameters defined in Generic Address Structure */
	if (CONFIG(DRIVERS_UART_8250IO) || CONFIG(DRIVERS_UART_8250MEM))
		subtype = ACPI_DBG2_PORT_SERIAL_16550;
	else if (CONFIG(DRIVERS_UART_PL011))
		subtype = ACPI_DBG2_PORT_SERIAL_ARM_PL011;
	else
		return current;

	acpi_create_dbg2(dbg2,
			 ACPI_DBG2_PORT_SERIAL,
			 subtype,
			 &address, size,
			 name);

	if (dbg2->header.length) {
		current += dbg2->header.length;
		current = acpi_align_current(current);
		acpi_add_table(rsdp, dbg2);
	}

	return current;
}

unsigned long acpi_write_dbg2_pci_uart(acpi_rsdp_t *rsdp, unsigned long current,
				       const struct device *dev, uint8_t access_size)
{
	struct resource *res;

	if (!dev) {
		printk(BIOS_DEBUG, "%s: Device not found\n", __func__);
		return current;
	}
	if (!dev->enabled) {
		printk(BIOS_INFO, "%s: Device not enabled\n", __func__);
		return current;
	}
	res = probe_resource(dev, PCI_BASE_ADDRESS_0);
	if (!res) {
		printk(BIOS_ERR, "%s: Unable to find resource for %s\n",
		       __func__, dev_path(dev));
		return current;
	}

	int space_id;
	if (res->flags & IORESOURCE_IO)
		space_id = ACPI_ADDRESS_SPACE_IO;
	else if (res->flags & IORESOURCE_MEM)
		space_id = ACPI_ADDRESS_SPACE_MEMORY;
	else {
		printk(BIOS_ERR, "%s: Unknown address space type\n", __func__);
		return current;
	}

	return acpi_write_dbg2_uart(rsdp, current, space_id, res->base, res->size, access_size, acpi_device_path(dev));
}

unsigned long acpi_pl011_write_dbg2_uart(acpi_rsdp_t *rsdp, unsigned long current,
					 uint64_t base, const char *name)
{
	return acpi_write_dbg2_uart(rsdp, current, ACPI_ADDRESS_SPACE_MEMORY, base,
				    sizeof(struct pl011_uart), ACPI_ACCESS_SIZE_DWORD_ACCESS,
				    name);
}

unsigned long acpi_16550_mmio32_write_dbg2_uart(acpi_rsdp_t *rsdp, unsigned long current,
					 uint64_t base, const char *name)
{
	return acpi_write_dbg2_uart(rsdp, current, ACPI_ADDRESS_SPACE_MEMORY, base,
				    0x100, ACPI_ACCESS_SIZE_DWORD_ACCESS,
				    name);
}

static void acpi_create_facs(void *header)
{
	acpi_facs_t *facs = header;

	memcpy(facs->signature, "FACS", 4);
	facs->length = sizeof(acpi_facs_t);
	facs->hardware_signature = 0;
	facs->firmware_waking_vector = 0;
	facs->global_lock = 0;
	facs->flags = 0;
	facs->x_firmware_waking_vector_l = 0;
	facs->x_firmware_waking_vector_h = 0;
	facs->version = get_acpi_table_revision(FACS);
}

static void acpi_write_rsdt(acpi_rsdt_t *rsdt, char *oem_id, char *oem_table_id)
{
	acpi_header_t *header = &(rsdt->header);

	if (acpi_fill_header(header, "RSDT", RSDT, sizeof(acpi_rsdt_t)) != CB_SUCCESS)
		return;

	/* Entries are filled in later, we come with an empty set. */

	/* Fix checksum. */
	header->checksum = acpi_checksum((void *)rsdt, sizeof(acpi_rsdt_t));
}

static void acpi_write_xsdt(acpi_xsdt_t *xsdt, char *oem_id, char *oem_table_id)
{
	acpi_header_t *header = &(xsdt->header);

	if (acpi_fill_header(header, "XSDT", XSDT, sizeof(acpi_xsdt_t)) != CB_SUCCESS)
		return;

	/* Entries are filled in later, we come with an empty set. */

	/* Fix checksum. */
	header->checksum = acpi_checksum((void *)xsdt, sizeof(acpi_xsdt_t));
}

static void acpi_write_rsdp(acpi_rsdp_t *rsdp, acpi_rsdt_t *rsdt,
			    acpi_xsdt_t *xsdt, char *oem_id)
{
	memset(rsdp, 0, sizeof(acpi_rsdp_t));

	memcpy(rsdp->signature, RSDP_SIG, 8);
	memcpy(rsdp->oem_id, oem_id, 6);

	rsdp->length = sizeof(acpi_rsdp_t);
	rsdp->rsdt_address = (uintptr_t)rsdt;

	/*
	 * Revision: ACPI 1.0: 0, ACPI 2.0/3.0/4.0: 2.
	 *
	 * Some OSes expect an XSDT to be present for RSD PTR revisions >= 2.
	 * If we don't have an ACPI XSDT, force ACPI 1.0 (and thus RSD PTR
	 * revision 0).
	 */
	if (xsdt == NULL) {
		rsdp->revision = 0;
	} else {
		rsdp->xsdt_address = (u64)(uintptr_t)xsdt;
		rsdp->revision = get_acpi_table_revision(RSDP);
	}

	/* Calculate checksums. */
	rsdp->checksum = acpi_checksum((void *)rsdp, 20);
	rsdp->ext_checksum = acpi_checksum((void *)rsdp, sizeof(acpi_rsdp_t));
}

unsigned long acpi_create_hest_error_source(acpi_hest_t *hest,
	acpi_hest_esd_t *esd, u16 type, void *data, u16 data_len)
{
	acpi_header_t *header = &(hest->header);
	acpi_hest_hen_t *hen;
	void *pos;
	u16 len;

	pos = esd;
	memset(pos, 0, sizeof(acpi_hest_esd_t));
	len = 0;
	esd->type = type;		/* MCE */
	esd->source_id = hest->error_source_count;
	esd->flags = 0;		/* FIRMWARE_FIRST */
	esd->enabled = 1;
	esd->prealloc_erecords = 1;
	esd->max_section_per_record = 0x1;

	len += sizeof(acpi_hest_esd_t);
	pos = esd + 1;

	switch (type) {
	case 0:			/* MCE */
		break;
	case 1:			/* CMC */
		hen = (acpi_hest_hen_t *)(pos);
		memset(pos, 0, sizeof(acpi_hest_hen_t));
		hen->type = 3;		/* SCI? */
		hen->length = sizeof(acpi_hest_hen_t);
		hen->conf_we = 0;	/* Configuration Write Enable. */
		hen->poll_interval = 0;
		hen->vector = 0;
		hen->sw2poll_threshold_val = 0;
		hen->sw2poll_threshold_win = 0;
		hen->error_threshold_val = 0;
		hen->error_threshold_win = 0;
		len += sizeof(acpi_hest_hen_t);
		pos = hen + 1;
		break;
	case 2:			/* NMI */
	case 6:			/* AER Root Port */
	case 7:			/* AER Endpoint */
	case 8:			/* AER Bridge */
	case 9:			/* Generic Hardware Error Source. */
		/* TODO: */
		break;
	default:
		printk(BIOS_DEBUG, "Invalid type of Error Source.");
		break;
	}
	hest->error_source_count++;

	memcpy(pos, data, data_len);
	len += data_len;
	if (header)
		header->length += len;

	return len;
}

/* ACPI 4.0 */
void acpi_write_hest(acpi_hest_t *hest,
		     unsigned long (*acpi_fill_hest)(acpi_hest_t *hest))
{
	acpi_header_t *header = &(hest->header);

	memset(hest, 0, sizeof(acpi_hest_t));

	if (acpi_fill_header(header, "HEST", HEST, sizeof(acpi_hest_t)) != CB_SUCCESS)
		return;

	acpi_fill_hest(hest);

	/* Calculate checksums. */
	header->checksum = acpi_checksum((void *)hest, header->length);
}

/* ACPI 3.0b */
static void acpi_create_bert(acpi_header_t *header, void *unused)
{
	if (!CONFIG(ACPI_BERT))
		return;

	acpi_bert_t *bert = (acpi_bert_t *)header;

	void *region;
	size_t size;
	if (acpi_soc_get_bert_region(&region, &size) != CB_SUCCESS)
		return;

	if (acpi_fill_header(header, "BERT", BERT, sizeof(acpi_bert_t)) != CB_SUCCESS)
		return;

	bert->error_region = (uintptr_t)region;
	bert->region_length = (size_t)size;
}

__weak void arch_fill_fadt(acpi_fadt_t *fadt) { }
__weak void soc_fill_fadt(acpi_fadt_t *fadt) { }
__weak void mainboard_fill_fadt(acpi_fadt_t *fadt) { }

static acpi_header_t *dsdt;
static void acpi_create_fadt(acpi_header_t *header, void *arg1)
{
	acpi_fadt_t *fadt = (acpi_fadt_t *)header;
	acpi_facs_t *facs = (acpi_facs_t *)(*(acpi_facs_t **)arg1);

	if (acpi_fill_header(header, "FACP", FADT, sizeof(acpi_fadt_t)) != CB_SUCCESS)
		return;

	fadt->FADT_MinorVersion = get_acpi_fadt_minor_version();
	if ((uintptr_t)facs <= UINT32_MAX)
		fadt->firmware_ctrl = (uintptr_t)facs;
	else
		fadt->x_firmware_ctl_h = (uint32_t)((uint64_t)(uintptr_t)facs >> 32);
	fadt->x_firmware_ctl_l = (uint32_t)(uintptr_t)facs;

	if ((uintptr_t)dsdt <= UINT32_MAX)
		fadt->dsdt = (uintptr_t)dsdt;
	else
		fadt->x_dsdt_h = (uint32_t)((uint64_t)(uintptr_t)dsdt >> 32);
	fadt->x_dsdt_l = (uint32_t)(uintptr_t)dsdt;

	/* should be 0 ACPI 3.0 */
	fadt->reserved = 0;

	/* P_LVLx latencies are not used as CPU _CST will override them. */
	fadt->p_lvl2_lat = ACPI_FADT_C2_NOT_SUPPORTED;
	fadt->p_lvl3_lat = ACPI_FADT_C3_NOT_SUPPORTED;

	/* Use CPU _PTC instead to provide P_CNT details. */
	fadt->duty_offset = 0;
	fadt->duty_width = 0;

	fadt->preferred_pm_profile = acpi_get_preferred_pm_profile();

	arch_fill_fadt(fadt);

	acpi_fill_fadt(fadt);

	soc_fill_fadt(fadt);
	mainboard_fill_fadt(fadt);
}

static void acpi_create_lpit(acpi_header_t *header, void *unused)
{
	if (!CONFIG(ACPI_LPIT))
		return;

	acpi_lpit_t *lpit = (acpi_lpit_t *)header;
	unsigned long current = (unsigned long)lpit + sizeof(acpi_lpit_t);

	if (acpi_fill_header(header, "LPIT", LPIT, sizeof(acpi_lpit_t)) != CB_SUCCESS)
		return;

	current = acpi_fill_lpit(current);

	/* (Re)calculate length. */
	header->length = current - (unsigned long)lpit;
}

static void acpi_create_gtdt(acpi_header_t *header, void *unused)
{
	if (!CONFIG(ACPI_GTDT))
		return;

	acpi_gtdt_t *gtdt = (acpi_gtdt_t *)header;
	unsigned long current = (unsigned long)gtdt + sizeof(acpi_gtdt_t);

	if (acpi_fill_header(header, "GTDT", GTDT, sizeof(acpi_gtdt_t)) != CB_SUCCESS)
		return;

	/* Fill out header fields. */
	gtdt->platform_timer_offset = sizeof(acpi_gtdt_t);

	acpi_soc_fill_gtdt(gtdt);
	current = acpi_soc_gtdt_add_timers(&gtdt->platform_timer_count, current);

	/* (Re)calculate length. */
	header->length = current - (unsigned long)gtdt;
}

unsigned long acpi_gtdt_add_timer_block(unsigned long current, const uint64_t address,
					   struct acpi_gtdt_timer_entry *timers, size_t number)
{
	struct acpi_gtdt_timer_block *block = (struct acpi_gtdt_timer_block *)current;
	memset(block, 0, sizeof(struct acpi_gtdt_timer_block));

	assert(number < 8 && number != 0);
	const size_t entries_size = number * sizeof(struct acpi_gtdt_timer_entry);

	block->header.type = ACPI_GTDT_TYPE_TIMER_BLOCK;
	block->header.length = sizeof(struct acpi_gtdt_timer_block)
		+ entries_size;
	block->block_address = address;
	block->timer_count = number;
	block->timer_offset = sizeof(struct acpi_gtdt_timer_block);
	current += sizeof(struct acpi_gtdt_timer_block);
	memcpy((void *)current, timers, entries_size);
	current += entries_size;
	return current;
}

unsigned long acpi_gtdt_add_watchdog(unsigned long current, uint64_t refresh_frame,
				     uint64_t control_frame, uint32_t gsiv, uint32_t flags)
{
	struct acpi_gtdt_watchdog *wd = (struct acpi_gtdt_watchdog *)current;
	memset(wd, 0, sizeof(struct acpi_gtdt_watchdog));

	wd->header.type = ACPI_GTDT_TYPE_WATCHDOG;
	wd->header.length = sizeof(struct acpi_gtdt_watchdog);
	wd->refresh_frame_address = refresh_frame;
	wd->control_frame_address = control_frame;
	wd->timer_interrupt = gsiv;
	wd->timer_flags = flags;

	return current + sizeof(struct acpi_gtdt_watchdog);
}

static void acpi_create_iort(acpi_header_t *header, void *unused)
{
	if (!CONFIG(ACPI_IORT))
		return;

	acpi_iort_t *iort = (acpi_iort_t *)header;
	unsigned long current = (unsigned long)iort + sizeof(acpi_iort_t);

	if (acpi_fill_header(header, "IORT", IORT, sizeof(acpi_iort_t)) != CB_SUCCESS)
		return;

	iort->node_count = 0;
	iort->node_offset = current - (unsigned long)iort;

	current = acpi_soc_fill_iort(iort, current);

	/* (Re)calculate length */
	header->length = current - (unsigned long)iort;
}

static void acpi_create_wdat(acpi_header_t *header, void *unused)
{
	if (!CONFIG(ACPI_WDAT_WDT))
		return;

	acpi_wdat_t *wdat = (acpi_wdat_t *)header;
	unsigned long current = (unsigned long)wdat + sizeof(acpi_wdat_t);

	memset((void *)wdat, 0, sizeof(acpi_wdat_t));

	if (acpi_fill_header(header, "WDAT", WDAT, sizeof(acpi_wdat_t)) != CB_SUCCESS)
		return;

	current = acpi_soc_fill_wdat(wdat, current);

	/* (Re)calculate length. */
	header->length = current - (unsigned long)wdat;
}

unsigned long acpi_create_lpi_desc_ncst(acpi_lpi_desc_ncst_t *lpi_desc, uint16_t uid)
{
	memset(lpi_desc, 0, sizeof(acpi_lpi_desc_ncst_t));
	lpi_desc->header.length = sizeof(acpi_lpi_desc_ncst_t);
	lpi_desc->header.type = ACPI_LPI_DESC_TYPE_NATIVE_CSTATE;
	lpi_desc->header.uid = uid;

	return lpi_desc->header.length;
}

static void acpi_create_pptt(acpi_header_t *header, void *unused)
{
	if (!CONFIG(ACPI_PPTT))
		return;

	if (acpi_fill_header(header, "PPTT", PPTT, sizeof(acpi_pptt_t)) != CB_SUCCESS)
		return;

	acpi_pptt_t *pptt = (acpi_pptt_t *)header;
	acpi_create_pptt_body(pptt);
}

static uint8_t acpi_spcr_type(void)
{
	/* 16550-compatible with parameters defined in Generic Address Structure */
	if (CONFIG(DRIVERS_UART_8250IO) || CONFIG(DRIVERS_UART_8250MEM))
		return 0x12;
	if (CONFIG(DRIVERS_UART_PL011))
		return 0x3;

	printk(BIOS_ERR, "%s: unknown serial type\n", __func__);
	return 0xff;
}

static void acpi_create_spcr(acpi_header_t *header, void *unused)
{
	acpi_spcr_t *spcr = (acpi_spcr_t *)header;
	struct lb_serial serial;

	if (!CONFIG(CONSOLE_SERIAL))
		return;

	if (fill_lb_serial(&serial) != CB_SUCCESS)
		return;

	if (acpi_fill_header(header, "SPCR", SPCR, sizeof(acpi_spcr_t)) != CB_SUCCESS)
		return;

	spcr->interface_type = acpi_spcr_type();
	assert(serial.type == LB_SERIAL_TYPE_IO_MAPPED
	       || serial.type == LB_SERIAL_TYPE_MEMORY_MAPPED);
	spcr->base_address.space_id = serial.type == LB_SERIAL_TYPE_IO_MAPPED ?
		ACPI_ADDRESS_SPACE_IO : ACPI_ADDRESS_SPACE_MEMORY;
	spcr->base_address.bit_width = serial.regwidth * 8;
	spcr->base_address.bit_offset = 0;
	switch (serial.regwidth) {
	case 1:
		spcr->base_address.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
		break;
	case 2:
		spcr->base_address.access_size = ACPI_ACCESS_SIZE_WORD_ACCESS;
		break;
	case 4:
		spcr->base_address.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
		break;
	default:
		printk(BIOS_ERR, "%s, Invalid serial regwidth\n", __func__);
	}

	spcr->base_address.addrl = serial.baseaddr;
	spcr->base_address.addrh = 0;
	spcr->interrupt_type = 0;
	spcr->irq = 0;
	spcr->configured_baudrate = 0; /* Have the OS use whatever is currently set */
	spcr->parity = 0;
	spcr->stop_bits = 1;
	spcr->flow_control = 0;
	spcr->terminal_type = 2; /* 2 = VT-UTF8 */
	spcr->language = 0;
	spcr->pci_did = 0xffff;
	spcr->pci_vid = 0xffff;

	header->checksum = acpi_checksum((void *)spcr, header->length);
}

unsigned long __weak fw_cfg_acpi_tables(unsigned long start)
{
	return 0;
}

void preload_acpi_dsdt(void)
{
	const char *file = CONFIG_CBFS_PREFIX "/dsdt.aml";

	if (!CONFIG(CBFS_PRELOAD))
		return;

	printk(BIOS_DEBUG, "Preloading %s\n", file);
	cbfs_preload(file);
}

static void acpi_create_dsdt(acpi_header_t *header, void *dsdt_file_arg)
{
	dsdt = header;
	acpi_header_t *dsdt_file = *(acpi_header_t **)dsdt_file_arg;
	unsigned long current = (unsigned long)header;

	dsdt = (acpi_header_t *)current;
	memcpy(dsdt, dsdt_file, sizeof(acpi_header_t));
	if (dsdt->length >= sizeof(acpi_header_t)) {
		current += sizeof(acpi_header_t);

		acpigen_set_current((char *)current);

		if (CONFIG(ACPI_SOC_NVS))
			acpi_fill_gnvs();
		if (CONFIG(CHROMEOS_NVS))
			acpi_fill_cnvs();

		current = (unsigned long)acpigen_get_current();
		memcpy((char *)current,
		       (char *)dsdt_file + sizeof(acpi_header_t),
		       dsdt->length - sizeof(acpi_header_t));
		current += dsdt->length - sizeof(acpi_header_t);

		/* (Re)calculate length. */
		dsdt->length = current - (unsigned long)dsdt;
	}
}

static void acpi_create_slic(acpi_header_t *header, void *slic_file_arg)
{
	acpi_header_t *slic_file = *(acpi_header_t **)slic_file_arg;
	acpi_header_t *slic = header;
	if (slic_file)
		memcpy(slic, slic_file, slic_file->length);
}

static uintptr_t coreboot_rsdp;

uintptr_t get_coreboot_rsdp(void)
{
	return coreboot_rsdp;
}

static void acpixtract_compatible_hexdump(const void *memory, size_t length)
{
	size_t i, j;
	uint8_t *line;
	size_t num_bytes;

	for (i = 0; i < length; i += 16) {
		num_bytes = MIN(length - i, 16);
		line = ((uint8_t *)memory) + i;

		printk(BIOS_SPEW, "    %04zX:", i);
		for (j = 0; j < num_bytes; j++)
			printk(BIOS_SPEW, " %02x", line[j]);
		for (; j < 16; j++)
			printk(BIOS_SPEW, "   ");
		printk(BIOS_SPEW, "  ");
		for (j = 0; j < num_bytes; j++)
			printk(BIOS_SPEW, "%c",
			       isprint(line[j]) ? line[j] : '.');
		printk(BIOS_SPEW, "\n");
	}
}

static void acpidump_print(void *table_ptr)
{
	if (table_ptr == NULL)
		return;
	const acpi_header_t *header = (acpi_header_t *)table_ptr;
	const size_t table_size = header->length;
	printk(BIOS_SPEW, "%.4s @ 0x0000000000000000\n", header->signature);
	acpixtract_compatible_hexdump(table_ptr, table_size);
	printk(BIOS_SPEW, "\n");
}

unsigned long write_acpi_tables(const unsigned long start)
{
	unsigned long current;
	acpi_rsdp_t *rsdp;
	acpi_rsdt_t *rsdt = NULL;
	acpi_xsdt_t *xsdt = NULL;
	acpi_facs_t *facs = NULL;
	acpi_header_t *slic_file;
	acpi_header_t *ssdt = NULL;
	acpi_header_t *dsdt_file;
	struct device *dev;
	unsigned long fw;
	size_t slic_size, dsdt_size;
	char oem_id[6], oem_table_id[8];

	const struct acpi_table_generator {
		void (*create_table)(acpi_header_t *table, void *arg);
		void *args;
		size_t min_size;
	} tables[] = {
		{ acpi_create_dsdt, &dsdt_file, sizeof(acpi_header_t) },
		{ acpi_create_fadt, &facs, sizeof(acpi_fadt_t) },
		{ acpi_create_slic, &slic_file, sizeof(acpi_header_t) },
		{ acpi_create_ssdt_generator, NULL, sizeof(acpi_header_t) },
		{ acpi_create_mcfg, NULL, sizeof(acpi_mcfg_t) },
		{ acpi_create_tcpa, NULL, sizeof(acpi_tcpa_t) },
		{ acpi_create_tpm2, NULL, sizeof(acpi_tpm2_t) },
		{ acpi_create_lpit, NULL, sizeof(acpi_lpit_t) },
		{ acpi_create_madt, NULL, sizeof(acpi_header_t) },
		{ acpi_create_bert, NULL, sizeof(acpi_bert_t) },
		{ acpi_create_spcr, NULL, sizeof(acpi_spcr_t) },
		{ acpi_create_gtdt, NULL, sizeof(acpi_gtdt_t) },
		{ acpi_create_pptt, NULL, sizeof(acpi_pptt_t) },
		{ acpi_create_iort, NULL, sizeof(acpi_iort_t) },
		{ acpi_create_wdat, NULL, sizeof(acpi_wdat_t) },
	};

	current = start;

	/* Align ACPI tables to 16byte */
	current = acpi_align_current(current);

	/* Special case for qemu */
	fw = fw_cfg_acpi_tables(current);
	if (fw) {
		rsdp = NULL;
		/* Find RSDP. */
		for (void *p = (void *)current; p < (void *)fw; p += 16) {
			if (valid_rsdp((acpi_rsdp_t *)p)) {
				rsdp = p;
				coreboot_rsdp = (uintptr_t)rsdp;
				break;
			}
		}
		if (!rsdp)
			return fw;

		current = fw;
		current = acpi_align_current(current);
		if (rsdp->xsdt_address == 0) {
			xsdt = (acpi_xsdt_t *)current;
			current += sizeof(acpi_xsdt_t);
			current = acpi_align_current(current);

			/*
			 * Qemu only creates an RSDT.
			 * Add an XSDT based on the existing RSDT entries.
			 */
			acpi_rsdt_t *existing_rsdt = (acpi_rsdt_t *)(uintptr_t)rsdp->rsdt_address;
			acpi_write_rsdp(rsdp, existing_rsdt, xsdt, oem_id);
			acpi_write_xsdt(xsdt, oem_id, oem_table_id);
			/*
			 * Copy existing entries to the new XSDT. This will override existing
			 * RSDT entries with the same value.
			 */
			for (int i = 0; existing_rsdt->entry[i]; i++)
				acpi_add_table(rsdp, (void *)(uintptr_t)existing_rsdt->entry[i]);

		}

		/* Add BOOT0000 for Linux google firmware driver */
		printk(BIOS_DEBUG, "ACPI:     * SSDT\n");
		ssdt = (acpi_header_t *)current;
		current += sizeof(acpi_header_t);

		memset((void *)ssdt, 0, sizeof(acpi_header_t));

		memcpy(&ssdt->signature, "SSDT", 4);
		ssdt->revision = get_acpi_table_revision(SSDT);
		memcpy(&ssdt->oem_id, OEM_ID, 6);
		memcpy(&ssdt->oem_table_id, oem_table_id, 8);
		ssdt->oem_revision = 42;
		memcpy(&ssdt->asl_compiler_id, ASLC, 4);
		ssdt->asl_compiler_revision = asl_revision;
		ssdt->length = sizeof(acpi_header_t);

		acpigen_set_current((char *)current);

		/* Write object to declare coreboot tables */
		acpi_ssdt_write_cbtable();

		/* (Re)calculate length and checksum. */
		ssdt->length = current - (unsigned long)ssdt;
		ssdt->checksum = acpi_checksum((void *)ssdt, ssdt->length);

		acpi_create_ssdt_generator(ssdt, NULL);

		acpi_add_table(rsdp, ssdt);

		return fw;
	}

	dsdt_file = cbfs_map(CONFIG_CBFS_PREFIX "/dsdt.aml", &dsdt_size);
	if (!dsdt_file) {
		printk(BIOS_ERR, "No DSDT file, skipping ACPI tables\n");
		return start;
	}

	if (dsdt_file->length > dsdt_size
	    || dsdt_file->length < sizeof(acpi_header_t)
	    || memcmp(dsdt_file->signature, "DSDT", 4) != 0) {
		printk(BIOS_ERR, "Invalid DSDT file, skipping ACPI tables\n");
		cbfs_unmap(dsdt_file);
		return start;
	}

	slic_file = cbfs_map(CONFIG_CBFS_PREFIX "/slic", &slic_size);
	if (slic_file
	    && (slic_file->length > slic_size
		|| slic_file->length < sizeof(acpi_header_t)
		|| (memcmp(slic_file->signature, "SLIC", 4) != 0
		    && memcmp(slic_file->signature, "MSDM", 4) != 0))) {
		cbfs_unmap(slic_file);
		slic_file = 0;
	}

	if (slic_file) {
		memcpy(oem_id, slic_file->oem_id, 6);
		memcpy(oem_table_id, slic_file->oem_table_id, 8);
	} else {
		memcpy(oem_id, OEM_ID, 6);
		memcpy(oem_table_id, ACPI_TABLE_CREATOR, 8);
	}

	printk(BIOS_INFO, "ACPI: Writing ACPI tables at %lx.\n", start);

	/* We need at least an RSDP, RSDT for ACPI 1.0 compat, otherwise XSDT */
	rsdp = (acpi_rsdp_t *)current;
	coreboot_rsdp = (uintptr_t)rsdp;
	current += sizeof(acpi_rsdp_t);
	current = acpi_align_current(current);
	if (current + sizeof(acpi_rsdt_t) - 1 <= UINT32_MAX) {
		rsdt = (acpi_rsdt_t *)current;
		current += sizeof(acpi_rsdt_t);
		current = acpi_align_current(current);
	} else {
		printk(BIOS_INFO, "Not adding RSDT because tables reside above 4G.");
	}

	xsdt = (acpi_xsdt_t *)current;
	current += sizeof(acpi_xsdt_t);
	current = acpi_align_current(current);

	/* clear all table memory */
	memset((void *)start, 0, current - start);

	acpi_write_rsdp(rsdp, rsdt, xsdt, oem_id);
	acpi_write_rsdt(rsdt, oem_id, oem_table_id);
	acpi_write_xsdt(xsdt, oem_id, oem_table_id);

	if (ENV_X86) {
		printk(BIOS_DEBUG, "ACPI:    * FACS\n");
		current = ALIGN_UP(current, 64);
		facs = (acpi_facs_t *)current;
		current += sizeof(acpi_facs_t);
		current = acpi_align_current(current);
		acpi_create_facs(facs);
	}

	for (size_t i = 0; i < ARRAY_SIZE(tables); i++) {
		acpi_header_t *header = (acpi_header_t *)current;
		memset(header, 0, tables[i].min_size);
		tables[i].create_table(header, tables[i].args);
		if (header->length < tables[i].min_size)
			continue;
		header->checksum = 0;
		header->checksum = acpi_checksum((void *)header, header->length);
		current += header->length;
		current = acpi_align_current(current);

		if (tables[i].create_table == acpi_create_dsdt)
			continue;

		printk(BIOS_DEBUG, "ACPI:    * %.4s\n", header->signature);
		acpi_add_table(rsdp, header);
	}

	/*
	 * cbfs_unmap() uses mem_pool_free() which works correctly only
	 * if freeing is done in reverse order than memory allocation.
	 * This is why unmapping of dsdt_file must be done after
	 * unmapping slic file.
	 */
	cbfs_unmap(slic_file);
	cbfs_unmap(dsdt_file);

	printk(BIOS_DEBUG, "current = %lx\n", current);

	for (dev = all_devices; dev; dev = dev->next) {
		if (dev->ops && dev->ops->write_acpi_tables) {
			current = dev->ops->write_acpi_tables(dev, current,
				rsdp);
			current = acpi_align_current(current);
		}
	}

	printk(BIOS_INFO, "ACPI: done.\n");

	if (CONFIG(DEBUG_ACPICA_COMPATIBLE)) {
		printk(BIOS_DEBUG, "Printing ACPI tables in ACPICA compatible format\n");
		if (facs)
			acpidump_print(facs);
		acpidump_print(dsdt);
		for (size_t i = 0; xsdt->entry[i] != 0; i++) {
			acpidump_print((void *)(uintptr_t)xsdt->entry[i]);
		}
		printk(BIOS_DEBUG, "Done printing ACPI tables in ACPICA compatible format\n");
	}

	return current;
}

static acpi_rsdp_t *valid_rsdp(acpi_rsdp_t *rsdp)
{
	if (strncmp((char *)rsdp, RSDP_SIG, sizeof(RSDP_SIG) - 1) != 0)
		return NULL;

	printk(BIOS_DEBUG, "Looking on %p for valid checksum\n", rsdp);

	if (acpi_checksum((void *)rsdp, 20) != 0)
		return NULL;
	printk(BIOS_DEBUG, "Checksum 1 passed\n");

	if ((rsdp->revision > 1) && (acpi_checksum((void *)rsdp,
						rsdp->length) != 0))
		return NULL;
	printk(BIOS_DEBUG, "Checksum 2 passed all OK\n");

	return rsdp;
}

void *acpi_find_wakeup_vector(void)
{
	char *p, *end;
	acpi_xsdt_t *xsdt;
	acpi_facs_t *facs;
	acpi_fadt_t *fadt = NULL;
	acpi_rsdp_t *rsdp = NULL;
	void *wake_vec;
	int i;

	if (!acpi_is_wakeup_s3())
		return NULL;

	printk(BIOS_DEBUG, "Trying to find the wakeup vector...\n");

	/* Find RSDP. */
	for (p = (char *)0xe0000; p < (char *)0xfffff; p += 16) {
		rsdp = valid_rsdp((acpi_rsdp_t *)p);
		if (rsdp)
			break;
	}

	if (rsdp == NULL) {
		printk(BIOS_ALERT,
		       "No RSDP found, wake up from S3 not possible.\n");
		return NULL;
	}

	printk(BIOS_DEBUG, "RSDP found at %p\n", rsdp);
	xsdt = (acpi_xsdt_t *)(uintptr_t)rsdp->xsdt_address;

	end = (char *)xsdt + xsdt->header.length;
	printk(BIOS_DEBUG, "XSDT found at %p ends at %p\n", xsdt, end);

	for (i = 0; ((char *)&xsdt->entry[i]) < end; i++) {
		fadt = (acpi_fadt_t *)(uintptr_t)xsdt->entry[i];
		if (strncmp((char *)fadt, "FACP", 4) == 0)
			break;
		fadt = NULL;
	}

	if (fadt == NULL) {
		printk(BIOS_ALERT,
		       "No FADT found, wake up from S3 not possible.\n");
		return NULL;
	}

	printk(BIOS_DEBUG, "FADT found at %p\n", fadt);
	facs = (acpi_facs_t *)(uintptr_t)((uint64_t)fadt->x_firmware_ctl_l
			       | (uint64_t)fadt->x_firmware_ctl_h << 32);

	if (facs == NULL) {
		printk(BIOS_ALERT,
		       "No FACS found, wake up from S3 not possible.\n");
		return NULL;
	}

	printk(BIOS_DEBUG, "FACS found at %p\n", facs);
	wake_vec = (void *)(uintptr_t)facs->firmware_waking_vector;
	printk(BIOS_DEBUG, "OS waking vector is %p\n", wake_vec);

	return wake_vec;
}

__weak int acpi_get_gpe(int gpe)
{
	return -1; /* implemented by SOC */
}

u8 get_acpi_fadt_minor_version(void)
{
	return ACPI_FADT_MINOR_VERSION_0;
}

int get_acpi_table_revision(enum acpi_tables table)
{
	switch (table) {
	case FADT:
		return ACPI_FADT_REV_ACPI_6;
	case MADT: /* ACPI 3.0: 2, ACPI 4.0/5.0: 3, ACPI 6.2b/6.3: 5 */
		return 3;
	case MCFG:
		return 1;
	case TCPA:
		return 2;
	case TPM2:
		return 4;
	case SSDT: /* ACPI 3.0 up to 6.3: 2 */
		return 2;
	case SRAT: /* ACPI 2.0: 1, ACPI 3.0: 2, ACPI 4.0 up to 6.4: 3 */
		return 3;
	case HMAT: /* ACPI 6.4: 2 */
		return 2;
	case DMAR:
		return 1;
	case SLIT: /* ACPI 2.0 up to 6.3: 1 */
		return 1;
	case SPMI: /* IMPI 2.0 */
		return 5;
	case HPET: /* Currently 1. Table added in ACPI 2.0. */
		return 1;
	case VFCT: /* ACPI 2.0/3.0/4.0: 1 */
		return 1;
	case IVRS:
		return IVRS_FORMAT_MIXED;
	case DBG2:
		return 0;
	case FACS: /* ACPI 2.0/3.0: 1, ACPI 4.0 up to 6.3: 2 */
		return 1;
	case RSDT: /* ACPI 1.0 up to 6.3: 1 */
		return 1;
	case XSDT: /* ACPI 2.0 up to 6.3: 1 */
		return 1;
	case RSDP: /* ACPI 2.0 up to 6.3: 2 */
		return 2;
	case EINJ:
		return 1;
	case HEST:
		return 1;
	case NHLT:
		return 5;
	case BERT:
		return 1;
	case CEDT: /* CXL 3.0 section 9.17.1 */
		return 1;
	case CRAT:
		return 1;
	case LPIT: /* ACPI 5.1 up to 6.3: 0 */
		return 0;
	case SPCR:
		return 4;
	case GTDT:
		return 3;
	case PPTT: /* ACPI 6.4 */
		return 3;
	case IORT: /* IO Remapping Table E.e */
		return 6;
	case WDAT:
		return 1;
	default:
		return -1;
	}
	return -1;
}
