Exemple #1
0
static void
AcpiTbConvertFadt (
    void)
{
    ACPI_GENERIC_ADDRESS    *Address64;
    UINT32                  Address32;
    UINT32                  i;


    /* Update the local FADT table header length */

    AcpiGbl_FADT.Header.Length = sizeof (ACPI_TABLE_FADT);

    /*
     * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary.
     * Later code will always use the X 64-bit field.
     */
    if (!AcpiGbl_FADT.XFacs)
    {
        AcpiGbl_FADT.XFacs = (UINT64) AcpiGbl_FADT.Facs;
    }
    if (!AcpiGbl_FADT.XDsdt)
    {
        AcpiGbl_FADT.XDsdt = (UINT64) AcpiGbl_FADT.Dsdt;
    }

    /*
     * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which
     * should be zero are indeed zero. This will workaround BIOSs that
     * inadvertently place values in these fields.
     *
     * The ACPI 1.0 reserved fields that will be zeroed are the bytes located
     * at offset 45, 55, 95, and the word located at offset 109, 110.
     *
     * Note: The FADT revision value is unreliable. Only the length can be
     * trusted.
     */
    if (AcpiGbl_FADT.Header.Length <= ACPI_FADT_V2_SIZE)
    {
        AcpiGbl_FADT.PreferredProfile = 0;
        AcpiGbl_FADT.PstateControl = 0;
        AcpiGbl_FADT.CstControl = 0;
        AcpiGbl_FADT.BootFlags = 0;
    }

    /*
     * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
     * generic address structures as necessary. Later code will always use
     * the 64-bit address structures.
     *
     * March 2009:
     * We now always use the 32-bit address if it is valid (non-null). This
     * is not in accordance with the ACPI specification which states that
     * the 64-bit address supersedes the 32-bit version, but we do this for
     * compatibility with other ACPI implementations. Most notably, in the
     * case where both the 32 and 64 versions are non-null, we use the 32-bit
     * version. This is the only address that is guaranteed to have been
     * tested by the BIOS manufacturer.
     */
    for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)
    {
        Address32 = *ACPI_ADD_PTR (UINT32,
                                   &AcpiGbl_FADT, FadtInfoTable[i].Address32);

        Address64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS,
                                  &AcpiGbl_FADT, FadtInfoTable[i].Address64);

        /*
         * If both 32- and 64-bit addresses are valid (non-zero),
         * they must match.
         */
        if (Address64->Address && Address32 &&
                (Address64->Address != (UINT64) Address32))
        {
            ACPI_ERROR ((AE_INFO,
                         "32/64X address mismatch in %s: 0x%8.8X/0x%8.8X%8.8X, using 32",
                         FadtInfoTable[i].Name, Address32,
                         ACPI_FORMAT_UINT64 (Address64->Address)));
        }

        /* Always use 32-bit address if it is valid (non-null) */

        if (Address32)
        {
            /*
             * Copy the 32-bit address to the 64-bit GAS structure. The
             * Space ID is always I/O for 32-bit legacy address fields
             */
            AcpiTbInitGenericAddress (Address64, ACPI_ADR_SPACE_SYSTEM_IO,
                                      *ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT, FadtInfoTable[i].Length),
                                      (UINT64) Address32);
        }
    }
}
Exemple #2
0
static void
AcpiTbSetupFadtRegisters (
    void)
{
    ACPI_GENERIC_ADDRESS    *Target64;
    ACPI_GENERIC_ADDRESS    *Source64;
    UINT8                   Pm1RegisterByteWidth;
    UINT32                  i;


    /*
     * Optionally check all register lengths against the default values and
     * update them if they are incorrect.
     */
    if (AcpiGbl_UseDefaultRegisterWidths)
    {
        for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)
        {
            Target64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT,
                                     FadtInfoTable[i].Address64);

            /*
             * If a valid register (Address != 0) and the (DefaultLength > 0)
             * (Not a GPE register), then check the width against the default.
             */
            if ((Target64->Address) &&
                    (FadtInfoTable[i].DefaultLength > 0) &&
                    (FadtInfoTable[i].DefaultLength != Target64->BitWidth))
            {
                ACPI_WARNING ((AE_INFO,
                               "Invalid length for %s: %u, using default %u",
                               FadtInfoTable[i].Name, Target64->BitWidth,
                               FadtInfoTable[i].DefaultLength));

                /* Incorrect size, set width to the default */

                Target64->BitWidth = FadtInfoTable[i].DefaultLength;
            }
        }
    }

    /*
     * Get the length of the individual PM1 registers (enable and status).
     * Each register is defined to be (event block length / 2). Extra divide
     * by 8 converts bits to bytes.
     */
    Pm1RegisterByteWidth = (UINT8)
                           ACPI_DIV_16 (AcpiGbl_FADT.XPm1aEventBlock.BitWidth);

    /*
     * Calculate separate GAS structs for the PM1x (A/B) Status and Enable
     * registers. These addresses do not appear (directly) in the FADT, so it
     * is useful to pre-calculate them from the PM1 Event Block definitions.
     *
     * The PM event blocks are split into two register blocks, first is the
     * PM Status Register block, followed immediately by the PM Enable
     * Register block. Each is of length (Pm1EventLength/2)
     *
     * Note: The PM1A event block is required by the ACPI specification.
     * However, the PM1B event block is optional and is rarely, if ever,
     * used.
     */

    for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++)
    {
        Source64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT,
                                 FadtPmInfoTable[i].Source);

        if (Source64->Address)
        {
            AcpiTbInitGenericAddress (FadtPmInfoTable[i].Target,
                                      Source64->SpaceId, Pm1RegisterByteWidth,
                                      Source64->Address +
                                      (FadtPmInfoTable[i].RegisterNum * Pm1RegisterByteWidth));
        }
    }
}
Exemple #3
0
static void
AcpiTbConvertFadt (
    void)
{
    char                    *Name;
    ACPI_GENERIC_ADDRESS    *Address64;
    UINT32                  Address32;
    UINT8                   Length;
    UINT8                   Flags;
    UINT32                  i;


    /*
     * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which
     * should be zero are indeed zero. This will workaround BIOSs that
     * inadvertently place values in these fields.
     *
     * The ACPI 1.0 reserved fields that will be zeroed are the bytes located
     * at offset 45, 55, 95, and the word located at offset 109, 110.
     *
     * Note: The FADT revision value is unreliable. Only the length can be
     * trusted.
     */
    if (AcpiGbl_FADT.Header.Length <= ACPI_FADT_V2_SIZE)
    {
        AcpiGbl_FADT.PreferredProfile = 0;
        AcpiGbl_FADT.PstateControl = 0;
        AcpiGbl_FADT.CstControl = 0;
        AcpiGbl_FADT.BootFlags = 0;
    }

    /*
     * Now we can update the local FADT length to the length of the
     * current FADT version as defined by the ACPI specification.
     * Thus, we will have a common FADT internally.
     */
    AcpiGbl_FADT.Header.Length = sizeof (ACPI_TABLE_FADT);

    /*
     * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary.
     * Later ACPICA code will always use the X 64-bit field.
     */
    AcpiGbl_FADT.XFacs = AcpiTbSelectAddress ("FACS",
        AcpiGbl_FADT.Facs, AcpiGbl_FADT.XFacs);

    AcpiGbl_FADT.XDsdt = AcpiTbSelectAddress ("DSDT",
        AcpiGbl_FADT.Dsdt, AcpiGbl_FADT.XDsdt);

    /* If Hardware Reduced flag is set, we are all done */

    if (AcpiGbl_ReducedHardware)
    {
        return;
    }

    /* Examine all of the 64-bit extended address fields (X fields) */

    for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)
    {
        /*
         * Get the 32-bit and 64-bit addresses, as well as the register
         * length and register name.
         */
        Address32 = *ACPI_ADD_PTR (UINT32,
            &AcpiGbl_FADT, FadtInfoTable[i].Address32);

        Address64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS,
            &AcpiGbl_FADT, FadtInfoTable[i].Address64);

        Length = *ACPI_ADD_PTR (UINT8,
            &AcpiGbl_FADT, FadtInfoTable[i].Length);

        Name = FadtInfoTable[i].Name;
        Flags = FadtInfoTable[i].Flags;

        /*
         * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
         * generic address structures as necessary. Later code will always use
         * the 64-bit address structures.
         *
         * November 2013:
         * Now always use the 64-bit address if it is valid (non-zero), in
         * accordance with the ACPI specification which states that a 64-bit
         * address supersedes the 32-bit version. This behavior can be
         * overridden by the AcpiGbl_Use32BitFadtAddresses flag.
         *
         * During 64-bit address construction and verification,
         * these cases are handled:
         *
         * Address32 zero, Address64 [don't care]   - Use Address64
         *
         * Address32 non-zero, Address64 zero       - Copy/use Address32
         * Address32 non-zero == Address64 non-zero - Use Address64
         * Address32 non-zero != Address64 non-zero - Warning, use Address64
         *
         * Override: if AcpiGbl_Use32BitFadtAddresses is TRUE, and:
         * Address32 non-zero != Address64 non-zero - Warning, copy/use Address32
         *
         * Note: SpaceId is always I/O for 32-bit legacy address fields
         */
        if (Address32)
        {
            if (!Address64->Address)
            {
                /* 64-bit address is zero, use 32-bit address */

                AcpiTbInitGenericAddress (Address64,
                    ACPI_ADR_SPACE_SYSTEM_IO,
                    *ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT,
                        FadtInfoTable[i].Length),
                    (UINT64) Address32, Name, Flags);
            }
            else if (Address64->Address != (UINT64) Address32)
            {
                /* Address mismatch */

                ACPI_BIOS_WARNING ((AE_INFO,
                    "32/64X address mismatch in FADT/%s: "
                    "0x%8.8X/0x%8.8X%8.8X, using %u-bit address",
                    Name, Address32,
                    ACPI_FORMAT_UINT64 (Address64->Address),
                    AcpiGbl_Use32BitFadtAddresses ? 32 : 64));

                if (AcpiGbl_Use32BitFadtAddresses)
                {
                    /* 32-bit address override */

                    AcpiTbInitGenericAddress (Address64,
                        ACPI_ADR_SPACE_SYSTEM_IO,
                        *ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT,
                            FadtInfoTable[i].Length),
                        (UINT64) Address32, Name, Flags);
                }
            }
        }

        /*
         * For each extended field, check for length mismatch between the
         * legacy length field and the corresponding 64-bit X length field.
         * Note: If the legacy length field is > 0xFF bits, ignore this
         * check. (GPE registers can be larger than the 64-bit GAS structure
         * can accomodate, 0xFF bits).
         */
        if (Address64->Address &&
           (ACPI_MUL_8 (Length) <= ACPI_UINT8_MAX) &&
           (Address64->BitWidth != ACPI_MUL_8 (Length)))
        {
            ACPI_BIOS_WARNING ((AE_INFO,
                "32/64X length mismatch in FADT/%s: %u/%u",
                Name, ACPI_MUL_8 (Length), Address64->BitWidth));
        }

        if (FadtInfoTable[i].Flags & ACPI_FADT_REQUIRED)
        {
            /*
             * Field is required (PM1aEvent, PM1aControl).
             * Both the address and length must be non-zero.
             */
            if (!Address64->Address || !Length)
            {
                ACPI_BIOS_ERROR ((AE_INFO,
                    "Required FADT field %s has zero address and/or length: "
                    "0x%8.8X%8.8X/0x%X",
                    Name, ACPI_FORMAT_UINT64 (Address64->Address), Length));
            }
        }
        else if (FadtInfoTable[i].Flags & ACPI_FADT_SEPARATE_LENGTH)
        {
            /*
             * Field is optional (PM2Control, GPE0, GPE1) AND has its own
             * length field. If present, both the address and length must
             * be valid.
             */
            if ((Address64->Address && !Length) ||
                (!Address64->Address && Length))
            {
                ACPI_BIOS_WARNING ((AE_INFO,
                    "Optional FADT field %s has zero address or length: "
                    "0x%8.8X%8.8X/0x%X",
                    Name, ACPI_FORMAT_UINT64 (Address64->Address), Length));
            }
        }
    }
}
Exemple #4
0
static void
AcpiTbConvertFadt (
    void)
{
    UINT8                       Pm1RegisterLength;
    ACPI_GENERIC_ADDRESS        *Target;
    ACPI_NATIVE_UINT            i;


    /* Update the local FADT table header length */

    AcpiGbl_FADT.Header.Length = sizeof (ACPI_TABLE_FADT);

    /* Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary */

    if (!AcpiGbl_FADT.XFacs)
    {
        AcpiGbl_FADT.XFacs = (UINT64) AcpiGbl_FADT.Facs;
    }

    if (!AcpiGbl_FADT.XDsdt)
    {
        AcpiGbl_FADT.XDsdt = (UINT64) AcpiGbl_FADT.Dsdt;
    }

    /*
     * Expand the 32-bit V1.0 addresses to the 64-bit "X" generic address
     * structures as necessary.
     */
    for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)
    {
        Target = ACPI_ADD_PTR (
            ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT, FadtInfoTable[i].Target);

        /* Expand only if the X target is null */

        if (!Target->Address)
        {
            AcpiTbInitGenericAddress (Target,
                *ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT, FadtInfoTable[i].Length),
                (UINT64) *ACPI_ADD_PTR (UINT32, &AcpiGbl_FADT, FadtInfoTable[i].Source));
        }
    }

    /*
     * Calculate separate GAS structs for the PM1 Enable registers.
     * These addresses do not appear (directly) in the FADT, so it is
     * useful to calculate them once, here.
     *
     * The PM event blocks are split into two register blocks, first is the
     * PM Status Register block, followed immediately by the PM Enable Register
     * block. Each is of length (Pm1EventLength/2)
     */
    Pm1RegisterLength = (UINT8) ACPI_DIV_2 (AcpiGbl_FADT.Pm1EventLength);

    /* The PM1A register block is required */

    AcpiTbInitGenericAddress (&AcpiGbl_XPm1aEnable, Pm1RegisterLength,
        (AcpiGbl_FADT.XPm1aEventBlock.Address + Pm1RegisterLength));

    /* The PM1B register block is optional, ignore if not present */

    if (AcpiGbl_FADT.XPm1bEventBlock.Address)
    {
        AcpiTbInitGenericAddress (&AcpiGbl_XPm1bEnable, Pm1RegisterLength,
            (AcpiGbl_FADT.XPm1bEventBlock.Address + Pm1RegisterLength));
    }
}
Exemple #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;
    }
}
Exemple #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)));
    }
}
Exemple #7
0
static void
AcpiTbConvertFadt (
    void)
{
    UINT8                       Pm1RegisterLength;
    ACPI_GENERIC_ADDRESS        *Target;
    ACPI_NATIVE_UINT            i;


    /* Update the local FADT table header length */

    AcpiGbl_FADT.Header.Length = sizeof (ACPI_TABLE_FADT);

    /* Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary */

    if (!AcpiGbl_FADT.XFacs)
    {
        AcpiGbl_FADT.XFacs = (UINT64) AcpiGbl_FADT.Facs;
    }

    if (!AcpiGbl_FADT.XDsdt)
    {
        AcpiGbl_FADT.XDsdt = (UINT64) AcpiGbl_FADT.Dsdt;
    }

    /*
     * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which
     * should be zero are indeed zero. This will workaround BIOSs that
     * inadvertently place values in these fields.
     *
     * The ACPI 1.0 reserved fields that will be zeroed are the bytes located at
     * offset 45, 55, 95, and the word located at offset 109, 110.
     */
    if (AcpiGbl_FADT.Header.Revision < 3)
    {
        AcpiGbl_FADT.PreferredProfile = 0;
        AcpiGbl_FADT.PstateControl = 0;
        AcpiGbl_FADT.CstControl = 0;
        AcpiGbl_FADT.BootFlags = 0;
    }

    /*
     * Expand the ACPI 1.0 32-bit V1.0 addresses to the ACPI 2.0 64-bit "X"
     * generic address structures as necessary.
     */
    for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)
    {
        Target = ACPI_ADD_PTR (
            ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT, FadtInfoTable[i].Target);

        /* Expand only if the X target is null */

        if (!Target->Address)
        {
            AcpiTbInitGenericAddress (Target,
                *ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT, FadtInfoTable[i].Length),
                (UINT64) *ACPI_ADD_PTR (UINT32, &AcpiGbl_FADT, FadtInfoTable[i].Source));
        }
    }

    /*
     * Calculate separate GAS structs for the PM1 Enable registers.
     * These addresses do not appear (directly) in the FADT, so it is
     * useful to calculate them once, here.
     *
     * The PM event blocks are split into two register blocks, first is the
     * PM Status Register block, followed immediately by the PM Enable Register
     * block. Each is of length (Pm1EventLength/2)
     */
    Pm1RegisterLength = (UINT8) ACPI_DIV_2 (AcpiGbl_FADT.Pm1EventLength);

    /* The PM1A register block is required */

    AcpiTbInitGenericAddress (&AcpiGbl_XPm1aEnable, Pm1RegisterLength,
        (AcpiGbl_FADT.XPm1aEventBlock.Address + Pm1RegisterLength));

    /* The PM1B register block is optional, ignore if not present */

    if (AcpiGbl_FADT.XPm1bEventBlock.Address)
    {
        AcpiTbInitGenericAddress (&AcpiGbl_XPm1bEnable, Pm1RegisterLength,
            (AcpiGbl_FADT.XPm1bEventBlock.Address + Pm1RegisterLength));
    }
}