summaryrefslogtreecommitdiffstats
path: root/sys/contrib/dev/acpica/components/tables
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2012-02-16 22:59:29 +0000
committerjkim <jkim@FreeBSD.org>2012-02-16 22:59:29 +0000
commita561c762bacb78b14d2bf5fb20afc1566203f990 (patch)
treed4ae2db1980d2ec7b164b1a5658fd2ae62569456 /sys/contrib/dev/acpica/components/tables
parent2b86faa18cb89921d202e133fa6a1c39b63cfe16 (diff)
parenta6dfe3119152f97e640cc135d963b9f7c95c84ef (diff)
downloadFreeBSD-src-a561c762bacb78b14d2bf5fb20afc1566203f990.zip
FreeBSD-src-a561c762bacb78b14d2bf5fb20afc1566203f990.tar.gz
Merge ACPICA 20120215.
Diffstat (limited to 'sys/contrib/dev/acpica/components/tables')
-rw-r--r--sys/contrib/dev/acpica/components/tables/tbfadt.c704
-rw-r--r--sys/contrib/dev/acpica/components/tables/tbfind.c143
-rw-r--r--sys/contrib/dev/acpica/components/tables/tbinstal.c806
-rw-r--r--sys/contrib/dev/acpica/components/tables/tbutils.c775
-rw-r--r--sys/contrib/dev/acpica/components/tables/tbxface.c722
-rw-r--r--sys/contrib/dev/acpica/components/tables/tbxfroot.c299
6 files changed, 3449 insertions, 0 deletions
diff --git a/sys/contrib/dev/acpica/components/tables/tbfadt.c b/sys/contrib/dev/acpica/components/tables/tbfadt.c
new file mode 100644
index 0000000..b137446
--- /dev/null
+++ b/sys/contrib/dev/acpica/components/tables/tbfadt.c
@@ -0,0 +1,704 @@
+/******************************************************************************
+ *
+ * Module Name: tbfadt - FADT table utilities
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * 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.
+ */
+
+#define __TBFADT_C__
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+#define _COMPONENT ACPI_TABLES
+ ACPI_MODULE_NAME ("tbfadt")
+
+/* Local prototypes */
+
+static ACPI_INLINE void
+AcpiTbInitGenericAddress (
+ ACPI_GENERIC_ADDRESS *GenericAddress,
+ UINT8 SpaceId,
+ UINT8 ByteWidth,
+ UINT64 Address);
+
+static void
+AcpiTbConvertFadt (
+ void);
+
+static void
+AcpiTbValidateFadt (
+ void);
+
+static void
+AcpiTbSetupFadtRegisters (
+ void);
+
+
+/* Table for conversion of FADT to common internal format and FADT validation */
+
+typedef struct acpi_fadt_info
+{
+ char *Name;
+ UINT16 Address64;
+ UINT16 Address32;
+ UINT16 Length;
+ UINT8 DefaultLength;
+ UINT8 Type;
+
+} ACPI_FADT_INFO;
+
+#define ACPI_FADT_OPTIONAL 0
+#define ACPI_FADT_REQUIRED 1
+#define ACPI_FADT_SEPARATE_LENGTH 2
+
+static ACPI_FADT_INFO FadtInfoTable[] =
+{
+ {"Pm1aEventBlock",
+ ACPI_FADT_OFFSET (XPm1aEventBlock),
+ ACPI_FADT_OFFSET (Pm1aEventBlock),
+ ACPI_FADT_OFFSET (Pm1EventLength),
+ ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */
+ ACPI_FADT_REQUIRED},
+
+ {"Pm1bEventBlock",
+ ACPI_FADT_OFFSET (XPm1bEventBlock),
+ ACPI_FADT_OFFSET (Pm1bEventBlock),
+ ACPI_FADT_OFFSET (Pm1EventLength),
+ ACPI_PM1_REGISTER_WIDTH * 2, /* Enable + Status register */
+ ACPI_FADT_OPTIONAL},
+
+ {"Pm1aControlBlock",
+ ACPI_FADT_OFFSET (XPm1aControlBlock),
+ ACPI_FADT_OFFSET (Pm1aControlBlock),
+ ACPI_FADT_OFFSET (Pm1ControlLength),
+ ACPI_PM1_REGISTER_WIDTH,
+ ACPI_FADT_REQUIRED},
+
+ {"Pm1bControlBlock",
+ ACPI_FADT_OFFSET (XPm1bControlBlock),
+ ACPI_FADT_OFFSET (Pm1bControlBlock),
+ ACPI_FADT_OFFSET (Pm1ControlLength),
+ ACPI_PM1_REGISTER_WIDTH,
+ ACPI_FADT_OPTIONAL},
+
+ {"Pm2ControlBlock",
+ ACPI_FADT_OFFSET (XPm2ControlBlock),
+ ACPI_FADT_OFFSET (Pm2ControlBlock),
+ ACPI_FADT_OFFSET (Pm2ControlLength),
+ ACPI_PM2_REGISTER_WIDTH,
+ ACPI_FADT_SEPARATE_LENGTH},
+
+ {"PmTimerBlock",
+ ACPI_FADT_OFFSET (XPmTimerBlock),
+ ACPI_FADT_OFFSET (PmTimerBlock),
+ ACPI_FADT_OFFSET (PmTimerLength),
+ ACPI_PM_TIMER_WIDTH,
+ ACPI_FADT_REQUIRED},
+
+ {"Gpe0Block",
+ ACPI_FADT_OFFSET (XGpe0Block),
+ ACPI_FADT_OFFSET (Gpe0Block),
+ ACPI_FADT_OFFSET (Gpe0BlockLength),
+ 0,
+ ACPI_FADT_SEPARATE_LENGTH},
+
+ {"Gpe1Block",
+ ACPI_FADT_OFFSET (XGpe1Block),
+ ACPI_FADT_OFFSET (Gpe1Block),
+ ACPI_FADT_OFFSET (Gpe1BlockLength),
+ 0,
+ ACPI_FADT_SEPARATE_LENGTH}
+};
+
+#define ACPI_FADT_INFO_ENTRIES \
+ (sizeof (FadtInfoTable) / sizeof (ACPI_FADT_INFO))
+
+
+/* Table used to split Event Blocks into separate status/enable registers */
+
+typedef struct acpi_fadt_pm_info
+{
+ ACPI_GENERIC_ADDRESS *Target;
+ UINT16 Source;
+ UINT8 RegisterNum;
+
+} ACPI_FADT_PM_INFO;
+
+static ACPI_FADT_PM_INFO FadtPmInfoTable[] =
+{
+ {&AcpiGbl_XPm1aStatus,
+ ACPI_FADT_OFFSET (XPm1aEventBlock),
+ 0},
+
+ {&AcpiGbl_XPm1aEnable,
+ ACPI_FADT_OFFSET (XPm1aEventBlock),
+ 1},
+
+ {&AcpiGbl_XPm1bStatus,
+ ACPI_FADT_OFFSET (XPm1bEventBlock),
+ 0},
+
+ {&AcpiGbl_XPm1bEnable,
+ ACPI_FADT_OFFSET (XPm1bEventBlock),
+ 1}
+};
+
+#define ACPI_FADT_PM_INFO_ENTRIES \
+ (sizeof (FadtPmInfoTable) / sizeof (ACPI_FADT_PM_INFO))
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbInitGenericAddress
+ *
+ * PARAMETERS: GenericAddress - GAS struct to be initialized
+ * SpaceId - ACPI Space ID for this register
+ * ByteWidth - Width of this register, in bytes
+ * Address - Address of the register
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Initialize a Generic Address Structure (GAS)
+ * See the ACPI specification for a full description and
+ * definition of this structure.
+ *
+ ******************************************************************************/
+
+static ACPI_INLINE void
+AcpiTbInitGenericAddress (
+ ACPI_GENERIC_ADDRESS *GenericAddress,
+ UINT8 SpaceId,
+ UINT8 ByteWidth,
+ UINT64 Address)
+{
+
+ /*
+ * The 64-bit Address field is non-aligned in the byte packed
+ * GAS struct.
+ */
+ ACPI_MOVE_64_TO_64 (&GenericAddress->Address, &Address);
+
+ /* All other fields are byte-wide */
+
+ GenericAddress->SpaceId = SpaceId;
+ GenericAddress->BitWidth = (UINT8) ACPI_MUL_8 (ByteWidth);
+ GenericAddress->BitOffset = 0;
+ GenericAddress->AccessWidth = 0; /* Access width ANY */
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbParseFadt
+ *
+ * PARAMETERS: TableIndex - Index for the FADT
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Initialize the FADT, DSDT and FACS tables
+ * (FADT contains the addresses of the DSDT and FACS)
+ *
+ ******************************************************************************/
+
+void
+AcpiTbParseFadt (
+ UINT32 TableIndex)
+{
+ UINT32 Length;
+ ACPI_TABLE_HEADER *Table;
+
+
+ /*
+ * The FADT has multiple versions with different lengths,
+ * and it contains pointers to both the DSDT and FACS tables.
+ *
+ * Get a local copy of the FADT and convert it to a common format
+ * Map entire FADT, assumed to be smaller than one page.
+ */
+ Length = AcpiGbl_RootTableList.Tables[TableIndex].Length;
+
+ Table = AcpiOsMapMemory (
+ AcpiGbl_RootTableList.Tables[TableIndex].Address, Length);
+ if (!Table)
+ {
+ return;
+ }
+
+ /*
+ * Validate the FADT checksum before we copy the table. Ignore
+ * checksum error as we want to try to get the DSDT and FACS.
+ */
+ (void) AcpiTbVerifyChecksum (Table, Length);
+
+ /* Create a local copy of the FADT in common ACPI 2.0+ format */
+
+ AcpiTbCreateLocalFadt (Table, Length);
+
+ /* All done with the real FADT, unmap it */
+
+ AcpiOsUnmapMemory (Table, Length);
+
+ /* Obtain the DSDT and FACS tables via their addresses within the FADT */
+
+ AcpiTbInstallTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XDsdt,
+ ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);
+
+ /* If Hardware Reduced flag is set, there is no FACS */
+
+ if (!AcpiGbl_ReducedHardware)
+ {
+ AcpiTbInstallTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XFacs,
+ ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbCreateLocalFadt
+ *
+ * PARAMETERS: Table - Pointer to BIOS FADT
+ * Length - Length of the table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Get a local copy of the FADT and convert it to a common format.
+ * Performs validation on some important FADT fields.
+ *
+ * NOTE: We create a local copy of the FADT regardless of the version.
+ *
+ ******************************************************************************/
+
+void
+AcpiTbCreateLocalFadt (
+ ACPI_TABLE_HEADER *Table,
+ UINT32 Length)
+{
+
+ /*
+ * Check if the FADT is larger than the largest table that we expect
+ * (the ACPI 5.0 version). If so, truncate the table, and issue
+ * a warning.
+ */
+ if (Length > sizeof (ACPI_TABLE_FADT))
+ {
+ ACPI_WARNING ((AE_INFO,
+ "FADT (revision %u) is longer than ACPI 5.0 version, "
+ "truncating length %u to %u",
+ Table->Revision, Length, (UINT32) sizeof (ACPI_TABLE_FADT)));
+ }
+
+ /* Clear the entire local FADT */
+
+ ACPI_MEMSET (&AcpiGbl_FADT, 0, sizeof (ACPI_TABLE_FADT));
+
+ /* Copy the original FADT, up to sizeof (ACPI_TABLE_FADT) */
+
+ ACPI_MEMCPY (&AcpiGbl_FADT, Table,
+ ACPI_MIN (Length, sizeof (ACPI_TABLE_FADT)));
+
+ /* Take a copy of the Hardware Reduced flag */
+
+ AcpiGbl_ReducedHardware = FALSE;
+ if (AcpiGbl_FADT.Flags & ACPI_FADT_HW_REDUCED)
+ {
+ AcpiGbl_ReducedHardware = TRUE;
+ }
+
+ /* Convert the local copy of the FADT to the common internal format */
+
+ AcpiTbConvertFadt ();
+
+ /* Validate FADT values now, before we make any changes */
+
+ AcpiTbValidateFadt ();
+
+ /* Initialize the global ACPI register structures */
+
+ AcpiTbSetupFadtRegisters ();
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbConvertFadt
+ *
+ * PARAMETERS: None, uses AcpiGbl_FADT
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Converts all versions of the FADT to a common internal format.
+ * Expand 32-bit addresses to 64-bit as necessary.
+ *
+ * NOTE: AcpiGbl_FADT must be of size (ACPI_TABLE_FADT),
+ * and must contain a copy of the actual FADT.
+ *
+ * Notes on 64-bit register addresses:
+ *
+ * After this FADT conversion, later ACPICA code will only use the 64-bit "X"
+ * fields of the FADT for all ACPI register addresses.
+ *
+ * The 64-bit "X" fields are optional extensions to the original 32-bit FADT
+ * V1.0 fields. Even if they are present in the FADT, they are optional and
+ * are unused if the BIOS sets them to zero. Therefore, we must copy/expand
+ * 32-bit V1.0 fields if the corresponding X field is zero.
+ *
+ * For ACPI 1.0 FADTs, all 32-bit address fields are expanded to the
+ * corresponding "X" fields in the internal FADT.
+ *
+ * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded
+ * to the corresponding 64-bit X fields. For compatibility with other ACPI
+ * implementations, we ignore the 64-bit field if the 32-bit field is valid,
+ * regardless of whether the host OS is 32-bit or 64-bit.
+ *
+ ******************************************************************************/
+
+static void
+AcpiTbConvertFadt (
+ void)
+{
+ ACPI_GENERIC_ADDRESS *Address64;
+ UINT32 Address32;
+ UINT32 i;
+
+
+ /* Update the local FADT table header length */
+
+ AcpiGbl_FADT.Header.Length = sizeof (ACPI_TABLE_FADT);
+
+ /*
+ * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary.
+ * Later code will always use the X 64-bit field.
+ */
+ if (!AcpiGbl_FADT.XFacs)
+ {
+ AcpiGbl_FADT.XFacs = (UINT64) AcpiGbl_FADT.Facs;
+ }
+ if (!AcpiGbl_FADT.XDsdt)
+ {
+ AcpiGbl_FADT.XDsdt = (UINT64) AcpiGbl_FADT.Dsdt;
+ }
+
+ /*
+ * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which
+ * should be zero are indeed zero. This will workaround BIOSs that
+ * inadvertently place values in these fields.
+ *
+ * The ACPI 1.0 reserved fields that will be zeroed are the bytes located
+ * at offset 45, 55, 95, and the word located at offset 109, 110.
+ *
+ * Note: The FADT revision value is unreliable. Only the length can be
+ * trusted.
+ */
+ if (AcpiGbl_FADT.Header.Length <= ACPI_FADT_V2_SIZE)
+ {
+ AcpiGbl_FADT.PreferredProfile = 0;
+ AcpiGbl_FADT.PstateControl = 0;
+ AcpiGbl_FADT.CstControl = 0;
+ AcpiGbl_FADT.BootFlags = 0;
+ }
+
+ /*
+ * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
+ * generic address structures as necessary. Later code will always use
+ * the 64-bit address structures.
+ *
+ * March 2009:
+ * We now always use the 32-bit address if it is valid (non-null). This
+ * is not in accordance with the ACPI specification which states that
+ * the 64-bit address supersedes the 32-bit version, but we do this for
+ * compatibility with other ACPI implementations. Most notably, in the
+ * case where both the 32 and 64 versions are non-null, we use the 32-bit
+ * version. This is the only address that is guaranteed to have been
+ * tested by the BIOS manufacturer.
+ */
+ for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)
+ {
+ Address32 = *ACPI_ADD_PTR (UINT32,
+ &AcpiGbl_FADT, FadtInfoTable[i].Address32);
+
+ Address64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS,
+ &AcpiGbl_FADT, FadtInfoTable[i].Address64);
+
+ /*
+ * If both 32- and 64-bit addresses are valid (non-zero),
+ * they must match.
+ */
+ if (Address64->Address && Address32 &&
+ (Address64->Address != (UINT64) Address32))
+ {
+ ACPI_ERROR ((AE_INFO,
+ "32/64X address mismatch in %s: 0x%8.8X/0x%8.8X%8.8X, using 32",
+ FadtInfoTable[i].Name, Address32,
+ ACPI_FORMAT_UINT64 (Address64->Address)));
+ }
+
+ /* Always use 32-bit address if it is valid (non-null) */
+
+ if (Address32)
+ {
+ /*
+ * Copy the 32-bit address to the 64-bit GAS structure. The
+ * Space ID is always I/O for 32-bit legacy address fields
+ */
+ AcpiTbInitGenericAddress (Address64, ACPI_ADR_SPACE_SYSTEM_IO,
+ *ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT, FadtInfoTable[i].Length),
+ (UINT64) Address32);
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbValidateFadt
+ *
+ * PARAMETERS: Table - Pointer to the FADT to be validated
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Validate various important fields within the FADT. If a problem
+ * is found, issue a message, but no status is returned.
+ * Used by both the table manager and the disassembler.
+ *
+ * Possible additional checks:
+ * (AcpiGbl_FADT.Pm1EventLength >= 4)
+ * (AcpiGbl_FADT.Pm1ControlLength >= 2)
+ * (AcpiGbl_FADT.PmTimerLength >= 4)
+ * Gpe block lengths must be multiple of 2
+ *
+ ******************************************************************************/
+
+static void
+AcpiTbValidateFadt (
+ void)
+{
+ char *Name;
+ ACPI_GENERIC_ADDRESS *Address64;
+ UINT8 Length;
+ UINT32 i;
+
+
+ /*
+ * Check for FACS and DSDT address mismatches. An address mismatch between
+ * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and
+ * DSDT/X_DSDT) would indicate the presence of two FACS or two DSDT tables.
+ */
+ if (AcpiGbl_FADT.Facs &&
+ (AcpiGbl_FADT.XFacs != (UINT64) AcpiGbl_FADT.Facs))
+ {
+ ACPI_WARNING ((AE_INFO,
+ "32/64X FACS address mismatch in FADT - "
+ "0x%8.8X/0x%8.8X%8.8X, using 32",
+ AcpiGbl_FADT.Facs, ACPI_FORMAT_UINT64 (AcpiGbl_FADT.XFacs)));
+
+ AcpiGbl_FADT.XFacs = (UINT64) AcpiGbl_FADT.Facs;
+ }
+
+ if (AcpiGbl_FADT.Dsdt &&
+ (AcpiGbl_FADT.XDsdt != (UINT64) AcpiGbl_FADT.Dsdt))
+ {
+ ACPI_WARNING ((AE_INFO,
+ "32/64X DSDT address mismatch in FADT - "
+ "0x%8.8X/0x%8.8X%8.8X, using 32",
+ AcpiGbl_FADT.Dsdt, ACPI_FORMAT_UINT64 (AcpiGbl_FADT.XDsdt)));
+
+ AcpiGbl_FADT.XDsdt = (UINT64) AcpiGbl_FADT.Dsdt;
+ }
+
+ /* If Hardware Reduced flag is set, we are all done */
+
+ if (AcpiGbl_ReducedHardware)
+ {
+ return;
+ }
+
+ /* Examine all of the 64-bit extended address fields (X fields) */
+
+ for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)
+ {
+ /*
+ * Generate pointer to the 64-bit address, get the register
+ * length (width) and the register name
+ */
+ Address64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS,
+ &AcpiGbl_FADT, FadtInfoTable[i].Address64);
+ Length = *ACPI_ADD_PTR (UINT8,
+ &AcpiGbl_FADT, FadtInfoTable[i].Length);
+ Name = FadtInfoTable[i].Name;
+
+ /*
+ * For each extended field, check for length mismatch between the
+ * legacy length field and the corresponding 64-bit X length field.
+ */
+ if (Address64->Address &&
+ (Address64->BitWidth != ACPI_MUL_8 (Length)))
+ {
+ ACPI_WARNING ((AE_INFO,
+ "32/64X length mismatch in %s: %u/%u",
+ Name, ACPI_MUL_8 (Length), Address64->BitWidth));
+ }
+
+ if (FadtInfoTable[i].Type & ACPI_FADT_REQUIRED)
+ {
+ /*
+ * Field is required (PM1aEvent, PM1aControl, PmTimer).
+ * Both the address and length must be non-zero.
+ */
+ if (!Address64->Address || !Length)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Required field %s has zero address and/or length:"
+ " 0x%8.8X%8.8X/0x%X",
+ Name, ACPI_FORMAT_UINT64 (Address64->Address), Length));
+ }
+ }
+ else if (FadtInfoTable[i].Type & ACPI_FADT_SEPARATE_LENGTH)
+ {
+ /*
+ * Field is optional (PM2Control, GPE0, GPE1) AND has its own
+ * length field. If present, both the address and length must
+ * be valid.
+ */
+ if ((Address64->Address && !Length) ||
+ (!Address64->Address && Length))
+ {
+ ACPI_WARNING ((AE_INFO,
+ "Optional field %s has zero address or length: "
+ "0x%8.8X%8.8X/0x%X",
+ Name, ACPI_FORMAT_UINT64 (Address64->Address), Length));
+ }
+ }
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbSetupFadtRegisters
+ *
+ * PARAMETERS: None, uses AcpiGbl_FADT.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Initialize global ACPI PM1 register definitions. Optionally,
+ * force FADT register definitions to their default lengths.
+ *
+ ******************************************************************************/
+
+static void
+AcpiTbSetupFadtRegisters (
+ void)
+{
+ ACPI_GENERIC_ADDRESS *Target64;
+ ACPI_GENERIC_ADDRESS *Source64;
+ UINT8 Pm1RegisterByteWidth;
+ UINT32 i;
+
+
+ /*
+ * Optionally check all register lengths against the default values and
+ * update them if they are incorrect.
+ */
+ if (AcpiGbl_UseDefaultRegisterWidths)
+ {
+ for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)
+ {
+ Target64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT,
+ FadtInfoTable[i].Address64);
+
+ /*
+ * If a valid register (Address != 0) and the (DefaultLength > 0)
+ * (Not a GPE register), then check the width against the default.
+ */
+ if ((Target64->Address) &&
+ (FadtInfoTable[i].DefaultLength > 0) &&
+ (FadtInfoTable[i].DefaultLength != Target64->BitWidth))
+ {
+ ACPI_WARNING ((AE_INFO,
+ "Invalid length for %s: %u, using default %u",
+ FadtInfoTable[i].Name, Target64->BitWidth,
+ FadtInfoTable[i].DefaultLength));
+
+ /* Incorrect size, set width to the default */
+
+ Target64->BitWidth = FadtInfoTable[i].DefaultLength;
+ }
+ }
+ }
+
+ /*
+ * Get the length of the individual PM1 registers (enable and status).
+ * Each register is defined to be (event block length / 2). Extra divide
+ * by 8 converts bits to bytes.
+ */
+ Pm1RegisterByteWidth = (UINT8)
+ ACPI_DIV_16 (AcpiGbl_FADT.XPm1aEventBlock.BitWidth);
+
+ /*
+ * Calculate separate GAS structs for the PM1x (A/B) Status and Enable
+ * registers. These addresses do not appear (directly) in the FADT, so it
+ * is useful to pre-calculate them from the PM1 Event Block definitions.
+ *
+ * The PM event blocks are split into two register blocks, first is the
+ * PM Status Register block, followed immediately by the PM Enable
+ * Register block. Each is of length (Pm1EventLength/2)
+ *
+ * Note: The PM1A event block is required by the ACPI specification.
+ * However, the PM1B event block is optional and is rarely, if ever,
+ * used.
+ */
+
+ for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++)
+ {
+ Source64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT,
+ FadtPmInfoTable[i].Source);
+
+ if (Source64->Address)
+ {
+ AcpiTbInitGenericAddress (FadtPmInfoTable[i].Target,
+ Source64->SpaceId, Pm1RegisterByteWidth,
+ Source64->Address +
+ (FadtPmInfoTable[i].RegisterNum * Pm1RegisterByteWidth));
+ }
+ }
+}
+
diff --git a/sys/contrib/dev/acpica/components/tables/tbfind.c b/sys/contrib/dev/acpica/components/tables/tbfind.c
new file mode 100644
index 0000000..f3acb42
--- /dev/null
+++ b/sys/contrib/dev/acpica/components/tables/tbfind.c
@@ -0,0 +1,143 @@
+/******************************************************************************
+ *
+ * Module Name: tbfind - find table
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * 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.
+ */
+
+#define __TBFIND_C__
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+#define _COMPONENT ACPI_TABLES
+ ACPI_MODULE_NAME ("tbfind")
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbFindTable
+ *
+ * PARAMETERS: Signature - String with ACPI table signature
+ * OemId - String with the table OEM ID
+ * OemTableId - String with the OEM Table ID
+ * TableIndex - Where the table index is returned
+ *
+ * RETURN: Status and table index
+ *
+ * DESCRIPTION: Find an ACPI table (in the RSDT/XSDT) that matches the
+ * Signature, OEM ID and OEM Table ID. Returns an index that can
+ * be used to get the table header or entire table.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiTbFindTable (
+ char *Signature,
+ char *OemId,
+ char *OemTableId,
+ UINT32 *TableIndex)
+{
+ UINT32 i;
+ ACPI_STATUS Status;
+ ACPI_TABLE_HEADER Header;
+
+
+ ACPI_FUNCTION_TRACE (TbFindTable);
+
+
+ /* Normalize the input strings */
+
+ ACPI_MEMSET (&Header, 0, sizeof (ACPI_TABLE_HEADER));
+ ACPI_STRNCPY (Header.Signature, Signature, ACPI_NAME_SIZE);
+ ACPI_STRNCPY (Header.OemId, OemId, ACPI_OEM_ID_SIZE);
+ ACPI_STRNCPY (Header.OemTableId, OemTableId, ACPI_OEM_TABLE_ID_SIZE);
+
+ /* Search for the table */
+
+ for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
+ {
+ if (ACPI_MEMCMP (&(AcpiGbl_RootTableList.Tables[i].Signature),
+ Header.Signature, ACPI_NAME_SIZE))
+ {
+ /* Not the requested table */
+
+ continue;
+ }
+
+ /* Table with matching signature has been found */
+
+ if (!AcpiGbl_RootTableList.Tables[i].Pointer)
+ {
+ /* Table is not currently mapped, map it */
+
+ Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ if (!AcpiGbl_RootTableList.Tables[i].Pointer)
+ {
+ continue;
+ }
+ }
+
+ /* Check for table match on all IDs */
+
+ if (!ACPI_MEMCMP (AcpiGbl_RootTableList.Tables[i].Pointer->Signature,
+ Header.Signature, ACPI_NAME_SIZE) &&
+ (!OemId[0] ||
+ !ACPI_MEMCMP (AcpiGbl_RootTableList.Tables[i].Pointer->OemId,
+ Header.OemId, ACPI_OEM_ID_SIZE)) &&
+ (!OemTableId[0] ||
+ !ACPI_MEMCMP (AcpiGbl_RootTableList.Tables[i].Pointer->OemTableId,
+ Header.OemTableId, ACPI_OEM_TABLE_ID_SIZE)))
+ {
+ *TableIndex = i;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Found table [%4.4s]\n",
+ Header.Signature));
+ return_ACPI_STATUS (AE_OK);
+ }
+ }
+
+ return_ACPI_STATUS (AE_NOT_FOUND);
+}
diff --git a/sys/contrib/dev/acpica/components/tables/tbinstal.c b/sys/contrib/dev/acpica/components/tables/tbinstal.c
new file mode 100644
index 0000000..e178d94
--- /dev/null
+++ b/sys/contrib/dev/acpica/components/tables/tbinstal.c
@@ -0,0 +1,806 @@
+/******************************************************************************
+ *
+ * Module Name: tbinstal - ACPI table installation and removal
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * 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.
+ */
+
+
+#define __TBINSTAL_C__
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+
+#define _COMPONENT ACPI_TABLES
+ ACPI_MODULE_NAME ("tbinstal")
+
+
+/******************************************************************************
+ *
+ * FUNCTION: AcpiTbVerifyTable
+ *
+ * PARAMETERS: TableDesc - table
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: this function is called to verify and map table
+ *
+ *****************************************************************************/
+
+ACPI_STATUS
+AcpiTbVerifyTable (
+ ACPI_TABLE_DESC *TableDesc)
+{
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (TbVerifyTable);
+
+
+ /* Map the table if necessary */
+
+ if (!TableDesc->Pointer)
+ {
+ if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) ==
+ ACPI_TABLE_ORIGIN_MAPPED)
+ {
+ TableDesc->Pointer = AcpiOsMapMemory (
+ TableDesc->Address, TableDesc->Length);
+ }
+
+ if (!TableDesc->Pointer)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+ }
+
+ /* FACS is the odd table, has no standard ACPI header and no checksum */
+
+ if (!ACPI_COMPARE_NAME (&TableDesc->Signature, ACPI_SIG_FACS))
+ {
+ /* Always calculate checksum, ignore bad checksum if requested */
+
+ Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length);
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbAddTable
+ *
+ * PARAMETERS: TableDesc - Table descriptor
+ * TableIndex - Where the table index is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to add an ACPI table. It is used to
+ * dynamically load tables via the Load and LoadTable AML
+ * operators.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiTbAddTable (
+ ACPI_TABLE_DESC *TableDesc,
+ UINT32 *TableIndex)
+{
+ UINT32 i;
+ ACPI_STATUS Status = AE_OK;
+
+
+ ACPI_FUNCTION_TRACE (TbAddTable);
+
+
+ if (!TableDesc->Pointer)
+ {
+ Status = AcpiTbVerifyTable (TableDesc);
+ if (ACPI_FAILURE (Status) || !TableDesc->Pointer)
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ /*
+ * Validate the incoming table signature.
+ *
+ * 1) Originally, we checked the table signature for "SSDT" or "PSDT".
+ * 2) We added support for OEMx tables, signature "OEM".
+ * 3) Valid tables were encountered with a null signature, so we just
+ * gave up on validating the signature, (05/2008).
+ * 4) We encountered non-AML tables such as the MADT, which caused
+ * interpreter errors and kernel faults. So now, we once again allow
+ * only "SSDT", "OEMx", and now, also a null signature. (05/2011).
+ */
+ if ((TableDesc->Pointer->Signature[0] != 0x00) &&
+ (!ACPI_COMPARE_NAME (TableDesc->Pointer->Signature, ACPI_SIG_SSDT)) &&
+ (ACPI_STRNCMP (TableDesc->Pointer->Signature, "OEM", 3)))
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Table has invalid signature [%4.4s] (0x%8.8X), must be SSDT or OEMx",
+ AcpiUtValidAcpiName (*(UINT32 *) TableDesc->Pointer->Signature) ?
+ TableDesc->Pointer->Signature : "????",
+ *(UINT32 *) TableDesc->Pointer->Signature));
+
+ return_ACPI_STATUS (AE_BAD_SIGNATURE);
+ }
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+
+ /* Check if table is already registered */
+
+ for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
+ {
+ if (!AcpiGbl_RootTableList.Tables[i].Pointer)
+ {
+ Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]);
+ if (ACPI_FAILURE (Status) ||
+ !AcpiGbl_RootTableList.Tables[i].Pointer)
+ {
+ continue;
+ }
+ }
+
+ /*
+ * Check for a table match on the entire table length,
+ * not just the header.
+ */
+ if (TableDesc->Length != AcpiGbl_RootTableList.Tables[i].Length)
+ {
+ continue;
+ }
+
+ if (ACPI_MEMCMP (TableDesc->Pointer,
+ AcpiGbl_RootTableList.Tables[i].Pointer,
+ AcpiGbl_RootTableList.Tables[i].Length))
+ {
+ continue;
+ }
+
+ /*
+ * Note: the current mechanism does not unregister a table if it is
+ * dynamically unloaded. The related namespace entries are deleted,
+ * but the table remains in the root table list.
+ *
+ * The assumption here is that the number of different tables that
+ * will be loaded is actually small, and there is minimal overhead
+ * in just keeping the table in case it is needed again.
+ *
+ * If this assumption changes in the future (perhaps on large
+ * machines with many table load/unload operations), tables will
+ * need to be unregistered when they are unloaded, and slots in the
+ * root table list should be reused when empty.
+ */
+
+ /*
+ * Table is already registered.
+ * We can delete the table that was passed as a parameter.
+ */
+ AcpiTbDeleteTable (TableDesc);
+ *TableIndex = i;
+
+ if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED)
+ {
+ /* Table is still loaded, this is an error */
+
+ Status = AE_ALREADY_EXISTS;
+ goto Release;
+ }
+ else
+ {
+ /* Table was unloaded, allow it to be reloaded */
+
+ TableDesc->Pointer = AcpiGbl_RootTableList.Tables[i].Pointer;
+ TableDesc->Address = AcpiGbl_RootTableList.Tables[i].Address;
+ Status = AE_OK;
+ goto PrintHeader;
+ }
+ }
+
+ /*
+ * ACPI Table Override:
+ * Allow the host to override dynamically loaded tables.
+ * NOTE: the table is fully mapped at this point, and the mapping will
+ * be deleted by TbTableOverride if the table is actually overridden.
+ */
+ (void) AcpiTbTableOverride (TableDesc->Pointer, TableDesc);
+
+ /* Add the table to the global root table list */
+
+ Status = AcpiTbStoreTable (TableDesc->Address, TableDesc->Pointer,
+ TableDesc->Length, TableDesc->Flags, TableIndex);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Release;
+ }
+
+PrintHeader:
+ AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);
+
+Release:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbTableOverride
+ *
+ * PARAMETERS: TableHeader - Header for the original table
+ * TableDesc - Table descriptor initialized for the
+ * original table. May or may not be mapped.
+ *
+ * RETURN: Pointer to the entire new table. NULL if table not overridden.
+ * If overridden, installs the new table within the input table
+ * descriptor.
+ *
+ * DESCRIPTION: Attempt table override by calling the OSL override functions.
+ * Note: If the table is overridden, then the entire new table
+ * is mapped and returned by this function.
+ *
+ ******************************************************************************/
+
+ACPI_TABLE_HEADER *
+AcpiTbTableOverride (
+ ACPI_TABLE_HEADER *TableHeader,
+ ACPI_TABLE_DESC *TableDesc)
+{
+ ACPI_STATUS Status;
+ ACPI_TABLE_HEADER *NewTable = NULL;
+ ACPI_PHYSICAL_ADDRESS NewAddress = 0;
+ UINT32 NewTableLength = 0;
+ UINT8 NewFlags;
+ char *OverrideType;
+
+
+ /* (1) Attempt logical override (returns a logical address) */
+
+ Status = AcpiOsTableOverride (TableHeader, &NewTable);
+ if (ACPI_SUCCESS (Status) && NewTable)
+ {
+ NewAddress = ACPI_PTR_TO_PHYSADDR (NewTable);
+ NewTableLength = NewTable->Length;
+ NewFlags = ACPI_TABLE_ORIGIN_OVERRIDE;
+ OverrideType = "Logical";
+ goto FinishOverride;
+ }
+
+ /* (2) Attempt physical override (returns a physical address) */
+
+ Status = AcpiOsPhysicalTableOverride (TableHeader,
+ &NewAddress, &NewTableLength);
+ if (ACPI_SUCCESS (Status) && NewAddress && NewTableLength)
+ {
+ /* Map the entire new table */
+
+ NewTable = AcpiOsMapMemory (NewAddress, NewTableLength);
+ if (!NewTable)
+ {
+ ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
+ "%4.4s %p Attempted physical table override failed",
+ TableHeader->Signature,
+ ACPI_CAST_PTR (void, TableDesc->Address)));
+ return (NULL);
+ }
+
+ OverrideType = "Physical";
+ NewFlags = ACPI_TABLE_ORIGIN_MAPPED;
+ goto FinishOverride;
+ }
+
+ return (NULL); /* There was no override */
+
+
+FinishOverride:
+
+ ACPI_INFO ((AE_INFO,
+ "%4.4s %p %s table override, new table: %p",
+ TableHeader->Signature,
+ ACPI_CAST_PTR (void, TableDesc->Address),
+ OverrideType, NewTable));
+
+ /* We can now unmap/delete the original table (if fully mapped) */
+
+ AcpiTbDeleteTable (TableDesc);
+
+ /* Setup descriptor for the new table */
+
+ TableDesc->Address = NewAddress;
+ TableDesc->Pointer = NewTable;
+ TableDesc->Length = NewTableLength;
+ TableDesc->Flags = NewFlags;
+
+ return (NewTable);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbResizeRootTableList
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Expand the size of global table array
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiTbResizeRootTableList (
+ void)
+{
+ ACPI_TABLE_DESC *Tables;
+
+
+ ACPI_FUNCTION_TRACE (TbResizeRootTableList);
+
+
+ /* AllowResize flag is a parameter to AcpiInitializeTables */
+
+ if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE))
+ {
+ ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed"));
+ return_ACPI_STATUS (AE_SUPPORT);
+ }
+
+ /* Increase the Table Array size */
+
+ Tables = ACPI_ALLOCATE_ZEROED (
+ ((ACPI_SIZE) AcpiGbl_RootTableList.MaxTableCount +
+ ACPI_ROOT_TABLE_SIZE_INCREMENT) *
+ sizeof (ACPI_TABLE_DESC));
+ if (!Tables)
+ {
+ ACPI_ERROR ((AE_INFO, "Could not allocate new root table array"));
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Copy and free the previous table array */
+
+ if (AcpiGbl_RootTableList.Tables)
+ {
+ ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables,
+ (ACPI_SIZE) AcpiGbl_RootTableList.MaxTableCount * sizeof (ACPI_TABLE_DESC));
+
+ if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
+ {
+ ACPI_FREE (AcpiGbl_RootTableList.Tables);
+ }
+ }
+
+ AcpiGbl_RootTableList.Tables = Tables;
+ AcpiGbl_RootTableList.MaxTableCount += ACPI_ROOT_TABLE_SIZE_INCREMENT;
+ AcpiGbl_RootTableList.Flags |= (UINT8) ACPI_ROOT_ORIGIN_ALLOCATED;
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbStoreTable
+ *
+ * PARAMETERS: Address - Table address
+ * Table - Table header
+ * Length - Table length
+ * Flags - flags
+ *
+ * RETURN: Status and table index.
+ *
+ * DESCRIPTION: Add an ACPI table to the global table list
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiTbStoreTable (
+ ACPI_PHYSICAL_ADDRESS Address,
+ ACPI_TABLE_HEADER *Table,
+ UINT32 Length,
+ UINT8 Flags,
+ UINT32 *TableIndex)
+{
+ ACPI_STATUS Status;
+ ACPI_TABLE_DESC *NewTable;
+
+
+ /* Ensure that there is room for the table in the Root Table List */
+
+ if (AcpiGbl_RootTableList.CurrentTableCount >=
+ AcpiGbl_RootTableList.MaxTableCount)
+ {
+ Status = AcpiTbResizeRootTableList();
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+
+ NewTable = &AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount];
+
+ /* Initialize added table */
+
+ NewTable->Address = Address;
+ NewTable->Pointer = Table;
+ NewTable->Length = Length;
+ NewTable->OwnerId = 0;
+ NewTable->Flags = Flags;
+
+ ACPI_MOVE_32_TO_32 (&NewTable->Signature, Table->Signature);
+
+ *TableIndex = AcpiGbl_RootTableList.CurrentTableCount;
+ AcpiGbl_RootTableList.CurrentTableCount++;
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbDeleteTable
+ *
+ * PARAMETERS: TableIndex - Table index
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Delete one internal ACPI table
+ *
+ ******************************************************************************/
+
+void
+AcpiTbDeleteTable (
+ ACPI_TABLE_DESC *TableDesc)
+{
+
+ /* Table must be mapped or allocated */
+
+ if (!TableDesc->Pointer)
+ {
+ return;
+ }
+
+ switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
+ {
+ case ACPI_TABLE_ORIGIN_MAPPED:
+ AcpiOsUnmapMemory (TableDesc->Pointer, TableDesc->Length);
+ break;
+
+ case ACPI_TABLE_ORIGIN_ALLOCATED:
+ ACPI_FREE (TableDesc->Pointer);
+ break;
+
+ default:
+ break;
+ }
+
+ TableDesc->Pointer = NULL;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbTerminate
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Delete all internal ACPI tables
+ *
+ ******************************************************************************/
+
+void
+AcpiTbTerminate (
+ void)
+{
+ UINT32 i;
+
+
+ ACPI_FUNCTION_TRACE (TbTerminate);
+
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+
+ /* Delete the individual tables */
+
+ for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
+ {
+ AcpiTbDeleteTable (&AcpiGbl_RootTableList.Tables[i]);
+ }
+
+ /*
+ * Delete the root table array if allocated locally. Array cannot be
+ * mapped, so we don't need to check for that flag.
+ */
+ if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
+ {
+ ACPI_FREE (AcpiGbl_RootTableList.Tables);
+ }
+
+ AcpiGbl_RootTableList.Tables = NULL;
+ AcpiGbl_RootTableList.Flags = 0;
+ AcpiGbl_RootTableList.CurrentTableCount = 0;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbDeleteNamespaceByOwner
+ *
+ * PARAMETERS: TableIndex - Table index
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Delete all namespace objects created when this table was loaded.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiTbDeleteNamespaceByOwner (
+ UINT32 TableIndex)
+{
+ ACPI_OWNER_ID OwnerId;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner);
+
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
+ {
+ /* The table index does not exist */
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
+ /* Get the owner ID for this table, used to delete namespace nodes */
+
+ OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+
+ /*
+ * Need to acquire the namespace writer lock to prevent interference
+ * with any concurrent namespace walks. The interpreter must be
+ * released during the deletion since the acquisition of the deletion
+ * lock may block, and also since the execution of a namespace walk
+ * must be allowed to use the interpreter.
+ */
+ (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
+ Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock);
+
+ AcpiNsDeleteNamespaceByOwner (OwnerId);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock);
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbAllocateOwnerId
+ *
+ * PARAMETERS: TableIndex - Table index
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Allocates OwnerId in TableDesc
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiTbAllocateOwnerId (
+ UINT32 TableIndex)
+{
+ ACPI_STATUS Status = AE_BAD_PARAMETER;
+
+
+ ACPI_FUNCTION_TRACE (TbAllocateOwnerId);
+
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+ if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
+ {
+ Status = AcpiUtAllocateOwnerId
+ (&(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
+ }
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbReleaseOwnerId
+ *
+ * PARAMETERS: TableIndex - Table index
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Releases OwnerId in TableDesc
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiTbReleaseOwnerId (
+ UINT32 TableIndex)
+{
+ ACPI_STATUS Status = AE_BAD_PARAMETER;
+
+
+ ACPI_FUNCTION_TRACE (TbReleaseOwnerId);
+
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+ if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
+ {
+ AcpiUtReleaseOwnerId (
+ &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
+ Status = AE_OK;
+ }
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbGetOwnerId
+ *
+ * PARAMETERS: TableIndex - Table index
+ * OwnerId - Where the table OwnerId is returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: returns OwnerId for the ACPI table
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiTbGetOwnerId (
+ UINT32 TableIndex,
+ ACPI_OWNER_ID *OwnerId)
+{
+ ACPI_STATUS Status = AE_BAD_PARAMETER;
+
+
+ ACPI_FUNCTION_TRACE (TbGetOwnerId);
+
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+ if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
+ {
+ *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
+ Status = AE_OK;
+ }
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbIsTableLoaded
+ *
+ * PARAMETERS: TableIndex - Table index
+ *
+ * RETURN: Table Loaded Flag
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiTbIsTableLoaded (
+ UINT32 TableIndex)
+{
+ BOOLEAN IsLoaded = FALSE;
+
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+ if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
+ {
+ IsLoaded = (BOOLEAN)
+ (AcpiGbl_RootTableList.Tables[TableIndex].Flags &
+ ACPI_TABLE_IS_LOADED);
+ }
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ return (IsLoaded);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbSetTableLoadedFlag
+ *
+ * PARAMETERS: TableIndex - Table index
+ * IsLoaded - TRUE if table is loaded, FALSE otherwise
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
+ *
+ ******************************************************************************/
+
+void
+AcpiTbSetTableLoadedFlag (
+ UINT32 TableIndex,
+ BOOLEAN IsLoaded)
+{
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+ if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
+ {
+ if (IsLoaded)
+ {
+ AcpiGbl_RootTableList.Tables[TableIndex].Flags |=
+ ACPI_TABLE_IS_LOADED;
+ }
+ else
+ {
+ AcpiGbl_RootTableList.Tables[TableIndex].Flags &=
+ ~ACPI_TABLE_IS_LOADED;
+ }
+ }
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+}
+
diff --git a/sys/contrib/dev/acpica/components/tables/tbutils.c b/sys/contrib/dev/acpica/components/tables/tbutils.c
new file mode 100644
index 0000000..02ee3e6
--- /dev/null
+++ b/sys/contrib/dev/acpica/components/tables/tbutils.c
@@ -0,0 +1,775 @@
+/******************************************************************************
+ *
+ * Module Name: tbutils - table utilities
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * 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.
+ */
+
+#define __TBUTILS_C__
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+#define _COMPONENT ACPI_TABLES
+ ACPI_MODULE_NAME ("tbutils")
+
+
+/* Local prototypes */
+
+static void
+AcpiTbFixString (
+ char *String,
+ ACPI_SIZE Length);
+
+static void
+AcpiTbCleanupTableHeader (
+ ACPI_TABLE_HEADER *OutHeader,
+ ACPI_TABLE_HEADER *Header);
+
+static ACPI_PHYSICAL_ADDRESS
+AcpiTbGetRootTableEntry (
+ UINT8 *TableEntry,
+ UINT32 TableEntrySize);
+
+
+#if (!ACPI_REDUCED_HARDWARE)
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbInitializeFacs
+ *
+ * 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
+AcpiTbInitializeFacs (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ /* If Hardware Reduced flag is set, there is no FACS */
+
+ if (AcpiGbl_ReducedHardware)
+ {
+ AcpiGbl_FACS = NULL;
+ return (AE_OK);
+ }
+
+ Status = AcpiGetTableByIndex (ACPI_TABLE_INDEX_FACS,
+ ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &AcpiGbl_FACS));
+ return (Status);
+}
+#endif /* !ACPI_REDUCED_HARDWARE */
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbTablesLoaded
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: TRUE if required ACPI tables are loaded
+ *
+ * DESCRIPTION: Determine if the minimum required ACPI tables are present
+ * (FADT, FACS, DSDT)
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiTbTablesLoaded (
+ void)
+{
+
+ if (AcpiGbl_RootTableList.CurrentTableCount >= 3)
+ {
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbFixString
+ *
+ * PARAMETERS: String - String to be repaired
+ * Length - Maximum length
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Replace every non-printable or non-ascii byte in the string
+ * with a question mark '?'.
+ *
+ ******************************************************************************/
+
+static void
+AcpiTbFixString (
+ char *String,
+ ACPI_SIZE Length)
+{
+
+ while (Length && *String)
+ {
+ if (!ACPI_IS_PRINT (*String))
+ {
+ *String = '?';
+ }
+ String++;
+ Length--;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbCleanupTableHeader
+ *
+ * PARAMETERS: OutHeader - Where the cleaned header is returned
+ * Header - Input ACPI table header
+ *
+ * RETURN: Returns the cleaned header in OutHeader
+ *
+ * DESCRIPTION: Copy the table header and ensure that all "string" fields in
+ * the header consist of printable characters.
+ *
+ ******************************************************************************/
+
+static void
+AcpiTbCleanupTableHeader (
+ ACPI_TABLE_HEADER *OutHeader,
+ ACPI_TABLE_HEADER *Header)
+{
+
+ ACPI_MEMCPY (OutHeader, Header, sizeof (ACPI_TABLE_HEADER));
+
+ AcpiTbFixString (OutHeader->Signature, ACPI_NAME_SIZE);
+ AcpiTbFixString (OutHeader->OemId, ACPI_OEM_ID_SIZE);
+ AcpiTbFixString (OutHeader->OemTableId, ACPI_OEM_TABLE_ID_SIZE);
+ AcpiTbFixString (OutHeader->AslCompilerId, ACPI_NAME_SIZE);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbPrintTableHeader
+ *
+ * PARAMETERS: Address - Table physical address
+ * Header - Table header
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP.
+ *
+ ******************************************************************************/
+
+void
+AcpiTbPrintTableHeader (
+ ACPI_PHYSICAL_ADDRESS Address,
+ ACPI_TABLE_HEADER *Header)
+{
+ ACPI_TABLE_HEADER LocalHeader;
+
+
+ /*
+ * The reason that the Address is cast to a void pointer is so that we
+ * can use %p which will work properly on both 32-bit and 64-bit hosts.
+ */
+ if (ACPI_COMPARE_NAME (Header->Signature, ACPI_SIG_FACS))
+ {
+ /* FACS only has signature and length fields */
+
+ ACPI_INFO ((AE_INFO, "%4.4s %p %05X",
+ Header->Signature, ACPI_CAST_PTR (void, Address),
+ Header->Length));
+ }
+ else if (ACPI_COMPARE_NAME (Header->Signature, ACPI_SIG_RSDP))
+ {
+ /* RSDP has no common fields */
+
+ ACPI_MEMCPY (LocalHeader.OemId,
+ ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->OemId, ACPI_OEM_ID_SIZE);
+ AcpiTbFixString (LocalHeader.OemId, ACPI_OEM_ID_SIZE);
+
+ ACPI_INFO ((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)",
+ ACPI_CAST_PTR (void, Address),
+ (ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Revision > 0) ?
+ ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Length : 20,
+ ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Revision,
+ LocalHeader.OemId));
+ }
+ else
+ {
+ /* Standard ACPI table with full common header */
+
+ AcpiTbCleanupTableHeader (&LocalHeader, Header);
+
+ ACPI_INFO ((AE_INFO,
+ "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)",
+ LocalHeader.Signature, ACPI_CAST_PTR (void, Address),
+ LocalHeader.Length, LocalHeader.Revision, LocalHeader.OemId,
+ LocalHeader.OemTableId, LocalHeader.OemRevision,
+ LocalHeader.AslCompilerId, LocalHeader.AslCompilerRevision));
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbValidateChecksum
+ *
+ * PARAMETERS: Table - ACPI table to verify
+ * Length - Length of entire table
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns
+ * exception on bad checksum.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiTbVerifyChecksum (
+ ACPI_TABLE_HEADER *Table,
+ UINT32 Length)
+{
+ UINT8 Checksum;
+
+
+ /* Compute the checksum on the table */
+
+ Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Length);
+
+ /* Checksum ok? (should be zero) */
+
+ if (Checksum)
+ {
+ ACPI_WARNING ((AE_INFO,
+ "Incorrect checksum in table [%4.4s] - 0x%2.2X, should be 0x%2.2X",
+ Table->Signature, Table->Checksum,
+ (UINT8) (Table->Checksum - Checksum)));
+
+#if (ACPI_CHECKSUM_ABORT)
+ return (AE_BAD_CHECKSUM);
+#endif
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbChecksum
+ *
+ * PARAMETERS: Buffer - Pointer to memory region to be checked
+ * Length - Length of this memory region
+ *
+ * RETURN: Checksum (UINT8)
+ *
+ * DESCRIPTION: Calculates circular checksum of memory region.
+ *
+ ******************************************************************************/
+
+UINT8
+AcpiTbChecksum (
+ UINT8 *Buffer,
+ UINT32 Length)
+{
+ UINT8 Sum = 0;
+ UINT8 *End = Buffer + Length;
+
+
+ while (Buffer < End)
+ {
+ Sum = (UINT8) (Sum + *(Buffer++));
+ }
+
+ return Sum;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbCheckDsdtHeader
+ *
+ * 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
+AcpiTbCheckDsdtHeader (
+ void)
+{
+
+ /* Compare original length and checksum to current values */
+
+ if (AcpiGbl_OriginalDsdtHeader.Length != AcpiGbl_DSDT->Length ||
+ AcpiGbl_OriginalDsdtHeader.Checksum != AcpiGbl_DSDT->Checksum)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "The DSDT has been corrupted or replaced - old, new headers below"));
+ AcpiTbPrintTableHeader (0, &AcpiGbl_OriginalDsdtHeader);
+ AcpiTbPrintTableHeader (0, AcpiGbl_DSDT);
+
+ /* Disable further error messages */
+
+ AcpiGbl_OriginalDsdtHeader.Length = AcpiGbl_DSDT->Length;
+ AcpiGbl_OriginalDsdtHeader.Checksum = AcpiGbl_DSDT->Checksum;
+ }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbCopyDsdt
+ *
+ * PARAMETERS: TableDesc - Installed table to copy
+ *
+ * RETURN: None
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+ACPI_TABLE_HEADER *
+AcpiTbCopyDsdt (
+ UINT32 TableIndex)
+{
+ ACPI_TABLE_HEADER *NewTable;
+ ACPI_TABLE_DESC *TableDesc;
+
+
+ TableDesc = &AcpiGbl_RootTableList.Tables[TableIndex];
+
+ NewTable = ACPI_ALLOCATE (TableDesc->Length);
+ if (!NewTable)
+ {
+ ACPI_ERROR ((AE_INFO, "Could not copy DSDT of length 0x%X",
+ TableDesc->Length));
+ return (NULL);
+ }
+
+ ACPI_MEMCPY (NewTable, TableDesc->Pointer, TableDesc->Length);
+ AcpiTbDeleteTable (TableDesc);
+ TableDesc->Pointer = NewTable;
+ TableDesc->Flags = ACPI_TABLE_ORIGIN_ALLOCATED;
+
+ ACPI_INFO ((AE_INFO,
+ "Forced DSDT copy: length 0x%05X copied locally, original unmapped",
+ NewTable->Length));
+
+ return (NewTable);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbInstallTable
+ *
+ * PARAMETERS: Address - Physical address of DSDT or FACS
+ * Signature - Table signature, NULL if no need to
+ * match
+ * TableIndex - Index into root table array
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Install an ACPI table into the global data structure. The
+ * table override mechanism is called to allow the host
+ * OS to replace any table before it is installed in the root
+ * table array.
+ *
+ ******************************************************************************/
+
+void
+AcpiTbInstallTable (
+ ACPI_PHYSICAL_ADDRESS Address,
+ char *Signature,
+ UINT32 TableIndex)
+{
+ ACPI_TABLE_HEADER *Table;
+ ACPI_TABLE_HEADER *FinalTable;
+ ACPI_TABLE_DESC *TableDesc;
+
+
+ if (!Address)
+ {
+ ACPI_ERROR ((AE_INFO, "Null physical address for ACPI table [%s]",
+ Signature));
+ return;
+ }
+
+ /* Map just the table header */
+
+ Table = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER));
+ if (!Table)
+ {
+ ACPI_ERROR ((AE_INFO, "Could not map memory for table [%s] at %p",
+ Signature, ACPI_CAST_PTR (void, Address)));
+ return;
+ }
+
+ /* Skip SSDT when DSDT is overriden */
+
+ if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT) &&
+ (AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Flags &
+ ACPI_TABLE_ORIGIN_OVERRIDE))
+ {
+ ACPI_INFO ((AE_INFO,
+ "%4.4s @ 0x%p Table override, replaced with:", ACPI_SIG_SSDT,
+ ACPI_CAST_PTR (void, Address)));
+ AcpiTbPrintTableHeader (
+ AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Address,
+ AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Pointer);
+ goto UnmapAndExit;
+ }
+
+ /* If a particular signature is expected (DSDT/FACS), it must match */
+
+ if (Signature &&
+ !ACPI_COMPARE_NAME (Table->Signature, Signature))
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Invalid signature 0x%X for ACPI table, expected [%s]",
+ *ACPI_CAST_PTR (UINT32, Table->Signature), Signature));
+ goto UnmapAndExit;
+ }
+
+ /*
+ * Initialize the table entry. Set the pointer to NULL, since the
+ * table is not fully mapped at this time.
+ */
+ TableDesc = &AcpiGbl_RootTableList.Tables[TableIndex];
+
+ TableDesc->Address = Address;
+ TableDesc->Pointer = NULL;
+ TableDesc->Length = Table->Length;
+ TableDesc->Flags = ACPI_TABLE_ORIGIN_MAPPED;
+ ACPI_MOVE_32_TO_32 (TableDesc->Signature.Ascii, Table->Signature);
+
+ /*
+ * ACPI Table Override:
+ *
+ * Before we install the table, let the host OS override it with a new
+ * one if desired. Any table within the RSDT/XSDT can be replaced,
+ * including the DSDT which is pointed to by the FADT.
+ *
+ * NOTE: If the table is overridden, then FinalTable will contain a
+ * mapped pointer to the full new table. If the table is not overridden,
+ * then the table will be fully mapped elsewhere (in verify table).
+ * In any case, we must unmap the header that was mapped above.
+ */
+ FinalTable = AcpiTbTableOverride (Table, TableDesc);
+ if (!FinalTable)
+ {
+ FinalTable = Table; /* There was no override */
+ }
+
+ AcpiTbPrintTableHeader (TableDesc->Address, FinalTable);
+
+ /* Set the global integer width (based upon revision of the DSDT) */
+
+ if (TableIndex == ACPI_TABLE_INDEX_DSDT)
+ {
+ AcpiUtSetIntegerWidth (FinalTable->Revision);
+ }
+
+UnmapAndExit:
+
+ /* Always unmap the table header that we mapped above */
+
+ AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER));
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbGetRootTableEntry
+ *
+ * PARAMETERS: TableEntry - Pointer to the RSDT/XSDT table entry
+ * TableEntrySize - 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
+AcpiTbGetRootTableEntry (
+ UINT8 *TableEntry,
+ UINT32 TableEntrySize)
+{
+ UINT64 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 (TableEntrySize == sizeof (UINT32))
+ {
+ /*
+ * 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 (UINT32, TableEntry)));
+ }
+ 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, TableEntry);
+
+#if ACPI_MACHINE_WIDTH == 32
+ if (Address64 > ACPI_UINT32_MAX)
+ {
+ /* Will truncate 64-bit address to 32 bits, issue warning */
+
+ ACPI_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: AcpiTbParseRootTable
+ *
+ * PARAMETERS: Rsdp - 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
+AcpiTbParseRootTable (
+ ACPI_PHYSICAL_ADDRESS RsdpAddress)
+{
+ ACPI_TABLE_RSDP *Rsdp;
+ UINT32 TableEntrySize;
+ UINT32 i;
+ UINT32 TableCount;
+ ACPI_TABLE_HEADER *Table;
+ ACPI_PHYSICAL_ADDRESS Address;
+ UINT32 Length;
+ UINT8 *TableEntry;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (TbParseRootTable);
+
+
+ /*
+ * Map the entire RSDP and extract the address of the RSDT or XSDT
+ */
+ Rsdp = AcpiOsMapMemory (RsdpAddress, sizeof (ACPI_TABLE_RSDP));
+ if (!Rsdp)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ AcpiTbPrintTableHeader (RsdpAddress,
+ ACPI_CAST_PTR (ACPI_TABLE_HEADER, Rsdp));
+
+ /* Differentiate between RSDT and XSDT root tables */
+
+ if (Rsdp->Revision > 1 && Rsdp->XsdtPhysicalAddress)
+ {
+ /*
+ * Root table is 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->XsdtPhysicalAddress;
+ TableEntrySize = sizeof (UINT64);
+ }
+ else
+ {
+ /* Root table is an RSDT (32-bit physical addresses) */
+
+ Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->RsdtPhysicalAddress;
+ TableEntrySize = sizeof (UINT32);
+ }
+
+ /*
+ * It is not possible to map more than one entry in some environments,
+ * so unmap the RSDP here before mapping other tables
+ */
+ AcpiOsUnmapMemory (Rsdp, sizeof (ACPI_TABLE_RSDP));
+
+
+ /* Map the RSDT/XSDT table header to get the full table length */
+
+ Table = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER));
+ if (!Table)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ AcpiTbPrintTableHeader (Address, Table);
+
+ /* Get the length of the full table, verify length and map entire table */
+
+ Length = Table->Length;
+ AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER));
+
+ if (Length < sizeof (ACPI_TABLE_HEADER))
+ {
+ ACPI_ERROR ((AE_INFO, "Invalid length 0x%X in RSDT/XSDT", Length));
+ return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
+ }
+
+ Table = AcpiOsMapMemory (Address, Length);
+ if (!Table)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /* Validate the root table checksum */
+
+ Status = AcpiTbVerifyChecksum (Table, Length);
+ if (ACPI_FAILURE (Status))
+ {
+ AcpiOsUnmapMemory (Table, Length);
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Calculate the number of tables described in the root table */
+
+ TableCount = (UINT32) ((Table->Length - sizeof (ACPI_TABLE_HEADER)) /
+ TableEntrySize);
+
+ /*
+ * First two entries in the table array are reserved for the DSDT
+ * and FACS, which are not actually present in the RSDT/XSDT - they
+ * come from the FADT
+ */
+ TableEntry = ACPI_CAST_PTR (UINT8, Table) + sizeof (ACPI_TABLE_HEADER);
+ AcpiGbl_RootTableList.CurrentTableCount = 2;
+
+ /*
+ * Initialize the root table array from the RSDT/XSDT
+ */
+ for (i = 0; i < TableCount; i++)
+ {
+ if (AcpiGbl_RootTableList.CurrentTableCount >=
+ AcpiGbl_RootTableList.MaxTableCount)
+ {
+ /* There is no more room in the root table array, attempt resize */
+
+ Status = AcpiTbResizeRootTableList ();
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_WARNING ((AE_INFO, "Truncating %u table entries!",
+ (unsigned) (TableCount -
+ (AcpiGbl_RootTableList.CurrentTableCount - 2))));
+ break;
+ }
+ }
+
+ /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */
+
+ AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount].Address =
+ AcpiTbGetRootTableEntry (TableEntry, TableEntrySize);
+
+ TableEntry += TableEntrySize;
+ AcpiGbl_RootTableList.CurrentTableCount++;
+ }
+
+ /*
+ * It is not possible to map more than one entry in some environments,
+ * so unmap the root table here before mapping other tables
+ */
+ AcpiOsUnmapMemory (Table, Length);
+
+ /*
+ * Complete the initialization of the root table array by examining
+ * the header of each table
+ */
+ for (i = 2; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
+ {
+ AcpiTbInstallTable (AcpiGbl_RootTableList.Tables[i].Address,
+ NULL, i);
+
+ /* Special case for FADT - get the DSDT and FACS */
+
+ if (ACPI_COMPARE_NAME (
+ &AcpiGbl_RootTableList.Tables[i].Signature, ACPI_SIG_FADT))
+ {
+ AcpiTbParseFadt (i);
+ }
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
diff --git a/sys/contrib/dev/acpica/components/tables/tbxface.c b/sys/contrib/dev/acpica/components/tables/tbxface.c
new file mode 100644
index 0000000..dc03a2c
--- /dev/null
+++ b/sys/contrib/dev/acpica/components/tables/tbxface.c
@@ -0,0 +1,722 @@
+/******************************************************************************
+ *
+ * Module Name: tbxface - Public interfaces to the ACPI subsystem
+ * ACPI table oriented interfaces
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * 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.
+ */
+
+#define __TBXFACE_C__
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/acnamesp.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+#define _COMPONENT ACPI_TABLES
+ ACPI_MODULE_NAME ("tbxface")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiTbLoadNamespace (
+ void);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiAllocateRootTable
+ *
+ * PARAMETERS: InitialTableCount - Size of InitialTableArray, in number of
+ * ACPI_TABLE_DESC structures
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Allocate a root table array. Used by iASL compiler and
+ * AcpiInitializeTables.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiAllocateRootTable (
+ UINT32 InitialTableCount)
+{
+
+ AcpiGbl_RootTableList.MaxTableCount = InitialTableCount;
+ AcpiGbl_RootTableList.Flags = ACPI_ROOT_ALLOW_RESIZE;
+
+ return (AcpiTbResizeRootTableList ());
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiInitializeTables
+ *
+ * PARAMETERS: InitialTableArray - Pointer to an array of pre-allocated
+ * ACPI_TABLE_DESC structures. If NULL, the
+ * array is dynamically allocated.
+ * InitialTableCount - Size of InitialTableArray, in number of
+ * ACPI_TABLE_DESC structures
+ * AllowRealloc - Flag to tell Table Manager if resize of
+ * pre-allocated array is allowed. Ignored
+ * if InitialTableArray is NULL.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT.
+ *
+ * NOTE: Allows static allocation of the initial table array in order
+ * to avoid the use of dynamic memory in confined environments
+ * such as the kernel boot sequence where it may not be available.
+ *
+ * If the host OS memory managers are initialized, use NULL for
+ * InitialTableArray, and the table will be dynamically allocated.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiInitializeTables (
+ ACPI_TABLE_DESC *InitialTableArray,
+ UINT32 InitialTableCount,
+ BOOLEAN AllowResize)
+{
+ ACPI_PHYSICAL_ADDRESS RsdpAddress;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiInitializeTables);
+
+
+ /*
+ * Set up the Root Table Array
+ * Allocate the table array if requested
+ */
+ if (!InitialTableArray)
+ {
+ Status = AcpiAllocateRootTable (InitialTableCount);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+ else
+ {
+ /* Root Table Array has been statically allocated by the host */
+
+ ACPI_MEMSET (InitialTableArray, 0,
+ (ACPI_SIZE) InitialTableCount * sizeof (ACPI_TABLE_DESC));
+
+ AcpiGbl_RootTableList.Tables = InitialTableArray;
+ AcpiGbl_RootTableList.MaxTableCount = InitialTableCount;
+ AcpiGbl_RootTableList.Flags = ACPI_ROOT_ORIGIN_UNKNOWN;
+ if (AllowResize)
+ {
+ AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ALLOW_RESIZE;
+ }
+ }
+
+ /* Get the address of the RSDP */
+
+ RsdpAddress = AcpiOsGetRootPointer ();
+ if (!RsdpAddress)
+ {
+ return_ACPI_STATUS (AE_NOT_FOUND);
+ }
+
+ /*
+ * Get the root table (RSDT or XSDT) and extract all entries to the local
+ * Root Table Array. This array contains the information of the RSDT/XSDT
+ * in a common, more useable format.
+ */
+ Status = AcpiTbParseRootTable (RsdpAddress);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiInitializeTables)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiReallocateRootTable
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the
+ * root list from the previously provided scratch area. Should
+ * be called once dynamic memory allocation is available in the
+ * kernel
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiReallocateRootTable (
+ void)
+{
+ ACPI_TABLE_DESC *Tables;
+ ACPI_SIZE NewSize;
+ ACPI_SIZE CurrentSize;
+
+
+ ACPI_FUNCTION_TRACE (AcpiReallocateRootTable);
+
+
+ /*
+ * Only reallocate the root table if the host provided a static buffer
+ * for the table array in the call to AcpiInitializeTables.
+ */
+ if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
+ {
+ return_ACPI_STATUS (AE_SUPPORT);
+ }
+
+ /*
+ * Get the current size of the root table and add the default
+ * increment to create the new table size.
+ */
+ CurrentSize = (ACPI_SIZE)
+ AcpiGbl_RootTableList.CurrentTableCount * sizeof (ACPI_TABLE_DESC);
+
+ NewSize = CurrentSize +
+ (ACPI_ROOT_TABLE_SIZE_INCREMENT * sizeof (ACPI_TABLE_DESC));
+
+ /* Create new array and copy the old array */
+
+ Tables = ACPI_ALLOCATE_ZEROED (NewSize);
+ if (!Tables)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables, CurrentSize);
+
+ /*
+ * Update the root table descriptor. The new size will be the current
+ * number of tables plus the increment, independent of the reserved
+ * size of the original table list.
+ */
+ AcpiGbl_RootTableList.Tables = Tables;
+ AcpiGbl_RootTableList.MaxTableCount =
+ AcpiGbl_RootTableList.CurrentTableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT;
+ AcpiGbl_RootTableList.Flags =
+ ACPI_ROOT_ORIGIN_ALLOCATED | ACPI_ROOT_ALLOW_RESIZE;
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiReallocateRootTable)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetTableHeader
+ *
+ * PARAMETERS: Signature - ACPI signature of needed table
+ * Instance - Which instance (for SSDTs)
+ * OutTableHeader - The pointer to the table header to fill
+ *
+ * RETURN: Status and pointer to mapped table header
+ *
+ * DESCRIPTION: Finds an ACPI table header.
+ *
+ * NOTE: Caller is responsible in unmapping the header with
+ * AcpiOsUnmapMemory
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetTableHeader (
+ char *Signature,
+ UINT32 Instance,
+ ACPI_TABLE_HEADER *OutTableHeader)
+{
+ UINT32 i;
+ UINT32 j;
+ ACPI_TABLE_HEADER *Header;
+
+
+ /* Parameter validation */
+
+ if (!Signature || !OutTableHeader)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Walk the root table list */
+
+ for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
+ {
+ if (!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
+ Signature))
+ {
+ continue;
+ }
+
+ if (++j < Instance)
+ {
+ continue;
+ }
+
+ if (!AcpiGbl_RootTableList.Tables[i].Pointer)
+ {
+ if ((AcpiGbl_RootTableList.Tables[i].Flags &
+ ACPI_TABLE_ORIGIN_MASK) ==
+ ACPI_TABLE_ORIGIN_MAPPED)
+ {
+ Header = AcpiOsMapMemory (
+ AcpiGbl_RootTableList.Tables[i].Address,
+ sizeof (ACPI_TABLE_HEADER));
+ if (!Header)
+ {
+ return AE_NO_MEMORY;
+ }
+
+ ACPI_MEMCPY (OutTableHeader, Header, sizeof(ACPI_TABLE_HEADER));
+ AcpiOsUnmapMemory (Header, sizeof(ACPI_TABLE_HEADER));
+ }
+ else
+ {
+ return AE_NOT_FOUND;
+ }
+ }
+ else
+ {
+ ACPI_MEMCPY (OutTableHeader,
+ AcpiGbl_RootTableList.Tables[i].Pointer,
+ sizeof(ACPI_TABLE_HEADER));
+ }
+
+ return (AE_OK);
+ }
+
+ return (AE_NOT_FOUND);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetTableHeader)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetTable
+ *
+ * PARAMETERS: Signature - ACPI signature of needed table
+ * Instance - Which instance (for SSDTs)
+ * OutTable - Where the pointer to the table is returned
+ *
+ * RETURN: Status and pointer to table
+ *
+ * DESCRIPTION: Finds and verifies an ACPI table.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetTable (
+ char *Signature,
+ UINT32 Instance,
+ ACPI_TABLE_HEADER **OutTable)
+{
+ UINT32 i;
+ UINT32 j;
+ ACPI_STATUS Status;
+
+
+ /* Parameter validation */
+
+ if (!Signature || !OutTable)
+ {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /* Walk the root table list */
+
+ for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
+ {
+ if (!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
+ Signature))
+ {
+ continue;
+ }
+
+ if (++j < Instance)
+ {
+ continue;
+ }
+
+ Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]);
+ if (ACPI_SUCCESS (Status))
+ {
+ *OutTable = AcpiGbl_RootTableList.Tables[i].Pointer;
+ }
+
+ return (Status);
+ }
+
+ return (AE_NOT_FOUND);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetTable)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetTableByIndex
+ *
+ * PARAMETERS: TableIndex - Table index
+ * Table - Where the pointer to the table is returned
+ *
+ * RETURN: Status and pointer to the table
+ *
+ * DESCRIPTION: Obtain a table by an index into the global table list.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetTableByIndex (
+ UINT32 TableIndex,
+ ACPI_TABLE_HEADER **Table)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiGetTableByIndex);
+
+
+ /* Parameter validation */
+
+ if (!Table)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+
+ /* Validate index */
+
+ if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
+ {
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ if (!AcpiGbl_RootTableList.Tables[TableIndex].Pointer)
+ {
+ /* Table is not mapped, map it */
+
+ Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[TableIndex]);
+ if (ACPI_FAILURE (Status))
+ {
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ *Table = AcpiGbl_RootTableList.Tables[TableIndex].Pointer;
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ return_ACPI_STATUS (AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetTableByIndex)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbLoadNamespace
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in
+ * the RSDT/XSDT.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiTbLoadNamespace (
+ void)
+{
+ ACPI_STATUS Status;
+ UINT32 i;
+ ACPI_TABLE_HEADER *NewDsdt;
+
+
+ ACPI_FUNCTION_TRACE (TbLoadNamespace);
+
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+
+ /*
+ * Load the namespace. The DSDT is required, but any SSDT and
+ * PSDT tables are optional. Verify the DSDT.
+ */
+ if (!AcpiGbl_RootTableList.CurrentTableCount ||
+ !ACPI_COMPARE_NAME (
+ &(AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Signature),
+ ACPI_SIG_DSDT) ||
+ ACPI_FAILURE (AcpiTbVerifyTable (
+ &AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT])))
+ {
+ Status = AE_NO_ACPI_TABLES;
+ goto UnlockAndExit;
+ }
+
+ /*
+ * Save the DSDT pointer for simple access. This is the mapped memory
+ * address. We must take care here because the address of the .Tables
+ * array can change dynamically as tables are loaded at run-time. Note:
+ * .Pointer field is not validated until after call to AcpiTbVerifyTable.
+ */
+ AcpiGbl_DSDT = AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Pointer;
+
+ /*
+ * Optionally copy the entire DSDT to local memory (instead of simply
+ * mapping it.) There are some BIOSs that corrupt or replace the original
+ * DSDT, creating the need for this option. Default is FALSE, do not copy
+ * the DSDT.
+ */
+ if (AcpiGbl_CopyDsdtLocally)
+ {
+ NewDsdt = AcpiTbCopyDsdt (ACPI_TABLE_INDEX_DSDT);
+ if (NewDsdt)
+ {
+ AcpiGbl_DSDT = NewDsdt;
+ }
+ }
+
+ /*
+ * Save the original DSDT header for detection of table corruption
+ * and/or replacement of the DSDT from outside the OS.
+ */
+ ACPI_MEMCPY (&AcpiGbl_OriginalDsdtHeader, AcpiGbl_DSDT,
+ sizeof (ACPI_TABLE_HEADER));
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+
+ /* Load and parse tables */
+
+ Status = AcpiNsLoadTable (ACPI_TABLE_INDEX_DSDT, AcpiGbl_RootNode);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+ for (i = 2; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
+ {
+ if ((!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
+ ACPI_SIG_SSDT) &&
+ !ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
+ ACPI_SIG_PSDT)) ||
+ ACPI_FAILURE (AcpiTbVerifyTable (
+ &AcpiGbl_RootTableList.Tables[i])))
+ {
+ continue;
+ }
+
+ /* Skip SSDT when DSDT is overriden */
+
+ if (ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature),
+ ACPI_SIG_SSDT) &&
+ (AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Flags &
+ ACPI_TABLE_ORIGIN_OVERRIDE))
+ {
+ continue;
+ }
+
+ /* Ignore errors while loading tables, get as many as possible */
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ (void) AcpiNsLoadTable (i, AcpiGbl_RootNode);
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI Tables successfully acquired\n"));
+
+UnlockAndExit:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiLoadTables
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiLoadTables (
+ void)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiLoadTables);
+
+
+ /* Load the namespace from the tables */
+
+ Status = AcpiTbLoadNamespace ();
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status,
+ "While loading namespace from ACPI tables"));
+ }
+
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiLoadTables)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiInstallTableHandler
+ *
+ * PARAMETERS: Handler - Table event handler
+ * Context - Value passed to the handler on each event
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Install table event handler
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiInstallTableHandler (
+ ACPI_TABLE_HANDLER Handler,
+ void *Context)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiInstallTableHandler);
+
+
+ if (!Handler)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Don't allow more than one handler */
+
+ if (AcpiGbl_TableHandler)
+ {
+ Status = AE_ALREADY_EXISTS;
+ goto Cleanup;
+ }
+
+ /* Install the handler */
+
+ AcpiGbl_TableHandler = Handler;
+ AcpiGbl_TableHandlerContext = Context;
+
+Cleanup:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiInstallTableHandler)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiRemoveTableHandler
+ *
+ * PARAMETERS: Handler - Table event handler that was installed
+ * previously.
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Remove table event handler
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiRemoveTableHandler (
+ ACPI_TABLE_HANDLER Handler)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiRemoveTableHandler);
+
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Make sure that the installed handler is the same */
+
+ if (!Handler ||
+ Handler != AcpiGbl_TableHandler)
+ {
+ Status = AE_BAD_PARAMETER;
+ goto Cleanup;
+ }
+
+ /* Remove the handler */
+
+ AcpiGbl_TableHandler = NULL;
+
+Cleanup:
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiRemoveTableHandler)
+
diff --git a/sys/contrib/dev/acpica/components/tables/tbxfroot.c b/sys/contrib/dev/acpica/components/tables/tbxfroot.c
new file mode 100644
index 0000000..c6ade4e
--- /dev/null
+++ b/sys/contrib/dev/acpica/components/tables/tbxfroot.c
@@ -0,0 +1,299 @@
+/******************************************************************************
+ *
+ * Module Name: tbxfroot - Find the root ACPI table (RSDT)
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * 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.
+ */
+
+#define __TBXFROOT_C__
+
+#include <contrib/dev/acpica/include/acpi.h>
+#include <contrib/dev/acpica/include/accommon.h>
+#include <contrib/dev/acpica/include/actables.h>
+
+
+#define _COMPONENT ACPI_TABLES
+ ACPI_MODULE_NAME ("tbxfroot")
+
+/* Local prototypes */
+
+static UINT8 *
+AcpiTbScanMemoryForRsdp (
+ UINT8 *StartAddress,
+ UINT32 Length);
+
+static ACPI_STATUS
+AcpiTbValidateRsdp (
+ ACPI_TABLE_RSDP *Rsdp);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbValidateRsdp
+ *
+ * PARAMETERS: Rsdp - Pointer to unvalidated RSDP
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Validate the RSDP (ptr)
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiTbValidateRsdp (
+ ACPI_TABLE_RSDP *Rsdp)
+{
+ ACPI_FUNCTION_ENTRY ();
+
+
+ /*
+ * The signature and checksum must both be correct
+ *
+ * Note: Sometimes there exists more than one RSDP in memory; the valid
+ * RSDP has a valid checksum, all others have an invalid checksum.
+ */
+ if (ACPI_STRNCMP ((char *) Rsdp, ACPI_SIG_RSDP,
+ sizeof (ACPI_SIG_RSDP)-1) != 0)
+ {
+ /* Nope, BAD Signature */
+
+ return (AE_BAD_SIGNATURE);
+ }
+
+ /* Check the standard checksum */
+
+ if (AcpiTbChecksum ((UINT8 *) Rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0)
+ {
+ return (AE_BAD_CHECKSUM);
+ }
+
+ /* Check extended checksum if table version >= 2 */
+
+ if ((Rsdp->Revision >= 2) &&
+ (AcpiTbChecksum ((UINT8 *) Rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0))
+ {
+ return (AE_BAD_CHECKSUM);
+ }
+
+ return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiFindRootPointer
+ *
+ * PARAMETERS: TableAddress - Where the table pointer is returned
+ *
+ * RETURN: Status, RSDP physical address
+ *
+ * DESCRIPTION: Search lower 1Mbyte 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 1K 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.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiFindRootPointer (
+ ACPI_SIZE *TableAddress)
+{
+ UINT8 *TablePtr;
+ UINT8 *MemRover;
+ UINT32 PhysicalAddress;
+
+
+ ACPI_FUNCTION_TRACE (AcpiFindRootPointer);
+
+
+ /* 1a) Get the location of the Extended BIOS Data Area (EBDA) */
+
+ TablePtr = AcpiOsMapMemory (
+ (ACPI_PHYSICAL_ADDRESS) ACPI_EBDA_PTR_LOCATION,
+ ACPI_EBDA_PTR_LENGTH);
+ if (!TablePtr)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Could not map memory at 0x%8.8X for length %u",
+ ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH));
+
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ ACPI_MOVE_16_TO_32 (&PhysicalAddress, TablePtr);
+
+ /* Convert segment part to physical address */
+
+ PhysicalAddress <<= 4;
+ AcpiOsUnmapMemory (TablePtr, ACPI_EBDA_PTR_LENGTH);
+
+ /* EBDA present? */
+
+ if (PhysicalAddress > 0x400)
+ {
+ /*
+ * 1b) Search EBDA paragraphs (EBDA is required to be a
+ * minimum of 1K length)
+ */
+ TablePtr = AcpiOsMapMemory (
+ (ACPI_PHYSICAL_ADDRESS) PhysicalAddress,
+ ACPI_EBDA_WINDOW_SIZE);
+ if (!TablePtr)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Could not map memory at 0x%8.8X for length %u",
+ PhysicalAddress, ACPI_EBDA_WINDOW_SIZE));
+
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ MemRover = AcpiTbScanMemoryForRsdp (TablePtr, ACPI_EBDA_WINDOW_SIZE);
+ AcpiOsUnmapMemory (TablePtr, ACPI_EBDA_WINDOW_SIZE);
+
+ if (MemRover)
+ {
+ /* Return the physical address */
+
+ PhysicalAddress += (UINT32) ACPI_PTR_DIFF (MemRover, TablePtr);
+
+ *TableAddress = PhysicalAddress;
+ return_ACPI_STATUS (AE_OK);
+ }
+ }
+
+ /*
+ * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh
+ */
+ TablePtr = AcpiOsMapMemory (
+ (ACPI_PHYSICAL_ADDRESS) ACPI_HI_RSDP_WINDOW_BASE,
+ ACPI_HI_RSDP_WINDOW_SIZE);
+
+ if (!TablePtr)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Could not map memory at 0x%8.8X for length %u",
+ ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE));
+
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ MemRover = AcpiTbScanMemoryForRsdp (TablePtr, ACPI_HI_RSDP_WINDOW_SIZE);
+ AcpiOsUnmapMemory (TablePtr, ACPI_HI_RSDP_WINDOW_SIZE);
+
+ if (MemRover)
+ {
+ /* Return the physical address */
+
+ PhysicalAddress = (UINT32)
+ (ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF (MemRover, TablePtr));
+
+ *TableAddress = PhysicalAddress;
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* A valid RSDP was not found */
+
+ ACPI_ERROR ((AE_INFO, "A valid RSDP was not found"));
+ return_ACPI_STATUS (AE_NOT_FOUND);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiFindRootPointer)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbScanMemoryForRsdp
+ *
+ * PARAMETERS: StartAddress - 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 UINT8 *
+AcpiTbScanMemoryForRsdp (
+ UINT8 *StartAddress,
+ UINT32 Length)
+{
+ ACPI_STATUS Status;
+ UINT8 *MemRover;
+ UINT8 *EndAddress;
+
+
+ ACPI_FUNCTION_TRACE (TbScanMemoryForRsdp);
+
+
+ EndAddress = StartAddress + Length;
+
+ /* Search from given start address for the requested length */
+
+ for (MemRover = StartAddress; MemRover < EndAddress;
+ MemRover += ACPI_RSDP_SCAN_STEP)
+ {
+ /* The RSDP signature and checksum must both be correct */
+
+ Status = AcpiTbValidateRsdp (ACPI_CAST_PTR (ACPI_TABLE_RSDP, MemRover));
+ if (ACPI_SUCCESS (Status))
+ {
+ /* Sig and checksum valid, we have found a real RSDP */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "RSDP located at physical address %p\n", MemRover));
+ return_PTR (MemRover);
+ }
+
+ /* No sig match or bad checksum, keep searching */
+ }
+
+ /* Searched entire block, no RSDP was found */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Searched entire block from %p, valid RSDP was not found\n",
+ StartAddress));
+ return_PTR (NULL);
+}
+
OpenPOWER on IntegriCloud