diff options
Diffstat (limited to 'sys/contrib/dev/acpica/exprep.c')
-rw-r--r-- | sys/contrib/dev/acpica/exprep.c | 218 |
1 files changed, 121 insertions, 97 deletions
diff --git a/sys/contrib/dev/acpica/exprep.c b/sys/contrib/dev/acpica/exprep.c index 1089492..98660e1 100644 --- a/sys/contrib/dev/acpica/exprep.c +++ b/sys/contrib/dev/acpica/exprep.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: exprep - ACPI AML (p-code) execution - field prep utilities - * $Revision: 99 $ + * $Revision: 109 $ * *****************************************************************************/ @@ -130,74 +130,91 @@ /******************************************************************************* * - * FUNCTION: AcpiExDecodeFieldAccessType + * FUNCTION: AcpiExDecodeFieldAccess * * PARAMETERS: Access - Encoded field access bits * Length - Field length. * - * RETURN: Field granularity (8, 16, 32 or 64) + * RETURN: Field granularity (8, 16, 32 or 64) and + * ByteAlignment (1, 2, 3, or 4) * * DESCRIPTION: Decode the AccessType bits of a field definition. * ******************************************************************************/ static UINT32 -AcpiExDecodeFieldAccessType ( - UINT32 Access, - UINT16 Length, - UINT32 *Alignment) +AcpiExDecodeFieldAccess ( + ACPI_OPERAND_OBJECT *ObjDesc, + UINT8 FieldFlags, + UINT32 *ReturnByteAlignment) { - PROC_NAME ("ExDecodeFieldAccessType"); + UINT32 Access; + UINT16 Length; + UINT8 ByteAlignment; + UINT8 BitLength; + + + PROC_NAME ("ExDecodeFieldAccess"); + + Access = (FieldFlags & AML_FIELD_ACCESS_TYPE_MASK); + Length = ObjDesc->CommonField.BitLength; switch (Access) { - case ACCESS_ANY_ACC: + case AML_FIELD_ACCESS_ANY: - *Alignment = 8; + ByteAlignment = 1; /* Use the length to set the access type */ if (Length <= 8) { - return (8); + BitLength = 8; } else if (Length <= 16) { - return (16); + BitLength = 16; } else if (Length <= 32) { - return (32); + BitLength = 32; } else if (Length <= 64) { - return (64); + BitLength = 64; } + else + { + /* Larger than Qword - just use byte-size chunks */ - /* Default is 8 (byte) */ + BitLength = 8; + } + break; - return (8); + case AML_FIELD_ACCESS_BYTE: + ByteAlignment = 1; + BitLength = 8; break; - case ACCESS_BYTE_ACC: - *Alignment = 8; - return (8); + case AML_FIELD_ACCESS_WORD: + ByteAlignment = 2; + BitLength = 16; break; - case ACCESS_WORD_ACC: - *Alignment = 16; - return (16); + case AML_FIELD_ACCESS_DWORD: + ByteAlignment = 4; + BitLength = 32; break; - case ACCESS_DWORD_ACC: - *Alignment = 32; - return (32); + case AML_FIELD_ACCESS_QWORD: /* ACPI 2.0 */ + ByteAlignment = 8; + BitLength = 64; break; - case ACCESS_QWORD_ACC: /* ACPI 2.0 */ - *Alignment = 64; - return (64); + case AML_FIELD_ACCESS_BUFFER: /* ACPI 2.0 */ + ByteAlignment = 8; + BitLength = 8; break; default: @@ -208,6 +225,19 @@ AcpiExDecodeFieldAccessType ( Access)); return (0); } + + if (ObjDesc->Common.Type == ACPI_TYPE_BUFFER_FIELD) + { + /* + * BufferField access can be on any byte boundary, so the + * ByteAlignment is always 1 byte -- regardless of any ByteAlignment + * implied by the field access type. + */ + ByteAlignment = 1; + } + + *ReturnByteAlignment = ByteAlignment; + return (BitLength); } @@ -225,7 +255,9 @@ AcpiExDecodeFieldAccessType ( * RETURN: Status * * DESCRIPTION: Initialize the areas of the field object that are common - * to the various types of fields. + * to the various types of fields. Note: This is very "sensitive" + * code because we are solving the general case for field + * alignment. * ******************************************************************************/ @@ -233,45 +265,48 @@ ACPI_STATUS AcpiExPrepCommonFieldObject ( ACPI_OPERAND_OBJECT *ObjDesc, UINT8 FieldFlags, + UINT8 FieldAttribute, UINT32 FieldBitPosition, UINT32 FieldBitLength) { UINT32 AccessBitWidth; - UINT32 Alignment; + UINT32 ByteAlignment; UINT32 NearestByteAddress; FUNCTION_TRACE ("ExPrepCommonFieldObject"); + if (FieldBitLength > ACPI_UINT16_MAX) + { + REPORT_ERROR (("Field size too long (> 0xFFFF), not supported\n")); + return_ACPI_STATUS (AE_SUPPORT); + } + /* * Note: the structure being initialized is the - * ACPI_COMMON_FIELD_INFO; No structure fields outside of the common area - * are initialized by this procedure. + * ACPI_COMMON_FIELD_INFO; No structure fields outside of the common + * area are initialized by this procedure. */ - - /* Demultiplex the FieldFlags byte */ - - ObjDesc->CommonField.LockRule = (UINT8) ((FieldFlags & LOCK_RULE_MASK) - >> LOCK_RULE_SHIFT); - ObjDesc->CommonField.UpdateRule = (UINT8) ((FieldFlags & UPDATE_RULE_MASK) - >> UPDATE_RULE_SHIFT); - /* Other misc fields */ - + ObjDesc->CommonField.FieldFlags = FieldFlags; + ObjDesc->CommonField.Attribute = FieldAttribute; ObjDesc->CommonField.BitLength = (UINT16) FieldBitLength; /* * Decode the access type so we can compute offsets. The access type gives * two pieces of information - the width of each field access and the - * necessary alignment of the access. For AnyAcc, the width used is the - * largest necessary/possible in an attempt to access the whole field in one - * I/O operation. However, for AnyAcc, the alignment is 8. For all other - * access types (Byte, Word, Dword, Qword), the width is the same as the - * alignment. + * necessary ByteAlignment (address granularity) of the access. + * + * For AnyAcc, the AccessBitWidth is the largest width that is both necessary + * and possible in an attempt to access the whole field in one + * I/O operation. However, for AnyAcc, the ByteAlignment is always one byte. + * + * For all Buffer Fields, the ByteAlignment is always one byte. + * + * For all other access types (Byte, Word, Dword, Qword), the Bitwidth is the + * same (equivalent) as the ByteAlignment. */ - AccessBitWidth = AcpiExDecodeFieldAccessType ( - ((FieldFlags & ACCESS_TYPE_MASK) >> ACCESS_TYPE_SHIFT), - ObjDesc->Field.BitLength, &Alignment); + AccessBitWidth = AcpiExDecodeFieldAccess (ObjDesc, FieldFlags, &ByteAlignment); if (!AccessBitWidth) { return_ACPI_STATUS (AE_AML_OPERAND_VALUE); @@ -279,64 +314,50 @@ AcpiExPrepCommonFieldObject ( /* Setup width (access granularity) fields */ - ObjDesc->CommonField.AccessBitWidth = (UINT8) AccessBitWidth; /* 8, 16, 32, 64 */ - ObjDesc->CommonField.AccessByteWidth = (UINT8) DIV_8 (AccessBitWidth); /* 1, 2, 4, 8 */ - - if (ObjDesc->Common.Type == ACPI_TYPE_BUFFER_FIELD) - { - /* - * BufferField access can be on any byte boundary, so the - * alignment is always 8 (regardless of any alignment implied by the - * field access type.) - */ - Alignment = 8; - } - + ObjDesc->CommonField.AccessBitWidth = (UINT8) AccessBitWidth; /* 8, 16, 32, 64 */ + ObjDesc->CommonField.AccessByteWidth = (UINT8) DIV_8 (AccessBitWidth); /* 1, 2, 4, 8 */ /* * BaseByteOffset is the address of the start of the field within the region. It is * the byte address of the first *datum* (field-width data unit) of the field. * (i.e., the first datum that contains at least the first *bit* of the field.) + * Note: ByteAlignment is always either equal to the AccessBitWidth or 8 (Byte access), + * and it defines the addressing granularity of the parent region or buffer. */ - NearestByteAddress = ROUND_BITS_DOWN_TO_BYTES (FieldBitPosition); - ObjDesc->CommonField.BaseByteOffset = ROUND_DOWN (NearestByteAddress, - DIV_8 (Alignment)); + NearestByteAddress = ROUND_BITS_DOWN_TO_BYTES (FieldBitPosition); + ObjDesc->CommonField.BaseByteOffset = ROUND_DOWN (NearestByteAddress, ByteAlignment); /* * StartFieldBitOffset is the offset of the first bit of the field within a field datum. - * This is calculated as the number of bits from the BaseByteOffset. In other words, - * the start of the field is relative to a byte address, regardless of the access type - * of the field. - */ - ObjDesc->CommonField.StartFieldBitOffset = (UINT8) (MOD_8 (FieldBitPosition)); - - /* - * DatumValidBits is the number of valid field bits in the first field datum. */ - ObjDesc->CommonField.DatumValidBits = (UINT8) (AccessBitWidth - - ObjDesc->CommonField.StartFieldBitOffset); + ObjDesc->CommonField.StartFieldBitOffset = (UINT8) (FieldBitPosition - + MUL_8 (ObjDesc->CommonField.BaseByteOffset)); /* * Valid bits -- the number of bits that compose a partial datum, * 1) At the end of the field within the region (arbitrary starting bit offset) * 2) At the end of a buffer used to contain the field (starting offset always zero) */ - ObjDesc->CommonField.EndFieldValidBits = (UINT8) ((ObjDesc->CommonField.StartFieldBitOffset + - FieldBitLength) % AccessBitWidth); - ObjDesc->CommonField.EndBufferValidBits = (UINT8) (FieldBitLength % AccessBitWidth); /* StartBufferBitOffset always = 0 */ + ObjDesc->CommonField.EndFieldValidBits = (UINT8) ((ObjDesc->CommonField.StartFieldBitOffset + FieldBitLength) % + AccessBitWidth); + ObjDesc->CommonField.EndBufferValidBits = (UINT8) (FieldBitLength % AccessBitWidth); /* StartBufferBitOffset always = 0 */ + /* + * DatumValidBits is the number of valid field bits in the first field datum. + */ + ObjDesc->CommonField.DatumValidBits = (UINT8) (AccessBitWidth - + ObjDesc->CommonField.StartFieldBitOffset); /* - * Does the entire field fit within a single field access element - * (datum)? (without crossing a datum boundary) + * Does the entire field fit within a single field access element? (datum) + * (i.e., without crossing a datum boundary) */ - if ((ObjDesc->CommonField.StartFieldBitOffset + ObjDesc->CommonField.BitLength) <= - (UINT16) ObjDesc->CommonField.AccessBitWidth) + if ((ObjDesc->CommonField.StartFieldBitOffset + FieldBitLength) <= + (UINT16) AccessBitWidth) { - ObjDesc->CommonField.AccessFlags |= AFIELD_SINGLE_DATUM; + ObjDesc->Common.Flags |= AOPOBJ_SINGLE_DATUM; } - return_ACPI_STATUS (AE_OK); } @@ -383,14 +404,15 @@ AcpiExPrepFieldValue ( Type = AcpiNsGetType (Info->RegionNode); if (Type != ACPI_TYPE_REGION) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Needed Region, found type %X %s\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Needed Region, found type %X %s\n", Type, AcpiUtGetTypeName (Type))); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } } - /* Allocate a new region object */ + /* Allocate a new field object */ ObjDesc = AcpiUtCreateInternalObject (Info->FieldType); if (!ObjDesc) @@ -400,8 +422,9 @@ AcpiExPrepFieldValue ( /* Initialize areas of the object that are common to all fields */ - Status = AcpiExPrepCommonFieldObject (ObjDesc, Info->FieldFlags, - Info->FieldBitPosition, Info->FieldBitLength); + ObjDesc->CommonField.Node = Info->FieldNode; + Status = AcpiExPrepCommonFieldObject (ObjDesc, Info->FieldFlags, + Info->Attribute, Info->FieldBitPosition, Info->FieldBitLength); if (ACPI_FAILURE (Status)) { AcpiUtDeleteObjectDesc (ObjDesc); @@ -414,13 +437,14 @@ AcpiExPrepFieldValue ( { case INTERNAL_TYPE_REGION_FIELD: - ObjDesc->Field.RegionObj = AcpiNsGetAttachedObject (Info->RegionNode); + ObjDesc->Field.RegionObj = AcpiNsGetAttachedObject (Info->RegionNode); /* An additional reference for the container */ AcpiUtAddReference (ObjDesc->Field.RegionObj); - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "RegionField: Bitoff=%X Off=%X Gran=%X Region %p\n", + ACPI_DEBUG_PRINT ((ACPI_DB_INFO, + "RegionField: Bitoff=%X Off=%X Gran=%X Region %p\n", ObjDesc->Field.StartFieldBitOffset, ObjDesc->Field.BaseByteOffset, ObjDesc->Field.AccessBitWidth, ObjDesc->Field.RegionObj)); break; @@ -428,19 +452,19 @@ AcpiExPrepFieldValue ( case INTERNAL_TYPE_BANK_FIELD: - ObjDesc->BankField.Value = Info->BankValue; - ObjDesc->BankField.RegionObj = AcpiNsGetAttachedObject (Info->RegionNode); - ObjDesc->BankField.BankRegisterObj = AcpiNsGetAttachedObject (Info->RegisterNode); + ObjDesc->BankField.Value = Info->BankValue; + ObjDesc->BankField.RegionObj = AcpiNsGetAttachedObject (Info->RegionNode); + ObjDesc->BankField.BankObj = AcpiNsGetAttachedObject (Info->RegisterNode); /* An additional reference for the attached objects */ AcpiUtAddReference (ObjDesc->BankField.RegionObj); - AcpiUtAddReference (ObjDesc->BankField.BankRegisterObj); + AcpiUtAddReference (ObjDesc->BankField.BankObj); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Bank Field: BitOff=%X Off=%X Gran=%X Region %p BankReg %p\n", ObjDesc->BankField.StartFieldBitOffset, ObjDesc->BankField.BaseByteOffset, ObjDesc->Field.AccessBitWidth, ObjDesc->BankField.RegionObj, - ObjDesc->BankField.BankRegisterObj)); + ObjDesc->BankField.BankObj)); break; @@ -473,11 +497,11 @@ AcpiExPrepFieldValue ( * Store the constructed descriptor (ObjDesc) into the parent Node, * preserving the current type of that NamedObj. */ - Status = AcpiNsAttachObject (Info->FieldNode, ObjDesc, + Status = AcpiNsAttachObject (Info->FieldNode, ObjDesc, (UINT8) AcpiNsGetType (Info->FieldNode)); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "set NamedObj %p (%4.4s) val = %p\n", - Info->FieldNode, (char*)&(Info->FieldNode->Name), ObjDesc)); + Info->FieldNode, (char*)&(Info->FieldNode->Name), ObjDesc)); /* Remove local reference to the object */ |