// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
/******************************************************************************
 *
 * Module Name: tbutils - ACPI Table utilities
 *
 * Copyright (C) 2000 - 2018, Intel Corp.
 *
 *****************************************************************************/

#include <acpi/acpi.h>
#include "accommon.h"
#include "actables.h"

#define _COMPONENT          ACPI_TABLES
ACPI_MODULE_NAME("tbutils")

/* Local prototypes */
static acpi_physical_address
acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size);

#if (!ACPI_REDUCED_HARDWARE)
/*******************************************************************************
 *
 * FUNCTION:    acpi_tb_initialize_facs
 *
 * PARAMETERS:  None
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Create a permanent mapping for the FADT and save it in a global
 *              for accessing the Global Lock and Firmware Waking Vector
 *
 ******************************************************************************/

acpi_status acpi_tb_initialize_facs(void)
{
	struct acpi_table_facs *facs;

	/* If Hardware Reduced flag is set, there is no FACS */

	if (acpi_gbl_reduced_hardware) {
		acpi_gbl_FACS = NULL;
		return (AE_OK);
	} else if (acpi_gbl_FADT.Xfacs &&
		   (!acpi_gbl_FADT.facs
		    || !acpi_gbl_use32_bit_facs_addresses)) {
		(void)acpi_get_table_by_index(acpi_gbl_xfacs_index,
					      ACPI_CAST_INDIRECT_PTR(struct
								     acpi_table_header,
								     &facs));
		acpi_gbl_FACS = facs;
	} else if (acpi_gbl_FADT.facs) {
		(void)acpi_get_table_by_index(acpi_gbl_facs_index,
					      ACPI_CAST_INDIRECT_PTR(struct
								     acpi_table_header,
								     &facs));
		acpi_gbl_FACS = facs;
	}

	/* If there is no FACS, just continue. There was already an error msg */

	return (AE_OK);
}
#endif				/* !ACPI_REDUCED_HARDWARE */

/*******************************************************************************
 *
 * FUNCTION:    acpi_tb_check_dsdt_header
 *
 * PARAMETERS:  None
 *
 * RETURN:      None
 *
 * DESCRIPTION: Quick compare to check validity of the DSDT. This will detect
 *              if the DSDT has been replaced from outside the OS and/or if
 *              the DSDT header has been corrupted.
 *
 ******************************************************************************/

void acpi_tb_check_dsdt_header(void)
{

	/* Compare original length and checksum to current values */

	if (acpi_gbl_original_dsdt_header.length != acpi_gbl_DSDT->length ||
	    acpi_gbl_original_dsdt_header.checksum != acpi_gbl_DSDT->checksum) {
		ACPI_BIOS_ERROR((AE_INFO,
				 "The DSDT has been corrupted or replaced - "
				 "old, new headers below"));

		acpi_tb_print_table_header(0, &acpi_gbl_original_dsdt_header);
		acpi_tb_print_table_header(0, acpi_gbl_DSDT);

		ACPI_ERROR((AE_INFO,
			    "Please send DMI info to linux-acpi@vger.kernel.org\n"
			    "If system does not work as expected, please boot with acpi=copy_dsdt"));

		/* Disable further error messages */

		acpi_gbl_original_dsdt_header.length = acpi_gbl_DSDT->length;
		acpi_gbl_original_dsdt_header.checksum =
		    acpi_gbl_DSDT->checksum;
	}
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_tb_copy_dsdt
 *
 * PARAMETERS:  table_index         - Index of installed table to copy
 *
 * RETURN:      The copied DSDT
 *
 * DESCRIPTION: Implements a subsystem option to copy the DSDT to local memory.
 *              Some very bad BIOSs are known to either corrupt the DSDT or
 *              install a new, bad DSDT. This copy works around the problem.
 *
 ******************************************************************************/

struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index)
{
	struct acpi_table_header *new_table;
	struct acpi_table_desc *table_desc;

	table_desc = &acpi_gbl_root_table_list.tables[table_index];

	new_table = ACPI_ALLOCATE(table_desc->length);
	if (!new_table) {
		ACPI_ERROR((AE_INFO, "Could not copy DSDT of length 0x%X",
			    table_desc->length));
		return (NULL);
	}

	memcpy(new_table, table_desc->pointer, table_desc->length);
	acpi_tb_uninstall_table(table_desc);

	acpi_tb_init_table_descriptor(&acpi_gbl_root_table_list.
				      tables[acpi_gbl_dsdt_index],
				      ACPI_PTR_TO_PHYSADDR(new_table),
				      ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL,
				      new_table);

	ACPI_INFO(("Forced DSDT copy: length 0x%05X copied locally, original unmapped", new_table->length));

	return (new_table);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_tb_get_root_table_entry
 *
 * PARAMETERS:  table_entry         - Pointer to the RSDT/XSDT table entry
 *              table_entry_size    - sizeof 32 or 64 (RSDT or XSDT)
 *
 * RETURN:      Physical address extracted from the root table
 *
 * DESCRIPTION: Get one root table entry. Handles 32-bit and 64-bit cases on
 *              both 32-bit and 64-bit platforms
 *
 * NOTE:        acpi_physical_address is 32-bit on 32-bit platforms, 64-bit on
 *              64-bit platforms.
 *
 ******************************************************************************/

static acpi_physical_address
acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size)
{
	u64 address64;

	/*
	 * Get the table physical address (32-bit for RSDT, 64-bit for XSDT):
	 * Note: Addresses are 32-bit aligned (not 64) in both RSDT and XSDT
	 */
	if (table_entry_size == ACPI_RSDT_ENTRY_SIZE) {
		/*
		 * 32-bit platform, RSDT: Return 32-bit table entry
		 * 64-bit platform, RSDT: Expand 32-bit to 64-bit and return
		 */
		return ((acpi_physical_address)
			(*ACPI_CAST_PTR(u32, table_entry)));
	} else {
		/*
		 * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return
		 * 64-bit platform, XSDT: Move (unaligned) 64-bit to local,
		 *  return 64-bit
		 */
		ACPI_MOVE_64_TO_64(&address64, table_entry);

#if ACPI_MACHINE_WIDTH == 32
		if (address64 > ACPI_UINT32_MAX) {

			/* Will truncate 64-bit address to 32 bits, issue warning */

			ACPI_BIOS_WARNING((AE_INFO,
					   "64-bit Physical Address in XSDT is too large (0x%8.8X%8.8X),"
					   " truncating",
					   ACPI_FORMAT_UINT64(address64)));
		}
#endif
		return ((acpi_physical_address)(address64));
	}
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_tb_parse_root_table
 *
 * PARAMETERS:  rsdp_address        - Pointer to the RSDP
 *
 * RETURN:      Status
 *
 * DESCRIPTION: This function is called to parse the Root System Description
 *              Table (RSDT or XSDT)
 *
 * NOTE:        Tables are mapped (not copied) for efficiency. The FACS must
 *              be mapped and cannot be copied because it contains the actual
 *              memory location of the ACPI Global Lock.
 *
 ******************************************************************************/

acpi_status ACPI_INIT_FUNCTION
acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
{
	struct acpi_table_rsdp *rsdp;
	u32 table_entry_size;
	u32 i;
	u32 table_count;
	struct acpi_table_header *table;
	acpi_physical_address address;
	u32 length;
	u8 *table_entry;
	acpi_status status;
	u32 table_index;

	ACPI_FUNCTION_TRACE(tb_parse_root_table);

	/* Map the entire RSDP and extract the address of the RSDT or XSDT */

	rsdp = acpi_os_map_memory(rsdp_address, sizeof(struct acpi_table_rsdp));
	if (!rsdp) {
		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	acpi_tb_print_table_header(rsdp_address,
				   ACPI_CAST_PTR(struct acpi_table_header,
						 rsdp));

	/* Use XSDT if present and not overridden. Otherwise, use RSDT */

	if ((rsdp->revision > 1) &&
	    rsdp->xsdt_physical_address && !acpi_gbl_do_not_use_xsdt) {
		/*
		 * RSDP contains an XSDT (64-bit physical addresses). We must use
		 * the XSDT if the revision is > 1 and the XSDT pointer is present,
		 * as per the ACPI specification.
		 */
		address = (acpi_physical_address)rsdp->xsdt_physical_address;
		table_entry_size = ACPI_XSDT_ENTRY_SIZE;
	} else {
		/* Root table is an RSDT (32-bit physical addresses) */

		address = (acpi_physical_address)rsdp->rsdt_physical_address;
		table_entry_size = ACPI_RSDT_ENTRY_SIZE;
	}

	/*
	 * It is not possible to map more than one entry in some environments,
	 * so unmap the RSDP here before mapping other tables
	 */
	acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp));

	/* Map the RSDT/XSDT table header to get the full table length */

	table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
	if (!table) {
		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	acpi_tb_print_table_header(address, table);

	/*
	 * Validate length of the table, and map entire table.
	 * Minimum length table must contain at least one entry.
	 */
	length = table->length;
	acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));

	if (length < (sizeof(struct acpi_table_header) + table_entry_size)) {
		ACPI_BIOS_ERROR((AE_INFO,
				 "Invalid table length 0x%X in RSDT/XSDT",
				 length));
		return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
	}

	table = acpi_os_map_memory(address, length);
	if (!table) {
		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	/* Validate the root table checksum */

	status = acpi_tb_verify_checksum(table, length);
	if (ACPI_FAILURE(status)) {
		acpi_os_unmap_memory(table, length);
		return_ACPI_STATUS(status);
	}

	/* Get the number of entries and pointer to first entry */

	table_count = (u32)((table->length - sizeof(struct acpi_table_header)) /
			    table_entry_size);
	table_entry = ACPI_ADD_PTR(u8, table, sizeof(struct acpi_table_header));

	/* Initialize the root table array from the RSDT/XSDT */

	for (i = 0; i < table_count; i++) {

		/* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */

		address =
		    acpi_tb_get_root_table_entry(table_entry, table_entry_size);

		/* Skip NULL entries in RSDT/XSDT */

		if (!address) {
			goto next_table;
		}

		status = acpi_tb_install_standard_table(address,
							ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL,
							FALSE, TRUE,
							&table_index);

		if (ACPI_SUCCESS(status) &&
		    ACPI_COMPARE_NAME(&acpi_gbl_root_table_list.
				      tables[table_index].signature,
				      ACPI_SIG_FADT)) {
			acpi_gbl_fadt_index = table_index;
			acpi_tb_parse_fadt();
		}

next_table:

		table_entry += table_entry_size;
	}

	acpi_os_unmap_memory(table, length);
	return_ACPI_STATUS(AE_OK);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_tb_get_table
 *
 * PARAMETERS:  table_desc          - Table descriptor
 *              out_table           - Where the pointer to the table is returned
 *
 * RETURN:      Status and pointer to the requested table
 *
 * DESCRIPTION: Increase a reference to a table descriptor and return the
 *              validated table pointer.
 *              If the table descriptor is an entry of the root table list,
 *              this API must be invoked with ACPI_MTX_TABLES acquired.
 *
 ******************************************************************************/

acpi_status
acpi_tb_get_table(struct acpi_table_desc *table_desc,
		  struct acpi_table_header **out_table)
{
	acpi_status status;

	ACPI_FUNCTION_TRACE(acpi_tb_get_table);

	if (table_desc->validation_count == 0) {

		/* Table need to be "VALIDATED" */

		status = acpi_tb_validate_table(table_desc);
		if (ACPI_FAILURE(status)) {
			return_ACPI_STATUS(status);
		}
	}

	if (table_desc->validation_count < ACPI_MAX_TABLE_VALIDATIONS) {
		table_desc->validation_count++;

		/*
		 * Detect validation_count overflows to ensure that the warning
		 * message will only be printed once.
		 */
		if (table_desc->validation_count >= ACPI_MAX_TABLE_VALIDATIONS) {
			ACPI_WARNING((AE_INFO,
				      "Table %p, Validation count overflows\n",
				      table_desc));
		}
	}

	*out_table = table_desc->pointer;
	return_ACPI_STATUS(AE_OK);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_tb_put_table
 *
 * PARAMETERS:  table_desc          - Table descriptor
 *
 * RETURN:      None
 *
 * DESCRIPTION: Decrease a reference to a table descriptor and release the
 *              validated table pointer if no references.
 *              If the table descriptor is an entry of the root table list,
 *              this API must be invoked with ACPI_MTX_TABLES acquired.
 *
 ******************************************************************************/

void acpi_tb_put_table(struct acpi_table_desc *table_desc)
{

	ACPI_FUNCTION_TRACE(acpi_tb_put_table);

	if (table_desc->validation_count < ACPI_MAX_TABLE_VALIDATIONS) {
		table_desc->validation_count--;

		/*
		 * Detect validation_count underflows to ensure that the warning
		 * message will only be printed once.
		 */
		if (table_desc->validation_count >= ACPI_MAX_TABLE_VALIDATIONS) {
			ACPI_WARNING((AE_INFO,
				      "Table %p, Validation count underflows\n",
				      table_desc));
			return_VOID;
		}
	}

	if (table_desc->validation_count == 0) {

		/* Table need to be "INVALIDATED" */

		acpi_tb_invalidate_table(table_desc);
	}

	return_VOID;
}
