Home | History | Annotate | Line # | Download | only in executer
exregion.c revision 1.1.1.2
      1 
      2 /******************************************************************************
      3  *
      4  * Module Name: exregion - ACPI default OpRegion (address space) handlers
      5  *
      6  *****************************************************************************/
      7 
      8 /*
      9  * Copyright (C) 2000 - 2011, Intel Corp.
     10  * All rights reserved.
     11  *
     12  * Redistribution and use in source and binary forms, with or without
     13  * modification, are permitted provided that the following conditions
     14  * are met:
     15  * 1. Redistributions of source code must retain the above copyright
     16  *    notice, this list of conditions, and the following disclaimer,
     17  *    without modification.
     18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     19  *    substantially similar to the "NO WARRANTY" disclaimer below
     20  *    ("Disclaimer") and any redistribution must be conditioned upon
     21  *    including a substantially similar Disclaimer requirement for further
     22  *    binary redistribution.
     23  * 3. Neither the names of the above-listed copyright holders nor the names
     24  *    of any contributors may be used to endorse or promote products derived
     25  *    from this software without specific prior written permission.
     26  *
     27  * Alternatively, this software may be distributed under the terms of the
     28  * GNU General Public License ("GPL") version 2 as published by the Free
     29  * Software Foundation.
     30  *
     31  * NO WARRANTY
     32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     42  * POSSIBILITY OF SUCH DAMAGES.
     43  */
     44 
     45 
     46 #define __EXREGION_C__
     47 
     48 #include "acpi.h"
     49 #include "accommon.h"
     50 #include "acinterp.h"
     51 
     52 
     53 #define _COMPONENT          ACPI_EXECUTER
     54         ACPI_MODULE_NAME    ("exregion")
     55 
     56 
     57 /*******************************************************************************
     58  *
     59  * FUNCTION:    AcpiExSystemMemorySpaceHandler
     60  *
     61  * PARAMETERS:  Function            - Read or Write operation
     62  *              Address             - Where in the space to read or write
     63  *              BitWidth            - Field width in bits (8, 16, or 32)
     64  *              Value               - Pointer to in or out value
     65  *              HandlerContext      - Pointer to Handler's context
     66  *              RegionContext       - Pointer to context specific to the
     67  *                                    accessed region
     68  *
     69  * RETURN:      Status
     70  *
     71  * DESCRIPTION: Handler for the System Memory address space (Op Region)
     72  *
     73  ******************************************************************************/
     74 
     75 ACPI_STATUS
     76 AcpiExSystemMemorySpaceHandler (
     77     UINT32                  Function,
     78     ACPI_PHYSICAL_ADDRESS   Address,
     79     UINT32                  BitWidth,
     80     UINT64                  *Value,
     81     void                    *HandlerContext,
     82     void                    *RegionContext)
     83 {
     84     ACPI_STATUS             Status = AE_OK;
     85     void                    *LogicalAddrPtr = NULL;
     86     ACPI_MEM_SPACE_CONTEXT  *MemInfo = RegionContext;
     87     UINT32                  Length;
     88     ACPI_SIZE               MapLength;
     89     ACPI_SIZE               PageBoundaryMapLength;
     90 #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
     91     UINT32                  Remainder;
     92 #endif
     93 
     94 
     95     ACPI_FUNCTION_TRACE (ExSystemMemorySpaceHandler);
     96 
     97 
     98     /* Validate and translate the bit width */
     99 
    100     switch (BitWidth)
    101     {
    102     case 8:
    103         Length = 1;
    104         break;
    105 
    106     case 16:
    107         Length = 2;
    108         break;
    109 
    110     case 32:
    111         Length = 4;
    112         break;
    113 
    114     case 64:
    115         Length = 8;
    116         break;
    117 
    118     default:
    119         ACPI_ERROR ((AE_INFO, "Invalid SystemMemory width %u",
    120             BitWidth));
    121         return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
    122     }
    123 
    124 #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
    125     /*
    126      * Hardware does not support non-aligned data transfers, we must verify
    127      * the request.
    128      */
    129     (void) AcpiUtShortDivide ((UINT64) Address, Length, NULL, &Remainder);
    130     if (Remainder != 0)
    131     {
    132         return_ACPI_STATUS (AE_AML_ALIGNMENT);
    133     }
    134 #endif
    135 
    136     /*
    137      * Does the request fit into the cached memory mapping?
    138      * Is 1) Address below the current mapping? OR
    139      *    2) Address beyond the current mapping?
    140      */
    141     if ((Address < MemInfo->MappedPhysicalAddress) ||
    142         (((UINT64) Address + Length) >
    143             ((UINT64)
    144             MemInfo->MappedPhysicalAddress + MemInfo->MappedLength)))
    145     {
    146         /*
    147          * The request cannot be resolved by the current memory mapping;
    148          * Delete the existing mapping and create a new one.
    149          */
    150         if (MemInfo->MappedLength)
    151         {
    152             /* Valid mapping, delete it */
    153 
    154             AcpiOsUnmapMemory (MemInfo->MappedLogicalAddress,
    155                 MemInfo->MappedLength);
    156         }
    157 
    158         /*
    159          * October 2009: Attempt to map from the requested address to the
    160          * end of the region. However, we will never map more than one
    161          * page, nor will we cross a page boundary.
    162          */
    163         MapLength = (ACPI_SIZE)
    164             ((MemInfo->Address + MemInfo->Length) - Address);
    165 
    166         /*
    167          * If mapping the entire remaining portion of the region will cross
    168          * a page boundary, just map up to the page boundary, do not cross.
    169          * On some systems, crossing a page boundary while mapping regions
    170          * can cause warnings if the pages have different attributes
    171          * due to resource management.
    172          *
    173          * This has the added benefit of constraining a single mapping to
    174          * one page, which is similar to the original code that used a 4k
    175          * maximum window.
    176          */
    177         PageBoundaryMapLength =
    178             ACPI_ROUND_UP (Address, ACPI_DEFAULT_PAGE_SIZE) - Address;
    179         if (PageBoundaryMapLength == 0)
    180         {
    181             PageBoundaryMapLength = ACPI_DEFAULT_PAGE_SIZE;
    182         }
    183 
    184         if (MapLength > PageBoundaryMapLength)
    185         {
    186             MapLength = PageBoundaryMapLength;
    187         }
    188 
    189         /* Create a new mapping starting at the address given */
    190 
    191         MemInfo->MappedLogicalAddress = AcpiOsMapMemory (
    192             (ACPI_PHYSICAL_ADDRESS) Address, MapLength);
    193         if (!MemInfo->MappedLogicalAddress)
    194         {
    195             ACPI_ERROR ((AE_INFO,
    196                 "Could not map memory at 0x%8.8X%8.8X, size %u",
    197                 ACPI_FORMAT_NATIVE_UINT (Address), (UINT32) MapLength));
    198             MemInfo->MappedLength = 0;
    199             return_ACPI_STATUS (AE_NO_MEMORY);
    200         }
    201 
    202         /* Save the physical address and mapping size */
    203 
    204         MemInfo->MappedPhysicalAddress = Address;
    205         MemInfo->MappedLength = MapLength;
    206     }
    207 
    208     /*
    209      * Generate a logical pointer corresponding to the address we want to
    210      * access
    211      */
    212     LogicalAddrPtr = MemInfo->MappedLogicalAddress +
    213         ((UINT64) Address - (UINT64) MemInfo->MappedPhysicalAddress);
    214 
    215     ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
    216         "System-Memory (width %u) R/W %u Address=%8.8X%8.8X\n",
    217         BitWidth, Function, ACPI_FORMAT_NATIVE_UINT (Address)));
    218 
    219     /*
    220      * Perform the memory read or write
    221      *
    222      * Note: For machines that do not support non-aligned transfers, the target
    223      * address was checked for alignment above.  We do not attempt to break the
    224      * transfer up into smaller (byte-size) chunks because the AML specifically
    225      * asked for a transfer width that the hardware may require.
    226      */
    227     switch (Function)
    228     {
    229     case ACPI_READ:
    230 
    231         *Value = 0;
    232         switch (BitWidth)
    233         {
    234         case 8:
    235             *Value = (UINT64) ACPI_GET8 (LogicalAddrPtr);
    236             break;
    237 
    238         case 16:
    239             *Value = (UINT64) ACPI_GET16 (LogicalAddrPtr);
    240             break;
    241 
    242         case 32:
    243             *Value = (UINT64) ACPI_GET32 (LogicalAddrPtr);
    244             break;
    245 
    246         case 64:
    247             *Value = (UINT64) ACPI_GET64 (LogicalAddrPtr);
    248             break;
    249 
    250         default:
    251             /* BitWidth was already validated */
    252             break;
    253         }
    254         break;
    255 
    256     case ACPI_WRITE:
    257 
    258         switch (BitWidth)
    259         {
    260         case 8:
    261             ACPI_SET8 (LogicalAddrPtr) = (UINT8) *Value;
    262             break;
    263 
    264         case 16:
    265             ACPI_SET16 (LogicalAddrPtr) = (UINT16) *Value;
    266             break;
    267 
    268         case 32:
    269             ACPI_SET32 ( LogicalAddrPtr) = (UINT32) *Value;
    270             break;
    271 
    272         case 64:
    273             ACPI_SET64 (LogicalAddrPtr) = (UINT64) *Value;
    274             break;
    275 
    276         default:
    277             /* BitWidth was already validated */
    278             break;
    279         }
    280         break;
    281 
    282     default:
    283         Status = AE_BAD_PARAMETER;
    284         break;
    285     }
    286 
    287     return_ACPI_STATUS (Status);
    288 }
    289 
    290 
    291 /*******************************************************************************
    292  *
    293  * FUNCTION:    AcpiExSystemIoSpaceHandler
    294  *
    295  * PARAMETERS:  Function            - Read or Write operation
    296  *              Address             - Where in the space to read or write
    297  *              BitWidth            - Field width in bits (8, 16, or 32)
    298  *              Value               - Pointer to in or out value
    299  *              HandlerContext      - Pointer to Handler's context
    300  *              RegionContext       - Pointer to context specific to the
    301  *                                    accessed region
    302  *
    303  * RETURN:      Status
    304  *
    305  * DESCRIPTION: Handler for the System IO address space (Op Region)
    306  *
    307  ******************************************************************************/
    308 
    309 ACPI_STATUS
    310 AcpiExSystemIoSpaceHandler (
    311     UINT32                  Function,
    312     ACPI_PHYSICAL_ADDRESS   Address,
    313     UINT32                  BitWidth,
    314     UINT64                  *Value,
    315     void                    *HandlerContext,
    316     void                    *RegionContext)
    317 {
    318     ACPI_STATUS             Status = AE_OK;
    319     UINT32                  Value32;
    320 
    321 
    322     ACPI_FUNCTION_TRACE (ExSystemIoSpaceHandler);
    323 
    324 
    325     ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
    326         "System-IO (width %u) R/W %u Address=%8.8X%8.8X\n",
    327         BitWidth, Function, ACPI_FORMAT_NATIVE_UINT (Address)));
    328 
    329     /* Decode the function parameter */
    330 
    331     switch (Function)
    332     {
    333     case ACPI_READ:
    334 
    335         Status = AcpiHwReadPort ((ACPI_IO_ADDRESS) Address,
    336                     &Value32, BitWidth);
    337         *Value = Value32;
    338         break;
    339 
    340     case ACPI_WRITE:
    341 
    342         Status = AcpiHwWritePort ((ACPI_IO_ADDRESS) Address,
    343                     (UINT32) *Value, BitWidth);
    344         break;
    345 
    346     default:
    347         Status = AE_BAD_PARAMETER;
    348         break;
    349     }
    350 
    351     return_ACPI_STATUS (Status);
    352 }
    353 
    354 
    355 /*******************************************************************************
    356  *
    357  * FUNCTION:    AcpiExPciConfigSpaceHandler
    358  *
    359  * PARAMETERS:  Function            - Read or Write operation
    360  *              Address             - Where in the space to read or write
    361  *              BitWidth            - Field width in bits (8, 16, or 32)
    362  *              Value               - Pointer to in or out value
    363  *              HandlerContext      - Pointer to Handler's context
    364  *              RegionContext       - Pointer to context specific to the
    365  *                                    accessed region
    366  *
    367  * RETURN:      Status
    368  *
    369  * DESCRIPTION: Handler for the PCI Config address space (Op Region)
    370  *
    371  ******************************************************************************/
    372 
    373 ACPI_STATUS
    374 AcpiExPciConfigSpaceHandler (
    375     UINT32                  Function,
    376     ACPI_PHYSICAL_ADDRESS   Address,
    377     UINT32                  BitWidth,
    378     UINT64                  *Value,
    379     void                    *HandlerContext,
    380     void                    *RegionContext)
    381 {
    382     ACPI_STATUS             Status = AE_OK;
    383     ACPI_PCI_ID             *PciId;
    384     UINT16                  PciRegister;
    385 
    386 
    387     ACPI_FUNCTION_TRACE (ExPciConfigSpaceHandler);
    388 
    389 
    390     /*
    391      *  The arguments to AcpiOs(Read|Write)PciConfiguration are:
    392      *
    393      *  PciSegment  is the PCI bus segment range 0-31
    394      *  PciBus      is the PCI bus number range 0-255
    395      *  PciDevice   is the PCI device number range 0-31
    396      *  PciFunction is the PCI device function number
    397      *  PciRegister is the Config space register range 0-255 bytes
    398      *
    399      *  Value - input value for write, output address for read
    400      *
    401      */
    402     PciId       = (ACPI_PCI_ID *) RegionContext;
    403     PciRegister = (UINT16) (UINT32) Address;
    404 
    405     ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
    406         "Pci-Config %u (%u) Seg(%04x) Bus(%04x) Dev(%04x) Func(%04x) Reg(%04x)\n",
    407         Function, BitWidth, PciId->Segment, PciId->Bus, PciId->Device,
    408         PciId->Function, PciRegister));
    409 
    410     switch (Function)
    411     {
    412     case ACPI_READ:
    413 
    414         *Value = 0;
    415         Status = AcpiOsReadPciConfiguration (PciId, PciRegister,
    416                     Value, BitWidth);
    417         break;
    418 
    419     case ACPI_WRITE:
    420 
    421         Status = AcpiOsWritePciConfiguration (PciId, PciRegister,
    422                     *Value, BitWidth);
    423         break;
    424 
    425     default:
    426 
    427         Status = AE_BAD_PARAMETER;
    428         break;
    429     }
    430 
    431     return_ACPI_STATUS (Status);
    432 }
    433 
    434 
    435 /*******************************************************************************
    436  *
    437  * FUNCTION:    AcpiExCmosSpaceHandler
    438  *
    439  * PARAMETERS:  Function            - Read or Write operation
    440  *              Address             - Where in the space to read or write
    441  *              BitWidth            - Field width in bits (8, 16, or 32)
    442  *              Value               - Pointer to in or out value
    443  *              HandlerContext      - Pointer to Handler's context
    444  *              RegionContext       - Pointer to context specific to the
    445  *                                    accessed region
    446  *
    447  * RETURN:      Status
    448  *
    449  * DESCRIPTION: Handler for the CMOS address space (Op Region)
    450  *
    451  ******************************************************************************/
    452 
    453 ACPI_STATUS
    454 AcpiExCmosSpaceHandler (
    455     UINT32                  Function,
    456     ACPI_PHYSICAL_ADDRESS   Address,
    457     UINT32                  BitWidth,
    458     UINT64                  *Value,
    459     void                    *HandlerContext,
    460     void                    *RegionContext)
    461 {
    462     ACPI_STATUS             Status = AE_OK;
    463 
    464 
    465     ACPI_FUNCTION_TRACE (ExCmosSpaceHandler);
    466 
    467 
    468     return_ACPI_STATUS (Status);
    469 }
    470 
    471 
    472 /*******************************************************************************
    473  *
    474  * FUNCTION:    AcpiExPciBarSpaceHandler
    475  *
    476  * PARAMETERS:  Function            - Read or Write operation
    477  *              Address             - Where in the space to read or write
    478  *              BitWidth            - Field width in bits (8, 16, or 32)
    479  *              Value               - Pointer to in or out value
    480  *              HandlerContext      - Pointer to Handler's context
    481  *              RegionContext       - Pointer to context specific to the
    482  *                                    accessed region
    483  *
    484  * RETURN:      Status
    485  *
    486  * DESCRIPTION: Handler for the PCI BarTarget address space (Op Region)
    487  *
    488  ******************************************************************************/
    489 
    490 ACPI_STATUS
    491 AcpiExPciBarSpaceHandler (
    492     UINT32                  Function,
    493     ACPI_PHYSICAL_ADDRESS   Address,
    494     UINT32                  BitWidth,
    495     UINT64                  *Value,
    496     void                    *HandlerContext,
    497     void                    *RegionContext)
    498 {
    499     ACPI_STATUS             Status = AE_OK;
    500 
    501 
    502     ACPI_FUNCTION_TRACE (ExPciBarSpaceHandler);
    503 
    504 
    505     return_ACPI_STATUS (Status);
    506 }
    507 
    508 
    509 /*******************************************************************************
    510  *
    511  * FUNCTION:    AcpiExDataTableSpaceHandler
    512  *
    513  * PARAMETERS:  Function            - Read or Write operation
    514  *              Address             - Where in the space to read or write
    515  *              BitWidth            - Field width in bits (8, 16, or 32)
    516  *              Value               - Pointer to in or out value
    517  *              HandlerContext      - Pointer to Handler's context
    518  *              RegionContext       - Pointer to context specific to the
    519  *                                    accessed region
    520  *
    521  * RETURN:      Status
    522  *
    523  * DESCRIPTION: Handler for the Data Table address space (Op Region)
    524  *
    525  ******************************************************************************/
    526 
    527 ACPI_STATUS
    528 AcpiExDataTableSpaceHandler (
    529     UINT32                  Function,
    530     ACPI_PHYSICAL_ADDRESS   Address,
    531     UINT32                  BitWidth,
    532     UINT64                  *Value,
    533     void                    *HandlerContext,
    534     void                    *RegionContext)
    535 {
    536     ACPI_FUNCTION_TRACE (ExDataTableSpaceHandler);
    537 
    538 
    539     /*
    540      * Perform the memory read or write. The BitWidth was already
    541      * validated.
    542      */
    543     switch (Function)
    544     {
    545     case ACPI_READ:
    546 
    547         ACPI_MEMCPY (ACPI_CAST_PTR (char, Value), ACPI_PHYSADDR_TO_PTR (Address),
    548             ACPI_DIV_8 (BitWidth));
    549         break;
    550 
    551     case ACPI_WRITE:
    552 
    553         ACPI_MEMCPY (ACPI_PHYSADDR_TO_PTR (Address), ACPI_CAST_PTR (char, Value),
    554             ACPI_DIV_8 (BitWidth));
    555         break;
    556 
    557     default:
    558 
    559         return_ACPI_STATUS (AE_BAD_PARAMETER);
    560     }
    561 
    562     return_ACPI_STATUS (AE_OK);
    563 }
    564 
    565 
    566