summaryrefslogtreecommitdiff
path: root/sys/contrib/dev/acpica/tbxfroot.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/dev/acpica/tbxfroot.c')
-rw-r--r--sys/contrib/dev/acpica/tbxfroot.c260
1 files changed, 221 insertions, 39 deletions
diff --git a/sys/contrib/dev/acpica/tbxfroot.c b/sys/contrib/dev/acpica/tbxfroot.c
index 14b09b11e4a40..0d1663d77cf92 100644
--- a/sys/contrib/dev/acpica/tbxfroot.c
+++ b/sys/contrib/dev/acpica/tbxfroot.c
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Module Name: tbxfroot - Find the root ACPI table (RSDT)
- * $Revision: 37 $
+ * $Revision: 39 $
*
*****************************************************************************/
@@ -152,7 +152,7 @@ AcpiFindRootPointer (
/* Get the RSDP */
- Status = AcpiTbFindRsdp (&TableInfo);
+ Status = AcpiTbFindRsdp (&TableInfo, ACPI_LOGICAL_ADDRESSING);
if (ACPI_FAILURE (Status))
{
DEBUG_PRINTP (ACPI_ERROR, ("RSDP structure not found\n"));
@@ -218,9 +218,9 @@ AcpiTbScanMemoryForRsdp (
*
* FUNCTION: AcpiTbFindRsdp
*
- * PARAMETERS: *BufferPtr - If == NULL, read data from buffer
- * rather than searching memory
- * *TableInfo - Where the table info is returned
+ * PARAMETERS: *TableInfo - Where the table info is returned
+ * Flags - Current memory mode (logical vs.
+ * physical addressing)
*
* RETURN: Status
*
@@ -235,7 +235,8 @@ AcpiTbScanMemoryForRsdp (
ACPI_STATUS
AcpiTbFindRsdp (
- ACPI_TABLE_DESC *TableInfo)
+ ACPI_TABLE_DESC *TableInfo,
+ UINT32 Flags)
{
UINT8 *TablePtr;
UINT8 *MemRover;
@@ -246,75 +247,256 @@ AcpiTbFindRsdp (
FUNCTION_TRACE ("TbFindRsdp");
- /*
- * Search memory for RSDP. First map low physical memory.
+ /*
+ * Scan supports either 1) Logical addressing or 2) Physical addressing
*/
+ if ((Flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING)
+ {
+ /*
+ * 1) Search EBDA (low memory) paragraphs
+ */
+ Status = AcpiOsMapMemory (LO_RSDP_WINDOW_BASE, LO_RSDP_WINDOW_SIZE,
+ (void **) &TablePtr);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
- Status = AcpiOsMapMemory (LO_RSDP_WINDOW_BASE, LO_RSDP_WINDOW_SIZE,
- (void **)&TablePtr);
+ MemRover = AcpiTbScanMemoryForRsdp (TablePtr, LO_RSDP_WINDOW_SIZE);
+ AcpiOsUnmapMemory (TablePtr, LO_RSDP_WINDOW_SIZE);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
+ if (MemRover)
+ {
+ /* Found it, return the physical address */
+
+ PhysAddr = LO_RSDP_WINDOW_BASE;
+ PhysAddr += (MemRover - TablePtr);
+
+ TableInfo->PhysicalAddress = PhysAddr;
+
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /*
+ * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h
+ */
+ Status = AcpiOsMapMemory (HI_RSDP_WINDOW_BASE, HI_RSDP_WINDOW_SIZE,
+ (void **) &TablePtr);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ MemRover = AcpiTbScanMemoryForRsdp (TablePtr, HI_RSDP_WINDOW_SIZE);
+ AcpiOsUnmapMemory (TablePtr, HI_RSDP_WINDOW_SIZE);
+
+ if (MemRover)
+ {
+ /* Found it, return the physical address */
+
+ PhysAddr = HI_RSDP_WINDOW_BASE;
+ PhysAddr += (MemRover - TablePtr);
+
+ TableInfo->PhysicalAddress = PhysAddr;
+
+ return_ACPI_STATUS (AE_OK);
+ }
}
+
/*
- * 1) Search EBDA (low memory) paragraphs
+ * Physical addressing
*/
+ else
+ {
+ /*
+ * 1) Search EBDA (low memory) paragraphs
+ */
+ MemRover = AcpiTbScanMemoryForRsdp ((UINT8 *) LO_RSDP_WINDOW_BASE,
+ LO_RSDP_WINDOW_SIZE);
+ if (MemRover)
+ {
+ /* Found it, return the physical address */
- MemRover = AcpiTbScanMemoryForRsdp (TablePtr, LO_RSDP_WINDOW_SIZE);
+ TableInfo->PhysicalAddress = (ACPI_TBLPTR) MemRover;
+ return_ACPI_STATUS (AE_OK);
+ }
- /* This mapping is no longer needed */
+ /*
+ * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h
+ */
+ MemRover = AcpiTbScanMemoryForRsdp ((UINT8 *) HI_RSDP_WINDOW_BASE,
+ HI_RSDP_WINDOW_SIZE);
+ if (MemRover)
+ {
+ /* Found it, return the physical address */
- AcpiOsUnmapMemory (TablePtr, LO_RSDP_WINDOW_SIZE);
+ TableInfo->PhysicalAddress = (ACPI_TBLPTR) MemRover;
+ return_ACPI_STATUS (AE_OK);
+ }
+ }
- if (MemRover)
- {
- /* Found it, return the physical address */
- PhysAddr = LO_RSDP_WINDOW_BASE;
- PhysAddr += (MemRover - TablePtr);
+ /* RSDP signature was not found */
- TableInfo->PhysicalAddress = PhysAddr;
+ return_ACPI_STATUS (AE_NOT_FOUND);
+}
- return_ACPI_STATUS (AE_OK);
- }
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiGetFirmwareTable
+ *
+ * PARAMETERS: Signature - Any ACPI table signature
+ * Instance - the non zero instance of the table, allows
+ * support for multiple tables of the same type
+ * Flags - 0: Physical/Virtual support
+ * RetBuffer - pointer to a structure containing a buffer to
+ * receive the table
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function is called to get an ACPI table. The caller
+ * supplies an OutBuffer large enough to contain the entire ACPI
+ * table. Upon completion
+ * the OutBuffer->Length field will indicate the number of bytes
+ * copied into the OutBuffer->BufPtr buffer. This table will be
+ * a complete table including the header.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetFirmwareTable (
+ ACPI_STRING Signature,
+ UINT32 Instance,
+ UINT32 Flags,
+ ACPI_TABLE_HEADER **TablePointer)
+{
+ ACPI_PHYSICAL_ADDRESS PhysicalAddress;
+ ACPI_TABLE_DESC TableInfo;
+ ACPI_TABLE_HEADER *RsdtPtr;
+ ACPI_TABLE_HEADER *TablePtr;
+ ACPI_STATUS Status;
+ UINT32 RsdtSize;
+ UINT32 TableSize;
+ UINT32 TableCount;
+ UINT32 i;
+ UINT32 j;
+
+
+ FUNCTION_TRACE ("AcpiGetFirmwareTable");
+
+
+ /*
+ * Ensure that at least the table manager is initialized. We don't
+ * require that the entire ACPI subsystem is up for this interface
+ */
/*
- * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h
+ * If we have a buffer, we must have a length too
*/
+ if ((Instance == 0) ||
+ (!Signature) ||
+ (!TablePointer))
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
- Status = AcpiOsMapMemory (HI_RSDP_WINDOW_BASE, HI_RSDP_WINDOW_SIZE,
- (void **)&TablePtr);
+ /* Get the RSDP by scanning low memory */
+ Status = AcpiTbFindRsdp (&TableInfo, Flags);
+ if (ACPI_FAILURE (Status))
+ {
+ DEBUG_PRINTP (ACPI_ERROR, ("RSDP structure not found\n"));
+ return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+ }
+
+ AcpiGbl_RSDP = (RSDP_DESCRIPTOR *) TableInfo.Pointer;
+
+
+ /* Get the RSDT and validate it */
+
+ PhysicalAddress = AcpiTbGetRsdtAddress ();
+ Status = AcpiTbGetTablePointer (PhysicalAddress, Flags, &RsdtSize, &RsdtPtr);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
- MemRover = AcpiTbScanMemoryForRsdp (TablePtr, HI_RSDP_WINDOW_SIZE);
+ Status = AcpiTbValidateRsdt (RsdtPtr);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
- /* This mapping is no longer needed */
+ /* Get the number of table pointers within the RSDT */
- AcpiOsUnmapMemory (TablePtr, HI_RSDP_WINDOW_SIZE);
+ TableCount = AcpiTbGetTableCount (AcpiGbl_RSDP, RsdtPtr);
- if (MemRover)
+
+ /*
+ * Search the RSDT/XSDT for the correct instance of the
+ * requested table
+ */
+ for (i = 0, j = 0; i < TableCount; i++)
{
- /* Found it, return the physical address */
+ /* Get the next table pointer */
+
+ if (AcpiGbl_RSDP->Revision < 2)
+ {
+ PhysicalAddress = ((RSDT_DESCRIPTOR *) RsdtPtr)->TableOffsetEntry[i];
+ }
+ else
+ {
+ PhysicalAddress = (ACPI_PHYSICAL_ADDRESS)
+ ACPI_GET_ADDRESS (((XSDT_DESCRIPTOR *) RsdtPtr)->TableOffsetEntry[i]);
+ }
+
+ /* Get addressibility if necessary */
+
+ Status = AcpiTbGetTablePointer (PhysicalAddress, Flags, &TableSize, &TablePtr);
+ if (ACPI_FAILURE (Status))
+ {
+ goto Cleanup;
+ }
+
+ /* Compare table signatures and table instance */
- PhysAddr = HI_RSDP_WINDOW_BASE;
- PhysAddr += (MemRover - TablePtr);
+ if (!STRNCMP ((char *) TablePtr, Signature, STRLEN (Signature)))
+ {
+ /* An instance of the table was found */
+
+ j++;
+ if (j >= Instance)
+ {
+ /* Found the correct instance */
+
+ *TablePointer = TablePtr;
+ goto Cleanup;
+ }
+ }
- TableInfo->PhysicalAddress = PhysAddr;
+ /* Delete table mapping if using virtual addressing */
- return_ACPI_STATUS (AE_OK);
+ if (TableSize)
+ {
+ AcpiOsUnmapMemory (TablePtr, TableSize);
+ }
}
+ /* Did not find the table */
- /* RSDP signature was not found */
+ Status = AE_NOT_EXIST;
- return_ACPI_STATUS (AE_NOT_FOUND);
+
+Cleanup:
+ if (RsdtSize)
+ {
+ AcpiOsUnmapMemory (RsdtPtr, RsdtSize);
+ }
+ return_ACPI_STATUS (Status);
}