/******************************************************************************
 *
 * Module Name: tbxfroot - Find the root ACPI table (RSDT)
 *
 *****************************************************************************/

/*
 * Copyright (C) 2000 - 2005, R. Byron Moore
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification.
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 *    substantially similar to the "NO WARRANTY" disclaimer below
 *    ("Disclaimer") and any redistribution must be conditioned upon
 *    including a substantially similar Disclaimer requirement for further
 *    binary redistribution.
 * 3. Neither the names of the above-listed copyright holders nor the names
 *    of any contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 *
 * NO WARRANTY
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 */

#include <linux/module.h>

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


#define _COMPONENT          ACPI_TABLES
	 ACPI_MODULE_NAME    ("tbxfroot")

/* Local prototypes */

static acpi_status
acpi_tb_find_rsdp (
	struct acpi_table_desc          *table_info,
	u32                             flags);

static u8 *
acpi_tb_scan_memory_for_rsdp (
	u8                              *start_address,
	u32                             length);


/*******************************************************************************
 *
 * FUNCTION:    acpi_tb_find_table
 *
 * PARAMETERS:  Signature           - String with ACPI table signature
 *              oem_id              - String with the table OEM ID
 *              oem_table_id        - String with the OEM Table ID
 *              table_ptr           - Where the table pointer is returned
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the
 *              Signature, OEM ID and OEM Table ID.
 *
 ******************************************************************************/

acpi_status
acpi_tb_find_table (
	char                            *signature,
	char                            *oem_id,
	char                            *oem_table_id,
	struct acpi_table_header        **table_ptr)
{
	acpi_status                     status;
	struct acpi_table_header        *table;


	ACPI_FUNCTION_TRACE ("tb_find_table");


	/* Validate string lengths */

	if ((ACPI_STRLEN (signature)  > ACPI_NAME_SIZE) ||
		(ACPI_STRLEN (oem_id)     > sizeof (table->oem_id)) ||
		(ACPI_STRLEN (oem_table_id) > sizeof (table->oem_table_id))) {
		return_ACPI_STATUS (AE_AML_STRING_LIMIT);
	}

	if (!ACPI_STRNCMP (signature, DSDT_SIG, ACPI_NAME_SIZE)) {
		/*
		 * The DSDT pointer is contained in the FADT, not the RSDT.
		 * This code should suffice, because the only code that would perform
		 * a "find" on the DSDT is the data_table_region() AML opcode -- in
		 * which case, the DSDT is guaranteed to be already loaded.
		 * If this becomes insufficient, the FADT will have to be found first.
		 */
		if (!acpi_gbl_DSDT) {
			return_ACPI_STATUS (AE_NO_ACPI_TABLES);
		}
		table = acpi_gbl_DSDT;
	}
	else {
		/* Find the table */

		status = acpi_get_firmware_table (signature, 1,
				 ACPI_LOGICAL_ADDRESSING, &table);
		if (ACPI_FAILURE (status)) {
			return_ACPI_STATUS (status);
		}
	}

	/* Check oem_id and oem_table_id */

	if ((oem_id[0] && ACPI_STRNCMP (
			   oem_id, table->oem_id,
			   sizeof (table->oem_id))) ||

		(oem_table_id[0] && ACPI_STRNCMP (
				   oem_table_id, table->oem_table_id,
				   sizeof (table->oem_table_id)))) {
		return_ACPI_STATUS (AE_AML_NAME_NOT_FOUND);
	}

	ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Found table [%4.4s]\n",
		table->signature));

	*table_ptr = table;
	return_ACPI_STATUS (AE_OK);
}


/*******************************************************************************
 *
 * FUNCTION:    acpi_get_firmware_table
 *
 * PARAMETERS:  Signature       - Any ACPI table signature
 *              Instance        - the non zero instance of the table, allows
 *                                support for multiple tables of the same type
 *              Flags           - Physical/Virtual support
 *              table_pointer   - Where a buffer containing the table is
 *                                returned
 *
 * RETURN:      Status
 *
 * DESCRIPTION: This function is called to get an ACPI table. A buffer is
 *              allocated for the table and returned in table_pointer.
 *              This table will be a complete table including the header.
 *
 ******************************************************************************/

acpi_status
acpi_get_firmware_table (
	acpi_string                     signature,
	u32                             instance,
	u32                             flags,
	struct acpi_table_header        **table_pointer)
{
	acpi_status                     status;
	struct acpi_pointer             address;
	struct acpi_table_header        *header = NULL;
	struct acpi_table_desc          *table_info = NULL;
	struct acpi_table_desc          *rsdt_info;
	u32                             table_count;
	u32                             i;
	u32                             j;


	ACPI_FUNCTION_TRACE ("acpi_get_firmware_table");


	/*
	 * Ensure that at least the table manager is initialized.  We don't
	 * require that the entire ACPI subsystem is up for this interface.
	 * If we have a buffer, we must have a length too
	 */
	if ((instance == 0)     ||
		(!signature)        ||
		(!table_pointer)) {
		return_ACPI_STATUS (AE_BAD_PARAMETER);
	}

	/* Ensure that we have a RSDP */

	if (!acpi_gbl_RSDP) {
		/* Get the RSDP */

		status = acpi_os_get_root_pointer (flags, &address);
		if (ACPI_FAILURE (status)) {
			ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "RSDP not found\n"));
			return_ACPI_STATUS (AE_NO_ACPI_TABLES);
		}

		/* Map and validate the RSDP */

		if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
			status = acpi_os_map_memory (address.pointer.physical,
					 sizeof (struct rsdp_descriptor), (void *) &acpi_gbl_RSDP);
			if (ACPI_FAILURE (status)) {
				return_ACPI_STATUS (status);
			}
		}
		else {
			acpi_gbl_RSDP = address.pointer.logical;
		}

		/* The signature and checksum must both be correct */

		if (ACPI_STRNCMP ((char *) acpi_gbl_RSDP, RSDP_SIG,
				sizeof (RSDP_SIG)-1) != 0) {
			/* Nope, BAD Signature */

			return_ACPI_STATUS (AE_BAD_SIGNATURE);
		}

		if (acpi_tb_checksum (acpi_gbl_RSDP, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
			/* Nope, BAD Checksum */

			return_ACPI_STATUS (AE_BAD_CHECKSUM);
		}
	}

	/* Get the RSDT address via the RSDP */

	acpi_tb_get_rsdt_address (&address);
	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
		"RSDP located at %p, RSDT physical=%8.8X%8.8X \n",
		acpi_gbl_RSDP,
		ACPI_FORMAT_UINT64 (address.pointer.value)));

	/* Insert processor_mode flags */

	address.pointer_type |= flags;

	/* Get and validate the RSDT */

	rsdt_info = ACPI_MEM_CALLOCATE (sizeof (struct acpi_table_desc));
	if (!rsdt_info) {
		return_ACPI_STATUS (AE_NO_MEMORY);
	}

	status = acpi_tb_get_table (&address, rsdt_info);
	if (ACPI_FAILURE (status)) {
		goto cleanup;
	}

	status = acpi_tb_validate_rsdt (rsdt_info->pointer);
	if (ACPI_FAILURE (status)) {
		goto cleanup;
	}

	/* Allocate a scratch table header and table descriptor */

	header = ACPI_MEM_ALLOCATE (sizeof (struct acpi_table_header));
	if (!header) {
		status = AE_NO_MEMORY;
		goto cleanup;
	}

	table_info = ACPI_MEM_ALLOCATE (sizeof (struct acpi_table_desc));
	if (!table_info) {
		status = AE_NO_MEMORY;
		goto cleanup;
	}

	/* Get the number of table pointers within the RSDT */

	table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, rsdt_info->pointer);
	address.pointer_type = acpi_gbl_table_flags | flags;

	/*
	 * Search the RSDT/XSDT for the correct instance of the
	 * requested table
	 */
	for (i = 0, j = 0; i < table_count; i++) {
		/* Get the next table pointer, handle RSDT vs. XSDT */

		if (acpi_gbl_RSDP->revision < 2) {
			address.pointer.value = (ACPI_CAST_PTR (
				RSDT_DESCRIPTOR, rsdt_info->pointer))->table_offset_entry[i];
		}
		else {
			address.pointer.value = (ACPI_CAST_PTR (
				XSDT_DESCRIPTOR, rsdt_info->pointer))->table_offset_entry[i];
		}

		/* Get the table header */

		status = acpi_tb_get_table_header (&address, header);
		if (ACPI_FAILURE (status)) {
			goto cleanup;
		}

		/* Compare table signatures and table instance */

		if (!ACPI_STRNCMP (header->signature, signature, ACPI_NAME_SIZE)) {
			/* An instance of the table was found */

			j++;
			if (j >= instance) {
				/* Found the correct instance, get the entire table */

				status = acpi_tb_get_table_body (&address, header, table_info);
				if (ACPI_FAILURE (status)) {
					goto cleanup;
				}

				*table_pointer = table_info->pointer;
				goto cleanup;
			}
		}
	}

	/* Did not find the table */

	status = AE_NOT_EXIST;


