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_BIOS_ERROR ((AE_INFO, "A valid RSDP was not found")); return_ACPI_STATUS (AE_NOT_FOUND); }
static ACPI_STATUS OslTableInitialize ( void) { char Buffer[32]; ACPI_TABLE_HEADER *MappedTable; UINT8 *TableAddress; UINT8 *RsdpAddress; ACPI_PHYSICAL_ADDRESS RsdpBase; ACPI_SIZE RsdpSize; ACPI_STATUS Status; u_long Address = 0; size_t Length = sizeof (Address); /* Get main ACPI tables from memory on first invocation of this function */ if (Gbl_MainTableObtained) { return (AE_OK); } /* Attempt to use kenv or sysctl to find RSD PTR record. */ if (Gbl_RsdpBase) { Address = Gbl_RsdpBase; } else if (kenv (KENV_GET, SYSTEM_KENV, Buffer, sizeof (Buffer)) > 0) { Address = ACPI_STRTOUL (Buffer, NULL, 0); } if (!Address) { if (sysctlbyname (SYSTEM_SYSCTL, &Address, &Length, NULL, 0) != 0) { Address = 0; } } if (Address) { RsdpBase = Address; RsdpSize = sizeof (Gbl_Rsdp); } else { RsdpBase = ACPI_HI_RSDP_WINDOW_BASE; RsdpSize = ACPI_HI_RSDP_WINDOW_SIZE; } /* Get RSDP from memory */ RsdpAddress = AcpiOsMapMemory (RsdpBase, RsdpSize); if (!RsdpAddress) { return (AE_BAD_ADDRESS); } /* Search low memory for the RSDP */ TableAddress = AcpiTbScanMemoryForRsdp (RsdpAddress, RsdpSize); if (!TableAddress) { AcpiOsUnmapMemory (RsdpAddress, RsdpSize); return (AE_ERROR); } ACPI_MEMCPY (&Gbl_Rsdp, TableAddress, sizeof (Gbl_Rsdp)); AcpiOsUnmapMemory (RsdpAddress, RsdpSize); /* Get XSDT from memory */ if (Gbl_Rsdp.Revision) { Status = OslMapTable (Gbl_Rsdp.XsdtPhysicalAddress, ACPI_SIG_XSDT, &MappedTable); if (ACPI_FAILURE (Status)) { return (Status); } Gbl_Revision = 2; Gbl_Xsdt = calloc (1, MappedTable->Length); if (!Gbl_Xsdt) { fprintf (stderr, "XSDT: Could not allocate buffer for table of length %X\n", MappedTable->Length); AcpiOsUnmapMemory (MappedTable, MappedTable->Length); return (AE_NO_MEMORY); } ACPI_MEMCPY (Gbl_Xsdt, MappedTable, MappedTable->Length); AcpiOsUnmapMemory (MappedTable, MappedTable->Length); } /* Get RSDT from memory */ if (Gbl_Rsdp.RsdtPhysicalAddress) { Status = OslMapTable (Gbl_Rsdp.RsdtPhysicalAddress, ACPI_SIG_RSDT, &MappedTable); if (ACPI_FAILURE (Status)) { return (Status); } Gbl_Rsdt = calloc (1, MappedTable->Length); if (!Gbl_Rsdt) { fprintf (stderr, "RSDT: Could not allocate buffer for table of length %X\n", MappedTable->Length); AcpiOsUnmapMemory (MappedTable, MappedTable->Length); return (AE_NO_MEMORY); } ACPI_MEMCPY (Gbl_Rsdt, MappedTable, MappedTable->Length); AcpiOsUnmapMemory (MappedTable, MappedTable->Length); } /* Get FADT from memory */ if (Gbl_Revision) { Gbl_FadtAddress = Gbl_Xsdt->TableOffsetEntry[0]; } else { Gbl_FadtAddress = Gbl_Rsdt->TableOffsetEntry[0]; } if (!Gbl_FadtAddress) { fprintf(stderr, "FADT: Table could not be found\n"); return (AE_ERROR); } Status = OslMapTable (Gbl_FadtAddress, ACPI_SIG_FADT, &MappedTable); if (ACPI_FAILURE (Status)) { return (Status); } Gbl_Fadt = calloc (1, MappedTable->Length); if (!Gbl_Fadt) { fprintf (stderr, "FADT: Could not allocate buffer for table of length %X\n", MappedTable->Length); AcpiOsUnmapMemory (MappedTable, MappedTable->Length); return (AE_NO_MEMORY); } ACPI_MEMCPY (Gbl_Fadt, MappedTable, MappedTable->Length); AcpiOsUnmapMemory (MappedTable, MappedTable->Length); Gbl_MainTableObtained = TRUE; return (AE_OK); }
ACPI_STATUS AcpiTbFindRsdp ( ACPI_TABLE_DESC *TableInfo, UINT32 Flags) { UINT8 *TablePtr; UINT8 *MemRover; UINT64 PhysAddr; ACPI_STATUS Status = AE_OK; ACPI_FUNCTION_TRACE ("TbFindRsdp"); /* * 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 ((UINT64) ACPI_LO_RSDP_WINDOW_BASE, ACPI_LO_RSDP_WINDOW_SIZE, (void **) &TablePtr); if (ACPI_FAILURE (Status)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %X for length %X\n", ACPI_LO_RSDP_WINDOW_BASE, ACPI_LO_RSDP_WINDOW_SIZE)); return_ACPI_STATUS (Status); } MemRover = AcpiTbScanMemoryForRsdp (TablePtr, ACPI_LO_RSDP_WINDOW_SIZE); AcpiOsUnmapMemory (TablePtr, ACPI_LO_RSDP_WINDOW_SIZE); if (MemRover) { /* Found it, return the physical address */ PhysAddr = ACPI_LO_RSDP_WINDOW_BASE; PhysAddr += ACPI_PTR_DIFF (MemRover,TablePtr); TableInfo->PhysicalAddress = PhysAddr; return_ACPI_STATUS (AE_OK); } /* * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h */ Status = AcpiOsMapMemory ((UINT64) ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE, (void **) &TablePtr); if (ACPI_FAILURE (Status)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %X for length %X\n", ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE)); return_ACPI_STATUS (Status); } MemRover = AcpiTbScanMemoryForRsdp (TablePtr, ACPI_HI_RSDP_WINDOW_SIZE); AcpiOsUnmapMemory (TablePtr, ACPI_HI_RSDP_WINDOW_SIZE); if (MemRover) { /* Found it, return the physical address */ PhysAddr = ACPI_HI_RSDP_WINDOW_BASE; PhysAddr += ACPI_PTR_DIFF (MemRover, TablePtr); TableInfo->PhysicalAddress = PhysAddr; return_ACPI_STATUS (AE_OK); } } /* * Physical addressing */ else { /* * 1) Search EBDA (low memory) paragraphs */ MemRover = AcpiTbScanMemoryForRsdp (ACPI_PHYSADDR_TO_PTR (ACPI_LO_RSDP_WINDOW_BASE), ACPI_LO_RSDP_WINDOW_SIZE); if (MemRover) { /* Found it, return the physical address */ TableInfo->PhysicalAddress = ACPI_TO_INTEGER (MemRover); return_ACPI_STATUS (AE_OK); } /* * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h */ MemRover = AcpiTbScanMemoryForRsdp (ACPI_PHYSADDR_TO_PTR (ACPI_HI_RSDP_WINDOW_BASE), ACPI_HI_RSDP_WINDOW_SIZE); if (MemRover) { /* Found it, return the physical address */ TableInfo->PhysicalAddress = ACPI_TO_INTEGER (MemRover); return_ACPI_STATUS (AE_OK); } } /* RSDP signature was not found */ return_ACPI_STATUS (AE_NOT_FOUND); }