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

📄 evgpeblk.c

📁 acpi tools for linux include acpiexec and acpixtract
💻 C
📖 第 1 页 / 共 3 页
字号:
    GpeEventInfo = ACPI_ALLOCATE_ZEROED (                        ((ACPI_SIZE) GpeBlock->RegisterCount *                        ACPI_GPE_REGISTER_WIDTH) *                        sizeof (ACPI_GPE_EVENT_INFO));    if (!GpeEventInfo)    {        ACPI_ERROR ((AE_INFO,            "Could not allocate the GpeEventInfo table"));        Status = AE_NO_MEMORY;        goto ErrorExit;    }    /* Save the new Info arrays in the GPE block */    GpeBlock->RegisterInfo = GpeRegisterInfo;    GpeBlock->EventInfo    = GpeEventInfo;    /*     * Initialize the GPE Register and Event structures. A goal of these     * tables is to hide the fact that there are two separate GPE register sets     * in a given GPE hardware block, the status registers occupy the first half,     * and the enable registers occupy the second half.     */    ThisRegister = GpeRegisterInfo;    ThisEvent    = GpeEventInfo;    for (i = 0; i < GpeBlock->RegisterCount; i++)    {        /* Init the RegisterInfo for this GPE register (8 GPEs) */        ThisRegister->BaseGpeNumber = (UINT8) (GpeBlock->BlockBaseNumber +                                             (i * ACPI_GPE_REGISTER_WIDTH));        ThisRegister->StatusAddress.Address =            GpeBlock->BlockAddress.Address + i;        ThisRegister->EnableAddress.Address =            GpeBlock->BlockAddress.Address + i + GpeBlock->RegisterCount;        ThisRegister->StatusAddress.SpaceId   = GpeBlock->BlockAddress.SpaceId;        ThisRegister->EnableAddress.SpaceId   = GpeBlock->BlockAddress.SpaceId;        ThisRegister->StatusAddress.BitWidth  = ACPI_GPE_REGISTER_WIDTH;        ThisRegister->EnableAddress.BitWidth  = ACPI_GPE_REGISTER_WIDTH;        ThisRegister->StatusAddress.BitOffset = ACPI_GPE_REGISTER_WIDTH;        ThisRegister->EnableAddress.BitOffset = ACPI_GPE_REGISTER_WIDTH;        /* Init the EventInfo for each GPE within this register */        for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)        {            ThisEvent->GpeNumber = (UINT8) (ThisRegister->BaseGpeNumber + j);            ThisEvent->RegisterInfo = ThisRegister;            ThisEvent++;        }        /* Disable all GPEs within this register */        Status = AcpiHwLowLevelWrite (ACPI_GPE_REGISTER_WIDTH, 0x00,                    &ThisRegister->EnableAddress);        if (ACPI_FAILURE (Status))        {            goto ErrorExit;        }        /* Clear any pending GPE events within this register */        Status = AcpiHwLowLevelWrite (ACPI_GPE_REGISTER_WIDTH, 0xFF,                    &ThisRegister->StatusAddress);        if (ACPI_FAILURE (Status))        {            goto ErrorExit;        }        ThisRegister++;    }    return_ACPI_STATUS (AE_OK);ErrorExit:    if (GpeRegisterInfo)    {        ACPI_FREE (GpeRegisterInfo);    }    if (GpeEventInfo)    {        ACPI_FREE (GpeEventInfo);    }    return_ACPI_STATUS (Status);}/******************************************************************************* * * FUNCTION:    AcpiEvCreateGpeBlock * * PARAMETERS:  GpeDevice           - Handle to the parent GPE block *              GpeBlockAddress     - Address and SpaceID *              RegisterCount       - Number of GPE register pairs in the block *              GpeBlockBaseNumber  - Starting GPE number for the block *              InterruptNumber     - H/W interrupt for the block *              ReturnGpeBlock      - Where the new block descriptor is returned * * RETURN:      Status * * DESCRIPTION: Create and Install a block of GPE registers. All GPEs within *              the block are disabled at exit. *              Note: Assumes namespace is locked. * ******************************************************************************/ACPI_STATUSAcpiEvCreateGpeBlock (    ACPI_NAMESPACE_NODE     *GpeDevice,    ACPI_GENERIC_ADDRESS    *GpeBlockAddress,    UINT32                  RegisterCount,    UINT8                   GpeBlockBaseNumber,    UINT32                  InterruptNumber,    ACPI_GPE_BLOCK_INFO     **ReturnGpeBlock){    ACPI_STATUS             Status;    ACPI_GPE_BLOCK_INFO     *GpeBlock;    ACPI_FUNCTION_TRACE (EvCreateGpeBlock);    if (!RegisterCount)    {        return_ACPI_STATUS (AE_OK);    }    /* Allocate a new GPE block */    GpeBlock = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_BLOCK_INFO));    if (!GpeBlock)    {        return_ACPI_STATUS (AE_NO_MEMORY);    }    /* Initialize the new GPE block */    GpeBlock->Node = GpeDevice;    GpeBlock->RegisterCount = RegisterCount;    GpeBlock->BlockBaseNumber = GpeBlockBaseNumber;    ACPI_MEMCPY (&GpeBlock->BlockAddress, GpeBlockAddress,        sizeof (ACPI_GENERIC_ADDRESS));    /*     * Create the RegisterInfo and EventInfo sub-structures     * Note: disables and clears all GPEs in the block     */    Status = AcpiEvCreateGpeInfoBlocks (GpeBlock);    if (ACPI_FAILURE (Status))    {        ACPI_FREE (GpeBlock);        return_ACPI_STATUS (Status);    }    /* Install the new block in the global lists */    Status = AcpiEvInstallGpeBlock (GpeBlock, InterruptNumber);    if (ACPI_FAILURE (Status))    {        ACPI_FREE (GpeBlock);        return_ACPI_STATUS (Status);    }    /* Find all GPE methods (_Lxx, _Exx) for this block */    Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD, GpeDevice,                ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,                AcpiEvSaveMethodInfo, GpeBlock, NULL);    /* Return the new block */    if (ReturnGpeBlock)    {        (*ReturnGpeBlock) = GpeBlock;    }    ACPI_DEBUG_PRINT ((ACPI_DB_INIT,        "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n",        (UINT32) GpeBlock->BlockBaseNumber,        (UINT32) (GpeBlock->BlockBaseNumber +                ((GpeBlock->RegisterCount * ACPI_GPE_REGISTER_WIDTH) -1)),        GpeDevice->Name.Ascii,        GpeBlock->RegisterCount,        InterruptNumber));    return_ACPI_STATUS (AE_OK);}/******************************************************************************* * * FUNCTION:    AcpiEvInitializeGpeBlock * * PARAMETERS:  GpeDevice           - Handle to the parent GPE block *              GpeBlock            - Gpe Block info * * RETURN:      Status * * DESCRIPTION: Initialize and enable a GPE block. First find and run any *              _PRT methods associated with the block, then enable the *              appropriate GPEs. *              Note: Assumes namespace is locked. * ******************************************************************************/ACPI_STATUSAcpiEvInitializeGpeBlock (    ACPI_NAMESPACE_NODE     *GpeDevice,    ACPI_GPE_BLOCK_INFO     *GpeBlock){    ACPI_STATUS             Status;    ACPI_GPE_EVENT_INFO     *GpeEventInfo;    ACPI_GPE_WALK_INFO      GpeInfo;    UINT32                  WakeGpeCount;    UINT32                  GpeEnabledCount;    ACPI_NATIVE_UINT        i;    ACPI_NATIVE_UINT        j;    ACPI_FUNCTION_TRACE (EvInitializeGpeBlock);    /* Ignore a null GPE block (e.g., if no GPE block 1 exists) */    if (!GpeBlock)    {        return_ACPI_STATUS (AE_OK);    }    /*     * Runtime option: Should wake GPEs be enabled at runtime?  The default     * is no, they should only be enabled just as the machine goes to sleep.     */    if (AcpiGbl_LeaveWakeGpesDisabled)    {        /*         * Differentiate runtime vs wake GPEs, via the _PRW control methods.         * Each GPE that has one or more _PRWs that reference it is by         * definition a wake GPE and will not be enabled while the machine         * is running.         */        GpeInfo.GpeBlock = GpeBlock;        GpeInfo.GpeDevice = GpeDevice;        Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,                    ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,                    AcpiEvMatchPrwAndGpe, &GpeInfo, NULL);    }    /*     * Enable all GPEs in this block that have these attributes:     * 1) are "runtime" or "run/wake" GPEs, and     * 2) have a corresponding _Lxx or _Exx method     *     * Any other GPEs within this block must be enabled via the AcpiEnableGpe()     * external interface.     */    WakeGpeCount = 0;    GpeEnabledCount = 0;    for (i = 0; i < GpeBlock->RegisterCount; i++)    {        for (j = 0; j < 8; j++)        {            /* Get the info block for this particular GPE */            GpeEventInfo = &GpeBlock->EventInfo[(i * ACPI_GPE_REGISTER_WIDTH) + j];            if (((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_METHOD) &&                 (GpeEventInfo->Flags & ACPI_GPE_TYPE_RUNTIME))            {                GpeEnabledCount++;            }            if (GpeEventInfo->Flags & ACPI_GPE_TYPE_WAKE)            {                WakeGpeCount++;            }        }    }    ACPI_DEBUG_PRINT ((ACPI_DB_INIT,        "Found %u Wake, Enabled %u Runtime GPEs in this block\n",        WakeGpeCount, GpeEnabledCount));    /* Enable all valid runtime GPEs found above */    Status = AcpiHwEnableRuntimeGpeBlock (NULL, GpeBlock);    if (ACPI_FAILURE (Status))    {        ACPI_ERROR ((AE_INFO, "Could not enable GPEs in GpeBlock %p",            GpeBlock));    }    return_ACPI_STATUS (Status);}/******************************************************************************* * * FUNCTION:    AcpiEvGpeInitialize * * PARAMETERS:  None * * RETURN:      Status * * DESCRIPTION: Initialize the GPE data structures * ******************************************************************************/ACPI_STATUSAcpiEvGpeInitialize (    void){    UINT32                  RegisterCount0 = 0;    UINT32                  RegisterCount1 = 0;    UINT32                  GpeNumberMax = 0;    ACPI_STATUS             Status;    ACPI_FUNCTION_TRACE (EvGpeInitialize);    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);    if (ACPI_FAILURE (Status))    {        return_ACPI_STATUS (Status);    }    /*     * Initialize the GPE Block(s) defined in the FADT     *     * Why the GPE register block lengths are divided by 2:  From the ACPI Spec,     * section "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."     */    /*     * Determine the maximum GPE number for this machine.     *     * Note: both GPE0 and GPE1 are optional, and either can exist without     * the other.     *     * If EITHER the register length OR the block address are zero, then that     * particular block is not supported.     */    if (AcpiGbl_FADT.Gpe0BlockLength &&        AcpiGbl_FADT.XGpe0Block.Address)    {        /* GPE block 0 exists (has both length and address > 0) */        RegisterCount0 = (UINT16) (AcpiGbl_FADT.Gpe0BlockLength / 2);        GpeNumberMax = (RegisterCount0 * ACPI_GPE_REGISTER_WIDTH) - 1;        /* Install GPE Block 0 */        Status = AcpiEvCreateGpeBlock (AcpiGbl_FadtGpeDevice,                    &AcpiGbl_FADT.XGpe0Block, RegisterCount0, 0,                    AcpiGbl_FADT.SciInterrupt, &AcpiGbl_GpeFadtBlocks[0]);        if (ACPI_FAILURE (Status))        {            ACPI_EXCEPTION ((AE_INFO, Status,                "Could not create GPE Block 0"));        }    }    if (AcpiGbl_FADT.Gpe1BlockLength &&        AcpiGbl_FADT.XGpe1Block.Address)    {        /* GPE block 1 exists (has both length and address > 0) */        RegisterCount1 = (UINT16) (AcpiGbl_FADT.Gpe1BlockLength / 2);        /* Check for GPE0/GPE1 overlap (if both banks exist) */        if ((RegisterCount0) &&            (GpeNumberMax >= AcpiGbl_FADT.Gpe1Base))        {            ACPI_ERROR ((AE_INFO,                "GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1",                GpeNumberMax, AcpiGbl_FADT.Gpe1Base,                AcpiGbl_FADT.Gpe1Base +                ((RegisterCount1 * ACPI_GPE_REGISTER_WIDTH) - 1)));            /* Ignore GPE1 block by setting the register count to zero */            RegisterCount1 = 0;        }        else        {            /* Install GPE Block 1 */            Status = AcpiEvCreateGpeBlock (AcpiGbl_FadtGpeDevice,                        &AcpiGbl_FADT.XGpe1Block, RegisterCount1,                        AcpiGbl_FADT.Gpe1Base,                        AcpiGbl_FADT.SciInterrupt, &AcpiGbl_GpeFadtBlocks[1]);            if (ACPI_FAILURE (Status))            {                ACPI_EXCEPTION ((AE_INFO, Status,                    "Could not create GPE Block 1"));            }            /*             * GPE0 and GPE1 do not have to be contiguous in the GPE number             * space. However, GPE0 always starts at GPE number zero.             */            GpeNumberMax = AcpiGbl_FADT.Gpe1Base +                            ((RegisterCount1 * ACPI_GPE_REGISTER_WIDTH) - 1);        }    }    /* Exit if there are no GPE registers */    if ((RegisterCount0 + RegisterCount1) == 0)    {        /* GPEs are not required by ACPI, this is OK */        ACPI_DEBUG_PRINT ((ACPI_DB_INIT,            "There are no GPE blocks defined in the FADT\n"));        Status = AE_OK;        goto Cleanup;    }    /* Check for Max GPE number out-of-range */    if (GpeNumberMax > ACPI_GPE_MAX)    {        ACPI_ERROR ((AE_INFO,            "Maximum GPE number from FADT is too large: 0x%X",            GpeNumberMax));        Status = AE_BAD_VALUE;        goto Cleanup;    }Cleanup:    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);    return_ACPI_STATUS (AE_OK);}

⌨️ 快捷键说明

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