exprep.c revision 246849
1229997Sken/****************************************************************************** 2229997Sken * 3232604Strasz * Module Name: exprep - ACPI AML (p-code) execution - field prep utilities 4229997Sken * 5229997Sken *****************************************************************************/ 6232604Strasz 7232604Strasz/* 8232604Strasz * Copyright (C) 2000 - 2013, Intel Corp. 9229997Sken * All rights reserved. 10229997Sken * 11229997Sken * Redistribution and use in source and binary forms, with or without 12229997Sken * modification, are permitted provided that the following conditions 13229997Sken * are met: 14229997Sken * 1. Redistributions of source code must retain the above copyright 15229997Sken * notice, this list of conditions, and the following disclaimer, 16229997Sken * without modification. 17229997Sken * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18229997Sken * substantially similar to the "NO WARRANTY" disclaimer below 19229997Sken * ("Disclaimer") and any redistribution must be conditioned upon 20229997Sken * including a substantially similar Disclaimer requirement for further 21229997Sken * binary redistribution. 22229997Sken * 3. Neither the names of the above-listed copyright holders nor the names 23229997Sken * of any contributors may be used to endorse or promote products derived 24229997Sken * from this software without specific prior written permission. 25229997Sken * 26229997Sken * Alternatively, this software may be distributed under the terms of the 27229997Sken * GNU General Public License ("GPL") version 2 as published by the Free 28229997Sken * Software Foundation. 29229997Sken * 30229997Sken * NO WARRANTY 31229997Sken * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32229997Sken * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33229997Sken * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34229997Sken * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35229997Sken * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36229997Sken * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37229997Sken * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38229997Sken * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39229997Sken * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40229997Sken * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41229997Sken * POSSIBILITY OF SUCH DAMAGES. 42229997Sken */ 43229997Sken 44229997Sken#define __EXPREP_C__ 45229997Sken 46229997Sken#include <contrib/dev/acpica/include/acpi.h> 47229997Sken#include <contrib/dev/acpica/include/accommon.h> 48229997Sken#include <contrib/dev/acpica/include/acinterp.h> 49229997Sken#include <contrib/dev/acpica/include/amlcode.h> 50229997Sken#include <contrib/dev/acpica/include/acnamesp.h> 51229997Sken#include <contrib/dev/acpica/include/acdispat.h> 52229997Sken 53264886Smav 54229997Sken#define _COMPONENT ACPI_EXECUTER 55229997Sken ACPI_MODULE_NAME ("exprep") 56229997Sken 57229997Sken/* Local prototypes */ 58229997Sken 59287621Smavstatic UINT32 60229997SkenAcpiExDecodeFieldAccess ( 61229997Sken ACPI_OPERAND_OBJECT *ObjDesc, 62287621Smav UINT8 FieldFlags, 63229997Sken UINT32 *ReturnByteAlignment); 64229997Sken 65229997Sken 66229997Sken#ifdef ACPI_UNDER_DEVELOPMENT 67229997Sken 68229997Skenstatic UINT32 69287621SmavAcpiExGenerateAccess ( 70287621Smav UINT32 FieldBitOffset, 71229997Sken UINT32 FieldBitLength, 72229997Sken UINT32 RegionLength); 73229997Sken 74229997Sken/******************************************************************************* 75229997Sken * 76229997Sken * FUNCTION: AcpiExGenerateAccess 77229997Sken * 78229997Sken * PARAMETERS: FieldBitOffset - Start of field within parent region/buffer 79229997Sken * FieldBitLength - Length of field in bits 80287500Smav * RegionLength - Length of parent in bytes 81264886Smav * 82229997Sken * RETURN: Field granularity (8, 16, 32 or 64) and 83229997Sken * ByteAlignment (1, 2, 3, or 4) 84229997Sken * 85229997Sken * DESCRIPTION: Generate an optimal access width for fields defined with the 86229997Sken * AnyAcc keyword. 87287499Smav * 88264886Smav * NOTE: Need to have the RegionLength in order to check for boundary 89264886Smav * conditions (end-of-region). However, the RegionLength is a deferred 90264886Smav * operation. Therefore, to complete this implementation, the generation 91267877Smav * of this access width must be deferred until the region length has 92229997Sken * been evaluated. 93229997Sken * 94229997Sken ******************************************************************************/ 95229997Sken 96229997Skenstatic UINT32 97229997SkenAcpiExGenerateAccess ( 98229997Sken UINT32 FieldBitOffset, 99229997Sken UINT32 FieldBitLength, 100229997Sken UINT32 RegionLength) 101229997Sken{ 102229997Sken UINT32 FieldByteLength; 103229997Sken UINT32 FieldByteOffset; 104229997Sken UINT32 FieldByteEndOffset; 105229997Sken UINT32 AccessByteWidth; 106229997Sken UINT32 FieldStartOffset; 107229997Sken UINT32 FieldEndOffset; 108287621Smav UINT32 MinimumAccessWidth = 0xFFFFFFFF; 109229997Sken UINT32 MinimumAccesses = 0xFFFFFFFF; 110229997Sken UINT32 Accesses; 111229997Sken 112229997Sken 113229997Sken ACPI_FUNCTION_TRACE (ExGenerateAccess); 114264886Smav 115229997Sken 116229997Sken /* Round Field start offset and length to "minimal" byte boundaries */ 117229997Sken 118229997Sken FieldByteOffset = ACPI_DIV_8 (ACPI_ROUND_DOWN (FieldBitOffset, 8)); 119229997Sken FieldByteEndOffset = ACPI_DIV_8 (ACPI_ROUND_UP (FieldBitLength + 120287499Smav FieldBitOffset, 8)); 121232604Strasz FieldByteLength = FieldByteEndOffset - FieldByteOffset; 122232604Strasz 123264886Smav ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 124229997Sken "Bit length %u, Bit offset %u\n", 125229997Sken FieldBitLength, FieldBitOffset)); 126229997Sken 127229997Sken ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 128229997Sken "Byte Length %u, Byte Offset %u, End Offset %u\n", 129229997Sken FieldByteLength, FieldByteOffset, FieldByteEndOffset)); 130229997Sken 131229997Sken /* 132230334Sken * Iterative search for the maximum access width that is both aligned 133230334Sken * and does not go beyond the end of the region 134230334Sken * 135230334Sken * Start at ByteAcc and work upwards to QwordAcc max. (1,2,4,8 bytes) 136230334Sken */ 137230334Sken for (AccessByteWidth = 1; AccessByteWidth <= 8; AccessByteWidth <<= 1) 138230334Sken { 139230334Sken /* 140229997Sken * 1) Round end offset up to next access boundary and make sure that 141229997Sken * this does not go beyond the end of the parent region. 142229997Sken * 2) When the Access width is greater than the FieldByteLength, we 143229997Sken * are done. (This does not optimize for the perfectly aligned 144229997Sken * case yet). 145229997Sken */ 146229997Sken if (ACPI_ROUND_UP (FieldByteEndOffset, AccessByteWidth) <= RegionLength) 147229997Sken { 148288220Smav FieldStartOffset = 149229997Sken ACPI_ROUND_DOWN (FieldByteOffset, AccessByteWidth) / 150240993Strasz AccessByteWidth; 151229997Sken 152229997Sken FieldEndOffset = 153229997Sken ACPI_ROUND_UP ((FieldByteLength + FieldByteOffset), 154267877Smav AccessByteWidth) / AccessByteWidth; 155229997Sken 156264886Smav Accesses = FieldEndOffset - FieldStartOffset; 157229997Sken 158229997Sken ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 159229997Sken "AccessWidth %u end is within region\n", AccessByteWidth)); 160229997Sken 161229997Sken ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 162240993Strasz "Field Start %u, Field End %u -- requires %u accesses\n", 163229997Sken FieldStartOffset, FieldEndOffset, Accesses)); 164229997Sken 165229997Sken /* Single access is optimal */ 166229997Sken 167229997Sken if (Accesses <= 1) 168229997Sken { 169229997Sken ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 170229997Sken "Entire field can be accessed with one operation of size %u\n", 171229997Sken AccessByteWidth)); 172229997Sken return_VALUE (AccessByteWidth); 173229997Sken } 174229997Sken 175288220Smav /* 176229997Sken * Fits in the region, but requires more than one read/write. 177229997Sken * try the next wider access on next iteration 178229997Sken */ 179229997Sken if (Accesses < MinimumAccesses) 180229997Sken { 181229997Sken MinimumAccesses = Accesses; 182229997Sken MinimumAccessWidth = AccessByteWidth; 183229997Sken } 184229997Sken } 185229997Sken else 186229997Sken { 187229997Sken ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 188229997Sken "AccessWidth %u end is NOT within region\n", AccessByteWidth)); 189229997Sken if (AccessByteWidth == 1) 190229997Sken { 191229997Sken ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 192229997Sken "Field goes beyond end-of-region!\n")); 193229997Sken 194229997Sken /* Field does not fit in the region at all */ 195229997Sken 196287499Smav return_VALUE (0); 197287499Smav } 198229997Sken 199229997Sken /* 200229997Sken * This width goes beyond the end-of-region, back off to 201229997Sken * previous access 202229997Sken */ 203229997Sken ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 204229997Sken "Backing off to previous optimal access width of %u\n", 205229997Sken MinimumAccessWidth)); 206229997Sken return_VALUE (MinimumAccessWidth); 207229997Sken } 208229997Sken } 209229997Sken 210229997Sken /* 211229997Sken * Could not read/write field with one operation, 212229997Sken * just use max access width 213229997Sken */ 214229997Sken ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 215229997Sken "Cannot access field in one operation, using width 8\n")); 216229997Sken return_VALUE (8); 217229997Sken} 218229997Sken#endif /* ACPI_UNDER_DEVELOPMENT */ 219229997Sken 220287499Smav 221264886Smav/******************************************************************************* 222229997Sken * 223229997Sken * FUNCTION: AcpiExDecodeFieldAccess 224229997Sken * 225229997Sken * PARAMETERS: ObjDesc - Field object 226229997Sken * FieldFlags - Encoded fieldflags (contains access bits) 227287499Smav * ReturnByteAlignment - Where the byte alignment is returned 228264886Smav * 229287499Smav * RETURN: Field granularity (8, 16, 32 or 64) and 230264886Smav * ByteAlignment (1, 2, 3, or 4) 231288215Smav * 232264886Smav * DESCRIPTION: Decode the AccessType bits of a field definition. 233264886Smav * 234288215Smav ******************************************************************************/ 235264886Smav 236264886Smavstatic UINT32 237264886SmavAcpiExDecodeFieldAccess ( 238264886Smav ACPI_OPERAND_OBJECT *ObjDesc, 239275058Smav UINT8 FieldFlags, 240275058Smav UINT32 *ReturnByteAlignment) 241275058Smav{ 242275058Smav UINT32 Access; 243267519Smav UINT32 ByteAlignment; 244267877Smav UINT32 BitLength; 245264886Smav 246264886Smav 247267877Smav ACPI_FUNCTION_TRACE (ExDecodeFieldAccess); 248264886Smav 249264886Smav 250264886Smav Access = (FieldFlags & AML_FIELD_ACCESS_TYPE_MASK); 251264886Smav 252275009Smav switch (Access) 253275058Smav { 254275058Smav case AML_FIELD_ACCESS_ANY: 255275058Smav 256229997Sken#ifdef ACPI_UNDER_DEVELOPMENT 257229997Sken ByteAlignment = 258229997Sken AcpiExGenerateAccess (ObjDesc->CommonField.StartFieldBitOffset, 259229997Sken ObjDesc->CommonField.BitLength, 260229997Sken 0xFFFFFFFF /* Temp until we pass RegionLength as parameter */); 261229997Sken BitLength = ByteAlignment * 8; 262229997Sken#endif 263229997Sken 264229997Sken ByteAlignment = 1; 265229997Sken BitLength = 8; 266229997Sken break; 267229997Sken 268229997Sken case AML_FIELD_ACCESS_BYTE: 269267537Smav case AML_FIELD_ACCESS_BUFFER: /* ACPI 2.0 (SMBus Buffer) */ 270229997Sken ByteAlignment = 1; 271229997Sken BitLength = 8; 272229997Sken break; 273229997Sken 274229997Sken case AML_FIELD_ACCESS_WORD: 275229997Sken ByteAlignment = 2; 276287499Smav BitLength = 16; 277267537Smav break; 278229997Sken 279287499Smav case AML_FIELD_ACCESS_DWORD: 280267519Smav ByteAlignment = 4; 281267537Smav BitLength = 32; 282267537Smav break; 283267537Smav 284267537Smav case AML_FIELD_ACCESS_QWORD: /* ACPI 2.0 */ 285267537Smav ByteAlignment = 8; 286267537Smav BitLength = 64; 287267519Smav break; 288287499Smav 289264886Smav default: 290264886Smav /* Invalid field access type */ 291264886Smav 292229997Sken ACPI_ERROR ((AE_INFO, 293264886Smav "Unknown field access type 0x%X", 294264886Smav Access)); 295264886Smav return_UINT32 (0); 296264886Smav } 297264886Smav 298264886Smav if (ObjDesc->Common.Type == ACPI_TYPE_BUFFER_FIELD) 299264886Smav { 300264886Smav /* 301264886Smav * BufferField access can be on any byte boundary, so the 302229997Sken * ByteAlignment is always 1 byte -- regardless of any ByteAlignment 303264886Smav * implied by the field access type. 304267519Smav */ 305229997Sken ByteAlignment = 1; 306264886Smav } 307264886Smav 308229997Sken *ReturnByteAlignment = ByteAlignment; 309264886Smav return_UINT32 (BitLength); 310229997Sken} 311229997Sken 312264886Smav 313229997Sken/******************************************************************************* 314275953Smav * 315264886Smav * FUNCTION: AcpiExPrepCommonFieldObject 316229997Sken * 317229997Sken * PARAMETERS: ObjDesc - The field object 318264886Smav * FieldFlags - Access, LockRule, and UpdateRule. 319264886Smav * The format of a FieldFlag is described 320229997Sken * in the ACPI specification 321264886Smav * FieldAttribute - Special attributes (not used) 322229997Sken * FieldBitPosition - Field start position 323264886Smav * FieldBitLength - Field length in number of bits 324264886Smav * 325264886Smav * RETURN: Status 326264886Smav * 327229997Sken * DESCRIPTION: Initialize the areas of the field object that are common 328267514Smav * to the various types of fields. Note: This is very "sensitive" 329267514Smav * code because we are solving the general case for field 330264886Smav * alignment. 331264886Smav * 332264886Smav ******************************************************************************/ 333267519Smav 334229997SkenACPI_STATUS 335288215SmavAcpiExPrepCommonFieldObject ( 336229997Sken ACPI_OPERAND_OBJECT *ObjDesc, 337229997Sken UINT8 FieldFlags, 338264886Smav UINT8 FieldAttribute, 339229997Sken UINT32 FieldBitPosition, 340264886Smav UINT32 FieldBitLength) 341264886Smav{ 342264886Smav UINT32 AccessBitWidth; 343264886Smav UINT32 ByteAlignment; 344264886Smav UINT32 NearestByteAddress; 345264886Smav 346264886Smav 347264886Smav ACPI_FUNCTION_TRACE (ExPrepCommonFieldObject); 348264886Smav 349264886Smav 350267877Smav /* 351264886Smav * Note: the structure being initialized is the 352264886Smav * ACPI_COMMON_FIELD_INFO; No structure fields outside of the common 353264886Smav * area are initialized by this procedure. 354264886Smav */ 355264886Smav ObjDesc->CommonField.FieldFlags = FieldFlags; 356267877Smav ObjDesc->CommonField.Attribute = FieldAttribute; 357264886Smav ObjDesc->CommonField.BitLength = FieldBitLength; 358267877Smav 359264886Smav /* 360264886Smav * Decode the access type so we can compute offsets. The access type gives 361264886Smav * two pieces of information - the width of each field access and the 362264886Smav * necessary ByteAlignment (address granularity) of the access. 363264886Smav * 364264886Smav * For AnyAcc, the AccessBitWidth is the largest width that is both 365264886Smav * necessary and possible in an attempt to access the whole field in one 366264886Smav * I/O operation. However, for AnyAcc, the ByteAlignment is always one 367264886Smav * byte. 368267877Smav * 369229997Sken * For all Buffer Fields, the ByteAlignment is always one byte. 370229997Sken * 371229997Sken * For all other access types (Byte, Word, Dword, Qword), the Bitwidth is 372229997Sken * the same (equivalent) as the ByteAlignment. 373229997Sken */ 374229997Sken AccessBitWidth = AcpiExDecodeFieldAccess (ObjDesc, FieldFlags, 375288220Smav &ByteAlignment); 376288220Smav if (!AccessBitWidth) 377229997Sken { 378229997Sken return_ACPI_STATUS (AE_AML_OPERAND_VALUE); 379229997Sken } 380229997Sken 381288220Smav /* Setup width (access granularity) fields (values are: 1, 2, 4, 8) */ 382229997Sken 383229997Sken ObjDesc->CommonField.AccessByteWidth = (UINT8) 384229997Sken ACPI_DIV_8 (AccessBitWidth); 385287499Smav 386229997Sken /* 387229997Sken * BaseByteOffset is the address of the start of the field within the 388229997Sken * region. It is the byte address of the first *datum* (field-width data 389229997Sken * unit) of the field. (i.e., the first datum that contains at least the 390232604Strasz * first *bit* of the field.) 391232604Strasz * 392232604Strasz * Note: ByteAlignment is always either equal to the AccessBitWidth or 8 393229997Sken * (Byte access), and it defines the addressing granularity of the parent 394229997Sken * region or buffer. 395229997Sken */ 396229997Sken NearestByteAddress = 397229997Sken ACPI_ROUND_BITS_DOWN_TO_BYTES (FieldBitPosition); 398229997Sken ObjDesc->CommonField.BaseByteOffset = (UINT32) 399229997Sken ACPI_ROUND_DOWN (NearestByteAddress, ByteAlignment); 400229997Sken 401229997Sken /* 402229997Sken * StartFieldBitOffset is the offset of the first bit of the field within 403229997Sken * a field datum. 404229997Sken */ 405229997Sken ObjDesc->CommonField.StartFieldBitOffset = (UINT8) 406229997Sken (FieldBitPosition - ACPI_MUL_8 (ObjDesc->CommonField.BaseByteOffset)); 407229997Sken 408229997Sken return_ACPI_STATUS (AE_OK); 409229997Sken} 410229997Sken 411229997Sken 412229997Sken/******************************************************************************* 413229997Sken * 414229997Sken * FUNCTION: AcpiExPrepFieldValue 415229997Sken * 416229997Sken * PARAMETERS: Info - Contains all field creation info 417229997Sken * 418229997Sken * RETURN: Status 419229997Sken * 420229997Sken * DESCRIPTION: Construct an object of type ACPI_OPERAND_OBJECT with a 421287499Smav * subtype of DefField and connect it to the parent Node. 422229997Sken * 423229997Sken ******************************************************************************/ 424229997Sken 425229997SkenACPI_STATUS 426229997SkenAcpiExPrepFieldValue ( 427229997Sken ACPI_CREATE_FIELD_INFO *Info) 428229997Sken{ 429229997Sken ACPI_OPERAND_OBJECT *ObjDesc; 430229997Sken ACPI_OPERAND_OBJECT *SecondDesc = NULL; 431229997Sken ACPI_STATUS Status; 432287499Smav UINT32 AccessByteWidth; 433229997Sken UINT32 Type; 434229997Sken 435229997Sken 436229997Sken ACPI_FUNCTION_TRACE (ExPrepFieldValue); 437229997Sken 438229997Sken 439229997Sken /* Parameter validation */ 440229997Sken 441229997Sken if (Info->FieldType != ACPI_TYPE_LOCAL_INDEX_FIELD) 442229997Sken { 443229997Sken if (!Info->RegionNode) 444229997Sken { 445229997Sken ACPI_ERROR ((AE_INFO, "Null RegionNode")); 446229997Sken return_ACPI_STATUS (AE_AML_NO_OPERAND); 447229997Sken } 448229997Sken 449229997Sken Type = AcpiNsGetType (Info->RegionNode); 450229997Sken if (Type != ACPI_TYPE_REGION) 451229997Sken { 452287499Smav ACPI_ERROR ((AE_INFO, "Needed Region, found type 0x%X (%s)", 453229997Sken Type, AcpiUtGetTypeName (Type))); 454229997Sken 455229997Sken return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 456229997Sken } 457252569Smav } 458252569Smav 459252569Smav /* Allocate a new field object */ 460229997Sken 461229997Sken ObjDesc = AcpiUtCreateInternalObject (Info->FieldType); 462229997Sken if (!ObjDesc) 463229997Sken { 464229997Sken return_ACPI_STATUS (AE_NO_MEMORY); 465229997Sken } 466288220Smav 467229997Sken /* Initialize areas of the object that are common to all fields */ 468229997Sken 469229997Sken ObjDesc->CommonField.Node = Info->FieldNode; 470229997Sken Status = AcpiExPrepCommonFieldObject (ObjDesc, 471229997Sken Info->FieldFlags, Info->Attribute, 472229997Sken Info->FieldBitPosition, Info->FieldBitLength); 473229997Sken if (ACPI_FAILURE (Status)) 474229997Sken { 475229997Sken AcpiUtDeleteObjectDesc (ObjDesc); 476229997Sken return_ACPI_STATUS (Status); 477229997Sken } 478229997Sken 479229997Sken /* Initialize areas of the object that are specific to the field type */ 480229997Sken 481229997Sken switch (Info->FieldType) 482229997Sken { 483229997Sken case ACPI_TYPE_LOCAL_REGION_FIELD: 484229997Sken 485264886Smav ObjDesc->Field.RegionObj = AcpiNsGetAttachedObject (Info->RegionNode); 486287670Smav 487264886Smav /* Fields specific to GenericSerialBus fields */ 488287499Smav 489267877Smav ObjDesc->Field.AccessLength = Info->AccessLength; 490229997Sken 491264886Smav if (Info->ConnectionNode) 492229997Sken { 493229997Sken SecondDesc = Info->ConnectionNode->Object; 494229997Sken if (!(SecondDesc->Common.Flags & AOPOBJ_DATA_VALID)) 495229997Sken { 496229997Sken Status = AcpiDsGetBufferArguments (SecondDesc); 497229997Sken if (ACPI_FAILURE (Status)) 498229997Sken { 499229997Sken AcpiUtDeleteObjectDesc (ObjDesc); 500229997Sken return_ACPI_STATUS (Status); 501229997Sken } 502229997Sken } 503287499Smav 504229997Sken ObjDesc->Field.ResourceBuffer = SecondDesc->Buffer.Pointer; 505229997Sken ObjDesc->Field.ResourceLength = (UINT16) SecondDesc->Buffer.Length; 506287499Smav } 507229997Sken else if (Info->ResourceBuffer) 508267481Smav { 509229997Sken ObjDesc->Field.ResourceBuffer = Info->ResourceBuffer; 510287499Smav ObjDesc->Field.ResourceLength = Info->ResourceLength; 511229997Sken } 512229997Sken 513229997Sken /* Allow full data read from EC address space */ 514229997Sken 515287499Smav if ((ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_EC) && 516287499Smav (ObjDesc->CommonField.BitLength > 8)) 517287499Smav { 518287500Smav AccessByteWidth = ACPI_ROUND_BITS_UP_TO_BYTES ( 519287499Smav ObjDesc->CommonField.BitLength); 520264886Smav 521287499Smav /* Maximum byte width supported is 255 */ 522229997Sken 523229997Sken if (AccessByteWidth < 256) 524287499Smav { 525229997Sken ObjDesc->CommonField.AccessByteWidth = (UINT8) AccessByteWidth; 526287499Smav } 527287499Smav } 528287621Smav 529287621Smav /* An additional reference for the container */ 530287621Smav 531287621Smav AcpiUtAddReference (ObjDesc->Field.RegionObj); 532287621Smav 533287621Smav ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 534287621Smav "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n", 535229997Sken ObjDesc->Field.StartFieldBitOffset, ObjDesc->Field.BaseByteOffset, 536287499Smav ObjDesc->Field.AccessByteWidth, ObjDesc->Field.RegionObj)); 537287499Smav break; 538287499Smav 539287499Smav 540287499Smav case ACPI_TYPE_LOCAL_BANK_FIELD: 541287499Smav 542229997Sken ObjDesc->BankField.Value = Info->BankValue; 543229997Sken ObjDesc->BankField.RegionObj = 544287499Smav AcpiNsGetAttachedObject (Info->RegionNode); 545229997Sken ObjDesc->BankField.BankObj = 546229997Sken AcpiNsGetAttachedObject (Info->RegisterNode); 547287499Smav 548287499Smav /* An additional reference for the attached objects */ 549287499Smav 550287499Smav AcpiUtAddReference (ObjDesc->BankField.RegionObj); 551287499Smav AcpiUtAddReference (ObjDesc->BankField.BankObj); 552229997Sken 553229997Sken ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 554229997Sken "Bank Field: BitOff %X, Off %X, Gran %X, Region %p, BankReg %p\n", 555287499Smav ObjDesc->BankField.StartFieldBitOffset, 556229997Sken ObjDesc->BankField.BaseByteOffset, 557229997Sken ObjDesc->Field.AccessByteWidth, 558287499Smav ObjDesc->BankField.RegionObj, 559267481Smav ObjDesc->BankField.BankObj)); 560287499Smav 561287499Smav /* 562287499Smav * Remember location in AML stream of the field unit 563287499Smav * opcode and operands -- since the BankValue 564287499Smav * operands must be evaluated. 565287499Smav */ 566287499Smav SecondDesc = ObjDesc->Common.NextObject; 567287499Smav SecondDesc->Extra.AmlStart = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, 568287499Smav Info->DataRegisterNode)->Named.Data; 569287499Smav SecondDesc->Extra.AmlLength = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, 570287499Smav Info->DataRegisterNode)->Named.Length; 571287499Smav 572254759Strasz break; 573229997Sken 574287499Smav 575287499Smav case ACPI_TYPE_LOCAL_INDEX_FIELD: 576229997Sken 577287499Smav /* Get the Index and Data registers */ 578229997Sken 579287499Smav ObjDesc->IndexField.IndexObj = 580287499Smav AcpiNsGetAttachedObject (Info->RegisterNode); 581287499Smav ObjDesc->IndexField.DataObj = 582229997Sken AcpiNsGetAttachedObject (Info->DataRegisterNode); 583229997Sken 584229997Sken if (!ObjDesc->IndexField.DataObj || !ObjDesc->IndexField.IndexObj) 585287499Smav { 586287499Smav ACPI_ERROR ((AE_INFO, "Null Index Object during field prep")); 587229997Sken AcpiUtDeleteObjectDesc (ObjDesc); 588229997Sken return_ACPI_STATUS (AE_AML_INTERNAL); 589229997Sken } 590275953Smav 591229997Sken /* An additional reference for the attached objects */ 592287499Smav 593287499Smav AcpiUtAddReference (ObjDesc->IndexField.DataObj); 594275953Smav AcpiUtAddReference (ObjDesc->IndexField.IndexObj); 595229997Sken 596229997Sken /* 597229997Sken * April 2006: Changed to match MS behavior 598287499Smav * 599287499Smav * The value written to the Index register is the byte offset of the 600229997Sken * target field in units of the granularity of the IndexField 601229997Sken * 602229997Sken * Previously, the value was calculated as an index in terms of the 603275953Smav * width of the Data register, as below: 604229997Sken * 605287499Smav * ObjDesc->IndexField.Value = (UINT32) 606287499Smav * (Info->FieldBitPosition / ACPI_MUL_8 ( 607275953Smav * ObjDesc->Field.AccessByteWidth)); 608229997Sken * 609229997Sken * February 2006: Tried value as a byte offset: 610264886Smav * ObjDesc->IndexField.Value = (UINT32) 611267877Smav * ACPI_DIV_8 (Info->FieldBitPosition); 612264886Smav */ 613264886Smav ObjDesc->IndexField.Value = (UINT32) ACPI_ROUND_DOWN ( 614264886Smav ACPI_DIV_8 (Info->FieldBitPosition), 615264886Smav ObjDesc->IndexField.AccessByteWidth); 616264886Smav 617264886Smav ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 618264886Smav "IndexField: BitOff %X, Off %X, Value %X, Gran %X, Index %p, Data %p\n", 619264886Smav ObjDesc->IndexField.StartFieldBitOffset, 620264886Smav ObjDesc->IndexField.BaseByteOffset, 621264886Smav ObjDesc->IndexField.Value, 622264886Smav ObjDesc->Field.AccessByteWidth, 623264886Smav ObjDesc->IndexField.IndexObj, 624264886Smav ObjDesc->IndexField.DataObj)); 625264886Smav break; 626264886Smav 627264886Smav default: 628264886Smav /* No other types should get here */ 629264886Smav break; 630264886Smav } 631229997Sken 632229997Sken /* 633229997Sken * Store the constructed descriptor (ObjDesc) into the parent Node, 634229997Sken * preserving the current type of that NamedObj. 635229997Sken */ 636287499Smav Status = AcpiNsAttachObject (Info->FieldNode, ObjDesc, 637229997Sken AcpiNsGetType (Info->FieldNode)); 638229997Sken 639229997Sken ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Set NamedObj %p [%4.4s], ObjDesc %p\n", 640229997Sken Info->FieldNode, AcpiUtGetNodeName (Info->FieldNode), ObjDesc)); 641229997Sken 642229997Sken /* Remove local reference to the object */ 643229997Sken 644229997Sken AcpiUtRemoveReference (ObjDesc); 645229997Sken return_ACPI_STATUS (Status); 646229997Sken} 647229997Sken