![]() |
|
|||
File indexing completed on 2025-05-11 08:24:03
0001 /******************************************************************************* 0002 * 0003 * Module Name: nsaccess - Top-level functions for accessing ACPI namespace 0004 * 0005 ******************************************************************************/ 0006 0007 /****************************************************************************** 0008 * 0009 * 1. Copyright Notice 0010 * 0011 * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp. 0012 * All rights reserved. 0013 * 0014 * 2. License 0015 * 0016 * 2.1. This is your license from Intel Corp. under its intellectual property 0017 * rights. You may have additional license terms from the party that provided 0018 * you this software, covering your right to use that party's intellectual 0019 * property rights. 0020 * 0021 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 0022 * copy of the source code appearing in this file ("Covered Code") an 0023 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 0024 * base code distributed originally by Intel ("Original Intel Code") to copy, 0025 * make derivatives, distribute, use and display any portion of the Covered 0026 * Code in any form, with the right to sublicense such rights; and 0027 * 0028 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 0029 * license (with the right to sublicense), under only those claims of Intel 0030 * patents that are infringed by the Original Intel Code, to make, use, sell, 0031 * offer to sell, and import the Covered Code and derivative works thereof 0032 * solely to the minimum extent necessary to exercise the above copyright 0033 * license, and in no event shall the patent license extend to any additions 0034 * to or modifications of the Original Intel Code. No other license or right 0035 * is granted directly or by implication, estoppel or otherwise; 0036 * 0037 * The above copyright and patent license is granted only if the following 0038 * conditions are met: 0039 * 0040 * 3. Conditions 0041 * 0042 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 0043 * Redistribution of source code of any substantial portion of the Covered 0044 * Code or modification with rights to further distribute source must include 0045 * the above Copyright Notice, the above License, this list of Conditions, 0046 * and the following Disclaimer and Export Compliance provision. In addition, 0047 * Licensee must cause all Covered Code to which Licensee contributes to 0048 * contain a file documenting the changes Licensee made to create that Covered 0049 * Code and the date of any change. Licensee must include in that file the 0050 * documentation of any changes made by any predecessor Licensee. Licensee 0051 * must include a prominent statement that the modification is derived, 0052 * directly or indirectly, from Original Intel Code. 0053 * 0054 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 0055 * Redistribution of source code of any substantial portion of the Covered 0056 * Code or modification without rights to further distribute source must 0057 * include the following Disclaimer and Export Compliance provision in the 0058 * documentation and/or other materials provided with distribution. In 0059 * addition, Licensee may not authorize further sublicense of source of any 0060 * portion of the Covered Code, and must include terms to the effect that the 0061 * license from Licensee to its licensee is limited to the intellectual 0062 * property embodied in the software Licensee provides to its licensee, and 0063 * not to intellectual property embodied in modifications its licensee may 0064 * make. 0065 * 0066 * 3.3. Redistribution of Executable. Redistribution in executable form of any 0067 * substantial portion of the Covered Code or modification must reproduce the 0068 * above Copyright Notice, and the following Disclaimer and Export Compliance 0069 * provision in the documentation and/or other materials provided with the 0070 * distribution. 0071 * 0072 * 3.4. Intel retains all right, title, and interest in and to the Original 0073 * Intel Code. 0074 * 0075 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 0076 * Intel shall be used in advertising or otherwise to promote the sale, use or 0077 * other dealings in products derived from or relating to the Covered Code 0078 * without prior written authorization from Intel. 0079 * 0080 * 4. Disclaimer and Export Compliance 0081 * 0082 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 0083 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 0084 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 0085 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 0086 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 0087 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 0088 * PARTICULAR PURPOSE. 0089 * 0090 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 0091 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 0092 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 0093 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 0094 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 0095 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 0096 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 0097 * LIMITED REMEDY. 0098 * 0099 * 4.3. Licensee shall not export, either directly or indirectly, any of this 0100 * software or system incorporating such software without first obtaining any 0101 * required license or other approval from the U. S. Department of Commerce or 0102 * any other agency or department of the United States Government. In the 0103 * event Licensee exports any such software from the United States or 0104 * re-exports any such software from a foreign destination, Licensee shall 0105 * ensure that the distribution and export/re-export of the software is in 0106 * compliance with all laws, regulations, orders, or other restrictions of the 0107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 0108 * any of its subsidiaries will export/re-export any technical data, process, 0109 * software, or service, directly or indirectly, to any country for which the 0110 * United States government or any agency thereof requires an export license, 0111 * other governmental approval, or letter of assurance, without first obtaining 0112 * such license, approval or letter. 0113 * 0114 ***************************************************************************** 0115 * 0116 * Alternatively, you may choose to be licensed under the terms of the 0117 * following license: 0118 * 0119 * Redistribution and use in source and binary forms, with or without 0120 * modification, are permitted provided that the following conditions 0121 * are met: 0122 * 1. Redistributions of source code must retain the above copyright 0123 * notice, this list of conditions, and the following disclaimer, 0124 * without modification. 0125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 0126 * substantially similar to the "NO WARRANTY" disclaimer below 0127 * ("Disclaimer") and any redistribution must be conditioned upon 0128 * including a substantially similar Disclaimer requirement for further 0129 * binary redistribution. 0130 * 3. Neither the names of the above-listed copyright holders nor the names 0131 * of any contributors may be used to endorse or promote products derived 0132 * from this software without specific prior written permission. 0133 * 0134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 0135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 0136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 0137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 0138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 0139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 0140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 0142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 0144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0145 * 0146 * Alternatively, you may choose to be licensed under the terms of the 0147 * GNU General Public License ("GPL") version 2 as published by the Free 0148 * Software Foundation. 0149 * 0150 *****************************************************************************/ 0151 0152 #include "acpi.h" 0153 #include "accommon.h" 0154 #include "amlcode.h" 0155 #include "acnamesp.h" 0156 #include "acdispat.h" 0157 0158 #ifdef ACPI_ASL_COMPILER 0159 #include "acdisasm.h" 0160 #endif 0161 0162 #define _COMPONENT ACPI_NAMESPACE 0163 ACPI_MODULE_NAME ("nsaccess") 0164 0165 0166 /******************************************************************************* 0167 * 0168 * FUNCTION: AcpiNsRootInitialize 0169 * 0170 * PARAMETERS: None 0171 * 0172 * RETURN: Status 0173 * 0174 * DESCRIPTION: Allocate and initialize the default root named objects 0175 * 0176 * MUTEX: Locks namespace for entire execution 0177 * 0178 ******************************************************************************/ 0179 0180 ACPI_STATUS 0181 AcpiNsRootInitialize ( 0182 void) 0183 { 0184 ACPI_STATUS Status; 0185 const ACPI_PREDEFINED_NAMES *InitVal = NULL; 0186 ACPI_NAMESPACE_NODE *NewNode; 0187 ACPI_NAMESPACE_NODE *PrevNode = NULL; 0188 ACPI_OPERAND_OBJECT *ObjDesc; 0189 ACPI_STRING Val = NULL; 0190 0191 0192 ACPI_FUNCTION_TRACE (NsRootInitialize); 0193 0194 0195 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 0196 if (ACPI_FAILURE (Status)) 0197 { 0198 return_ACPI_STATUS (Status); 0199 } 0200 0201 /* 0202 * The global root ptr is initially NULL, so a non-NULL value indicates 0203 * that AcpiNsRootInitialize() has already been called; just return. 0204 */ 0205 if (AcpiGbl_RootNode) 0206 { 0207 Status = AE_OK; 0208 goto UnlockAndExit; 0209 } 0210 0211 /* 0212 * Tell the rest of the subsystem that the root is initialized 0213 * (This is OK because the namespace is locked) 0214 */ 0215 AcpiGbl_RootNode = &AcpiGbl_RootNodeStruct; 0216 0217 /* Enter the predefined names in the name table */ 0218 0219 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 0220 "Entering predefined entries into namespace\n")); 0221 0222 /* 0223 * Create the initial (default) namespace. 0224 * This namespace looks like something similar to this: 0225 * 0226 * ACPI Namespace (from Namespace Root): 0227 * 0 _GPE Scope 00203160 00 0228 * 0 _PR_ Scope 002031D0 00 0229 * 0 _SB_ Device 00203240 00 Notify Object: 0020ADD8 0230 * 0 _SI_ Scope 002032B0 00 0231 * 0 _TZ_ Device 00203320 00 0232 * 0 _REV Integer 00203390 00 = 0000000000000002 0233 * 0 _OS_ String 00203488 00 Len 14 "Microsoft Windows NT" 0234 * 0 _GL_ Mutex 00203580 00 Object 002035F0 0235 * 0 _OSI Method 00203678 00 Args 1 Len 0000 Aml 00000000 0236 */ 0237 for (InitVal = AcpiGbl_PreDefinedNames; InitVal->Name; InitVal++) 0238 { 0239 Status = AE_OK; 0240 0241 /* _OSI is optional for now, will be permanent later */ 0242 0243 if (!strcmp (InitVal->Name, "_OSI") && !AcpiGbl_CreateOsiMethod) 0244 { 0245 continue; 0246 } 0247 0248 /* 0249 * Create, init, and link the new predefined name 0250 * Note: No need to use AcpiNsLookup here because all the 0251 * predefined names are at the root level. It is much easier to 0252 * just create and link the new node(s) here. 0253 */ 0254 NewNode = AcpiNsCreateNode (*ACPI_CAST_PTR (UINT32, InitVal->Name)); 0255 if (!NewNode) 0256 { 0257 Status = AE_NO_MEMORY; 0258 goto UnlockAndExit; 0259 } 0260 0261 NewNode->DescriptorType = ACPI_DESC_TYPE_NAMED; 0262 NewNode->Type = InitVal->Type; 0263 0264 if (!PrevNode) 0265 { 0266 AcpiGbl_RootNodeStruct.Child = NewNode; 0267 } 0268 else 0269 { 0270 PrevNode->Peer = NewNode; 0271 } 0272 0273 NewNode->Parent = &AcpiGbl_RootNodeStruct; 0274 PrevNode = NewNode; 0275 0276 /* 0277 * Name entered successfully. If entry in PreDefinedNames[] specifies 0278 * an initial value, create the initial value. 0279 */ 0280 if (InitVal->Val) 0281 { 0282 Status = AcpiOsPredefinedOverride (InitVal, &Val); 0283 if (ACPI_FAILURE (Status)) 0284 { 0285 ACPI_ERROR ((AE_INFO, 0286 "Could not override predefined %s", 0287 InitVal->Name)); 0288 } 0289 0290 if (!Val) 0291 { 0292 Val = InitVal->Val; 0293 } 0294 0295 /* 0296 * Entry requests an initial value, allocate a 0297 * descriptor for it. 0298 */ 0299 ObjDesc = AcpiUtCreateInternalObject (InitVal->Type); 0300 if (!ObjDesc) 0301 { 0302 Status = AE_NO_MEMORY; 0303 goto UnlockAndExit; 0304 } 0305 0306 /* 0307 * Convert value string from table entry to 0308 * internal representation. Only types actually 0309 * used for initial values are implemented here. 0310 */ 0311 switch (InitVal->Type) 0312 { 0313 case ACPI_TYPE_METHOD: 0314 0315 ObjDesc->Method.ParamCount = (UINT8) ACPI_TO_INTEGER (Val); 0316 ObjDesc->Common.Flags |= AOPOBJ_DATA_VALID; 0317 0318 #if defined (ACPI_ASL_COMPILER) 0319 0320 /* Save the parameter count for the iASL compiler */ 0321 0322 NewNode->Value = ObjDesc->Method.ParamCount; 0323 #else 0324 /* Mark this as a very SPECIAL method (_OSI) */ 0325 0326 ObjDesc->Method.InfoFlags = ACPI_METHOD_INTERNAL_ONLY; 0327 ObjDesc->Method.Dispatch.Implementation = AcpiUtOsiImplementation; 0328 #endif 0329 break; 0330 0331 case ACPI_TYPE_INTEGER: 0332 0333 ObjDesc->Integer.Value = ACPI_TO_INTEGER (Val); 0334 break; 0335 0336 case ACPI_TYPE_STRING: 0337 0338 /* Build an object around the static string */ 0339 0340 ObjDesc->String.Length = (UINT32) strlen (Val); 0341 ObjDesc->String.Pointer = Val; 0342 ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER; 0343 break; 0344 0345 case ACPI_TYPE_MUTEX: 0346 0347 ObjDesc->Mutex.Node = NewNode; 0348 ObjDesc->Mutex.SyncLevel = (UINT8) (ACPI_TO_INTEGER (Val) - 1); 0349 0350 /* Create a mutex */ 0351 0352 Status = AcpiOsCreateMutex (&ObjDesc->Mutex.OsMutex); 0353 if (ACPI_FAILURE (Status)) 0354 { 0355 AcpiUtRemoveReference (ObjDesc); 0356 goto UnlockAndExit; 0357 } 0358 0359 /* Special case for ACPI Global Lock */ 0360 0361 if (strcmp (InitVal->Name, "_GL_") == 0) 0362 { 0363 AcpiGbl_GlobalLockMutex = ObjDesc; 0364 0365 /* Create additional counting semaphore for global lock */ 0366 0367 Status = AcpiOsCreateSemaphore ( 0368 1, 0, &AcpiGbl_GlobalLockSemaphore); 0369 if (ACPI_FAILURE (Status)) 0370 { 0371 AcpiUtRemoveReference (ObjDesc); 0372 goto UnlockAndExit; 0373 } 0374 } 0375 break; 0376 0377 default: 0378 0379 ACPI_ERROR ((AE_INFO, "Unsupported initial type value 0x%X", 0380 InitVal->Type)); 0381 AcpiUtRemoveReference (ObjDesc); 0382 ObjDesc = NULL; 0383 continue; 0384 } 0385 0386 /* Store pointer to value descriptor in the Node */ 0387 0388 Status = AcpiNsAttachObject (NewNode, ObjDesc, 0389 ObjDesc->Common.Type); 0390 0391 /* Remove local reference to the object */ 0392 0393 AcpiUtRemoveReference (ObjDesc); 0394 } 0395 } 0396 0397 UnlockAndExit: 0398 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 0399 0400 /* Save a handle to "_GPE", it is always present */ 0401 0402 if (ACPI_SUCCESS (Status)) 0403 { 0404 Status = AcpiNsGetNode (NULL, "\\_GPE", ACPI_NS_NO_UPSEARCH, 0405 &AcpiGbl_FadtGpeDevice); 0406 } 0407 0408 return_ACPI_STATUS (Status); 0409 } 0410 0411 0412 /******************************************************************************* 0413 * 0414 * FUNCTION: AcpiNsLookup 0415 * 0416 * PARAMETERS: ScopeInfo - Current scope info block 0417 * Pathname - Search pathname, in internal format 0418 * (as represented in the AML stream) 0419 * Type - Type associated with name 0420 * InterpreterMode - IMODE_LOAD_PASS2 => add name if not found 0421 * Flags - Flags describing the search restrictions 0422 * WalkState - Current state of the walk 0423 * ReturnNode - Where the Node is placed (if found 0424 * or created successfully) 0425 * 0426 * RETURN: Status 0427 * 0428 * DESCRIPTION: Find or enter the passed name in the name space. 0429 * Log an error if name not found in Exec mode. 0430 * 0431 * MUTEX: Assumes namespace is locked. 0432 * 0433 ******************************************************************************/ 0434 0435 ACPI_STATUS 0436 AcpiNsLookup ( 0437 ACPI_GENERIC_STATE *ScopeInfo, 0438 char *Pathname, 0439 ACPI_OBJECT_TYPE Type, 0440 ACPI_INTERPRETER_MODE InterpreterMode, 0441 UINT32 Flags, 0442 ACPI_WALK_STATE *WalkState, 0443 ACPI_NAMESPACE_NODE **ReturnNode) 0444 { 0445 ACPI_STATUS Status; 0446 char *Path = Pathname; 0447 char *ExternalPath; 0448 ACPI_NAMESPACE_NODE *PrefixNode; 0449 ACPI_NAMESPACE_NODE *CurrentNode = NULL; 0450 ACPI_NAMESPACE_NODE *ThisNode = NULL; 0451 UINT32 NumSegments; 0452 UINT32 NumCarats; 0453 ACPI_NAME SimpleName; 0454 ACPI_OBJECT_TYPE TypeToCheckFor; 0455 ACPI_OBJECT_TYPE ThisSearchType; 0456 UINT32 SearchParentFlag = ACPI_NS_SEARCH_PARENT; 0457 UINT32 LocalFlags; 0458 ACPI_INTERPRETER_MODE LocalInterpreterMode; 0459 0460 0461 ACPI_FUNCTION_TRACE (NsLookup); 0462 0463 0464 if (!ReturnNode) 0465 { 0466 return_ACPI_STATUS (AE_BAD_PARAMETER); 0467 } 0468 0469 LocalFlags = Flags & 0470 ~(ACPI_NS_ERROR_IF_FOUND | ACPI_NS_OVERRIDE_IF_FOUND | 0471 ACPI_NS_SEARCH_PARENT); 0472 *ReturnNode = ACPI_ENTRY_NOT_FOUND; 0473 AcpiGbl_NsLookupCount++; 0474 0475 if (!AcpiGbl_RootNode) 0476 { 0477 return_ACPI_STATUS (AE_NO_NAMESPACE); 0478 } 0479 0480 /* Get the prefix scope. A null scope means use the root scope */ 0481 0482 if ((!ScopeInfo) || 0483 (!ScopeInfo->Scope.Node)) 0484 { 0485 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 0486 "Null scope prefix, using root node (%p)\n", 0487 AcpiGbl_RootNode)); 0488 0489 PrefixNode = AcpiGbl_RootNode; 0490 } 0491 else 0492 { 0493 PrefixNode = ScopeInfo->Scope.Node; 0494 if (ACPI_GET_DESCRIPTOR_TYPE (PrefixNode) != ACPI_DESC_TYPE_NAMED) 0495 { 0496 ACPI_ERROR ((AE_INFO, "%p is not a namespace node [%s]", 0497 PrefixNode, AcpiUtGetDescriptorName (PrefixNode))); 0498 return_ACPI_STATUS (AE_AML_INTERNAL); 0499 } 0500 0501 if (!(Flags & ACPI_NS_PREFIX_IS_SCOPE)) 0502 { 0503 /* 0504 * This node might not be a actual "scope" node (such as a 0505 * Device/Method, etc.) It could be a Package or other object 0506 * node. Backup up the tree to find the containing scope node. 0507 */ 0508 while (!AcpiNsOpensScope (PrefixNode->Type) && 0509 PrefixNode->Type != ACPI_TYPE_ANY) 0510 { 0511 PrefixNode = PrefixNode->Parent; 0512 } 0513 } 0514 } 0515 0516 /* Save type. TBD: may be no longer necessary */ 0517 0518 TypeToCheckFor = Type; 0519 0520 /* 0521 * Begin examination of the actual pathname 0522 */ 0523 if (!Pathname) 0524 { 0525 /* A Null NamePath is allowed and refers to the root */ 0526 0527 NumSegments = 0; 0528 ThisNode = AcpiGbl_RootNode; 0529 Path = ""; 0530 0531 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 0532 "Null Pathname (Zero segments), Flags=%X\n", Flags)); 0533 } 0534 else 0535 { 0536 /* 0537 * Name pointer is valid (and must be in internal name format) 0538 * 0539 * Check for scope prefixes: 0540 * 0541 * As represented in the AML stream, a namepath consists of an 0542 * optional scope prefix followed by a name segment part. 0543 * 0544 * If present, the scope prefix is either a Root Prefix (in 0545 * which case the name is fully qualified), or one or more 0546 * Parent Prefixes (in which case the name's scope is relative 0547 * to the current scope). 0548 */ 0549 if (*Path == (UINT8) AML_ROOT_PREFIX) 0550 { 0551 /* Pathname is fully qualified, start from the root */ 0552 0553 ThisNode = AcpiGbl_RootNode; 0554 SearchParentFlag = ACPI_NS_NO_UPSEARCH; 0555 0556 /* Point to name segment part */ 0557 0558 Path++; 0559 0560 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 0561 "Path is absolute from root [%p]\n", ThisNode)); 0562 } 0563 else 0564 { 0565 /* Pathname is relative to current scope, start there */ 0566 0567 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 0568 "Searching relative to prefix scope [%4.4s] (%p)\n", 0569 AcpiUtGetNodeName (PrefixNode), PrefixNode)); 0570 0571 /* 0572 * Handle multiple Parent Prefixes (carat) by just getting 0573 * the parent node for each prefix instance. 0574 */ 0575 ThisNode = PrefixNode; 0576 NumCarats = 0; 0577 while (*Path == (UINT8) AML_PARENT_PREFIX) 0578 { 0579 /* Name is fully qualified, no search rules apply */ 0580 0581 SearchParentFlag = ACPI_NS_NO_UPSEARCH; 0582 0583 /* 0584 * Point past this prefix to the name segment 0585 * part or the next Parent Prefix 0586 */ 0587 Path++; 0588 0589 /* Backup to the parent node */ 0590 0591 NumCarats++; 0592 ThisNode = ThisNode->Parent; 0593 if (!ThisNode) 0594 { 0595 /* 0596 * Current scope has no parent scope. Externalize 0597 * the internal path for error message. 0598 */ 0599 Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, Pathname, 0600 NULL, &ExternalPath); 0601 if (ACPI_SUCCESS (Status)) 0602 { 0603 ACPI_ERROR ((AE_INFO, 0604 "%s: Path has too many parent prefixes (^)", 0605 ExternalPath)); 0606 0607 ACPI_FREE (ExternalPath); 0608 } 0609 0610 return_ACPI_STATUS (AE_NOT_FOUND); 0611 } 0612 } 0613 0614 if (SearchParentFlag == ACPI_NS_NO_UPSEARCH) 0615 { 0616 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 0617 "Search scope is [%4.4s], path has %u carat(s)\n", 0618 AcpiUtGetNodeName (ThisNode), NumCarats)); 0619 } 0620 } 0621 0622 /* 0623 * Determine the number of ACPI name segments in this pathname. 0624 * 0625 * The segment part consists of either: 0626 * - A Null name segment (0) 0627 * - A DualNamePrefix followed by two 4-byte name segments 0628 * - A MultiNamePrefix followed by a byte indicating the 0629 * number of segments and the segments themselves. 0630 * - A single 4-byte name segment 0631 * 0632 * Examine the name prefix opcode, if any, to determine the number of 0633 * segments. 0634 */ 0635 switch (*Path) 0636 { 0637 case 0: 0638 /* 0639 * Null name after a root or parent prefixes. We already 0640 * have the correct target node and there are no name segments. 0641 */ 0642 NumSegments = 0; 0643 Type = ThisNode->Type; 0644 0645 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 0646 "Prefix-only Pathname (Zero name segments), Flags=%X\n", 0647 Flags)); 0648 break; 0649 0650 case AML_DUAL_NAME_PREFIX: 0651 0652 /* More than one NameSeg, search rules do not apply */ 0653 0654 SearchParentFlag = ACPI_NS_NO_UPSEARCH; 0655 0656 /* Two segments, point to first name segment */ 0657 0658 NumSegments = 2; 0659 Path++; 0660 0661 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 0662 "Dual Pathname (2 segments, Flags=%X)\n", Flags)); 0663 break; 0664 0665 case AML_MULTI_NAME_PREFIX: 0666 0667 /* More than one NameSeg, search rules do not apply */ 0668 0669 SearchParentFlag = ACPI_NS_NO_UPSEARCH; 0670 0671 /* Extract segment count, point to first name segment */ 0672 0673 Path++; 0674 NumSegments = (UINT32) (UINT8) *Path; 0675 Path++; 0676 0677 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 0678 "Multi Pathname (%u Segments, Flags=%X)\n", 0679 NumSegments, Flags)); 0680 break; 0681 0682 default: 0683 /* 0684 * Not a Null name, no Dual or Multi prefix, hence there is 0685 * only one name segment and Pathname is already pointing to it. 0686 */ 0687 NumSegments = 1; 0688 0689 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 0690 "Simple Pathname (1 segment, Flags=%X)\n", Flags)); 0691 break; 0692 } 0693 0694 ACPI_DEBUG_EXEC (AcpiNsPrintPathname (NumSegments, Path)); 0695 } 0696 0697 0698 /* 0699 * Search namespace for each segment of the name. Loop through and 0700 * verify (or add to the namespace) each name segment. 0701 * 0702 * The object type is significant only at the last name 0703 * segment. (We don't care about the types along the path, only 0704 * the type of the final target object.) 0705 */ 0706 ThisSearchType = ACPI_TYPE_ANY; 0707 CurrentNode = ThisNode; 0708 0709 while (NumSegments && CurrentNode) 0710 { 0711 NumSegments--; 0712 if (!NumSegments) 0713 { 0714 /* This is the last segment, enable typechecking */ 0715 0716 ThisSearchType = Type; 0717 0718 /* 0719 * Only allow automatic parent search (search rules) if the caller 0720 * requested it AND we have a single, non-fully-qualified NameSeg 0721 */ 0722 if ((SearchParentFlag != ACPI_NS_NO_UPSEARCH) && 0723 (Flags & ACPI_NS_SEARCH_PARENT)) 0724 { 0725 LocalFlags |= ACPI_NS_SEARCH_PARENT; 0726 } 0727 0728 /* Set error flag according to caller */ 0729 0730 if (Flags & ACPI_NS_ERROR_IF_FOUND) 0731 { 0732 LocalFlags |= ACPI_NS_ERROR_IF_FOUND; 0733 } 0734 0735 /* Set override flag according to caller */ 0736 0737 if (Flags & ACPI_NS_OVERRIDE_IF_FOUND) 0738 { 0739 LocalFlags |= ACPI_NS_OVERRIDE_IF_FOUND; 0740 } 0741 } 0742 0743 /* Handle opcodes that create a new NameSeg via a full NamePath */ 0744 0745 LocalInterpreterMode = InterpreterMode; 0746 if ((Flags & ACPI_NS_PREFIX_MUST_EXIST) && (NumSegments > 0)) 0747 { 0748 /* Every element of the path must exist (except for the final NameSeg) */ 0749 0750 LocalInterpreterMode = ACPI_IMODE_EXECUTE; 0751 } 0752 0753 /* Extract one ACPI name from the front of the pathname */ 0754 0755 ACPI_MOVE_32_TO_32 (&SimpleName, Path); 0756 0757 /* Try to find the single (4 character) ACPI name */ 0758 0759 Status = AcpiNsSearchAndEnter (SimpleName, WalkState, CurrentNode, 0760 LocalInterpreterMode, ThisSearchType, LocalFlags, &ThisNode); 0761 if (ACPI_FAILURE (Status)) 0762 { 0763 if (Status == AE_NOT_FOUND) 0764 { 0765 #if !defined ACPI_ASL_COMPILER /* Note: iASL reports this error by itself, not needed here */ 0766 if (Flags & ACPI_NS_PREFIX_MUST_EXIST) 0767 { 0768 AcpiOsPrintf (ACPI_MSG_BIOS_ERROR 0769 "Object does not exist: %4.4s\n", (char *) &SimpleName); 0770 } 0771 #endif 0772 /* Name not found in ACPI namespace */ 0773 0774 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 0775 "Name [%4.4s] not found in scope [%4.4s] %p\n", 0776 (char *) &SimpleName, (char *) &CurrentNode->Name, 0777 CurrentNode)); 0778 } 0779 0780 #ifdef ACPI_EXEC_APP 0781 if ((Status == AE_ALREADY_EXISTS) && 0782 (ThisNode->Flags & ANOBJ_NODE_EARLY_INIT)) 0783 { 0784 ThisNode->Flags &= ~ANOBJ_NODE_EARLY_INIT; 0785 Status = AE_OK; 0786 } 0787 #endif 0788 0789 #ifdef ACPI_ASL_COMPILER 0790 /* 0791 * If this ACPI name already exists within the namespace as an 0792 * external declaration, then mark the external as a conflicting 0793 * declaration and proceed to process the current node as if it did 0794 * not exist in the namespace. If this node is not processed as 0795 * normal, then it could cause improper namespace resolution 0796 * by failing to open a new scope. 0797 */ 0798 if (AcpiGbl_DisasmFlag && 0799 (Status == AE_ALREADY_EXISTS) && 0800 ((ThisNode->Flags & ANOBJ_IS_EXTERNAL) || 0801 (WalkState && WalkState->Opcode == AML_EXTERNAL_OP))) 0802 { 0803 ThisNode->Flags &= ~ANOBJ_IS_EXTERNAL; 0804 ThisNode->Type = (UINT8)ThisSearchType; 0805 if (WalkState->Opcode != AML_EXTERNAL_OP) 0806 { 0807 AcpiDmMarkExternalConflict (ThisNode); 0808 } 0809 break; 0810 } 0811 #endif 0812 0813 *ReturnNode = ThisNode; 0814 return_ACPI_STATUS (Status); 0815 } 0816 0817 /* More segments to follow? */ 0818 0819 if (NumSegments > 0) 0820 { 0821 /* 0822 * If we have an alias to an object that opens a scope (such as a 0823 * device or processor), we need to dereference the alias here so 0824 * that we can access any children of the original node (via the 0825 * remaining segments). 0826 */ 0827 if (ThisNode->Type == ACPI_TYPE_LOCAL_ALIAS) 0828 { 0829 if (!ThisNode->Object) 0830 { 0831 return_ACPI_STATUS (AE_NOT_EXIST); 0832 } 0833 0834 if (AcpiNsOpensScope (((ACPI_NAMESPACE_NODE *) 0835 ThisNode->Object)->Type)) 0836 { 0837 ThisNode = (ACPI_NAMESPACE_NODE *) ThisNode->Object; 0838 } 0839 } 0840 } 0841 0842 /* Special handling for the last segment (NumSegments == 0) */ 0843 0844 else 0845 { 0846 /* 0847 * Sanity typecheck of the target object: 0848 * 0849 * If 1) This is the last segment (NumSegments == 0) 0850 * 2) And we are looking for a specific type 0851 * (Not checking for TYPE_ANY) 0852 * 3) Which is not an alias 0853 * 4) Which is not a local type (TYPE_SCOPE) 0854 * 5) And the type of target object is known (not TYPE_ANY) 0855 * 6) And target object does not match what we are looking for 0856 * 0857 * Then we have a type mismatch. Just warn and ignore it. 0858 */ 0859 if ((TypeToCheckFor != ACPI_TYPE_ANY) && 0860 (TypeToCheckFor != ACPI_TYPE_LOCAL_ALIAS) && 0861 (TypeToCheckFor != ACPI_TYPE_LOCAL_METHOD_ALIAS) && 0862 (TypeToCheckFor != ACPI_TYPE_LOCAL_SCOPE) && 0863 (ThisNode->Type != ACPI_TYPE_ANY) && 0864 (ThisNode->Type != TypeToCheckFor)) 0865 { 0866 /* Complain about a type mismatch */ 0867 0868 ACPI_WARNING ((AE_INFO, 0869 "NsLookup: Type mismatch on %4.4s (%s), searching for (%s)", 0870 ACPI_CAST_PTR (char, &SimpleName), 0871 AcpiUtGetTypeName (ThisNode->Type), 0872 AcpiUtGetTypeName (TypeToCheckFor))); 0873 } 0874 0875 /* 0876 * If this is the last name segment and we are not looking for a 0877 * specific type, but the type of found object is known, use that 0878 * type to (later) see if it opens a scope. 0879 */ 0880 if (Type == ACPI_TYPE_ANY) 0881 { 0882 Type = ThisNode->Type; 0883 } 0884 } 0885 0886 /* Point to next name segment and make this node current */ 0887 0888 Path += ACPI_NAMESEG_SIZE; 0889 CurrentNode = ThisNode; 0890 } 0891 0892 /* Always check if we need to open a new scope */ 0893 0894 if (!(Flags & ACPI_NS_DONT_OPEN_SCOPE) && (WalkState)) 0895 { 0896 /* 0897 * If entry is a type which opens a scope, push the new scope on the 0898 * scope stack. 0899 */ 0900 if (AcpiNsOpensScope (Type)) 0901 { 0902 Status = AcpiDsScopeStackPush (ThisNode, Type, WalkState); 0903 if (ACPI_FAILURE (Status)) 0904 { 0905 return_ACPI_STATUS (Status); 0906 } 0907 } 0908 } 0909 0910 #ifdef ACPI_EXEC_APP 0911 if (Flags & ACPI_NS_EARLY_INIT) 0912 { 0913 ThisNode->Flags |= ANOBJ_NODE_EARLY_INIT; 0914 } 0915 #endif 0916 0917 *ReturnNode = ThisNode; 0918 return_ACPI_STATUS (AE_OK); 0919 }
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |