diff --git a/sys/contrib/dev/acpica/CHANGES.txt b/sys/contrib/dev/acpica/CHANGES.txt index e3f7151f3d96..54057f3752e5 100644 --- a/sys/contrib/dev/acpica/CHANGES.txt +++ b/sys/contrib/dev/acpica/CHANGES.txt @@ -1,3 +1,65 @@ +---------------------------------------- +11 March 2004. Summary of changes for version 20040311: + +1) ACPI CA Core Subsystem: + +Fixed a problem where errors occurring during the parse phase of +control method execution did not abort cleanly. For example, +objects created and installed in the namespace were not deleted. +This caused all subsequent invocations of the method to return +the AE_ALREADY_EXISTS exception. + +Implemented a mechanism to force a control method to "Serialized" +execution if the method attempts to create namespace objects. +(The root of the AE_ALREADY_EXISTS problem.) + +Implemented support for the predefined _OSI "internal" control +method. Initial supported strings are "Linux", "Windows 2000", +"Windows 2001", and "Windows 2001.1", and can be easily upgraded +for new strings as necessary. This feature will allow "other" +operating systems to execute the fully tested, "Windows" code +path through the ASL code + +Global Lock Support: Now allows multiple acquires and releases +with any internal thread. Removed concept of "owning thread" for +this special mutex. + +Fixed two functions that were inappropriately declaring large +objects on the CPU stack: PsParseLoop, NsEvaluateRelative. +Reduces the stack usage during method execution considerably. + +Fixed a problem in the ACPI 2.0 FACS descriptor (actbl2.h) where +the S4Bios_f field was incorrectly defined as UINT32 instead of +UINT32_BIT. + +Fixed a problem where AcpiEvGpeDetect would fault if there were +no GPEs defined on the machine. + +Implemented two runtime options: One to force all control method +execution to "Serialized" to mimic Windows behavior, another to +disable _OSI support if it causes problems on a given machine. + +Code and Data Size: Current and previous core subsystem library +sizes are shown below. These are the code and data sizes for the +acpica.lib produced by the Microsoft Visual C++ 6.0 compiler, and +these values do not include any ACPI driver or OSPM code. The +debug version of the code includes the debug output trace +mechanism and has a much larger code and data size. Note that +these values will vary depending on the efficiency of the +compiler and the compiler options used during generation. + + Previous Release: + Non-Debug Version: 74.8K Code, 10.1K Data, 84.9K Total + Debug Version: 158.7K Code, 65.1K Data, 223.8K Total + Current Release: + Non-Debug Version: 76.5K Code, 11.3K Data, 87.8K Total + Debug Version: 160.3K Code, 66.0K Data, 226.3K Total + +2) iASL Compiler/Disassembler: + +Fixed an array size problem for FreeBSD that would cause the +compiler to fault. + ---------------------------------------- 20 February 2004. Summary of changes for version 20040220: diff --git a/sys/contrib/dev/acpica/acconfig.h b/sys/contrib/dev/acpica/acconfig.h index fcbeffd05ef2..b4effcbca27a 100644 --- a/sys/contrib/dev/acpica/acconfig.h +++ b/sys/contrib/dev/acpica/acconfig.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acconfig.h - Global configuration constants - * $Revision: 149 $ + * $Revision: 150 $ * *****************************************************************************/ @@ -137,7 +137,7 @@ /* Version string */ -#define ACPI_CA_VERSION 0x20040220 +#define ACPI_CA_VERSION 0x20040311 /* Maximum objects in the various object caches */ @@ -258,6 +258,10 @@ #define ACPI_SMBUS_BUFFER_SIZE 34 +/* Number of strings associated with the _OSI reserved method */ + +#define ACPI_NUM_OSI_STRINGS 4 + /****************************************************************************** * diff --git a/sys/contrib/dev/acpica/acglobal.h b/sys/contrib/dev/acpica/acglobal.h index d80bf7d05612..fedc2395dca8 100644 --- a/sys/contrib/dev/acpica/acglobal.h +++ b/sys/contrib/dev/acpica/acglobal.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acglobal.h - Declarations for global variables - * $Revision: 147 $ + * $Revision: 148 $ * *****************************************************************************/ @@ -152,6 +152,14 @@ extern UINT32 AcpiDbgLayer; extern UINT32 AcpiGbl_NestingLevel; +/***************************************************************************** + * + * Runtime configuration + * + ****************************************************************************/ + +ACPI_EXTERN UINT8 AcpiGbl_CreateOsiMethod; +ACPI_EXTERN UINT8 AcpiGbl_AllMethodsSerialized; /***************************************************************************** * @@ -242,6 +250,7 @@ extern const char *AcpiGbl_SleepStateNames[ACPI_S_STATE_COU extern const char *AcpiGbl_HighestDstateNames[4]; extern const ACPI_OPCODE_INFO AcpiGbl_AmlOpInfo[AML_NUM_OPCODES]; extern const char *AcpiGbl_RegionTypes[ACPI_NUM_PREDEFINED_REGIONS]; +extern const char *AcpiGbl_ValidOsiStrings[ACPI_NUM_OSI_STRINGS]; /***************************************************************************** @@ -252,7 +261,7 @@ extern const char *AcpiGbl_RegionTypes[ACPI_NUM_PREDEFINED_ #define NUM_NS_TYPES ACPI_TYPE_INVALID+1 -#if defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY) +#if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY) #define NUM_PREDEFINED_NAMES 10 #else #define NUM_PREDEFINED_NAMES 9 diff --git a/sys/contrib/dev/acpica/acmacros.h b/sys/contrib/dev/acpica/acmacros.h index 670fe7434e19..3d4f66c8bbfd 100644 --- a/sys/contrib/dev/acpica/acmacros.h +++ b/sys/contrib/dev/acpica/acmacros.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acmacros.h - C macros for the entire subsystem. - * $Revision: 148 $ + * $Revision: 149 $ * *****************************************************************************/ @@ -754,7 +754,4 @@ #endif /* ACPI_DBG_TRACK_ALLOCATIONS */ - -#define ACPI_GET_STACK_POINTER _asm {mov eax, ebx} - #endif /* ACMACROS_H */ diff --git a/sys/contrib/dev/acpica/acobject.h b/sys/contrib/dev/acpica/acobject.h index b31eed87f747..dbdb9ef28c6f 100644 --- a/sys/contrib/dev/acpica/acobject.h +++ b/sys/contrib/dev/acpica/acobject.h @@ -2,7 +2,7 @@ /****************************************************************************** * * Name: acobject.h - Definition of ACPI_OPERAND_OBJECT (Internal object only) - * $Revision: 123 $ + * $Revision: 124 $ * *****************************************************************************/ @@ -259,7 +259,11 @@ typedef struct acpi_object_event } ACPI_OBJECT_EVENT; -#define INFINITE_CONCURRENCY 0xFF +#define ACPI_INFINITE_CONCURRENCY 0xFF + +typedef +ACPI_STATUS (*ACPI_INTERNAL_METHOD) ( + struct acpi_walk_state *WalkState); typedef struct acpi_object_method { @@ -269,6 +273,7 @@ typedef struct acpi_object_method UINT32 AmlLength; void *Semaphore; UINT8 *AmlStart; + ACPI_INTERNAL_METHOD Implementation; UINT8 Concurrency; UINT8 ThreadCount; ACPI_OWNER_ID OwningId; diff --git a/sys/contrib/dev/acpica/actbl2.h b/sys/contrib/dev/acpica/actbl2.h index 6aa1d93ccfcf..932e84f62f3f 100644 --- a/sys/contrib/dev/acpica/actbl2.h +++ b/sys/contrib/dev/acpica/actbl2.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: actbl2.h - ACPI Specification Revision 2.0 Tables - * $Revision: 35 $ + * $Revision: 36 $ * *****************************************************************************/ @@ -171,7 +171,7 @@ typedef struct facs_descriptor_rev2 UINT32 HardwareSignature; /* Hardware configuration signature */ UINT32 FirmwareWakingVector; /* 32bit physical address of the Firmware Waking Vector. */ UINT32 GlobalLock; /* Global Lock used to synchronize access to shared hardware resources */ - UINT32 S4Bios_f : 1; /* S4Bios_f - Indicates if S4BIOS support is present */ + UINT32_BIT S4Bios_f : 1; /* S4Bios_f - Indicates if S4BIOS support is present */ UINT32_BIT Reserved1 : 31; /* Must be 0 */ UINT64 XFirmwareWakingVector; /* 64bit physical address of the Firmware Waking Vector. */ UINT8 Version; /* Version of this table */ diff --git a/sys/contrib/dev/acpica/actypes.h b/sys/contrib/dev/acpica/actypes.h index bffcf6bf2994..7e4ea1447301 100644 --- a/sys/contrib/dev/acpica/actypes.h +++ b/sys/contrib/dev/acpica/actypes.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: actypes.h - Common data types for the entire ACPI subsystem - * $Revision: 264 $ + * $Revision: 265 $ * *****************************************************************************/ @@ -428,7 +428,6 @@ typedef UINT64 ACPI_INTEGER; /* * Power state values */ - #define ACPI_STATE_UNKNOWN (UINT8) 0xFF #define ACPI_STATE_S0 (UINT8) 0 @@ -472,7 +471,6 @@ typedef UINT64 ACPI_INTEGER; #define ACPI_NOTIFY_BUS_MODE_MISMATCH (UINT8) 6 #define ACPI_NOTIFY_POWER_FAULT (UINT8) 7 - /* * Table types. These values are passed to the table related APIs */ @@ -488,7 +486,6 @@ typedef UINT32 ACPI_TABLE_TYPE; #define ACPI_TABLE_MAX 6 #define NUM_ACPI_TABLE_TYPES (ACPI_TABLE_MAX+1) - /* * Types associated with ACPI names and objects. The first group of * values (up to ACPI_TYPE_EXTERNAL_MAX) correspond to the definition @@ -878,7 +875,7 @@ ACPI_STATUS (*ACPI_INIT_HANDLER) ( #define ACPI_INIT_DEVICE_INI 1 -/* Address Spaces (Operation Regions */ +/* Address Spaces (For Operation Regions) */ typedef ACPI_STATUS (*ACPI_ADR_SPACE_HANDLER) ( diff --git a/sys/contrib/dev/acpica/acutils.h b/sys/contrib/dev/acpica/acutils.h index 9f9b6d11cfa7..81e1df894a64 100644 --- a/sys/contrib/dev/acpica/acutils.h +++ b/sys/contrib/dev/acpica/acutils.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acutils.h -- prototypes for the common (subsystem-wide) procedures - * $Revision: 159 $ + * $Revision: 160 $ * *****************************************************************************/ @@ -125,7 +125,6 @@ ACPI_STATUS (*ACPI_PKG_CALLBACK) ( ACPI_GENERIC_STATE *State, void *Context); - ACPI_STATUS AcpiUtWalkPackageTree ( ACPI_OPERAND_OBJECT *SourceObject, @@ -133,7 +132,6 @@ AcpiUtWalkPackageTree ( ACPI_PKG_CALLBACK WalkCallback, void *Context); - typedef struct acpi_pkg_info { UINT8 *FreeSpace; @@ -549,6 +547,10 @@ AcpiUtDeleteInternalObjectList ( #define METHOD_NAME__PRS "_PRS" +ACPI_STATUS +AcpiUtOsiImplementation ( + ACPI_WALK_STATE *WalkState); + ACPI_STATUS AcpiUtEvaluateObject ( ACPI_NAMESPACE_NODE *PrefixNode, diff --git a/sys/contrib/dev/acpica/amlcode.h b/sys/contrib/dev/acpica/amlcode.h index bb1b6e03a202..dd1f60355b89 100644 --- a/sys/contrib/dev/acpica/amlcode.h +++ b/sys/contrib/dev/acpica/amlcode.h @@ -3,7 +3,7 @@ * Name: amlcode.h - Definitions for AML, as included in "definition blocks" * Declarations and definitions contained herein are derived * directly from the ACPI specification. - * $Revision: 74 $ + * $Revision: 75 $ * *****************************************************************************/ @@ -569,11 +569,17 @@ typedef enum } AML_ACCESS_ATTRIBUTE; -/* bit fields in MethodFlags byte */ +/* Bit fields in MethodFlags byte */ -#define METHOD_FLAGS_ARG_COUNT 0x07 -#define METHOD_FLAGS_SERIALIZED 0x08 -#define METHOD_FLAGS_SYNCH_LEVEL 0xF0 +#define AML_METHOD_ARG_COUNT 0x07 +#define AML_METHOD_SERIALIZED 0x08 +#define AML_METHOD_SYNCH_LEVEL 0xF0 + +/* METHOD_FLAGS_ARG_COUNT is not used internally, define additional flags */ + +#define AML_METHOD_INTERNAL_ONLY 0x01 +#define AML_METHOD_RESERVED1 0x02 +#define AML_METHOD_RESERVED2 0x04 #endif /* __AMLCODE_H__ */ diff --git a/sys/contrib/dev/acpica/compiler/aslutils.c b/sys/contrib/dev/acpica/compiler/aslutils.c index a33a904f6d6f..b5e50518d3de 100644 --- a/sys/contrib/dev/acpica/compiler/aslutils.c +++ b/sys/contrib/dev/acpica/compiler/aslutils.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: aslutils -- compiler utilities - * $Revision: 57 $ + * $Revision: 58 $ * *****************************************************************************/ diff --git a/sys/contrib/dev/acpica/dbexec.c b/sys/contrib/dev/acpica/dbexec.c index 5397ef4aceb1..9eded346e275 100644 --- a/sys/contrib/dev/acpica/dbexec.c +++ b/sys/contrib/dev/acpica/dbexec.c @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: dbexec - debugger control method execution - * $Revision: 57 $ + * $Revision: 59 $ * ******************************************************************************/ @@ -474,12 +474,14 @@ AcpiDbMethodThread ( #endif Status = AcpiDbExecuteMethod (Info, &ReturnObj); - if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("%s During execution of %s at iteration %X\n", AcpiFormatException (Status), Info->Pathname, i); - break; + if (Status == AE_ABORT_METHOD) + { + break; + } } if ((i % 1000) == 0) diff --git a/sys/contrib/dev/acpica/dsmethod.c b/sys/contrib/dev/acpica/dsmethod.c index 12275cca459b..f6e69df62e08 100644 --- a/sys/contrib/dev/acpica/dsmethod.c +++ b/sys/contrib/dev/acpica/dsmethod.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: dsmethod - Parser/Interpreter interface - control method parsing - * $Revision: 93 $ + * $Revision: 94 $ * *****************************************************************************/ @@ -182,7 +182,7 @@ AcpiDsParseMethod ( /* Create a mutex for the method if there is a concurrency limit */ - if ((ObjDesc->Method.Concurrency != INFINITE_CONCURRENCY) && + if ((ObjDesc->Method.Concurrency != ACPI_INFINITE_CONCURRENCY) && (!ObjDesc->Method.Semaphore)) { Status = AcpiOsCreateSemaphore (ObjDesc->Method.Concurrency, @@ -389,38 +389,42 @@ AcpiDsCallControlMethod ( return_ACPI_STATUS (Status); } - /* 1) Parse: Create a new walk state for the preempting walk */ - - NextWalkState = AcpiDsCreateWalkState (ObjDesc->Method.OwningId, - Op, ObjDesc, NULL); - if (!NextWalkState) + if (!(ObjDesc->Method.MethodFlags & AML_METHOD_INTERNAL_ONLY)) { - return_ACPI_STATUS (AE_NO_MEMORY); + /* 1) Parse: Create a new walk state for the preempting walk */ + + NextWalkState = AcpiDsCreateWalkState (ObjDesc->Method.OwningId, + Op, ObjDesc, NULL); + if (!NextWalkState) + { + return_ACPI_STATUS (AE_NO_MEMORY); + } + + + /* Create and init a Root Node */ + + Op = AcpiPsCreateScopeOp (); + if (!Op) + { + Status = AE_NO_MEMORY; + goto Cleanup; + } + + Status = AcpiDsInitAmlWalk (NextWalkState, Op, MethodNode, + ObjDesc->Method.AmlStart, ObjDesc->Method.AmlLength, + NULL, NULL, 1); + if (ACPI_FAILURE (Status)) + { + AcpiDsDeleteWalkState (NextWalkState); + goto Cleanup; + } + + /* Begin AML parse */ + + Status = AcpiPsParseAml (NextWalkState); + AcpiPsDeleteParseTree (Op); } - /* Create and init a Root Node */ - - Op = AcpiPsCreateScopeOp (); - if (!Op) - { - Status = AE_NO_MEMORY; - goto Cleanup; - } - - Status = AcpiDsInitAmlWalk (NextWalkState, Op, MethodNode, - ObjDesc->Method.AmlStart, ObjDesc->Method.AmlLength, - NULL, NULL, 1); - if (ACPI_FAILURE (Status)) - { - AcpiDsDeleteWalkState (NextWalkState); - goto Cleanup; - } - - /* Begin AML parse */ - - Status = AcpiPsParseAml (NextWalkState); - AcpiPsDeleteParseTree (Op); - /* 2) Execute: Create a new state for the preempting walk */ NextWalkState = AcpiDsCreateWalkState (ObjDesc->Method.OwningId, @@ -430,7 +434,6 @@ AcpiDsCallControlMethod ( Status = AE_NO_MEMORY; goto Cleanup; } - /* * The resolved arguments were put on the previous walk state's operand * stack. Operands on the previous walk state stack always @@ -464,16 +467,27 @@ AcpiDsCallControlMethod ( ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Starting nested execution, newstate=%p\n", NextWalkState)); + if (ObjDesc->Method.MethodFlags & AML_METHOD_INTERNAL_ONLY) + { + Status = ObjDesc->Method.Implementation (NextWalkState); + return_ACPI_STATUS (Status); + } + return_ACPI_STATUS (AE_OK); /* On error, we must delete the new walk state */ Cleanup: + if (NextWalkState->MethodDesc) + { + /* Decrement the thread count on the method parse tree */ + + NextWalkState->MethodDesc->Method.ThreadCount--; + } (void) AcpiDsTerminateControlMethod (NextWalkState); AcpiDsDeleteWalkState (NextWalkState); return_ACPI_STATUS (Status); - } @@ -604,11 +618,33 @@ AcpiDsTerminateControlMethod ( } } - /* Decrement the thread count on the method parse tree */ + if (WalkState->MethodDesc->Method.ThreadCount) + { + ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, + "*** Not deleting method namespace, there are still %d threads\n", + WalkState->MethodDesc->Method.ThreadCount)); + } - WalkState->MethodDesc->Method.ThreadCount--; if (!WalkState->MethodDesc->Method.ThreadCount) { + /* + * Support to dynamically change a method from NotSerialized to + * Serialized if it appears that the method is written foolishly and + * does not support multiple thread execution. The best example of this + * is if such a method creates namespace objects and blocks. A second + * thread will fail with an AE_ALREADY_EXISTS exception + * + * This code is here because we must wait until the last thread exits + * before creating the synchronization semaphore. + */ + if ((WalkState->MethodDesc->Method.Concurrency == 1) && + (!WalkState->MethodDesc->Method.Semaphore)) + { + Status = AcpiOsCreateSemaphore (1, + 1, + &WalkState->MethodDesc->Method.Semaphore); + } + /* * There are no more threads executing this method. Perform * additional cleanup. diff --git a/sys/contrib/dev/acpica/evgpe.c b/sys/contrib/dev/acpica/evgpe.c index 4391d83d5001..95978fcbb16b 100644 --- a/sys/contrib/dev/acpica/evgpe.c +++ b/sys/contrib/dev/acpica/evgpe.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: evgpe - General Purpose Event handling and dispatch - * $Revision: 33 $ + * $Revision: 34 $ * *****************************************************************************/ @@ -228,6 +228,12 @@ AcpiEvGpeDetect ( ACPI_FUNCTION_NAME ("EvGpeDetect"); + /* Check for the case where there are no GPEs */ + + if (!GpeXruptList) + { + return (IntStatus); + } /* Examine all GPE blocks attached to this interrupt level */ diff --git a/sys/contrib/dev/acpica/excreate.c b/sys/contrib/dev/acpica/excreate.c index b0162df6ba7c..8f4be4c36219 100644 --- a/sys/contrib/dev/acpica/excreate.c +++ b/sys/contrib/dev/acpica/excreate.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: excreate - Named object creation - * $Revision: 101 $ + * $Revision: 102 $ * *****************************************************************************/ @@ -681,29 +681,36 @@ AcpiExCreateMethod ( ObjDesc->Method.AmlStart = AmlStart; ObjDesc->Method.AmlLength = AmlLength; - /* disassemble the method flags */ - + /* + * Disassemble the method flags. Split off the Arg Count + * for efficiency + */ MethodFlags = (UINT8) Operand[1]->Integer.Value; - ObjDesc->Method.MethodFlags = MethodFlags; - ObjDesc->Method.ParamCount = (UINT8) (MethodFlags & METHOD_FLAGS_ARG_COUNT); + ObjDesc->Method.MethodFlags = (UINT8) (MethodFlags & ~AML_METHOD_ARG_COUNT); + ObjDesc->Method.ParamCount = (UINT8) (MethodFlags & AML_METHOD_ARG_COUNT); /* * Get the concurrency count. If required, a semaphore will be * created for this method when it is parsed. */ - if (MethodFlags & METHOD_FLAGS_SERIALIZED) + if (AcpiGbl_AllMethodsSerialized) + { + ObjDesc->Method.Concurrency = 1; + ObjDesc->Method.MethodFlags |= AML_METHOD_SERIALIZED; + } + else if (MethodFlags & AML_METHOD_SERIALIZED) { /* * ACPI 1.0: Concurrency = 1 * ACPI 2.0: Concurrency = (SyncLevel (in method declaration) + 1) */ ObjDesc->Method.Concurrency = (UINT8) - (((MethodFlags & METHOD_FLAGS_SYNCH_LEVEL) >> 4) + 1); + (((MethodFlags & AML_METHOD_SYNCH_LEVEL) >> 4) + 1); } else { - ObjDesc->Method.Concurrency = INFINITE_CONCURRENCY; + ObjDesc->Method.Concurrency = ACPI_INFINITE_CONCURRENCY; } /* Attach the new object to the method Node */ diff --git a/sys/contrib/dev/acpica/exmutex.c b/sys/contrib/dev/acpica/exmutex.c index cd96da31b3be..3c1f4dd03963 100644 --- a/sys/contrib/dev/acpica/exmutex.c +++ b/sys/contrib/dev/acpica/exmutex.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: exmutex - ASL Mutex Acquire/Release functions - * $Revision: 20 $ + * $Revision: 21 $ * *****************************************************************************/ @@ -258,16 +258,20 @@ AcpiExAcquireMutex ( /* * Support for multiple acquires by the owning thread */ - - if ((ObjDesc->Mutex.OwnerThread) && - (ObjDesc->Mutex.OwnerThread->ThreadId == WalkState->Thread->ThreadId)) + if (ObjDesc->Mutex.OwnerThread) { - /* - * The mutex is already owned by this thread, - * just increment the acquisition depth - */ - ObjDesc->Mutex.AcquisitionDepth++; - return_ACPI_STATUS (AE_OK); + /* Special case for Global Lock, allow all threads */ + + if ((ObjDesc->Mutex.OwnerThread->ThreadId == WalkState->Thread->ThreadId) || + (ObjDesc->Mutex.Semaphore == AcpiGbl_GlobalLockSemaphore)) + { + /* + * The mutex is already owned by this thread, + * just increment the acquisition depth + */ + ObjDesc->Mutex.AcquisitionDepth++; + return_ACPI_STATUS (AE_OK); + } } /* Acquire the mutex, wait if necessary */ @@ -341,9 +345,13 @@ AcpiExReleaseMutex ( return_ACPI_STATUS (AE_AML_INTERNAL); } - /* The Mutex is owned, but this thread must be the owner */ + /* + * The Mutex is owned, but this thread must be the owner. + * Special case for Global Lock, any thread can release + */ + if ((ObjDesc->Mutex.OwnerThread->ThreadId != WalkState->Thread->ThreadId) && + (ObjDesc->Mutex.Semaphore != AcpiGbl_GlobalLockSemaphore)) - if (ObjDesc->Mutex.OwnerThread->ThreadId != WalkState->Thread->ThreadId) { ACPI_REPORT_ERROR (( "Thread %X cannot release Mutex [%4.4s] acquired by thread %X\n", diff --git a/sys/contrib/dev/acpica/nsaccess.c b/sys/contrib/dev/acpica/nsaccess.c index e6554c75b692..a01b22d3a158 100644 --- a/sys/contrib/dev/acpica/nsaccess.c +++ b/sys/contrib/dev/acpica/nsaccess.c @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: nsaccess - Top-level functions for accessing ACPI namespace - * $Revision: 177 $ + * $Revision: 179 $ * ******************************************************************************/ @@ -182,8 +182,16 @@ AcpiNsRootInitialize (void) for (InitVal = AcpiGbl_PreDefinedNames; InitVal->Name; InitVal++) { + /* _OSI is optional for now, will be permanent later */ + + if (!ACPI_STRCMP (InitVal->Name, "_OSI") && !AcpiGbl_CreateOsiMethod) + { + continue; + } + Status = AcpiNsLookup (NULL, InitVal->Name, InitVal->Type, - ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH, NULL, &NewNode); + ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH, + NULL, &NewNode); if (ACPI_FAILURE (Status) || (!NewNode)) /* Must be on same line for code converter */ { @@ -202,7 +210,8 @@ AcpiNsRootInitialize (void) Status = AcpiOsPredefinedOverride (InitVal, &Val); if (ACPI_FAILURE (Status)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not override predefined %s\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Could not override predefined %s\n", InitVal->Name)); } @@ -230,15 +239,20 @@ AcpiNsRootInitialize (void) switch (InitVal->Type) { case ACPI_TYPE_METHOD: - ObjDesc->Method.ParamCount = - (UINT8) ACPI_STRTOUL (Val, NULL, 10); + ObjDesc->Method.ParamCount = (UINT8) ACPI_STRTOUL + (Val, NULL, 10); ObjDesc->Common.Flags |= AOPOBJ_DATA_VALID; -#if defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY) +#if defined (_ACPI_ASL_COMPILER) || defined (_ACPI_DUMP_APP) - /* Compiler cheats by putting parameter count in the OwnerID */ + /* iASL Compiler cheats by putting parameter count in the OwnerID */ NewNode->OwnerId = ObjDesc->Method.ParamCount; +#else + /* Mark this as a very SPECIAL method */ + + ObjDesc->Method.MethodFlags = AML_METHOD_INTERNAL_ONLY; + ObjDesc->Method.Implementation = AcpiUtOsiImplementation; #endif break; @@ -263,8 +277,8 @@ AcpiNsRootInitialize (void) case ACPI_TYPE_MUTEX: ObjDesc->Mutex.Node = NewNode; - ObjDesc->Mutex.SyncLevel = - (UINT16) ACPI_STRTOUL (Val, NULL, 10); + ObjDesc->Mutex.SyncLevel = (UINT16) ACPI_STRTOUL + (Val, NULL, 10); if (ACPI_STRCMP (InitVal->Name, "_GL_") == 0) { @@ -300,6 +314,7 @@ AcpiNsRootInitialize (void) default: + ACPI_REPORT_ERROR (("Unsupported initial type value %X\n", InitVal->Type)); AcpiUtRemoveReference (ObjDesc); diff --git a/sys/contrib/dev/acpica/nsalloc.c b/sys/contrib/dev/acpica/nsalloc.c index 4736829f6159..065403c927c4 100644 --- a/sys/contrib/dev/acpica/nsalloc.c +++ b/sys/contrib/dev/acpica/nsalloc.c @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: nsalloc - Namespace allocation and deletion utilities - * $Revision: 84 $ + * $Revision: 85 $ * ******************************************************************************/ @@ -428,10 +428,11 @@ AcpiNsInstallNode ( Node->OwnerId = OwnerId; Node->Type = (UINT8) Type; - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%4.4s (%s) added to %4.4s (%s) %p at %p\n", - AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type), + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, + "%4.4s (%s) [Node %p Owner %X] added to %4.4s (%s) [Node %p]\n", + AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type), Node, OwnerId, AcpiUtGetNodeName (ParentNode), AcpiUtGetTypeName (ParentNode->Type), - ParentNode, Node)); + ParentNode)); /* * Increment the reference count(s) of all parents up to diff --git a/sys/contrib/dev/acpica/nseval.c b/sys/contrib/dev/acpica/nseval.c index e464f8cb1ab1..cb509d3ae6cc 100644 --- a/sys/contrib/dev/acpica/nseval.c +++ b/sys/contrib/dev/acpica/nseval.c @@ -2,7 +2,7 @@ * * Module Name: nseval - Object evaluation interfaces -- includes control * method lookup and execution. - * $Revision: 123 $ + * $Revision: 124 $ * ******************************************************************************/ @@ -157,11 +157,11 @@ AcpiNsEvaluateRelative ( ACPI_OPERAND_OBJECT **Params, ACPI_OPERAND_OBJECT **ReturnObject) { - ACPI_NAMESPACE_NODE *PrefixNode; ACPI_STATUS Status; + ACPI_NAMESPACE_NODE *PrefixNode; ACPI_NAMESPACE_NODE *Node = NULL; + ACPI_GENERIC_STATE *ScopeInfo; char *InternalPath = NULL; - ACPI_GENERIC_STATE ScopeInfo; ACPI_FUNCTION_TRACE ("NsEvaluateRelative"); @@ -183,6 +183,12 @@ AcpiNsEvaluateRelative ( return_ACPI_STATUS (Status); } + ScopeInfo = AcpiUtCreateGenericState (); + if (!ScopeInfo) + { + goto Cleanup1; + } + /* Get the prefix handle and Node */ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); @@ -201,8 +207,8 @@ AcpiNsEvaluateRelative ( /* Lookup the name in the namespace */ - ScopeInfo.Scope.Node = PrefixNode; - Status = AcpiNsLookup (&ScopeInfo, InternalPath, ACPI_TYPE_ANY, + ScopeInfo->Scope.Node = PrefixNode; + Status = AcpiNsLookup (ScopeInfo, InternalPath, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL, &Node); @@ -228,7 +234,9 @@ AcpiNsEvaluateRelative ( Pathname)); Cleanup: + AcpiUtDeleteGenericState (ScopeInfo); +Cleanup1: ACPI_MEM_FREE (InternalPath); return_ACPI_STATUS (Status); } diff --git a/sys/contrib/dev/acpica/psparse.c b/sys/contrib/dev/acpica/psparse.c index 44b129306741..5783fa6313fc 100644 --- a/sys/contrib/dev/acpica/psparse.c +++ b/sys/contrib/dev/acpica/psparse.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: psparse - Parser top level AML parse routines - * $Revision: 143 $ + * $Revision: 144 $ * *****************************************************************************/ @@ -522,7 +522,7 @@ AcpiPsParseLoop ( ACPI_STATUS Status = AE_OK; ACPI_PARSE_OBJECT *Op = NULL; /* current op */ ACPI_PARSE_OBJECT *Arg = NULL; - ACPI_PARSE_OBJECT PreOp; + ACPI_PARSE_OBJECT *PreOp = NULL; ACPI_PARSE_STATE *ParserState; UINT8 *AmlOpStart = NULL; @@ -654,8 +654,19 @@ AcpiPsParseLoop ( if (WalkState->OpInfo->Flags & AML_NAMED) { - PreOp.Common.Value.Arg = NULL; - PreOp.Common.AmlOpcode = WalkState->Opcode; + /* Allocate a new PreOp if necessary */ + + if (!PreOp) + { + PreOp = AcpiPsAllocOp (WalkState->Opcode); + if (!PreOp) + { + return_ACPI_STATUS (AE_NO_MEMORY); + } + } + + PreOp->Common.Value.Arg = NULL; + PreOp->Common.AmlOpcode = WalkState->Opcode; /* * Get and append arguments until we find the node that contains @@ -671,7 +682,7 @@ AcpiPsParseLoop ( goto CloseThisOp; } - AcpiPsAppendArg (&PreOp, Arg); + AcpiPsAppendArg (PreOp, Arg); INCREMENT_ARG_LIST (WalkState->ArgTypes); } @@ -717,7 +728,7 @@ AcpiPsParseLoop ( goto CloseThisOp; } - AcpiPsAppendArg (Op, PreOp.Common.Value.Arg); + AcpiPsAppendArg (Op, PreOp->Common.Value.Arg); AcpiGbl_Depth++; if (Op->Common.AmlOpcode == AML_REGION_OP) @@ -993,6 +1004,11 @@ CloseThisOp: AcpiPsCompleteThisOp (WalkState, Op); Op = NULL; + if (PreOp) + { + AcpiPsFreeOp (PreOp); + PreOp = NULL; + } switch (Status) { @@ -1281,6 +1297,30 @@ AcpiPsParseAml ( { ACPI_REPORT_METHOD_ERROR ("Method execution failed", WalkState->MethodNode, NULL, Status); + + /* Check for possible multi-thread reentrancy problem */ + + if ((Status == AE_ALREADY_EXISTS) && + (!WalkState->MethodDesc->Method.Semaphore)) + { + /* + * This method is marked NotSerialized, but it tried to create a named + * object, causing the second thread entrance to fail. We will workaround + * this by marking the method permanently as Serialized. + */ + WalkState->MethodDesc->Method.MethodFlags |= AML_METHOD_SERIALIZED; + WalkState->MethodDesc->Method.Concurrency = 1; + } + } + + if (WalkState->MethodDesc) + { + /* Decrement the thread count on the method parse tree */ + + if (WalkState->MethodDesc->Method.ThreadCount) + { + WalkState->MethodDesc->Method.ThreadCount--; + } } /* We are done with this walk, move on to the parent if any */ diff --git a/sys/contrib/dev/acpica/psscope.c b/sys/contrib/dev/acpica/psscope.c index bc1781898019..7fa31c06fbaa 100644 --- a/sys/contrib/dev/acpica/psscope.c +++ b/sys/contrib/dev/acpica/psscope.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: psscope - Parser scope stack management routines - * $Revision: 37 $ + * $Revision: 38 $ * *****************************************************************************/ @@ -242,7 +242,6 @@ AcpiPsPushScope ( return_ACPI_STATUS (AE_NO_MEMORY); } - Scope->Common.DataType = ACPI_DESC_TYPE_STATE_PSCOPE; Scope->ParseScope.Op = Op; Scope->ParseScope.ArgList = RemainingArgs; @@ -253,14 +252,12 @@ AcpiPsPushScope ( AcpiUtPushGenericState (&ParserState->Scope, Scope); - if (ArgCount == ACPI_VAR_ARGS) { /* multiple arguments */ Scope->ParseScope.ArgEnd = ParserState->PkgEnd; } - else { /* single argument */ @@ -319,7 +316,6 @@ AcpiPsPopScope ( AcpiUtDeleteGenericState (Scope); } - else { /* empty parse stack, prepare to fetch next opcode */ @@ -329,7 +325,6 @@ AcpiPsPopScope ( *ArgCount = 0; } - ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped Op %p Args %X\n", *Op, *ArgCount)); return_VOID; } @@ -354,15 +349,15 @@ AcpiPsCleanupScope ( { ACPI_GENERIC_STATE *Scope; + ACPI_FUNCTION_TRACE_PTR ("PsCleanupScope", ParserState); if (!ParserState) { - return; + return_VOID; } - /* Delete anything on the scope stack */ while (ParserState->Scope) diff --git a/sys/contrib/dev/acpica/uteval.c b/sys/contrib/dev/acpica/uteval.c index cf457869b497..635d711c820a 100644 --- a/sys/contrib/dev/acpica/uteval.c +++ b/sys/contrib/dev/acpica/uteval.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: uteval - Object evaluation - * $Revision: 51 $ + * $Revision: 52 $ * *****************************************************************************/ @@ -125,6 +125,66 @@ ACPI_MODULE_NAME ("uteval") +/******************************************************************************* + * + * FUNCTION: AcpiUtOsiImplementation + * + * PARAMETERS: WalkState - Current walk state + * + * RETURN: Status + * + * DESCRIPTION: Implementation of _OSI predefined control method + * Supported = _OSI (String) + * + ******************************************************************************/ + +ACPI_STATUS +AcpiUtOsiImplementation ( + ACPI_WALK_STATE *WalkState) +{ + ACPI_OPERAND_OBJECT *StringDesc; + ACPI_OPERAND_OBJECT *ReturnDesc; + ACPI_NATIVE_UINT i; + + + ACPI_FUNCTION_TRACE ("UtOsiImplementation"); + + + /* Validate the string input argument */ + + StringDesc = WalkState->Arguments[0].Object; + if (!StringDesc || (StringDesc->Common.Type != ACPI_TYPE_STRING)) + { + return_ACPI_STATUS (AE_TYPE); + } + + /* Create a return object (Default value = 0) */ + + ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); + if (!ReturnDesc) + { + return_ACPI_STATUS (AE_NO_MEMORY); + } + + /* Compare input string to table of supported strings */ + + for (i = 0; i < ACPI_NUM_OSI_STRINGS; i++) + { + if (!ACPI_STRCMP (StringDesc->String.Pointer, + (char *) AcpiGbl_ValidOsiStrings[i])) + { + /* This string is supported */ + + ReturnDesc->Integer.Value = 0xFFFFFFFF; + break; + } + } + + WalkState->ReturnDesc = ReturnDesc; + return_ACPI_STATUS (AE_CTRL_TERMINATE); +} + + /******************************************************************************* * * FUNCTION: AcpiUtEvaluateObject diff --git a/sys/contrib/dev/acpica/utglobal.c b/sys/contrib/dev/acpica/utglobal.c index 39ebd58a269e..d3ad37a27c53 100644 --- a/sys/contrib/dev/acpica/utglobal.c +++ b/sys/contrib/dev/acpica/utglobal.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: utglobal - Global variables for the ACPI subsystem - * $Revision: 193 $ + * $Revision: 194 $ * *****************************************************************************/ @@ -265,6 +265,15 @@ const char *AcpiGbl_HighestDstateNames[4] = { "_S3D", "_S4D"}; +/* Strings supported by the _OSI predefined (internal) method */ + +const char *AcpiGbl_ValidOsiStrings[ACPI_NUM_OSI_STRINGS] = { + "Linux", + "Windows 2000", + "Windows 2001", + "Windows 2001.1"}; + + /****************************************************************************** * * Namespace globals @@ -275,14 +284,10 @@ const char *AcpiGbl_HighestDstateNames[4] = { /* * Predefined ACPI Names (Built-in to the Interpreter) * - * Initial values are currently supported only for types String and Number. - * Both are specified as strings in this table. - * * NOTES: - * 1) _SB_ is defined to be a device to allow _SB_/_INI to be run + * 1) _SB_ is defined to be a device to allow \_SB_._INI to be run * during the initialization sequence. */ - const ACPI_PREDEFINED_NAMES AcpiGbl_PreDefinedNames[] = { {"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL}, @@ -294,7 +299,7 @@ const ACPI_PREDEFINED_NAMES AcpiGbl_PreDefinedNames[] = {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME}, {"_GL_", ACPI_TYPE_MUTEX, "0"}, -#if defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY) +#if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY) {"_OSI", ACPI_TYPE_METHOD, "1"}, #endif {NULL, ACPI_TYPE_ANY, NULL} /* Table terminator */ @@ -305,7 +310,6 @@ const ACPI_PREDEFINED_NAMES AcpiGbl_PreDefinedNames[] = * Properties of the ACPI Object Types, both internal and external. * The table is indexed by values of ACPI_OBJECT_TYPE */ - const UINT8 AcpiGbl_NsProperties[] = { ACPI_NS_NORMAL, /* 00 Any */ @@ -384,10 +388,8 @@ AcpiUtHexToAsciiChar ( * ******************************************************************************/ - ACPI_TABLE_LIST AcpiGbl_TableLists[NUM_ACPI_TABLE_TYPES]; - ACPI_TABLE_SUPPORT AcpiGbl_TableData[NUM_ACPI_TABLE_TYPES] = { /*********** Name, Signature, Global typed pointer Signature size, Type How many allowed?, Contains valid AML? */ @@ -551,9 +553,8 @@ AcpiUtGetEventName ( * * The type ACPI_TYPE_ANY (Untyped) is used as a "don't care" when searching; when * stored in a table it really means that we have thus far seen no evidence to - * indicatewhat type is actually going to be stored for this entry. + * indicate what type is actually going to be stored for this entry. */ - static const char AcpiGbl_BadType[] = "UNDEFINED"; #define TYPE_NAME_LENGTH 12 /* Maximum length of each string */ @@ -858,6 +859,11 @@ AcpiUtInitGlobals ( ACPI_FUNCTION_TRACE ("UtInitGlobals"); + /* Runtime configuration */ + + AcpiGbl_CreateOsiMethod = TRUE; + AcpiGbl_AllMethodsSerialized = FALSE; + /* Memory allocation and cache lists */ ACPI_MEMSET (AcpiGbl_MemoryLists, 0, sizeof (ACPI_MEMORY_LIST) * ACPI_NUM_MEM_LISTS);