diff options
author | Jung-uk Kim <jkim@FreeBSD.org> | 2009-11-16 18:28:41 +0000 |
---|---|---|
committer | Jung-uk Kim <jkim@FreeBSD.org> | 2009-11-16 18:28:41 +0000 |
commit | 1b40f7cf3cd1180573e2d9ec6cd169e887b720e0 (patch) | |
tree | a94f496090c5bfd215b19df99d9e0f6ea0f6c293 | |
parent | a19285149615c60009a9c5190c260de14b2293f7 (diff) | |
download | src-test2-1b40f7cf3cd1180573e2d9ec6cd169e887b720e0.tar.gz src-test2-1b40f7cf3cd1180573e2d9ec6cd169e887b720e0.zip |
Notes
43 files changed, 1253 insertions, 225 deletions
diff --git a/changes.txt b/changes.txt index 9e8ff8961a7a..a615bdde09ac 100644 --- a/changes.txt +++ b/changes.txt @@ -1,4 +1,77 @@ ---------------------------------------- +12 November 2009. Summary of changes for version 20091112: + +This release is available at www.acpica.org/downloads + +1) ACPI CA Core Subsystem: + +Implemented a post-order callback to AcpiWalkNamespace. The existing +interface only has a pre-order callback. This change adds an additional +parameter for a post-order callback which will be more useful for bus scans. +ACPICA BZ 779. Lin Ming. Updated the ACPICA Programmer Reference. + +Modified the behavior of the operation region memory mapping cache for +SystemMemory. Ensure that the memory mappings created for operation regions +do not cross 4K page boundaries. Crossing a page boundary while mapping +regions can cause kernel warnings on some hosts if the pages have different +attributes. Such regions are probably BIOS bugs, and this is the workaround. +Linux BZ 14445. Lin Ming. + +Implemented an automatic repair for predefined methods that must return +sorted lists. This change will repair (by sorting) packages returned by _ALR, +_PSS, and _TSS. Drivers can now assume that the packages are correctly sorted +and do not contain NULL package elements. Adds one new file, +namespace/nsrepair2.c. ACPICA BZ 784. Lin Ming, Bob Moore. + +Fixed a possible fault during predefined name validation if a return Package +object contains NULL elements. Also adds a warning if a NULL element is +followed by any non-null elements. ACPICA BZ 813, 814. Future enhancement may +include repair or removal of all such NULL elements where possible. + +Implemented additional module-level executable AML code support. This change +will execute module-level code that is not at the root of the namespace +(under a Device object, etc.) at table load time. Module-level executable AML +code has been illegal since ACPI 2.0. ACPICA BZ 762. Lin Ming. + +Implemented a new internal function to create Integer objects. This function +simplifies miscellaneous object creation code. ACPICA BZ 823. + +Reduced the severity of predefined repair messages, Warning to Info. Since +the object was successfully repaired, a warning is too severe. Reduced to an +info message for now. These messages may eventually be changed to debug-only. +ACPICA BZ 812. + +Example Code and Data Size: These are the sizes for the OS-independent +acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The +debug version of the code includes the debug output trace mechanism and has a +much larger code and data size. + + Previous Release: + Non-Debug Version: 85.8K Code, 18.0K Data, 103.8K Total + Debug Version: 161.8K Code, 50.6K Data, 212.4K Total + Current Release: + Non-Debug Version: 86.6K Code, 18.2K Data, 104.8K Total + Debug Version: 162.7K Code, 50.8K Data, 213.5K Total + +2) iASL Compiler/Disassembler and Tools: + +iASL: Implemented Switch() with While(1) so that Break works correctly. This +change correctly implements the Switch operator with a surrounding While(1) +so that the Break operator works as expected. ACPICA BZ 461. Lin Ming. + +iASL: Added a message if a package initializer list is shorter than package +length. Adds a new remark for a Package() declaration if an initializer list +exists, but is shorter than the declared length of the package. Although +technically legal, this is probably a coding error and it is seen in the +field. ACPICA BZ 815. Lin Ming, Bob Moore. + +iASL: Fixed a problem where the compiler could fault after the maximum number +of errors was reached (200). + +acpixtract: Fixed a possible warning for pointer cast if the compiler warning +level set very high. + +---------------------------------------- 13 October 2009. Summary of changes for version 20091013: This release is available at www.acpica.org/downloads diff --git a/compiler/aslcompile.c b/compiler/aslcompile.c index 07de1fe63c9b..d9836ca908e4 100644 --- a/compiler/aslcompile.c +++ b/compiler/aslcompile.c @@ -895,13 +895,6 @@ CmCleanupAndExit ( 10) / Gbl_NsLookupCount); } - /* Close all open files */ - - for (i = 2; i < ASL_MAX_FILE_TYPE; i++) - { - FlCloseFile (i); - } - /* * TBD: SourceOutput should be .TMP, then rename if we want to keep it? */ @@ -923,6 +916,13 @@ CmCleanupAndExit ( } UtDisplaySummary (ASL_FILE_STDOUT); + + /* Close all open files */ + + for (i = 2; i < ASL_MAX_FILE_TYPE; i++) + { + FlCloseFile (i); + } } diff --git a/compiler/aslerror.c b/compiler/aslerror.c index 87300b1529c8..5aa9e8c36a26 100644 --- a/compiler/aslerror.c +++ b/compiler/aslerror.c @@ -535,6 +535,7 @@ AslCommonError ( Gbl_NextError = Gbl_ErrorLog; CmDoOutputFiles (); CmCleanupAndExit (); + exit(1); } return; diff --git a/compiler/asllookup.c b/compiler/asllookup.c index 51c036967c8d..b99d03787798 100644 --- a/compiler/asllookup.c +++ b/compiler/asllookup.c @@ -526,7 +526,7 @@ LsDisplayNamespace ( /* Walk entire namespace from the root */ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, FALSE, LsDoOneNamespaceObject, + ACPI_UINT32_MAX, FALSE, LsDoOneNamespaceObject, NULL, NULL, NULL); /* Print the full pathname for each namespace node */ @@ -534,7 +534,7 @@ LsDisplayNamespace ( FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\nNamespace pathnames\n\n"); Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, FALSE, LsDoOnePathname, + ACPI_UINT32_MAX, FALSE, LsDoOnePathname, NULL, NULL, NULL); return (Status); @@ -598,7 +598,7 @@ LkObjectExists ( /* Walk entire namespace from the supplied root */ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, FALSE, LsCompareOneNamespaceObject, + ACPI_UINT32_MAX, FALSE, LsCompareOneNamespaceObject, NULL, Name, NULL); if (Status == AE_CTRL_TRUE) { @@ -753,7 +753,7 @@ LkFindUnreferencedObjects ( /* Walk entire namespace from the supplied root */ (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, FALSE, LkIsObjectUsed, + ACPI_UINT32_MAX, FALSE, LkIsObjectUsed, NULL, NULL, NULL); } diff --git a/compiler/asloperands.c b/compiler/asloperands.c index c354855dd61f..8f2388e365bd 100644 --- a/compiler/asloperands.c +++ b/compiler/asloperands.c @@ -788,20 +788,30 @@ OpnDoPackage ( if ((PackageLengthOp->Asl.ParseOpcode == PARSEOP_INTEGER) || (PackageLengthOp->Asl.ParseOpcode == PARSEOP_QWORDCONST)) { - if (PackageLengthOp->Asl.Value.Integer >= PackageLength) + if (PackageLengthOp->Asl.Value.Integer > PackageLength) { - /* Allow package to be longer than the initializer list */ + /* + * Allow package length to be longer than the initializer + * list -- but if the length of initializer list is nonzero, + * issue a message since this is probably a coding error, + * even though technically legal. + */ + if (PackageLength > 0) + { + AslError (ASL_REMARK, ASL_MSG_LIST_LENGTH_SHORT, + PackageLengthOp, NULL); + } PackageLength = (UINT32) PackageLengthOp->Asl.Value.Integer; } - else + else if (PackageLengthOp->Asl.Value.Integer < PackageLength) { /* - * Initializer list is longer than the package length. This - * is an error as per the ACPI spec. + * The package length is smaller than the length of the + * initializer list. This is an error as per the ACPI spec. */ - AslError (ASL_ERROR, ASL_MSG_LIST_LENGTH, - PackageLengthOp->Asl.Next, NULL); + AslError (ASL_ERROR, ASL_MSG_LIST_LENGTH_LONG, + PackageLengthOp, NULL); } } diff --git a/compiler/asltransform.c b/compiler/asltransform.c index eb4546818c35..b6b22c52ec60 100644 --- a/compiler/asltransform.c +++ b/compiler/asltransform.c @@ -468,6 +468,8 @@ TrDoSwitch ( ACPI_PARSE_OBJECT *NewOp; ACPI_PARSE_OBJECT *NewOp2; ACPI_PARSE_OBJECT *MethodOp; + ACPI_PARSE_OBJECT *StoreOp; + ACPI_PARSE_OBJECT *BreakOp; char *PredicateValueName; UINT16 Index; UINT32 Btype; @@ -638,11 +640,7 @@ TrDoSwitch ( */ if (CurrentParentNode == StartNode) { - Conditional->Asl.Parent = CurrentParentNode->Asl.Parent; - - /* Link IF into the peer list */ - - TrAmlInsertPeer (CurrentParentNode, Conditional); + Conditional->Asl.Next = NULL; } else { @@ -695,6 +693,7 @@ TrDoSwitch ( { return; } + TrAmlInitNode (DefaultOp, PARSEOP_ELSE); DefaultOp->Asl.Parent = Conditional->Asl.Parent; @@ -799,22 +798,44 @@ TrDoSwitch ( TrAmlSetSubtreeParent (NewOp2, NewOp); /* - * Transform the Switch() into a Store() node which will be used to save the + * Transform the Switch() into a While(One)-Break node. + * And create a Store() node which will be used to save the * Switch() value. The store is of the form: Store (Value, _T_x) * where _T_x is the temp variable. */ - TrAmlInitNode (StartNode, PARSEOP_STORE); - StartNode->Asl.Child = NULL; + TrAmlInitNode (StartNode, PARSEOP_WHILE); + NewOp = TrCreateLeafNode (PARSEOP_ONE); + NewOp->Asl.Next = Predicate->Asl.Next; + NewOp->Asl.Parent = StartNode; + StartNode->Asl.Child = NewOp; + + /* Create a Store() node */ + + StoreOp = TrCreateLeafNode (PARSEOP_STORE); + StoreOp->Asl.Parent = StartNode; + TrAmlInsertPeer (NewOp, StoreOp); /* Complete the Store subtree */ - StartNode->Asl.Child = Predicate; - Predicate->Asl.Parent = StartNode; + StoreOp->Asl.Child = Predicate; + Predicate->Asl.Parent = StoreOp; NewOp = TrCreateValuedLeafNode (PARSEOP_NAMESEG, (ACPI_INTEGER) ACPI_TO_INTEGER (PredicateValueName)); - NewOp->Asl.Parent = StartNode; + NewOp->Asl.Parent = StoreOp; Predicate->Asl.Next = NewOp; + + /* Create a Break() node and insert it into the end of While() */ + + Conditional = StartNode->Asl.Child; + while (Conditional->Asl.Next) + { + Conditional = Conditional->Asl.Next; + } + + BreakOp = TrCreateLeafNode (PARSEOP_BREAK); + BreakOp->Asl.Parent = StartNode; + TrAmlInsertPeer (Conditional, BreakOp); } diff --git a/compiler/asltypes.h b/compiler/asltypes.h index fb2396f4dde9..0500ba9d3776 100644 --- a/compiler/asltypes.h +++ b/compiler/asltypes.h @@ -369,7 +369,8 @@ typedef enum ASL_MSG_INVALID_TIME, ASL_MSG_INVALID_TYPE, ASL_MSG_INVALID_UUID, - ASL_MSG_LIST_LENGTH, + ASL_MSG_LIST_LENGTH_LONG, + ASL_MSG_LIST_LENGTH_SHORT, ASL_MSG_LISTING_FILE_OPEN, ASL_MSG_LISTING_FILENAME, ASL_MSG_LOCAL_INIT, @@ -488,7 +489,8 @@ char *AslMessages [] = { /* ASL_MSG_INVALID_TIME */ "Time parameter too long (255 max)", /* ASL_MSG_INVALID_TYPE */ "Invalid type", /* ASL_MSG_INVALID_UUID */ "UUID string must be of the form \"aabbccdd-eeff-gghh-iijj-kkllmmnnoopp\"", -/* ASL_MSG_LIST_LENGTH */ "Initializer list too long", +/* ASL_MSG_LIST_LENGTH_LONG */ "Initializer list longer than declared package length", +/* ASL_MSG_LIST_LENGTH_SHORT */ "Initializer list shorter than declared package length", /* ASL_MSG_LISTING_FILE_OPEN */ "Could not open listing file", /* ASL_MSG_LISTING_FILENAME */ "Could not create listing filename", /* ASL_MSG_LOCAL_INIT */ "Method local variable is not initialized", diff --git a/debugger/dbcmds.c b/debugger/dbcmds.c index 6c0f8234afd3..0a542d952f45 100644 --- a/debugger/dbcmds.c +++ b/debugger/dbcmds.c @@ -383,7 +383,7 @@ AcpiDbFindReferences ( /* Search all nodes in namespace */ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - AcpiDbWalkForReferences, (void *) ObjDesc, NULL); + AcpiDbWalkForReferences, NULL, (void *) ObjDesc, NULL); } @@ -475,7 +475,7 @@ AcpiDbCheckPredefinedNames ( /* Search all nodes in namespace */ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - AcpiDbWalkForPredefinedNames, (void *) &Count, NULL); + AcpiDbWalkForPredefinedNames, NULL, (void *) &Count, NULL); AcpiOsPrintf ("Found %d predefined names in the namespace\n", Count); } @@ -617,7 +617,7 @@ AcpiDbBatchExecute ( /* Search all nodes in namespace */ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - AcpiDbWalkForExecute, (void *) &Info, NULL); + AcpiDbWalkForExecute, NULL, (void *) &Info, NULL); AcpiOsPrintf ("Executed %d predefined names in the namespace\n", Info.Count); } @@ -1161,15 +1161,13 @@ AcpiDbSetMethodData ( /* Create and initialize the new object */ - ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + ObjDesc = AcpiUtCreateIntegerObject ((UINT64) Value); if (!ObjDesc) { AcpiOsPrintf ("Could not create an internal object\n"); return; } - ObjDesc->Integer.Value = Value; - /* Store the new object into the target */ switch (Type) @@ -1321,7 +1319,7 @@ AcpiDbDisplayObjects ( /* Walk the namespace from the root */ (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - AcpiDbWalkForSpecificObjects, (void *) &Info, NULL); + AcpiDbWalkForSpecificObjects, NULL, (void *) &Info, NULL); AcpiOsPrintf ( "\nFound %u objects of type [%s] in the current ACPI Namespace\n", @@ -1437,7 +1435,7 @@ AcpiDbFindNameInNamespace ( /* Walk the namespace from the root */ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - AcpiDbWalkAndMatchName, AcpiName, NULL); + AcpiDbWalkAndMatchName, NULL, AcpiName, NULL); AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); return (AE_OK); @@ -1938,7 +1936,7 @@ AcpiDbCheckIntegrity ( /* Search all nodes in namespace */ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - AcpiDbIntegrityWalk, (void *) &Info, NULL); + AcpiDbIntegrityWalk, NULL, (void *) &Info, NULL); AcpiOsPrintf ("Verified %d namespace nodes with %d Objects\n", Info.Nodes, Info.Objects); @@ -2125,7 +2123,7 @@ AcpiDbGetBusInfo ( /* Search all nodes in namespace */ (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, - AcpiDbBusWalk, NULL, NULL); + AcpiDbBusWalk, NULL, NULL, NULL); } #endif /* ACPI_DEBUGGER */ diff --git a/debugger/dbexec.c b/debugger/dbexec.c index f6e20ce55c79..7990890fc056 100644 --- a/debugger/dbexec.c +++ b/debugger/dbexec.c @@ -453,7 +453,7 @@ AcpiDbExecute ( if (*Name == '*') { (void) AcpiWalkNamespace (ACPI_TYPE_METHOD, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, AcpiDbExecutionWalk, NULL, NULL); + ACPI_UINT32_MAX, AcpiDbExecutionWalk, NULL, NULL, NULL); return; } else diff --git a/debugger/dbstats.c b/debugger/dbstats.c index f2f2f78f6a69..63a62ecbef8b 100644 --- a/debugger/dbstats.c +++ b/debugger/dbstats.c @@ -446,7 +446,7 @@ AcpiDbCountNamespaceObjects ( } (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, FALSE, AcpiDbClassifyOneObject, NULL, NULL); + ACPI_UINT32_MAX, FALSE, AcpiDbClassifyOneObject, NULL, NULL, NULL); } diff --git a/dispatcher/dsinit.c b/dispatcher/dsinit.c index af29476410ff..efea20e83d35 100644 --- a/dispatcher/dsinit.c +++ b/dispatcher/dsinit.c @@ -283,7 +283,7 @@ AcpiDsInitializeObjects ( * the namespace reader lock. */ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, StartNode, ACPI_UINT32_MAX, - ACPI_NS_WALK_UNLOCK, AcpiDsInitOneObject, &Info, NULL); + ACPI_NS_WALK_UNLOCK, AcpiDsInitOneObject, NULL, &Info, NULL); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "During WalkNamespace")); diff --git a/dispatcher/dsmthdat.c b/dispatcher/dsmthdat.c index 43777ab80f08..551e8480a984 100644 --- a/dispatcher/dsmthdat.c +++ b/dispatcher/dsmthdat.c @@ -524,13 +524,12 @@ AcpiDsMethodDataGetValue ( if (AcpiGbl_EnableInterpreterSlack) { - Object = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + Object = AcpiUtCreateIntegerObject ((UINT64) 0); if (!Object) { return_ACPI_STATUS (AE_NO_MEMORY); } - Object->Integer.Value = 0; Node->Object = Object; } diff --git a/dispatcher/dsobject.c b/dispatcher/dsobject.c index 57e78c1b3394..cf444a1df2bc 100644 --- a/dispatcher/dsobject.c +++ b/dispatcher/dsobject.c @@ -574,7 +574,7 @@ AcpiDsBuildInternalPackageObj ( * * Note: technically, this is an error, from ACPI spec: "It is an error * for NumElements to be less than the number of elements in the - * PackageList". However, we just print an error message and + * PackageList". However, we just print a message and * no exception is returned. This provides Windows compatibility. Some * BIOSs will alter the NumElements on the fly, creating this type * of ill-formed package object. @@ -598,8 +598,8 @@ AcpiDsBuildInternalPackageObj ( Arg = Arg->Common.Next; } - ACPI_ERROR ((AE_INFO, - "Package List length (0x%X) larger than NumElements count (0x%X), truncated\n", + ACPI_INFO ((AE_INFO, + "Actual Package length (0x%X) is larger than NumElements field (0x%X), truncated\n", i, ElementCount)); } else if (i < ElementCount) diff --git a/events/evgpeblk.c b/events/evgpeblk.c index 343a31d28efd..c86f80aa7f54 100644 --- a/events/evgpeblk.c +++ b/events/evgpeblk.c @@ -1110,7 +1110,7 @@ AcpiEvCreateGpeBlock ( Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD, GpeDevice, ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, - AcpiEvSaveMethodInfo, GpeBlock, NULL); + AcpiEvSaveMethodInfo, NULL, GpeBlock, NULL); /* Return the new block */ @@ -1192,7 +1192,7 @@ AcpiEvInitializeGpeBlock ( Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, - AcpiEvMatchPrwAndGpe, &GpeInfo, NULL); + AcpiEvMatchPrwAndGpe, NULL, &GpeInfo, NULL); } /* diff --git a/events/evregion.c b/events/evregion.c index 4cfbc0c224eb..50edaa49a399 100644 --- a/events/evregion.c +++ b/events/evregion.c @@ -400,25 +400,21 @@ AcpiEvExecuteRegMethod ( * connection status 1 for connecting the handler, 0 for disconnecting * the handler (Passed as a parameter) */ - Args[0] = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + Args[0] = AcpiUtCreateIntegerObject ((UINT64) RegionObj->Region.SpaceId); if (!Args[0]) { Status = AE_NO_MEMORY; goto Cleanup1; } - Args[1] = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + Args[1] = AcpiUtCreateIntegerObject ((UINT64) Function); if (!Args[1]) { Status = AE_NO_MEMORY; goto Cleanup2; } - /* Setup the parameter objects */ - - Args[0]->Integer.Value = RegionObj->Region.SpaceId; - Args[1]->Integer.Value = Function; - Args[2] = NULL; + Args[2] = NULL; /* Terminate list */ /* Execute the method, no return value */ @@ -1173,7 +1169,7 @@ AcpiEvInstallSpaceHandler ( * of the branch */ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX, - ACPI_NS_WALK_UNLOCK, AcpiEvInstallHandler, + ACPI_NS_WALK_UNLOCK, AcpiEvInstallHandler, NULL, HandlerObj, NULL); UnlockAndExit: @@ -1213,7 +1209,7 @@ AcpiEvExecuteRegMethods ( * regions of this Space ID before we can run any _REG methods) */ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX, - ACPI_NS_WALK_UNLOCK, AcpiEvRegRun, + ACPI_NS_WALK_UNLOCK, AcpiEvRegRun, NULL, &SpaceId, NULL); return_ACPI_STATUS (Status); diff --git a/executer/exconfig.c b/executer/exconfig.c index 8c08165251a1..d0acdd5f8030 100644 --- a/executer/exconfig.c +++ b/executer/exconfig.c @@ -263,15 +263,13 @@ AcpiExLoadTableOp ( /* Table not found, return an Integer=0 and AE_OK */ - DdbHandle = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + DdbHandle = AcpiUtCreateIntegerObject ((UINT64) 0); if (!DdbHandle) { return_ACPI_STATUS (AE_NO_MEMORY); } - DdbHandle->Integer.Value = 0; *ReturnDesc = DdbHandle; - return_ACPI_STATUS (AE_OK); } diff --git a/executer/exconvrt.c b/executer/exconvrt.c index e7d853032989..fd8fec1c711e 100644 --- a/executer/exconvrt.c +++ b/executer/exconvrt.c @@ -260,7 +260,7 @@ AcpiExConvertToInteger ( /* Create a new integer */ - ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + ReturnDesc = AcpiUtCreateIntegerObject (Result); if (!ReturnDesc) { return_ACPI_STATUS (AE_NO_MEMORY); @@ -271,7 +271,6 @@ AcpiExConvertToInteger ( /* Save the Result */ - ReturnDesc->Integer.Value = Result; AcpiExTruncateFor32bitTable (ReturnDesc); *ResultDesc = ReturnDesc; return_ACPI_STATUS (AE_OK); diff --git a/executer/exfield.c b/executer/exfield.c index 0ee522c572a4..503e8e6b370b 100644 --- a/executer/exfield.c +++ b/executer/exfield.c @@ -249,14 +249,13 @@ AcpiExReadDataFromField ( { /* Field will fit within an Integer (normal case) */ - BufferDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + BufferDesc = AcpiUtCreateIntegerObject ((UINT64) 0); if (!BufferDesc) { return_ACPI_STATUS (AE_NO_MEMORY); } Length = AcpiGbl_IntegerByteWidth; - BufferDesc->Integer.Value = 0; Buffer = &BufferDesc->Integer.Value; } diff --git a/executer/exoparg1.c b/executer/exoparg1.c index 70085693ba49..4a90b9c9506d 100644 --- a/executer/exoparg1.c +++ b/executer/exoparg1.c @@ -183,13 +183,12 @@ AcpiExOpcode_0A_0T_1R ( /* Create a return object of type Integer */ - ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + ReturnDesc = AcpiUtCreateIntegerObject (AcpiOsGetTimer ()); if (!ReturnDesc) { Status = AE_NO_MEMORY; goto Cleanup; } - ReturnDesc->Integer.Value = AcpiOsGetTimer (); break; default: /* Unknown opcode */ @@ -733,7 +732,7 @@ AcpiExOpcode_1A_0T_1R ( { case AML_LNOT_OP: /* LNot (Operand) */ - ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + ReturnDesc = AcpiUtCreateIntegerObject ((UINT64) 0); if (!ReturnDesc) { Status = AE_NO_MEMORY; @@ -838,14 +837,12 @@ AcpiExOpcode_1A_0T_1R ( /* Allocate a descriptor to hold the type. */ - ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + ReturnDesc = AcpiUtCreateIntegerObject ((UINT64) Type); if (!ReturnDesc) { Status = AE_NO_MEMORY; goto Cleanup; } - - ReturnDesc->Integer.Value = Type; break; @@ -917,14 +914,12 @@ AcpiExOpcode_1A_0T_1R ( * Now that we have the size of the object, create a result * object to hold the value */ - ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + ReturnDesc = AcpiUtCreateIntegerObject (Value); if (!ReturnDesc) { Status = AE_NO_MEMORY; goto Cleanup; } - - ReturnDesc->Integer.Value = Value; break; @@ -1089,21 +1084,18 @@ AcpiExOpcode_1A_0T_1R ( * NOTE: index into a buffer is NOT a pointer to a * sub-buffer of the main buffer, it is only a pointer to a * single element (byte) of the buffer! + * + * Since we are returning the value of the buffer at the + * indexed location, we don't need to add an additional + * reference to the buffer itself. */ - ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + ReturnDesc = AcpiUtCreateIntegerObject ((UINT64) + TempDesc->Buffer.Pointer[Operand[0]->Reference.Value]); if (!ReturnDesc) { Status = AE_NO_MEMORY; goto Cleanup; } - - /* - * Since we are returning the value of the buffer at the - * indexed location, we don't need to add an additional - * reference to the buffer itself. - */ - ReturnDesc->Integer.Value = - TempDesc->Buffer.Pointer[Operand[0]->Reference.Value]; break; diff --git a/executer/exoparg6.c b/executer/exoparg6.c index 96c16a33bd08..c2609471dd7c 100644 --- a/executer/exoparg6.c +++ b/executer/exoparg6.c @@ -344,8 +344,9 @@ AcpiExOpcode_6A_0T_1R ( } /* Create an integer for the return value */ + /* Default return value is ACPI_INTEGER_MAX if no match found */ - ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + ReturnDesc = AcpiUtCreateIntegerObject (ACPI_INTEGER_MAX); if (!ReturnDesc) { Status = AE_NO_MEMORY; @@ -353,10 +354,6 @@ AcpiExOpcode_6A_0T_1R ( } - /* Default return value if no match found */ - - ReturnDesc->Integer.Value = ACPI_INTEGER_MAX; - /* * Examine each element until a match is found. Both match conditions * must be satisfied for a match to occur. Within the loop, diff --git a/executer/exregion.c b/executer/exregion.c index 958dc4e06705..5a37be25950e 100644 --- a/executer/exregion.c +++ b/executer/exregion.c @@ -157,7 +157,8 @@ AcpiExSystemMemorySpaceHandler ( void *LogicalAddrPtr = NULL; ACPI_MEM_SPACE_CONTEXT *MemInfo = RegionContext; UINT32 Length; - ACPI_SIZE WindowSize; + ACPI_SIZE MapLength; + ACPI_SIZE PageBoundaryMapLength; #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED UINT32 Remainder; #endif @@ -227,26 +228,45 @@ AcpiExSystemMemorySpaceHandler ( } /* - * Don't attempt to map memory beyond the end of the region, and - * constrain the maximum mapping size to something reasonable. + * October 2009: Attempt to map from the requested address to the + * end of the region. However, we will never map more than one + * page, nor will we cross a page boundary. */ - WindowSize = (ACPI_SIZE) + MapLength = (ACPI_SIZE) ((MemInfo->Address + MemInfo->Length) - Address); - if (WindowSize > ACPI_SYSMEM_REGION_WINDOW_SIZE) + /* + * If mapping the entire remaining portion of the region will cross + * a page boundary, just map up to the page boundary, do not cross. + * On some systems, crossing a page boundary while mapping regions + * can cause warnings if the pages have different attributes + * due to resource management. + * + * This has the added benefit of constraining a single mapping to + * one page, which is similar to the original code that used a 4k + * maximum window. + */ + PageBoundaryMapLength = + ACPI_ROUND_UP (Address, ACPI_DEFAULT_PAGE_SIZE) - Address; + if (PageBoundaryMapLength == 0) + { + PageBoundaryMapLength = ACPI_DEFAULT_PAGE_SIZE; + } + + if (MapLength > PageBoundaryMapLength) { - WindowSize = ACPI_SYSMEM_REGION_WINDOW_SIZE; + MapLength = PageBoundaryMapLength; } /* Create a new mapping starting at the address given */ MemInfo->MappedLogicalAddress = AcpiOsMapMemory ( - (ACPI_PHYSICAL_ADDRESS) Address, WindowSize); + (ACPI_PHYSICAL_ADDRESS) Address, MapLength); if (!MemInfo->MappedLogicalAddress) { ACPI_ERROR ((AE_INFO, "Could not map memory at %8.8X%8.8X, size %X", - ACPI_FORMAT_NATIVE_UINT (Address), (UINT32) WindowSize)); + ACPI_FORMAT_NATIVE_UINT (Address), (UINT32) MapLength)); MemInfo->MappedLength = 0; return_ACPI_STATUS (AE_NO_MEMORY); } @@ -254,7 +274,7 @@ AcpiExSystemMemorySpaceHandler ( /* Save the physical address and mapping size */ MemInfo->MappedPhysicalAddress = Address; - MemInfo->MappedLength = WindowSize; + MemInfo->MappedLength = MapLength; } /* diff --git a/include/acconfig.h b/include/acconfig.h index 1fcc45a364a8..8fbe0e371b26 100644 --- a/include/acconfig.h +++ b/include/acconfig.h @@ -177,9 +177,9 @@ #define ACPI_MAX_REFERENCE_COUNT 0x800 -/* Size of cached memory mapping for system memory operation region */ +/* Default page size for use in mapping memory for operation regions */ -#define ACPI_SYSMEM_REGION_WINDOW_SIZE 4096 +#define ACPI_DEFAULT_PAGE_SIZE 4096 /* Must be power of 2 */ /* OwnerId tracking. 8 entries allows for 255 OwnerIds */ diff --git a/include/acmacros.h b/include/acmacros.h index 28c934deb996..3d351f9fc85e 100644 --- a/include/acmacros.h +++ b/include/acmacros.h @@ -403,6 +403,7 @@ #define ACPI_ERROR_NAMESPACE(s, e) AcpiNsReportError (AE_INFO, s, e); #define ACPI_ERROR_METHOD(s, n, p, e) AcpiNsReportMethodError (AE_INFO, s, n, p, e); #define ACPI_WARN_PREDEFINED(plist) AcpiUtPredefinedWarning plist +#define ACPI_INFO_PREDEFINED(plist) AcpiUtPredefinedInfo plist #else @@ -411,6 +412,7 @@ #define ACPI_ERROR_NAMESPACE(s, e) #define ACPI_ERROR_METHOD(s, n, p, e) #define ACPI_WARN_PREDEFINED(plist) +#define ACPI_INFO_PREDEFINED(plist) #endif /* ACPI_NO_ERROR_MESSAGES */ diff --git a/include/acnamesp.h b/include/acnamesp.h index ce0ba2aa08f1..5ea23da0d28b 100644 --- a/include/acnamesp.h +++ b/include/acnamesp.h @@ -189,7 +189,8 @@ AcpiNsWalkNamespace ( ACPI_HANDLE StartObject, UINT32 MaxDepth, UINT32 Flags, - ACPI_WALK_CALLBACK UserFunction, + ACPI_WALK_CALLBACK PreOrderVisit, + ACPI_WALK_CALLBACK PostOrderVisit, void *Context, void **ReturnValue); @@ -428,7 +429,8 @@ AcpiNsGetAttachedData ( /* - * nsrepair - return object repair for predefined methods/objects + * nsrepair - General return object repair for all + * predefined methods/objects */ ACPI_STATUS AcpiNsRepairObject ( @@ -444,6 +446,18 @@ AcpiNsRepairPackageList ( /* + * nsrepair2 - Return object repair for specific + * predefined methods/objects + */ +ACPI_STATUS +AcpiNsComplexRepairs ( + ACPI_PREDEFINED_DATA *Data, + ACPI_NAMESPACE_NODE *Node, + ACPI_STATUS ValidateStatus, + ACPI_OPERAND_OBJECT **ReturnObjectPtr); + + +/* * nssearch - Namespace searching and entry */ ACPI_STATUS diff --git a/include/acpixf.h b/include/acpixf.h index 88135a783bc5..17c5bd3d061b 100644 --- a/include/acpixf.h +++ b/include/acpixf.h @@ -120,7 +120,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20091013 +#define ACPI_CA_VERSION 0x20091112 #include "actypes.h" #include "actbl.h" @@ -267,7 +267,8 @@ AcpiWalkNamespace ( ACPI_OBJECT_TYPE Type, ACPI_HANDLE StartObject, UINT32 MaxDepth, - ACPI_WALK_CALLBACK UserFunction, + ACPI_WALK_CALLBACK PreOrderVisit, + ACPI_WALK_CALLBACK PostOrderVisit, void *Context, void **ReturnValue); diff --git a/include/acutils.h b/include/acutils.h index 33d33c2f4787..3e12b7ca3617 100644 --- a/include/acutils.h +++ b/include/acutils.h @@ -644,6 +644,10 @@ AcpiUtCreatePackageObject ( UINT32 Count); ACPI_OPERAND_OBJECT * +AcpiUtCreateIntegerObject ( + UINT64 Value); + +ACPI_OPERAND_OBJECT * AcpiUtCreateBufferObject ( ACPI_SIZE BufferSize); @@ -795,6 +799,15 @@ AcpiUtPredefinedWarning ( const char *Format, ...); +void ACPI_INTERNAL_VAR_XFACE +AcpiUtPredefinedInfo ( + const char *ModuleName, + UINT32 LineNumber, + char *Pathname, + UINT8 NodeFlags, + const char *Format, + ...); + /* Values for Base above (16=Hex, 10=Decimal) */ #define ACPI_ANY_BASE 0 diff --git a/namespace/nsdump.c b/namespace/nsdump.c index 762437aa1286..96510564ee4a 100644 --- a/namespace/nsdump.c +++ b/namespace/nsdump.c @@ -736,7 +736,7 @@ AcpiNsDumpObjects ( (void) AcpiNsWalkNamespace (Type, StartHandle, MaxDepth, ACPI_NS_WALK_NO_UNLOCK | ACPI_NS_WALK_TEMP_NODES, - AcpiNsDumpOneObject, (void *) &Info, NULL); + AcpiNsDumpOneObject, NULL, (void *) &Info, NULL); } diff --git a/namespace/nsdumpdv.c b/namespace/nsdumpdv.c index a2456b24291c..fbb66a616759 100644 --- a/namespace/nsdumpdv.c +++ b/namespace/nsdumpdv.c @@ -225,7 +225,7 @@ AcpiNsDumpRootDevices ( Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, SysBusHandle, ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, - AcpiNsDumpOneDevice, NULL, NULL); + AcpiNsDumpOneDevice, NULL, NULL, NULL); } #endif diff --git a/namespace/nseval.c b/namespace/nseval.c index c84a4d58ce6f..e5d4cf327e53 100644 --- a/namespace/nseval.c +++ b/namespace/nseval.c @@ -460,36 +460,53 @@ AcpiNsExecModuleCode ( ACPI_OPERAND_OBJECT *MethodObj, ACPI_EVALUATE_INFO *Info) { - ACPI_OPERAND_OBJECT *RootObj; + ACPI_OPERAND_OBJECT *ParentObj; + ACPI_NAMESPACE_NODE *ParentNode; + ACPI_OBJECT_TYPE Type; ACPI_STATUS Status; ACPI_FUNCTION_TRACE (NsExecModuleCode); + /* + * Get the parent node. We cheat by using the NextObject field + * of the method object descriptor. + */ + ParentNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, + MethodObj->Method.NextObject); + Type = AcpiNsGetType (ParentNode); + + /* Must clear NextObject (AcpiNsAttachObject needs the field) */ + + MethodObj->Method.NextObject = NULL; + /* Initialize the evaluation information block */ ACPI_MEMSET (Info, 0, sizeof (ACPI_EVALUATE_INFO)); - Info->PrefixNode = AcpiGbl_RootNode; + Info->PrefixNode = ParentNode; /* - * Get the currently attached root object. Add a reference, because the + * Get the currently attached parent object. Add a reference, because the * ref count will be decreased when the method object is installed to - * the root node. + * the parent node. */ - RootObj = AcpiNsGetAttachedObject (AcpiGbl_RootNode); - AcpiUtAddReference (RootObj); + ParentObj = AcpiNsGetAttachedObject (ParentNode); + if (ParentObj) + { + AcpiUtAddReference (ParentObj); + } - /* Install the method (module-level code) in the root node */ + /* Install the method (module-level code) in the parent node */ - Status = AcpiNsAttachObject (AcpiGbl_RootNode, MethodObj, + Status = AcpiNsAttachObject (ParentNode, MethodObj, ACPI_TYPE_METHOD); if (ACPI_FAILURE (Status)) { goto Exit; } - /* Execute the root node as a control method */ + /* Execute the parent node as a control method */ Status = AcpiNsEvaluate (Info); @@ -498,14 +515,24 @@ AcpiNsExecModuleCode ( /* Detach the temporary method object */ - AcpiNsDetachObject (AcpiGbl_RootNode); + AcpiNsDetachObject (ParentNode); - /* Restore the original root object */ + /* Restore the original parent object */ - Status = AcpiNsAttachObject (AcpiGbl_RootNode, RootObj, ACPI_TYPE_DEVICE); + if (ParentObj) + { + Status = AcpiNsAttachObject (ParentNode, ParentObj, Type); + } + else + { + ParentNode->Type = (UINT8) Type; + } Exit: - AcpiUtRemoveReference (RootObj); + if (ParentObj) + { + AcpiUtRemoveReference (ParentObj); + } return_VOID; } diff --git a/namespace/nsinit.c b/namespace/nsinit.c index fcea63e7acc9..b36fa6c7ea96 100644 --- a/namespace/nsinit.c +++ b/namespace/nsinit.c @@ -185,7 +185,7 @@ AcpiNsInitializeObjects ( /* Walk entire namespace from the supplied root */ Status = AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, AcpiNsInitOneObject, + ACPI_UINT32_MAX, AcpiNsInitOneObject, NULL, &Info, NULL); if (ACPI_FAILURE (Status)) { @@ -249,7 +249,7 @@ AcpiNsInitializeDevices ( /* Tree analysis: find all subtrees that contain _INI methods */ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, FALSE, AcpiNsFindIniMethods, &Info, NULL); + ACPI_UINT32_MAX, FALSE, AcpiNsFindIniMethods, NULL, &Info, NULL); if (ACPI_FAILURE (Status)) { goto ErrorExit; @@ -283,7 +283,7 @@ AcpiNsInitializeDevices ( /* Walk namespace to execute all _INIs on present devices */ Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, FALSE, AcpiNsInitOneDevice, &Info, NULL); + ACPI_UINT32_MAX, FALSE, AcpiNsInitOneDevice, NULL, &Info, NULL); ACPI_FREE (Info.EvaluateInfo); if (ACPI_FAILURE (Status)) diff --git a/namespace/nspredef.c b/namespace/nspredef.c index 93bcbdef28d1..ae4e17d43826 100644 --- a/namespace/nspredef.c +++ b/namespace/nspredef.c @@ -330,6 +330,12 @@ AcpiNsCheckPredefinedNames ( Status = AcpiNsCheckPackage (Data, ReturnObjectPtr); } + /* + * Perform additional, more complicated repairs on a per-name + * basis. + */ + Status = AcpiNsComplexRepairs (Data, Node, Status, ReturnObjectPtr); + CheckValidationStatus: /* @@ -719,7 +725,7 @@ AcpiNsCheckPackage ( * there is only one entry). We may be able to repair this by * wrapping the returned Package with a new outer Package. */ - if ((*Elements)->Common.Type != ACPI_TYPE_PACKAGE) + if (*Elements && ((*Elements)->Common.Type != ACPI_TYPE_PACKAGE)) { /* Create the new outer package and populate it */ @@ -794,6 +800,7 @@ AcpiNsCheckPackageList ( ACPI_OPERAND_OBJECT *SubPackage; ACPI_OPERAND_OBJECT **SubElements; ACPI_STATUS Status; + BOOLEAN NonTrailingNull = FALSE; UINT32 ExpectedCount; UINT32 i; UINT32 j; @@ -803,6 +810,46 @@ AcpiNsCheckPackageList ( for (i = 0; i < Count; i++) { + /* + * Handling for NULL package elements. For now, we will simply allow + * a parent package with trailing NULL elements. This can happen if + * the package was defined to be longer than the initializer list. + * This is legal as per the ACPI specification. It is often used + * to allow for dynamic initialization of a Package. + * + * A future enhancement may be to simply truncate the package to + * remove the trailing NULL elements. + */ + if (!(*Elements)) + { + if (!NonTrailingNull) + { + /* Ensure the remaining elements are all NULL */ + + for (j = 1; j < (Count - i + 1); j++) + { + if (Elements[j]) + { + NonTrailingNull = TRUE; + } + } + + if (!NonTrailingNull) + { + /* Ignore the trailing NULL elements */ + + return (AE_OK); + } + } + + /* There are trailing non-null elements, issue warning */ + + ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, + "Found NULL element at package index %u", i)); + Elements++; + continue; + } + SubPackage = *Elements; SubElements = SubPackage->Package.Elements; diff --git a/namespace/nsrepair.c b/namespace/nsrepair.c index 695a93f5ead5..3e3a23125d91 100644 --- a/namespace/nsrepair.c +++ b/namespace/nsrepair.c @@ -276,14 +276,14 @@ AcpiNsRepairObject ( ReturnObject->Common.ReferenceCount--; } - ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, + ACPI_INFO_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, "Converted %s to expected %s at index %u", AcpiUtGetObjectTypeName (ReturnObject), AcpiUtGetObjectTypeName (NewObject), PackageIndex)); } else { - ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, + ACPI_INFO_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, "Converted %s to expected %s", AcpiUtGetObjectTypeName (ReturnObject), AcpiUtGetObjectTypeName (NewObject))); @@ -347,8 +347,8 @@ AcpiNsRepairPackageList ( *ObjDescPtr = PkgObjDesc; Data->Flags |= ACPI_OBJECT_REPAIRED; - ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, - "Incorrectly formed Package, attempting repair")); + ACPI_INFO_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, + "Repaired Incorrectly formed Package")); return (AE_OK); } diff --git a/namespace/nsrepair2.c b/namespace/nsrepair2.c new file mode 100644 index 000000000000..d248906182b8 --- /dev/null +++ b/namespace/nsrepair2.c @@ -0,0 +1,669 @@ +/****************************************************************************** + * + * Module Name: nsrepair2 - Repair for objects returned by specific + * predefined methods + * + *****************************************************************************/ + +/****************************************************************************** + * + * 1. Copyright Notice + * + * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. + * All rights reserved. + * + * 2. License + * + * 2.1. This is your license from Intel Corp. under its intellectual property + * rights. You may have additional license terms from the party that provided + * you this software, covering your right to use that party's intellectual + * property rights. + * + * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a + * copy of the source code appearing in this file ("Covered Code") an + * irrevocable, perpetual, worldwide license under Intel's copyrights in the + * base code distributed originally by Intel ("Original Intel Code") to copy, + * make derivatives, distribute, use and display any portion of the Covered + * Code in any form, with the right to sublicense such rights; and + * + * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent + * license (with the right to sublicense), under only those claims of Intel + * patents that are infringed by the Original Intel Code, to make, use, sell, + * offer to sell, and import the Covered Code and derivative works thereof + * solely to the minimum extent necessary to exercise the above copyright + * license, and in no event shall the patent license extend to any additions + * to or modifications of the Original Intel Code. No other license or right + * is granted directly or by implication, estoppel or otherwise; + * + * The above copyright and patent license is granted only if the following + * conditions are met: + * + * 3. Conditions + * + * 3.1. Redistribution of Source with Rights to Further Distribute Source. + * Redistribution of source code of any substantial portion of the Covered + * Code or modification with rights to further distribute source must include + * the above Copyright Notice, the above License, this list of Conditions, + * and the following Disclaimer and Export Compliance provision. In addition, + * Licensee must cause all Covered Code to which Licensee contributes to + * contain a file documenting the changes Licensee made to create that Covered + * Code and the date of any change. Licensee must include in that file the + * documentation of any changes made by any predecessor Licensee. Licensee + * must include a prominent statement that the modification is derived, + * directly or indirectly, from Original Intel Code. + * + * 3.2. Redistribution of Source with no Rights to Further Distribute Source. + * Redistribution of source code of any substantial portion of the Covered + * Code or modification without rights to further distribute source must + * include the following Disclaimer and Export Compliance provision in the + * documentation and/or other materials provided with distribution. In + * addition, Licensee may not authorize further sublicense of source of any + * portion of the Covered Code, and must include terms to the effect that the + * license from Licensee to its licensee is limited to the intellectual + * property embodied in the software Licensee provides to its licensee, and + * not to intellectual property embodied in modifications its licensee may + * make. + * + * 3.3. Redistribution of Executable. Redistribution in executable form of any + * substantial portion of the Covered Code or modification must reproduce the + * above Copyright Notice, and the following Disclaimer and Export Compliance + * provision in the documentation and/or other materials provided with the + * distribution. + * + * 3.4. Intel retains all right, title, and interest in and to the Original + * Intel Code. + * + * 3.5. Neither the name Intel nor any other trademark owned or controlled by + * Intel shall be used in advertising or otherwise to promote the sale, use or + * other dealings in products derived from or relating to the Covered Code + * without prior written authorization from Intel. + * + * 4. Disclaimer and Export Compliance + * + * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED + * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE + * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, + * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY + * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY + * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A + * PARTICULAR PURPOSE. + * + * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES + * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR + * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, + * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY + * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL + * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS + * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY + * LIMITED REMEDY. + * + * 4.3. Licensee shall not export, either directly or indirectly, any of this + * software or system incorporating such software without first obtaining any + * required license or other approval from the U. S. Department of Commerce or + * any other agency or department of the United States Government. In the + * event Licensee exports any such software from the United States or + * re-exports any such software from a foreign destination, Licensee shall + * ensure that the distribution and export/re-export of the software is in + * compliance with all laws, regulations, orders, or other restrictions of the + * U.S. Export Administration Regulations. Licensee agrees that neither it nor + * any of its subsidiaries will export/re-export any technical data, process, + * software, or service, directly or indirectly, to any country for which the + * United States government or any agency thereof requires an export license, + * other governmental approval, or letter of assurance, without first obtaining + * such license, approval or letter. + * + *****************************************************************************/ + +#define __NSREPAIR2_C__ + +#include "acpi.h" +#include "accommon.h" +#include "acnamesp.h" + +#define _COMPONENT ACPI_NAMESPACE + ACPI_MODULE_NAME ("nsrepair2") + + +/* + * Information structure and handler for ACPI predefined names that can + * be repaired on a per-name basis. + */ +typedef +ACPI_STATUS (*ACPI_REPAIR_FUNCTION) ( + ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT **ReturnObjectPtr); + +typedef struct acpi_repair_info +{ + char Name[ACPI_NAME_SIZE]; + ACPI_REPAIR_FUNCTION RepairFunction; + +} ACPI_REPAIR_INFO; + + +/* Local prototypes */ + +static const ACPI_REPAIR_INFO * +AcpiNsMatchRepairableName ( + ACPI_NAMESPACE_NODE *Node); + +static ACPI_STATUS +AcpiNsRepair_ALR ( + ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT **ReturnObjectPtr); + +static ACPI_STATUS +AcpiNsRepair_PSS ( + ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT **ReturnObjectPtr); + +static ACPI_STATUS +AcpiNsRepair_TSS ( + ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT **ReturnObjectPtr); + +static ACPI_STATUS +AcpiNsCheckSortedList ( + ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT *ReturnObject, + UINT32 ExpectedCount, + UINT32 SortIndex, + UINT8 SortDirection, + char *SortKeyName); + +static ACPI_STATUS +AcpiNsRemoveNullElements ( + ACPI_OPERAND_OBJECT *Package); + +static ACPI_STATUS +AcpiNsSortList ( + ACPI_OPERAND_OBJECT **Elements, + UINT32 Count, + UINT32 Index, + UINT8 SortDirection); + +/* Values for SortDirection above */ + +#define ACPI_SORT_ASCENDING 0 +#define ACPI_SORT_DESCENDING 1 + + +/* + * This table contains the names of the predefined methods for which we can + * perform more complex repairs. + * + * _ALR: Sort the list ascending by AmbientIlluminance if necessary + * _PSS: Sort the list descending by Power if necessary + * _TSS: Sort the list descending by Power if necessary + */ +static const ACPI_REPAIR_INFO AcpiNsRepairableNames[] = +{ + {"_ALR", AcpiNsRepair_ALR}, + {"_PSS", AcpiNsRepair_PSS}, + {"_TSS", AcpiNsRepair_TSS}, + {{0,0,0,0}, NULL} /* Table terminator */ +}; + + +/****************************************************************************** + * + * FUNCTION: AcpiNsComplexRepairs + * + * PARAMETERS: Data - Pointer to validation data structure + * Node - Namespace node for the method/object + * ValidateStatus - Original status of earlier validation + * ReturnObjectPtr - Pointer to the object returned from the + * evaluation of a method or object + * + * RETURN: Status. AE_OK if repair was successful. If name is not + * matched, ValidateStatus is returned. + * + * DESCRIPTION: Attempt to repair/convert a return object of a type that was + * not expected. + * + *****************************************************************************/ + +ACPI_STATUS +AcpiNsComplexRepairs ( + ACPI_PREDEFINED_DATA *Data, + ACPI_NAMESPACE_NODE *Node, + ACPI_STATUS ValidateStatus, + ACPI_OPERAND_OBJECT **ReturnObjectPtr) +{ + const ACPI_REPAIR_INFO *Predefined; + ACPI_STATUS Status; + + + /* Check if this name is in the list of repairable names */ + + Predefined = AcpiNsMatchRepairableName (Node); + if (!Predefined) + { + return (ValidateStatus); + } + + Status = Predefined->RepairFunction (Data, ReturnObjectPtr); + return (Status); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiNsMatchRepairableName + * + * PARAMETERS: Node - Namespace node for the method/object + * + * RETURN: Pointer to entry in repair table. NULL indicates not found. + * + * DESCRIPTION: Check an object name against the repairable object list. + * + *****************************************************************************/ + +static const ACPI_REPAIR_INFO * +AcpiNsMatchRepairableName ( + ACPI_NAMESPACE_NODE *Node) +{ + const ACPI_REPAIR_INFO *ThisName; + + + /* Search info table for a repairable predefined method/object name */ + + ThisName = AcpiNsRepairableNames; + while (ThisName->RepairFunction) + { + if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Name)) + { + return (ThisName); + } + ThisName++; + } + + return (NULL); /* Not found */ +} + + +/****************************************************************************** + * + * FUNCTION: AcpiNsRepair_ALR + * + * PARAMETERS: Data - Pointer to validation data structure + * ReturnObjectPtr - Pointer to the object returned from the + * evaluation of a method or object + * + * RETURN: Status. AE_OK if object is OK or was repaired successfully + * + * DESCRIPTION: Repair for the _ALR object. If necessary, sort the object list + * ascending by the ambient illuminance values. + * + *****************************************************************************/ + +static ACPI_STATUS +AcpiNsRepair_ALR ( + ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT **ReturnObjectPtr) +{ + ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; + ACPI_STATUS Status; + + + Status = AcpiNsCheckSortedList (Data, ReturnObject, 2, 1, + ACPI_SORT_ASCENDING, "AmbientIlluminance"); + + return (Status); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiNsRepair_TSS + * + * PARAMETERS: Data - Pointer to validation data structure + * ReturnObjectPtr - Pointer to the object returned from the + * evaluation of a method or object + * + * RETURN: Status. AE_OK if object is OK or was repaired successfully + * + * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list + * descending by the power dissipation values. + * + *****************************************************************************/ + +static ACPI_STATUS +AcpiNsRepair_TSS ( + ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT **ReturnObjectPtr) +{ + ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; + ACPI_STATUS Status; + + + Status = AcpiNsCheckSortedList (Data, ReturnObject, 5, 1, + ACPI_SORT_DESCENDING, "PowerDissipation"); + + return (Status); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiNsRepair_PSS + * + * PARAMETERS: Data - Pointer to validation data structure + * ReturnObjectPtr - Pointer to the object returned from the + * evaluation of a method or object + * + * RETURN: Status. AE_OK if object is OK or was repaired successfully + * + * DESCRIPTION: Repair for the _PSS object. If necessary, sort the object list + * by the CPU frequencies. Check that the power dissipation values + * are all proportional to CPU frequency (i.e., sorting by + * frequency should be the same as sorting by power.) + * + *****************************************************************************/ + +static ACPI_STATUS +AcpiNsRepair_PSS ( + ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT **ReturnObjectPtr) +{ + ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; + ACPI_OPERAND_OBJECT **OuterElements; + UINT32 OuterElementCount; + ACPI_OPERAND_OBJECT **Elements; + ACPI_OPERAND_OBJECT *ObjDesc; + UINT32 PreviousValue; + ACPI_STATUS Status; + UINT32 i; + + + /* + * Entries (sub-packages) in the _PSS Package must be sorted by power + * dissipation, in descending order. If it appears that the list is + * incorrectly sorted, sort it. We sort by CpuFrequency, since this + * should be proportional to the power. + */ + Status =AcpiNsCheckSortedList (Data, ReturnObject, 6, 0, + ACPI_SORT_DESCENDING, "CpuFrequency"); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + /* + * We now know the list is correctly sorted by CPU frequency. Check if + * the power dissipation values are proportional. + */ + PreviousValue = ACPI_UINT32_MAX; + OuterElements = ReturnObject->Package.Elements; + OuterElementCount = ReturnObject->Package.Count; + + for (i = 0; i < OuterElementCount; i++) + { + Elements = (*OuterElements)->Package.Elements; + ObjDesc = Elements[1]; /* Index1 = PowerDissipation */ + + if ((UINT32) ObjDesc->Integer.Value > PreviousValue) + { + ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, + "SubPackage[%u,%u] - suspicious power dissipation values", + i-1, i)); + } + + PreviousValue = (UINT32) ObjDesc->Integer.Value; + OuterElements++; + } + + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiNsCheckSortedList + * + * PARAMETERS: Data - Pointer to validation data structure + * ReturnObject - Pointer to the top-level returned object + * ExpectedCount - Minimum length of each sub-package + * SortIndex - Sub-package entry to sort on + * SortDirection - Ascending or descending + * SortKeyName - Name of the SortIndex field + * + * RETURN: Status. AE_OK if the list is valid and is sorted correctly or + * has been repaired by sorting the list. + * + * DESCRIPTION: Check if the package list is valid and sorted correctly by the + * SortIndex. If not, then sort the list. + * + *****************************************************************************/ + +static ACPI_STATUS +AcpiNsCheckSortedList ( + ACPI_PREDEFINED_DATA *Data, + ACPI_OPERAND_OBJECT *ReturnObject, + UINT32 ExpectedCount, + UINT32 SortIndex, + UINT8 SortDirection, + char *SortKeyName) +{ + UINT32 OuterElementCount; + ACPI_OPERAND_OBJECT **OuterElements; + ACPI_OPERAND_OBJECT **Elements; + ACPI_OPERAND_OBJECT *ObjDesc; + UINT32 i; + UINT32 PreviousValue; + ACPI_STATUS Status; + + + /* The top-level object must be a package */ + + if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE) + { + return (AE_AML_OPERAND_TYPE); + } + + /* + * Detect any NULL package elements and remove them from the + * package. + * + * TBD: We may want to do this for all predefined names that + * return a variable-length package of packages. + */ + Status = AcpiNsRemoveNullElements (ReturnObject); + if (Status == AE_NULL_ENTRY) + { + ACPI_INFO_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, + "NULL elements removed from package")); + + /* Exit if package is now zero length */ + + if (!ReturnObject->Package.Count) + { + return (AE_NULL_ENTRY); + } + } + + OuterElements = ReturnObject->Package.Elements; + OuterElementCount = ReturnObject->Package.Count; + if (!OuterElementCount) + { + return (AE_AML_PACKAGE_LIMIT); + } + + PreviousValue = 0; + if (SortDirection == ACPI_SORT_DESCENDING) + { + PreviousValue = ACPI_UINT32_MAX; + } + + /* Examine each subpackage */ + + for (i = 0; i < OuterElementCount; i++) + { + /* Each element of the top-level package must also be a package */ + + if ((*OuterElements)->Common.Type != ACPI_TYPE_PACKAGE) + { + return (AE_AML_OPERAND_TYPE); + } + + /* Each sub-package must have the minimum length */ + + if ((*OuterElements)->Package.Count < ExpectedCount) + { + return (AE_AML_PACKAGE_LIMIT); + } + + Elements = (*OuterElements)->Package.Elements; + ObjDesc = Elements[SortIndex]; + + if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER) + { + return (AE_AML_OPERAND_TYPE); + } + + /* + * The list must be sorted in the specified order. If we detect a + * discrepancy, issue a warning and sort the entire list + */ + if (((SortDirection == ACPI_SORT_ASCENDING) && + (ObjDesc->Integer.Value < PreviousValue)) || + ((SortDirection == ACPI_SORT_DESCENDING) && + (ObjDesc->Integer.Value > PreviousValue))) + { + Status = AcpiNsSortList (ReturnObject->Package.Elements, + OuterElementCount, SortIndex, SortDirection); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + Data->Flags |= ACPI_OBJECT_REPAIRED; + + ACPI_INFO_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags, + "Repaired unsorted list - now sorted by %s", SortKeyName)); + return (AE_OK); + } + + PreviousValue = (UINT32) ObjDesc->Integer.Value; + OuterElements++; + } + + return (AE_OK); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiNsRemoveNullElements + * + * PARAMETERS: ObjDesc - A Package object + * + * RETURN: Status. AE_NULL_ENTRY means that one or more elements were + * removed. + * + * DESCRIPTION: Remove all NULL package elements and update the package count. + * + *****************************************************************************/ + +static ACPI_STATUS +AcpiNsRemoveNullElements ( + ACPI_OPERAND_OBJECT *ObjDesc) +{ + ACPI_OPERAND_OBJECT **Source; + ACPI_OPERAND_OBJECT **Dest; + ACPI_STATUS Status = AE_OK; + UINT32 Count; + UINT32 NewCount; + UINT32 i; + + + Count = ObjDesc->Package.Count; + NewCount = Count; + + Source = ObjDesc->Package.Elements; + Dest = Source; + + /* Examine all elements of the package object */ + + for (i = 0; i < Count; i++) + { + if (!*Source) + { + Status = AE_NULL_ENTRY; + NewCount--; + } + else + { + *Dest = *Source; + Dest++; + } + Source++; + } + + if (Status == AE_NULL_ENTRY) + { + /* NULL terminate list and update the package count */ + + *Dest = NULL; + ObjDesc->Package.Count = NewCount; + } + + return (Status); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiNsSortList + * + * PARAMETERS: Elements - Package object element list + * Count - Element count for above + * Index - Sort by which package element + * SortDirection - Ascending or Descending sort + * + * RETURN: Status + * + * DESCRIPTION: Sort the objects that are in a package element list. + * + * NOTE: Assumes that all NULL elements have been removed from the package. + * + *****************************************************************************/ + +static ACPI_STATUS +AcpiNsSortList ( + ACPI_OPERAND_OBJECT **Elements, + UINT32 Count, + UINT32 Index, + UINT8 SortDirection) +{ + ACPI_OPERAND_OBJECT *ObjDesc1; + ACPI_OPERAND_OBJECT *ObjDesc2; + ACPI_OPERAND_OBJECT *TempObj; + UINT32 i; + UINT32 j; + + + /* Simple bubble sort */ + + for (i = 1; i < Count; i++) + { + for (j = (Count - 1); j >= i; j--) + { + ObjDesc1 = Elements[j-1]->Package.Elements[Index]; + ObjDesc2 = Elements[j]->Package.Elements[Index]; + + if (((SortDirection == ACPI_SORT_ASCENDING) && + (ObjDesc1->Integer.Value > ObjDesc2->Integer.Value)) || + + ((SortDirection == ACPI_SORT_DESCENDING) && + (ObjDesc1->Integer.Value < ObjDesc2->Integer.Value))) + { + TempObj = Elements[j-1]; + Elements[j-1] = Elements[j]; + Elements[j] = TempObj; + } + } + } + + return (AE_OK); +} diff --git a/namespace/nswalk.c b/namespace/nswalk.c index 881573e905d2..7711e9a37684 100644 --- a/namespace/nswalk.c +++ b/namespace/nswalk.c @@ -247,24 +247,27 @@ AcpiNsGetNextNodeTyped ( * MaxDepth - Depth to which search is to reach * Flags - Whether to unlock the NS before invoking * the callback routine - * UserFunction - Called when an object of "Type" is found - * Context - Passed to user function - * ReturnValue - from the UserFunction if terminated early. - * Otherwise, returns NULL. + * PreOrderVisit - Called during tree pre-order visit + * when an object of "Type" is found + * PostOrderVisit - Called during tree post-order visit + * when an object of "Type" is found + * Context - Passed to user function(s) above + * ReturnValue - from the UserFunction if terminated + * early. Otherwise, returns NULL. * RETURNS: Status * * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, * starting (and ending) at the node specified by StartHandle. - * The UserFunction is called whenever a node that matches - * the type parameter is found. If the user function returns + * The callback function is called whenever a node that matches + * the type parameter is found. If the callback function returns * a non-zero value, the search is terminated immediately and * this value is returned to the caller. * * The point of this procedure is to provide a generic namespace * walk routine that can be called from multiple places to - * provide multiple services; the User Function can be tailored - * to each task, whether it is a print function, a compare - * function, etc. + * provide multiple services; the callback function(s) can be + * tailored to each task, whether it is a print function, + * a compare function, etc. * ******************************************************************************/ @@ -274,7 +277,8 @@ AcpiNsWalkNamespace ( ACPI_HANDLE StartNode, UINT32 MaxDepth, UINT32 Flags, - ACPI_WALK_CALLBACK UserFunction, + ACPI_WALK_CALLBACK PreOrderVisit, + ACPI_WALK_CALLBACK PostOrderVisit, void *Context, void **ReturnValue) { @@ -284,6 +288,7 @@ AcpiNsWalkNamespace ( ACPI_NAMESPACE_NODE *ParentNode; ACPI_OBJECT_TYPE ChildType; UINT32 Level; + BOOLEAN NodePreviouslyVisited = FALSE; ACPI_FUNCTION_TRACE (NsWalkNamespace); @@ -299,7 +304,7 @@ AcpiNsWalkNamespace ( /* Null child means "get first node" */ ParentNode = StartNode; - ChildNode = NULL; + ChildNode = AcpiNsGetNextNode (ParentNode, NULL); ChildType = ACPI_TYPE_ANY; Level = 1; @@ -308,103 +313,139 @@ AcpiNsWalkNamespace ( * started. When Level is zero, the loop is done because we have * bubbled up to (and passed) the original parent handle (StartEntry) */ - while (Level > 0) + while (Level > 0 && ChildNode) { - /* Get the next node in this scope. Null if not found */ - Status = AE_OK; - ChildNode = AcpiNsGetNextNode (ParentNode, ChildNode); - if (ChildNode) + + /* Found next child, get the type if we are not searching for ANY */ + + if (Type != ACPI_TYPE_ANY) + { + ChildType = ChildNode->Type; + } + + /* + * Ignore all temporary namespace nodes (created during control + * method execution) unless told otherwise. These temporary nodes + * can cause a race condition because they can be deleted during + * the execution of the user function (if the namespace is + * unlocked before invocation of the user function.) Only the + * debugger namespace dump will examine the temporary nodes. + */ + if ((ChildNode->Flags & ANOBJ_TEMPORARY) && + !(Flags & ACPI_NS_WALK_TEMP_NODES)) { - /* Found next child, get the type if we are not searching for ANY */ + Status = AE_CTRL_DEPTH; + } - if (Type != ACPI_TYPE_ANY) + /* Type must match requested type */ + + else if (ChildType == Type) + { + /* + * Found a matching node, invoke the user callback function. + * Unlock the namespace if flag is set. + */ + if (Flags & ACPI_NS_WALK_UNLOCK) { - ChildType = ChildNode->Type; + MutexStatus = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (MutexStatus)) + { + return_ACPI_STATUS (MutexStatus); + } } /* - * Ignore all temporary namespace nodes (created during control - * method execution) unless told otherwise. These temporary nodes - * can cause a race condition because they can be deleted during - * the execution of the user function (if the namespace is - * unlocked before invocation of the user function.) Only the - * debugger namespace dump will examine the temporary nodes. + * Invoke the user function, either pre-order or post-order + * or both. */ - if ((ChildNode->Flags & ANOBJ_TEMPORARY) && - !(Flags & ACPI_NS_WALK_TEMP_NODES)) + if (!NodePreviouslyVisited) { - Status = AE_CTRL_DEPTH; + if (PreOrderVisit) + { + Status = PreOrderVisit (ChildNode, Level, + Context, ReturnValue); + } } - - /* Type must match requested type */ - - else if (ChildType == Type) + else { - /* - * Found a matching node, invoke the user callback function. - * Unlock the namespace if flag is set. - */ - if (Flags & ACPI_NS_WALK_UNLOCK) + if (PostOrderVisit) { - MutexStatus = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (MutexStatus)) - { - return_ACPI_STATUS (MutexStatus); - } + Status = PostOrderVisit (ChildNode, Level, + Context, ReturnValue); } + } - Status = UserFunction (ChildNode, Level, Context, ReturnValue); - - if (Flags & ACPI_NS_WALK_UNLOCK) + if (Flags & ACPI_NS_WALK_UNLOCK) + { + MutexStatus = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (MutexStatus)) { - MutexStatus = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (MutexStatus)) - { - return_ACPI_STATUS (MutexStatus); - } + return_ACPI_STATUS (MutexStatus); } + } - switch (Status) - { - case AE_OK: - case AE_CTRL_DEPTH: + switch (Status) + { + case AE_OK: + case AE_CTRL_DEPTH: - /* Just keep going */ - break; + /* Just keep going */ + break; - case AE_CTRL_TERMINATE: + case AE_CTRL_TERMINATE: - /* Exit now, with OK status */ + /* Exit now, with OK status */ - return_ACPI_STATUS (AE_OK); + return_ACPI_STATUS (AE_OK); - default: + default: - /* All others are valid exceptions */ + /* All others are valid exceptions */ - return_ACPI_STATUS (Status); - } + return_ACPI_STATUS (Status); } + } - /* - * Depth first search: Attempt to go down another level in the - * namespace if we are allowed to. Don't go any further if we have - * reached the caller specified maximum depth or if the user - * function has specified that the maximum depth has been reached. - */ - if ((Level < MaxDepth) && (Status != AE_CTRL_DEPTH)) + /* + * Depth first search: Attempt to go down another level in the + * namespace if we are allowed to. Don't go any further if we have + * reached the caller specified maximum depth or if the user + * function has specified that the maximum depth has been reached. + */ + if (!NodePreviouslyVisited && + (Level < MaxDepth) && + (Status != AE_CTRL_DEPTH)) + { + if (ChildNode->Child) { - if (ChildNode->Child) - { - /* There is at least one child of this node, visit it */ + /* There is at least one child of this node, visit it */ - Level++; - ParentNode = ChildNode; - ChildNode = NULL; - } + Level++; + ParentNode = ChildNode; + ChildNode = AcpiNsGetNextNode (ParentNode, NULL); + continue; } } + + /* No more children, re-visit this node */ + + if (!NodePreviouslyVisited) + { + NodePreviouslyVisited = TRUE; + continue; + } + + /* No more children, visit peers */ + + ChildNode = AcpiNsGetNextNode (ParentNode, ChildNode); + if (ChildNode) + { + NodePreviouslyVisited = FALSE; + } + + /* No peers, re-visit parent */ + else { /* @@ -414,6 +455,8 @@ AcpiNsWalkNamespace ( Level--; ChildNode = ParentNode; ParentNode = AcpiNsGetParentNode (ParentNode); + + NodePreviouslyVisited = TRUE; } } diff --git a/namespace/nsxfeval.c b/namespace/nsxfeval.c index 157ca93e2a44..1ba85ab05fd7 100644 --- a/namespace/nsxfeval.c +++ b/namespace/nsxfeval.c @@ -544,8 +544,11 @@ AcpiNsResolveReferences ( * PARAMETERS: Type - ACPI_OBJECT_TYPE to search for * StartObject - Handle in namespace where search begins * MaxDepth - Depth to which search is to reach - * UserFunction - Called when an object of "Type" is found - * Context - Passed to user function + * PreOrderVisit - Called during tree pre-order visit + * when an object of "Type" is found + * PostOrderVisit - Called during tree post-order visit + * when an object of "Type" is found + * Context - Passed to user function(s) above * ReturnValue - Location where return value of * UserFunction is put if terminated early * @@ -554,16 +557,16 @@ AcpiNsResolveReferences ( * * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, * starting (and ending) at the object specified by StartHandle. - * The UserFunction is called whenever an object that matches - * the type parameter is found. If the user function returns + * The callback function is called whenever an object that matches + * the type parameter is found. If the callback function returns * a non-zero value, the search is terminated immediately and this * value is returned to the caller. * * The point of this procedure is to provide a generic namespace * walk routine that can be called from multiple places to - * provide multiple services; the User Function can be tailored - * to each task, whether it is a print function, a compare - * function, etc. + * provide multiple services; the callback function(s) can be + * tailored to each task, whether it is a print function, + * a compare function, etc. * ******************************************************************************/ @@ -572,7 +575,8 @@ AcpiWalkNamespace ( ACPI_OBJECT_TYPE Type, ACPI_HANDLE StartObject, UINT32 MaxDepth, - ACPI_WALK_CALLBACK UserFunction, + ACPI_WALK_CALLBACK PreOrderVisit, + ACPI_WALK_CALLBACK PostOrderVisit, void *Context, void **ReturnValue) { @@ -586,7 +590,7 @@ AcpiWalkNamespace ( if ((Type > ACPI_TYPE_LOCAL_MAX) || (!MaxDepth) || - (!UserFunction)) + (!PreOrderVisit && !PostOrderVisit)) { return_ACPI_STATUS (AE_BAD_PARAMETER); } @@ -621,7 +625,8 @@ AcpiWalkNamespace ( } Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth, - ACPI_NS_WALK_UNLOCK, UserFunction, Context, ReturnValue); + ACPI_NS_WALK_UNLOCK, PreOrderVisit, + PostOrderVisit, Context, ReturnValue); (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); @@ -833,7 +838,7 @@ AcpiGetDevices ( Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, - AcpiNsGetDeviceCallback, &Info, ReturnValue); + AcpiNsGetDeviceCallback, NULL, &Info, ReturnValue); (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); return_ACPI_STATUS (Status); diff --git a/parser/psloop.c b/parser/psloop.c index fe9b7311a27a..4171e0dc6de0 100644 --- a/parser/psloop.c +++ b/parser/psloop.c @@ -173,6 +173,7 @@ AcpiPsCompleteFinalOp ( static void AcpiPsLinkModuleCode ( + ACPI_PARSE_OBJECT *ParentOp, UINT8 *AmlStart, UINT32 AmlLength, ACPI_OWNER_ID OwnerId); @@ -593,7 +594,7 @@ AcpiPsGetArguments ( */ if (WalkState->PassNumber == ACPI_IMODE_LOAD_PASS1) { - AcpiPsLinkModuleCode (AmlOpStart, + AcpiPsLinkModuleCode (Op->Common.Parent, AmlOpStart, (UINT32) (WalkState->ParserState.PkgEnd - AmlOpStart), WalkState->OwnerId); } @@ -704,7 +705,8 @@ AcpiPsGetArguments ( * * FUNCTION: AcpiPsLinkModuleCode * - * PARAMETERS: AmlStart - Pointer to the AML + * PARAMETERS: ParentOp - Parent parser op + * AmlStart - Pointer to the AML * AmlLength - Length of executable AML * OwnerId - OwnerId of module level code * @@ -718,6 +720,7 @@ AcpiPsGetArguments ( static void AcpiPsLinkModuleCode ( + ACPI_PARSE_OBJECT *ParentOp, UINT8 *AmlStart, UINT32 AmlLength, ACPI_OWNER_ID OwnerId) @@ -725,6 +728,7 @@ AcpiPsLinkModuleCode ( ACPI_OPERAND_OBJECT *Prev; ACPI_OPERAND_OBJECT *Next; ACPI_OPERAND_OBJECT *MethodObj; + ACPI_NAMESPACE_NODE *ParentNode; /* Get the tail of the list */ @@ -751,11 +755,27 @@ AcpiPsLinkModuleCode ( return; } + if (ParentOp->Common.Node) + { + ParentNode = ParentOp->Common.Node; + } + else + { + ParentNode = AcpiGbl_RootNode; + } + MethodObj->Method.AmlStart = AmlStart; MethodObj->Method.AmlLength = AmlLength; MethodObj->Method.OwnerId = OwnerId; MethodObj->Method.Flags |= AOPOBJ_MODULE_LEVEL; + /* + * Save the parent node in NextObject. This is cheating, but we + * don't want to expand the method object. + */ + MethodObj->Method.NextObject = + ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, ParentNode); + if (!Prev) { AcpiGbl_ModuleCodeList = MethodObj; diff --git a/parser/psparse.c b/parser/psparse.c index d9d6a2944bb5..820f54bd0ca9 100644 --- a/parser/psparse.c +++ b/parser/psparse.c @@ -705,13 +705,11 @@ AcpiPsParseAml ( !PreviousWalkState->ImplicitReturnObj) { PreviousWalkState->ImplicitReturnObj = - AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + AcpiUtCreateIntegerObject ((UINT64) 0); if (!PreviousWalkState->ImplicitReturnObj) { return_ACPI_STATUS (AE_NO_MEMORY); } - - PreviousWalkState->ImplicitReturnObj->Integer.Value = 0; } /* Restart the calling control method */ diff --git a/parser/psxface.c b/parser/psxface.c index 1859b6921438..5f6f663d8d7f 100644 --- a/parser/psxface.c +++ b/parser/psxface.c @@ -422,15 +422,13 @@ AcpiPsExecuteMethod ( if (AcpiGbl_EnableInterpreterSlack) { WalkState->ImplicitReturnObj = - AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + AcpiUtCreateIntegerObject ((UINT64) 0); if (!WalkState->ImplicitReturnObj) { Status = AE_NO_MEMORY; AcpiDsDeleteWalkState (WalkState); goto Cleanup; } - - WalkState->ImplicitReturnObj->Integer.Value = 0; } /* Parse the AML */ diff --git a/tools/acpiexec/Makefile b/tools/acpiexec/Makefile index 7e5a27ea9242..2022bbbf3bb2 100644 --- a/tools/acpiexec/Makefile +++ b/tools/acpiexec/Makefile @@ -90,6 +90,7 @@ SRCS= aetables.c aehandlers.c aeexec.c aemain.c \ ../../namespace/nsparse.c \ ../../namespace/nspredef.c \ ../../namespace/nsrepair.c \ + ../../namespace/nsrepair2.c \ ../../namespace/nssearch.c \ ../../namespace/nsutils.c \ ../../namespace/nswalk.c \ diff --git a/tools/acpisrc/astable.c b/tools/acpisrc/astable.c index 33dbc42fcacc..e66fe72fdffa 100644 --- a/tools/acpisrc/astable.c +++ b/tools/acpisrc/astable.c @@ -391,6 +391,8 @@ ACPI_TYPED_IDENTIFIER_TABLE AcpiIdentifiers[] = { {"ACPI_PREDEFINED_INFO", SRC_TYPE_UNION}, {"ACPI_PREDEFINED_NAMES", SRC_TYPE_STRUCT}, {"ACPI_PSCOPE_STATE", SRC_TYPE_STRUCT}, + {"ACPI_REPAIR_FUNCTION", SRC_TYPE_SIMPLE}, + {"ACPI_REPAIR_INFO", SRC_TYPE_STRUCT}, {"ACPI_RESOURCE", SRC_TYPE_STRUCT}, {"ACPI_RESOURCE_ADDRESS", SRC_TYPE_STRUCT}, {"ACPI_RESOURCE_ADDRESS16", SRC_TYPE_STRUCT}, diff --git a/tools/acpixtract/acpixtract.c b/tools/acpixtract/acpixtract.c index 01b77802b698..044d552240d9 100644 --- a/tools/acpixtract/acpixtract.c +++ b/tools/acpixtract/acpixtract.c @@ -716,7 +716,7 @@ ListTables ( size_t HeaderSize; unsigned char Header[48]; int TableCount = 0; - ACPI_TABLE_HEADER *TableHeader = (ACPI_TABLE_HEADER *) Header; + ACPI_TABLE_HEADER *TableHeader = (ACPI_TABLE_HEADER *) (void *) Header; /* Open input in text mode, output is in binary mode */ diff --git a/utilities/utmisc.c b/utilities/utmisc.c index 89e1addba65e..bc27cd529388 100644 --- a/utilities/utmisc.c +++ b/utilities/utmisc.c @@ -1435,3 +1435,51 @@ AcpiUtPredefinedWarning ( ACPI_COMMON_MSG_SUFFIX; va_end (args); } + +/******************************************************************************* + * + * FUNCTION: AcpiUtPredefinedInfo + * + * PARAMETERS: ModuleName - Caller's module name (for error output) + * LineNumber - Caller's line number (for error output) + * Pathname - Full pathname to the node + * NodeFlags - From Namespace node for the method/object + * Format - Printf format string + additional args + * + * RETURN: None + * + * DESCRIPTION: Info messages for the predefined validation module. Messages + * are only emitted the first time a problem with a particular + * method/object is detected. This prevents a flood of + * messages for methods that are repeatedly evaluated. + * + ******************************************************************************/ + +void ACPI_INTERNAL_VAR_XFACE +AcpiUtPredefinedInfo ( + const char *ModuleName, + UINT32 LineNumber, + char *Pathname, + UINT8 NodeFlags, + const char *Format, + ...) +{ + va_list args; + + + /* + * Warning messages for this method/object will be disabled after the + * first time a validation fails or an object is successfully repaired. + */ + if (NodeFlags & ANOBJ_EVALUATED) + { + return; + } + + AcpiOsPrintf ("ACPI Info for %s: ", Pathname); + + va_start (args, Format); + AcpiOsVprintf (Format, args); + ACPI_COMMON_MSG_SUFFIX; + va_end (args); +} diff --git a/utilities/utobject.c b/utilities/utobject.c index e38d2b28799e..5164744891b8 100644 --- a/utilities/utobject.c +++ b/utilities/utobject.c @@ -281,6 +281,41 @@ AcpiUtCreatePackageObject ( /******************************************************************************* * + * FUNCTION: AcpiUtCreateIntegerObject + * + * PARAMETERS: InitialValue - Initial value for the integer + * + * RETURN: Pointer to a new Integer object, null on failure + * + * DESCRIPTION: Create an initialized integer object + * + ******************************************************************************/ + +ACPI_OPERAND_OBJECT * +AcpiUtCreateIntegerObject ( + UINT64 InitialValue) +{ + ACPI_OPERAND_OBJECT *IntegerDesc; + + + ACPI_FUNCTION_TRACE (UtCreateIntegerObject); + + + /* Create and initialize a new integer object */ + + IntegerDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + if (!IntegerDesc) + { + return_PTR (NULL); + } + + IntegerDesc->Integer.Value = InitialValue; + return_PTR (IntegerDesc); +} + + +/******************************************************************************* + * * FUNCTION: AcpiUtCreateBufferObject * * PARAMETERS: BufferSize - Size of buffer to be created |