⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tbfadt.c

📁 acpi tools for linux include acpiexec and acpixtract
💻 C
📖 第 1 页 / 共 2 页
字号:
    /*     * Validate the FADT checksum before we copy the table. Ignore     * checksum error as we want to try to get the DSDT and FACS.     */    (void) AcpiTbVerifyChecksum (Table, Length);    /* Obtain a local copy of the FADT in common ACPI 2.0+ format */    AcpiTbCreateLocalFadt (Table, Length);    /* All done with the real FADT, unmap it */    AcpiOsUnmapMemory (Table, Length);    /* Obtain the DSDT and FACS tables via their addresses within the FADT */    AcpiTbInstallTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XDsdt,        Flags, ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);    AcpiTbInstallTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XFacs,        Flags, ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);}/******************************************************************************* * * FUNCTION:    AcpiTbCreateLocalFadt * * PARAMETERS:  Table               - Pointer to BIOS FADT *              Length              - Length of the table * * RETURN:      None * * DESCRIPTION: Get a local copy of the FADT and convert it to a common format. *              Performs validation on some important FADT fields. * * NOTE:        We create a local copy of the FADT regardless of the version. * ******************************************************************************/voidAcpiTbCreateLocalFadt (    ACPI_TABLE_HEADER       *Table,    UINT32                  Length){    /*     * Check if the FADT is larger than the largest table that we expect     * (the ACPI 2.0/3.0 version). If so, truncate the table, and issue     * a warning.     */    if (Length > sizeof (ACPI_TABLE_FADT))    {        ACPI_WARNING ((AE_INFO,            "FADT (revision %u) is longer than ACPI 2.0 version, truncating length 0x%X to 0x%X",            Table->Revision, Length, sizeof (ACPI_TABLE_FADT)));    }    /* Clear the entire local FADT */    ACPI_MEMSET (&AcpiGbl_FADT, 0, sizeof (ACPI_TABLE_FADT));    /* Copy the original FADT, up to sizeof (ACPI_TABLE_FADT) */    ACPI_MEMCPY (&AcpiGbl_FADT, Table,        ACPI_MIN (Length, sizeof (ACPI_TABLE_FADT)));    /*     * 1) Convert the local copy of the FADT to the common internal format     * 2) Validate some of the important values within the FADT     */    AcpiTbConvertFadt ();    AcpiTbValidateFadt ();}/******************************************************************************* * * FUNCTION:    AcpiTbConvertFadt * * PARAMETERS:  None, uses AcpiGbl_FADT * * RETURN:      None * * DESCRIPTION: Converts all versions of the FADT to a common internal format. *              Expand all 32-bit addresses to 64-bit. * * NOTE:        AcpiGbl_FADT must be of size (ACPI_TABLE_FADT), *              and must contain a copy of the actual FADT. * * ACPICA will use the "X" fields of the FADT for all addresses. * * "X" fields are optional extensions to the original V1.0 fields. Even if * they are present in the structure, they can be optionally not used by * setting them to zero. Therefore, we must selectively expand V1.0 fields * if the corresponding X field is zero. * * For ACPI 1.0 FADTs, all address fields are expanded to the corresponding * "X" fields. * * For ACPI 2.0 FADTs, any "X" fields that are NULL are filled in by * expanding the corresponding ACPI 1.0 field. * ******************************************************************************/static voidAcpiTbConvertFadt (    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));    }}/****************************************************************************** * * FUNCTION:    AcpiTbValidateFadt * * PARAMETERS:  Table           - Pointer to the FADT to be validated * * RETURN:      None * * DESCRIPTION: Validate various important fields within the FADT. If a problem *              is found, issue a message, but no status is returned. *              Used by both the table manager and the disassembler. * * Possible additional checks: * (AcpiGbl_FADT.Pm1EventLength >= 4) * (AcpiGbl_FADT.Pm1ControlLength >= 2) * (AcpiGbl_FADT.PmTimerLength >= 4) * Gpe block lengths must be multiple of 2 * ******************************************************************************/static voidAcpiTbValidateFadt (    void){    UINT32                  *Address32;    ACPI_GENERIC_ADDRESS    *Address64;    UINT8                   Length;    ACPI_NATIVE_UINT        i;    /* Examine all of the 64-bit extended address fields (X fields) */    for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)    {        /* Generate pointers to the 32-bit and 64-bit addresses and get the length */        Address64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS, &AcpiGbl_FADT, FadtInfoTable[i].Target);        Address32 = ACPI_ADD_PTR (UINT32, &AcpiGbl_FADT, FadtInfoTable[i].Source);        Length = *ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT, FadtInfoTable[i].Length);        if (FadtInfoTable[i].Type & ACPI_FADT_REQUIRED)        {            /*             * Field is required (PM1aEvent, PM1aControl, PmTimer).             * Both the address and length must be non-zero.             */            if (!Address64->Address || !Length)            {                ACPI_ERROR ((AE_INFO,                    "Required field \"%s\" has zero address and/or length: %8.8X%8.8X/%X",                    FadtInfoTable[i].Name, ACPI_FORMAT_UINT64 (Address64->Address), Length));            }        }        else if (FadtInfoTable[i].Type & 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_WARNING ((AE_INFO,                    "Optional field \"%s\" has zero address or length: %8.8X%8.8X/%X",                    FadtInfoTable[i].Name, ACPI_FORMAT_UINT64 (Address64->Address), Length));            }        }        /* 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\": [%8.8X] [%8.8X%8.8X], using 64X",                FadtInfoTable[i].Name, *Address32, ACPI_FORMAT_UINT64 (Address64->Address)));        }    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -