167754Smsmith/****************************************************************************** 267754Smsmith * 3306536Sjkim * Module Name: exprep - ACPI AML field prep utilities 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 7217365Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 970243Smsmith * All rights reserved. 1067754Smsmith * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 2567754Smsmith * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 2967754Smsmith * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 4367754Smsmith 44193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 45193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 46193341Sjkim#include <contrib/dev/acpica/include/acinterp.h> 47193341Sjkim#include <contrib/dev/acpica/include/amlcode.h> 48193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 49228110Sjkim#include <contrib/dev/acpica/include/acdispat.h> 5067754Smsmith 5167754Smsmith 5277424Smsmith#define _COMPONENT ACPI_EXECUTER 5391116Smsmith ACPI_MODULE_NAME ("exprep") 5467754Smsmith 55151937Sjkim/* Local prototypes */ 5667754Smsmith 57151937Sjkimstatic UINT32 58151937SjkimAcpiExDecodeFieldAccess ( 59151937Sjkim ACPI_OPERAND_OBJECT *ObjDesc, 60151937Sjkim UINT8 FieldFlags, 61151937Sjkim UINT32 *ReturnByteAlignment); 62151937Sjkim 63151937Sjkim 64123315Snjl#ifdef ACPI_UNDER_DEVELOPMENT 65151937Sjkim 66151937Sjkimstatic UINT32 67151937SjkimAcpiExGenerateAccess ( 68151937Sjkim UINT32 FieldBitOffset, 69151937Sjkim UINT32 FieldBitLength, 70151937Sjkim UINT32 RegionLength); 71151937Sjkim 72306536Sjkim 7367754Smsmith/******************************************************************************* 7467754Smsmith * 75123315Snjl * FUNCTION: AcpiExGenerateAccess 76123315Snjl * 77123315Snjl * PARAMETERS: FieldBitOffset - Start of field within parent region/buffer 78123315Snjl * FieldBitLength - Length of field in bits 79123315Snjl * RegionLength - Length of parent in bytes 80123315Snjl * 81123315Snjl * RETURN: Field granularity (8, 16, 32 or 64) and 82123315Snjl * ByteAlignment (1, 2, 3, or 4) 83123315Snjl * 84123315Snjl * DESCRIPTION: Generate an optimal access width for fields defined with the 85123315Snjl * AnyAcc keyword. 86123315Snjl * 87123315Snjl * NOTE: Need to have the RegionLength in order to check for boundary 88241973Sjkim * conditions (end-of-region). However, the RegionLength is a deferred 89241973Sjkim * operation. Therefore, to complete this implementation, the generation 90123315Snjl * of this access width must be deferred until the region length has 91123315Snjl * been evaluated. 92123315Snjl * 93123315Snjl ******************************************************************************/ 94123315Snjl 95123315Snjlstatic UINT32 96123315SnjlAcpiExGenerateAccess ( 97123315Snjl UINT32 FieldBitOffset, 98123315Snjl UINT32 FieldBitLength, 99123315Snjl UINT32 RegionLength) 100123315Snjl{ 101123315Snjl UINT32 FieldByteLength; 102123315Snjl UINT32 FieldByteOffset; 103123315Snjl UINT32 FieldByteEndOffset; 104123315Snjl UINT32 AccessByteWidth; 105123315Snjl UINT32 FieldStartOffset; 106123315Snjl UINT32 FieldEndOffset; 107123315Snjl UINT32 MinimumAccessWidth = 0xFFFFFFFF; 108123315Snjl UINT32 MinimumAccesses = 0xFFFFFFFF; 109123315Snjl UINT32 Accesses; 110123315Snjl 111123315Snjl 112167802Sjkim ACPI_FUNCTION_TRACE (ExGenerateAccess); 113123315Snjl 114123315Snjl 115123315Snjl /* Round Field start offset and length to "minimal" byte boundaries */ 116123315Snjl 117306536Sjkim FieldByteOffset = ACPI_DIV_8 ( 118306536Sjkim ACPI_ROUND_DOWN (FieldBitOffset, 8)); 119123315Snjl 120306536Sjkim FieldByteEndOffset = ACPI_DIV_8 ( 121306536Sjkim ACPI_ROUND_UP (FieldBitLength + FieldBitOffset, 8)); 122306536Sjkim 123306536Sjkim FieldByteLength = FieldByteEndOffset - FieldByteOffset; 124306536Sjkim 125123315Snjl ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 126210976Sjkim "Bit length %u, Bit offset %u\n", 127210976Sjkim FieldBitLength, FieldBitOffset)); 128151937Sjkim 129123315Snjl ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 130210976Sjkim "Byte Length %u, Byte Offset %u, End Offset %u\n", 131210976Sjkim FieldByteLength, FieldByteOffset, FieldByteEndOffset)); 132123315Snjl 133123315Snjl /* 134123315Snjl * Iterative search for the maximum access width that is both aligned 135123315Snjl * and does not go beyond the end of the region 136123315Snjl * 137123315Snjl * Start at ByteAcc and work upwards to QwordAcc max. (1,2,4,8 bytes) 138123315Snjl */ 139123315Snjl for (AccessByteWidth = 1; AccessByteWidth <= 8; AccessByteWidth <<= 1) 140123315Snjl { 141123315Snjl /* 142151937Sjkim * 1) Round end offset up to next access boundary and make sure that 143151937Sjkim * this does not go beyond the end of the parent region. 144151937Sjkim * 2) When the Access width is greater than the FieldByteLength, we 145151937Sjkim * are done. (This does not optimize for the perfectly aligned 146151937Sjkim * case yet). 147123315Snjl */ 148306536Sjkim if (ACPI_ROUND_UP (FieldByteEndOffset, AccessByteWidth) <= 149306536Sjkim RegionLength) 150123315Snjl { 151151937Sjkim FieldStartOffset = 152151937Sjkim ACPI_ROUND_DOWN (FieldByteOffset, AccessByteWidth) / 153151937Sjkim AccessByteWidth; 154123315Snjl 155151937Sjkim FieldEndOffset = 156151937Sjkim ACPI_ROUND_UP ((FieldByteLength + FieldByteOffset), 157151937Sjkim AccessByteWidth) / AccessByteWidth; 158151937Sjkim 159151937Sjkim Accesses = FieldEndOffset - FieldStartOffset; 160151937Sjkim 161123315Snjl ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 162210976Sjkim "AccessWidth %u end is within region\n", AccessByteWidth)); 163151937Sjkim 164123315Snjl ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 165210976Sjkim "Field Start %u, Field End %u -- requires %u accesses\n", 166210976Sjkim FieldStartOffset, FieldEndOffset, Accesses)); 167123315Snjl 168123315Snjl /* Single access is optimal */ 169123315Snjl 170123315Snjl if (Accesses <= 1) 171123315Snjl { 172123315Snjl ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 173306536Sjkim "Entire field can be accessed " 174306536Sjkim "with one operation of size %u\n", 175151937Sjkim AccessByteWidth)); 176123315Snjl return_VALUE (AccessByteWidth); 177123315Snjl } 178123315Snjl 179123315Snjl /* 180123315Snjl * Fits in the region, but requires more than one read/write. 181123315Snjl * try the next wider access on next iteration 182123315Snjl */ 183123315Snjl if (Accesses < MinimumAccesses) 184123315Snjl { 185306536Sjkim MinimumAccesses = Accesses; 186123315Snjl MinimumAccessWidth = AccessByteWidth; 187123315Snjl } 188123315Snjl } 189123315Snjl else 190123315Snjl { 191123315Snjl ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 192306536Sjkim "AccessWidth %u end is NOT within region\n", 193306536Sjkim AccessByteWidth)); 194123315Snjl if (AccessByteWidth == 1) 195123315Snjl { 196123315Snjl ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 197210976Sjkim "Field goes beyond end-of-region!\n")); 198151937Sjkim 199151937Sjkim /* Field does not fit in the region at all */ 200151937Sjkim 201151937Sjkim return_VALUE (0); 202123315Snjl } 203123315Snjl 204151937Sjkim /* 205151937Sjkim * This width goes beyond the end-of-region, back off to 206151937Sjkim * previous access 207151937Sjkim */ 208123315Snjl ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 209210976Sjkim "Backing off to previous optimal access width of %u\n", 210210976Sjkim MinimumAccessWidth)); 211123315Snjl return_VALUE (MinimumAccessWidth); 212123315Snjl } 213123315Snjl } 214123315Snjl 215151937Sjkim /* 216151937Sjkim * Could not read/write field with one operation, 217151937Sjkim * just use max access width 218151937Sjkim */ 219123315Snjl ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 220210976Sjkim "Cannot access field in one operation, using width 8\n")); 221306536Sjkim 222123315Snjl return_VALUE (8); 223123315Snjl} 224123315Snjl#endif /* ACPI_UNDER_DEVELOPMENT */ 225123315Snjl 226123315Snjl 227123315Snjl/******************************************************************************* 228123315Snjl * 22987031Smsmith * FUNCTION: AcpiExDecodeFieldAccess 23067754Smsmith * 231151937Sjkim * PARAMETERS: ObjDesc - Field object 232151937Sjkim * FieldFlags - Encoded fieldflags (contains access bits) 233151937Sjkim * ReturnByteAlignment - Where the byte alignment is returned 23467754Smsmith * 23587031Smsmith * RETURN: Field granularity (8, 16, 32 or 64) and 23687031Smsmith * ByteAlignment (1, 2, 3, or 4) 23767754Smsmith * 23867754Smsmith * DESCRIPTION: Decode the AccessType bits of a field definition. 23967754Smsmith * 24067754Smsmith ******************************************************************************/ 24167754Smsmith 24269450Smsmithstatic UINT32 24387031SmsmithAcpiExDecodeFieldAccess ( 24487031Smsmith ACPI_OPERAND_OBJECT *ObjDesc, 24587031Smsmith UINT8 FieldFlags, 24687031Smsmith UINT32 *ReturnByteAlignment) 24767754Smsmith{ 24887031Smsmith UINT32 Access; 249123315Snjl UINT32 ByteAlignment; 250123315Snjl UINT32 BitLength; 25167754Smsmith 25282367Smsmith 253167802Sjkim ACPI_FUNCTION_TRACE (ExDecodeFieldAccess); 25487031Smsmith 25587031Smsmith 25687031Smsmith Access = (FieldFlags & AML_FIELD_ACCESS_TYPE_MASK); 25787031Smsmith 25867754Smsmith switch (Access) 25967754Smsmith { 26087031Smsmith case AML_FIELD_ACCESS_ANY: 26177424Smsmith 262123315Snjl#ifdef ACPI_UNDER_DEVELOPMENT 263151937Sjkim ByteAlignment = 264151937Sjkim AcpiExGenerateAccess (ObjDesc->CommonField.StartFieldBitOffset, 265151937Sjkim ObjDesc->CommonField.BitLength, 266151937Sjkim 0xFFFFFFFF /* Temp until we pass RegionLength as parameter */); 267123315Snjl BitLength = ByteAlignment * 8; 268123315Snjl#endif 269123315Snjl 27087031Smsmith ByteAlignment = 1; 27192388Smsmith BitLength = 8; 27287031Smsmith break; 27377424Smsmith 27487031Smsmith case AML_FIELD_ACCESS_BYTE: 275107325Siwasaki case AML_FIELD_ACCESS_BUFFER: /* ACPI 2.0 (SMBus Buffer) */ 276250838Sjkim 27787031Smsmith ByteAlignment = 1; 278107325Siwasaki BitLength = 8; 27967754Smsmith break; 28067754Smsmith 28187031Smsmith case AML_FIELD_ACCESS_WORD: 282250838Sjkim 28387031Smsmith ByteAlignment = 2; 284107325Siwasaki BitLength = 16; 28567754Smsmith break; 28667754Smsmith 28787031Smsmith case AML_FIELD_ACCESS_DWORD: 288250838Sjkim 28987031Smsmith ByteAlignment = 4; 290107325Siwasaki BitLength = 32; 29167754Smsmith break; 29267754Smsmith 293107325Siwasaki case AML_FIELD_ACCESS_QWORD: /* ACPI 2.0 */ 294250838Sjkim 29587031Smsmith ByteAlignment = 8; 296107325Siwasaki BitLength = 64; 29767754Smsmith break; 29867754Smsmith 29967754Smsmith default: 300250838Sjkim 30167754Smsmith /* Invalid field access type */ 30267754Smsmith 303167802Sjkim ACPI_ERROR ((AE_INFO, 304204773Sjkim "Unknown field access type 0x%X", 30567754Smsmith Access)); 306306536Sjkim 307246849Sjkim return_UINT32 (0); 30867754Smsmith } 30987031Smsmith 310193267Sjkim if (ObjDesc->Common.Type == ACPI_TYPE_BUFFER_FIELD) 31187031Smsmith { 31287031Smsmith /* 31387031Smsmith * BufferField access can be on any byte boundary, so the 31487031Smsmith * ByteAlignment is always 1 byte -- regardless of any ByteAlignment 31587031Smsmith * implied by the field access type. 31687031Smsmith */ 31787031Smsmith ByteAlignment = 1; 31887031Smsmith } 31987031Smsmith 32087031Smsmith *ReturnByteAlignment = ByteAlignment; 321246849Sjkim return_UINT32 (BitLength); 32267754Smsmith} 32367754Smsmith 32467754Smsmith 32567754Smsmith/******************************************************************************* 32667754Smsmith * 32777424Smsmith * FUNCTION: AcpiExPrepCommonFieldObject 32867754Smsmith * 32967754Smsmith * PARAMETERS: ObjDesc - The field object 33077424Smsmith * FieldFlags - Access, LockRule, and UpdateRule. 33167754Smsmith * The format of a FieldFlag is described 33267754Smsmith * in the ACPI specification 333151937Sjkim * FieldAttribute - Special attributes (not used) 33477424Smsmith * FieldBitPosition - Field start position 33577424Smsmith * FieldBitLength - Field length in number of bits 33667754Smsmith * 33767754Smsmith * RETURN: Status 33867754Smsmith * 33967754Smsmith * DESCRIPTION: Initialize the areas of the field object that are common 340241973Sjkim * to the various types of fields. Note: This is very "sensitive" 34187031Smsmith * code because we are solving the general case for field 34287031Smsmith * alignment. 34367754Smsmith * 34467754Smsmith ******************************************************************************/ 34567754Smsmith 34677424SmsmithACPI_STATUS 34777424SmsmithAcpiExPrepCommonFieldObject ( 34867754Smsmith ACPI_OPERAND_OBJECT *ObjDesc, 34967754Smsmith UINT8 FieldFlags, 35087031Smsmith UINT8 FieldAttribute, 35177424Smsmith UINT32 FieldBitPosition, 35277424Smsmith UINT32 FieldBitLength) 35367754Smsmith{ 35477424Smsmith UINT32 AccessBitWidth; 35587031Smsmith UINT32 ByteAlignment; 35677424Smsmith UINT32 NearestByteAddress; 35767754Smsmith 35867754Smsmith 359167802Sjkim ACPI_FUNCTION_TRACE (ExPrepCommonFieldObject); 36067754Smsmith 36167754Smsmith 36267754Smsmith /* 36367754Smsmith * Note: the structure being initialized is the 36487031Smsmith * ACPI_COMMON_FIELD_INFO; No structure fields outside of the common 36587031Smsmith * area are initialized by this procedure. 36667754Smsmith */ 36787031Smsmith ObjDesc->CommonField.FieldFlags = FieldFlags; 36887031Smsmith ObjDesc->CommonField.Attribute = FieldAttribute; 36991116Smsmith ObjDesc->CommonField.BitLength = FieldBitLength; 37067754Smsmith 37183174Smsmith /* 372241973Sjkim * Decode the access type so we can compute offsets. The access type gives 37380062Smsmith * two pieces of information - the width of each field access and the 37491116Smsmith * necessary ByteAlignment (address granularity) of the access. 37591116Smsmith * 376102550Siwasaki * For AnyAcc, the AccessBitWidth is the largest width that is both 37799146Siwasaki * necessary and possible in an attempt to access the whole field in one 378241973Sjkim * I/O operation. However, for AnyAcc, the ByteAlignment is always one 37999146Siwasaki * byte. 38091116Smsmith * 38187031Smsmith * For all Buffer Fields, the ByteAlignment is always one byte. 38287031Smsmith * 383102550Siwasaki * For all other access types (Byte, Word, Dword, Qword), the Bitwidth is 38499146Siwasaki * the same (equivalent) as the ByteAlignment. 38580062Smsmith */ 386306536Sjkim AccessBitWidth = AcpiExDecodeFieldAccess ( 387306536Sjkim ObjDesc, FieldFlags, &ByteAlignment); 38877424Smsmith if (!AccessBitWidth) 38967754Smsmith { 39067754Smsmith return_ACPI_STATUS (AE_AML_OPERAND_VALUE); 39167754Smsmith } 39267754Smsmith 393210976Sjkim /* Setup width (access granularity) fields (values are: 1, 2, 4, 8) */ 39467754Smsmith 395102550Siwasaki ObjDesc->CommonField.AccessByteWidth = (UINT8) 396210976Sjkim ACPI_DIV_8 (AccessBitWidth); 39767754Smsmith 39883174Smsmith /* 399102550Siwasaki * BaseByteOffset is the address of the start of the field within the 400241973Sjkim * region. It is the byte address of the first *datum* (field-width data 401102550Siwasaki * unit) of the field. (i.e., the first datum that contains at least the 40299146Siwasaki * first *bit* of the field.) 40399146Siwasaki * 404102550Siwasaki * Note: ByteAlignment is always either equal to the AccessBitWidth or 8 405102550Siwasaki * (Byte access), and it defines the addressing granularity of the parent 40699146Siwasaki * region or buffer. 40777424Smsmith */ 408102550Siwasaki NearestByteAddress = 409210976Sjkim ACPI_ROUND_BITS_DOWN_TO_BYTES (FieldBitPosition); 410123315Snjl ObjDesc->CommonField.BaseByteOffset = (UINT32) 411210976Sjkim ACPI_ROUND_DOWN (NearestByteAddress, ByteAlignment); 41277424Smsmith 41377424Smsmith /* 414102550Siwasaki * StartFieldBitOffset is the offset of the first bit of the field within 41599146Siwasaki * a field datum. 41677424Smsmith */ 41799146Siwasaki ObjDesc->CommonField.StartFieldBitOffset = (UINT8) 41899146Siwasaki (FieldBitPosition - ACPI_MUL_8 (ObjDesc->CommonField.BaseByteOffset)); 41977424Smsmith 42067754Smsmith return_ACPI_STATUS (AE_OK); 42167754Smsmith} 42267754Smsmith 42367754Smsmith 42467754Smsmith/******************************************************************************* 42567754Smsmith * 42685756Smsmith * FUNCTION: AcpiExPrepFieldValue 42767754Smsmith * 428151937Sjkim * PARAMETERS: Info - Contains all field creation info 42967754Smsmith * 43067754Smsmith * RETURN: Status 43167754Smsmith * 432238381Sjkim * DESCRIPTION: Construct an object of type ACPI_OPERAND_OBJECT with a 433238381Sjkim * subtype of DefField and connect it to the parent Node. 43467754Smsmith * 43567754Smsmith ******************************************************************************/ 43667754Smsmith 43767754SmsmithACPI_STATUS 43885756SmsmithAcpiExPrepFieldValue ( 43985756Smsmith ACPI_CREATE_FIELD_INFO *Info) 44067754Smsmith{ 44167754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 442193267Sjkim ACPI_OPERAND_OBJECT *SecondDesc = NULL; 443210976Sjkim ACPI_STATUS Status; 444210976Sjkim UINT32 AccessByteWidth; 44567754Smsmith UINT32 Type; 44667754Smsmith 44767754Smsmith 448167802Sjkim ACPI_FUNCTION_TRACE (ExPrepFieldValue); 44967754Smsmith 45067754Smsmith 45167754Smsmith /* Parameter validation */ 45267754Smsmith 453107325Siwasaki if (Info->FieldType != ACPI_TYPE_LOCAL_INDEX_FIELD) 45467754Smsmith { 45585756Smsmith if (!Info->RegionNode) 45685756Smsmith { 457167802Sjkim ACPI_ERROR ((AE_INFO, "Null RegionNode")); 45885756Smsmith return_ACPI_STATUS (AE_AML_NO_OPERAND); 45985756Smsmith } 46067754Smsmith 46185756Smsmith Type = AcpiNsGetType (Info->RegionNode); 46285756Smsmith if (Type != ACPI_TYPE_REGION) 46385756Smsmith { 464210976Sjkim ACPI_ERROR ((AE_INFO, "Needed Region, found type 0x%X (%s)", 46585756Smsmith Type, AcpiUtGetTypeName (Type))); 46685756Smsmith 46785756Smsmith return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 46885756Smsmith } 46967754Smsmith } 47067754Smsmith 47187031Smsmith /* Allocate a new field object */ 47267754Smsmith 47385756Smsmith ObjDesc = AcpiUtCreateInternalObject (Info->FieldType); 47467754Smsmith if (!ObjDesc) 47567754Smsmith { 47667754Smsmith return_ACPI_STATUS (AE_NO_MEMORY); 47767754Smsmith } 47867754Smsmith 47967754Smsmith /* Initialize areas of the object that are common to all fields */ 48067754Smsmith 48187031Smsmith ObjDesc->CommonField.Node = Info->FieldNode; 482210976Sjkim Status = AcpiExPrepCommonFieldObject (ObjDesc, 483306536Sjkim Info->FieldFlags, Info->Attribute, 484306536Sjkim Info->FieldBitPosition, Info->FieldBitLength); 48567754Smsmith if (ACPI_FAILURE (Status)) 48667754Smsmith { 48785756Smsmith AcpiUtDeleteObjectDesc (ObjDesc); 48867754Smsmith return_ACPI_STATUS (Status); 48967754Smsmith } 49067754Smsmith 49185756Smsmith /* Initialize areas of the object that are specific to the field type */ 49267754Smsmith 49385756Smsmith switch (Info->FieldType) 49485756Smsmith { 495107325Siwasaki case ACPI_TYPE_LOCAL_REGION_FIELD: 49667754Smsmith 497151937Sjkim ObjDesc->Field.RegionObj = AcpiNsGetAttachedObject (Info->RegionNode); 49867754Smsmith 499228110Sjkim /* Fields specific to GenericSerialBus fields */ 500228110Sjkim 501228110Sjkim ObjDesc->Field.AccessLength = Info->AccessLength; 502228110Sjkim 503228110Sjkim if (Info->ConnectionNode) 504228110Sjkim { 505228110Sjkim SecondDesc = Info->ConnectionNode->Object; 506228110Sjkim if (!(SecondDesc->Common.Flags & AOPOBJ_DATA_VALID)) 507228110Sjkim { 508228110Sjkim Status = AcpiDsGetBufferArguments (SecondDesc); 509228110Sjkim if (ACPI_FAILURE (Status)) 510228110Sjkim { 511228110Sjkim AcpiUtDeleteObjectDesc (ObjDesc); 512228110Sjkim return_ACPI_STATUS (Status); 513228110Sjkim } 514228110Sjkim } 515228110Sjkim 516306536Sjkim ObjDesc->Field.ResourceBuffer = 517306536Sjkim SecondDesc->Buffer.Pointer; 518306536Sjkim ObjDesc->Field.ResourceLength = 519306536Sjkim (UINT16) SecondDesc->Buffer.Length; 520228110Sjkim } 521228110Sjkim else if (Info->ResourceBuffer) 522228110Sjkim { 523228110Sjkim ObjDesc->Field.ResourceBuffer = Info->ResourceBuffer; 524228110Sjkim ObjDesc->Field.ResourceLength = Info->ResourceLength; 525228110Sjkim } 526228110Sjkim 527281075Sdim ObjDesc->Field.PinNumberIndex = Info->PinNumberIndex; 528281075Sdim 529210976Sjkim /* Allow full data read from EC address space */ 530210976Sjkim 531210976Sjkim if ((ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_EC) && 532210976Sjkim (ObjDesc->CommonField.BitLength > 8)) 533210976Sjkim { 534210976Sjkim AccessByteWidth = ACPI_ROUND_BITS_UP_TO_BYTES ( 535210976Sjkim ObjDesc->CommonField.BitLength); 536210976Sjkim 537210976Sjkim /* Maximum byte width supported is 255 */ 538210976Sjkim 539210976Sjkim if (AccessByteWidth < 256) 540210976Sjkim { 541306536Sjkim ObjDesc->CommonField.AccessByteWidth = 542306536Sjkim (UINT8) AccessByteWidth; 543210976Sjkim } 544210976Sjkim } 545210976Sjkim 54685756Smsmith /* An additional reference for the container */ 54767754Smsmith 54885756Smsmith AcpiUtAddReference (ObjDesc->Field.RegionObj); 54967754Smsmith 55099146Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 551123315Snjl "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n", 552306536Sjkim ObjDesc->Field.StartFieldBitOffset, 553306536Sjkim ObjDesc->Field.BaseByteOffset, 554306536Sjkim ObjDesc->Field.AccessByteWidth, 555306536Sjkim ObjDesc->Field.RegionObj)); 55685756Smsmith break; 55767754Smsmith 558107325Siwasaki case ACPI_TYPE_LOCAL_BANK_FIELD: 55967754Smsmith 560210976Sjkim ObjDesc->BankField.Value = Info->BankValue; 561210976Sjkim ObjDesc->BankField.RegionObj = 562210976Sjkim AcpiNsGetAttachedObject (Info->RegionNode); 563210976Sjkim ObjDesc->BankField.BankObj = 564210976Sjkim AcpiNsGetAttachedObject (Info->RegisterNode); 56567754Smsmith 56685756Smsmith /* An additional reference for the attached objects */ 56767754Smsmith 56885756Smsmith AcpiUtAddReference (ObjDesc->BankField.RegionObj); 56987031Smsmith AcpiUtAddReference (ObjDesc->BankField.BankObj); 57067754Smsmith 571102550Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 572123315Snjl "Bank Field: BitOff %X, Off %X, Gran %X, Region %p, BankReg %p\n", 573102550Siwasaki ObjDesc->BankField.StartFieldBitOffset, 57499146Siwasaki ObjDesc->BankField.BaseByteOffset, 575102550Siwasaki ObjDesc->Field.AccessByteWidth, 57699146Siwasaki ObjDesc->BankField.RegionObj, 57787031Smsmith ObjDesc->BankField.BankObj)); 578193267Sjkim 579193267Sjkim /* 580193267Sjkim * Remember location in AML stream of the field unit 581193267Sjkim * opcode and operands -- since the BankValue 582193267Sjkim * operands must be evaluated. 583193267Sjkim */ 584210976Sjkim SecondDesc = ObjDesc->Common.NextObject; 585210976Sjkim SecondDesc->Extra.AmlStart = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, 586210976Sjkim Info->DataRegisterNode)->Named.Data; 587210976Sjkim SecondDesc->Extra.AmlLength = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, 588210976Sjkim Info->DataRegisterNode)->Named.Length; 589193267Sjkim 59085756Smsmith break; 59167754Smsmith 592107325Siwasaki case ACPI_TYPE_LOCAL_INDEX_FIELD: 59367754Smsmith 594167802Sjkim /* Get the Index and Data registers */ 595167802Sjkim 596210976Sjkim ObjDesc->IndexField.IndexObj = 597210976Sjkim AcpiNsGetAttachedObject (Info->RegisterNode); 598210976Sjkim ObjDesc->IndexField.DataObj = 599210976Sjkim AcpiNsGetAttachedObject (Info->DataRegisterNode); 60067754Smsmith 60185756Smsmith if (!ObjDesc->IndexField.DataObj || !ObjDesc->IndexField.IndexObj) 60285756Smsmith { 603167802Sjkim ACPI_ERROR ((AE_INFO, "Null Index Object during field prep")); 604138287Smarks AcpiUtDeleteObjectDesc (ObjDesc); 60585756Smsmith return_ACPI_STATUS (AE_AML_INTERNAL); 60685756Smsmith } 60767754Smsmith 60885756Smsmith /* An additional reference for the attached objects */ 60967754Smsmith 61085756Smsmith AcpiUtAddReference (ObjDesc->IndexField.DataObj); 61185756Smsmith AcpiUtAddReference (ObjDesc->IndexField.IndexObj); 61267754Smsmith 613167802Sjkim /* 614167802Sjkim * April 2006: Changed to match MS behavior 615167802Sjkim * 616167802Sjkim * The value written to the Index register is the byte offset of the 617167802Sjkim * target field in units of the granularity of the IndexField 618167802Sjkim * 619167802Sjkim * Previously, the value was calculated as an index in terms of the 620167802Sjkim * width of the Data register, as below: 621167802Sjkim * 622167802Sjkim * ObjDesc->IndexField.Value = (UINT32) 623167802Sjkim * (Info->FieldBitPosition / ACPI_MUL_8 ( 624167802Sjkim * ObjDesc->Field.AccessByteWidth)); 625167802Sjkim * 626167802Sjkim * February 2006: Tried value as a byte offset: 627167802Sjkim * ObjDesc->IndexField.Value = (UINT32) 628167802Sjkim * ACPI_DIV_8 (Info->FieldBitPosition); 629167802Sjkim */ 630167802Sjkim ObjDesc->IndexField.Value = (UINT32) ACPI_ROUND_DOWN ( 631167802Sjkim ACPI_DIV_8 (Info->FieldBitPosition), 632167802Sjkim ObjDesc->IndexField.AccessByteWidth); 633167802Sjkim 634102550Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 635306536Sjkim "IndexField: BitOff %X, Off %X, Value %X, " 636306536Sjkim "Gran %X, Index %p, Data %p\n", 637102550Siwasaki ObjDesc->IndexField.StartFieldBitOffset, 63899146Siwasaki ObjDesc->IndexField.BaseByteOffset, 639123315Snjl ObjDesc->IndexField.Value, 640102550Siwasaki ObjDesc->Field.AccessByteWidth, 64199146Siwasaki ObjDesc->IndexField.IndexObj, 64285756Smsmith ObjDesc->IndexField.DataObj)); 64385756Smsmith break; 64499679Siwasaki 64599679Siwasaki default: 646250838Sjkim 64799679Siwasaki /* No other types should get here */ 648250838Sjkim 64999679Siwasaki break; 65067754Smsmith } 65167754Smsmith 65267754Smsmith /* 65377424Smsmith * Store the constructed descriptor (ObjDesc) into the parent Node, 65477424Smsmith * preserving the current type of that NamedObj. 65567754Smsmith */ 656306536Sjkim Status = AcpiNsAttachObject ( 657306536Sjkim Info->FieldNode, ObjDesc, AcpiNsGetType (Info->FieldNode)); 65867754Smsmith 659306536Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 660306536Sjkim "Set NamedObj %p [%4.4s], ObjDesc %p\n", 661210976Sjkim Info->FieldNode, AcpiUtGetNodeName (Info->FieldNode), ObjDesc)); 66267754Smsmith 66385756Smsmith /* Remove local reference to the object */ 66467754Smsmith 66585756Smsmith AcpiUtRemoveReference (ObjDesc); 66667754Smsmith return_ACPI_STATUS (Status); 66767754Smsmith} 668