diff --git a/changes.txt b/changes.txt index 5bd82ab6949a..d2c8c0e41edf 100644 --- a/changes.txt +++ b/changes.txt @@ -1,3 +1,78 @@ +---------------------------------------- +31 March 2010. Summary of changes for version 20100331: + +1) ACPI CA Core Subsystem: + +Completed a major update for the GPE support in order to improve support for +shared GPEs and to simplify both host OS and ACPICA code. Added a reference +count mechanism to support shared GPEs that require multiple device drivers. +Several external interfaces have changed. One external interface has been +removed. One new external interface was added. Most of the GPE external +interfaces now use the GPE spinlock instead of the events mutex (and the +Flags parameter for many GPE interfaces has been removed.) See the updated +ACPICA Programmer Reference for details. Matthew Garrett, Bob Moore, Rafael +Wysocki. ACPICA BZ 831. + +Changed: + AcpiEnableGpe, AcpiDisableGpe, AcpiClearGpe, AcpiGetGpeStatus +Removed: + AcpiSetGpeType +New: + AcpiSetGpe + +Implemented write support for DataTable operation regions. These regions are +defined via the DataTableRegion() operator. Previously, only read support was +implemented. The ACPI specification allows DataTableRegions to be read/write, +however. + +Implemented a new subsystem option to force a copy of the DSDT to local +memory. Optionally copy the entire DSDT to local memory (instead of simply +mapping it.) There are some (albeit very rare) BIOSs that corrupt or replace +the original DSDT, creating the need for this option. Default is FALSE, do +not copy the DSDT. + +Implemented detection of a corrupted or replaced DSDT. This change adds +support to detect a DSDT that has been corrupted and/or replaced from outside +the OS (by firmware). This is typically catastrophic for the system, but has +been seen on some machines. Once this problem has been detected, the DSDT +copy option can be enabled via system configuration. Lin Ming, Bob Moore. + +Fixed two problems with AcpiReallocateRootTable during the root table copy. +When copying the root table to the new allocation, the length used was +incorrect. The new size was used instead of the current table size, meaning +too much data was copied. Also, the count of available slots for ACPI tables +was not set correctly. Alexey Starikovskiy, Bob Moore. + +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: 87.5K Code, 18.4K Data, 105.9K Total + Debug Version: 163.4K Code, 51.1K Data, 214.5K Total + Current Release: + Non-Debug Version: 87.9K Code, 18.6K Data, 106.5K Total + Debug Version: 163.5K Code, 51.3K Data, 214.8K Total + +2) iASL Compiler/Disassembler and Tools: + +iASL: Implement limited typechecking for values returned from predefined +control methods. The type of any returned static (unnamed) object is now +validated. For example, Return(1). ACPICA BZ 786. + +iASL: Fixed a predefined name object verification regression. Fixes a problem +introduced in version 20100304. An error is incorrectly generated if a +predefined name is declared as a static named object with a value defined +using the keywords "Zero", "One", or "Ones". Lin Ming. + +iASL: Added Windows 7 support for the -g option (get local ACPI tables) by +reducing the requested registry access rights. ACPICA BZ 842. + +Disassembler: fixed a possible fault when generating External() statements. +Introduced in commit ae7d6fd: Properly handle externals with parent-prefix +(carat). Fixes a string length allocation calculation. Lin Ming. + ---------------------------------------- 04 March 2010. Summary of changes for version 20100304: diff --git a/common/dmextern.c b/common/dmextern.c index 5afd03419884..ab46b6979348 100644 --- a/common/dmextern.c +++ b/common/dmextern.c @@ -270,6 +270,15 @@ AcpiDmNormalizeParentPrefix ( } Length = (ACPI_STRLEN (ParentPath) + ACPI_STRLEN (Path) + 1); + if (ParentPath[1]) + { + /* + * If ParentPath is not just a simple '\', increment the length + * for the required dot separator (ParentPath.Path) + */ + Length++; + } + Fullpath = ACPI_ALLOCATE_ZEROED (Length); if (!Fullpath) { diff --git a/compiler/aslanalyze.c b/compiler/aslanalyze.c index eaefd3fdf7f9..19440c875c3b 100644 --- a/compiler/aslanalyze.c +++ b/compiler/aslanalyze.c @@ -1156,6 +1156,12 @@ AnMethodAnalysisWalkEnd ( case PARSEOP_RETURN: + /* + * If the parent is a predefined method name, attempt to typecheck + * the return value. Only static types can be validated. + */ + ApCheckPredefinedReturnValue (Op, MethodInfo); + /* * The parent block does not "exit" and continue execution -- the * method is terminated here with the Return() statement. diff --git a/compiler/aslcompiler.h b/compiler/aslcompiler.h index cf6c8f3ce018..508379829894 100644 --- a/compiler/aslcompiler.h +++ b/compiler/aslcompiler.h @@ -461,6 +461,11 @@ ApCheckForPredefinedMethod ( ACPI_PARSE_OBJECT *Op, ASL_METHOD_INFO *MethodInfo); +void +ApCheckPredefinedReturnValue ( + ACPI_PARSE_OBJECT *Op, + ASL_METHOD_INFO *MethodInfo); + UINT32 ApCheckForPredefinedName ( ACPI_PARSE_OBJECT *Op, diff --git a/compiler/aslpredef.c b/compiler/aslpredef.c index 04cd2d405c14..6346bafd10ec 100644 --- a/compiler/aslpredef.c +++ b/compiler/aslpredef.c @@ -296,7 +296,11 @@ ApCheckForPredefinedMethod ( if (MethodInfo->NumReturnNoValue && PredefinedNames[Index].Info.ExpectedBtypes) { - sprintf (MsgBuffer, "%4.4s", PredefinedNames[Index].Info.Name); + ApGetExpectedTypes (StringBuffer, + PredefinedNames[Index].Info.ExpectedBtypes); + + sprintf (MsgBuffer, "%s required for %4.4s", + StringBuffer, PredefinedNames[Index].Info.Name); AslError (ASL_WARNING, ASL_MSG_RESERVED_RETURN_VALUE, Op, MsgBuffer); @@ -306,6 +310,90 @@ ApCheckForPredefinedMethod ( } +/******************************************************************************* + * + * FUNCTION: ApCheckPredefinedReturnValue + * + * PARAMETERS: Op - A parse node of type "RETURN". + * MethodInfo - Saved info about this method + * + * RETURN: None + * + * DESCRIPTION: If method is a predefined name, attempt to validate the return + * value. Only "static" types can be validated - a simple return + * of an integer/string/buffer/package or a named reference to + * a static object. Values such as a Localx or Argx or a control + * method invocation are not checked. + * + ******************************************************************************/ + +void +ApCheckPredefinedReturnValue ( + ACPI_PARSE_OBJECT *Op, + ASL_METHOD_INFO *MethodInfo) +{ + UINT32 Index; + ACPI_PARSE_OBJECT *ReturnValueOp; + + + /* Check parent method for a match against the predefined name list */ + + Index = ApCheckForPredefinedName (MethodInfo->Op, + MethodInfo->Op->Asl.NameSeg); + + switch (Index) + { + case ACPI_NOT_RESERVED_NAME: /* No underscore or _Txx or _xxx name not matched */ + case ACPI_PREDEFINED_NAME: /* Resource Name or reserved scope name */ + case ACPI_COMPILER_RESERVED_NAME: /* A _Txx that was not emitted by compiler */ + case ACPI_EVENT_RESERVED_NAME: /* _Lxx, _Exx, and _Qxx methods */ + + /* Just return, nothing to do */ + return; + + default: /* a real predefined ACPI name */ + + /* Exit if no return value expected */ + + if (!PredefinedNames[Index].Info.ExpectedBtypes) + { + return; + } + + /* Get the object returned, it is the next argument */ + + ReturnValueOp = Op->Asl.Child; + switch (ReturnValueOp->Asl.ParseOpcode) + { + case PARSEOP_ZERO: + case PARSEOP_ONE: + case PARSEOP_ONES: + case PARSEOP_INTEGER: + case PARSEOP_STRING_LITERAL: + case PARSEOP_BUFFER: + case PARSEOP_PACKAGE: + + /* Static data return object - check against expected type */ + + ApCheckObjectType (ReturnValueOp, + PredefinedNames[Index].Info.ExpectedBtypes); + break; + + default: + + /* + * All other ops are very difficult or impossible to typecheck at + * compile time. These include all Localx, Argx, and method + * invocations. Also, NAMESEG and NAMESTRING because the type of + * any named object can be changed at runtime (for example, + * CopyObject will change the type of the target object.) + */ + break; + } + } +} + + /******************************************************************************* * * FUNCTION: ApCheckForPredefinedObject @@ -441,7 +529,7 @@ ApCheckForPredefinedName ( * * RETURN: None * - * DESCRIPTION: Check for the "special" predefined names - + * DESCRIPTION: Check for the "special" predefined names - * _Lxx, _Exx, _Qxx, and _T_x * ******************************************************************************/ @@ -512,7 +600,7 @@ ApCheckForSpecialName ( * * FUNCTION: ApCheckObjectType * - * PARAMETERS: Op - A parse node + * PARAMETERS: Op - Current parse node * ExpectedBtypes - Bitmap of expected return type(s) * * RETURN: None @@ -529,11 +617,13 @@ ApCheckObjectType ( UINT32 ExpectedBtypes) { UINT32 ReturnBtype; - char TypeBuffer[48]; /* Room for 5 types */ switch (Op->Asl.ParseOpcode) { + case PARSEOP_ZERO: + case PARSEOP_ONE: + case PARSEOP_ONES: case PARSEOP_INTEGER: ReturnBtype = ACPI_RTYPE_INTEGER; break; @@ -552,11 +642,11 @@ ApCheckObjectType ( default: /* Not one of the supported object types */ - + goto TypeErrorExit; } - /* Is the object one of the expected types? */ + /* Exit if the object is one of the expected types */ if (ReturnBtype & ExpectedBtypes) { @@ -568,10 +658,13 @@ ApCheckObjectType ( /* Format the expected types and emit an error message */ - ApGetExpectedTypes (TypeBuffer, ExpectedBtypes); + ApGetExpectedTypes (StringBuffer, ExpectedBtypes); + + sprintf (MsgBuffer, "found %s, requires %s", + UtGetOpName (Op->Asl.ParseOpcode), StringBuffer); AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Op, - TypeBuffer); + MsgBuffer); } diff --git a/compiler/aslstubs.c b/compiler/aslstubs.c index 8f3de7e83b4a..4555873189b3 100644 --- a/compiler/aslstubs.c +++ b/compiler/aslstubs.c @@ -243,13 +243,6 @@ AcpiEvInitializeRegion ( return (AE_OK); } -ACPI_STATUS -AcpiEvCheckForWakeOnlyGpe ( - ACPI_GPE_EVENT_INFO *GpeEventInfo) -{ - return (AE_OK); -} - void AcpiExDoDebugObject ( ACPI_OPERAND_OBJECT *SourceDesc, diff --git a/compiler/asltypes.h b/compiler/asltypes.h index 6edf9870680a..30b8fdfe7d04 100644 --- a/compiler/asltypes.h +++ b/compiler/asltypes.h @@ -507,7 +507,7 @@ char *AslMessages [] = { /* ASL_MSG_RESERVED_ARG_COUNT_HI */ "Reserved method has too many arguments", /* ASL_MSG_RESERVED_ARG_COUNT_LO */ "Reserved method has too few arguments", /* ASL_MSG_RESERVED_METHOD */ "Reserved name must be a control method", -/* ASL_MSG_RESERVED_OPERAND_TYPE */ "Invalid object type for reserved name, must be", +/* ASL_MSG_RESERVED_OPERAND_TYPE */ "Invalid object type for reserved name", /* ASL_MSG_RESERVED_RETURN_VALUE */ "Reserved method must return a value", /* ASL_MSG_RESERVED_USE */ "Invalid use of reserved name", /* ASL_MSG_RESERVED_WORD */ "Use of reserved name", diff --git a/debugger/dbdisply.c b/debugger/dbdisply.c index 7c04ffca8bc0..ec4715bddf69 100644 --- a/debugger/dbdisply.c +++ b/debugger/dbdisply.c @@ -848,13 +848,12 @@ AcpiDbDisplayGpes ( Block, GpeBlock, GpeBlock->Node, Buffer); AcpiOsPrintf (" Registers: %u (%u GPEs)\n", - GpeBlock->RegisterCount, - ACPI_MUL_8 (GpeBlock->RegisterCount)); + GpeBlock->RegisterCount, GpeBlock->GpeCount); - AcpiOsPrintf (" GPE range: 0x%X to 0x%X\n", + AcpiOsPrintf (" GPE range: 0x%X to 0x%X on interrupt %u\n", GpeBlock->BlockBaseNumber, - GpeBlock->BlockBaseNumber + - (GpeBlock->RegisterCount * 8) -1); + GpeBlock->BlockBaseNumber + (GpeBlock->GpeCount - 1), + GpeXruptInfo->InterruptNumber); AcpiOsPrintf ( " RegisterInfo: %p Status %8.8X%8.8X Enable %8.8X%8.8X\n", @@ -871,9 +870,12 @@ AcpiDbDisplayGpes ( GpeRegisterInfo = &GpeBlock->RegisterInfo[i]; AcpiOsPrintf ( - " Reg %u: WakeEnable %2.2X, RunEnable %2.2X Status %8.8X%8.8X Enable %8.8X%8.8X\n", - i, GpeRegisterInfo->EnableForWake, + " Reg %u: (GPE %.2X-%.2X) RunEnable %2.2X WakeEnable %2.2X" + " Status %8.8X%8.8X Enable %8.8X%8.8X\n", + i, GpeRegisterInfo->BaseGpeNumber, + GpeRegisterInfo->BaseGpeNumber + (ACPI_GPE_REGISTER_WIDTH - 1), GpeRegisterInfo->EnableForRun, + GpeRegisterInfo->EnableForWake, ACPI_FORMAT_UINT64 (GpeRegisterInfo->StatusAddress.Address), ACPI_FORMAT_UINT64 (GpeRegisterInfo->EnableAddress.Address)); @@ -886,17 +888,19 @@ AcpiDbDisplayGpes ( if (!(GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK)) { - /* This GPE is not used (no method or handler) */ + /* This GPE is not used (no method or handler), ignore it */ continue; } AcpiOsPrintf ( - " GPE %.3X: %p Flags %2.2X: ", - GpeBlock->BlockBaseNumber + GpeIndex, - GpeEventInfo, + " GPE %.2X: %p RunRefs %2.2X WakeRefs %2.2X Flags %2.2X (", + GpeBlock->BlockBaseNumber + GpeIndex, GpeEventInfo, + GpeEventInfo->RuntimeCount, GpeEventInfo->WakeupCount, GpeEventInfo->Flags); + /* Decode the flags byte */ + if (GpeEventInfo->Flags & ACPI_GPE_LEVEL_TRIGGERED) { AcpiOsPrintf ("Level, "); @@ -906,38 +910,13 @@ AcpiDbDisplayGpes ( AcpiOsPrintf ("Edge, "); } - switch (GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK) + if (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE) { - case ACPI_GPE_TYPE_WAKE: - AcpiOsPrintf ("WakeOnly: "); - break; - case ACPI_GPE_TYPE_RUNTIME: - AcpiOsPrintf (" RunOnly: "); - break; - case ACPI_GPE_TYPE_WAKE_RUN: - AcpiOsPrintf (" WakeRun: "); - break; - default: - AcpiOsPrintf (" NotUsed: "); - break; - } - - if (GpeEventInfo->Flags & ACPI_GPE_WAKE_ENABLED) - { - AcpiOsPrintf ("[Wake 1 "); + AcpiOsPrintf ("CanWake, "); } else { - AcpiOsPrintf ("[Wake 0 "); - } - - if (GpeEventInfo->Flags & ACPI_GPE_RUN_ENABLED) - { - AcpiOsPrintf ("Run 1], "); - } - else - { - AcpiOsPrintf ("Run 0], "); + AcpiOsPrintf ("RunOnly, "); } switch (GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) @@ -957,7 +936,7 @@ AcpiDbDisplayGpes ( break; } - AcpiOsPrintf ("\n"); + AcpiOsPrintf (")\n"); } } Block++; diff --git a/events/evgpe.c b/events/evgpe.c index 41efada245e6..d3569b188400 100644 --- a/events/evgpe.c +++ b/events/evgpe.c @@ -132,73 +132,22 @@ AcpiEvAsynchEnableGpe ( void *Context); -/******************************************************************************* - * - * FUNCTION: AcpiEvSetGpeType - * - * PARAMETERS: GpeEventInfo - GPE to set - * Type - New type - * - * RETURN: Status - * - * DESCRIPTION: Sets the new type for the GPE (wake, run, or wake/run) - * - ******************************************************************************/ - -ACPI_STATUS -AcpiEvSetGpeType ( - ACPI_GPE_EVENT_INFO *GpeEventInfo, - UINT8 Type) -{ - ACPI_STATUS Status; - - - ACPI_FUNCTION_TRACE (EvSetGpeType); - - - /* Validate type and update register enable masks */ - - switch (Type) - { - case ACPI_GPE_TYPE_WAKE: - case ACPI_GPE_TYPE_RUNTIME: - case ACPI_GPE_TYPE_WAKE_RUN: - break; - - default: - return_ACPI_STATUS (AE_BAD_PARAMETER); - } - - /* Disable the GPE if currently enabled */ - - Status = AcpiEvDisableGpe (GpeEventInfo); - - /* Clear the type bits and insert the new Type */ - - GpeEventInfo->Flags &= ~ACPI_GPE_TYPE_MASK; - GpeEventInfo->Flags |= Type; - return_ACPI_STATUS (Status); -} - - /******************************************************************************* * * FUNCTION: AcpiEvUpdateGpeEnableMasks * * PARAMETERS: GpeEventInfo - GPE to update - * Type - What to do: ACPI_GPE_DISABLE or - * ACPI_GPE_ENABLE * * RETURN: Status * - * DESCRIPTION: Updates GPE register enable masks based on the GPE type + * DESCRIPTION: Updates GPE register enable masks based upon whether there are + * references (either wake or run) to this GPE * ******************************************************************************/ ACPI_STATUS AcpiEvUpdateGpeEnableMasks ( - ACPI_GPE_EVENT_INFO *GpeEventInfo, - UINT8 Type) + ACPI_GPE_EVENT_INFO *GpeEventInfo) { ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; UINT8 RegisterBit; @@ -216,36 +165,21 @@ AcpiEvUpdateGpeEnableMasks ( RegisterBit = (UINT8) (1 << (GpeEventInfo->GpeNumber - GpeRegisterInfo->BaseGpeNumber)); - /* 1) Disable case. Simply clear all enable bits */ + /* Clear the wake/run bits up front */ - if (Type == ACPI_GPE_DISABLE) + ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, RegisterBit); + ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit); + + /* Set the mask bits only if there are references to this GPE */ + + if (GpeEventInfo->RuntimeCount) { - ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, RegisterBit); - ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit); - return_ACPI_STATUS (AE_OK); + ACPI_SET_BIT (GpeRegisterInfo->EnableForRun, RegisterBit); } - /* 2) Enable case. Set/Clear the appropriate enable bits */ - - switch (GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK) + if (GpeEventInfo->WakeupCount) { - case ACPI_GPE_TYPE_WAKE: - ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, RegisterBit); - ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit); - break; - - case ACPI_GPE_TYPE_RUNTIME: - ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, RegisterBit); - ACPI_SET_BIT (GpeRegisterInfo->EnableForRun, RegisterBit); - break; - - case ACPI_GPE_TYPE_WAKE_RUN: - ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, RegisterBit); - ACPI_SET_BIT (GpeRegisterInfo->EnableForRun, RegisterBit); - break; - - default: - return_ACPI_STATUS (AE_BAD_PARAMETER); + ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, RegisterBit); } return_ACPI_STATUS (AE_OK); @@ -257,19 +191,19 @@ AcpiEvUpdateGpeEnableMasks ( * FUNCTION: AcpiEvEnableGpe * * PARAMETERS: GpeEventInfo - GPE to enable - * WriteToHardware - Enable now, or just mark data structs - * (WAKE GPEs should be deferred) * * RETURN: Status * - * DESCRIPTION: Enable a GPE based on the GPE type + * DESCRIPTION: Hardware-enable a GPE. Always enables the GPE, regardless + * of type or number of references. + * + * Note: The GPE lock should be already acquired when this function is called. * ******************************************************************************/ ACPI_STATUS AcpiEvEnableGpe ( - ACPI_GPE_EVENT_INFO *GpeEventInfo, - BOOLEAN WriteToHardware) + ACPI_GPE_EVENT_INFO *GpeEventInfo) { ACPI_STATUS Status; @@ -277,54 +211,37 @@ AcpiEvEnableGpe ( ACPI_FUNCTION_TRACE (EvEnableGpe); - /* Make sure HW enable masks are updated */ + /* + * We will only allow a GPE to be enabled if it has either an + * associated method (_Lxx/_Exx) or a handler. Otherwise, the + * GPE will be immediately disabled by AcpiEvGpeDispatch the + * first time it fires. + */ + if (!(GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK)) + { + return_ACPI_STATUS (AE_NO_HANDLER); + } - Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo, ACPI_GPE_ENABLE); + /* Ensure the HW enable masks are current */ + + Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } - /* Mark wake-enabled or HW enable, or both */ + /* Clear the GPE (of stale events) */ - switch (GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK) + Status = AcpiHwClearGpe (GpeEventInfo); + if (ACPI_FAILURE (Status)) { - case ACPI_GPE_TYPE_WAKE: - - ACPI_SET_BIT (GpeEventInfo->Flags, ACPI_GPE_WAKE_ENABLED); - break; - - case ACPI_GPE_TYPE_WAKE_RUN: - - ACPI_SET_BIT (GpeEventInfo->Flags, ACPI_GPE_WAKE_ENABLED); - - /*lint -fallthrough */ - - case ACPI_GPE_TYPE_RUNTIME: - - ACPI_SET_BIT (GpeEventInfo->Flags, ACPI_GPE_RUN_ENABLED); - - if (WriteToHardware) - { - /* Clear the GPE (of stale events), then enable it */ - - Status = AcpiHwClearGpe (GpeEventInfo); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } - - /* Enable the requested runtime GPE */ - - Status = AcpiHwWriteGpeEnableReg (GpeEventInfo); - } - break; - - default: - return_ACPI_STATUS (AE_BAD_PARAMETER); + return_ACPI_STATUS (Status); } - return_ACPI_STATUS (AE_OK); + /* Enable the requested GPE */ + + Status = AcpiHwWriteGpeEnableReg (GpeEventInfo); + return_ACPI_STATUS (Status); } @@ -336,7 +253,10 @@ AcpiEvEnableGpe ( * * RETURN: Status * - * DESCRIPTION: Disable a GPE based on the GPE type + * DESCRIPTION: Hardware-disable a GPE. Always disables the requested GPE, + * regardless of the type or number of references. + * + * Note: The GPE lock should be already acquired when this function is called. * ******************************************************************************/ @@ -356,40 +276,14 @@ AcpiEvDisableGpe ( * the GPE behind our back. */ - /* Make sure HW enable masks are updated */ + /* Ensure the HW enable masks are current */ - Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo, ACPI_GPE_DISABLE); + Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } - /* Clear the appropriate enabled flags for this GPE */ - - switch (GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK) - { - case ACPI_GPE_TYPE_WAKE: - - ACPI_CLEAR_BIT (GpeEventInfo->Flags, ACPI_GPE_WAKE_ENABLED); - break; - - case ACPI_GPE_TYPE_WAKE_RUN: - - ACPI_CLEAR_BIT (GpeEventInfo->Flags, ACPI_GPE_WAKE_ENABLED); - - /*lint -fallthrough */ - - case ACPI_GPE_TYPE_RUNTIME: - - /* Disable the requested runtime GPE */ - - ACPI_CLEAR_BIT (GpeEventInfo->Flags, ACPI_GPE_RUN_ENABLED); - break; - - default: - break; - } - /* * Always H/W disable this GPE, even if we don't know the GPE type. * Simply clear the enable bit for this particular GPE, but do not @@ -403,6 +297,49 @@ AcpiEvDisableGpe ( } +/******************************************************************************* + * + * FUNCTION: AcpiEvLowGetGpeInfo + * + * PARAMETERS: GpeNumber - Raw GPE number + * GpeBlock - A GPE info block + * + * RETURN: A GPE EventInfo struct. NULL if not a valid GPE (The GpeNumber + * is not within the specified GPE block) + * + * DESCRIPTION: Returns the EventInfo struct associated with this GPE. This is + * the low-level implementation of EvGetGpeEventInfo. + * + ******************************************************************************/ + +ACPI_GPE_EVENT_INFO * +AcpiEvLowGetGpeInfo ( + UINT32 GpeNumber, + ACPI_GPE_BLOCK_INFO *GpeBlock) +{ + UINT32 GpeIndex; + + + /* + * Validate that the GpeNumber is within the specified GpeBlock. + * (Two steps) + */ + if (!GpeBlock || + (GpeNumber < GpeBlock->BlockBaseNumber)) + { + return (NULL); + } + + GpeIndex = GpeNumber - GpeBlock->BlockBaseNumber; + if (GpeIndex >= GpeBlock->GpeCount) + { + return (NULL); + } + + return (&GpeBlock->EventInfo[GpeIndex]); +} + + /******************************************************************************* * * FUNCTION: AcpiEvGetGpeEventInfo @@ -426,7 +363,7 @@ AcpiEvGetGpeEventInfo ( UINT32 GpeNumber) { ACPI_OPERAND_OBJECT *ObjDesc; - ACPI_GPE_BLOCK_INFO *GpeBlock; + ACPI_GPE_EVENT_INFO *GpeInfo; UINT32 i; @@ -441,16 +378,11 @@ AcpiEvGetGpeEventInfo ( for (i = 0; i < ACPI_MAX_GPE_BLOCKS; i++) { - GpeBlock = AcpiGbl_GpeFadtBlocks[i]; - if (GpeBlock) + GpeInfo = AcpiEvLowGetGpeInfo (GpeNumber, + AcpiGbl_GpeFadtBlocks[i]); + if (GpeInfo) { - if ((GpeNumber >= GpeBlock->BlockBaseNumber) && - (GpeNumber < GpeBlock->BlockBaseNumber + - (GpeBlock->RegisterCount * 8))) - { - return (&GpeBlock->EventInfo[GpeNumber - - GpeBlock->BlockBaseNumber]); - } + return (GpeInfo); } } @@ -468,15 +400,7 @@ AcpiEvGetGpeEventInfo ( return (NULL); } - GpeBlock = ObjDesc->Device.GpeBlock; - - if ((GpeNumber >= GpeBlock->BlockBaseNumber) && - (GpeNumber < GpeBlock->BlockBaseNumber + (GpeBlock->RegisterCount * 8))) - { - return (&GpeBlock->EventInfo[GpeNumber - GpeBlock->BlockBaseNumber]); - } - - return (NULL); + return (AcpiEvLowGetGpeInfo (GpeNumber, ObjDesc->Device.GpeBlock)); } @@ -654,9 +578,9 @@ AcpiEvAsynchExecuteGpeMethod ( return_VOID; } - /* Set the GPE flags for return to enabled state */ + /* Update the GPE register masks for return to enabled state */ - (void) AcpiEvEnableGpe (GpeEventInfo, FALSE); + (void) AcpiEvUpdateGpeEnableMasks (GpeEventInfo); /* * Take a snapshot of the GPE info for this level - we copy the info to @@ -872,15 +796,18 @@ AcpiEvGpeDispatch ( default: - /* No handler or method to run! */ - + /* + * No handler or method to run! + * 03/2010: This case should no longer be possible. We will not allow + * a GPE to be enabled if it has no handler or method. + */ ACPI_ERROR ((AE_INFO, "No handler or method for GPE[0x%2X], disabling event", GpeNumber)); /* - * Disable the GPE. The GPE will remain disabled until the ACPICA - * Core Subsystem is restarted, or a handler is installed. + * Disable the GPE. The GPE will remain disabled a handler + * is installed or ACPICA is restarted. */ Status = AcpiEvDisableGpe (GpeEventInfo); if (ACPI_FAILURE (Status)) diff --git a/events/evgpeblk.c b/events/evgpeblk.c index be6d45b5dc37..b109673ba8ee 100644 --- a/events/evgpeblk.c +++ b/events/evgpeblk.c @@ -124,7 +124,7 @@ /* Local prototypes */ static ACPI_STATUS -AcpiEvSaveMethodInfo ( +AcpiEvMatchGpeMethod ( ACPI_HANDLE ObjHandle, UINT32 Level, void *ObjDesc, @@ -194,8 +194,7 @@ AcpiEvValidGpeEvent ( while (GpeBlock) { if ((&GpeBlock->EventInfo[0] <= GpeEventInfo) && - (&GpeBlock->EventInfo[((ACPI_SIZE) - GpeBlock->RegisterCount) * 8] > GpeEventInfo)) + (&GpeBlock->EventInfo[GpeBlock->GpeCount] > GpeEventInfo)) { return (TRUE); } @@ -328,7 +327,7 @@ AcpiEvDeleteGpeHandlers ( /******************************************************************************* * - * FUNCTION: AcpiEvSaveMethodInfo + * FUNCTION: AcpiEvMatchGpeMethod * * PARAMETERS: Callback from WalkNamespace * @@ -340,8 +339,7 @@ AcpiEvDeleteGpeHandlers ( * information for quick lookup during GPE dispatch * * The name of each GPE control method is of the form: - * "_Lxx" or "_Exx" - * Where: + * "_Lxx" or "_Exx", where: * L - means that the GPE is level triggered * E - means that the GPE is edge triggered * xx - is the GPE number [in HEX] @@ -349,38 +347,44 @@ AcpiEvDeleteGpeHandlers ( ******************************************************************************/ static ACPI_STATUS -AcpiEvSaveMethodInfo ( +AcpiEvMatchGpeMethod ( ACPI_HANDLE ObjHandle, UINT32 Level, void *ObjDesc, void **ReturnValue) { + ACPI_NAMESPACE_NODE *MethodNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle); ACPI_GPE_BLOCK_INFO *GpeBlock = (void *) ObjDesc; ACPI_GPE_EVENT_INFO *GpeEventInfo; UINT32 GpeNumber; char Name[ACPI_NAME_SIZE + 1]; UINT8 Type; - ACPI_STATUS Status; - ACPI_FUNCTION_TRACE (EvSaveMethodInfo); + ACPI_FUNCTION_TRACE (EvMatchGpeMethod); /* - * _Lxx and _Exx GPE method support + * Match and decode the _Lxx and _Exx GPE method names * - * 1) Extract the name from the object and convert to a string + * 1) Extract the method name and null terminate it */ - ACPI_MOVE_32_TO_32 ( - Name, &((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Integer); + ACPI_MOVE_32_TO_32 (Name, &MethodNode->Name.Integer); Name[ACPI_NAME_SIZE] = 0; + /* 2) Name must begin with an underscore */ + + if (Name[0] != '_') + { + return_ACPI_STATUS (AE_OK); /* Ignore this method */ + } + /* - * 2) Edge/Level determination is based on the 2nd character + * 3) Edge/Level determination is based on the 2nd character * of the method name * - * NOTE: Default GPE type is RUNTIME. May be changed later to WAKE - * if a _PRW object is found that points to this GPE. + * NOTE: Default GPE type is RUNTIME only. Later, if a _PRW object is + * found that points to this GPE, the ACPI_GPE_CAN_WAKE flag is set. */ switch (Name[1]) { @@ -393,16 +397,15 @@ AcpiEvSaveMethodInfo ( break; default: - /* Unknown method type, just ignore it! */ + /* Unknown method type, just ignore it */ ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Ignoring unknown GPE method type: %s " - "(name not of form _Lxx or _Exx)", - Name)); + "(name not of form _Lxx or _Exx)", Name)); return_ACPI_STATUS (AE_OK); } - /* Convert the last two characters of the name to the GPE Number */ + /* 4) The last two characters of the name are the hex GPE Number */ GpeNumber = ACPI_STRTOUL (&Name[2], NULL, 16); if (GpeNumber == ACPI_UINT32_MAX) @@ -411,45 +414,34 @@ AcpiEvSaveMethodInfo ( ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Could not extract GPE number from name: %s " - "(name is not of form _Lxx or _Exx)", - Name)); + "(name is not of form _Lxx or _Exx)", Name)); return_ACPI_STATUS (AE_OK); } /* Ensure that we have a valid GPE number for this GPE block */ - if ((GpeNumber < GpeBlock->BlockBaseNumber) || - (GpeNumber >= (GpeBlock->BlockBaseNumber + - (GpeBlock->RegisterCount * 8)))) + GpeEventInfo = AcpiEvLowGetGpeInfo (GpeNumber, GpeBlock); + if (!GpeEventInfo) { /* - * Not valid for this GPE block, just ignore it. However, it may be - * valid for a different GPE block, since GPE0 and GPE1 methods both - * appear under \_GPE. + * This GpeNumber is not valid for this GPE block, just ignore it. + * However, it may be valid for a different GPE block, since GPE0 + * and GPE1 methods both appear under \_GPE. */ return_ACPI_STATUS (AE_OK); } /* - * Now we can add this information to the GpeEventInfo block for use - * during dispatch of this GPE. Default type is RUNTIME, although this may - * change when the _PRW methods are executed later. + * Add the GPE information from above to the GpeEventInfo block for + * use during dispatch of this GPE. */ - GpeEventInfo = &GpeBlock->EventInfo[GpeNumber - GpeBlock->BlockBaseNumber]; - - GpeEventInfo->Flags = (UINT8) - (Type | ACPI_GPE_DISPATCH_METHOD | ACPI_GPE_TYPE_RUNTIME); - - GpeEventInfo->Dispatch.MethodNode = (ACPI_NAMESPACE_NODE *) ObjHandle; - - /* Update enable mask, but don't enable the HW GPE as of yet */ - - Status = AcpiEvEnableGpe (GpeEventInfo, FALSE); + GpeEventInfo->Flags = (UINT8) (Type | ACPI_GPE_DISPATCH_METHOD); + GpeEventInfo->Dispatch.MethodNode = MethodNode; ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Registered GPE method %s as GPE number 0x%.2X\n", Name, GpeNumber)); - return_ACPI_STATUS (Status); + return_ACPI_STATUS (AE_OK); } @@ -464,7 +456,7 @@ AcpiEvSaveMethodInfo ( * * DESCRIPTION: Called from AcpiWalkNamespace. Expects each object to be a * Device. Run the _PRW method. If present, extract the GPE - * number and mark the GPE as a WAKE GPE. + * number and mark the GPE as a CAN_WAKE GPE. * ******************************************************************************/ @@ -495,7 +487,7 @@ AcpiEvMatchPrwAndGpe ( ACPI_BTYPE_PACKAGE, &PkgDesc); if (ACPI_FAILURE (Status)) { - /* Ignore all errors from _PRW, we don't want to abort the subsystem */ + /* Ignore all errors from _PRW, we don't want to abort the walk */ return_ACPI_STATUS (AE_OK); } @@ -561,25 +553,17 @@ AcpiEvMatchPrwAndGpe ( * 2) The GPE index(number) is within the range of the Gpe Block * associated with the GPE device. */ - if ((GpeDevice == TargetGpeDevice) && - (GpeNumber >= GpeBlock->BlockBaseNumber) && - (GpeNumber < GpeBlock->BlockBaseNumber + - (GpeBlock->RegisterCount * 8))) + if (GpeDevice != TargetGpeDevice) { - GpeEventInfo = &GpeBlock->EventInfo[GpeNumber - - GpeBlock->BlockBaseNumber]; + goto Cleanup; + } - /* Mark GPE for WAKE-ONLY but WAKE_DISABLED */ + GpeEventInfo = AcpiEvLowGetGpeInfo (GpeNumber, GpeBlock); + if (GpeEventInfo) + { + /* This GPE can wake the system */ - GpeEventInfo->Flags &= ~(ACPI_GPE_WAKE_ENABLED | ACPI_GPE_RUN_ENABLED); - - Status = AcpiEvSetGpeType (GpeEventInfo, ACPI_GPE_TYPE_WAKE); - if (ACPI_FAILURE (Status)) - { - goto Cleanup; - } - - Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo, ACPI_GPE_DISABLE); + GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE; } Cleanup: @@ -880,7 +864,7 @@ AcpiEvDeleteGpeBlock ( AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); } - AcpiCurrentGpeCount -= GpeBlock->RegisterCount * ACPI_GPE_REGISTER_WIDTH; + AcpiCurrentGpeCount -= GpeBlock->GpeCount; /* Free the GpeBlock */ @@ -925,8 +909,8 @@ AcpiEvCreateGpeInfoBlocks ( /* Allocate the GPE register information block */ GpeRegisterInfo = ACPI_ALLOCATE_ZEROED ( - (ACPI_SIZE) GpeBlock->RegisterCount * - sizeof (ACPI_GPE_REGISTER_INFO)); + (ACPI_SIZE) GpeBlock->RegisterCount * + sizeof (ACPI_GPE_REGISTER_INFO)); if (!GpeRegisterInfo) { ACPI_ERROR ((AE_INFO, @@ -938,10 +922,8 @@ AcpiEvCreateGpeInfoBlocks ( * Allocate the GPE EventInfo block. There are eight distinct GPEs * per register. Initialization to zeros is sufficient. */ - GpeEventInfo = ACPI_ALLOCATE_ZEROED ( - ((ACPI_SIZE) GpeBlock->RegisterCount * - ACPI_GPE_REGISTER_WIDTH) * - sizeof (ACPI_GPE_EVENT_INFO)); + GpeEventInfo = ACPI_ALLOCATE_ZEROED ((ACPI_SIZE) GpeBlock->GpeCount * + sizeof (ACPI_GPE_EVENT_INFO)); if (!GpeEventInfo) { ACPI_ERROR ((AE_INFO, @@ -1080,6 +1062,7 @@ AcpiEvCreateGpeBlock ( /* Initialize the new GPE block */ GpeBlock->Node = GpeDevice; + GpeBlock->GpeCount = (UINT16) (RegisterCount * ACPI_GPE_REGISTER_WIDTH); GpeBlock->RegisterCount = RegisterCount; GpeBlock->BlockBaseNumber = GpeBlockBaseNumber; @@ -1110,7 +1093,7 @@ AcpiEvCreateGpeBlock ( Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD, GpeDevice, ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, - AcpiEvSaveMethodInfo, NULL, GpeBlock, NULL); + AcpiEvMatchGpeMethod, NULL, GpeBlock, NULL); /* Return the new block */ @@ -1122,15 +1105,13 @@ AcpiEvCreateGpeBlock ( ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n", (UINT32) GpeBlock->BlockBaseNumber, - (UINT32) (GpeBlock->BlockBaseNumber + - ((GpeBlock->RegisterCount * ACPI_GPE_REGISTER_WIDTH) -1)), - GpeDevice->Name.Ascii, - GpeBlock->RegisterCount, + (UINT32) (GpeBlock->BlockBaseNumber + (GpeBlock->GpeCount - 1)), + GpeDevice->Name.Ascii, GpeBlock->RegisterCount, InterruptNumber)); /* Update global count of currently available GPEs */ - AcpiCurrentGpeCount += RegisterCount * ACPI_GPE_REGISTER_WIDTH; + AcpiCurrentGpeCount += GpeBlock->GpeCount; return_ACPI_STATUS (AE_OK); } @@ -1161,6 +1142,8 @@ AcpiEvInitializeGpeBlock ( ACPI_GPE_WALK_INFO GpeInfo; UINT32 WakeGpeCount; UINT32 GpeEnabledCount; + UINT32 GpeIndex; + UINT32 GpeNumber; UINT32 i; UINT32 j; @@ -1193,39 +1176,65 @@ AcpiEvInitializeGpeBlock ( Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, AcpiEvMatchPrwAndGpe, NULL, &GpeInfo, NULL); + if (ACPI_FAILURE (Status)) + { + ACPI_EXCEPTION ((AE_INFO, Status, "While executing _PRW methods")); + } } /* - * Enable all GPEs in this block that have these attributes: - * 1) are "runtime" or "run/wake" GPEs, and - * 2) have a corresponding _Lxx or _Exx method - * - * Any other GPEs within this block must be enabled via the - * AcpiEnableGpe() external interface. + * Enable all GPEs that have a corresponding method and are not + * capable of generating wakeups. Any other GPEs within this block + * must be enabled via the AcpiEnableGpe interface. */ WakeGpeCount = 0; GpeEnabledCount = 0; + if (GpeDevice == AcpiGbl_FadtGpeDevice) + { + GpeDevice = NULL; + } + for (i = 0; i < GpeBlock->RegisterCount; i++) { - for (j = 0; j < 8; j++) + for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { /* Get the info block for this particular GPE */ - GpeEventInfo = &GpeBlock->EventInfo[((ACPI_SIZE) i * - ACPI_GPE_REGISTER_WIDTH) + j]; + GpeIndex = (i * ACPI_GPE_REGISTER_WIDTH) + j; + GpeEventInfo = &GpeBlock->EventInfo[GpeIndex]; - if (((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == - ACPI_GPE_DISPATCH_METHOD) && - (GpeEventInfo->Flags & ACPI_GPE_TYPE_RUNTIME)) - { - GpeEnabledCount++; - } + /* Ignore GPEs that can wake the system */ - if (GpeEventInfo->Flags & ACPI_GPE_TYPE_WAKE) + if (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE) { WakeGpeCount++; + if (AcpiGbl_LeaveWakeGpesDisabled) + { + continue; + } } + + /* Ignore GPEs that have no corresponding _Lxx/_Exx method */ + + if (!(GpeEventInfo->Flags & ACPI_GPE_DISPATCH_METHOD)) + { + continue; + } + + /* Enable this GPE */ + + GpeNumber = GpeIndex + GpeBlock->BlockBaseNumber; + Status = AcpiEnableGpe (GpeDevice, GpeNumber, + ACPI_GPE_TYPE_RUNTIME); + if (ACPI_FAILURE (Status)) + { + ACPI_EXCEPTION ((AE_INFO, Status, + "Could not enable GPE 0x%02X", GpeNumber)); + continue; + } + + GpeEnabledCount++; } } @@ -1233,16 +1242,7 @@ AcpiEvInitializeGpeBlock ( "Found %u Wake, Enabled %u Runtime GPEs in this block\n", WakeGpeCount, GpeEnabledCount)); - /* Enable all valid runtime GPEs found above */ - - Status = AcpiHwEnableRuntimeGpeBlock (NULL, GpeBlock, NULL); - if (ACPI_FAILURE (Status)) - { - ACPI_ERROR ((AE_INFO, "Could not enable GPEs in GpeBlock %p", - GpeBlock)); - } - - return_ACPI_STATUS (Status); + return_ACPI_STATUS (AE_OK); } diff --git a/events/evxface.c b/events/evxface.c index 051e5bf4a7f8..567eba444770 100644 --- a/events/evxface.c +++ b/events/evxface.c @@ -705,7 +705,7 @@ AcpiInstallGpeHandler ( /* Parameter validation */ - if ((!Address) || (Type > ACPI_GPE_XRUPT_TYPE_MASK)) + if ((!Address) || (Type & ~ACPI_GPE_XRUPT_TYPE_MASK)) { return_ACPI_STATUS (AE_BAD_PARAMETER); } diff --git a/events/evxfevnt.c b/events/evxfevnt.c index 886096153c72..9f2906311b7e 100644 --- a/events/evxfevnt.c +++ b/events/evxfevnt.c @@ -305,70 +305,20 @@ AcpiEnableEvent ( ACPI_EXPORT_SYMBOL (AcpiEnableEvent) -/******************************************************************************* - * - * FUNCTION: AcpiSetGpeType - * - * PARAMETERS: GpeDevice - Parent GPE Device - * GpeNumber - GPE level within the GPE block - * Type - New GPE type - * - * RETURN: Status - * - * DESCRIPTION: Set the type of an individual GPE - * - ******************************************************************************/ - -ACPI_STATUS -AcpiSetGpeType ( - ACPI_HANDLE GpeDevice, - UINT32 GpeNumber, - UINT8 Type) -{ - ACPI_STATUS Status = AE_OK; - ACPI_GPE_EVENT_INFO *GpeEventInfo; - - - ACPI_FUNCTION_TRACE (AcpiSetGpeType); - - - /* Ensure that we have a valid GPE number */ - - GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); - if (!GpeEventInfo) - { - Status = AE_BAD_PARAMETER; - goto UnlockAndExit; - } - - if ((GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK) == Type) - { - return_ACPI_STATUS (AE_OK); - } - - /* Set the new type (will disable GPE if currently enabled) */ - - Status = AcpiEvSetGpeType (GpeEventInfo, Type); - -UnlockAndExit: - return_ACPI_STATUS (Status); -} - -ACPI_EXPORT_SYMBOL (AcpiSetGpeType) - - /******************************************************************************* * * FUNCTION: AcpiEnableGpe * - * PARAMETERS: GpeDevice - Parent GPE Device + * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 * GpeNumber - GPE level within the GPE block - * Flags - Just enable, or also wake enable? - * Called from ISR or not + * GpeType - ACPI_GPE_TYPE_RUNTIME or ACPI_GPE_TYPE_WAKE + * or both * * RETURN: Status * - * DESCRIPTION: Enable an ACPI event (general purpose) + * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is + * hardware-enabled (for runtime GPEs), or the GPE register mask + * is updated (for wake GPEs). * ******************************************************************************/ @@ -376,26 +326,25 @@ ACPI_STATUS AcpiEnableGpe ( ACPI_HANDLE GpeDevice, UINT32 GpeNumber, - UINT32 Flags) + UINT8 GpeType) { ACPI_STATUS Status = AE_OK; ACPI_GPE_EVENT_INFO *GpeEventInfo; + ACPI_CPU_FLAGS Flags; ACPI_FUNCTION_TRACE (AcpiEnableGpe); - /* Use semaphore lock if not executing at interrupt level */ + /* Parameter validation */ - if (Flags & ACPI_NOT_ISR) + if (!GpeType || (GpeType & ~ACPI_GPE_TYPE_WAKE_RUN)) { - Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } + return_ACPI_STATUS (AE_BAD_PARAMETER); } + Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); + /* Ensure that we have a valid GPE number */ GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); @@ -405,15 +354,55 @@ AcpiEnableGpe ( goto UnlockAndExit; } - /* Perform the enable */ + if (GpeType & ACPI_GPE_TYPE_RUNTIME) + { + if (GpeEventInfo->RuntimeCount == ACPI_UINT8_MAX) + { + Status = AE_LIMIT; /* Too many references */ + goto UnlockAndExit; + } - Status = AcpiEvEnableGpe (GpeEventInfo, TRUE); + GpeEventInfo->RuntimeCount++; + if (GpeEventInfo->RuntimeCount == 1) + { + Status = AcpiEvEnableGpe (GpeEventInfo); + if (ACPI_FAILURE (Status)) + { + GpeEventInfo->RuntimeCount--; + goto UnlockAndExit; + } + } + } + + if (GpeType & ACPI_GPE_TYPE_WAKE) + { + /* The GPE must have the ability to wake the system */ + + if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)) + { + Status = AE_TYPE; + goto UnlockAndExit; + } + + if (GpeEventInfo->WakeupCount == ACPI_UINT8_MAX) + { + Status = AE_LIMIT; /* Too many references */ + goto UnlockAndExit; + } + + /* + * Update the enable mask on the first wakeup reference. Wake GPEs + * are only hardware-enabled just before sleeping. + */ + GpeEventInfo->WakeupCount++; + if (GpeEventInfo->WakeupCount == 1) + { + (void) AcpiEvUpdateGpeEnableMasks (GpeEventInfo); + } + } UnlockAndExit: - if (Flags & ACPI_NOT_ISR) - { - (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); - } + AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); return_ACPI_STATUS (Status); } @@ -424,14 +413,16 @@ ACPI_EXPORT_SYMBOL (AcpiEnableGpe) * * FUNCTION: AcpiDisableGpe * - * PARAMETERS: GpeDevice - Parent GPE Device + * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 * GpeNumber - GPE level within the GPE block - * Flags - Just disable, or also wake disable? - * Called from ISR or not + * GpeType - ACPI_GPE_TYPE_RUNTIME or ACPI_GPE_TYPE_WAKE + * or both * * RETURN: Status * - * DESCRIPTION: Disable an ACPI event (general purpose) + * DESCRIPTION: Remove a reference to a GPE. When the last reference is + * removed, only then is the GPE disabled (for runtime GPEs), or + * the GPE mask bit disabled (for wake GPEs) * ******************************************************************************/ @@ -439,26 +430,25 @@ ACPI_STATUS AcpiDisableGpe ( ACPI_HANDLE GpeDevice, UINT32 GpeNumber, - UINT32 Flags) + UINT8 GpeType) { ACPI_STATUS Status = AE_OK; ACPI_GPE_EVENT_INFO *GpeEventInfo; + ACPI_CPU_FLAGS Flags; ACPI_FUNCTION_TRACE (AcpiDisableGpe); - /* Use semaphore lock if not executing at interrupt level */ + /* Parameter validation */ - if (Flags & ACPI_NOT_ISR) + if (!GpeType || (GpeType & ~ACPI_GPE_TYPE_WAKE_RUN)) { - Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } + return_ACPI_STATUS (AE_BAD_PARAMETER); } + Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); + /* Ensure that we have a valid GPE number */ GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); @@ -468,19 +458,127 @@ AcpiDisableGpe ( goto UnlockAndExit; } - Status = AcpiEvDisableGpe (GpeEventInfo); + /* Hardware-disable a runtime GPE on removal of the last reference */ + + if (GpeType & ACPI_GPE_TYPE_RUNTIME) + { + if (!GpeEventInfo->RuntimeCount) + { + Status = AE_LIMIT; /* There are no references to remove */ + goto UnlockAndExit; + } + + GpeEventInfo->RuntimeCount--; + if (!GpeEventInfo->RuntimeCount) + { + Status = AcpiEvDisableGpe (GpeEventInfo); + if (ACPI_FAILURE (Status)) + { + GpeEventInfo->RuntimeCount++; + goto UnlockAndExit; + } + } + } + + /* + * Update masks for wake GPE on removal of the last reference. + * No need to hardware-disable wake GPEs here, they are not currently + * enabled. + */ + if (GpeType & ACPI_GPE_TYPE_WAKE) + { + if (!GpeEventInfo->WakeupCount) + { + Status = AE_LIMIT; /* There are no references to remove */ + goto UnlockAndExit; + } + + GpeEventInfo->WakeupCount--; + if (!GpeEventInfo->WakeupCount) + { + (void) AcpiEvUpdateGpeEnableMasks (GpeEventInfo); + } + } + UnlockAndExit: - if (Flags & ACPI_NOT_ISR) - { - (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); - } + AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); return_ACPI_STATUS (Status); } ACPI_EXPORT_SYMBOL (AcpiDisableGpe) +/******************************************************************************* + * + * FUNCTION: AcpiSetGpe + * + * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 + * GpeNumber - GPE level within the GPE block + * Action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE + * + * RETURN: Status + * + * DESCRIPTION: Enable or disable an individual GPE. This function bypasses + * the reference count mechanism used in the AcpiEnableGpe and + * AcpiDisableGpe interfaces -- and should be used with care. + * + * Note: Typically used to disable a runtime GPE for short period of time, + * then re-enable it, without disturbing the existing reference counts. This + * is useful, for example, in the Embedded Controller (EC) driver. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiSetGpe ( + ACPI_HANDLE GpeDevice, + UINT32 GpeNumber, + UINT8 Action) +{ + ACPI_GPE_EVENT_INFO *GpeEventInfo; + ACPI_STATUS Status; + ACPI_CPU_FLAGS Flags; + + + ACPI_FUNCTION_TRACE (AcpiSetGpe); + + + Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); + + /* Ensure that we have a valid GPE number */ + + GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); + if (!GpeEventInfo) + { + Status = AE_BAD_PARAMETER; + goto UnlockAndExit; + } + + /* Perform the action */ + + switch (Action) + { + case ACPI_GPE_ENABLE: + Status = AcpiEvEnableGpe (GpeEventInfo); + break; + + case ACPI_GPE_DISABLE: + Status = AcpiEvDisableGpe (GpeEventInfo); + break; + + default: + Status = AE_BAD_PARAMETER; + break; + } + +UnlockAndExit: + AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); + return_ACPI_STATUS (Status); +} + +ACPI_EXPORT_SYMBOL (AcpiSetGpe) + + /******************************************************************************* * * FUNCTION: AcpiDisableEvent @@ -592,9 +690,8 @@ ACPI_EXPORT_SYMBOL (AcpiClearEvent) * * FUNCTION: AcpiClearGpe * - * PARAMETERS: GpeDevice - Parent GPE Device + * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 * GpeNumber - GPE level within the GPE block - * Flags - Called from an ISR or not * * RETURN: Status * @@ -605,26 +702,17 @@ ACPI_EXPORT_SYMBOL (AcpiClearEvent) ACPI_STATUS AcpiClearGpe ( ACPI_HANDLE GpeDevice, - UINT32 GpeNumber, - UINT32 Flags) + UINT32 GpeNumber) { ACPI_STATUS Status = AE_OK; ACPI_GPE_EVENT_INFO *GpeEventInfo; + ACPI_CPU_FLAGS Flags; ACPI_FUNCTION_TRACE (AcpiClearGpe); - /* Use semaphore lock if not executing at interrupt level */ - - if (Flags & ACPI_NOT_ISR) - { - Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } - } + Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); /* Ensure that we have a valid GPE number */ @@ -638,10 +726,7 @@ AcpiClearGpe ( Status = AcpiHwClearGpe (GpeEventInfo); UnlockAndExit: - if (Flags & ACPI_NOT_ISR) - { - (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); - } + AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); return_ACPI_STATUS (Status); } @@ -700,9 +785,8 @@ ACPI_EXPORT_SYMBOL (AcpiGetEventStatus) * * FUNCTION: AcpiGetGpeStatus * - * PARAMETERS: GpeDevice - Parent GPE Device + * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 * GpeNumber - GPE level within the GPE block - * Flags - Called from an ISR or not * EventStatus - Where the current status of the event will * be returned * @@ -716,26 +800,17 @@ ACPI_STATUS AcpiGetGpeStatus ( ACPI_HANDLE GpeDevice, UINT32 GpeNumber, - UINT32 Flags, ACPI_EVENT_STATUS *EventStatus) { ACPI_STATUS Status = AE_OK; ACPI_GPE_EVENT_INFO *GpeEventInfo; + ACPI_CPU_FLAGS Flags; ACPI_FUNCTION_TRACE (AcpiGetGpeStatus); - /* Use semaphore lock if not executing at interrupt level */ - - if (Flags & ACPI_NOT_ISR) - { - Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } - } + Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); /* Ensure that we have a valid GPE number */ @@ -751,10 +826,7 @@ AcpiGetGpeStatus ( Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus); UnlockAndExit: - if (Flags & ACPI_NOT_ISR) - { - (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); - } + AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); return_ACPI_STATUS (Status); } @@ -823,21 +895,15 @@ AcpiInstallGpeBlock ( goto UnlockAndExit; } - /* Run the _PRW methods and enable the GPEs */ - - Status = AcpiEvInitializeGpeBlock (Node, GpeBlock); - if (ACPI_FAILURE (Status)) - { - goto UnlockAndExit; - } - - /* Get the DeviceObject attached to the node */ + /* Install block in the DeviceObject attached to the node */ ObjDesc = AcpiNsGetAttachedObject (Node); if (!ObjDesc) { - /* No object, create a new one */ - + /* + * No object, create a new one (Device nodes do not always have + * an attached object) + */ ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE); if (!ObjDesc) { @@ -850,17 +916,20 @@ AcpiInstallGpeBlock ( /* Remove local reference to the object */ AcpiUtRemoveReference (ObjDesc); - if (ACPI_FAILURE (Status)) { goto UnlockAndExit; } } - /* Install the GPE block in the DeviceObject */ + /* Now install the GPE block in the DeviceObject */ ObjDesc->Device.GpeBlock = GpeBlock; + /* Run the _PRW methods and enable the runtime GPEs in the new block */ + + Status = AcpiEvInitializeGpeBlock (Node, GpeBlock); + UnlockAndExit: (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); @@ -1018,8 +1087,7 @@ AcpiEvGetGpeDevice ( /* Increment Index by the number of GPEs in this block */ - Info->NextBlockBaseIndex += - (GpeBlock->RegisterCount * ACPI_GPE_REGISTER_WIDTH); + Info->NextBlockBaseIndex += GpeBlock->GpeCount; if (Info->Index < Info->NextBlockBaseIndex) { diff --git a/executer/exdebug.c b/executer/exdebug.c index bef4f24a2086..7347c71f1d71 100644 --- a/executer/exdebug.c +++ b/executer/exdebug.c @@ -235,7 +235,7 @@ AcpiExDoDebugObject ( AcpiOsPrintf ("[0x%.2X]\n", (UINT32) SourceDesc->Buffer.Length); AcpiUtDumpBuffer2 (SourceDesc->Buffer.Pointer, - (SourceDesc->Buffer.Length < 256) ? + (SourceDesc->Buffer.Length < 256) ? SourceDesc->Buffer.Length : 256, DB_BYTE_DISPLAY); break; diff --git a/executer/exmutex.c b/executer/exmutex.c index 172db6392de6..e9646ca77d92 100644 --- a/executer/exmutex.c +++ b/executer/exmutex.c @@ -168,10 +168,10 @@ AcpiExUnlinkMutex ( (ObjDesc->Mutex.Prev)->Mutex.Next = ObjDesc->Mutex.Next; /* - * Migrate the previous sync level associated with this mutex to the - * previous mutex on the list so that it may be preserved. This handles - * the case where several mutexes have been acquired at the same level, - * but are not released in opposite order. + * Migrate the previous sync level associated with this mutex to + * the previous mutex on the list so that it may be preserved. + * This handles the case where several mutexes have been acquired + * at the same level, but are not released in opposite order. */ (ObjDesc->Mutex.Prev)->Mutex.OriginalSyncLevel = ObjDesc->Mutex.OriginalSyncLevel; @@ -187,8 +187,8 @@ AcpiExUnlinkMutex ( * * FUNCTION: AcpiExLinkMutex * - * PARAMETERS: ObjDesc - The mutex to be linked - * Thread - Current executing thread object + * PARAMETERS: ObjDesc - The mutex to be linked + * Thread - Current executing thread object * * RETURN: None * @@ -228,9 +228,9 @@ AcpiExLinkMutex ( * * FUNCTION: AcpiExAcquireMutexObject * - * PARAMETERS: TimeDesc - Timeout in milliseconds + * PARAMETERS: Timeout - Timeout in milliseconds * ObjDesc - Mutex object - * Thread - Current thread state + * ThreadId - Current thread state * * RETURN: Status * @@ -337,11 +337,12 @@ AcpiExAcquireMutex ( return_ACPI_STATUS (AE_BAD_PARAMETER); } - /* Must have a valid thread ID */ + /* Must have a valid thread state struct */ if (!WalkState->Thread) { - ACPI_ERROR ((AE_INFO, "Cannot acquire Mutex [%4.4s], null thread info", + ACPI_ERROR ((AE_INFO, + "Cannot acquire Mutex [%4.4s], null thread info", AcpiUtGetNodeName (ObjDesc->Mutex.Node))); return_ACPI_STATUS (AE_AML_INTERNAL); } @@ -488,7 +489,8 @@ AcpiExReleaseMutex ( if (!OwnerThread) { - ACPI_ERROR ((AE_INFO, "Cannot release Mutex [%4.4s], not acquired", + ACPI_ERROR ((AE_INFO, + "Cannot release Mutex [%4.4s], not acquired", AcpiUtGetNodeName (ObjDesc->Mutex.Node))); return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED); } @@ -497,7 +499,8 @@ AcpiExReleaseMutex ( if (!WalkState->Thread) { - ACPI_ERROR ((AE_INFO, "Cannot release Mutex [%4.4s], null thread info", + ACPI_ERROR ((AE_INFO, + "Cannot release Mutex [%4.4s], null thread info", AcpiUtGetNodeName (ObjDesc->Mutex.Node))); return_ACPI_STATUS (AE_AML_INTERNAL); } @@ -553,6 +556,7 @@ AcpiExReleaseMutex ( OwnerThread->CurrentSyncLevel = PreviousSyncLevel; } + return_ACPI_STATUS (Status); } @@ -561,7 +565,7 @@ AcpiExReleaseMutex ( * * FUNCTION: AcpiExReleaseAllMutexes * - * PARAMETERS: Thread - Current executing thread object + * PARAMETERS: Thread - Current executing thread object * * RETURN: Status * @@ -620,5 +624,3 @@ AcpiExReleaseAllMutexes ( Thread->CurrentSyncLevel = ObjDesc->Mutex.OriginalSyncLevel; } } - - diff --git a/executer/exoparg2.c b/executer/exoparg2.c index d71c91020434..6df45ea8abac 100644 --- a/executer/exoparg2.c +++ b/executer/exoparg2.c @@ -206,33 +206,6 @@ AcpiExOpcode_2A_0T_0R ( break; } -#ifdef ACPI_GPE_NOTIFY_CHECK - /* - * GPE method wake/notify check. Here, we want to ensure that we - * don't receive any "DeviceWake" Notifies from a GPE _Lxx or _Exx - * GPE method during system runtime. If we do, the GPE is marked - * as "wake-only" and disabled. - * - * 1) Is the Notify() value == DeviceWake? - * 2) Is this a GPE deferred method? (An _Lxx or _Exx method) - * 3) Did the original GPE happen at system runtime? - * (versus during wake) - * - * If all three cases are true, this is a wake-only GPE that should - * be disabled at runtime. - */ - if (Value == 2) /* DeviceWake */ - { - Status = AcpiEvCheckForWakeOnlyGpe (WalkState->GpeEventInfo); - if (ACPI_FAILURE (Status)) - { - /* AE_WAKE_ONLY_GPE only error, means ignore this notify */ - - return_ACPI_STATUS (AE_OK) - } - } -#endif - /* * Dispatch the notify to the appropriate handler * NOTE: the request is queued for execution after this method diff --git a/executer/exregion.c b/executer/exregion.c index efe83ebc83c3..2ac8a0e93e05 100644 --- a/executer/exregion.c +++ b/executer/exregion.c @@ -608,8 +608,10 @@ AcpiExDataTableSpaceHandler ( ACPI_FUNCTION_TRACE (ExDataTableSpaceHandler); - /* Perform the memory read or write */ - + /* + * Perform the memory read or write. The BitWidth was already + * validated. + */ switch (Function) { case ACPI_READ: @@ -619,9 +621,14 @@ AcpiExDataTableSpaceHandler ( break; case ACPI_WRITE: + + ACPI_MEMCPY (ACPI_PHYSADDR_TO_PTR (Address), ACPI_CAST_PTR (char, Value), + ACPI_DIV_8 (BitWidth)); + break; + default: - return_ACPI_STATUS (AE_SUPPORT); + return_ACPI_STATUS (AE_BAD_PARAMETER); } return_ACPI_STATUS (AE_OK); diff --git a/include/acevents.h b/include/acevents.h index 567ac1ec0e13..4d945eff8aad 100644 --- a/include/acevents.h +++ b/include/acevents.h @@ -171,13 +171,11 @@ AcpiEvQueueNotifyRequest ( */ ACPI_STATUS AcpiEvUpdateGpeEnableMasks ( - ACPI_GPE_EVENT_INFO *GpeEventInfo, - UINT8 Type); + ACPI_GPE_EVENT_INFO *GpeEventInfo); ACPI_STATUS AcpiEvEnableGpe ( - ACPI_GPE_EVENT_INFO *GpeEventInfo, - BOOLEAN WriteToHardware); + ACPI_GPE_EVENT_INFO *GpeEventInfo); ACPI_STATUS AcpiEvDisableGpe ( @@ -188,6 +186,11 @@ AcpiEvGetGpeEventInfo ( ACPI_HANDLE GpeDevice, UINT32 GpeNumber); +ACPI_GPE_EVENT_INFO * +AcpiEvLowGetGpeInfo ( + UINT32 GpeNumber, + ACPI_GPE_BLOCK_INFO *GpeBlock); + /* * evgpeblk @@ -234,15 +237,6 @@ UINT32 AcpiEvGpeDetect ( ACPI_GPE_XRUPT_INFO *GpeXruptList); -ACPI_STATUS -AcpiEvSetGpeType ( - ACPI_GPE_EVENT_INFO *GpeEventInfo, - UINT8 Type); - -ACPI_STATUS -AcpiEvCheckForWakeOnlyGpe ( - ACPI_GPE_EVENT_INFO *GpeEventInfo); - ACPI_STATUS AcpiEvGpeInitialize ( void); diff --git a/include/acexcep.h b/include/acexcep.h index 89fe5c66898f..a46de7d82f5e 100644 --- a/include/acexcep.h +++ b/include/acexcep.h @@ -162,7 +162,7 @@ #define AE_NO_GLOBAL_LOCK (ACPI_STATUS) (0x0017 | AE_CODE_ENVIRONMENTAL) #define AE_ABORT_METHOD (ACPI_STATUS) (0x0018 | AE_CODE_ENVIRONMENTAL) #define AE_SAME_HANDLER (ACPI_STATUS) (0x0019 | AE_CODE_ENVIRONMENTAL) -#define AE_WAKE_ONLY_GPE (ACPI_STATUS) (0x001A | AE_CODE_ENVIRONMENTAL) +#define AE_NO_HANDLER (ACPI_STATUS) (0x001A | AE_CODE_ENVIRONMENTAL) #define AE_OWNER_ID_LIMIT (ACPI_STATUS) (0x001B | AE_CODE_ENVIRONMENTAL) #define AE_CODE_ENV_MAX 0x001B diff --git a/include/acglobal.h b/include/acglobal.h index 0df0c2719ecf..4f0769e6f676 100644 --- a/include/acglobal.h +++ b/include/acglobal.h @@ -191,6 +191,14 @@ UINT8 ACPI_INIT_GLOBAL (AcpiGbl_UseDefaultRegisterWidths, TRUE); */ UINT8 ACPI_INIT_GLOBAL (AcpiGbl_EnableAmlDebugObject, FALSE); +/* + * Optionally copy the entire DSDT to local memory (instead of simply + * mapping it.) There are some BIOSs that corrupt or replace the original + * DSDT, creating the need for this option. Default is FALSE, do not copy + * the DSDT. + */ +UINT8 ACPI_INIT_GLOBAL (AcpiGbl_CopyDsdtLocally, FALSE); + /* AcpiGbl_FADT is a local copy of the FADT, converted to a common format. */ @@ -223,6 +231,11 @@ ACPI_EXTERN ACPI_GENERIC_ADDRESS AcpiGbl_XPm1aEnable; ACPI_EXTERN ACPI_GENERIC_ADDRESS AcpiGbl_XPm1bStatus; ACPI_EXTERN ACPI_GENERIC_ADDRESS AcpiGbl_XPm1bEnable; +/* DSDT information. Used to check for DSDT corruption */ + +ACPI_EXTERN ACPI_TABLE_HEADER *AcpiGbl_DSDT; +ACPI_EXTERN ACPI_TABLE_HEADER AcpiGbl_OriginalDsdtHeader; + /* * Handle both ACPI 1.0 and ACPI 2.0 Integer widths. The integer width is * determined by the revision of the DSDT: If the DSDT revision is less than diff --git a/include/aclocal.h b/include/aclocal.h index 0aeacff6c525..8818a6ea9b53 100644 --- a/include/aclocal.h +++ b/include/aclocal.h @@ -561,6 +561,8 @@ typedef struct acpi_gpe_event_info struct acpi_gpe_register_info *RegisterInfo; /* Backpointer to register info */ UINT8 Flags; /* Misc info about this GPE */ UINT8 GpeNumber; /* This GPE */ + UINT8 RuntimeCount; /* References to a run GPE */ + UINT8 WakeupCount; /* References to a wake GPE */ } ACPI_GPE_EVENT_INFO; @@ -590,6 +592,7 @@ typedef struct acpi_gpe_block_info ACPI_GPE_EVENT_INFO *EventInfo; /* One for each GPE */ ACPI_GENERIC_ADDRESS BlockAddress; /* Base address of the block */ UINT32 RegisterCount; /* Number of register pairs in block */ + UINT16 GpeCount; /* Number of individual GPEs in block */ UINT8 BlockBaseNumber;/* Base GPE number for this block */ } ACPI_GPE_BLOCK_INFO; diff --git a/include/acpixf.h b/include/acpixf.h index 220350afc807..300b2c73f5fe 100644 --- a/include/acpixf.h +++ b/include/acpixf.h @@ -120,7 +120,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20100304 +#define ACPI_CA_VERSION 0x20100331 #include "actypes.h" #include "actbl.h" @@ -146,6 +146,7 @@ extern UINT8 AcpiGbl_UseDefaultRegisterWidths; extern ACPI_NAME AcpiGbl_TraceMethodName; extern UINT32 AcpiGbl_TraceFlags; extern UINT8 AcpiGbl_EnableAmlDebugObject; +extern UINT8 AcpiGbl_CopyDsdtLocally; /* @@ -463,34 +464,32 @@ AcpiGetEventStatus ( * GPE Interfaces */ ACPI_STATUS -AcpiSetGpeType ( +AcpiSetGpe ( ACPI_HANDLE GpeDevice, UINT32 GpeNumber, - UINT8 Type); + UINT8 Action); ACPI_STATUS AcpiEnableGpe ( ACPI_HANDLE GpeDevice, UINT32 GpeNumber, - UINT32 Flags); + UINT8 GpeType); ACPI_STATUS AcpiDisableGpe ( ACPI_HANDLE GpeDevice, UINT32 GpeNumber, - UINT32 Flags); + UINT8 GpeType); ACPI_STATUS AcpiClearGpe ( ACPI_HANDLE GpeDevice, - UINT32 GpeNumber, - UINT32 Flags); + UINT32 GpeNumber); ACPI_STATUS AcpiGetGpeStatus ( ACPI_HANDLE GpeDevice, UINT32 GpeNumber, - UINT32 Flags, ACPI_EVENT_STATUS *EventStatus); ACPI_STATUS diff --git a/include/actables.h b/include/actables.h index 54fdaae9b1a7..9f1c4f00e5a8 100644 --- a/include/actables.h +++ b/include/actables.h @@ -230,6 +230,14 @@ AcpiTbVerifyChecksum ( ACPI_TABLE_HEADER *Table, UINT32 Length); +void +AcpiTbCheckDsdtHeader ( + void); + +ACPI_TABLE_HEADER * +AcpiTbCopyDsdt ( + UINT32 TableIndex); + void AcpiTbInstallTable ( ACPI_PHYSICAL_ADDRESS Address, diff --git a/include/actypes.h b/include/actypes.h index 8d0d06ad62ce..3c0626ab1e35 100644 --- a/include/actypes.h +++ b/include/actypes.h @@ -742,53 +742,42 @@ typedef UINT32 ACPI_EVENT_STATUS; #define ACPI_GPE_MAX 0xFF #define ACPI_NUM_GPE 256 +/* Actions for AcpiSetGpe */ + #define ACPI_GPE_ENABLE 0 #define ACPI_GPE_DISABLE 1 +/* GpeTypes for AcpiEnableGpe and AcpiDisableGpe */ + +#define ACPI_GPE_TYPE_WAKE (UINT8) 0x01 +#define ACPI_GPE_TYPE_RUNTIME (UINT8) 0x02 +#define ACPI_GPE_TYPE_WAKE_RUN (UINT8) 0x03 /* * GPE info flags - Per GPE - * +-+-+-+---+---+-+ - * |7|6|5|4:3|2:1|0| - * +-+-+-+---+---+-+ - * | | | | | | - * | | | | | +--- Interrupt type: Edge or Level Triggered - * | | | | +--- Type: Wake-only, Runtime-only, or wake/runtime - * | | | +--- Type of dispatch -- to method, handler, or none - * | | +--- Enabled for runtime? - * | +--- Enabled for wake? - * +--- Unused + * +-------+---+-+-+ + * | 7:4 |3:2|1|0| + * +-------+---+-+-+ + * | | | | + * | | | +--- Interrupt type: edge or level triggered + * | | +----- GPE can wake the system + * | +-------- Type of dispatch:to method, handler, or none + * +-------------- */ #define ACPI_GPE_XRUPT_TYPE_MASK (UINT8) 0x01 #define ACPI_GPE_LEVEL_TRIGGERED (UINT8) 0x01 #define ACPI_GPE_EDGE_TRIGGERED (UINT8) 0x00 -#define ACPI_GPE_TYPE_MASK (UINT8) 0x06 -#define ACPI_GPE_TYPE_WAKE_RUN (UINT8) 0x06 -#define ACPI_GPE_TYPE_WAKE (UINT8) 0x02 -#define ACPI_GPE_TYPE_RUNTIME (UINT8) 0x04 /* Default */ +#define ACPI_GPE_CAN_WAKE (UINT8) 0x02 -#define ACPI_GPE_DISPATCH_MASK (UINT8) 0x18 -#define ACPI_GPE_DISPATCH_HANDLER (UINT8) 0x08 -#define ACPI_GPE_DISPATCH_METHOD (UINT8) 0x10 -#define ACPI_GPE_DISPATCH_NOT_USED (UINT8) 0x00 /* Default */ - -#define ACPI_GPE_RUN_ENABLE_MASK (UINT8) 0x20 -#define ACPI_GPE_RUN_ENABLED (UINT8) 0x20 -#define ACPI_GPE_RUN_DISABLED (UINT8) 0x00 /* Default */ - -#define ACPI_GPE_WAKE_ENABLE_MASK (UINT8) 0x40 -#define ACPI_GPE_WAKE_ENABLED (UINT8) 0x40 -#define ACPI_GPE_WAKE_DISABLED (UINT8) 0x00 /* Default */ - -#define ACPI_GPE_ENABLE_MASK (UINT8) 0x60 /* Both run/wake */ +#define ACPI_GPE_DISPATCH_MASK (UINT8) 0x0C +#define ACPI_GPE_DISPATCH_HANDLER (UINT8) 0x04 +#define ACPI_GPE_DISPATCH_METHOD (UINT8) 0x08 +#define ACPI_GPE_DISPATCH_NOT_USED (UINT8) 0x00 /* * Flags for GPE and Lock interfaces */ -#define ACPI_EVENT_WAKE_ENABLE 0x2 /* AcpiGpeEnable */ -#define ACPI_EVENT_WAKE_DISABLE 0x2 /* AcpiGpeDisable */ - #define ACPI_NOT_ISR 0x1 #define ACPI_ISR 0x0 diff --git a/include/platform/acfreebsd.h b/include/platform/acfreebsd.h index 09ad54ae1b25..6e0e3b5c31b0 100644 --- a/include/platform/acfreebsd.h +++ b/include/platform/acfreebsd.h @@ -114,7 +114,7 @@ *****************************************************************************/ #ifndef __ACFREEBSD_H__ -#define __ACFREEBSD_H__ +#define __ACFREEBSD_H__ /* FreeBSD uses GCC */ @@ -123,12 +123,10 @@ #include #include -#define ACPI_UINTPTR_T uintptr_t - -#define ACPI_USE_LOCAL_CACHE -#define ACPI_USE_SYSTEM_CLIBRARY - -#define __cdecl +#define ACPI_UINTPTR_T uintptr_t +#define ACPI_USE_LOCAL_CACHE +#define ACPI_USE_SYSTEM_CLIBRARY +#define __cdecl #ifdef _KERNEL @@ -140,17 +138,17 @@ #include "opt_acpi.h" -#define ACPI_THREAD_ID lwpid_t +#define ACPI_THREAD_ID lwpid_t #ifdef ACPI_DEBUG -#define ACPI_DEBUG_OUTPUT /* for backward compatibility */ -#define ACPI_DISASSEMBLER +#define ACPI_DEBUG_OUTPUT /* for backward compatibility */ +#define ACPI_DISASSEMBLER #endif #ifdef ACPI_DEBUG_OUTPUT #include "opt_ddb.h" #ifdef DDB -#define ACPI_DEBUGGER +#define ACPI_DEBUGGER #endif /* DDB */ #endif /* ACPI_DEBUG_OUTPUT */ @@ -158,7 +156,7 @@ #undef DEBUGGER_THREADING #endif /* DEBUGGER_THREADING */ -#define DEBUGGER_THREADING 0 /* integrated with DDB */ +#define DEBUGGER_THREADING 0 /* integrated with DDB */ #else /* _KERNEL */ @@ -166,14 +164,13 @@ #include #endif -#define ACPI_THREAD_ID pthread_t +#define ACPI_THREAD_ID pthread_t /* Not building kernel code, so use libc */ -#define ACPI_USE_STANDARD_HEADERS -#define ACPI_FLUSH_CPU_CACHE() - -#define __cli() -#define __sti() +#define ACPI_USE_STANDARD_HEADERS +#define ACPI_FLUSH_CPU_CACHE() +#define __cli() +#define __sti() #endif /* _KERNEL */ diff --git a/os_specific/service_layers/oswintbl.c b/os_specific/service_layers/oswintbl.c index 30d7ba66b9c7..db609ee99d12 100644 --- a/os_specific/service_layers/oswintbl.c +++ b/os_specific/service_layers/oswintbl.c @@ -132,6 +132,22 @@ static char KeyBuffer[64]; +static char ErrorBuffer[64]; + + +/* Little front-end to win FormatMessage */ + +char * +OsFormatException ( + LONG Status) +{ + + ErrorBuffer[0] = 0; + FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, Status, 0, + ErrorBuffer, 64, NULL); + + return (ErrorBuffer); +} /****************************************************************************** @@ -169,7 +185,7 @@ OsGetTable ( ACPI_STRCAT (KeyBuffer, Signature); Status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, KeyBuffer, - 0L, KEY_ALL_ACCESS, &Handle); + 0L, KEY_READ, &Handle); if (Status != ERROR_SUCCESS) { @@ -187,8 +203,9 @@ OsGetTable ( } else { - AcpiOsPrintf ("Could not find %s in registry at %s\n", - Signature, KeyBuffer); + AcpiOsPrintf ( + "Could not find %s in registry at %s: %s (Status=0x%X)\n", + Signature, KeyBuffer, OsFormatException (Status), Status); return (NULL); } } @@ -212,7 +229,8 @@ OsGetTable ( Status = RegOpenKey (Handle, KeyBuffer, &SubKey); if (Status != ERROR_SUCCESS) { - AcpiOsPrintf ("Could not open %s entry\n", Signature); + AcpiOsPrintf ("Could not open %s entry: %s\n", + Signature, OsFormatException (Status)); return (NULL); } @@ -230,7 +248,8 @@ OsGetTable ( NULL, &Type, NULL, 0); if (Status != ERROR_SUCCESS) { - AcpiOsPrintf ("Could not get %s registry entry\n", Signature); + AcpiOsPrintf ("Could not get %s registry entry: %s\n", + Signature, OsFormatException (Status)); return (NULL); } @@ -246,7 +265,8 @@ OsGetTable ( Status = RegQueryValueEx (Handle, KeyBuffer, NULL, NULL, NULL, &DataSize); if (Status != ERROR_SUCCESS) { - AcpiOsPrintf ("Could not read the %s table size\n", Signature); + AcpiOsPrintf ("Could not read the %s table size: %s\n", + Signature, OsFormatException (Status)); return (NULL); } @@ -264,7 +284,8 @@ OsGetTable ( (UCHAR *) ReturnTable, &DataSize); if (Status != ERROR_SUCCESS) { - AcpiOsPrintf ("Could not read %s data\n", Signature); + AcpiOsPrintf ("Could not read %s data: %s\n", + Signature, OsFormatException (Status)); AcpiOsFree (ReturnTable); return (NULL); } diff --git a/os_specific/service_layers/oswinxf.c b/os_specific/service_layers/oswinxf.c index 3e441968e099..0f117772eaa6 100644 --- a/os_specific/service_layers/oswinxf.c +++ b/os_specific/service_layers/oswinxf.c @@ -336,7 +336,7 @@ AcpiOsTableOverride ( *NewTable = OsGetTable (TableName); if (*NewTable) { - AcpiOsPrintf ("Table %s obtained from registry, %d bytes\n", + AcpiOsPrintf ("Table [%s] obtained from registry, %d bytes\n", TableName, (*NewTable)->Length); } else @@ -1415,7 +1415,7 @@ AcpiOsSignal ( * FUNCTION: Local cache interfaces * * DESCRIPTION: Implements cache interfaces via malloc/free for testing - * purposes only. + * purposes only. * *****************************************************************************/ @@ -1470,7 +1470,7 @@ AcpiOsAcquireObject ( NewObject = malloc (((ACPI_MEMORY_LIST *) Cache)->ObjectSize); memset (NewObject, 0, ((ACPI_MEMORY_LIST *) Cache)->ObjectSize); - + return (NewObject); } diff --git a/parser/psxface.c b/parser/psxface.c index b34d9859afc9..6cc5f413b989 100644 --- a/parser/psxface.c +++ b/parser/psxface.c @@ -120,6 +120,7 @@ #include "acparser.h" #include "acdispat.h" #include "acinterp.h" +#include "actables.h" #include "amlcode.h" @@ -334,6 +335,10 @@ AcpiPsExecuteMethod ( ACPI_FUNCTION_TRACE (PsExecuteMethod); + /* Quick validation of DSDT header */ + + AcpiTbCheckDsdtHeader (); + /* Validate the Info and method Node */ if (!Info || !Info->ResolvedNode) diff --git a/tables/tbutils.c b/tables/tbutils.c index a496556f43e3..eb8bc43597d0 100644 --- a/tables/tbutils.c +++ b/tables/tbutils.c @@ -393,6 +393,88 @@ AcpiTbChecksum ( } +/******************************************************************************* + * + * FUNCTION: AcpiTbCheckDsdtHeader + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Quick compare to check validity of the DSDT. This will detect + * if the DSDT has been replaced from outside the OS and/or if + * the DSDT header has been corrupted. + * + ******************************************************************************/ + +void +AcpiTbCheckDsdtHeader ( + void) +{ + + /* Compare original length and checksum to current values */ + + if (AcpiGbl_OriginalDsdtHeader.Length != AcpiGbl_DSDT->Length || + AcpiGbl_OriginalDsdtHeader.Checksum != AcpiGbl_DSDT->Checksum) + { + ACPI_ERROR ((AE_INFO, + "The DSDT has been corrupted or replaced - old, new headers below")); + AcpiTbPrintTableHeader (0, &AcpiGbl_OriginalDsdtHeader); + AcpiTbPrintTableHeader (0, AcpiGbl_DSDT); + + /* Disable further error messages */ + + AcpiGbl_OriginalDsdtHeader.Length = AcpiGbl_DSDT->Length; + AcpiGbl_OriginalDsdtHeader.Checksum = AcpiGbl_DSDT->Checksum; + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbCopyDsdt + * + * PARAMETERS: TableDesc - Installed table to copy + * + * RETURN: None + * + * DESCRIPTION: Implements a subsystem option to copy the DSDT to local memory. + * Some very bad BIOSs are known to either corrupt the DSDT or + * install a new, bad DSDT. This copy works around the problem. + * + ******************************************************************************/ + +ACPI_TABLE_HEADER * +AcpiTbCopyDsdt ( + UINT32 TableIndex) +{ + ACPI_TABLE_HEADER *NewTable; + ACPI_TABLE_DESC *TableDesc; + + + TableDesc = &AcpiGbl_RootTableList.Tables[TableIndex]; + + NewTable = ACPI_ALLOCATE (TableDesc->Length); + if (!NewTable) + { + ACPI_ERROR ((AE_INFO, "Could not copy DSDT of length 0x%X", + TableDesc->Length)); + return (NULL); + } + + ACPI_MEMCPY (NewTable, TableDesc->Pointer, TableDesc->Length); + AcpiTbDeleteTable (TableDesc); + TableDesc->Pointer = NewTable; + TableDesc->Flags = ACPI_TABLE_ORIGIN_ALLOCATED; + + ACPI_INFO ((AE_INFO, + "Forced DSDT copy: length 0x%05X copied locally, original unmapped", + NewTable->Length)); + + return (NewTable); +} + + /******************************************************************************* * * FUNCTION: AcpiTbInstallTable diff --git a/tables/tbxface.c b/tables/tbxface.c index 6a4f413d04c5..8cbf15ac8d4e 100644 --- a/tables/tbxface.c +++ b/tables/tbxface.c @@ -265,6 +265,7 @@ AcpiReallocateRootTable ( { ACPI_TABLE_DESC *Tables; ACPI_SIZE NewSize; + ACPI_SIZE CurrentSize; ACPI_FUNCTION_TRACE (AcpiReallocateRootTable); @@ -279,9 +280,15 @@ AcpiReallocateRootTable ( return_ACPI_STATUS (AE_SUPPORT); } - NewSize = ((ACPI_SIZE) AcpiGbl_RootTableList.Count + - ACPI_ROOT_TABLE_SIZE_INCREMENT) * - sizeof (ACPI_TABLE_DESC); + /* + * Get the current size of the root table and add the default + * increment to create the new table size. + */ + CurrentSize = (ACPI_SIZE) + AcpiGbl_RootTableList.Count * sizeof (ACPI_TABLE_DESC); + + NewSize = CurrentSize + + (ACPI_ROOT_TABLE_SIZE_INCREMENT * sizeof (ACPI_TABLE_DESC)); /* Create new array and copy the old array */ @@ -291,10 +298,12 @@ AcpiReallocateRootTable ( return_ACPI_STATUS (AE_NO_MEMORY); } - ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables, NewSize); + ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables, CurrentSize); + + /* Update the root table descriptor */ - AcpiGbl_RootTableList.Size = AcpiGbl_RootTableList.Count; AcpiGbl_RootTableList.Tables = Tables; + AcpiGbl_RootTableList.Size += ACPI_ROOT_TABLE_SIZE_INCREMENT; AcpiGbl_RootTableList.Flags = ACPI_ROOT_ORIGIN_ALLOCATED | ACPI_ROOT_ALLOW_RESIZE; @@ -534,6 +543,7 @@ AcpiTbLoadNamespace ( { ACPI_STATUS Status; UINT32 i; + ACPI_TABLE_HEADER *NewDsdt; ACPI_FUNCTION_TRACE (TbLoadNamespace); @@ -542,30 +552,47 @@ AcpiTbLoadNamespace ( (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); /* - * Load the namespace. The DSDT is required, but any SSDT and PSDT tables - * are optional. + * Save the DSDT pointer for simple access. This is the mapped memory + * address. We must take care here because the address of the .Tables + * array can change dynamically as tables are loaded at run-time + */ + AcpiGbl_DSDT = AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Pointer; + + /* + * Load the namespace. The DSDT is required, but any SSDT and + * PSDT tables are optional. Verify the DSDT. */ if (!AcpiGbl_RootTableList.Count || - !ACPI_COMPARE_NAME ( - &(AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Signature), - ACPI_SIG_DSDT) || - ACPI_FAILURE (AcpiTbVerifyTable ( + !ACPI_COMPARE_NAME (AcpiGbl_DSDT->Signature, ACPI_SIG_DSDT) || + ACPI_FAILURE (AcpiTbVerifyTable ( &AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT]))) { Status = AE_NO_ACPI_TABLES; goto UnlockAndExit; } - /* A valid DSDT is required */ - - Status = AcpiTbVerifyTable ( - &AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT]); - if (ACPI_FAILURE (Status)) + /* + * Optionally copy the entire DSDT to local memory (instead of simply + * mapping it.) There are some BIOSs that corrupt or replace the original + * DSDT, creating the need for this option. Default is FALSE, do not copy + * the DSDT. + */ + if (AcpiGbl_CopyDsdtLocally) { - Status = AE_NO_ACPI_TABLES; - goto UnlockAndExit; + NewDsdt = AcpiTbCopyDsdt (ACPI_TABLE_INDEX_DSDT); + if (NewDsdt) + { + AcpiGbl_DSDT = NewDsdt; + } } + /* + * Save the original DSDT header for detection of table corruption + * and/or replacement of the DSDT from outside the OS. + */ + ACPI_MEMCPY (&AcpiGbl_OriginalDsdtHeader, AcpiGbl_DSDT, + sizeof (ACPI_TABLE_HEADER)); + (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); /* Load and parse tables */ diff --git a/tools/acpiexec/aeexec.c b/tools/acpiexec/aeexec.c index 06dbddbb1591..9aec80d95869 100644 --- a/tools/acpiexec/aeexec.c +++ b/tools/acpiexec/aeexec.c @@ -204,7 +204,8 @@ AeSetupConfiguration ( * * RETURN: None * - * DESCRIPTION: Various GPE initialization + * DESCRIPTION: Test GPE block device initialization. Requires test ASL with + * A \GPE2 device. * *****************************************************************************/ @@ -226,23 +227,18 @@ AfInstallGpeBlock ( return; } - BlockAddress.SpaceId = 0; + ACPI_MEMSET (&BlockAddress, 0, sizeof (ACPI_GENERIC_ADDRESS)); + BlockAddress.SpaceId = ACPI_ADR_SPACE_SYSTEM_MEMORY; BlockAddress.Address = 0x76540000; -#ifdef _OBSOLETE - Status = AcpiInstallGpeBlock (Handle, &BlockAddress, 4, 8); -#endif - - /* Above should fail, ignore */ - Status = AcpiGetHandle (NULL, "\\GPE2", &Handle2); if (ACPI_SUCCESS (Status)) { - Status = AcpiInstallGpeBlock (Handle2, &BlockAddress, 8, 8); + Status = AcpiInstallGpeBlock (Handle2, &BlockAddress, 7, 8); + Status = AcpiInstallGpeBlock (Handle2, &BlockAddress, 2, 0); AcpiInstallGpeHandler (Handle2, 8, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); - AcpiSetGpeType (Handle2, 8, ACPI_GPE_TYPE_WAKE); - AcpiEnableGpe (Handle2, 8, 0); + AcpiEnableGpe (Handle2, 8, ACPI_GPE_TYPE_RUNTIME); Status = AcpiGetGpeDevice (0x30, &GpeDevice); Status = AcpiGetGpeDevice (0x42, &GpeDevice); @@ -250,8 +246,6 @@ AfInstallGpeBlock ( Status = AcpiGetGpeDevice (AcpiCurrentGpeCount, &GpeDevice); AcpiRemoveGpeHandler (Handle2, 8, AeGpeHandler); - - Status = AcpiRemoveGpeBlock (Handle2); } Status = AcpiGetHandle (NULL, "\\GPE3", &Handle3); @@ -259,12 +253,6 @@ AfInstallGpeBlock ( { Status = AcpiInstallGpeBlock (Handle3, &BlockAddress, 8, 11); } - -#ifdef _OBSOLETE - Status = AcpiRemoveGpeBlock (Handle); - Status = AcpiRemoveGpeBlock (Handle2); - Status = AcpiRemoveGpeBlock (Handle3); -#endif } @@ -540,35 +528,34 @@ AeMiscellaneousTests ( AcpiGetName (AcpiGbl_RootNode, ACPI_FULL_PATHNAME, &ReturnBuf); AcpiEnableEvent (ACPI_EVENT_GLOBAL, 0); + /* + * GPEs: Handlers, enable/disable, etc. + */ AcpiInstallGpeHandler (NULL, 0, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); - AcpiSetGpeType (NULL, 0, ACPI_GPE_TYPE_WAKE_RUN); - AcpiEnableGpe (NULL, 0, ACPI_NOT_ISR); + AcpiEnableGpe (NULL, 0, ACPI_GPE_TYPE_RUNTIME); AcpiRemoveGpeHandler (NULL, 0, AeGpeHandler); AcpiInstallGpeHandler (NULL, 0, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); - AcpiSetGpeType (NULL, 0, ACPI_GPE_TYPE_WAKE_RUN); - AcpiEnableGpe (NULL, 0, ACPI_NOT_ISR); + AcpiEnableGpe (NULL, 0, ACPI_GPE_TYPE_RUNTIME); + AcpiSetGpe (NULL, 0, ACPI_GPE_DISABLE); + AcpiSetGpe (NULL, 0, ACPI_GPE_ENABLE); AcpiInstallGpeHandler (NULL, 1, ACPI_GPE_EDGE_TRIGGERED, AeGpeHandler, NULL); - AcpiSetGpeType (NULL, 1, ACPI_GPE_TYPE_RUNTIME); - AcpiEnableGpe (NULL, 1, ACPI_NOT_ISR); + AcpiEnableGpe (NULL, 1, ACPI_GPE_TYPE_RUNTIME); AcpiInstallGpeHandler (NULL, 2, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); - AcpiSetGpeType (NULL, 2, ACPI_GPE_TYPE_WAKE); - AcpiEnableGpe (NULL, 2, ACPI_NOT_ISR); + AcpiEnableGpe (NULL, 2, ACPI_GPE_TYPE_RUNTIME); AcpiInstallGpeHandler (NULL, 3, ACPI_GPE_EDGE_TRIGGERED, AeGpeHandler, NULL); - AcpiSetGpeType (NULL, 3, ACPI_GPE_TYPE_WAKE_RUN); - AcpiInstallGpeHandler (NULL, 4, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); - AcpiSetGpeType (NULL, 4, ACPI_GPE_TYPE_RUNTIME); - AcpiInstallGpeHandler (NULL, 5, ACPI_GPE_EDGE_TRIGGERED, AeGpeHandler, NULL); - AcpiSetGpeType (NULL, 5, ACPI_GPE_TYPE_WAKE); AcpiInstallGpeHandler (NULL, 0x19, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); - AcpiSetGpeType (NULL, 0x19, ACPI_GPE_TYPE_WAKE_RUN); - AcpiEnableGpe (NULL, 0x19, ACPI_NOT_ISR); + AcpiEnableGpe (NULL, 0x19, ACPI_GPE_TYPE_RUNTIME); + + AcpiInstallGpeHandler (NULL, 0x62, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); + AcpiEnableGpe (NULL, 0x62, ACPI_GPE_TYPE_RUNTIME); + AcpiDisableGpe (NULL, 0x62, ACPI_GPE_TYPE_RUNTIME); AfInstallGpeBlock (); diff --git a/utilities/utglobal.c b/utilities/utglobal.c index 236d811714cd..986dbeb58d82 100644 --- a/utilities/utglobal.c +++ b/utilities/utglobal.c @@ -916,6 +916,7 @@ AcpiUtInitGlobals ( /* Miscellaneous variables */ + AcpiGbl_DSDT = NULL; AcpiGbl_CmSingleStep = FALSE; AcpiGbl_DbTerminateThreads = FALSE; AcpiGbl_Shutdown = FALSE;