LCOV - code coverage report
Current view: top level - drivers/acpi/acpica - exutils.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 77 95 81.1 %
Date: 2022-04-01 14:58:12 Functions: 9 10 90.0 %
Branches: 26 38 68.4 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
       2                 :            : /******************************************************************************
       3                 :            :  *
       4                 :            :  * Module Name: exutils - interpreter/scanner utilities
       5                 :            :  *
       6                 :            :  * Copyright (C) 2000 - 2020, Intel Corp.
       7                 :            :  *
       8                 :            :  *****************************************************************************/
       9                 :            : 
      10                 :            : /*
      11                 :            :  * DEFINE_AML_GLOBALS is tested in amlcode.h
      12                 :            :  * to determine whether certain global names should be "defined" or only
      13                 :            :  * "declared" in the current compilation. This enhances maintainability
      14                 :            :  * by enabling a single header file to embody all knowledge of the names
      15                 :            :  * in question.
      16                 :            :  *
      17                 :            :  * Exactly one module of any executable should #define DEFINE_GLOBALS
      18                 :            :  * before #including the header files which use this convention. The
      19                 :            :  * names in question will be defined and initialized in that module,
      20                 :            :  * and declared as extern in all other modules which #include those
      21                 :            :  * header files.
      22                 :            :  */
      23                 :            : 
      24                 :            : #define DEFINE_AML_GLOBALS
      25                 :            : 
      26                 :            : #include <acpi/acpi.h>
      27                 :            : #include "accommon.h"
      28                 :            : #include "acinterp.h"
      29                 :            : #include "amlcode.h"
      30                 :            : 
      31                 :            : #define _COMPONENT          ACPI_EXECUTER
      32                 :            : ACPI_MODULE_NAME("exutils")
      33                 :            : 
      34                 :            : /* Local prototypes */
      35                 :            : static u32 acpi_ex_digits_needed(u64 value, u32 base);
      36                 :            : 
      37                 :            : /*******************************************************************************
      38                 :            :  *
      39                 :            :  * FUNCTION:    acpi_ex_enter_interpreter
      40                 :            :  *
      41                 :            :  * PARAMETERS:  None
      42                 :            :  *
      43                 :            :  * RETURN:      None
      44                 :            :  *
      45                 :            :  * DESCRIPTION: Enter the interpreter execution region. Failure to enter
      46                 :            :  *              the interpreter region is a fatal system error. Used in
      47                 :            :  *              conjunction with exit_interpreter.
      48                 :            :  *
      49                 :            :  ******************************************************************************/
      50                 :            : 
      51                 :       3237 : void acpi_ex_enter_interpreter(void)
      52                 :            : {
      53                 :       3237 :         acpi_status status;
      54                 :            : 
      55                 :       3237 :         ACPI_FUNCTION_TRACE(ex_enter_interpreter);
      56                 :            : 
      57                 :       3237 :         status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
      58         [ -  + ]:       3237 :         if (ACPI_FAILURE(status)) {
      59                 :          0 :                 ACPI_ERROR((AE_INFO,
      60                 :            :                             "Could not acquire AML Interpreter mutex"));
      61                 :            :         }
      62                 :       3237 :         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
      63         [ -  + ]:       3237 :         if (ACPI_FAILURE(status)) {
      64                 :          0 :                 ACPI_ERROR((AE_INFO, "Could not acquire AML Namespace mutex"));
      65                 :            :         }
      66                 :            : 
      67                 :       3237 :         return_VOID;
      68                 :            : }
      69                 :            : 
      70                 :            : /*******************************************************************************
      71                 :            :  *
      72                 :            :  * FUNCTION:    acpi_ex_exit_interpreter
      73                 :            :  *
      74                 :            :  * PARAMETERS:  None
      75                 :            :  *
      76                 :            :  * RETURN:      None
      77                 :            :  *
      78                 :            :  * DESCRIPTION: Exit the interpreter execution region. This is the top level
      79                 :            :  *              routine used to exit the interpreter when all processing has
      80                 :            :  *              been completed, or when the method blocks.
      81                 :            :  *
      82                 :            :  * Cases where the interpreter is unlocked internally:
      83                 :            :  *      1) Method will be blocked on a Sleep() AML opcode
      84                 :            :  *      2) Method will be blocked on an Acquire() AML opcode
      85                 :            :  *      3) Method will be blocked on a Wait() AML opcode
      86                 :            :  *      4) Method will be blocked to acquire the global lock
      87                 :            :  *      5) Method will be blocked waiting to execute a serialized control
      88                 :            :  *          method that is currently executing
      89                 :            :  *      6) About to invoke a user-installed opregion handler
      90                 :            :  *
      91                 :            :  ******************************************************************************/
      92                 :            : 
      93                 :       3237 : void acpi_ex_exit_interpreter(void)
      94                 :            : {
      95                 :       3237 :         acpi_status status;
      96                 :            : 
      97                 :       3237 :         ACPI_FUNCTION_TRACE(ex_exit_interpreter);
      98                 :            : 
      99                 :       3237 :         status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
     100         [ -  + ]:       3237 :         if (ACPI_FAILURE(status)) {
     101                 :          0 :                 ACPI_ERROR((AE_INFO, "Could not release AML Namespace mutex"));
     102                 :            :         }
     103                 :       3237 :         status = acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
     104         [ -  + ]:       3237 :         if (ACPI_FAILURE(status)) {
     105                 :          0 :                 ACPI_ERROR((AE_INFO,
     106                 :            :                             "Could not release AML Interpreter mutex"));
     107                 :            :         }
     108                 :            : 
     109                 :       3237 :         return_VOID;
     110                 :            : }
     111                 :            : 
     112                 :            : /*******************************************************************************
     113                 :            :  *
     114                 :            :  * FUNCTION:    acpi_ex_truncate_for32bit_table
     115                 :            :  *
     116                 :            :  * PARAMETERS:  obj_desc        - Object to be truncated
     117                 :            :  *
     118                 :            :  * RETURN:      TRUE if a truncation was performed, FALSE otherwise.
     119                 :            :  *
     120                 :            :  * DESCRIPTION: Truncate an ACPI Integer to 32 bits if the execution mode is
     121                 :            :  *              32-bit, as determined by the revision of the DSDT.
     122                 :            :  *
     123                 :            :  ******************************************************************************/
     124                 :            : 
     125                 :      34203 : u8 acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc)
     126                 :            : {
     127                 :            : 
     128                 :      34203 :         ACPI_FUNCTION_ENTRY();
     129                 :            : 
     130                 :            :         /*
     131                 :            :          * Object must be a valid number and we must be executing
     132                 :            :          * a control method. Object could be NS node for AML_INT_NAMEPATH_OP.
     133                 :            :          */
     134         [ +  + ]:      34203 :         if ((!obj_desc) ||
     135         [ +  - ]:      15804 :             (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) ||
     136         [ +  + ]:      15804 :             (obj_desc->common.type != ACPI_TYPE_INTEGER)) {
     137                 :            :                 return (FALSE);
     138                 :            :         }
     139                 :            : 
     140         [ +  - ]:      13434 :         if ((acpi_gbl_integer_byte_width == 4) &&
     141         [ +  + ]:      13434 :             (obj_desc->integer.value > (u64)ACPI_UINT32_MAX)) {
     142                 :            :                 /*
     143                 :            :                  * We are executing in a 32-bit ACPI table. Truncate
     144                 :            :                  * the value to 32 bits by zeroing out the upper 32-bit field
     145                 :            :                  */
     146                 :        816 :                 obj_desc->integer.value &= (u64)ACPI_UINT32_MAX;
     147                 :        816 :                 return (TRUE);
     148                 :            :         }
     149                 :            : 
     150                 :            :         return (FALSE);
     151                 :            : }
     152                 :            : 
     153                 :            : /*******************************************************************************
     154                 :            :  *
     155                 :            :  * FUNCTION:    acpi_ex_acquire_global_lock
     156                 :            :  *
     157                 :            :  * PARAMETERS:  field_flags           - Flags with Lock rule:
     158                 :            :  *                                      always_lock or never_lock
     159                 :            :  *
     160                 :            :  * RETURN:      None
     161                 :            :  *
     162                 :            :  * DESCRIPTION: Obtain the ACPI hardware Global Lock, only if the field
     163                 :            :  *              flags specify that it is to be obtained before field access.
     164                 :            :  *
     165                 :            :  ******************************************************************************/
     166                 :            : 
     167                 :        210 : void acpi_ex_acquire_global_lock(u32 field_flags)
     168                 :            : {
     169                 :        210 :         acpi_status status;
     170                 :            : 
     171                 :        210 :         ACPI_FUNCTION_TRACE(ex_acquire_global_lock);
     172                 :            : 
     173                 :            :         /* Only use the lock if the always_lock bit is set */
     174                 :            : 
     175         [ +  + ]:        210 :         if (!(field_flags & AML_FIELD_LOCK_RULE_MASK)) {
     176                 :            :                 return_VOID;
     177                 :            :         }
     178                 :            : 
     179                 :            :         /* Attempt to get the global lock, wait forever */
     180                 :            : 
     181                 :         24 :         status = acpi_ex_acquire_mutex_object(ACPI_WAIT_FOREVER,
     182                 :            :                                               acpi_gbl_global_lock_mutex,
     183                 :            :                                               acpi_os_get_thread_id());
     184                 :            : 
     185         [ -  + ]:         24 :         if (ACPI_FAILURE(status)) {
     186                 :          0 :                 ACPI_EXCEPTION((AE_INFO, status,
     187                 :            :                                 "Could not acquire Global Lock"));
     188                 :            :         }
     189                 :            : 
     190                 :            :         return_VOID;
     191                 :            : }
     192                 :            : 
     193                 :            : /*******************************************************************************
     194                 :            :  *
     195                 :            :  * FUNCTION:    acpi_ex_release_global_lock
     196                 :            :  *
     197                 :            :  * PARAMETERS:  field_flags           - Flags with Lock rule:
     198                 :            :  *                                      always_lock or never_lock
     199                 :            :  *
     200                 :            :  * RETURN:      None
     201                 :            :  *
     202                 :            :  * DESCRIPTION: Release the ACPI hardware Global Lock
     203                 :            :  *
     204                 :            :  ******************************************************************************/
     205                 :            : 
     206                 :        210 : void acpi_ex_release_global_lock(u32 field_flags)
     207                 :            : {
     208                 :        210 :         acpi_status status;
     209                 :            : 
     210                 :        210 :         ACPI_FUNCTION_TRACE(ex_release_global_lock);
     211                 :            : 
     212                 :            :         /* Only use the lock if the always_lock bit is set */
     213                 :            : 
     214         [ +  + ]:        210 :         if (!(field_flags & AML_FIELD_LOCK_RULE_MASK)) {
     215                 :            :                 return_VOID;
     216                 :            :         }
     217                 :            : 
     218                 :            :         /* Release the global lock */
     219                 :            : 
     220                 :         24 :         status = acpi_ex_release_mutex_object(acpi_gbl_global_lock_mutex);
     221         [ -  + ]:         24 :         if (ACPI_FAILURE(status)) {
     222                 :            : 
     223                 :            :                 /* Report the error, but there isn't much else we can do */
     224                 :            : 
     225                 :          0 :                 ACPI_EXCEPTION((AE_INFO, status,
     226                 :            :                                 "Could not release Global Lock"));
     227                 :            :         }
     228                 :            : 
     229                 :            :         return_VOID;
     230                 :            : }
     231                 :            : 
     232                 :            : /*******************************************************************************
     233                 :            :  *
     234                 :            :  * FUNCTION:    acpi_ex_digits_needed
     235                 :            :  *
     236                 :            :  * PARAMETERS:  value           - Value to be represented
     237                 :            :  *              base            - Base of representation
     238                 :            :  *
     239                 :            :  * RETURN:      The number of digits.
     240                 :            :  *
     241                 :            :  * DESCRIPTION: Calculate the number of digits needed to represent the Value
     242                 :            :  *              in the given Base (Radix)
     243                 :            :  *
     244                 :            :  ******************************************************************************/
     245                 :            : 
     246                 :         54 : static u32 acpi_ex_digits_needed(u64 value, u32 base)
     247                 :            : {
     248                 :         54 :         u32 num_digits;
     249                 :         54 :         u64 current_value;
     250                 :            : 
     251                 :         54 :         ACPI_FUNCTION_TRACE(ex_digits_needed);
     252                 :            : 
     253                 :            :         /* u64 is unsigned, so we don't worry about a '-' prefix */
     254                 :            : 
     255         [ +  + ]:         54 :         if (value == 0) {
     256                 :            :                 return_UINT32(1);
     257                 :            :         }
     258                 :            : 
     259                 :         42 :         current_value = value;
     260                 :         42 :         num_digits = 0;
     261                 :            : 
     262                 :            :         /* Count the digits in the requested base */
     263                 :            : 
     264         [ +  + ]:         84 :         while (current_value) {
     265                 :         42 :                 (void)acpi_ut_short_divide(current_value, base, &current_value,
     266                 :            :                                            NULL);
     267                 :         42 :                 num_digits++;
     268                 :            :         }
     269                 :            : 
     270                 :            :         return_UINT32(num_digits);
     271                 :            : }
     272                 :            : 
     273                 :            : /*******************************************************************************
     274                 :            :  *
     275                 :            :  * FUNCTION:    acpi_ex_eisa_id_to_string
     276                 :            :  *
     277                 :            :  * PARAMETERS:  out_string      - Where to put the converted string (8 bytes)
     278                 :            :  *              compressed_id   - EISAID to be converted
     279                 :            :  *
     280                 :            :  * RETURN:      None
     281                 :            :  *
     282                 :            :  * DESCRIPTION: Convert a numeric EISAID to string representation. Return
     283                 :            :  *              buffer must be large enough to hold the string. The string
     284                 :            :  *              returned is always exactly of length ACPI_EISAID_STRING_SIZE
     285                 :            :  *              (includes null terminator). The EISAID is always 32 bits.
     286                 :            :  *
     287                 :            :  ******************************************************************************/
     288                 :            : 
     289                 :        243 : void acpi_ex_eisa_id_to_string(char *out_string, u64 compressed_id)
     290                 :            : {
     291                 :        243 :         u32 swapped_id;
     292                 :            : 
     293                 :        243 :         ACPI_FUNCTION_ENTRY();
     294                 :            : 
     295                 :            :         /* The EISAID should be a 32-bit integer */
     296                 :            : 
     297         [ -  + ]:        243 :         if (compressed_id > ACPI_UINT32_MAX) {
     298                 :          0 :                 ACPI_WARNING((AE_INFO,
     299                 :            :                               "Expected EISAID is larger than 32 bits: "
     300                 :            :                               "0x%8.8X%8.8X, truncating",
     301                 :            :                               ACPI_FORMAT_UINT64(compressed_id)));
     302                 :            :         }
     303                 :            : 
     304                 :            :         /* Swap ID to big-endian to get contiguous bits */
     305                 :            : 
     306                 :        243 :         swapped_id = acpi_ut_dword_byte_swap((u32)compressed_id);
     307                 :            : 
     308                 :            :         /* First 3 bytes are uppercase letters. Next 4 bytes are hexadecimal */
     309                 :            : 
     310                 :        243 :         out_string[0] =
     311                 :        243 :             (char)(0x40 + (((unsigned long)swapped_id >> 26) & 0x1F));
     312                 :        243 :         out_string[1] = (char)(0x40 + ((swapped_id >> 21) & 0x1F));
     313                 :        243 :         out_string[2] = (char)(0x40 + ((swapped_id >> 16) & 0x1F));
     314                 :        243 :         out_string[3] = acpi_ut_hex_to_ascii_char((u64) swapped_id, 12);
     315                 :        243 :         out_string[4] = acpi_ut_hex_to_ascii_char((u64) swapped_id, 8);
     316                 :        243 :         out_string[5] = acpi_ut_hex_to_ascii_char((u64) swapped_id, 4);
     317                 :        243 :         out_string[6] = acpi_ut_hex_to_ascii_char((u64) swapped_id, 0);
     318                 :        243 :         out_string[7] = 0;
     319                 :        243 : }
     320                 :            : 
     321                 :            : /*******************************************************************************
     322                 :            :  *
     323                 :            :  * FUNCTION:    acpi_ex_integer_to_string
     324                 :            :  *
     325                 :            :  * PARAMETERS:  out_string      - Where to put the converted string. At least
     326                 :            :  *                                21 bytes are needed to hold the largest
     327                 :            :  *                                possible 64-bit integer.
     328                 :            :  *              value           - Value to be converted
     329                 :            :  *
     330                 :            :  * RETURN:      Converted string in out_string
     331                 :            :  *
     332                 :            :  * DESCRIPTION: Convert a 64-bit integer to decimal string representation.
     333                 :            :  *              Assumes string buffer is large enough to hold the string. The
     334                 :            :  *              largest string is (ACPI_MAX64_DECIMAL_DIGITS + 1).
     335                 :            :  *
     336                 :            :  ******************************************************************************/
     337                 :            : 
     338                 :         54 : void acpi_ex_integer_to_string(char *out_string, u64 value)
     339                 :            : {
     340                 :         54 :         u32 count;
     341                 :         54 :         u32 digits_needed;
     342                 :         54 :         u32 remainder;
     343                 :            : 
     344                 :         54 :         ACPI_FUNCTION_ENTRY();
     345                 :            : 
     346                 :         54 :         digits_needed = acpi_ex_digits_needed(value, 10);
     347                 :         54 :         out_string[digits_needed] = 0;
     348                 :            : 
     349         [ +  + ]:        108 :         for (count = digits_needed; count > 0; count--) {
     350                 :         54 :                 (void)acpi_ut_short_divide(value, 10, &value, &remainder);
     351                 :         54 :                 out_string[count - 1] = (char)('0' + remainder);
     352                 :            :         }
     353                 :         54 : }
     354                 :            : 
     355                 :            : /*******************************************************************************
     356                 :            :  *
     357                 :            :  * FUNCTION:    acpi_ex_pci_cls_to_string
     358                 :            :  *
     359                 :            :  * PARAMETERS:  out_string      - Where to put the converted string (7 bytes)
     360                 :            :  *              class_code      - PCI class code to be converted (3 bytes)
     361                 :            :  *
     362                 :            :  * RETURN:      Converted string in out_string
     363                 :            :  *
     364                 :            :  * DESCRIPTION: Convert 3-bytes PCI class code to string representation.
     365                 :            :  *              Return buffer must be large enough to hold the string. The
     366                 :            :  *              string returned is always exactly of length
     367                 :            :  *              ACPI_PCICLS_STRING_SIZE (includes null terminator).
     368                 :            :  *
     369                 :            :  ******************************************************************************/
     370                 :            : 
     371                 :          0 : void acpi_ex_pci_cls_to_string(char *out_string, u8 class_code[3])
     372                 :            : {
     373                 :            : 
     374                 :          0 :         ACPI_FUNCTION_ENTRY();
     375                 :            : 
     376                 :            :         /* All 3 bytes are hexadecimal */
     377                 :            : 
     378                 :          0 :         out_string[0] = acpi_ut_hex_to_ascii_char((u64)class_code[0], 4);
     379                 :          0 :         out_string[1] = acpi_ut_hex_to_ascii_char((u64)class_code[0], 0);
     380                 :          0 :         out_string[2] = acpi_ut_hex_to_ascii_char((u64)class_code[1], 4);
     381                 :          0 :         out_string[3] = acpi_ut_hex_to_ascii_char((u64)class_code[1], 0);
     382                 :          0 :         out_string[4] = acpi_ut_hex_to_ascii_char((u64)class_code[2], 4);
     383                 :          0 :         out_string[5] = acpi_ut_hex_to_ascii_char((u64)class_code[2], 0);
     384                 :          0 :         out_string[6] = 0;
     385                 :          0 : }
     386                 :            : 
     387                 :            : /*******************************************************************************
     388                 :            :  *
     389                 :            :  * FUNCTION:    acpi_is_valid_space_id
     390                 :            :  *
     391                 :            :  * PARAMETERS:  space_id            - ID to be validated
     392                 :            :  *
     393                 :            :  * RETURN:      TRUE if space_id is a valid/supported ID.
     394                 :            :  *
     395                 :            :  * DESCRIPTION: Validate an operation region space_ID.
     396                 :            :  *
     397                 :            :  ******************************************************************************/
     398                 :            : 
     399                 :        204 : u8 acpi_is_valid_space_id(u8 space_id)
     400                 :            : {
     401                 :            : 
     402                 :        204 :         if ((space_id >= ACPI_NUM_PREDEFINED_REGIONS) &&
     403                 :        204 :             (space_id < ACPI_USER_REGION_BEGIN) &&
     404   [ -  +  -  - ]:        204 :             (space_id != ACPI_ADR_SPACE_DATA_TABLE) &&
     405                 :            :             (space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) {
     406                 :          0 :                 return (FALSE);
     407                 :            :         }
     408                 :            : 
     409                 :            :         return (TRUE);
     410                 :            : }

Generated by: LCOV version 1.14