示例#1
0
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);
}
示例#3
0
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);
}