cleanup:
	if (rsdt_info->pointer) {
		acpi_os_unmap_memory (rsdt_info->pointer,
			(acpi_size) rsdt_info->pointer->length);
	}
	ACPI_MEM_FREE (rsdt_info);

	if (header) {
		ACPI_MEM_FREE (header);
	}
	if (table_info) {
		ACPI_MEM_FREE (table_info);
	}
	return_ACPI_STATUS (status);
}
EXPORT_SYMBOL(acpi_get_firmware_table);


/* TBD: Move to a new file */

#if ACPI_MACHINE_WIDTH != 16

/*******************************************************************************
 *
 * FUNCTION:    acpi_find_root_pointer
 *
 * PARAMETERS:  Flags                   - Logical/Physical addressing
 *              rsdp_address            - Where to place the RSDP address
 *
 * RETURN:      Status, Physical address of the RSDP
 *
 * DESCRIPTION: Find the RSDP
 *
 ******************************************************************************/

acpi_status
acpi_find_root_pointer (
	u32                             flags,
	struct acpi_pointer             *rsdp_address)
{
	struct acpi_table_desc          table_info;
	acpi_status                     status;


	ACPI_FUNCTION_TRACE ("acpi_find_root_pointer");


	/* Get the RSDP */

	status = acpi_tb_find_rsdp (&table_info, flags);
	if (ACPI_FAILURE (status)) {
		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
			"RSDP structure not found, %s Flags=%X\n",
			acpi_format_exception (status), flags));

		return_ACPI_STATUS (AE_NO_ACPI_TABLES);
	}

	rsdp_address->pointer_type = ACPI_PHYSICAL_POINTER;
	rsdp_address->pointer.physical = table_info.physical_address;
	return_ACPI_STATUS (AE_OK);
}


/*******************************************************************************
 *
 * FUNCTION:    acpi_tb_scan_memory_for_rsdp
 *
 * PARAMETERS:  start_address       - Starting pointer for search
 *              Length              - Maximum length to search
 *
 * RETURN:      Pointer to the RSDP if found, otherwise NULL.
 *
 * DESCRIPTION: Search a block of memory for the RSDP signature
 *
 ******************************************************************************/

static u8 *
acpi_tb_scan_memory_for_rsdp (
	u8                              *start_address,
	u32                             length)
{
	u8                              *mem_rover;
	u8                              *end_address;
	u8                              checksum;


	ACPI_FUNCTION_TRACE ("tb_scan_memory_for_rsdp");


	end_address = start_address + length;

	/* Search from given start address for the requested length */

	for (mem_rover = start_address; mem_rover < end_address;
		 mem_rover += ACPI_RSDP_SCAN_STEP) {
		/* The signature and checksum must both be correct */

		if (ACPI_STRNCMP ((char *) mem_rover,
				RSDP_SIG, sizeof (RSDP_SIG) - 1) != 0) {
			/* No signature match, keep looking */

			continue;
		}

		/* Signature matches, check the appropriate checksum */

		if ((ACPI_CAST_PTR (struct rsdp_descriptor, mem_rover))->revision < 2) {
			/* ACPI version 1.0 */

			checksum = acpi_tb_checksum (mem_rover, ACPI_RSDP_CHECKSUM_LENGTH);
		}
		else {
			/* Post ACPI 1.0, use extended_checksum */

			checksum = acpi_tb_checksum (mem_rover, ACPI_RSDP_XCHECKSUM_LENGTH);
		}

		if (checksum == 0) {
			/* Checksum valid, we have found a valid RSDP */

			ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
				"RSDP located at physical address %p\n", mem_rover));
			return_PTR (mem_rover);
		}

		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
			"Found an RSDP at physical address %p, but it has a bad checksum\n",
			mem_rover));
	}

	/* Searched entire block, no RSDP was found */

	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
		"Searched entire block, no valid RSDP was found.\n"));
	return_PTR (NULL);
}


/*******************************************************************************
 *
 * FUNCTION:    acpi_tb_find_rsdp
 *
 * PARAMETERS:  table_info              - Where the table info is returned
 *              Flags                   - Current memory mode (logical vs.
 *                                        physical addressing)
 *
 * RETURN:      Status, RSDP physical address
 *
 * DESCRIPTION: search lower 1_mbyte of memory for the root system descriptor
 *              pointer structure.  If it is found, set *RSDP to point to it.
 *
 *              NOTE1: The RSDp must be either in the first 1_k of the Extended
 *              BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.)
 *              Only a 32-bit physical address is necessary.
 *
 *              NOTE2: This function is always available, regardless of the
 *              initialization state of the rest of ACPI.
 *
 ******************************************************************************/

