Exemplo n.º 1
0
ACPI_STATUS
AcpiTbBuildCommonFacs (
    ACPI_TABLE_DESC         *TableInfo)
{

    ACPI_FUNCTION_TRACE (TbBuildCommonFacs);


    /* Absolute minimum length is 24, but the ACPI spec says 64 */

    if (AcpiGbl_FACS->Length < 24)
    {
        ACPI_ERROR ((AE_INFO, "Invalid FACS table length: 0x%X",
            AcpiGbl_FACS->Length));
        return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
    }

    if (AcpiGbl_FACS->Length < 64)
    {
        ACPI_WARNING ((AE_INFO,
            "FACS is shorter than the ACPI specification allows: 0x%X, using anyway",
            AcpiGbl_FACS->Length));
    }

    /* Copy fields to the new FACS */

    AcpiGbl_CommonFACS.GlobalLock = &(AcpiGbl_FACS->GlobalLock);

    if ((AcpiGbl_RSDP->Revision < 2) ||
        (AcpiGbl_FACS->Length < 32)  ||
        (!(ACPI_GET_ADDRESS (AcpiGbl_FACS->XFirmwareWakingVector))))
    {
        /* ACPI 1.0 FACS or short table or optional X_ field is zero */

        AcpiGbl_CommonFACS.FirmwareWakingVector = ACPI_CAST_PTR (UINT64,
                &(AcpiGbl_FACS->FirmwareWakingVector));
        AcpiGbl_CommonFACS.VectorWidth = 32;
    }
    else
    {
        /* ACPI 2.0 FACS with valid X_ field */

        AcpiGbl_CommonFACS.FirmwareWakingVector = &AcpiGbl_FACS->XFirmwareWakingVector;
        AcpiGbl_CommonFACS.VectorWidth = 64;
    }

    return_ACPI_STATUS (AE_OK);
}
Exemplo n.º 2
0
static void
AcpiTbConvertFadt2 (
    FADT_DESCRIPTOR_REV2   *LocalFadt,
    FADT_DESCRIPTOR_REV2   *OriginalFadt)
{

    /* We have an ACPI 2.0 FADT but we must copy it to our local buffer */

    ACPI_MEMCPY (LocalFadt, OriginalFadt, sizeof (FADT_DESCRIPTOR_REV2));

    /*
     * "X" fields are optional extensions to the original V1.0 fields, so
     * we must selectively expand V1.0 fields if the corresponding X field
     * is zero.
     */
    if (!(ACPI_GET_ADDRESS (LocalFadt->XFirmwareCtrl)))
    {
        ACPI_STORE_ADDRESS (LocalFadt->XFirmwareCtrl, LocalFadt->V1_FirmwareCtrl);
    }

    if (!(ACPI_GET_ADDRESS (LocalFadt->XDsdt)))
    {
        ACPI_STORE_ADDRESS (LocalFadt->XDsdt, LocalFadt->V1_Dsdt);
    }

    if (!(ACPI_GET_ADDRESS (LocalFadt->XPm1aEvtBlk.Address)))
    {
        ASL_BUILD_GAS_FROM_V1_ENTRY (LocalFadt->XPm1aEvtBlk,
            LocalFadt->Pm1EvtLen,  LocalFadt->V1_Pm1aEvtBlk);
    }

    if (!(ACPI_GET_ADDRESS (LocalFadt->XPm1bEvtBlk.Address)))
    {
        ASL_BUILD_GAS_FROM_V1_ENTRY (LocalFadt->XPm1bEvtBlk,
            LocalFadt->Pm1EvtLen,  LocalFadt->V1_Pm1bEvtBlk);
    }

    if (!(ACPI_GET_ADDRESS (LocalFadt->XPm1aCntBlk.Address)))
    {
        ASL_BUILD_GAS_FROM_V1_ENTRY (LocalFadt->XPm1aCntBlk,
            LocalFadt->Pm1CntLen,  LocalFadt->V1_Pm1aCntBlk);
    }

    if (!(ACPI_GET_ADDRESS (LocalFadt->XPm1bCntBlk.Address)))
    {
        ASL_BUILD_GAS_FROM_V1_ENTRY (LocalFadt->XPm1bCntBlk,
            LocalFadt->Pm1CntLen,  LocalFadt->V1_Pm1bCntBlk);
    }

    if (!(ACPI_GET_ADDRESS (LocalFadt->XPm2CntBlk.Address)))
    {
        ASL_BUILD_GAS_FROM_V1_ENTRY (LocalFadt->XPm2CntBlk,
            LocalFadt->Pm2CntLen,  LocalFadt->V1_Pm2CntBlk);
    }

    if (!(ACPI_GET_ADDRESS (LocalFadt->XPmTmrBlk.Address)))
    {
        ASL_BUILD_GAS_FROM_V1_ENTRY (LocalFadt->XPmTmrBlk,
            LocalFadt->PmTmLen,    LocalFadt->V1_PmTmrBlk);
    }

    if (!(ACPI_GET_ADDRESS (LocalFadt->XGpe0Blk.Address)))
    {
        ASL_BUILD_GAS_FROM_V1_ENTRY (LocalFadt->XGpe0Blk,
            0, LocalFadt->V1_Gpe0Blk);
    }

    if (!(ACPI_GET_ADDRESS (LocalFadt->XGpe1Blk.Address)))
    {
        ASL_BUILD_GAS_FROM_V1_ENTRY (LocalFadt->XGpe1Blk,
            0, LocalFadt->V1_Gpe1Blk);
    }
}
Exemplo n.º 3
0
ACPI_STATUS
AcpiTbGetRequiredTables (
    void)
{
    ACPI_STATUS             Status = AE_OK;
    UINT32                  i;
    ACPI_TABLE_DESC         TableInfo;
    ACPI_POINTER            Address;


    ACPI_FUNCTION_TRACE ("TbGetRequiredTables");

    ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%d ACPI tables in RSDT\n",
        AcpiGbl_RsdtTableCount));


    Address.PointerType   = AcpiGbl_TableFlags | ACPI_LOGICAL_ADDRESSING;

    /*
     * 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 tables we are interested in getting here is the FADT and
     * any SSDTs.
     */
    for (i = 0; i < AcpiGbl_RsdtTableCount; i++)
    {
        /* Get the table addresss from the common internal XSDT */

        Address.Pointer.Value = ACPI_GET_ADDRESS (AcpiGbl_XSDT->TableOffsetEntry[i]);

        /*
         * Get the tables needed by this subsystem (FADT and any SSDTs).
         * NOTE: All other tables are completely ignored at this time.
         */
        Status = AcpiTbGetPrimaryTable (&Address, &TableInfo);
        if ((Status != AE_OK) && (Status != AE_TABLE_NOT_SUPPORTED))
        {
            ACPI_REPORT_WARNING (("%s, while getting table at %8.8X%8.8X\n",
                AcpiFormatException (Status),
                ACPI_HIDWORD (Address.Pointer.Value),
                ACPI_LODWORD (Address.Pointer.Value)));
        }
    }

    /* We must have a FADT to continue */

    if (!AcpiGbl_FADT)
    {
        ACPI_REPORT_ERROR (("No FADT present in RSDT/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);
    }

    /*
     * Get the FACS (Pointed to by the FADT)
     */
    Address.Pointer.Value = ACPI_GET_ADDRESS (AcpiGbl_FADT->XFirmwareCtrl);

    Status = AcpiTbGetSecondaryTable (&Address, FACS_SIG, &TableInfo);
    if (ACPI_FAILURE (Status))
    {
        ACPI_REPORT_ERROR (("Could not get/install the FACS, %s\n",
            AcpiFormatException (Status)));
        return_ACPI_STATUS (Status);
    }

    /*
     * Create the common FACS pointer table
     * (Contains pointers to the original table)
     */
    Status = AcpiTbBuildCommonFacs (&TableInfo);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /*
     * Get/install the DSDT (Pointed to by the FADT)
     */
    Address.Pointer.Value = ACPI_GET_ADDRESS (AcpiGbl_FADT->XDsdt);

    Status = AcpiTbGetSecondaryTable (&Address, DSDT_SIG, &TableInfo);
    if (ACPI_FAILURE (Status))
    {
        ACPI_REPORT_ERROR (("Could not get/install 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 */

    AcpiTbDeleteAcpiTable (ACPI_TABLE_RSDP);
    return_ACPI_STATUS (Status);
}
Exemplo n.º 4
0
ACPI_STATUS
AcpiGetFirmwareTable (
    ACPI_STRING             Signature,
    UINT32                  Instance,
    UINT32                  Flags,
    ACPI_TABLE_HEADER       **TablePointer)
{
    ACPI_POINTER            RsdpAddress;
    ACPI_POINTER            Address;
    ACPI_STATUS             Status;
    ACPI_TABLE_HEADER       Header;
    ACPI_TABLE_DESC         TableInfo;
    ACPI_TABLE_DESC         RsdtInfo;
    UINT32                  TableCount;
    UINT32                  i;
    UINT32                  j;


    ACPI_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
     */

    /*
     *  If we have a buffer, we must have a length too
     */
    if ((Instance == 0)                 ||
        (!Signature)                    ||
        (!TablePointer))
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    RsdtInfo.Pointer = NULL;

    if (!AcpiGbl_RSDP)
    {
        /* Get the RSDP */

        Status = AcpiOsGetRootPointer (Flags, &RsdpAddress);
        if (ACPI_FAILURE (Status))
        {
            ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "RSDP  not found\n"));
            return_ACPI_STATUS (AE_NO_ACPI_TABLES);
        }

        /* Map and validate the RSDP */

        if ((Flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING)
        {
            Status = AcpiOsMapMemory (RsdpAddress.Pointer.Physical, sizeof (RSDP_DESCRIPTOR),
                                        (void **) &AcpiGbl_RSDP);
            if (ACPI_FAILURE (Status))
            {
                return_ACPI_STATUS (Status);
            }
        }
        else
        {
            AcpiGbl_RSDP = RsdpAddress.Pointer.Logical;
        }

        /*
         *  The signature and checksum must both be correct
         */
        if (ACPI_STRNCMP ((char *) AcpiGbl_RSDP, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0)
        {
            /* Nope, BAD Signature */

            return_ACPI_STATUS (AE_BAD_SIGNATURE);
        }

        if (AcpiTbChecksum (AcpiGbl_RSDP, ACPI_RSDP_CHECKSUM_LENGTH) != 0)
        {
            /* Nope, BAD Checksum */

            return_ACPI_STATUS (AE_BAD_CHECKSUM);
        }
    }

    /* Get the RSDT and validate it */

    AcpiTbGetRsdtAddress (&Address);

    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)));

    /* Insert ProcessorMode flags */

    Address.PointerType |= Flags;

    Status = AcpiTbGetTable (&Address, &RsdtInfo);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    Status = AcpiTbValidateRsdt (RsdtInfo.Pointer);
    if (ACPI_FAILURE (Status))
    {
        goto Cleanup;
    }

    /* Get the number of table pointers within the RSDT */

    TableCount = AcpiTbGetTableCount (AcpiGbl_RSDP, RsdtInfo.Pointer);

    Address.PointerType = AcpiGbl_TableFlags | Flags;

    /*
     * Search the RSDT/XSDT for the correct instance of the
     * requested table
     */
    for (i = 0, j = 0; i < TableCount; i++)
    {
        /* Get the next table pointer, handle RSDT vs. XSDT */

        if (AcpiGbl_RSDP->Revision < 2)
        {
            Address.Pointer.Value = ((RSDT_DESCRIPTOR *) RsdtInfo.Pointer)->TableOffsetEntry[i];
        }
        else
        {
            Address.Pointer.Value = ACPI_GET_ADDRESS (
                ((XSDT_DESCRIPTOR *) RsdtInfo.Pointer)->TableOffsetEntry[i]);
        }

        /* Get the table header */

        Status = AcpiTbGetTableHeader (&Address, &Header);
        if (ACPI_FAILURE (Status))
        {
            goto Cleanup;
        }

        /* Compare table signatures and table instance */

        if (!ACPI_STRNCMP (Header.Signature, Signature, ACPI_NAME_SIZE))
        {
            /* An instance of the table was found */

            j++;
            if (j >= Instance)
            {
                /* Found the correct instance, get the entire table */

                Status = AcpiTbGetTableBody (&Address, &Header, &TableInfo);
                if (ACPI_FAILURE (Status))
                {
                    goto Cleanup;
                }

                *TablePointer = TableInfo.Pointer;
                goto Cleanup;
            }
        }
    }

    /* Did not find the table */

    Status = AE_NOT_EXIST;


Cleanup:
    AcpiOsUnmapMemory (RsdtInfo.Pointer, (ACPI_SIZE) RsdtInfo.Pointer->Length);
    return_ACPI_STATUS (Status);
}
Exemplo n.º 5
0
static void
AcpiTbConvertFadt2 (
    FADT_DESCRIPTOR         *LocalFadt,
    FADT_DESCRIPTOR         *OriginalFadt)
{

    /* We have an ACPI 2.0 FADT but we must copy it to our local buffer */

    ACPI_MEMCPY (LocalFadt, OriginalFadt, sizeof (FADT_DESCRIPTOR));

    /*
     * "X" fields are optional extensions to the original V1.0 fields, so
     * we must selectively expand V1.0 fields if the corresponding X field
     * is zero.
     */
    if (!(ACPI_GET_ADDRESS (LocalFadt->XFirmwareCtrl)))
    {
        ACPI_STORE_ADDRESS (LocalFadt->XFirmwareCtrl,
            LocalFadt->V1_FirmwareCtrl);
    }

    if (!(ACPI_GET_ADDRESS (LocalFadt->XDsdt)))
    {
        ACPI_STORE_ADDRESS (LocalFadt->XDsdt, LocalFadt->V1_Dsdt);
    }

    if (!(ACPI_GET_ADDRESS (LocalFadt->XPm1aEvtBlk.Address)))
    {
        AcpiTbInitGenericAddress (&LocalFadt->XPm1aEvtBlk,
            LocalFadt->Pm1EvtLen,
            (ACPI_PHYSICAL_ADDRESS) LocalFadt->V1_Pm1aEvtBlk);
    }

    if (!(ACPI_GET_ADDRESS (LocalFadt->XPm1bEvtBlk.Address)))
    {
        AcpiTbInitGenericAddress (&LocalFadt->XPm1bEvtBlk,
            LocalFadt->Pm1EvtLen,
            (ACPI_PHYSICAL_ADDRESS) LocalFadt->V1_Pm1bEvtBlk);
    }

    if (!(ACPI_GET_ADDRESS (LocalFadt->XPm1aCntBlk.Address)))
    {
        AcpiTbInitGenericAddress (&LocalFadt->XPm1aCntBlk,
            LocalFadt->Pm1CntLen,
            (ACPI_PHYSICAL_ADDRESS) LocalFadt->V1_Pm1aCntBlk);
    }

    if (!(ACPI_GET_ADDRESS (LocalFadt->XPm1bCntBlk.Address)))
    {
        AcpiTbInitGenericAddress (&LocalFadt->XPm1bCntBlk,
            LocalFadt->Pm1CntLen,
            (ACPI_PHYSICAL_ADDRESS) LocalFadt->V1_Pm1bCntBlk);
    }

    if (!(ACPI_GET_ADDRESS (LocalFadt->XPm2CntBlk.Address)))
    {
        AcpiTbInitGenericAddress (&LocalFadt->XPm2CntBlk,
            LocalFadt->Pm2CntLen,
            (ACPI_PHYSICAL_ADDRESS) LocalFadt->V1_Pm2CntBlk);
    }

    if (!(ACPI_GET_ADDRESS (LocalFadt->XPmTmrBlk.Address)))
    {
        AcpiTbInitGenericAddress (&LocalFadt->XPmTmrBlk,
            LocalFadt->PmTmLen,
            (ACPI_PHYSICAL_ADDRESS) LocalFadt->V1_PmTmrBlk);
    }

    if (!(ACPI_GET_ADDRESS (LocalFadt->XGpe0Blk.Address)))
    {
        AcpiTbInitGenericAddress (&LocalFadt->XGpe0Blk,
            0, (ACPI_PHYSICAL_ADDRESS) LocalFadt->V1_Gpe0Blk);
    }

    if (!(ACPI_GET_ADDRESS (LocalFadt->XGpe1Blk.Address)))
    {
        AcpiTbInitGenericAddress (&LocalFadt->XGpe1Blk,
            0, (ACPI_PHYSICAL_ADDRESS) LocalFadt->V1_Gpe1Blk);
    }

    /* Create separate GAS structs for the PM1 Enable registers */

    AcpiTbInitGenericAddress (&AcpiGbl_XPm1aEnable,
        (UINT8) ACPI_DIV_2 (AcpiGbl_FADT->Pm1EvtLen),
        (ACPI_PHYSICAL_ADDRESS)
            (ACPI_GET_ADDRESS (LocalFadt->XPm1aEvtBlk.Address) +
            ACPI_DIV_2 (AcpiGbl_FADT->Pm1EvtLen)));

    AcpiGbl_XPm1aEnable.AddressSpaceId =
        LocalFadt->XPm1aEvtBlk.AddressSpaceId;

    /* PM1B is optional; leave null if not present */

    if (ACPI_GET_ADDRESS (LocalFadt->XPm1bEvtBlk.Address))
    {
        AcpiTbInitGenericAddress (&AcpiGbl_XPm1bEnable,
            (UINT8) ACPI_DIV_2 (AcpiGbl_FADT->Pm1EvtLen),
            (ACPI_PHYSICAL_ADDRESS)
                (ACPI_GET_ADDRESS (LocalFadt->XPm1bEvtBlk.Address) +
                ACPI_DIV_2 (AcpiGbl_FADT->Pm1EvtLen)));

        AcpiGbl_XPm1bEnable.AddressSpaceId =
            LocalFadt->XPm1bEvtBlk.AddressSpaceId;
    }
}
Exemplo n.º 6
0
static void
AcpiTbConvertFadt1 (
    FADT_DESCRIPTOR         *LocalFadt,
    FADT_DESCRIPTOR_REV1    *OriginalFadt)
{

    /* ACPI 1.0 FACS */
    /* The BIOS stored FADT should agree with Revision 1.0 */

    /*
     * Copy the table header and the common part of the tables.
     *
     * The 2.0 table is an extension of the 1.0 table, so the entire 1.0
     * table can be copied first, then expand some fields to 64 bits.
     */
    ACPI_MEMCPY (LocalFadt, OriginalFadt, sizeof (FADT_DESCRIPTOR_REV1));

    /* Convert table pointers to 64-bit fields */

    ACPI_STORE_ADDRESS (LocalFadt->XFirmwareCtrl, LocalFadt->V1_FirmwareCtrl);
    ACPI_STORE_ADDRESS (LocalFadt->XDsdt, LocalFadt->V1_Dsdt);

    /*
     * System Interrupt Model isn't used in ACPI 2.0
     * (LocalFadt->Reserved1 = 0;)
     */

    /*
     * This field is set by the OEM to convey the preferred power management
     * profile to OSPM. It doesn't have any 1.0 equivalence.  Since we don't
     * know what kind of 32-bit system this is, we will use "unspecified".
     */
    LocalFadt->Prefer_PM_Profile = PM_UNSPECIFIED;

    /*
     * Processor Performance State Control. This is the value OSPM writes to
     * the SMI_CMD register to assume processor performance state control
     * responsibility. There isn't any equivalence in 1.0, leave it zeroed.
     */
    LocalFadt->PstateCnt = 0;

    /*
     * Support for the _CST object and C States change notification.
     * This data item hasn't any 1.0 equivalence so leave it zero.
     */
    LocalFadt->CstCnt = 0;

    /*
     * FADT Rev 2 was an interim FADT released between ACPI 1.0 and ACPI 2.0.
     * It primarily adds the FADT reset mechanism.
     */
    if ((OriginalFadt->Revision == 2) &&
        (OriginalFadt->Length == sizeof (FADT_DESCRIPTOR_REV2_MINUS)))
    {
        /*
         * Grab the entire generic address struct, plus the 1-byte reset value
         * that immediately follows.
         */
        ACPI_MEMCPY (&LocalFadt->ResetRegister,
            &(ACPI_CAST_PTR (FADT_DESCRIPTOR_REV2_MINUS,
                OriginalFadt))->ResetRegister,
            sizeof (ACPI_GENERIC_ADDRESS) + 1);
    }
    else
    {
        /*
         * Since there isn't any equivalence in 1.0 and since it is highly
         * likely that a 1.0 system has legacy support.
         */
        LocalFadt->IapcBootArch = BAF_LEGACY_DEVICES;
    }

    /*
     * Convert the V1.0 block addresses to V2.0 GAS structures
     */
    AcpiTbInitGenericAddress (&LocalFadt->XPm1aEvtBlk, LocalFadt->Pm1EvtLen,
                             (ACPI_PHYSICAL_ADDRESS)   LocalFadt->V1_Pm1aEvtBlk);
    AcpiTbInitGenericAddress (&LocalFadt->XPm1bEvtBlk, LocalFadt->Pm1EvtLen,
                             (ACPI_PHYSICAL_ADDRESS)   LocalFadt->V1_Pm1bEvtBlk);
    AcpiTbInitGenericAddress (&LocalFadt->XPm1aCntBlk, LocalFadt->Pm1CntLen,
                             (ACPI_PHYSICAL_ADDRESS)   LocalFadt->V1_Pm1aCntBlk);
    AcpiTbInitGenericAddress (&LocalFadt->XPm1bCntBlk, LocalFadt->Pm1CntLen,
                             (ACPI_PHYSICAL_ADDRESS)   LocalFadt->V1_Pm1bCntBlk);
    AcpiTbInitGenericAddress (&LocalFadt->XPm2CntBlk,  LocalFadt->Pm2CntLen,
                             (ACPI_PHYSICAL_ADDRESS)   LocalFadt->V1_Pm2CntBlk);
    AcpiTbInitGenericAddress (&LocalFadt->XPmTmrBlk,   LocalFadt->PmTmLen,
                             (ACPI_PHYSICAL_ADDRESS)   LocalFadt->V1_PmTmrBlk);
    AcpiTbInitGenericAddress (&LocalFadt->XGpe0Blk,    0,
                             (ACPI_PHYSICAL_ADDRESS)   LocalFadt->V1_Gpe0Blk);
    AcpiTbInitGenericAddress (&LocalFadt->XGpe1Blk,    0,
                             (ACPI_PHYSICAL_ADDRESS)   LocalFadt->V1_Gpe1Blk);

    /* Create separate GAS structs for the PM1 Enable registers */

    AcpiTbInitGenericAddress (&AcpiGbl_XPm1aEnable,
         (UINT8) ACPI_DIV_2 (AcpiGbl_FADT->Pm1EvtLen),
         (ACPI_PHYSICAL_ADDRESS)
            (ACPI_GET_ADDRESS (LocalFadt->XPm1aEvtBlk.Address) +
            ACPI_DIV_2 (AcpiGbl_FADT->Pm1EvtLen)));

    /* PM1B is optional; leave null if not present */

    if (ACPI_GET_ADDRESS (LocalFadt->XPm1bEvtBlk.Address))
    {
        AcpiTbInitGenericAddress (&AcpiGbl_XPm1bEnable,
             (UINT8) ACPI_DIV_2 (AcpiGbl_FADT->Pm1EvtLen),
             (ACPI_PHYSICAL_ADDRESS)
                (ACPI_GET_ADDRESS (LocalFadt->XPm1bEvtBlk.Address) +
                ACPI_DIV_2 (AcpiGbl_FADT->Pm1EvtLen)));
    }
}
Exemplo n.º 7
0
acpi_status
acpi_ev_gpe_initialize (void)
{
	u32                     i;
	u32                     j;
	u32                     register_index;
	u32                     gpe_number;
	u16                     gpe0register_count;
	u16                     gpe1_register_count;


	FUNCTION_TRACE ("Ev_gpe_initialize");

	/*
	 * Set up various GPE counts
	 *
	 * You may ask,why are the GPE register block lengths divided by 2?
	 * From the ACPI 2.0 Spec, section, 4.7.1.6 General-Purpose Event
	 * Registers, we have,
	 *
	 * "Each register block contains two registers of equal length
	 * GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the
	 * GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN
	 * The length of the GPE1_STS and GPE1_EN registers is equal to
	 * half the GPE1_LEN. If a generic register block is not supported
	 * then its respective block pointer and block length values in the
	 * FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need
	 * to be the same size."
	 */
	gpe0register_count          = (u16) DIV_2 (acpi_gbl_FADT->gpe0blk_len);
	gpe1_register_count         = (u16) DIV_2 (acpi_gbl_FADT->gpe1_blk_len);
	acpi_gbl_gpe_register_count = gpe0register_count + gpe1_register_count;

	if (!acpi_gbl_gpe_register_count) {
		REPORT_WARNING (("Zero GPEs are defined in the FADT\n"));
		return_ACPI_STATUS (AE_OK);
	}

	/*
	 * Allocate the Gpe information block
	 */
	acpi_gbl_gpe_registers = ACPI_MEM_CALLOCATE (acpi_gbl_gpe_register_count *
			  sizeof (acpi_gpe_registers));
	if (!acpi_gbl_gpe_registers) {
		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
			"Could not allocate the Gpe_registers block\n"));
		return_ACPI_STATUS (AE_NO_MEMORY);
	}

	/*
	 * Allocate the Gpe dispatch handler block
	 * There are eight distinct GP events per register.
	 * Initialization to zeros is sufficient
	 */
	acpi_gbl_gpe_info = ACPI_MEM_CALLOCATE (MUL_8 (acpi_gbl_gpe_register_count) *
			  sizeof (acpi_gpe_level_info));
	if (!acpi_gbl_gpe_info) {
		ACPI_MEM_FREE (acpi_gbl_gpe_registers);
		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not allocate the Gpe_info block\n"));
		return_ACPI_STATUS (AE_NO_MEMORY);
	}

	/* Set the Gpe validation table to GPE_INVALID */

	MEMSET (acpi_gbl_gpe_valid, (int) ACPI_GPE_INVALID, ACPI_NUM_GPE);

	/*
	 * Initialize the Gpe information and validation blocks.  A goal of these
	 * blocks is to hide the fact that there are two separate GPE register sets
	 * In a given block, the status registers occupy the first half, and
	 * the enable registers occupy the second half.
	 */

	/* GPE Block 0 */

	register_index = 0;

	for (i = 0; i < gpe0register_count; i++) {
		acpi_gbl_gpe_registers[register_index].status_addr =
				 (u16) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) + i);

		acpi_gbl_gpe_registers[register_index].enable_addr =
				 (u16) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) + i + gpe0register_count);

		acpi_gbl_gpe_registers[register_index].gpe_base = (u8) MUL_8 (i);

		for (j = 0; j < 8; j++) {
			gpe_number = acpi_gbl_gpe_registers[register_index].gpe_base + j;
			acpi_gbl_gpe_valid[gpe_number] = (u8) register_index;
		}

		/*
		 * Clear the status/enable registers.  Note that status registers
		 * are cleared by writing a '1', while enable registers are cleared
		 * by writing a '0'.
		 */
		acpi_os_write_port (acpi_gbl_gpe_registers[register_index].enable_addr, 0x00, 8);
		acpi_os_write_port (acpi_gbl_gpe_registers[register_index].status_addr, 0xFF, 8);

		register_index++;
	}

	/* GPE Block 1 */

	for (i = 0; i < gpe1_register_count; i++) {
		acpi_gbl_gpe_registers[register_index].status_addr =
				 (u16) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) + i);

		acpi_gbl_gpe_registers[register_index].enable_addr =
				 (u16) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) + i + gpe1_register_count);

		acpi_gbl_gpe_registers[register_index].gpe_base =
				 (u8) (acpi_gbl_FADT->gpe1_base + MUL_8 (i));

		for (j = 0; j < 8; j++) {
			gpe_number = acpi_gbl_gpe_registers[register_index].gpe_base + j;
			acpi_gbl_gpe_valid[gpe_number] = (u8) register_index;
		}

		/*
		 * Clear the status/enable registers.  Note that status registers
		 * are cleared by writing a '1', while enable registers are cleared
		 * by writing a '0'.
		 */
		acpi_os_write_port (acpi_gbl_gpe_registers[register_index].enable_addr, 0x00, 8);
		acpi_os_write_port (acpi_gbl_gpe_registers[register_index].status_addr, 0xFF, 8);

		register_index++;
	}

	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "GPE registers: %X@%8.8X%8.8X (Blk0) %X@%8.8X%8.8X (Blk1)\n",
		gpe0register_count, HIDWORD(acpi_gbl_FADT->Xgpe0blk.address), LODWORD(acpi_gbl_FADT->Xgpe0blk.address),
		gpe1_register_count, HIDWORD(acpi_gbl_FADT->Xgpe1_blk.address), LODWORD(acpi_gbl_FADT->Xgpe1_blk.address)));

	return_ACPI_STATUS (AE_OK);
}