diff options
Diffstat (limited to 'source/tools/acpiexec/aehandlers.c')
| -rw-r--r-- | source/tools/acpiexec/aehandlers.c | 283 | 
1 files changed, 231 insertions, 52 deletions
diff --git a/source/tools/acpiexec/aehandlers.c b/source/tools/acpiexec/aehandlers.c index aa6540d0c33f..b89a431abf45 100644 --- a/source/tools/acpiexec/aehandlers.c +++ b/source/tools/acpiexec/aehandlers.c @@ -4,42 +4,114 @@   *   *****************************************************************************/ -/* - * Copyright (C) 2000 - 2013, Intel Corp. +/****************************************************************************** + * + * 1. Copyright Notice + * + * Some or all of this work - Copyright (c) 1999 - 2014, Intel Corp.   * All rights reserved.   * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - *    notice, this list of conditions, and the following disclaimer, - *    without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - *    substantially similar to the "NO WARRANTY" disclaimer below - *    ("Disclaimer") and any redistribution must be conditioned upon - *    including a substantially similar Disclaimer requirement for further - *    binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - *    of any contributors may be used to endorse or promote products derived - *    from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - */ + * 2. License + * + * 2.1. This is your license from Intel Corp. under its intellectual property + * rights. You may have additional license terms from the party that provided + * you this software, covering your right to use that party's intellectual + * property rights. + * + * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a + * copy of the source code appearing in this file ("Covered Code") an + * irrevocable, perpetual, worldwide license under Intel's copyrights in the + * base code distributed originally by Intel ("Original Intel Code") to copy, + * make derivatives, distribute, use and display any portion of the Covered + * Code in any form, with the right to sublicense such rights; and + * + * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent + * license (with the right to sublicense), under only those claims of Intel + * patents that are infringed by the Original Intel Code, to make, use, sell, + * offer to sell, and import the Covered Code and derivative works thereof + * solely to the minimum extent necessary to exercise the above copyright + * license, and in no event shall the patent license extend to any additions + * to or modifications of the Original Intel Code. No other license or right + * is granted directly or by implication, estoppel or otherwise; + * + * The above copyright and patent license is granted only if the following + * conditions are met: + * + * 3. Conditions + * + * 3.1. Redistribution of Source with Rights to Further Distribute Source. + * Redistribution of source code of any substantial portion of the Covered + * Code or modification with rights to further distribute source must include + * the above Copyright Notice, the above License, this list of Conditions, + * and the following Disclaimer and Export Compliance provision. In addition, + * Licensee must cause all Covered Code to which Licensee contributes to + * contain a file documenting the changes Licensee made to create that Covered + * Code and the date of any change. Licensee must include in that file the + * documentation of any changes made by any predecessor Licensee. Licensee + * must include a prominent statement that the modification is derived, + * directly or indirectly, from Original Intel Code. + * + * 3.2. Redistribution of Source with no Rights to Further Distribute Source. + * Redistribution of source code of any substantial portion of the Covered + * Code or modification without rights to further distribute source must + * include the following Disclaimer and Export Compliance provision in the + * documentation and/or other materials provided with distribution. In + * addition, Licensee may not authorize further sublicense of source of any + * portion of the Covered Code, and must include terms to the effect that the + * license from Licensee to its licensee is limited to the intellectual + * property embodied in the software Licensee provides to its licensee, and + * not to intellectual property embodied in modifications its licensee may + * make. + * + * 3.3. Redistribution of Executable. Redistribution in executable form of any + * substantial portion of the Covered Code or modification must reproduce the + * above Copyright Notice, and the following Disclaimer and Export Compliance + * provision in the documentation and/or other materials provided with the + * distribution. + * + * 3.4. Intel retains all right, title, and interest in and to the Original + * Intel Code. + * + * 3.5. Neither the name Intel nor any other trademark owned or controlled by + * Intel shall be used in advertising or otherwise to promote the sale, use or + * other dealings in products derived from or relating to the Covered Code + * without prior written authorization from Intel. + * + * 4. Disclaimer and Export Compliance + * + * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED + * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE + * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, + * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY + * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY + * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A + * PARTICULAR PURPOSE. + * + * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES + * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR + * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, + * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY + * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL + * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS + * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY + * LIMITED REMEDY. + * + * 4.3. Licensee shall not export, either directly or indirectly, any of this + * software or system incorporating such software without first obtaining any + * required license or other approval from the U. S. Department of Commerce or + * any other agency or department of the United States Government. In the + * event Licensee exports any such software from the United States or + * re-exports any such software from a foreign destination, Licensee shall + * ensure that the distribution and export/re-export of the software is in + * compliance with all laws, regulations, orders, or other restrictions of the + * U.S. Export Administration Regulations. Licensee agrees that neither it nor + * any of its subsidiaries will export/re-export any technical data, process, + * software, or service, directly or indirectly, to any country for which the + * United States government or any agency thereof requires an export license, + * other governmental approval, or letter of assurance, without first obtaining + * such license, approval or letter. + * + *****************************************************************************/  #include "aecommon.h" @@ -149,18 +221,22 @@ static AE_DEBUG_REGIONS     AeRegions;  BOOLEAN                     AcpiGbl_DisplayRegionAccess = FALSE;  /* - * We will override some of the default region handlers, especially the - * SystemMemory handler, which must be implemented locally. Do not override - * the PCI_Config handler since we would like to exercise the default handler - * code. These handlers are installed "early" - before any _REG methods + * We will override some of the default region handlers, especially + * the SystemMemory handler, which must be implemented locally. + * These handlers are installed "early" - before any _REG methods   * are executed - since they are special in the sense that the ACPI spec   * declares that they must "always be available". Cannot override the   * DataTable region handler either -- needed for test execution. + * + * NOTE: The local region handler will simulate access to these address + * spaces by creating a memory buffer behind each operation region.   */  static ACPI_ADR_SPACE_TYPE  DefaultSpaceIdList[] =  {      ACPI_ADR_SPACE_SYSTEM_MEMORY, -    ACPI_ADR_SPACE_SYSTEM_IO +    ACPI_ADR_SPACE_SYSTEM_IO, +    ACPI_ADR_SPACE_PCI_CONFIG, +    ACPI_ADR_SPACE_EC  };  /* @@ -1152,13 +1228,20 @@ AeRegionHandler (      ACPI_OPERAND_OBJECT     *RegionObject = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, RegionContext);      UINT8                   *Buffer = ACPI_CAST_PTR (UINT8, Value); +    UINT8                   *OldBuffer; +    UINT8                   *NewBuffer;      ACPI_PHYSICAL_ADDRESS   BaseAddress; +    ACPI_PHYSICAL_ADDRESS   BaseAddressEnd; +    ACPI_PHYSICAL_ADDRESS   RegionAddress; +    ACPI_PHYSICAL_ADDRESS   RegionAddressEnd;      ACPI_SIZE               Length;      BOOLEAN                 BufferExists; +    BOOLEAN                 BufferResize;      AE_REGION               *RegionElement;      void                    *BufferValue;      ACPI_STATUS             Status;      UINT32                  ByteWidth; +    UINT32                  RegionLength;      UINT32                  i;      UINT8                   SpaceId;      ACPI_CONNECTION_INFO    *MyContext; @@ -1441,21 +1524,119 @@ AeRegionHandler (       * Search through the linked list for this region's buffer       */      BufferExists = FALSE; +    BufferResize = FALSE;      RegionElement = AeRegions.RegionList;      if (AeRegions.NumberOfRegions)      { +        BaseAddressEnd = BaseAddress + Length - 1;          while (!BufferExists && RegionElement)          { -            if (RegionElement->Address == BaseAddress && -                RegionElement->Length == Length && -                RegionElement->SpaceId == SpaceId) +            RegionAddress = RegionElement->Address; +            RegionAddressEnd = RegionElement->Address + RegionElement->Length - 1; +            RegionLength = RegionElement->Length; + +            /* +             * Overlapping Region Support +             * +             * While searching through the region buffer list, determine if an +             * overlap exists between the requested buffer space and the current +             * RegionElement space. If there is an overlap then replace the old +             * buffer with a new buffer of increased size before continuing to +             * do the read or write +             */ +            if (RegionElement->SpaceId != SpaceId || +                BaseAddressEnd < RegionAddress || +                BaseAddress > RegionAddressEnd)              { -                BufferExists = TRUE; +                /* +                 * Requested buffer is outside of the current RegionElement +                 * bounds +                 */ +                RegionElement = RegionElement->NextRegion;              }              else              { -                RegionElement = RegionElement->NextRegion; +                /* +                 * Some amount of buffer space sharing exists. There are 4 cases +                 * to consider: +                 * +                 * 1. Right overlap +                 * 2. Left overlap +                 * 3. Left and right overlap +                 * 4. Fully contained - no resizing required +                 */ +                BufferExists = TRUE; + +                if ((BaseAddress >= RegionAddress) && +                    (BaseAddress <= RegionAddressEnd) && +                    (BaseAddressEnd > RegionAddressEnd)) +                { +                    /* Right overlap */ + +                    RegionElement->Length = BaseAddress - +                        RegionAddress + Length; +                    BufferResize = TRUE; +                } + +                 else if ((BaseAddressEnd >= RegionAddress) && +                         (BaseAddressEnd <= RegionAddressEnd) && +                         (BaseAddress < RegionAddress)) +                { +                    /* Left overlap */ + +                    RegionElement->Address = BaseAddress; +                    RegionElement->Length = RegionAddress - +                        BaseAddress + RegionElement->Length; +                    BufferResize = TRUE; +                } + +                else if ((BaseAddress < RegionAddress) && +                         (BaseAddressEnd > RegionAddressEnd)) +                { +                    /* Left and right overlap */ + +                    RegionElement->Address = BaseAddress; +                    RegionElement->Length = Length; +                    BufferResize = TRUE; +                } + +                /* +                 * only remaining case is fully contained for which we don't +                 * need to do anything +                 */ +                if (BufferResize) +                { +                    NewBuffer = AcpiOsAllocate (RegionElement->Length); +                    if (!NewBuffer) +                    { +                        return (AE_NO_MEMORY); +                    } + +                    OldBuffer = RegionElement->Buffer; +                    RegionElement->Buffer = NewBuffer; +                    NewBuffer = NULL; + +                    /* Initialize the region with the default fill value */ + +                    ACPI_MEMSET (RegionElement->Buffer, +                        AcpiGbl_RegionFillValue, RegionElement->Length); + +                    /* +                     * Get BufferValue to point (within the new buffer) to the +                     * base address of the old buffer +                     */ +                    BufferValue = (UINT8 *) RegionElement->Buffer + +                        (UINT64) RegionAddress - +                        (UINT64) RegionElement->Address; + +                    /* +                     * Copy the old buffer to its same location within the new +                     * buffer +                     */ +                    ACPI_MEMCPY (BufferValue, OldBuffer, RegionLength); +                    AcpiOsFree (OldBuffer); +                }              }          }      } @@ -1465,9 +1646,8 @@ AeRegionHandler (       */      if (!BufferExists)      { -        /* -         * Do the memory allocations first -         */ +        /* Do the memory allocations first */ +          RegionElement = AcpiOsAllocate (sizeof (AE_REGION));          if (!RegionElement)          { @@ -1492,8 +1672,8 @@ AeRegionHandler (          /*           * Increment the number of regions and put this one -         *  at the head of the list as it will probably get accessed -         *  more often anyway. +         * at the head of the list as it will probably get accessed +         * more often anyway.           */          AeRegions.NumberOfRegions += 1; @@ -1505,9 +1685,8 @@ AeRegionHandler (          AeRegions.RegionList = RegionElement;      } -    /* -     * Calculate the size of the memory copy -     */ +    /* Calculate the size of the memory copy */ +      ByteWidth = (BitWidth / 8);      if (BitWidth % 8)  | 
