1a159c266SJung-uk Kim /****************************************************************************** 2a159c266SJung-uk Kim * 3a159c266SJung-uk Kim * Module Name: exfield - ACPI AML (p-code) execution - field manipulation 4a159c266SJung-uk Kim * 5a159c266SJung-uk Kim *****************************************************************************/ 6a159c266SJung-uk Kim 70d84335fSJung-uk Kim /****************************************************************************** 80d84335fSJung-uk Kim * 90d84335fSJung-uk Kim * 1. Copyright Notice 100d84335fSJung-uk Kim * 11*32ac4016SJung-uk Kim * Some or all of this work - Copyright (c) 1999 - 2018, Intel Corp. 12a159c266SJung-uk Kim * All rights reserved. 13a159c266SJung-uk Kim * 140d84335fSJung-uk Kim * 2. License 150d84335fSJung-uk Kim * 160d84335fSJung-uk Kim * 2.1. This is your license from Intel Corp. under its intellectual property 170d84335fSJung-uk Kim * rights. You may have additional license terms from the party that provided 180d84335fSJung-uk Kim * you this software, covering your right to use that party's intellectual 190d84335fSJung-uk Kim * property rights. 200d84335fSJung-uk Kim * 210d84335fSJung-uk Kim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 220d84335fSJung-uk Kim * copy of the source code appearing in this file ("Covered Code") an 230d84335fSJung-uk Kim * irrevocable, perpetual, worldwide license under Intel's copyrights in the 240d84335fSJung-uk Kim * base code distributed originally by Intel ("Original Intel Code") to copy, 250d84335fSJung-uk Kim * make derivatives, distribute, use and display any portion of the Covered 260d84335fSJung-uk Kim * Code in any form, with the right to sublicense such rights; and 270d84335fSJung-uk Kim * 280d84335fSJung-uk Kim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 290d84335fSJung-uk Kim * license (with the right to sublicense), under only those claims of Intel 300d84335fSJung-uk Kim * patents that are infringed by the Original Intel Code, to make, use, sell, 310d84335fSJung-uk Kim * offer to sell, and import the Covered Code and derivative works thereof 320d84335fSJung-uk Kim * solely to the minimum extent necessary to exercise the above copyright 330d84335fSJung-uk Kim * license, and in no event shall the patent license extend to any additions 340d84335fSJung-uk Kim * to or modifications of the Original Intel Code. No other license or right 350d84335fSJung-uk Kim * is granted directly or by implication, estoppel or otherwise; 360d84335fSJung-uk Kim * 370d84335fSJung-uk Kim * The above copyright and patent license is granted only if the following 380d84335fSJung-uk Kim * conditions are met: 390d84335fSJung-uk Kim * 400d84335fSJung-uk Kim * 3. Conditions 410d84335fSJung-uk Kim * 420d84335fSJung-uk Kim * 3.1. Redistribution of Source with Rights to Further Distribute Source. 430d84335fSJung-uk Kim * Redistribution of source code of any substantial portion of the Covered 440d84335fSJung-uk Kim * Code or modification with rights to further distribute source must include 450d84335fSJung-uk Kim * the above Copyright Notice, the above License, this list of Conditions, 460d84335fSJung-uk Kim * and the following Disclaimer and Export Compliance provision. In addition, 470d84335fSJung-uk Kim * Licensee must cause all Covered Code to which Licensee contributes to 480d84335fSJung-uk Kim * contain a file documenting the changes Licensee made to create that Covered 490d84335fSJung-uk Kim * Code and the date of any change. Licensee must include in that file the 500d84335fSJung-uk Kim * documentation of any changes made by any predecessor Licensee. Licensee 510d84335fSJung-uk Kim * must include a prominent statement that the modification is derived, 520d84335fSJung-uk Kim * directly or indirectly, from Original Intel Code. 530d84335fSJung-uk Kim * 540d84335fSJung-uk Kim * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 550d84335fSJung-uk Kim * Redistribution of source code of any substantial portion of the Covered 560d84335fSJung-uk Kim * Code or modification without rights to further distribute source must 570d84335fSJung-uk Kim * include the following Disclaimer and Export Compliance provision in the 580d84335fSJung-uk Kim * documentation and/or other materials provided with distribution. In 590d84335fSJung-uk Kim * addition, Licensee may not authorize further sublicense of source of any 600d84335fSJung-uk Kim * portion of the Covered Code, and must include terms to the effect that the 610d84335fSJung-uk Kim * license from Licensee to its licensee is limited to the intellectual 620d84335fSJung-uk Kim * property embodied in the software Licensee provides to its licensee, and 630d84335fSJung-uk Kim * not to intellectual property embodied in modifications its licensee may 640d84335fSJung-uk Kim * make. 650d84335fSJung-uk Kim * 660d84335fSJung-uk Kim * 3.3. Redistribution of Executable. Redistribution in executable form of any 670d84335fSJung-uk Kim * substantial portion of the Covered Code or modification must reproduce the 680d84335fSJung-uk Kim * above Copyright Notice, and the following Disclaimer and Export Compliance 690d84335fSJung-uk Kim * provision in the documentation and/or other materials provided with the 700d84335fSJung-uk Kim * distribution. 710d84335fSJung-uk Kim * 720d84335fSJung-uk Kim * 3.4. Intel retains all right, title, and interest in and to the Original 730d84335fSJung-uk Kim * Intel Code. 740d84335fSJung-uk Kim * 750d84335fSJung-uk Kim * 3.5. Neither the name Intel nor any other trademark owned or controlled by 760d84335fSJung-uk Kim * Intel shall be used in advertising or otherwise to promote the sale, use or 770d84335fSJung-uk Kim * other dealings in products derived from or relating to the Covered Code 780d84335fSJung-uk Kim * without prior written authorization from Intel. 790d84335fSJung-uk Kim * 800d84335fSJung-uk Kim * 4. Disclaimer and Export Compliance 810d84335fSJung-uk Kim * 820d84335fSJung-uk Kim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 830d84335fSJung-uk Kim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 840d84335fSJung-uk Kim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 850d84335fSJung-uk Kim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 860d84335fSJung-uk Kim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 870d84335fSJung-uk Kim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 880d84335fSJung-uk Kim * PARTICULAR PURPOSE. 890d84335fSJung-uk Kim * 900d84335fSJung-uk Kim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 910d84335fSJung-uk Kim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 920d84335fSJung-uk Kim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 930d84335fSJung-uk Kim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 940d84335fSJung-uk Kim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 950d84335fSJung-uk Kim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 960d84335fSJung-uk Kim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 970d84335fSJung-uk Kim * LIMITED REMEDY. 980d84335fSJung-uk Kim * 990d84335fSJung-uk Kim * 4.3. Licensee shall not export, either directly or indirectly, any of this 1000d84335fSJung-uk Kim * software or system incorporating such software without first obtaining any 1010d84335fSJung-uk Kim * required license or other approval from the U. S. Department of Commerce or 1020d84335fSJung-uk Kim * any other agency or department of the United States Government. In the 1030d84335fSJung-uk Kim * event Licensee exports any such software from the United States or 1040d84335fSJung-uk Kim * re-exports any such software from a foreign destination, Licensee shall 1050d84335fSJung-uk Kim * ensure that the distribution and export/re-export of the software is in 1060d84335fSJung-uk Kim * compliance with all laws, regulations, orders, or other restrictions of the 1070d84335fSJung-uk Kim * U.S. Export Administration Regulations. Licensee agrees that neither it nor 1080d84335fSJung-uk Kim * any of its subsidiaries will export/re-export any technical data, process, 1090d84335fSJung-uk Kim * software, or service, directly or indirectly, to any country for which the 1100d84335fSJung-uk Kim * United States government or any agency thereof requires an export license, 1110d84335fSJung-uk Kim * other governmental approval, or letter of assurance, without first obtaining 1120d84335fSJung-uk Kim * such license, approval or letter. 1130d84335fSJung-uk Kim * 1140d84335fSJung-uk Kim ***************************************************************************** 1150d84335fSJung-uk Kim * 1160d84335fSJung-uk Kim * Alternatively, you may choose to be licensed under the terms of the 1170d84335fSJung-uk Kim * following license: 1180d84335fSJung-uk Kim * 119a159c266SJung-uk Kim * Redistribution and use in source and binary forms, with or without 120a159c266SJung-uk Kim * modification, are permitted provided that the following conditions 121a159c266SJung-uk Kim * are met: 122a159c266SJung-uk Kim * 1. Redistributions of source code must retain the above copyright 123a159c266SJung-uk Kim * notice, this list of conditions, and the following disclaimer, 124a159c266SJung-uk Kim * without modification. 125a159c266SJung-uk Kim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126a159c266SJung-uk Kim * substantially similar to the "NO WARRANTY" disclaimer below 127a159c266SJung-uk Kim * ("Disclaimer") and any redistribution must be conditioned upon 128a159c266SJung-uk Kim * including a substantially similar Disclaimer requirement for further 129a159c266SJung-uk Kim * binary redistribution. 130a159c266SJung-uk Kim * 3. Neither the names of the above-listed copyright holders nor the names 131a159c266SJung-uk Kim * of any contributors may be used to endorse or promote products derived 132a159c266SJung-uk Kim * from this software without specific prior written permission. 133a159c266SJung-uk Kim * 1340d84335fSJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1350d84335fSJung-uk Kim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1360d84335fSJung-uk Kim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1370d84335fSJung-uk Kim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1380d84335fSJung-uk Kim * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1390d84335fSJung-uk Kim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1400d84335fSJung-uk Kim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1410d84335fSJung-uk Kim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1420d84335fSJung-uk Kim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1430d84335fSJung-uk Kim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1440d84335fSJung-uk Kim * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1450d84335fSJung-uk Kim * 1460d84335fSJung-uk Kim * Alternatively, you may choose to be licensed under the terms of the 147a159c266SJung-uk Kim * GNU General Public License ("GPL") version 2 as published by the Free 148a159c266SJung-uk Kim * Software Foundation. 149a159c266SJung-uk Kim * 1500d84335fSJung-uk Kim *****************************************************************************/ 151a159c266SJung-uk Kim 152a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h> 153a159c266SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h> 154a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acdispat.h> 155a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acinterp.h> 156313a0c13SJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h> 157a159c266SJung-uk Kim 158a159c266SJung-uk Kim 159a159c266SJung-uk Kim #define _COMPONENT ACPI_EXECUTER 160a159c266SJung-uk Kim ACPI_MODULE_NAME ("exfield") 161a159c266SJung-uk Kim 162313a0c13SJung-uk Kim /* Local prototypes */ 163313a0c13SJung-uk Kim 164313a0c13SJung-uk Kim static UINT32 165313a0c13SJung-uk Kim AcpiExGetSerialAccessLength ( 166313a0c13SJung-uk Kim UINT32 AccessorType, 167313a0c13SJung-uk Kim UINT32 AccessLength); 168313a0c13SJung-uk Kim 169313a0c13SJung-uk Kim 170313a0c13SJung-uk Kim /******************************************************************************* 171313a0c13SJung-uk Kim * 172313a0c13SJung-uk Kim * FUNCTION: AcpiExGetSerialAccessLength 173313a0c13SJung-uk Kim * 174313a0c13SJung-uk Kim * PARAMETERS: AccessorType - The type of the protocol indicated by region 175313a0c13SJung-uk Kim * field access attributes 176313a0c13SJung-uk Kim * AccessLength - The access length of the region field 177313a0c13SJung-uk Kim * 178313a0c13SJung-uk Kim * RETURN: Decoded access length 179313a0c13SJung-uk Kim * 180313a0c13SJung-uk Kim * DESCRIPTION: This routine returns the length of the GenericSerialBus 181313a0c13SJung-uk Kim * protocol bytes 182313a0c13SJung-uk Kim * 183313a0c13SJung-uk Kim ******************************************************************************/ 184313a0c13SJung-uk Kim 185313a0c13SJung-uk Kim static UINT32 186313a0c13SJung-uk Kim AcpiExGetSerialAccessLength ( 187313a0c13SJung-uk Kim UINT32 AccessorType, 188313a0c13SJung-uk Kim UINT32 AccessLength) 189313a0c13SJung-uk Kim { 190313a0c13SJung-uk Kim UINT32 Length; 191313a0c13SJung-uk Kim 192313a0c13SJung-uk Kim 193313a0c13SJung-uk Kim switch (AccessorType) 194313a0c13SJung-uk Kim { 195313a0c13SJung-uk Kim case AML_FIELD_ATTRIB_QUICK: 196313a0c13SJung-uk Kim 197313a0c13SJung-uk Kim Length = 0; 198313a0c13SJung-uk Kim break; 199313a0c13SJung-uk Kim 200313a0c13SJung-uk Kim case AML_FIELD_ATTRIB_SEND_RCV: 201313a0c13SJung-uk Kim case AML_FIELD_ATTRIB_BYTE: 202313a0c13SJung-uk Kim 203313a0c13SJung-uk Kim Length = 1; 204313a0c13SJung-uk Kim break; 205313a0c13SJung-uk Kim 206313a0c13SJung-uk Kim case AML_FIELD_ATTRIB_WORD: 207313a0c13SJung-uk Kim case AML_FIELD_ATTRIB_WORD_CALL: 208313a0c13SJung-uk Kim 209313a0c13SJung-uk Kim Length = 2; 210313a0c13SJung-uk Kim break; 211313a0c13SJung-uk Kim 212313a0c13SJung-uk Kim case AML_FIELD_ATTRIB_MULTIBYTE: 213313a0c13SJung-uk Kim case AML_FIELD_ATTRIB_RAW_BYTES: 214313a0c13SJung-uk Kim case AML_FIELD_ATTRIB_RAW_PROCESS: 215313a0c13SJung-uk Kim 216313a0c13SJung-uk Kim Length = AccessLength; 217313a0c13SJung-uk Kim break; 218313a0c13SJung-uk Kim 219313a0c13SJung-uk Kim case AML_FIELD_ATTRIB_BLOCK: 220313a0c13SJung-uk Kim case AML_FIELD_ATTRIB_BLOCK_CALL: 221313a0c13SJung-uk Kim default: 222313a0c13SJung-uk Kim 223313a0c13SJung-uk Kim Length = ACPI_GSBUS_BUFFER_SIZE - 2; 224313a0c13SJung-uk Kim break; 225313a0c13SJung-uk Kim } 226313a0c13SJung-uk Kim 227313a0c13SJung-uk Kim return (Length); 228313a0c13SJung-uk Kim } 229313a0c13SJung-uk Kim 230a159c266SJung-uk Kim 231a159c266SJung-uk Kim /******************************************************************************* 232a159c266SJung-uk Kim * 233a159c266SJung-uk Kim * FUNCTION: AcpiExReadDataFromField 234a159c266SJung-uk Kim * 235a159c266SJung-uk Kim * PARAMETERS: WalkState - Current execution state 236a159c266SJung-uk Kim * ObjDesc - The named field 237a159c266SJung-uk Kim * RetBufferDesc - Where the return data object is stored 238a159c266SJung-uk Kim * 239a159c266SJung-uk Kim * RETURN: Status 240a159c266SJung-uk Kim * 241a159c266SJung-uk Kim * DESCRIPTION: Read from a named field. Returns either an Integer or a 242a159c266SJung-uk Kim * Buffer, depending on the size of the field. 243a159c266SJung-uk Kim * 244a159c266SJung-uk Kim ******************************************************************************/ 245a159c266SJung-uk Kim 246a159c266SJung-uk Kim ACPI_STATUS 247a159c266SJung-uk Kim AcpiExReadDataFromField ( 248a159c266SJung-uk Kim ACPI_WALK_STATE *WalkState, 249a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc, 250a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **RetBufferDesc) 251a159c266SJung-uk Kim { 252a159c266SJung-uk Kim ACPI_STATUS Status; 253a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *BufferDesc; 254a159c266SJung-uk Kim ACPI_SIZE Length; 255a159c266SJung-uk Kim void *Buffer; 256a159c266SJung-uk Kim UINT32 Function; 257313a0c13SJung-uk Kim UINT16 AccessorType; 258a159c266SJung-uk Kim 259a159c266SJung-uk Kim 260a159c266SJung-uk Kim ACPI_FUNCTION_TRACE_PTR (ExReadDataFromField, ObjDesc); 261a159c266SJung-uk Kim 262a159c266SJung-uk Kim 263a159c266SJung-uk Kim /* Parameter validation */ 264a159c266SJung-uk Kim 265a159c266SJung-uk Kim if (!ObjDesc) 266a159c266SJung-uk Kim { 267a159c266SJung-uk Kim return_ACPI_STATUS (AE_AML_NO_OPERAND); 268a159c266SJung-uk Kim } 269a159c266SJung-uk Kim if (!RetBufferDesc) 270a159c266SJung-uk Kim { 271a159c266SJung-uk Kim return_ACPI_STATUS (AE_BAD_PARAMETER); 272a159c266SJung-uk Kim } 273a159c266SJung-uk Kim 274a159c266SJung-uk Kim if (ObjDesc->Common.Type == ACPI_TYPE_BUFFER_FIELD) 275a159c266SJung-uk Kim { 276a159c266SJung-uk Kim /* 277a159c266SJung-uk Kim * If the BufferField arguments have not been previously evaluated, 278a159c266SJung-uk Kim * evaluate them now and save the results. 279a159c266SJung-uk Kim */ 280a159c266SJung-uk Kim if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)) 281a159c266SJung-uk Kim { 282a159c266SJung-uk Kim Status = AcpiDsGetBufferFieldArguments (ObjDesc); 283a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 284a159c266SJung-uk Kim { 285a159c266SJung-uk Kim return_ACPI_STATUS (Status); 286a159c266SJung-uk Kim } 287a159c266SJung-uk Kim } 288a159c266SJung-uk Kim } 289a159c266SJung-uk Kim else if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REGION_FIELD) && 290a159c266SJung-uk Kim (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_SMBUS || 291a159c266SJung-uk Kim ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GSBUS || 292a159c266SJung-uk Kim ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_IPMI)) 293a159c266SJung-uk Kim { 294a159c266SJung-uk Kim /* 295f8146b88SJung-uk Kim * This is an SMBus, GSBus or IPMI read. We must create a buffer to 296f8146b88SJung-uk Kim * hold the data and then directly access the region handler. 297a159c266SJung-uk Kim * 298f8146b88SJung-uk Kim * Note: SMBus and GSBus protocol value is passed in upper 16-bits 299f8146b88SJung-uk Kim * of Function 300a159c266SJung-uk Kim */ 301f8146b88SJung-uk Kim if (ObjDesc->Field.RegionObj->Region.SpaceId == 302f8146b88SJung-uk Kim ACPI_ADR_SPACE_SMBUS) 303a159c266SJung-uk Kim { 304a159c266SJung-uk Kim Length = ACPI_SMBUS_BUFFER_SIZE; 305a159c266SJung-uk Kim Function = ACPI_READ | (ObjDesc->Field.Attribute << 16); 306a159c266SJung-uk Kim } 307f8146b88SJung-uk Kim else if (ObjDesc->Field.RegionObj->Region.SpaceId == 308f8146b88SJung-uk Kim ACPI_ADR_SPACE_GSBUS) 309a159c266SJung-uk Kim { 310313a0c13SJung-uk Kim AccessorType = ObjDesc->Field.Attribute; 311f8146b88SJung-uk Kim Length = AcpiExGetSerialAccessLength ( 312f8146b88SJung-uk Kim AccessorType, ObjDesc->Field.AccessLength); 313313a0c13SJung-uk Kim 314313a0c13SJung-uk Kim /* 315313a0c13SJung-uk Kim * Add additional 2 bytes for the GenericSerialBus data buffer: 316313a0c13SJung-uk Kim * 317313a0c13SJung-uk Kim * Status; (Byte 0 of the data buffer) 318313a0c13SJung-uk Kim * Length; (Byte 1 of the data buffer) 319f8146b88SJung-uk Kim * Data[x-1]: (Bytes 2-x of the arbitrary length data buffer) 320313a0c13SJung-uk Kim */ 321313a0c13SJung-uk Kim Length += 2; 322313a0c13SJung-uk Kim Function = ACPI_READ | (AccessorType << 16); 323a159c266SJung-uk Kim } 324a159c266SJung-uk Kim else /* IPMI */ 325a159c266SJung-uk Kim { 326a159c266SJung-uk Kim Length = ACPI_IPMI_BUFFER_SIZE; 327a159c266SJung-uk Kim Function = ACPI_READ; 328a159c266SJung-uk Kim } 329a159c266SJung-uk Kim 330a159c266SJung-uk Kim BufferDesc = AcpiUtCreateBufferObject (Length); 331a159c266SJung-uk Kim if (!BufferDesc) 332a159c266SJung-uk Kim { 333a159c266SJung-uk Kim return_ACPI_STATUS (AE_NO_MEMORY); 334a159c266SJung-uk Kim } 335a159c266SJung-uk Kim 336a159c266SJung-uk Kim /* Lock entire transaction if requested */ 337a159c266SJung-uk Kim 338a159c266SJung-uk Kim AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags); 339a159c266SJung-uk Kim 340a159c266SJung-uk Kim /* Call the region handler for the read */ 341a159c266SJung-uk Kim 342a159c266SJung-uk Kim Status = AcpiExAccessRegion (ObjDesc, 0, 343f8146b88SJung-uk Kim ACPI_CAST_PTR (UINT64, BufferDesc->Buffer.Pointer), Function); 344f8146b88SJung-uk Kim 345a159c266SJung-uk Kim AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags); 346a159c266SJung-uk Kim goto Exit; 347a159c266SJung-uk Kim } 348a159c266SJung-uk Kim 349a159c266SJung-uk Kim /* 350a159c266SJung-uk Kim * Allocate a buffer for the contents of the field. 351a159c266SJung-uk Kim * 352a159c266SJung-uk Kim * If the field is larger than the current integer width, create 353a159c266SJung-uk Kim * a BUFFER to hold it. Otherwise, use an INTEGER. This allows 354a159c266SJung-uk Kim * the use of arithmetic operators on the returned value if the 355a159c266SJung-uk Kim * field size is equal or smaller than an Integer. 356a159c266SJung-uk Kim * 357a159c266SJung-uk Kim * Note: Field.length is in bits. 358a159c266SJung-uk Kim */ 359f8146b88SJung-uk Kim Length = (ACPI_SIZE) ACPI_ROUND_BITS_UP_TO_BYTES ( 360f8146b88SJung-uk Kim ObjDesc->Field.BitLength); 361f8146b88SJung-uk Kim 362a159c266SJung-uk Kim if (Length > AcpiGbl_IntegerByteWidth) 363a159c266SJung-uk Kim { 364a159c266SJung-uk Kim /* Field is too large for an Integer, create a Buffer instead */ 365a159c266SJung-uk Kim 366a159c266SJung-uk Kim BufferDesc = AcpiUtCreateBufferObject (Length); 367a159c266SJung-uk Kim if (!BufferDesc) 368a159c266SJung-uk Kim { 369a159c266SJung-uk Kim return_ACPI_STATUS (AE_NO_MEMORY); 370a159c266SJung-uk Kim } 371a159c266SJung-uk Kim Buffer = BufferDesc->Buffer.Pointer; 372a159c266SJung-uk Kim } 373a159c266SJung-uk Kim else 374a159c266SJung-uk Kim { 375a159c266SJung-uk Kim /* Field will fit within an Integer (normal case) */ 376a159c266SJung-uk Kim 377a159c266SJung-uk Kim BufferDesc = AcpiUtCreateIntegerObject ((UINT64) 0); 378a159c266SJung-uk Kim if (!BufferDesc) 379a159c266SJung-uk Kim { 380a159c266SJung-uk Kim return_ACPI_STATUS (AE_NO_MEMORY); 381a159c266SJung-uk Kim } 382a159c266SJung-uk Kim 383a159c266SJung-uk Kim Length = AcpiGbl_IntegerByteWidth; 384a159c266SJung-uk Kim Buffer = &BufferDesc->Integer.Value; 385a159c266SJung-uk Kim } 386a159c266SJung-uk Kim 387313a0c13SJung-uk Kim if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REGION_FIELD) && 388313a0c13SJung-uk Kim (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GPIO)) 389313a0c13SJung-uk Kim { 390313a0c13SJung-uk Kim /* 391313a0c13SJung-uk Kim * For GPIO (GeneralPurposeIo), the Address will be the bit offset 392313a0c13SJung-uk Kim * from the previous Connection() operator, making it effectively a 393313a0c13SJung-uk Kim * pin number index. The BitLength is the length of the field, which 394313a0c13SJung-uk Kim * is thus the number of pins. 395313a0c13SJung-uk Kim */ 396313a0c13SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 397313a0c13SJung-uk Kim "GPIO FieldRead [FROM]: Pin %u Bits %u\n", 398313a0c13SJung-uk Kim ObjDesc->Field.PinNumberIndex, ObjDesc->Field.BitLength)); 399313a0c13SJung-uk Kim 400313a0c13SJung-uk Kim /* Lock entire transaction if requested */ 401313a0c13SJung-uk Kim 402313a0c13SJung-uk Kim AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags); 403313a0c13SJung-uk Kim 404313a0c13SJung-uk Kim /* Perform the write */ 405313a0c13SJung-uk Kim 406f8146b88SJung-uk Kim Status = AcpiExAccessRegion ( 407f8146b88SJung-uk Kim ObjDesc, 0, (UINT64 *) Buffer, ACPI_READ); 408f8146b88SJung-uk Kim 409313a0c13SJung-uk Kim AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags); 410313a0c13SJung-uk Kim if (ACPI_FAILURE (Status)) 411313a0c13SJung-uk Kim { 412313a0c13SJung-uk Kim AcpiUtRemoveReference (BufferDesc); 413313a0c13SJung-uk Kim } 414313a0c13SJung-uk Kim else 415313a0c13SJung-uk Kim { 416313a0c13SJung-uk Kim *RetBufferDesc = BufferDesc; 417313a0c13SJung-uk Kim } 418313a0c13SJung-uk Kim return_ACPI_STATUS (Status); 419313a0c13SJung-uk Kim } 420313a0c13SJung-uk Kim 421a159c266SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 422a159c266SJung-uk Kim "FieldRead [TO]: Obj %p, Type %X, Buf %p, ByteLen %X\n", 423a159c266SJung-uk Kim ObjDesc, ObjDesc->Common.Type, Buffer, (UINT32) Length)); 424a159c266SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 425a159c266SJung-uk Kim "FieldRead [FROM]: BitLen %X, BitOff %X, ByteOff %X\n", 426a159c266SJung-uk Kim ObjDesc->CommonField.BitLength, 427a159c266SJung-uk Kim ObjDesc->CommonField.StartFieldBitOffset, 428a159c266SJung-uk Kim ObjDesc->CommonField.BaseByteOffset)); 429a159c266SJung-uk Kim 430a159c266SJung-uk Kim /* Lock entire transaction if requested */ 431a159c266SJung-uk Kim 432a159c266SJung-uk Kim AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags); 433a159c266SJung-uk Kim 434a159c266SJung-uk Kim /* Read from the field */ 435a159c266SJung-uk Kim 436a159c266SJung-uk Kim Status = AcpiExExtractFromField (ObjDesc, Buffer, (UINT32) Length); 437a159c266SJung-uk Kim AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags); 438a159c266SJung-uk Kim 439a159c266SJung-uk Kim 440a159c266SJung-uk Kim Exit: 441a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 442a159c266SJung-uk Kim { 443a159c266SJung-uk Kim AcpiUtRemoveReference (BufferDesc); 444a159c266SJung-uk Kim } 445a159c266SJung-uk Kim else 446a159c266SJung-uk Kim { 447a159c266SJung-uk Kim *RetBufferDesc = BufferDesc; 448a159c266SJung-uk Kim } 449a159c266SJung-uk Kim 450a159c266SJung-uk Kim return_ACPI_STATUS (Status); 451a159c266SJung-uk Kim } 452a159c266SJung-uk Kim 453a159c266SJung-uk Kim 454a159c266SJung-uk Kim /******************************************************************************* 455a159c266SJung-uk Kim * 456a159c266SJung-uk Kim * FUNCTION: AcpiExWriteDataToField 457a159c266SJung-uk Kim * 458a159c266SJung-uk Kim * PARAMETERS: SourceDesc - Contains data to write 459a159c266SJung-uk Kim * ObjDesc - The named field 460a159c266SJung-uk Kim * ResultDesc - Where the return value is returned, if any 461a159c266SJung-uk Kim * 462a159c266SJung-uk Kim * RETURN: Status 463a159c266SJung-uk Kim * 464a159c266SJung-uk Kim * DESCRIPTION: Write to a named field 465a159c266SJung-uk Kim * 466a159c266SJung-uk Kim ******************************************************************************/ 467a159c266SJung-uk Kim 468a159c266SJung-uk Kim ACPI_STATUS 469a159c266SJung-uk Kim AcpiExWriteDataToField ( 470a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *SourceDesc, 471a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *ObjDesc, 472a159c266SJung-uk Kim ACPI_OPERAND_OBJECT **ResultDesc) 473a159c266SJung-uk Kim { 474a159c266SJung-uk Kim ACPI_STATUS Status; 475a159c266SJung-uk Kim UINT32 Length; 476a159c266SJung-uk Kim void *Buffer; 477a159c266SJung-uk Kim ACPI_OPERAND_OBJECT *BufferDesc; 478a159c266SJung-uk Kim UINT32 Function; 479313a0c13SJung-uk Kim UINT16 AccessorType; 480a159c266SJung-uk Kim 481a159c266SJung-uk Kim 482a159c266SJung-uk Kim ACPI_FUNCTION_TRACE_PTR (ExWriteDataToField, ObjDesc); 483a159c266SJung-uk Kim 484a159c266SJung-uk Kim 485a159c266SJung-uk Kim /* Parameter validation */ 486a159c266SJung-uk Kim 487a159c266SJung-uk Kim if (!SourceDesc || !ObjDesc) 488a159c266SJung-uk Kim { 489a159c266SJung-uk Kim return_ACPI_STATUS (AE_AML_NO_OPERAND); 490a159c266SJung-uk Kim } 491a159c266SJung-uk Kim 492a159c266SJung-uk Kim if (ObjDesc->Common.Type == ACPI_TYPE_BUFFER_FIELD) 493a159c266SJung-uk Kim { 494a159c266SJung-uk Kim /* 495a159c266SJung-uk Kim * If the BufferField arguments have not been previously evaluated, 496a159c266SJung-uk Kim * evaluate them now and save the results. 497a159c266SJung-uk Kim */ 498a159c266SJung-uk Kim if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)) 499a159c266SJung-uk Kim { 500a159c266SJung-uk Kim Status = AcpiDsGetBufferFieldArguments (ObjDesc); 501a159c266SJung-uk Kim if (ACPI_FAILURE (Status)) 502a159c266SJung-uk Kim { 503a159c266SJung-uk Kim return_ACPI_STATUS (Status); 504a159c266SJung-uk Kim } 505a159c266SJung-uk Kim } 506a159c266SJung-uk Kim } 507a159c266SJung-uk Kim else if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REGION_FIELD) && 508a159c266SJung-uk Kim (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_SMBUS || 509a159c266SJung-uk Kim ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GSBUS || 510a159c266SJung-uk Kim ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_IPMI)) 511a159c266SJung-uk Kim { 512a159c266SJung-uk Kim /* 513f8146b88SJung-uk Kim * This is an SMBus, GSBus or IPMI write. We will bypass the entire 514f8146b88SJung-uk Kim * field mechanism and handoff the buffer directly to the handler. 515f8146b88SJung-uk Kim * For these address spaces, the buffer is bi-directional; on a 516f8146b88SJung-uk Kim * write, return data is returned in the same buffer. 517a159c266SJung-uk Kim * 518a159c266SJung-uk Kim * Source must be a buffer of sufficient size: 519f8146b88SJung-uk Kim * ACPI_SMBUS_BUFFER_SIZE, ACPI_GSBUS_BUFFER_SIZE, or 520f8146b88SJung-uk Kim * ACPI_IPMI_BUFFER_SIZE. 521a159c266SJung-uk Kim * 522f8146b88SJung-uk Kim * Note: SMBus and GSBus protocol type is passed in upper 16-bits 523f8146b88SJung-uk Kim * of Function 524a159c266SJung-uk Kim */ 525a159c266SJung-uk Kim if (SourceDesc->Common.Type != ACPI_TYPE_BUFFER) 526a159c266SJung-uk Kim { 527a159c266SJung-uk Kim ACPI_ERROR ((AE_INFO, 528f8146b88SJung-uk Kim "SMBus/IPMI/GenericSerialBus write requires " 529f8146b88SJung-uk Kim "Buffer, found type %s", 530a159c266SJung-uk Kim AcpiUtGetObjectTypeName (SourceDesc))); 531a159c266SJung-uk Kim 532a159c266SJung-uk Kim return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 533a159c266SJung-uk Kim } 534a159c266SJung-uk Kim 535f8146b88SJung-uk Kim if (ObjDesc->Field.RegionObj->Region.SpaceId == 536f8146b88SJung-uk Kim ACPI_ADR_SPACE_SMBUS) 537a159c266SJung-uk Kim { 538a159c266SJung-uk Kim Length = ACPI_SMBUS_BUFFER_SIZE; 539a159c266SJung-uk Kim Function = ACPI_WRITE | (ObjDesc->Field.Attribute << 16); 540a159c266SJung-uk Kim } 541f8146b88SJung-uk Kim else if (ObjDesc->Field.RegionObj->Region.SpaceId == 542f8146b88SJung-uk Kim ACPI_ADR_SPACE_GSBUS) 543a159c266SJung-uk Kim { 544313a0c13SJung-uk Kim AccessorType = ObjDesc->Field.Attribute; 545f8146b88SJung-uk Kim Length = AcpiExGetSerialAccessLength ( 546f8146b88SJung-uk Kim AccessorType, ObjDesc->Field.AccessLength); 547313a0c13SJung-uk Kim 548313a0c13SJung-uk Kim /* 549313a0c13SJung-uk Kim * Add additional 2 bytes for the GenericSerialBus data buffer: 550313a0c13SJung-uk Kim * 551313a0c13SJung-uk Kim * Status; (Byte 0 of the data buffer) 552313a0c13SJung-uk Kim * Length; (Byte 1 of the data buffer) 553f8146b88SJung-uk Kim * Data[x-1]: (Bytes 2-x of the arbitrary length data buffer) 554313a0c13SJung-uk Kim */ 555313a0c13SJung-uk Kim Length += 2; 556313a0c13SJung-uk Kim Function = ACPI_WRITE | (AccessorType << 16); 557a159c266SJung-uk Kim } 558a159c266SJung-uk Kim else /* IPMI */ 559a159c266SJung-uk Kim { 560a159c266SJung-uk Kim Length = ACPI_IPMI_BUFFER_SIZE; 561a159c266SJung-uk Kim Function = ACPI_WRITE; 562a159c266SJung-uk Kim } 563a159c266SJung-uk Kim 564a159c266SJung-uk Kim if (SourceDesc->Buffer.Length < Length) 565a159c266SJung-uk Kim { 566a159c266SJung-uk Kim ACPI_ERROR ((AE_INFO, 567f8146b88SJung-uk Kim "SMBus/IPMI/GenericSerialBus write requires " 568f8146b88SJung-uk Kim "Buffer of length %u, found length %u", 569a159c266SJung-uk Kim Length, SourceDesc->Buffer.Length)); 570a159c266SJung-uk Kim 571a159c266SJung-uk Kim return_ACPI_STATUS (AE_AML_BUFFER_LIMIT); 572a159c266SJung-uk Kim } 573a159c266SJung-uk Kim 574a159c266SJung-uk Kim /* Create the bi-directional buffer */ 575a159c266SJung-uk Kim 576a159c266SJung-uk Kim BufferDesc = AcpiUtCreateBufferObject (Length); 577a159c266SJung-uk Kim if (!BufferDesc) 578a159c266SJung-uk Kim { 579a159c266SJung-uk Kim return_ACPI_STATUS (AE_NO_MEMORY); 580a159c266SJung-uk Kim } 581a159c266SJung-uk Kim 582a159c266SJung-uk Kim Buffer = BufferDesc->Buffer.Pointer; 5835ef50723SJung-uk Kim memcpy (Buffer, SourceDesc->Buffer.Pointer, Length); 584a159c266SJung-uk Kim 585a159c266SJung-uk Kim /* Lock entire transaction if requested */ 586a159c266SJung-uk Kim 587a159c266SJung-uk Kim AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags); 588a159c266SJung-uk Kim 589a159c266SJung-uk Kim /* 590a159c266SJung-uk Kim * Perform the write (returns status and perhaps data in the 591a159c266SJung-uk Kim * same buffer) 592a159c266SJung-uk Kim */ 593f8146b88SJung-uk Kim Status = AcpiExAccessRegion ( 594f8146b88SJung-uk Kim ObjDesc, 0, (UINT64 *) Buffer, Function); 595a159c266SJung-uk Kim AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags); 596a159c266SJung-uk Kim 597a159c266SJung-uk Kim *ResultDesc = BufferDesc; 598a159c266SJung-uk Kim return_ACPI_STATUS (Status); 599a159c266SJung-uk Kim } 600313a0c13SJung-uk Kim else if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REGION_FIELD) && 601313a0c13SJung-uk Kim (ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GPIO)) 602313a0c13SJung-uk Kim { 603313a0c13SJung-uk Kim /* 604313a0c13SJung-uk Kim * For GPIO (GeneralPurposeIo), we will bypass the entire field 605313a0c13SJung-uk Kim * mechanism and handoff the bit address and bit width directly to 606313a0c13SJung-uk Kim * the handler. The Address will be the bit offset 607313a0c13SJung-uk Kim * from the previous Connection() operator, making it effectively a 608313a0c13SJung-uk Kim * pin number index. The BitLength is the length of the field, which 609313a0c13SJung-uk Kim * is thus the number of pins. 610313a0c13SJung-uk Kim */ 611313a0c13SJung-uk Kim if (SourceDesc->Common.Type != ACPI_TYPE_INTEGER) 612313a0c13SJung-uk Kim { 613313a0c13SJung-uk Kim return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 614313a0c13SJung-uk Kim } 615313a0c13SJung-uk Kim 616313a0c13SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 617313a0c13SJung-uk Kim "GPIO FieldWrite [FROM]: (%s:%X), Val %.8X [TO]: Pin %u Bits %u\n", 618313a0c13SJung-uk Kim AcpiUtGetTypeName (SourceDesc->Common.Type), 619313a0c13SJung-uk Kim SourceDesc->Common.Type, (UINT32) SourceDesc->Integer.Value, 620313a0c13SJung-uk Kim ObjDesc->Field.PinNumberIndex, ObjDesc->Field.BitLength)); 621313a0c13SJung-uk Kim 622313a0c13SJung-uk Kim Buffer = &SourceDesc->Integer.Value; 623313a0c13SJung-uk Kim 624313a0c13SJung-uk Kim /* Lock entire transaction if requested */ 625313a0c13SJung-uk Kim 626313a0c13SJung-uk Kim AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags); 627313a0c13SJung-uk Kim 628313a0c13SJung-uk Kim /* Perform the write */ 629313a0c13SJung-uk Kim 630f8146b88SJung-uk Kim Status = AcpiExAccessRegion ( 631f8146b88SJung-uk Kim ObjDesc, 0, (UINT64 *) Buffer, ACPI_WRITE); 632313a0c13SJung-uk Kim AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags); 633313a0c13SJung-uk Kim return_ACPI_STATUS (Status); 634313a0c13SJung-uk Kim } 635a159c266SJung-uk Kim 636a159c266SJung-uk Kim /* Get a pointer to the data to be written */ 637a159c266SJung-uk Kim 638a159c266SJung-uk Kim switch (SourceDesc->Common.Type) 639a159c266SJung-uk Kim { 640a159c266SJung-uk Kim case ACPI_TYPE_INTEGER: 641a9d8d09cSJung-uk Kim 642a159c266SJung-uk Kim Buffer = &SourceDesc->Integer.Value; 643a159c266SJung-uk Kim Length = sizeof (SourceDesc->Integer.Value); 644a159c266SJung-uk Kim break; 645a159c266SJung-uk Kim 646a159c266SJung-uk Kim case ACPI_TYPE_BUFFER: 647a9d8d09cSJung-uk Kim 648a159c266SJung-uk Kim Buffer = SourceDesc->Buffer.Pointer; 649a159c266SJung-uk Kim Length = SourceDesc->Buffer.Length; 650a159c266SJung-uk Kim break; 651a159c266SJung-uk Kim 652a159c266SJung-uk Kim case ACPI_TYPE_STRING: 653a9d8d09cSJung-uk Kim 654a159c266SJung-uk Kim Buffer = SourceDesc->String.Pointer; 655a159c266SJung-uk Kim Length = SourceDesc->String.Length; 656a159c266SJung-uk Kim break; 657a159c266SJung-uk Kim 658a159c266SJung-uk Kim default: 659a9d8d09cSJung-uk Kim 660a159c266SJung-uk Kim return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 661a159c266SJung-uk Kim } 662a159c266SJung-uk Kim 663a159c266SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 664a159c266SJung-uk Kim "FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n", 665a159c266SJung-uk Kim SourceDesc, AcpiUtGetTypeName (SourceDesc->Common.Type), 666a159c266SJung-uk Kim SourceDesc->Common.Type, Buffer, Length)); 667a159c266SJung-uk Kim 668a159c266SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, 669a159c266SJung-uk Kim "FieldWrite [TO]: Obj %p (%s:%X), BitLen %X, BitOff %X, ByteOff %X\n", 670a159c266SJung-uk Kim ObjDesc, AcpiUtGetTypeName (ObjDesc->Common.Type), 671a159c266SJung-uk Kim ObjDesc->Common.Type, 672a159c266SJung-uk Kim ObjDesc->CommonField.BitLength, 673a159c266SJung-uk Kim ObjDesc->CommonField.StartFieldBitOffset, 674a159c266SJung-uk Kim ObjDesc->CommonField.BaseByteOffset)); 675a159c266SJung-uk Kim 676a159c266SJung-uk Kim /* Lock entire transaction if requested */ 677a159c266SJung-uk Kim 678a159c266SJung-uk Kim AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags); 679a159c266SJung-uk Kim 680a159c266SJung-uk Kim /* Write to the field */ 681a159c266SJung-uk Kim 682a159c266SJung-uk Kim Status = AcpiExInsertIntoField (ObjDesc, Buffer, Length); 683a159c266SJung-uk Kim AcpiExReleaseGlobalLock (ObjDesc->CommonField.FieldFlags); 684a159c266SJung-uk Kim 685a159c266SJung-uk Kim return_ACPI_STATUS (Status); 686a159c266SJung-uk Kim } 687