summaryrefslogtreecommitdiffstats
path: root/sys/contrib/dev/acpica/tbget.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/dev/acpica/tbget.c')
-rw-r--r--sys/contrib/dev/acpica/tbget.c844
1 files changed, 240 insertions, 604 deletions
diff --git a/sys/contrib/dev/acpica/tbget.c b/sys/contrib/dev/acpica/tbget.c
index ba020ce..3616875 100644
--- a/sys/contrib/dev/acpica/tbget.c
+++ b/sys/contrib/dev/acpica/tbget.c
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Module Name: tbget - ACPI Table get* routines
- * $Revision: 77 $
+ * $Revision: 78 $
*
*****************************************************************************/
@@ -126,821 +126,457 @@
/*******************************************************************************
*
- * FUNCTION: AcpiTbTableOverride
+ * FUNCTION: AcpiTbGetTable
*
- * PARAMETERS: *TableInfo - Info for current table
+ * PARAMETERS: Address - Address of table to retrieve. Can be
+ * Logical or Physical
+ * TableInfo - Where table info is returned
*
* RETURN: None
*
- * DESCRIPTION: Attempts override of current table with a new one if provided
- * by the host OS.
- *
- ******************************************************************************/
-
-void
-AcpiTbTableOverride (
- ACPI_TABLE_DESC *TableInfo)
-{
- ACPI_TABLE_HEADER *NewTable;
- ACPI_STATUS Status;
- ACPI_POINTER Address;
- ACPI_TABLE_DESC NewTableInfo;
-
-
- ACPI_FUNCTION_TRACE ("AcpiTbTableOverride");
-
-
- Status = AcpiOsTableOverride (TableInfo->Pointer, &NewTable);
- if (ACPI_FAILURE (Status))
- {
- /* Some severe error from the OSL, but we basically ignore it */
-
- ACPI_REPORT_ERROR (("Could not override ACPI table, %s\n",
- AcpiFormatException (Status)));
- return_VOID;
- }
-
- if (!NewTable)
- {
- /* No table override */
-
- return_VOID;
- }
-
- /*
- * We have a new table to override the old one. Get a copy of
- * the new one. We know that the new table has a logical pointer.
- */
- Address.PointerType = ACPI_LOGICAL_POINTER;
- Address.Pointer.Logical = NewTable;
-
- Status = AcpiTbGetTable (&Address, &NewTableInfo);
- if (ACPI_FAILURE (Status))
- {
- ACPI_REPORT_ERROR (("Could not copy ACPI table override\n"));
- return_VOID;
- }
-
- /*
- * Delete the original table
- */
- AcpiTbDeleteSingleTable (TableInfo);
-
- /* Copy the table info */
-
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Successful table override [%4.4s]\n",
- ((ACPI_TABLE_HEADER *) NewTableInfo.Pointer)->Signature));
-
- ACPI_MEMCPY (TableInfo, &NewTableInfo, sizeof (ACPI_TABLE_DESC));
- return_VOID;
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AcpiTbGetTableWithOverride
- *
- * PARAMETERS: Address - Physical or logical address of table
- * *TableInfo - Where the table info is returned
- *
- * RETURN: Status
- *
- * DESCRIPTION: Gets and installs the table with possible table override by OS.
+ * DESCRIPTION: Get entire table of unknown size.
*
******************************************************************************/
ACPI_STATUS
-AcpiTbGetTableWithOverride (
+AcpiTbGetTable (
ACPI_POINTER *Address,
ACPI_TABLE_DESC *TableInfo)
{
ACPI_STATUS Status;
+ ACPI_TABLE_HEADER Header;
- ACPI_FUNCTION_TRACE ("AcpiTbGetTableWithOverride");
-
+ ACPI_FUNCTION_TRACE ("TbGetTable");
- Status = AcpiTbGetTable (Address, TableInfo);
- if (ACPI_FAILURE (Status))
- {
- ACPI_REPORT_ERROR (("Could not get ACPI table, %s\n",
- AcpiFormatException (Status)));
- return_ACPI_STATUS (Status);
- }
/*
- * Attempt override. It either happens or it doesn't, no status
+ * Get the header in order to get signature and table size
*/
- AcpiTbTableOverride (TableInfo);
-
- /* Install the table */
-
- Status = AcpiTbInstallTable (TableInfo);
+ Status = AcpiTbGetTableHeader (Address, &Header);
if (ACPI_FAILURE (Status))
{
- ACPI_REPORT_ERROR (("Could not install ACPI table, %s\n",
- AcpiFormatException (Status)));
- }
-
- return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AcpiTbGetTablePtr
- *
- * PARAMETERS: TableType - one of the defined table types
- * Instance - Which table of this type
- * TablePtrLoc - pointer to location to place the pointer for
- * return
- *
- * RETURN: Status
- *
- * DESCRIPTION: This function is called to get the pointer to an ACPI table.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiTbGetTablePtr (
- ACPI_TABLE_TYPE TableType,
- UINT32 Instance,
- ACPI_TABLE_HEADER **TablePtrLoc)
-{
- ACPI_TABLE_DESC *TableDesc;
- UINT32 i;
-
-
- ACPI_FUNCTION_TRACE ("TbGetTablePtr");
-
-
- if (!AcpiGbl_DSDT)
- {
- return_ACPI_STATUS (AE_NO_ACPI_TABLES);
- }
-
- if (TableType > ACPI_TABLE_MAX)
- {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- }
-
- /*
- * For all table types (Single/Multiple), the first
- * instance is always in the list head.
- */
- if (Instance == 1)
- {
- /*
- * Just pluck the pointer out of the global table!
- * Will be null if no table is present
- */
- *TablePtrLoc = AcpiGbl_AcpiTables[TableType].Pointer;
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS (Status);
}
- /*
- * Check for instance out of range
- */
- if (Instance > AcpiGbl_AcpiTables[TableType].Count)
- {
- return_ACPI_STATUS (AE_NOT_EXIST);
- }
+ /* Get the entire table */
- /* Walk the list to get the desired table
- * Since the if (Instance == 1) check above checked for the
- * first table, setting TableDesc equal to the .Next member
- * is actually pointing to the second table. Therefore, we
- * need to walk from the 2nd table until we reach the Instance
- * that the user is looking for and return its table pointer.
- */
- TableDesc = AcpiGbl_AcpiTables[TableType].Next;
- for (i = 2; i < Instance; i++)
+ Status = AcpiTbGetTableBody (Address, &Header, TableInfo);
+ if (ACPI_FAILURE (Status))
{
- TableDesc = TableDesc->Next;
+ ACPI_REPORT_ERROR (("Could not get ACPI table (size %X), %s\n",
+ Header.Length, AcpiFormatException (Status)));
+ return_ACPI_STATUS (Status);
}
- /* We are now pointing to the requested table's descriptor */
-
- *TablePtrLoc = TableDesc->Pointer;
-
return_ACPI_STATUS (AE_OK);
}
/*******************************************************************************
*
- * FUNCTION: AcpiTbGetTable
+ * FUNCTION: AcpiTbGetTableHeader
*
- * PARAMETERS: Address - Physical address of table to retrieve
- * *TableInfo - Where the table info is returned
+ * PARAMETERS: Address - Address of table to retrieve. Can be
+ * Logical or Physical
+ * ReturnHeader - Where the table header is returned
*
* RETURN: Status
*
- * DESCRIPTION: Maps the physical address of table into a logical address
+ * DESCRIPTION: Get an ACPI table header. Works in both physical or virtual
+ * addressing mode. Works with both physical or logical pointers.
+ * Table is either copied or mapped, depending on the pointer
+ * type and mode of the processor.
*
******************************************************************************/
ACPI_STATUS
-AcpiTbGetTable (
+AcpiTbGetTableHeader (
ACPI_POINTER *Address,
- ACPI_TABLE_DESC *TableInfo)
+ ACPI_TABLE_HEADER *ReturnHeader)
{
- ACPI_TABLE_HEADER *TableHeader = NULL;
- ACPI_TABLE_HEADER *FullTable = NULL;
- ACPI_SIZE Size;
- UINT8 Allocation;
ACPI_STATUS Status = AE_OK;
+ ACPI_TABLE_HEADER *Header = NULL;
- ACPI_FUNCTION_TRACE ("TbGetTable");
+ ACPI_FUNCTION_TRACE ("TbGetTableHeader");
- if (!TableInfo || !Address)
- {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- }
-
+ /*
+ * Flags contains the current processor mode (Virtual or Physical addressing)
+ * The PointerType is either Logical or Physical
+ */
switch (Address->PointerType)
{
- case ACPI_LOGICAL_POINTER:
-
- /*
- * Getting data from a buffer, not BIOS tables
- */
- TableHeader = Address->Pointer.Logical;
+ case ACPI_PHYSMODE_PHYSPTR:
+ case ACPI_LOGMODE_LOGPTR:
- /* Allocate buffer for the entire table */
+ /* Pointer matches processor mode, copy the header */
- FullTable = ACPI_MEM_ALLOCATE (TableHeader->Length);
- if (!FullTable)
- {
- return_ACPI_STATUS (AE_NO_MEMORY);
- }
-
- /* Copy the entire table (including header) to the local buffer */
-
- Size = (ACPI_SIZE) TableHeader->Length;
- ACPI_MEMCPY (FullTable, TableHeader, Size);
-
- /* Save allocation type */
-
- Allocation = ACPI_MEM_ALLOCATED;
+ ACPI_MEMCPY (ReturnHeader, Address->Pointer.Logical, sizeof (ACPI_TABLE_HEADER));
break;
- case ACPI_PHYSICAL_POINTER:
+ case ACPI_LOGMODE_PHYSPTR:
- /*
- * Not reading from a buffer, just map the table's physical memory
- * into our address space.
- */
- Size = SIZE_IN_HEADER;
+ /* Create a logical address for the physical pointer*/
- Status = AcpiTbMapAcpiTable (Address->Pointer.Physical, &Size, &FullTable);
+ Status = AcpiOsMapMemory (Address->Pointer.Physical, sizeof (ACPI_TABLE_HEADER),
+ (void **) &Header);
if (ACPI_FAILURE (Status))
{
+ ACPI_REPORT_ERROR (("Could not map memory at %p for length %X\n",
+ Address->Pointer.Physical, sizeof (ACPI_TABLE_HEADER)));
return_ACPI_STATUS (Status);
}
- /* Save allocation type */
+ /* Copy header and delete mapping */
- Allocation = ACPI_MEM_MAPPED;
+ ACPI_MEMCPY (ReturnHeader, Header, sizeof (ACPI_TABLE_HEADER));
+ AcpiOsUnmapMemory (Header, sizeof (ACPI_TABLE_HEADER));
break;
default:
+
+ ACPI_REPORT_ERROR (("Invalid address flags %X\n",
+ Address->PointerType));
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
- /* Return values */
-
- TableInfo->Pointer = FullTable;
- TableInfo->Length = Size;
- TableInfo->Allocation = Allocation;
- TableInfo->BasePointer = FullTable;
-
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "Found table [%4.4s] at %8.8X%8.8X, mapped/copied to %p\n",
- FullTable->Signature,
- ACPI_HIDWORD (Address->Pointer.Physical),
- ACPI_LODWORD (Address->Pointer.Physical), FullTable));
-
- return_ACPI_STATUS (Status);
+ return_ACPI_STATUS (AE_OK);
}
/*******************************************************************************
*
- * FUNCTION: AcpiTbGetAllTables
+ * FUNCTION: AcpiTbGetTableBody
*
- * PARAMETERS: NumberOfTables - Number of tables to get
+ * PARAMETERS: Address - Address of table to retrieve. Can be
+ * Logical or Physical
+ * Header - Header of the table to retrieve
+ * TableInfo - Where the table info is returned
*
* RETURN: Status
*
- * DESCRIPTION: Load and validate tables other than the RSDT. The RSDT must
- * already be loaded and validated.
- *
- * Get the minimum set of ACPI tables, namely:
- *
- * 1) FADT (via RSDT in loop below)
- * 2) FACS (via FADT)
- * 3) DSDT (via FADT)
+ * DESCRIPTION: Get an entire ACPI table with support to allow the host OS to
+ * replace the table with a newer version (table override.)
+ * Works in both physical or virtual
+ * addressing mode. Works with both physical or logical pointers.
+ * Table is either copied or mapped, depending on the pointer
+ * type and mode of the processor.
*
******************************************************************************/
ACPI_STATUS
-AcpiTbGetAllTables (
- UINT32 NumberOfTables)
+AcpiTbGetTableBody (
+ ACPI_POINTER *Address,
+ ACPI_TABLE_HEADER *Header,
+ ACPI_TABLE_DESC *TableInfo)
{
- ACPI_STATUS Status = AE_OK;
- UINT32 Index;
- ACPI_TABLE_DESC TableInfo;
- ACPI_POINTER Address;
-
-
- ACPI_FUNCTION_TRACE ("TbGetAllTables");
-
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Number of tables: %d\n", NumberOfTables));
-
-
- /*
- * Loop through all table pointers found in RSDT.
- * This will NOT include the FACS and DSDT - we must get
- * them after the loop.
- *
- * The ONLY table we are interested in getting here is the FADT.
- */
- for (Index = 0; Index < NumberOfTables; Index++)
- {
- /* Clear the TableInfo each time */
-
- ACPI_MEMSET (&TableInfo, 0, sizeof (ACPI_TABLE_DESC));
-
- /* Get the table via the XSDT */
-
- Address.PointerType = AcpiGbl_TableFlags;
- Address.Pointer.Value = ACPI_GET_ADDRESS (AcpiGbl_XSDT->TableOffsetEntry[Index]);
-
- Status = AcpiTbGetTable (&Address, &TableInfo);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
-
- /* Recognize and install the table */
-
- Status = AcpiTbInstallTable (&TableInfo);
- if (ACPI_FAILURE (Status))
- {
- /*
- * Unrecognized or unsupported table, delete it and ignore the
- * error. Just get as many tables as we can, later we will
- * determine if there are enough tables to continue.
- */
- (void) AcpiTbUninstallTable (&TableInfo);
- Status = AE_OK;
- }
- }
+ ACPI_STATUS Status;
- if (!AcpiGbl_FADT)
- {
- ACPI_REPORT_ERROR (("No FADT present in R/XSDT\n"));
- return_ACPI_STATUS (AE_NO_ACPI_TABLES);
- }
- /*
- * Convert the FADT to a common format. This allows earlier revisions of the
- * table to coexist with newer versions, using common access code.
- */
- Status = AcpiTbConvertTableFadt ();
- if (ACPI_FAILURE (Status))
- {
- ACPI_REPORT_ERROR (("Could not convert FADT to internal common format\n"));
- return_ACPI_STATUS (Status);
- }
+ ACPI_FUNCTION_TRACE ("TbGetTableBody");
- /*
- * Get the FACS (must have the FADT first, from loop above)
- * AcpiTbGetTableFacs will fail if FADT pointer is not valid
- */
- Address.PointerType = AcpiGbl_TableFlags;
- Address.Pointer.Value = ACPI_GET_ADDRESS (AcpiGbl_FADT->XFirmwareCtrl);
- Status = AcpiTbGetTable (&Address, &TableInfo);
- if (ACPI_FAILURE (Status))
- {
- ACPI_REPORT_ERROR (("Could not get the FACS, %s\n",
- AcpiFormatException (Status)));
- return_ACPI_STATUS (Status);
- }
-
- /* Install the FACS */
-
- Status = AcpiTbInstallTable (&TableInfo);
- if (ACPI_FAILURE (Status))
+ if (!TableInfo || !Address)
{
- ACPI_REPORT_ERROR (("Could not install the FACS, %s\n",
- AcpiFormatException (Status)));
- return_ACPI_STATUS (Status);
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/*
- * Create the common FACS pointer table
- * (Contains pointers to the original table)
+ * Attempt table override.
*/
- Status = AcpiTbBuildCommonFacs (&TableInfo);
- if (ACPI_FAILURE (Status))
+ Status = AcpiTbTableOverride (Header, TableInfo);
+ if (ACPI_SUCCESS (Status))
{
- return_ACPI_STATUS (Status);
- }
-
- /*
- * Get/install the DSDT (We know that the FADT is valid now)
- */
- Address.PointerType = AcpiGbl_TableFlags;
- Address.Pointer.Value = ACPI_GET_ADDRESS (AcpiGbl_FADT->XDsdt);
+ /* Table was overridden by the host OS */
- Status = AcpiTbGetTableWithOverride (&Address, &TableInfo);
- if (ACPI_FAILURE (Status))
- {
- ACPI_REPORT_ERROR (("Could not get the DSDT\n"));
return_ACPI_STATUS (Status);
}
- /* Set Integer Width (32/64) based upon DSDT revision */
-
- AcpiUtSetIntegerWidth (AcpiGbl_DSDT->Revision);
-
- /* Dump the entire DSDT */
-
- ACPI_DEBUG_PRINT ((ACPI_DB_TABLES,
- "Hex dump of entire DSDT, size %d (0x%X), Integer width = %d\n",
- AcpiGbl_DSDT->Length, AcpiGbl_DSDT->Length, AcpiGbl_IntegerBitWidth));
- ACPI_DUMP_BUFFER ((UINT8 *) AcpiGbl_DSDT, AcpiGbl_DSDT->Length);
-
- /* Always delete the RSDP mapping, we are done with it */
+ /* No override, get the original table */
- AcpiTbDeleteAcpiTable (ACPI_TABLE_RSDP);
+ Status = AcpiTbGetThisTable (Address, Header, TableInfo);
return_ACPI_STATUS (Status);
}
/*******************************************************************************
*
- * FUNCTION: AcpiTbVerifyRsdp
+ * FUNCTION: AcpiTbTableOverride
*
- * PARAMETERS: NumberOfTables - Where the table count is placed
+ * PARAMETERS: Header - Pointer to table header
+ * TableInfo - Return info if table is overridden
*
- * RETURN: Status
+ * RETURN: None
*
- * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
+ * DESCRIPTION: Attempts override of current table with a new one if provided
+ * by the host OS.
*
******************************************************************************/
ACPI_STATUS
-AcpiTbVerifyRsdp (
- ACPI_POINTER *Address)
+AcpiTbTableOverride (
+ ACPI_TABLE_HEADER *Header,
+ ACPI_TABLE_DESC *TableInfo)
{
- ACPI_TABLE_DESC TableInfo;
+ ACPI_TABLE_HEADER *NewTable;
ACPI_STATUS Status;
- RSDP_DESCRIPTOR *Rsdp;
-
-
- ACPI_FUNCTION_TRACE ("TbVerifyRsdp");
+ ACPI_POINTER Address;
- switch (Address->PointerType)
- {
- case ACPI_LOGICAL_POINTER:
+ ACPI_FUNCTION_TRACE ("TbTableOverride");
- Rsdp = Address->Pointer.Logical;
- break;
-
- case ACPI_PHYSICAL_POINTER:
- /*
- * Obtain access to the RSDP structure
- */
- Status = AcpiOsMapMemory (Address->Pointer.Physical, sizeof (RSDP_DESCRIPTOR),
- (void **) &Rsdp);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
- break;
-
- default:
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- }
/*
- * The signature and checksum must both be correct
+ * The OSL will examine the header and decide whether to override this
+ * table. If it decides to override, a table will be returned in NewTable,
+ * which we will then copy.
*/
- if (ACPI_STRNCMP ((NATIVE_CHAR *) Rsdp, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0)
+ Status = AcpiOsTableOverride (Header, &NewTable);
+ if (ACPI_FAILURE (Status))
{
- /* Nope, BAD Signature */
+ /* Some severe error from the OSL, but we basically ignore it */
- Status = AE_BAD_SIGNATURE;
- goto Cleanup;
+ ACPI_REPORT_ERROR (("Could not override ACPI table, %s\n",
+ AcpiFormatException (Status)));
+ return_ACPI_STATUS (Status);
}
- /* Check the standard checksum */
-
- if (AcpiTbChecksum (Rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0)
+ if (!NewTable)
{
- Status = AE_BAD_CHECKSUM;
- goto Cleanup;
- }
-
- /* Check extended checksum if table version >= 2 */
+ /* No table override */
- if (Rsdp->Revision >= 2)
- {
- if (AcpiTbChecksum (Rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)
- {
- Status = AE_BAD_CHECKSUM;
- goto Cleanup;
- }
+ return_ACPI_STATUS (AE_NO_ACPI_TABLES);
}
- /* The RSDP supplied is OK */
-
- TableInfo.Pointer = ACPI_CAST_PTR (ACPI_TABLE_HEADER, Rsdp);
- TableInfo.Length = sizeof (RSDP_DESCRIPTOR);
- TableInfo.Allocation = ACPI_MEM_MAPPED;
- TableInfo.BasePointer = Rsdp;
-
- /* Save the table pointers and allocation info */
+ /*
+ * We have a new table to override the old one. Get a copy of
+ * the new one. We know that the new table has a logical pointer.
+ */
+ Address.PointerType = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING;
+ Address.Pointer.Logical = NewTable;
- Status = AcpiTbInitTableDescriptor (ACPI_TABLE_RSDP, &TableInfo);
+ Status = AcpiTbGetThisTable (&Address, NewTable, TableInfo);
if (ACPI_FAILURE (Status))
{
- goto Cleanup;
- }
-
- /* Save the RSDP in a global for easy access */
-
- AcpiGbl_RSDP = ACPI_CAST_PTR (RSDP_DESCRIPTOR, TableInfo.Pointer);
- return_ACPI_STATUS (Status);
-
-
- /* Error exit */
-Cleanup:
-
- if (AcpiGbl_TableFlags & ACPI_PHYSICAL_POINTER)
- {
- AcpiOsUnmapMemory (Rsdp, sizeof (RSDP_DESCRIPTOR));
+ ACPI_REPORT_ERROR (("Could not copy override ACPI table, %s\n",
+ AcpiFormatException (Status)));
+ return_ACPI_STATUS (Status);
}
- return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AcpiTbGetRsdtAddress
- *
- * PARAMETERS: None
- *
- * RETURN: RSDT physical address
- *
- * DESCRIPTION: Extract the address of the RSDT or XSDT, depending on the
- * version of the RSDP
- *
- ******************************************************************************/
-
-void
-AcpiTbGetRsdtAddress (
- ACPI_POINTER *OutAddress)
-{
-
- ACPI_FUNCTION_ENTRY ();
+ /* Copy the table info */
- OutAddress->PointerType = AcpiGbl_TableFlags;
+ ACPI_REPORT_INFO (("Table [%4.4s] replaced by host OS\n",
+ TableInfo->Pointer->Signature));
- /*
- * For RSDP revision 0 or 1, we use the RSDT.
- * For RSDP revision 2 (and above), we use the XSDT
- */
- if (AcpiGbl_RSDP->Revision < 2)
- {
- OutAddress->Pointer.Value = AcpiGbl_RSDP->RsdtPhysicalAddress;
- }
- else
- {
- OutAddress->Pointer.Value = ACPI_GET_ADDRESS (AcpiGbl_RSDP->XsdtPhysicalAddress);
- }
+ return_ACPI_STATUS (AE_OK);
}
/*******************************************************************************
*
- * FUNCTION: AcpiTbValidateRsdt
+ * FUNCTION: AcpiTbGetThisTable
*
- * PARAMETERS: TablePtr - Addressable pointer to the RSDT.
+ * PARAMETERS: Address - Address of table to retrieve. Can be
+ * Logical or Physical
+ * Header - Header of the table to retrieve
+ * TableInfo - Where the table info is returned
*
* RETURN: Status
*
- * DESCRIPTION: Validate signature for the RSDT or XSDT
+ * DESCRIPTION: Get an entire ACPI table. Works in both physical or virtual
+ * addressing mode. Works with both physical or logical pointers.
+ * Table is either copied or mapped, depending on the pointer
+ * type and mode of the processor.
*
******************************************************************************/
ACPI_STATUS
-AcpiTbValidateRsdt (
- ACPI_TABLE_HEADER *TablePtr)
+AcpiTbGetThisTable (
+ ACPI_POINTER *Address,
+ ACPI_TABLE_HEADER *Header,
+ ACPI_TABLE_DESC *TableInfo)
{
- int NoMatch;
-
+ ACPI_TABLE_HEADER *FullTable = NULL;
+ UINT8 Allocation;
+ ACPI_STATUS Status = AE_OK;
- ACPI_FUNCTION_NAME ("TbValidateRsdt");
+
+ ACPI_FUNCTION_TRACE ("TbGetThisTable");
/*
- * For RSDP revision 0 or 1, we use the RSDT.
- * For RSDP revision 2 and above, we use the XSDT
+ * Flags contains the current processor mode (Virtual or Physical addressing)
+ * The PointerType is either Logical or Physical
*/
- if (AcpiGbl_RSDP->Revision < 2)
- {
- NoMatch = ACPI_STRNCMP ((char *) TablePtr, RSDT_SIG,
- sizeof (RSDT_SIG) -1);
- }
- else
+ switch (Address->PointerType)
{
- NoMatch = ACPI_STRNCMP ((char *) TablePtr, XSDT_SIG,
- sizeof (XSDT_SIG) -1);
- }
+ case ACPI_PHYSMODE_PHYSPTR:
+ case ACPI_LOGMODE_LOGPTR:
- if (NoMatch)
- {
- /* Invalid RSDT or XSDT signature */
+ /* Pointer matches processor mode, copy the table to a new buffer */
+
+ FullTable = ACPI_MEM_ALLOCATE (Header->Length);
+ if (!FullTable)
+ {
+ ACPI_REPORT_ERROR (("Could not allocate table memory for [%4.4s] length %X\n",
+ Header->Signature, Header->Length));
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
- ACPI_REPORT_ERROR (("Invalid signature where RSDP indicates RSDT/XSDT should be located\n"));
+ /* Copy the entire table (including header) to the local buffer */
- ACPI_DUMP_BUFFER (AcpiGbl_RSDP, 20);
+ ACPI_MEMCPY (FullTable, Address->Pointer.Logical, Header->Length);
- ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR,
- "RSDT/XSDT signature at %X (%p) is invalid\n",
- AcpiGbl_RSDP->RsdtPhysicalAddress,
- (void *) (NATIVE_UINT) AcpiGbl_RSDP->RsdtPhysicalAddress));
+ /* Save allocation type */
- return (AE_BAD_SIGNATURE);
- }
+ Allocation = ACPI_MEM_ALLOCATED;
+ break;
- return (AE_OK);
-}
+ case ACPI_LOGMODE_PHYSPTR:
-/*******************************************************************************
- *
- * FUNCTION: AcpiTbGetTablePointer
- *
- * PARAMETERS: PhysicalAddress - Address from RSDT
- * Flags - virtual or physical addressing
- * TablePtr - Addressable address (output)
- *
- * RETURN: Status
- *
- * DESCRIPTION: Create an addressable pointer to an ACPI table
- *
- ******************************************************************************/
+ /*
+ * Just map the table's physical memory
+ * into our address space.
+ */
+ Status = AcpiOsMapMemory (Address->Pointer.Physical, (ACPI_SIZE) Header->Length,
+ (void **) &FullTable);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_REPORT_ERROR (("Could not map memory for table [%4.4s] at %p for length %X\n",
+ Header->Signature, Address->Pointer.Physical, Header->Length));
+ return (Status);
+ }
-ACPI_STATUS
-AcpiTbGetTablePointer (
- ACPI_POINTER *Address,
- UINT32 Flags,
- ACPI_SIZE *Size,
- ACPI_TABLE_HEADER **TablePtr)
-{
- ACPI_STATUS Status = AE_OK;
+ /* Save allocation type */
+ Allocation = ACPI_MEM_MAPPED;
+ break;
- ACPI_FUNCTION_ENTRY ();
+ default:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid address flags %X\n",
+ Address->PointerType));
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
/*
- * What mode is the processor in? (Virtual or Physical addressing)
+ * Validate checksum for _most_ tables,
+ * even the ones whose signature we don't recognize
*/
- if ((Flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING)
+ if (TableInfo->Type != ACPI_TABLE_FACS)
{
- /* Incoming pointer can be either logical or physical */
+ Status = AcpiTbVerifyTableChecksum (FullTable);
- switch (Address->PointerType)
+#if (!ACPI_CHECKSUM_ABORT)
+ if (ACPI_FAILURE (Status))
{
- case ACPI_PHYSICAL_POINTER:
+ /* Ignore the error if configuration says so */
- *Size = SIZE_IN_HEADER;
- Status = AcpiTbMapAcpiTable (Address->Pointer.Physical, Size, TablePtr);
- break;
-
- case ACPI_LOGICAL_POINTER:
-
- *TablePtr = Address->Pointer.Logical;
- *Size = 0;
- break;
-
- default:
- return (AE_BAD_PARAMETER);
+ Status = AE_OK;
}
+#endif
}
- else
- {
- /* In Physical addressing mode, all pointers must be physical */
-
- switch (Address->PointerType)
- {
- case ACPI_PHYSICAL_POINTER:
- *Size = 0;
- *TablePtr = Address->Pointer.Logical;
- break;
- case ACPI_LOGICAL_POINTER:
+ /* Return values */
- Status = AE_BAD_PARAMETER;
- break;
+ TableInfo->Pointer = FullTable;
+ TableInfo->Length = (ACPI_SIZE) Header->Length;
+ TableInfo->Allocation = Allocation;
+ TableInfo->BasePointer = FullTable;
- default:
- return (AE_BAD_PARAMETER);
- }
- }
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Found table [%4.4s] at %8.8X%8.8X, mapped/copied to %p\n",
+ FullTable->Signature,
+ ACPI_HIDWORD (Address->Pointer.Physical),
+ ACPI_LODWORD (Address->Pointer.Physical), FullTable));
- return (Status);
+ return_ACPI_STATUS (Status);
}
/*******************************************************************************
*
- * FUNCTION: AcpiTbGetTableRsdt
+ * FUNCTION: AcpiTbGetTablePtr
*
- * PARAMETERS: NumberOfTables - Where the table count is placed
+ * PARAMETERS: TableType - one of the defined table types
+ * Instance - Which table of this type
+ * TablePtrLoc - pointer to location to place the pointer for
+ * return
*
* RETURN: Status
*
- * DESCRIPTION: Load and validate the RSDP (ptr) and RSDT (table)
+ * DESCRIPTION: This function is called to get the pointer to an ACPI table.
*
******************************************************************************/
ACPI_STATUS
-AcpiTbGetTableRsdt (
- UINT32 *NumberOfTables)
+AcpiTbGetTablePtr (
+ ACPI_TABLE_TYPE TableType,
+ UINT32 Instance,
+ ACPI_TABLE_HEADER **TablePtrLoc)
{
- ACPI_TABLE_DESC TableInfo;
- ACPI_STATUS Status;
- ACPI_POINTER Address;
-
+ ACPI_TABLE_DESC *TableDesc;
+ UINT32 i;
- ACPI_FUNCTION_TRACE ("TbGetTableRsdt");
+ ACPI_FUNCTION_TRACE ("TbGetTablePtr");
- /* Get the RSDT/XSDT from the RSDP */
- AcpiTbGetRsdtAddress (&Address);
- Status = AcpiTbGetTable (&Address, &TableInfo);
- if (ACPI_FAILURE (Status))
+ if (!AcpiGbl_DSDT)
{
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not get the R/XSDT, %s\n",
- AcpiFormatException (Status)));
- return_ACPI_STATUS (Status);
+ return_ACPI_STATUS (AE_NO_ACPI_TABLES);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
- "RSDP located at %p, RSDT physical=%8.8X%8.8X \n",
- AcpiGbl_RSDP,
- ACPI_HIDWORD (Address.Pointer.Value),
- ACPI_LODWORD (Address.Pointer.Value)));
-
- /* Check the RSDT or XSDT signature */
-
- Status = AcpiTbValidateRsdt (TableInfo.Pointer);
- if (ACPI_FAILURE (Status))
+ if (TableType > ACPI_TABLE_MAX)
{
- return_ACPI_STATUS (Status);
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/*
- * Valid RSDT signature, verify the checksum. If it fails, just
- * print a warning and ignore it.
+ * For all table types (Single/Multiple), the first
+ * instance is always in the list head.
*/
- Status = AcpiTbVerifyTableChecksum (TableInfo.Pointer);
-
- /* Convert and/or copy to an XSDT structure */
-
- Status = AcpiTbConvertToXsdt (&TableInfo, NumberOfTables);
- if (ACPI_FAILURE (Status))
+ if (Instance == 1)
{
- return_ACPI_STATUS (Status);
+ /*
+ * Just pluck the pointer out of the global table!
+ * Will be null if no table is present
+ */
+ *TablePtrLoc = AcpiGbl_AcpiTables[TableType].Pointer;
+ return_ACPI_STATUS (AE_OK);
}
- /* Save the table pointers and allocation info */
+ /*
+ * Check for instance out of range
+ */
+ if (Instance > AcpiGbl_AcpiTables[TableType].Count)
+ {
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
- Status = AcpiTbInitTableDescriptor (ACPI_TABLE_XSDT, &TableInfo);
- if (ACPI_FAILURE (Status))
+ /* Walk the list to get the desired table
+ * Since the if (Instance == 1) check above checked for the
+ * first table, setting TableDesc equal to the .Next member
+ * is actually pointing to the second table. Therefore, we
+ * need to walk from the 2nd table until we reach the Instance
+ * that the user is looking for and return its table pointer.
+ */
+ TableDesc = AcpiGbl_AcpiTables[TableType].Next;
+ for (i = 2; i < Instance; i++)
{
- return_ACPI_STATUS (Status);
+ TableDesc = TableDesc->Next;
}
- AcpiGbl_XSDT = (XSDT_DESCRIPTOR *) TableInfo.Pointer;
+ /* We are now pointing to the requested table's descriptor */
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "XSDT located at %p\n", AcpiGbl_XSDT));
- return_ACPI_STATUS (Status);
-}
+ *TablePtrLoc = TableDesc->Pointer;
+ return_ACPI_STATUS (AE_OK);
+}
OpenPOWER on IntegriCloud