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

📄 exfldio.c

📁 acpi tools for linux include acpiexec and acpixtract
💻 C
📖 第 1 页 / 共 3 页
字号:
        AcpiUtGetRegionName (RgnDesc->Region.SpaceId),        RgnDesc->Region.SpaceId,        ObjDesc->CommonField.AccessByteWidth,        ObjDesc->CommonField.BaseByteOffset,        FieldDatumByteOffset,        ACPI_CAST_PTR (void, Address)));    /* Invoke the appropriate AddressSpace/OpRegion handler */    Status = AcpiEvAddressSpaceDispatch (RgnDesc, Function,                Address,                ACPI_MUL_8 (ObjDesc->CommonField.AccessByteWidth), Value);    if (ACPI_FAILURE (Status))    {        if (Status == AE_NOT_IMPLEMENTED)        {            ACPI_ERROR ((AE_INFO,                "Region %s(%X) not implemented",                AcpiUtGetRegionName (RgnDesc->Region.SpaceId),                RgnDesc->Region.SpaceId));        }        else if (Status == AE_NOT_EXIST)        {            ACPI_ERROR ((AE_INFO,                "Region %s(%X) has no handler",                AcpiUtGetRegionName (RgnDesc->Region.SpaceId),                RgnDesc->Region.SpaceId));        }    }    return_ACPI_STATUS (Status);}/******************************************************************************* * * FUNCTION:    AcpiExRegisterOverflow * * PARAMETERS:  ObjDesc                 - Register(Field) to be written *              Value                   - Value to be stored * * RETURN:      TRUE if value overflows the field, FALSE otherwise * * DESCRIPTION: Check if a value is out of range of the field being written. *              Used to check if the values written to Index and Bank registers *              are out of range.  Normally, the value is simply truncated *              to fit the field, but this case is most likely a serious *              coding error in the ASL. * ******************************************************************************/static BOOLEANAcpiExRegisterOverflow (    ACPI_OPERAND_OBJECT     *ObjDesc,    ACPI_INTEGER            Value){    if (ObjDesc->CommonField.BitLength >= ACPI_INTEGER_BIT_SIZE)    {        /*         * The field is large enough to hold the maximum integer, so we can         * never overflow it.         */        return (FALSE);    }    if (Value >= ((ACPI_INTEGER) 1 << ObjDesc->CommonField.BitLength))    {        /*         * The Value is larger than the maximum value that can fit into         * the register.         */        return (TRUE);    }    /* The Value will fit into the field with no truncation */    return (FALSE);}/******************************************************************************* * * FUNCTION:    AcpiExFieldDatumIo * * PARAMETERS:  ObjDesc                 - Field to be read *              FieldDatumByteOffset    - Byte offset of this datum within the *                                        parent field *              Value                   - Where to store value (must be 64 bits) *              ReadWrite               - Read or Write flag * * RETURN:      Status * * DESCRIPTION: Read or Write a single datum of a field.  The FieldType is *              demultiplexed here to handle the different types of fields *              (BufferField, RegionField, IndexField, BankField) * ******************************************************************************/static ACPI_STATUSAcpiExFieldDatumIo (    ACPI_OPERAND_OBJECT     *ObjDesc,    UINT32                  FieldDatumByteOffset,    ACPI_INTEGER            *Value,    UINT32                  ReadWrite){    ACPI_STATUS             Status;    ACPI_INTEGER            LocalValue;    ACPI_FUNCTION_TRACE_U32 (ExFieldDatumIo, FieldDatumByteOffset);    if (ReadWrite == ACPI_READ)    {        if (!Value)        {            LocalValue = 0;            /* To support reads without saving return value */            Value = &LocalValue;        }        /* Clear the entire return buffer first, [Very Important!] */        *Value = 0;    }    /*     * The four types of fields are:     *     * BufferField - Read/write from/to a Buffer     * RegionField - Read/write from/to a Operation Region.     * BankField   - Write to a Bank Register, then read/write from/to an     *               OperationRegion     * IndexField  - Write to an Index Register, then read/write from/to a     *               Data Register     */    switch (ACPI_GET_OBJECT_TYPE (ObjDesc))    {    case ACPI_TYPE_BUFFER_FIELD:        /*         * If the BufferField arguments have not been previously evaluated,         * evaluate them now and save the results.         */        if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))        {            Status = AcpiDsGetBufferFieldArguments (ObjDesc);            if (ACPI_FAILURE (Status))            {                return_ACPI_STATUS (Status);            }        }        if (ReadWrite == ACPI_READ)        {            /*             * Copy the data from the source buffer.             * Length is the field width in bytes.             */            ACPI_MEMCPY (Value,                (ObjDesc->BufferField.BufferObj)->Buffer.Pointer +                    ObjDesc->BufferField.BaseByteOffset +                    FieldDatumByteOffset,                ObjDesc->CommonField.AccessByteWidth);        }        else        {            /*             * Copy the data to the target buffer.             * Length is the field width in bytes.             */            ACPI_MEMCPY ((ObjDesc->BufferField.BufferObj)->Buffer.Pointer +                ObjDesc->BufferField.BaseByteOffset +                FieldDatumByteOffset,                Value, ObjDesc->CommonField.AccessByteWidth);        }        Status = AE_OK;        break;    case ACPI_TYPE_LOCAL_BANK_FIELD:        /*         * Ensure that the BankValue is not beyond the capacity of         * the register         */        if (AcpiExRegisterOverflow (ObjDesc->BankField.BankObj,                (ACPI_INTEGER) ObjDesc->BankField.Value))        {            return_ACPI_STATUS (AE_AML_REGISTER_LIMIT);        }        /*         * For BankFields, we must write the BankValue to the BankRegister         * (itself a RegionField) before we can access the data.         */        Status = AcpiExInsertIntoField (ObjDesc->BankField.BankObj,                    &ObjDesc->BankField.Value,                    sizeof (ObjDesc->BankField.Value));        if (ACPI_FAILURE (Status))        {            return_ACPI_STATUS (Status);        }        /*         * Now that the Bank has been selected, fall through to the         * RegionField case and write the datum to the Operation Region         */        /*lint -fallthrough */    case ACPI_TYPE_LOCAL_REGION_FIELD:        /*         * For simple RegionFields, we just directly access the owning         * Operation Region.         */        Status = AcpiExAccessRegion (ObjDesc, FieldDatumByteOffset, Value,                    ReadWrite);        break;    case ACPI_TYPE_LOCAL_INDEX_FIELD:        /*         * Ensure that the IndexValue is not beyond the capacity of         * the register         */        if (AcpiExRegisterOverflow (ObjDesc->IndexField.IndexObj,                (ACPI_INTEGER) ObjDesc->IndexField.Value))        {            return_ACPI_STATUS (AE_AML_REGISTER_LIMIT);        }        /* Write the index value to the IndexRegister (itself a RegionField) */        FieldDatumByteOffset += ObjDesc->IndexField.Value;        ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,            "Write to Index Register: Value %8.8X\n",            FieldDatumByteOffset));        Status = AcpiExInsertIntoField (ObjDesc->IndexField.IndexObj,                    &FieldDatumByteOffset,                    sizeof (FieldDatumByteOffset));        if (ACPI_FAILURE (Status))        {            return_ACPI_STATUS (Status);        }        ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,            "I/O to Data Register: ValuePtr %p\n", Value));        if (ReadWrite == ACPI_READ)        {            /* Read the datum from the DataRegister */            Status = AcpiExExtractFromField (ObjDesc->IndexField.DataObj,                        Value, sizeof (ACPI_INTEGER));        }        else        {            /* Write the datum to the DataRegister */            Status = AcpiExInsertIntoField (ObjDesc->IndexField.DataObj,                        Value, sizeof (ACPI_INTEGER));        }        break;    default:        ACPI_ERROR ((AE_INFO, "Wrong object type in field I/O %X",            ACPI_GET_OBJECT_TYPE (ObjDesc)));        Status = AE_AML_INTERNAL;        break;    }    if (ACPI_SUCCESS (Status))    {        if (ReadWrite == ACPI_READ)        {            ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,                "Value Read %8.8X%8.8X, Width %d\n",                ACPI_FORMAT_UINT64 (*Value),                ObjDesc->CommonField.AccessByteWidth));        }        else        {            ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,                "Value Written %8.8X%8.8X, Width %d\n",                ACPI_FORMAT_UINT64 (*Value),                ObjDesc->CommonField.AccessByteWidth));        }    }    return_ACPI_STATUS (Status);}/******************************************************************************* * * FUNCTION:    AcpiExWriteWithUpdateRule * * PARAMETERS:  ObjDesc                 - Field to be written *              Mask                    - bitmask within field datum *              FieldValue              - Value to write *              FieldDatumByteOffset    - Offset of datum within field * * RETURN:      Status * * DESCRIPTION: Apply the field update rule to a field write * ******************************************************************************/ACPI_STATUSAcpiExWriteWithUpdateRule (    ACPI_OPERAND_OBJECT     *ObjDesc,    ACPI_INTEGER            Mask,    ACPI_INTEGER            FieldValue,    UINT32                  FieldDatumByteOffset){    ACPI_STATUS             Status = AE_OK;    ACPI_INTEGER            MergedValue;    ACPI_INTEGER            CurrentValue;    ACPI_FUNCTION_TRACE_U32 (ExWriteWithUpdateRule, Mask);    /* Start with the new bits  */    MergedValue = FieldValue;    /* If the mask is all ones, we don't need to worry about the update rule */    if (Mask != ACPI_INTEGER_MAX)    {        /* Decode the update rule */        switch (ObjDesc->CommonField.FieldFlags & AML_FIELD_UPDATE_RULE_MASK)        {        case AML_FIELD_UPDATE_PRESERVE:            /*             * Check if update rule needs to be applied (not if mask is all             * ones)  The left shift drops the bits we want to ignore.             */            if ((~Mask << (ACPI_MUL_8 (sizeof (Mask)) -                           ACPI_MUL_8 (ObjDesc->CommonField.AccessByteWidth))) != 0)            {                /*                 * Read the current contents of the byte/word/dword containing                 * the field, and merge with the new field value.                 */                Status = AcpiExFieldDatumIo (ObjDesc, FieldDatumByteOffset,                            &CurrentValue, ACPI_READ);                if (ACPI_FAILURE (Status))                {

⌨️ 快捷键说明

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