static acpi_status
acpi_tb_find_rsdp (
	struct acpi_table_desc          *table_info,
	u32                             flags)
{
	u8                              *table_ptr;
	u8                              *mem_rover;
	u32                             physical_address;
	acpi_status                     status;


	ACPI_FUNCTION_TRACE ("tb_find_rsdp");


	/*
	 * Scan supports either logical addressing or physical addressing
	 */
	if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
		/* 1a) Get the location of the Extended BIOS Data Area (EBDA) */

		status = acpi_os_map_memory (
				 (acpi_physical_address) ACPI_EBDA_PTR_LOCATION,
				 ACPI_EBDA_PTR_LENGTH, (void *) &table_ptr);
		if (ACPI_FAILURE (status)) {
			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
				"Could not map memory at %8.8X for length %X\n",
				ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH));

			return_ACPI_STATUS (status);
		}

		ACPI_MOVE_16_TO_32 (&physical_address, table_ptr);

		/* Convert segment part to physical address */

		physical_address <<= 4;
		acpi_os_unmap_memory (table_ptr, ACPI_EBDA_PTR_LENGTH);

		/* EBDA present? */

		if (physical_address > 0x400) {
			/*
			 * 1b) Search EBDA paragraphs (EBDa is required to be a
			 *     minimum of 1_k length)
			 */
			status = acpi_os_map_memory (
					 (acpi_physical_address) physical_address,
					 ACPI_EBDA_WINDOW_SIZE, (void *) &table_ptr);
			if (ACPI_FAILURE (status)) {
				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
					"Could not map memory at %8.8X for length %X\n",
					physical_address, ACPI_EBDA_WINDOW_SIZE));

				return_ACPI_STATUS (status);
			}

			mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr,
					  ACPI_EBDA_WINDOW_SIZE);
			acpi_os_unmap_memory (table_ptr, ACPI_EBDA_WINDOW_SIZE);

			if (mem_rover) {
				/* Found it, return the physical address */

				physical_address += ACPI_PTR_DIFF (mem_rover, table_ptr);

				table_info->physical_address =
					(acpi_physical_address) physical_address;
				return_ACPI_STATUS (AE_OK);
			}
		}

		/*
		 * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh
		 */
		status = acpi_os_map_memory (
				 (acpi_physical_address) ACPI_HI_RSDP_WINDOW_BASE,
				 ACPI_HI_RSDP_WINDOW_SIZE, (void *) &table_ptr);

		if (ACPI_FAILURE (status)) {
			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
				"Could not map memory at %8.8X for length %X\n",
				ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE));

			return_ACPI_STATUS (status);
		}

		mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);
		acpi_os_unmap_memory (table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);

		if (mem_rover) {
			/* Found it, return the physical address */

			physical_address =
				ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF (mem_rover, table_ptr);

			table_info->physical_address =
				(acpi_physical_address) physical_address;
			return_ACPI_STATUS (AE_OK);
		}
	}

	/*
	 * Physical addressing
	 */
	else {
		/* 1a) Get the location of the EBDA */

		ACPI_MOVE_16_TO_32 (&physical_address, ACPI_EBDA_PTR_LOCATION);
		physical_address <<= 4;     /* Convert segment to physical address */

		/* EBDA present? */

		if (physical_address > 0x400) {
			/*
			 * 1b) Search EBDA paragraphs (EBDa is required to be a minimum of
			 *     1_k length)
			 */
			mem_rover = acpi_tb_scan_memory_for_rsdp (
					  ACPI_PHYSADDR_TO_PTR (physical_address),
					  ACPI_EBDA_WINDOW_SIZE);
			if (mem_rover) {
				/* Found it, return the physical address */

				table_info->physical_address = ACPI_TO_INTEGER (mem_rover);
				return_ACPI_STATUS (AE_OK);
			}
		}

		/* 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh */

		mem_rover = acpi_tb_scan_memory_for_rsdp (
				  ACPI_PHYSADDR_TO_PTR (ACPI_HI_RSDP_WINDOW_BASE),
				  ACPI_HI_RSDP_WINDOW_SIZE);
		if (mem_rover) {
			/* Found it, return the physical address */

			table_info->physical_address = ACPI_TO_INTEGER (mem_rover);
			return_ACPI_STATUS (AE_OK);
		}
	}

	/* RSDP signature was not found */

	return_ACPI_STATUS (AE_NOT_FOUND);
}

#endif

