root/drivers/acpi/acpica/exnames.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. acpi_ex_name_segment
  3. acpi_ex_get_name_string

   1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Module Name: exnames - interpreter/scanner name load/execute
   5  *
   6  * Copyright (C) 2000 - 2019, Intel Corp.
   7  *
   8  *****************************************************************************/
   9 
  10 #include <acpi/acpi.h>
  11 #include "accommon.h"
  12 #include "acinterp.h"
  13 #include "amlcode.h"
  14 
  15 #define _COMPONENT          ACPI_EXECUTER
  16 ACPI_MODULE_NAME("exnames")
  17 
  18 /* Local prototypes */
  19 static char *acpi_ex_allocate_name_string(u32 prefix_count, u32 num_name_segs);
  20 
  21 static acpi_status acpi_ex_name_segment(u8 **in_aml_address, char *name_string);
  22 
  23 /*******************************************************************************
  24  *
  25  * FUNCTION:    acpi_ex_allocate_name_string
  26  *
  27  * PARAMETERS:  prefix_count        - Count of parent levels. Special cases:
  28  *                                    (-1)==root,  0==none
  29  *              num_name_segs       - count of 4-character name segments
  30  *
  31  * RETURN:      A pointer to the allocated string segment. This segment must
  32  *              be deleted by the caller.
  33  *
  34  * DESCRIPTION: Allocate a buffer for a name string. Ensure allocated name
  35  *              string is long enough, and set up prefix if any.
  36  *
  37  ******************************************************************************/
  38 
  39 static char *acpi_ex_allocate_name_string(u32 prefix_count, u32 num_name_segs)
  40 {
  41         char *temp_ptr;
  42         char *name_string;
  43         u32 size_needed;
  44 
  45         ACPI_FUNCTION_TRACE(ex_allocate_name_string);
  46 
  47         /*
  48          * Allow room for all \ and ^ prefixes, all segments and a multi_name_prefix.
  49          * Also, one byte for the null terminator.
  50          * This may actually be somewhat longer than needed.
  51          */
  52         if (prefix_count == ACPI_UINT32_MAX) {
  53 
  54                 /* Special case for root */
  55 
  56                 size_needed = 1 + (ACPI_NAMESEG_SIZE * num_name_segs) + 2 + 1;
  57         } else {
  58                 size_needed =
  59                     prefix_count + (ACPI_NAMESEG_SIZE * num_name_segs) + 2 + 1;
  60         }
  61 
  62         /*
  63          * Allocate a buffer for the name.
  64          * This buffer must be deleted by the caller!
  65          */
  66         name_string = ACPI_ALLOCATE(size_needed);
  67         if (!name_string) {
  68                 ACPI_ERROR((AE_INFO,
  69                             "Could not allocate size %u", size_needed));
  70                 return_PTR(NULL);
  71         }
  72 
  73         temp_ptr = name_string;
  74 
  75         /* Set up Root or Parent prefixes if needed */
  76 
  77         if (prefix_count == ACPI_UINT32_MAX) {
  78                 *temp_ptr++ = AML_ROOT_PREFIX;
  79         } else {
  80                 while (prefix_count--) {
  81                         *temp_ptr++ = AML_PARENT_PREFIX;
  82                 }
  83         }
  84 
  85         /* Set up Dual or Multi prefixes if needed */
  86 
  87         if (num_name_segs > 2) {
  88 
  89                 /* Set up multi prefixes   */
  90 
  91                 *temp_ptr++ = AML_MULTI_NAME_PREFIX;
  92                 *temp_ptr++ = (char)num_name_segs;
  93         } else if (2 == num_name_segs) {
  94 
  95                 /* Set up dual prefixes */
  96 
  97                 *temp_ptr++ = AML_DUAL_NAME_PREFIX;
  98         }
  99 
 100         /*
 101          * Terminate string following prefixes. acpi_ex_name_segment() will
 102          * append the segment(s)
 103          */
 104         *temp_ptr = 0;
 105 
 106         return_PTR(name_string);
 107 }
 108 
 109 /*******************************************************************************
 110  *
 111  * FUNCTION:    acpi_ex_name_segment
 112  *
 113  * PARAMETERS:  in_aml_address  - Pointer to the name in the AML code
 114  *              name_string     - Where to return the name. The name is appended
 115  *                                to any existing string to form a namepath
 116  *
 117  * RETURN:      Status
 118  *
 119  * DESCRIPTION: Extract an ACPI name (4 bytes) from the AML byte stream
 120  *
 121  ******************************************************************************/
 122 
 123 static acpi_status acpi_ex_name_segment(u8 ** in_aml_address, char *name_string)
 124 {
 125         char *aml_address = (void *)*in_aml_address;
 126         acpi_status status = AE_OK;
 127         u32 index;
 128         char char_buf[5];
 129 
 130         ACPI_FUNCTION_TRACE(ex_name_segment);
 131 
 132         /*
 133          * If first character is a digit, then we know that we aren't looking
 134          * at a valid name segment
 135          */
 136         char_buf[0] = *aml_address;
 137 
 138         if ('0' <= char_buf[0] && char_buf[0] <= '9') {
 139                 ACPI_ERROR((AE_INFO, "Invalid leading digit: %c", char_buf[0]));
 140                 return_ACPI_STATUS(AE_CTRL_PENDING);
 141         }
 142 
 143         for (index = 0;
 144              (index < ACPI_NAMESEG_SIZE)
 145              && (acpi_ut_valid_name_char(*aml_address, 0)); index++) {
 146                 char_buf[index] = *aml_address++;
 147         }
 148 
 149         /* Valid name segment  */
 150 
 151         if (index == 4) {
 152 
 153                 /* Found 4 valid characters */
 154 
 155                 char_buf[4] = '\0';
 156 
 157                 if (name_string) {
 158                         ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 159                                           "Appending NameSeg %s\n", char_buf));
 160                         strcat(name_string, char_buf);
 161                 } else {
 162                         ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
 163                                           "No Name string - %s\n", char_buf));
 164                 }
 165         } else if (index == 0) {
 166                 /*
 167                  * First character was not a valid name character,
 168                  * so we are looking at something other than a name.
 169                  */
 170                 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 171                                   "Leading character is not alpha: %02Xh (not a name)\n",
 172                                   char_buf[0]));
 173                 status = AE_CTRL_PENDING;
 174         } else {
 175                 /*
 176                  * Segment started with one or more valid characters, but fewer than
 177                  * the required 4
 178                  */
 179                 status = AE_AML_BAD_NAME;
 180                 ACPI_ERROR((AE_INFO,
 181                             "Bad character 0x%02x in name, at %p",
 182                             *aml_address, aml_address));
 183         }
 184 
 185         *in_aml_address = ACPI_CAST_PTR(u8, aml_address);
 186         return_ACPI_STATUS(status);
 187 }
 188 
 189 /*******************************************************************************
 190  *
 191  * FUNCTION:    acpi_ex_get_name_string
 192  *
 193  * PARAMETERS:  data_type           - Object type to be associated with this
 194  *                                    name
 195  *              in_aml_address      - Pointer to the namestring in the AML code
 196  *              out_name_string     - Where the namestring is returned
 197  *              out_name_length     - Length of the returned string
 198  *
 199  * RETURN:      Status, namestring and length
 200  *
 201  * DESCRIPTION: Extract a full namepath from the AML byte stream,
 202  *              including any prefixes.
 203  *
 204  ******************************************************************************/
 205 
 206 acpi_status
 207 acpi_ex_get_name_string(acpi_object_type data_type,
 208                         u8 * in_aml_address,
 209                         char **out_name_string, u32 * out_name_length)
 210 {
 211         acpi_status status = AE_OK;
 212         u8 *aml_address = in_aml_address;
 213         char *name_string = NULL;
 214         u32 num_segments;
 215         u32 prefix_count = 0;
 216         u8 has_prefix = FALSE;
 217 
 218         ACPI_FUNCTION_TRACE_PTR(ex_get_name_string, aml_address);
 219 
 220         if (ACPI_TYPE_LOCAL_REGION_FIELD == data_type ||
 221             ACPI_TYPE_LOCAL_BANK_FIELD == data_type ||
 222             ACPI_TYPE_LOCAL_INDEX_FIELD == data_type) {
 223 
 224                 /* Disallow prefixes for types associated with field_unit names */
 225 
 226                 name_string = acpi_ex_allocate_name_string(0, 1);
 227                 if (!name_string) {
 228                         status = AE_NO_MEMORY;
 229                 } else {
 230                         status =
 231                             acpi_ex_name_segment(&aml_address, name_string);
 232                 }
 233         } else {
 234                 /*
 235                  * data_type is not a field name.
 236                  * Examine first character of name for root or parent prefix operators
 237                  */
 238                 switch (*aml_address) {
 239                 case AML_ROOT_PREFIX:
 240 
 241                         ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
 242                                           "RootPrefix(\\) at %p\n",
 243                                           aml_address));
 244 
 245                         /*
 246                          * Remember that we have a root_prefix --
 247                          * see comment in acpi_ex_allocate_name_string()
 248                          */
 249                         aml_address++;
 250                         prefix_count = ACPI_UINT32_MAX;
 251                         has_prefix = TRUE;
 252                         break;
 253 
 254                 case AML_PARENT_PREFIX:
 255 
 256                         /* Increment past possibly multiple parent prefixes */
 257 
 258                         do {
 259                                 ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
 260                                                   "ParentPrefix (^) at %p\n",
 261                                                   aml_address));
 262 
 263                                 aml_address++;
 264                                 prefix_count++;
 265 
 266                         } while (*aml_address == AML_PARENT_PREFIX);
 267 
 268                         has_prefix = TRUE;
 269                         break;
 270 
 271                 default:
 272 
 273                         /* Not a prefix character */
 274 
 275                         break;
 276                 }
 277 
 278                 /* Examine first character of name for name segment prefix operator */
 279 
 280                 switch (*aml_address) {
 281                 case AML_DUAL_NAME_PREFIX:
 282 
 283                         ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
 284                                           "DualNamePrefix at %p\n",
 285                                           aml_address));
 286 
 287                         aml_address++;
 288                         name_string =
 289                             acpi_ex_allocate_name_string(prefix_count, 2);
 290                         if (!name_string) {
 291                                 status = AE_NO_MEMORY;
 292                                 break;
 293                         }
 294 
 295                         /* Indicate that we processed a prefix */
 296 
 297                         has_prefix = TRUE;
 298 
 299                         status =
 300                             acpi_ex_name_segment(&aml_address, name_string);
 301                         if (ACPI_SUCCESS(status)) {
 302                                 status =
 303                                     acpi_ex_name_segment(&aml_address,
 304                                                          name_string);
 305                         }
 306                         break;
 307 
 308                 case AML_MULTI_NAME_PREFIX:
 309 
 310                         ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
 311                                           "MultiNamePrefix at %p\n",
 312                                           aml_address));
 313 
 314                         /* Fetch count of segments remaining in name path */
 315 
 316                         aml_address++;
 317                         num_segments = *aml_address;
 318 
 319                         name_string =
 320                             acpi_ex_allocate_name_string(prefix_count,
 321                                                          num_segments);
 322                         if (!name_string) {
 323                                 status = AE_NO_MEMORY;
 324                                 break;
 325                         }
 326 
 327                         /* Indicate that we processed a prefix */
 328 
 329                         aml_address++;
 330                         has_prefix = TRUE;
 331 
 332                         while (num_segments &&
 333                                (status =
 334                                 acpi_ex_name_segment(&aml_address,
 335                                                      name_string)) == AE_OK) {
 336                                 num_segments--;
 337                         }
 338 
 339                         break;
 340 
 341                 case 0:
 342 
 343                         /* null_name valid as of 8-12-98 ASL/AML Grammar Update */
 344 
 345                         if (prefix_count == ACPI_UINT32_MAX) {
 346                                 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 347                                                   "NameSeg is \"\\\" followed by NULL\n"));
 348                         }
 349 
 350                         /* Consume the NULL byte */
 351 
 352                         aml_address++;
 353                         name_string =
 354                             acpi_ex_allocate_name_string(prefix_count, 0);
 355                         if (!name_string) {
 356                                 status = AE_NO_MEMORY;
 357                                 break;
 358                         }
 359 
 360                         break;
 361 
 362                 default:
 363 
 364                         /* Name segment string */
 365 
 366                         name_string =
 367                             acpi_ex_allocate_name_string(prefix_count, 1);
 368                         if (!name_string) {
 369                                 status = AE_NO_MEMORY;
 370                                 break;
 371                         }
 372 
 373                         status =
 374                             acpi_ex_name_segment(&aml_address, name_string);
 375                         break;
 376                 }
 377         }
 378 
 379         if (AE_CTRL_PENDING == status && has_prefix) {
 380 
 381                 /* Ran out of segments after processing a prefix */
 382 
 383                 ACPI_ERROR((AE_INFO, "Malformed Name at %p", name_string));
 384                 status = AE_AML_BAD_NAME;
 385         }
 386 
 387         if (ACPI_FAILURE(status)) {
 388                 if (name_string) {
 389                         ACPI_FREE(name_string);
 390                 }
 391                 return_ACPI_STATUS(status);
 392         }
 393 
 394         *out_name_string = name_string;
 395         *out_name_length = (u32) (aml_address - in_aml_address);
 396 
 397         return_ACPI_STATUS(status);
 398 }

/* [<][>][^][v][top][bottom][index][help] */