LCOV - code coverage report
Current view: top level - drivers/acpi/acpica - exregion.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 73 128 57.0 %
Date: 2022-03-28 16:04:14 Functions: 3 6 50.0 %
Branches: 13 37 35.1 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
       2                 :            : /******************************************************************************
       3                 :            :  *
       4                 :            :  * Module Name: exregion - ACPI default op_region (address space) handlers
       5                 :            :  *
       6                 :            :  * Copyright (C) 2000 - 2020, Intel Corp.
       7                 :            :  *
       8                 :            :  *****************************************************************************/
       9                 :            : 
      10                 :            : #include <acpi/acpi.h>
      11                 :            : #include "accommon.h"
      12                 :            : #include "acinterp.h"
      13                 :            : 
      14                 :            : #define _COMPONENT          ACPI_EXECUTER
      15                 :            : ACPI_MODULE_NAME("exregion")
      16                 :            : 
      17                 :            : /*******************************************************************************
      18                 :            :  *
      19                 :            :  * FUNCTION:    acpi_ex_system_memory_space_handler
      20                 :            :  *
      21                 :            :  * PARAMETERS:  function            - Read or Write operation
      22                 :            :  *              address             - Where in the space to read or write
      23                 :            :  *              bit_width           - Field width in bits (8, 16, or 32)
      24                 :            :  *              value               - Pointer to in or out value
      25                 :            :  *              handler_context     - Pointer to Handler's context
      26                 :            :  *              region_context      - Pointer to context specific to the
      27                 :            :  *                                    accessed region
      28                 :            :  *
      29                 :            :  * RETURN:      Status
      30                 :            :  *
      31                 :            :  * DESCRIPTION: Handler for the System Memory address space (Op Region)
      32                 :            :  *
      33                 :            :  ******************************************************************************/
      34                 :            : acpi_status
      35                 :        104 : acpi_ex_system_memory_space_handler(u32 function,
      36                 :            :                                     acpi_physical_address address,
      37                 :            :                                     u32 bit_width,
      38                 :            :                                     u64 *value,
      39                 :            :                                     void *handler_context, void *region_context)
      40                 :            : {
      41                 :        104 :         acpi_status status = AE_OK;
      42                 :        104 :         void *logical_addr_ptr = NULL;
      43                 :        104 :         struct acpi_mem_space_context *mem_info = region_context;
      44                 :        104 :         u32 length;
      45                 :        104 :         acpi_size map_length;
      46                 :        104 :         acpi_size page_boundary_map_length;
      47                 :            : #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
      48                 :            :         u32 remainder;
      49                 :            : #endif
      50                 :            : 
      51                 :        104 :         ACPI_FUNCTION_TRACE(ex_system_memory_space_handler);
      52                 :            : 
      53                 :            :         /* Validate and translate the bit width */
      54                 :            : 
      55   [ -  +  -  -  :        104 :         switch (bit_width) {
                      - ]
      56                 :            :         case 8:
      57                 :            : 
      58                 :            :                 length = 1;
      59                 :            :                 break;
      60                 :            : 
      61                 :          0 :         case 16:
      62                 :            : 
      63                 :          0 :                 length = 2;
      64                 :          0 :                 break;
      65                 :            : 
      66                 :        104 :         case 32:
      67                 :            : 
      68                 :        104 :                 length = 4;
      69                 :        104 :                 break;
      70                 :            : 
      71                 :          0 :         case 64:
      72                 :            : 
      73                 :          0 :                 length = 8;
      74                 :          0 :                 break;
      75                 :            : 
      76                 :          0 :         default:
      77                 :            : 
      78                 :          0 :                 ACPI_ERROR((AE_INFO, "Invalid SystemMemory width %u",
      79                 :            :                             bit_width));
      80                 :          0 :                 return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
      81                 :            :         }
      82                 :            : 
      83                 :            : #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
      84                 :            :         /*
      85                 :            :          * Hardware does not support non-aligned data transfers, we must verify
      86                 :            :          * the request.
      87                 :            :          */
      88                 :            :         (void)acpi_ut_short_divide((u64) address, length, NULL, &remainder);
      89                 :            :         if (remainder != 0) {
      90                 :            :                 return_ACPI_STATUS(AE_AML_ALIGNMENT);
      91                 :            :         }
      92                 :            : #endif
      93                 :            : 
      94                 :            :         /*
      95                 :            :          * Does the request fit into the cached memory mapping?
      96                 :            :          * Is 1) Address below the current mapping? OR
      97                 :            :          *    2) Address beyond the current mapping?
      98                 :            :          */
      99         [ +  - ]:        104 :         if ((address < mem_info->mapped_physical_address) ||
     100                 :        104 :             (((u64) address + length) > ((u64)
     101                 :        104 :                                          mem_info->mapped_physical_address +
     102         [ +  + ]:        104 :                                          mem_info->mapped_length))) {
     103                 :            :                 /*
     104                 :            :                  * The request cannot be resolved by the current memory mapping;
     105                 :            :                  * Delete the existing mapping and create a new one.
     106                 :            :                  */
     107         [ -  + ]:         13 :                 if (mem_info->mapped_length) {
     108                 :            : 
     109                 :            :                         /* Valid mapping, delete it */
     110                 :            : 
     111                 :          0 :                         acpi_os_unmap_memory(mem_info->mapped_logical_address,
     112                 :            :                                              mem_info->mapped_length);
     113                 :            :                 }
     114                 :            : 
     115                 :            :                 /*
     116                 :            :                  * October 2009: Attempt to map from the requested address to the
     117                 :            :                  * end of the region. However, we will never map more than one
     118                 :            :                  * page, nor will we cross a page boundary.
     119                 :            :                  */
     120                 :         13 :                 map_length = (acpi_size)
     121                 :         13 :                     ((mem_info->address + mem_info->length) - address);
     122                 :            : 
     123                 :            :                 /*
     124                 :            :                  * If mapping the entire remaining portion of the region will cross
     125                 :            :                  * a page boundary, just map up to the page boundary, do not cross.
     126                 :            :                  * On some systems, crossing a page boundary while mapping regions
     127                 :            :                  * can cause warnings if the pages have different attributes
     128                 :            :                  * due to resource management.
     129                 :            :                  *
     130                 :            :                  * This has the added benefit of constraining a single mapping to
     131                 :            :                  * one page, which is similar to the original code that used a 4k
     132                 :            :                  * maximum window.
     133                 :            :                  */
     134                 :         13 :                 page_boundary_map_length = (acpi_size)
     135                 :         13 :                     (ACPI_ROUND_UP(address, ACPI_DEFAULT_PAGE_SIZE) - address);
     136         [ +  - ]:         13 :                 if (page_boundary_map_length == 0) {
     137                 :         13 :                         page_boundary_map_length = ACPI_DEFAULT_PAGE_SIZE;
     138                 :            :                 }
     139                 :            : 
     140                 :         13 :                 if (map_length > page_boundary_map_length) {
     141                 :            :                         map_length = page_boundary_map_length;
     142                 :            :                 }
     143                 :            : 
     144                 :            :                 /* Create a new mapping starting at the address given */
     145                 :            : 
     146                 :         26 :                 mem_info->mapped_logical_address =
     147                 :         13 :                     acpi_os_map_memory(address, map_length);
     148         [ -  + ]:         13 :                 if (!mem_info->mapped_logical_address) {
     149                 :          0 :                         ACPI_ERROR((AE_INFO,
     150                 :            :                                     "Could not map memory at 0x%8.8X%8.8X, size %u",
     151                 :            :                                     ACPI_FORMAT_UINT64(address),
     152                 :            :                                     (u32)map_length));
     153                 :          0 :                         mem_info->mapped_length = 0;
     154                 :          0 :                         return_ACPI_STATUS(AE_NO_MEMORY);
     155                 :            :                 }
     156                 :            : 
     157                 :            :                 /* Save the physical address and mapping size */
     158                 :            : 
     159                 :         13 :                 mem_info->mapped_physical_address = address;
     160                 :         13 :                 mem_info->mapped_length = map_length;
     161                 :            :         }
     162                 :            : 
     163                 :            :         /*
     164                 :            :          * Generate a logical pointer corresponding to the address we want to
     165                 :            :          * access
     166                 :            :          */
     167                 :        104 :         logical_addr_ptr = mem_info->mapped_logical_address +
     168                 :        104 :             ((u64) address - (u64) mem_info->mapped_physical_address);
     169                 :            : 
     170                 :            :         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
     171                 :            :                           "System-Memory (width %u) R/W %u Address=%8.8X%8.8X\n",
     172                 :        104 :                           bit_width, function, ACPI_FORMAT_UINT64(address)));
     173                 :            : 
     174                 :            :         /*
     175                 :            :          * Perform the memory read or write
     176                 :            :          *
     177                 :            :          * Note: For machines that do not support non-aligned transfers, the target
     178                 :            :          * address was checked for alignment above. We do not attempt to break the
     179                 :            :          * transfer up into smaller (byte-size) chunks because the AML specifically
     180                 :            :          * asked for a transfer width that the hardware may require.
     181                 :            :          */
     182      [ +  -  - ]:        104 :         switch (function) {
     183                 :        104 :         case ACPI_READ:
     184                 :            : 
     185                 :        104 :                 *value = 0;
     186   [ -  -  +  -  :        104 :                 switch (bit_width) {
                      - ]
     187                 :          0 :                 case 8:
     188                 :            : 
     189                 :          0 :                         *value = (u64)ACPI_GET8(logical_addr_ptr);
     190                 :          0 :                         break;
     191                 :            : 
     192                 :          0 :                 case 16:
     193                 :            : 
     194                 :          0 :                         *value = (u64)ACPI_GET16(logical_addr_ptr);
     195                 :          0 :                         break;
     196                 :            : 
     197                 :        104 :                 case 32:
     198                 :            : 
     199                 :        104 :                         *value = (u64)ACPI_GET32(logical_addr_ptr);
     200                 :        104 :                         break;
     201                 :            : 
     202                 :          0 :                 case 64:
     203                 :            : 
     204                 :          0 :                         *value = (u64)ACPI_GET64(logical_addr_ptr);
     205                 :          0 :                         break;
     206                 :            : 
     207                 :            :                 default:
     208                 :            : 
     209                 :            :                         /* bit_width was already validated */
     210                 :            : 
     211                 :            :                         break;
     212                 :            :                 }
     213                 :            :                 break;
     214                 :            : 
     215                 :          0 :         case ACPI_WRITE:
     216                 :            : 
     217   [ #  #  #  #  :          0 :                 switch (bit_width) {
                      # ]
     218                 :          0 :                 case 8:
     219                 :            : 
     220                 :          0 :                         ACPI_SET8(logical_addr_ptr, *value);
     221                 :          0 :                         break;
     222                 :            : 
     223                 :          0 :                 case 16:
     224                 :            : 
     225                 :          0 :                         ACPI_SET16(logical_addr_ptr, *value);
     226                 :          0 :                         break;
     227                 :            : 
     228                 :          0 :                 case 32:
     229                 :            : 
     230                 :          0 :                         ACPI_SET32(logical_addr_ptr, *value);
     231                 :          0 :                         break;
     232                 :            : 
     233                 :          0 :                 case 64:
     234                 :            : 
     235                 :          0 :                         ACPI_SET64(logical_addr_ptr, *value);
     236                 :          0 :                         break;
     237                 :            : 
     238                 :            :                 default:
     239                 :            : 
     240                 :            :                         /* bit_width was already validated */
     241                 :            : 
     242                 :            :                         break;
     243                 :            :                 }
     244                 :            :                 break;
     245                 :            : 
     246                 :            :         default:
     247                 :            : 
     248                 :            :                 status = AE_BAD_PARAMETER;
     249                 :            :                 break;
     250                 :            :         }
     251                 :            : 
     252                 :            :         return_ACPI_STATUS(status);
     253                 :            : }
     254                 :            : 
     255                 :            : /*******************************************************************************
     256                 :            :  *
     257                 :            :  * FUNCTION:    acpi_ex_system_io_space_handler
     258                 :            :  *
     259                 :            :  * PARAMETERS:  function            - Read or Write operation
     260                 :            :  *              address             - Where in the space to read or write
     261                 :            :  *              bit_width           - Field width in bits (8, 16, or 32)
     262                 :            :  *              value               - Pointer to in or out value
     263                 :            :  *              handler_context     - Pointer to Handler's context
     264                 :            :  *              region_context      - Pointer to context specific to the
     265                 :            :  *                                    accessed region
     266                 :            :  *
     267                 :            :  * RETURN:      Status
     268                 :            :  *
     269                 :            :  * DESCRIPTION: Handler for the System IO address space (Op Region)
     270                 :            :  *
     271                 :            :  ******************************************************************************/
     272                 :            : 
     273                 :            : acpi_status
     274                 :         65 : acpi_ex_system_io_space_handler(u32 function,
     275                 :            :                                 acpi_physical_address address,
     276                 :            :                                 u32 bit_width,
     277                 :            :                                 u64 *value,
     278                 :            :                                 void *handler_context, void *region_context)
     279                 :            : {
     280                 :         65 :         acpi_status status = AE_OK;
     281                 :         65 :         u32 value32;
     282                 :            : 
     283                 :         65 :         ACPI_FUNCTION_TRACE(ex_system_io_space_handler);
     284                 :            : 
     285                 :            :         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
     286                 :            :                           "System-IO (width %u) R/W %u Address=%8.8X%8.8X\n",
     287                 :         65 :                           bit_width, function, ACPI_FORMAT_UINT64(address)));
     288                 :            : 
     289                 :            :         /* Decode the function parameter */
     290                 :            : 
     291      [ +  +  - ]:         65 :         switch (function) {
     292                 :         26 :         case ACPI_READ:
     293                 :            : 
     294                 :         26 :                 status = acpi_hw_read_port((acpi_io_address)address,
     295                 :            :                                            &value32, bit_width);
     296                 :         26 :                 *value = value32;
     297                 :         26 :                 break;
     298                 :            : 
     299                 :         39 :         case ACPI_WRITE:
     300                 :            : 
     301                 :         39 :                 status = acpi_hw_write_port((acpi_io_address)address,
     302                 :         39 :                                             (u32)*value, bit_width);
     303                 :         39 :                 break;
     304                 :            : 
     305                 :            :         default:
     306                 :            : 
     307                 :            :                 status = AE_BAD_PARAMETER;
     308                 :            :                 break;
     309                 :            :         }
     310                 :            : 
     311                 :         65 :         return_ACPI_STATUS(status);
     312                 :            : }
     313                 :            : 
     314                 :            : #ifdef ACPI_PCI_CONFIGURED
     315                 :            : /*******************************************************************************
     316                 :            :  *
     317                 :            :  * FUNCTION:    acpi_ex_pci_config_space_handler
     318                 :            :  *
     319                 :            :  * PARAMETERS:  function            - Read or Write operation
     320                 :            :  *              address             - Where in the space to read or write
     321                 :            :  *              bit_width           - Field width in bits (8, 16, or 32)
     322                 :            :  *              value               - Pointer to in or out value
     323                 :            :  *              handler_context     - Pointer to Handler's context
     324                 :            :  *              region_context      - Pointer to context specific to the
     325                 :            :  *                                    accessed region
     326                 :            :  *
     327                 :            :  * RETURN:      Status
     328                 :            :  *
     329                 :            :  * DESCRIPTION: Handler for the PCI Config address space (Op Region)
     330                 :            :  *
     331                 :            :  ******************************************************************************/
     332                 :            : 
     333                 :            : acpi_status
     334                 :        611 : acpi_ex_pci_config_space_handler(u32 function,
     335                 :            :                                  acpi_physical_address address,
     336                 :            :                                  u32 bit_width,
     337                 :            :                                  u64 *value,
     338                 :            :                                  void *handler_context, void *region_context)
     339                 :            : {
     340                 :        611 :         acpi_status status = AE_OK;
     341                 :        611 :         struct acpi_pci_id *pci_id;
     342                 :        611 :         u16 pci_register;
     343                 :            : 
     344                 :        611 :         ACPI_FUNCTION_TRACE(ex_pci_config_space_handler);
     345                 :            : 
     346                 :            :         /*
     347                 :            :          *  The arguments to acpi_os(Read|Write)pci_configuration are:
     348                 :            :          *
     349                 :            :          *  pci_segment is the PCI bus segment range 0-31
     350                 :            :          *  pci_bus     is the PCI bus number range 0-255
     351                 :            :          *  pci_device  is the PCI device number range 0-31
     352                 :            :          *  pci_function is the PCI device function number
     353                 :            :          *  pci_register is the Config space register range 0-255 bytes
     354                 :            :          *
     355                 :            :          *  value - input value for write, output address for read
     356                 :            :          *
     357                 :            :          */
     358                 :        611 :         pci_id = (struct acpi_pci_id *)region_context;
     359                 :        611 :         pci_register = (u16) (u32) address;
     360                 :            : 
     361                 :            :         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
     362                 :            :                           "Pci-Config %u (%u) Seg(%04x) Bus(%04x) "
     363                 :            :                           "Dev(%04x) Func(%04x) Reg(%04x)\n",
     364                 :            :                           function, bit_width, pci_id->segment, pci_id->bus,
     365                 :        611 :                           pci_id->device, pci_id->function, pci_register));
     366                 :            : 
     367      [ +  +  - ]:        611 :         switch (function) {
     368                 :        546 :         case ACPI_READ:
     369                 :            : 
     370                 :        546 :                 *value = 0;
     371                 :        546 :                 status =
     372                 :        546 :                     acpi_os_read_pci_configuration(pci_id, pci_register, value,
     373                 :            :                                                    bit_width);
     374                 :        546 :                 break;
     375                 :            : 
     376                 :         65 :         case ACPI_WRITE:
     377                 :            : 
     378                 :         65 :                 status =
     379                 :         65 :                     acpi_os_write_pci_configuration(pci_id, pci_register,
     380                 :            :                                                     *value, bit_width);
     381                 :         65 :                 break;
     382                 :            : 
     383                 :            :         default:
     384                 :            : 
     385                 :            :                 status = AE_BAD_PARAMETER;
     386                 :            :                 break;
     387                 :            :         }
     388                 :            : 
     389                 :        611 :         return_ACPI_STATUS(status);
     390                 :            : }
     391                 :            : #endif
     392                 :            : 
     393                 :            : /*******************************************************************************
     394                 :            :  *
     395                 :            :  * FUNCTION:    acpi_ex_cmos_space_handler
     396                 :            :  *
     397                 :            :  * PARAMETERS:  function            - Read or Write operation
     398                 :            :  *              address             - Where in the space to read or write
     399                 :            :  *              bit_width           - Field width in bits (8, 16, or 32)
     400                 :            :  *              value               - Pointer to in or out value
     401                 :            :  *              handler_context     - Pointer to Handler's context
     402                 :            :  *              region_context      - Pointer to context specific to the
     403                 :            :  *                                    accessed region
     404                 :            :  *
     405                 :            :  * RETURN:      Status
     406                 :            :  *
     407                 :            :  * DESCRIPTION: Handler for the CMOS address space (Op Region)
     408                 :            :  *
     409                 :            :  ******************************************************************************/
     410                 :            : 
     411                 :            : acpi_status
     412                 :          0 : acpi_ex_cmos_space_handler(u32 function,
     413                 :            :                            acpi_physical_address address,
     414                 :            :                            u32 bit_width,
     415                 :            :                            u64 *value,
     416                 :            :                            void *handler_context, void *region_context)
     417                 :            : {
     418                 :          0 :         acpi_status status = AE_OK;
     419                 :            : 
     420                 :          0 :         ACPI_FUNCTION_TRACE(ex_cmos_space_handler);
     421                 :            : 
     422                 :          0 :         return_ACPI_STATUS(status);
     423                 :            : }
     424                 :            : 
     425                 :            : #ifdef ACPI_PCI_CONFIGURED
     426                 :            : /*******************************************************************************
     427                 :            :  *
     428                 :            :  * FUNCTION:    acpi_ex_pci_bar_space_handler
     429                 :            :  *
     430                 :            :  * PARAMETERS:  function            - Read or Write operation
     431                 :            :  *              address             - Where in the space to read or write
     432                 :            :  *              bit_width           - Field width in bits (8, 16, or 32)
     433                 :            :  *              value               - Pointer to in or out value
     434                 :            :  *              handler_context     - Pointer to Handler's context
     435                 :            :  *              region_context      - Pointer to context specific to the
     436                 :            :  *                                    accessed region
     437                 :            :  *
     438                 :            :  * RETURN:      Status
     439                 :            :  *
     440                 :            :  * DESCRIPTION: Handler for the PCI bar_target address space (Op Region)
     441                 :            :  *
     442                 :            :  ******************************************************************************/
     443                 :            : 
     444                 :            : acpi_status
     445                 :          0 : acpi_ex_pci_bar_space_handler(u32 function,
     446                 :            :                               acpi_physical_address address,
     447                 :            :                               u32 bit_width,
     448                 :            :                               u64 *value,
     449                 :            :                               void *handler_context, void *region_context)
     450                 :            : {
     451                 :          0 :         acpi_status status = AE_OK;
     452                 :            : 
     453                 :          0 :         ACPI_FUNCTION_TRACE(ex_pci_bar_space_handler);
     454                 :            : 
     455                 :          0 :         return_ACPI_STATUS(status);
     456                 :            : }
     457                 :            : #endif
     458                 :            : 
     459                 :            : /*******************************************************************************
     460                 :            :  *
     461                 :            :  * FUNCTION:    acpi_ex_data_table_space_handler
     462                 :            :  *
     463                 :            :  * PARAMETERS:  function            - Read or Write operation
     464                 :            :  *              address             - Where in the space to read or write
     465                 :            :  *              bit_width           - Field width in bits (8, 16, or 32)
     466                 :            :  *              value               - Pointer to in or out value
     467                 :            :  *              handler_context     - Pointer to Handler's context
     468                 :            :  *              region_context      - Pointer to context specific to the
     469                 :            :  *                                    accessed region
     470                 :            :  *
     471                 :            :  * RETURN:      Status
     472                 :            :  *
     473                 :            :  * DESCRIPTION: Handler for the Data Table address space (Op Region)
     474                 :            :  *
     475                 :            :  ******************************************************************************/
     476                 :            : 
     477                 :            : acpi_status
     478                 :          0 : acpi_ex_data_table_space_handler(u32 function,
     479                 :            :                                  acpi_physical_address address,
     480                 :            :                                  u32 bit_width,
     481                 :            :                                  u64 *value,
     482                 :            :                                  void *handler_context, void *region_context)
     483                 :            : {
     484                 :          0 :         ACPI_FUNCTION_TRACE(ex_data_table_space_handler);
     485                 :            : 
     486                 :            :         /*
     487                 :            :          * Perform the memory read or write. The bit_width was already
     488                 :            :          * validated.
     489                 :            :          */
     490      [ #  #  # ]:          0 :         switch (function) {
     491                 :          0 :         case ACPI_READ:
     492                 :            : 
     493                 :          0 :                 memcpy(ACPI_CAST_PTR(char, value),
     494                 :          0 :                        ACPI_PHYSADDR_TO_PTR(address), ACPI_DIV_8(bit_width));
     495                 :          0 :                 break;
     496                 :            : 
     497                 :          0 :         case ACPI_WRITE:
     498                 :            : 
     499                 :          0 :                 memcpy(ACPI_PHYSADDR_TO_PTR(address),
     500                 :          0 :                        ACPI_CAST_PTR(char, value), ACPI_DIV_8(bit_width));
     501                 :          0 :                 break;
     502                 :            : 
     503                 :            :         default:
     504                 :            : 
     505                 :            :                 return_ACPI_STATUS(AE_BAD_PARAMETER);
     506                 :            :         }
     507                 :            : 
     508                 :            :         return_ACPI_STATUS(AE_OK);
     509                 :            : }

Generated by: LCOV version 1.14