1 /******************************************************************************* 2 * 3 * Module Name: nsaccess - Top-level functions for accessing ACPI namespace 4 * 5 ******************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2020, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 ***************************************************************************** 115 * 116 * Alternatively, you may choose to be licensed under the terms of the 117 * following license: 118 * 119 * Redistribution and use in source and binary forms, with or without 120 * modification, are permitted provided that the following conditions 121 * are met: 122 * 1. Redistributions of source code must retain the above copyright 123 * notice, this list of conditions, and the following disclaimer, 124 * without modification. 125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126 * substantially similar to the "NO WARRANTY" disclaimer below 127 * ("Disclaimer") and any redistribution must be conditioned upon 128 * including a substantially similar Disclaimer requirement for further 129 * binary redistribution. 130 * 3. Neither the names of the above-listed copyright holders nor the names 131 * of any contributors may be used to endorse or promote products derived 132 * from this software without specific prior written permission. 133 * 134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145 * 146 * Alternatively, you may choose to be licensed under the terms of the 147 * GNU General Public License ("GPL") version 2 as published by the Free 148 * Software Foundation. 149 * 150 *****************************************************************************/ 151 152 #include <contrib/dev/acpica/include/acpi.h> 153 #include <contrib/dev/acpica/include/accommon.h> 154 #include <contrib/dev/acpica/include/amlcode.h> 155 #include <contrib/dev/acpica/include/acnamesp.h> 156 #include <contrib/dev/acpica/include/acdispat.h> 157 158 #ifdef ACPI_ASL_COMPILER 159 #include <contrib/dev/acpica/include/acdisasm.h> 160 #endif 161 162 #define _COMPONENT ACPI_NAMESPACE 163 ACPI_MODULE_NAME ("nsaccess") 164 165 166 /******************************************************************************* 167 * 168 * FUNCTION: AcpiNsRootInitialize 169 * 170 * PARAMETERS: None 171 * 172 * RETURN: Status 173 * 174 * DESCRIPTION: Allocate and initialize the default root named objects 175 * 176 * MUTEX: Locks namespace for entire execution 177 * 178 ******************************************************************************/ 179 180 ACPI_STATUS 181 AcpiNsRootInitialize ( 182 void) 183 { 184 ACPI_STATUS Status; 185 const ACPI_PREDEFINED_NAMES *InitVal = NULL; 186 ACPI_NAMESPACE_NODE *NewNode; 187 ACPI_NAMESPACE_NODE *PrevNode = NULL; 188 ACPI_OPERAND_OBJECT *ObjDesc; 189 ACPI_STRING Val = NULL; 190 191 192 ACPI_FUNCTION_TRACE (NsRootInitialize); 193 194 195 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 196 if (ACPI_FAILURE (Status)) 197 { 198 return_ACPI_STATUS (Status); 199 } 200 201 /* 202 * The global root ptr is initially NULL, so a non-NULL value indicates 203 * that AcpiNsRootInitialize() has already been called; just return. 204 */ 205 if (AcpiGbl_RootNode) 206 { 207 Status = AE_OK; 208 goto UnlockAndExit; 209 } 210 211 /* 212 * Tell the rest of the subsystem that the root is initialized 213 * (This is OK because the namespace is locked) 214 */ 215 AcpiGbl_RootNode = &AcpiGbl_RootNodeStruct; 216 217 /* Enter the predefined names in the name table */ 218 219 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 220 "Entering predefined entries into namespace\n")); 221 222 /* 223 * Create the initial (default) namespace. 224 * This namespace looks like something similar to this: 225 * 226 * ACPI Namespace (from Namespace Root): 227 * 0 _GPE Scope 00203160 00 228 * 0 _PR_ Scope 002031D0 00 229 * 0 _SB_ Device 00203240 00 Notify Object: 0020ADD8 230 * 0 _SI_ Scope 002032B0 00 231 * 0 _TZ_ Device 00203320 00 232 * 0 _REV Integer 00203390 00 = 0000000000000002 233 * 0 _OS_ String 00203488 00 Len 14 "Microsoft Windows NT" 234 * 0 _GL_ Mutex 00203580 00 Object 002035F0 235 * 0 _OSI Method 00203678 00 Args 1 Len 0000 Aml 00000000 236 */ 237 for (InitVal = AcpiGbl_PreDefinedNames; InitVal->Name; InitVal++) 238 { 239 Status = AE_OK; 240 241 /* _OSI is optional for now, will be permanent later */ 242 243 if (!strcmp (InitVal->Name, "_OSI") && !AcpiGbl_CreateOsiMethod) 244 { 245 continue; 246 } 247 248 /* 249 * Create, init, and link the new predefined name 250 * Note: No need to use AcpiNsLookup here because all the 251 * predefined names are at the root level. It is much easier to 252 * just create and link the new node(s) here. 253 */ 254 NewNode = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_NAMESPACE_NODE)); 255 if (!NewNode) 256 { 257 Status = AE_NO_MEMORY; 258 goto UnlockAndExit; 259 } 260 261 ACPI_COPY_NAMESEG (NewNode->Name.Ascii, InitVal->Name); 262 NewNode->DescriptorType = ACPI_DESC_TYPE_NAMED; 263 NewNode->Type = InitVal->Type; 264 265 if (!PrevNode) 266 { 267 AcpiGbl_RootNodeStruct.Child = NewNode; 268 } 269 else 270 { 271 PrevNode->Peer = NewNode; 272 } 273 274 NewNode->Parent = &AcpiGbl_RootNodeStruct; 275 PrevNode = NewNode; 276 277 /* 278 * Name entered successfully. If entry in PreDefinedNames[] specifies 279 * an initial value, create the initial value. 280 */ 281 if (InitVal->Val) 282 { 283 Status = AcpiOsPredefinedOverride (InitVal, &Val); 284 if (ACPI_FAILURE (Status)) 285 { 286 ACPI_ERROR ((AE_INFO, 287 "Could not override predefined %s", 288 InitVal->Name)); 289 } 290 291 if (!Val) 292 { 293 Val = InitVal->Val; 294 } 295 296 /* 297 * Entry requests an initial value, allocate a 298 * descriptor for it. 299 */ 300 ObjDesc = AcpiUtCreateInternalObject (InitVal->Type); 301 if (!ObjDesc) 302 { 303 Status = AE_NO_MEMORY; 304 goto UnlockAndExit; 305 } 306 307 /* 308 * Convert value string from table entry to 309 * internal representation. Only types actually 310 * used for initial values are implemented here. 311 */ 312 switch (InitVal->Type) 313 { 314 case ACPI_TYPE_METHOD: 315 316 ObjDesc->Method.ParamCount = (UINT8) ACPI_TO_INTEGER (Val); 317 ObjDesc->Common.Flags |= AOPOBJ_DATA_VALID; 318 319 #if defined (ACPI_ASL_COMPILER) 320 321 /* Save the parameter count for the iASL compiler */ 322 323 NewNode->Value = ObjDesc->Method.ParamCount; 324 #else 325 /* Mark this as a very SPECIAL method (_OSI) */ 326 327 ObjDesc->Method.InfoFlags = ACPI_METHOD_INTERNAL_ONLY; 328 ObjDesc->Method.Dispatch.Implementation = AcpiUtOsiImplementation; 329 #endif 330 break; 331 332 case ACPI_TYPE_INTEGER: 333 334 ObjDesc->Integer.Value = ACPI_TO_INTEGER (Val); 335 break; 336 337 case ACPI_TYPE_STRING: 338 339 /* Build an object around the static string */ 340 341 ObjDesc->String.Length = (UINT32) strlen (Val); 342 ObjDesc->String.Pointer = Val; 343 ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER; 344 break; 345 346 case ACPI_TYPE_MUTEX: 347 348 ObjDesc->Mutex.Node = NewNode; 349 ObjDesc->Mutex.SyncLevel = (UINT8) (ACPI_TO_INTEGER (Val) - 1); 350 351 /* Create a mutex */ 352 353 Status = AcpiOsCreateMutex (&ObjDesc->Mutex.OsMutex); 354 if (ACPI_FAILURE (Status)) 355 { 356 AcpiUtRemoveReference (ObjDesc); 357 goto UnlockAndExit; 358 } 359 360 /* Special case for ACPI Global Lock */ 361 362 if (strcmp (InitVal->Name, "_GL_") == 0) 363 { 364 AcpiGbl_GlobalLockMutex = ObjDesc; 365 366 /* Create additional counting semaphore for global lock */ 367 368 Status = AcpiOsCreateSemaphore ( 369 1, 0, &AcpiGbl_GlobalLockSemaphore); 370 if (ACPI_FAILURE (Status)) 371 { 372 AcpiUtRemoveReference (ObjDesc); 373 goto UnlockAndExit; 374 } 375 } 376 break; 377 378 default: 379 380 ACPI_ERROR ((AE_INFO, "Unsupported initial type value 0x%X", 381 InitVal->Type)); 382 AcpiUtRemoveReference (ObjDesc); 383 ObjDesc = NULL; 384 continue; 385 } 386 387 /* Store pointer to value descriptor in the Node */ 388 389 Status = AcpiNsAttachObject (NewNode, ObjDesc, 390 ObjDesc->Common.Type); 391 392 /* Remove local reference to the object */ 393 394 AcpiUtRemoveReference (ObjDesc); 395 } 396 } 397 398 UnlockAndExit: 399 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 400 401 /* Save a handle to "_GPE", it is always present */ 402 403 if (ACPI_SUCCESS (Status)) 404 { 405 Status = AcpiNsGetNode (NULL, "\\_GPE", ACPI_NS_NO_UPSEARCH, 406 &AcpiGbl_FadtGpeDevice); 407 } 408 409 return_ACPI_STATUS (Status); 410 } 411 412 413 /******************************************************************************* 414 * 415 * FUNCTION: AcpiNsLookup 416 * 417 * PARAMETERS: ScopeInfo - Current scope info block 418 * Pathname - Search pathname, in internal format 419 * (as represented in the AML stream) 420 * Type - Type associated with name 421 * InterpreterMode - IMODE_LOAD_PASS2 => add name if not found 422 * Flags - Flags describing the search restrictions 423 * WalkState - Current state of the walk 424 * ReturnNode - Where the Node is placed (if found 425 * or created successfully) 426 * 427 * RETURN: Status 428 * 429 * DESCRIPTION: Find or enter the passed name in the name space. 430 * Log an error if name not found in Exec mode. 431 * 432 * MUTEX: Assumes namespace is locked. 433 * 434 ******************************************************************************/ 435 436 ACPI_STATUS 437 AcpiNsLookup ( 438 ACPI_GENERIC_STATE *ScopeInfo, 439 char *Pathname, 440 ACPI_OBJECT_TYPE Type, 441 ACPI_INTERPRETER_MODE InterpreterMode, 442 UINT32 Flags, 443 ACPI_WALK_STATE *WalkState, 444 ACPI_NAMESPACE_NODE **ReturnNode) 445 { 446 ACPI_STATUS Status; 447 char *Path = Pathname; 448 char *ExternalPath; 449 ACPI_NAMESPACE_NODE *PrefixNode; 450 ACPI_NAMESPACE_NODE *CurrentNode = NULL; 451 ACPI_NAMESPACE_NODE *ThisNode = NULL; 452 UINT32 NumSegments; 453 UINT32 NumCarats; 454 ACPI_NAME SimpleName; 455 ACPI_OBJECT_TYPE TypeToCheckFor; 456 ACPI_OBJECT_TYPE ThisSearchType; 457 UINT32 SearchParentFlag = ACPI_NS_SEARCH_PARENT; 458 UINT32 LocalFlags; 459 ACPI_INTERPRETER_MODE LocalInterpreterMode; 460 461 462 ACPI_FUNCTION_TRACE (NsLookup); 463 464 465 if (!ReturnNode) 466 { 467 return_ACPI_STATUS (AE_BAD_PARAMETER); 468 } 469 470 LocalFlags = Flags & 471 ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_OVERRIDE_IF_FOUND | 472 ACPI_NS_SEARCH_PARENT); 473 *ReturnNode = ACPI_ENTRY_NOT_FOUND; 474 AcpiGbl_NsLookupCount++; 475 476 if (!AcpiGbl_RootNode) 477 { 478 return_ACPI_STATUS (AE_NO_NAMESPACE); 479 } 480 481 /* Get the prefix scope. A null scope means use the root scope */ 482 483 if ((!ScopeInfo) || 484 (!ScopeInfo->Scope.Node)) 485 { 486 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 487 "Null scope prefix, using root node (%p)\n", 488 AcpiGbl_RootNode)); 489 490 PrefixNode = AcpiGbl_RootNode; 491 } 492 else 493 { 494 PrefixNode = ScopeInfo->Scope.Node; 495 if (ACPI_GET_DESCRIPTOR_TYPE (PrefixNode) != ACPI_DESC_TYPE_NAMED) 496 { 497 ACPI_ERROR ((AE_INFO, "%p is not a namespace node [%s]", 498 PrefixNode, AcpiUtGetDescriptorName (PrefixNode))); 499 return_ACPI_STATUS (AE_AML_INTERNAL); 500 } 501 502 if (!(Flags & ACPI_NS_PREFIX_IS_SCOPE)) 503 { 504 /* 505 * This node might not be a actual "scope" node (such as a 506 * Device/Method, etc.) It could be a Package or other object 507 * node. Backup up the tree to find the containing scope node. 508 */ 509 while (!AcpiNsOpensScope (PrefixNode->Type) && 510 PrefixNode->Type != ACPI_TYPE_ANY) 511 { 512 PrefixNode = PrefixNode->Parent; 513 } 514 } 515 } 516 517 /* Save type. TBD: may be no longer necessary */ 518 519 TypeToCheckFor = Type; 520 521 /* 522 * Begin examination of the actual pathname 523 */ 524 if (!Pathname) 525 { 526 /* A Null NamePath is allowed and refers to the root */ 527 528 NumSegments = 0; 529 ThisNode = AcpiGbl_RootNode; 530 Path = ""; 531 532 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 533 "Null Pathname (Zero segments), Flags=%X\n", Flags)); 534 } 535 else 536 { 537 /* 538 * Name pointer is valid (and must be in internal name format) 539 * 540 * Check for scope prefixes: 541 * 542 * As represented in the AML stream, a namepath consists of an 543 * optional scope prefix followed by a name segment part. 544 * 545 * If present, the scope prefix is either a Root Prefix (in 546 * which case the name is fully qualified), or one or more 547 * Parent Prefixes (in which case the name's scope is relative 548 * to the current scope). 549 */ 550 if (*Path == (UINT8) AML_ROOT_PREFIX) 551 { 552 /* Pathname is fully qualified, start from the root */ 553 554 ThisNode = AcpiGbl_RootNode; 555 SearchParentFlag = ACPI_NS_NO_UPSEARCH; 556 557 /* Point to name segment part */ 558 559 Path++; 560 561 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 562 "Path is absolute from root [%p]\n", ThisNode)); 563 } 564 else 565 { 566 /* Pathname is relative to current scope, start there */ 567 568 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 569 "Searching relative to prefix scope [%4.4s] (%p)\n", 570 AcpiUtGetNodeName (PrefixNode), PrefixNode)); 571 572 /* 573 * Handle multiple Parent Prefixes (carat) by just getting 574 * the parent node for each prefix instance. 575 */ 576 ThisNode = PrefixNode; 577 NumCarats = 0; 578 while (*Path == (UINT8) AML_PARENT_PREFIX) 579 { 580 /* Name is fully qualified, no search rules apply */ 581 582 SearchParentFlag = ACPI_NS_NO_UPSEARCH; 583 584 /* 585 * Point past this prefix to the name segment 586 * part or the next Parent Prefix 587 */ 588 Path++; 589 590 /* Backup to the parent node */ 591 592 NumCarats++; 593 ThisNode = ThisNode->Parent; 594 if (!ThisNode) 595 { 596 /* 597 * Current scope has no parent scope. Externalize 598 * the internal path for error message. 599 */ 600 Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Pathname, 601 NULL, &ExternalPath); 602 if (ACPI_SUCCESS (Status)) 603 { 604 ACPI_ERROR ((AE_INFO, 605 "%s: Path has too many parent prefixes (^)", 606 ExternalPath)); 607 608 ACPI_FREE (ExternalPath); 609 } 610 611 return_ACPI_STATUS (AE_NOT_FOUND); 612 } 613 } 614 615 if (SearchParentFlag == ACPI_NS_NO_UPSEARCH) 616 { 617 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 618 "Search scope is [%4.4s], path has %u carat(s)\n", 619 AcpiUtGetNodeName (ThisNode), NumCarats)); 620 } 621 } 622 623 /* 624 * Determine the number of ACPI name segments in this pathname. 625 * 626 * The segment part consists of either: 627 * - A Null name segment (0) 628 * - A DualNamePrefix followed by two 4-byte name segments 629 * - A MultiNamePrefix followed by a byte indicating the 630 * number of segments and the segments themselves. 631 * - A single 4-byte name segment 632 * 633 * Examine the name prefix opcode, if any, to determine the number of 634 * segments. 635 */ 636 switch (*Path) 637 { 638 case 0: 639 /* 640 * Null name after a root or parent prefixes. We already 641 * have the correct target node and there are no name segments. 642 */ 643 NumSegments = 0; 644 Type = ThisNode->Type; 645 646 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 647 "Prefix-only Pathname (Zero name segments), Flags=%X\n", 648 Flags)); 649 break; 650 651 case AML_DUAL_NAME_PREFIX: 652 653 /* More than one NameSeg, search rules do not apply */ 654 655 SearchParentFlag = ACPI_NS_NO_UPSEARCH; 656 657 /* Two segments, point to first name segment */ 658 659 NumSegments = 2; 660 Path++; 661 662 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 663 "Dual Pathname (2 segments, Flags=%X)\n", Flags)); 664 break; 665 666 case AML_MULTI_NAME_PREFIX: 667 668 /* More than one NameSeg, search rules do not apply */ 669 670 SearchParentFlag = ACPI_NS_NO_UPSEARCH; 671 672 /* Extract segment count, point to first name segment */ 673 674 Path++; 675 NumSegments = (UINT32) (UINT8) *Path; 676 Path++; 677 678 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 679 "Multi Pathname (%u Segments, Flags=%X)\n", 680 NumSegments, Flags)); 681 break; 682 683 default: 684 /* 685 * Not a Null name, no Dual or Multi prefix, hence there is 686 * only one name segment and Pathname is already pointing to it. 687 */ 688 NumSegments = 1; 689 690 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 691 "Simple Pathname (1 segment, Flags=%X)\n", Flags)); 692 break; 693 } 694 695 ACPI_DEBUG_EXEC (AcpiNsPrintPathname (NumSegments, Path)); 696 } 697 698 699 /* 700 * Search namespace for each segment of the name. Loop through and 701 * verify (or add to the namespace) each name segment. 702 * 703 * The object type is significant only at the last name 704 * segment. (We don't care about the types along the path, only 705 * the type of the final target object.) 706 */ 707 ThisSearchType = ACPI_TYPE_ANY; 708 CurrentNode = ThisNode; 709 710 while (NumSegments && CurrentNode) 711 { 712 NumSegments--; 713 if (!NumSegments) 714 { 715 /* This is the last segment, enable typechecking */ 716 717 ThisSearchType = Type; 718 719 /* 720 * Only allow automatic parent search (search rules) if the caller 721 * requested it AND we have a single, non-fully-qualified NameSeg 722 */ 723 if ((SearchParentFlag != ACPI_NS_NO_UPSEARCH) && 724 (Flags & ACPI_NS_SEARCH_PARENT)) 725 { 726 LocalFlags |= ACPI_NS_SEARCH_PARENT; 727 } 728 729 /* Set error flag according to caller */ 730 731 if (Flags & ACPI_NS_ERROR_IF_FOUND) 732 { 733 LocalFlags |= ACPI_NS_ERROR_IF_FOUND; 734 } 735 736 /* Set override flag according to caller */ 737 738 if (Flags & ACPI_NS_OVERRIDE_IF_FOUND) 739 { 740 LocalFlags |= ACPI_NS_OVERRIDE_IF_FOUND; 741 } 742 } 743 744 /* Handle opcodes that create a new NameSeg via a full NamePath */ 745 746 LocalInterpreterMode = InterpreterMode; 747 if ((Flags & ACPI_NS_PREFIX_MUST_EXIST) && (NumSegments > 0)) 748 { 749 /* Every element of the path must exist (except for the final NameSeg) */ 750 751 LocalInterpreterMode = ACPI_IMODE_EXECUTE; 752 } 753 754 /* Extract one ACPI name from the front of the pathname */ 755 756 ACPI_MOVE_32_TO_32 (&SimpleName, Path); 757 758 /* Try to find the single (4 character) ACPI name */ 759 760 Status = AcpiNsSearchAndEnter (SimpleName, WalkState, CurrentNode, 761 LocalInterpreterMode, ThisSearchType, LocalFlags, &ThisNode); 762 if (ACPI_FAILURE (Status)) 763 { 764 if (Status == AE_NOT_FOUND) 765 { 766 #if !defined ACPI_ASL_COMPILER /* Note: iASL reports this error by itself, not needed here */ 767 if (Flags & ACPI_NS_PREFIX_MUST_EXIST) 768 { 769 AcpiOsPrintf (ACPI_MSG_BIOS_ERROR 770 "Object does not exist: %4.4s\n", (char *) &SimpleName); 771 } 772 #endif 773 /* Name not found in ACPI namespace */ 774 775 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 776 "Name [%4.4s] not found in scope [%4.4s] %p\n", 777 (char *) &SimpleName, (char *) &CurrentNode->Name, 778 CurrentNode)); 779 } 780 781 #ifdef ACPI_EXEC_APP 782 if ((Status == AE_ALREADY_EXISTS) && 783 (ThisNode->Flags & ANOBJ_NODE_EARLY_INIT)) 784 { 785 ThisNode->Flags &= ~ANOBJ_NODE_EARLY_INIT; 786 Status = AE_OK; 787 } 788 #endif 789 790 #ifdef ACPI_ASL_COMPILER 791 /* 792 * If this ACPI name already exists within the namespace as an 793 * external declaration, then mark the external as a conflicting 794 * declaration and proceed to process the current node as if it did 795 * not exist in the namespace. If this node is not processed as 796 * normal, then it could cause improper namespace resolution 797 * by failing to open a new scope. 798 */ 799 if (AcpiGbl_DisasmFlag && 800 (Status == AE_ALREADY_EXISTS) && 801 ((ThisNode->Flags & ANOBJ_IS_EXTERNAL) || 802 (WalkState && WalkState->Opcode == AML_EXTERNAL_OP))) 803 { 804 ThisNode->Flags &= ~ANOBJ_IS_EXTERNAL; 805 ThisNode->Type = (UINT8)ThisSearchType; 806 if (WalkState->Opcode != AML_EXTERNAL_OP) 807 { 808 AcpiDmMarkExternalConflict (ThisNode); 809 } 810 break; 811 } 812 #endif 813 814 *ReturnNode = ThisNode; 815 return_ACPI_STATUS (Status); 816 } 817 818 /* More segments to follow? */ 819 820 if (NumSegments > 0) 821 { 822 /* 823 * If we have an alias to an object that opens a scope (such as a 824 * device or processor), we need to dereference the alias here so 825 * that we can access any children of the original node (via the 826 * remaining segments). 827 */ 828 if (ThisNode->Type == ACPI_TYPE_LOCAL_ALIAS) 829 { 830 if (!ThisNode->Object) 831 { 832 return_ACPI_STATUS (AE_NOT_EXIST); 833 } 834 835 if (AcpiNsOpensScope (((ACPI_NAMESPACE_NODE *) 836 ThisNode->Object)->Type)) 837 { 838 ThisNode = (ACPI_NAMESPACE_NODE *) ThisNode->Object; 839 } 840 } 841 } 842 843 /* Special handling for the last segment (NumSegments == 0) */ 844 845 else 846 { 847 /* 848 * Sanity typecheck of the target object: 849 * 850 * If 1) This is the last segment (NumSegments == 0) 851 * 2) And we are looking for a specific type 852 * (Not checking for TYPE_ANY) 853 * 3) Which is not an alias 854 * 4) Which is not a local type (TYPE_SCOPE) 855 * 5) And the type of target object is known (not TYPE_ANY) 856 * 6) And target object does not match what we are looking for 857 * 858 * Then we have a type mismatch. Just warn and ignore it. 859 */ 860 if ((TypeToCheckFor != ACPI_TYPE_ANY) && 861 (TypeToCheckFor != ACPI_TYPE_LOCAL_ALIAS) && 862 (TypeToCheckFor != ACPI_TYPE_LOCAL_METHOD_ALIAS) && 863 (TypeToCheckFor != ACPI_TYPE_LOCAL_SCOPE) && 864 (ThisNode->Type != ACPI_TYPE_ANY) && 865 (ThisNode->Type != TypeToCheckFor)) 866 { 867 /* Complain about a type mismatch */ 868 869 ACPI_WARNING ((AE_INFO, 870 "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)", 871 ACPI_CAST_PTR (char, &SimpleName), 872 AcpiUtGetTypeName (ThisNode->Type), 873 AcpiUtGetTypeName (TypeToCheckFor))); 874 } 875 876 /* 877 * If this is the last name segment and we are not looking for a 878 * specific type, but the type of found object is known, use that 879 * type to (later) see if it opens a scope. 880 */ 881 if (Type == ACPI_TYPE_ANY) 882 { 883 Type = ThisNode->Type; 884 } 885 } 886 887 /* Point to next name segment and make this node current */ 888 889 Path += ACPI_NAMESEG_SIZE; 890 CurrentNode = ThisNode; 891 } 892 893 /* Always check if we need to open a new scope */ 894 895 if (!(Flags & ACPI_NS_DONT_OPEN_SCOPE) && (WalkState)) 896 { 897 /* 898 * If entry is a type which opens a scope, push the new scope on the 899 * scope stack. 900 */ 901 if (AcpiNsOpensScope (Type)) 902 { 903 Status = AcpiDsScopeStackPush (ThisNode, Type, WalkState); 904 if (ACPI_FAILURE (Status)) 905 { 906 return_ACPI_STATUS (Status); 907 } 908 } 909 } 910 911 #ifdef ACPI_EXEC_APP 912 if (Flags & ACPI_NS_EARLY_INIT) 913 { 914 ThisNode->Flags |= ANOBJ_NODE_EARLY_INIT; 915 } 916 #endif 917 918 *ReturnNode = ThisNode; 919 return_ACPI_STATUS (AE_OK); 920 } 921