aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJung-uk Kim <jkim@FreeBSD.org>2010-04-02 16:48:51 +0000
committerJung-uk Kim <jkim@FreeBSD.org>2010-04-02 16:48:51 +0000
commitb9ee7222924c1df653ed09d1b5befac3c98aa3f5 (patch)
treea128dad9042628a002a14e4ba0a4f5a98c9db600
parent6e5c66621e4fd1bac329fef86cb2c60491b539a9 (diff)
downloadsrc-b9ee7222924c1df653ed09d1b5befac3c98aa3f5.tar.gz
src-b9ee7222924c1df653ed09d1b5befac3c98aa3f5.zip
Import ACPICA 20100331.vendor/acpica/20100331
Notes
Notes: svn path=/vendor-sys/acpica/dist/; revision=206104 svn path=/vendor-sys/acpica/20100331/; revision=206105; tag=vendor/acpica/20100331
-rw-r--r--changes.txt75
-rw-r--r--common/dmextern.c9
-rw-r--r--compiler/aslanalyze.c6
-rw-r--r--compiler/aslcompiler.h5
-rw-r--r--compiler/aslpredef.c109
-rw-r--r--compiler/aslstubs.c7
-rw-r--r--compiler/asltypes.h2
-rw-r--r--debugger/dbdisply.c59
-rw-r--r--events/evgpe.c279
-rw-r--r--events/evgpeblk.c196
-rw-r--r--events/evxface.c2
-rw-r--r--events/evxfevnt.c282
-rw-r--r--executer/exdebug.c2
-rw-r--r--executer/exmutex.c32
-rw-r--r--executer/exoparg2.c27
-rw-r--r--executer/exregion.c13
-rw-r--r--include/acevents.h20
-rw-r--r--include/acexcep.h2
-rw-r--r--include/acglobal.h13
-rw-r--r--include/aclocal.h3
-rw-r--r--include/acpixf.h15
-rw-r--r--include/actables.h8
-rw-r--r--include/actypes.h51
-rw-r--r--include/platform/acfreebsd.h33
-rw-r--r--os_specific/service_layers/oswintbl.c35
-rw-r--r--os_specific/service_layers/oswinxf.c6
-rw-r--r--parser/psxface.c5
-rw-r--r--tables/tbutils.c82
-rw-r--r--tables/tbxface.c63
-rw-r--r--tools/acpiexec/aeexec.c55
-rw-r--r--utilities/utglobal.c1
31 files changed, 880 insertions, 617 deletions
diff --git a/changes.txt b/changes.txt
index 5bd82ab6949a..d2c8c0e41edf 100644
--- a/changes.txt
+++ b/changes.txt
@@ -1,4 +1,79 @@
----------------------------------------
+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:
1) ACPI CA Core Subsystem:
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
@@ -1157,6 +1157,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);
@@ -308,6 +312,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
*
* PARAMETERS: Op - A parse node
@@ -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 @@ TypeErrorExit:
/* 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)
- {
- 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 ");
- }
- else
- {
- AcpiOsPrintf ("[Wake 0 ");
- }
-
- if (GpeEventInfo->Flags & ACPI_GPE_RUN_ENABLED)
+ if (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)
{
- AcpiOsPrintf ("Run 1], ");
+ AcpiOsPrintf ("CanWake, ");
}
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
@@ -134,71 +134,20 @@ AcpiEvAsynchEnableGpe (
/*******************************************************************************
*
- * 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);
- return_ACPI_STATUS (AE_OK);
- }
+ ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
+ ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
- /* 2) Enable case. Set/Clear the appropriate enable bits */
+ /* Set the mask bits only if there are references to this GPE */
- switch (GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK)
+ if (GpeEventInfo->RuntimeCount)
{
- 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;
+ ACPI_SET_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
+ }
- default:
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ if (GpeEventInfo->WakeupCount)
+ {
+ 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);
+ }
+
+ /* Ensure the HW enable masks are current */
- Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo, ACPI_GPE_ENABLE);
+ 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
@@ -405,6 +299,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
*
* PARAMETERS: GpeDevice - Device node. NULL for GPE0/GPE1
@@ -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];
-
- /* Mark GPE for WAKE-ONLY but WAKE_DISABLED */
-
- GpeEventInfo->Flags &= ~(ACPI_GPE_WAKE_ENABLED | ACPI_GPE_RUN_ENABLED);
+ goto Cleanup;
+ }
- Status = AcpiEvSetGpeType (GpeEventInfo, ACPI_GPE_TYPE_WAKE);
- if (ACPI_FAILURE (Status))
- {
- goto Cleanup;
- }
+ GpeEventInfo = AcpiEvLowGetGpeInfo (GpeNumber, GpeBlock);
+ if (GpeEventInfo)
+ {
+ /* This GPE can wake the system */
- 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];
+
+ /* Ignore GPEs that can wake the system */
- if (((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
- ACPI_GPE_DISPATCH_METHOD) &&
- (GpeEventInfo->Flags & ACPI_GPE_TYPE_RUNTIME))
+ if (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)
{
- GpeEnabledCount++;
+ WakeGpeCount++;
+ if (AcpiGbl_LeaveWakeGpesDisabled)
+ {
+ continue;
+ }
}
- if (GpeEventInfo->Flags & ACPI_GPE_TYPE_WAKE)
+ /* Ignore GPEs that have no corresponding _Lxx/_Exx method */
+
+ if (!(GpeEventInfo->Flags & ACPI_GPE_DISPATCH_METHOD))
{
- WakeGpeCount++;
+ 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
@@ -307,30 +307,43 @@ ACPI_EXPORT_SYMBOL (AcpiEnableEvent)
/*******************************************************************************
*
- * FUNCTION: AcpiSetGpeType
+ * FUNCTION: AcpiEnableGpe
*
- * PARAMETERS: GpeDevice - Parent GPE Device
+ * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
* GpeNumber - GPE level within the GPE block
- * Type - New GPE type
+ * GpeType - ACPI_GPE_TYPE_RUNTIME or ACPI_GPE_TYPE_WAKE
+ * or both
*
* RETURN: Status
*
- * DESCRIPTION: Set the type of an individual GPE
+ * 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).
*
******************************************************************************/
ACPI_STATUS
-AcpiSetGpeType (
+AcpiEnableGpe (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber,
- UINT8 Type)
+ UINT8 GpeType)
{
ACPI_STATUS Status = AE_OK;
ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_CPU_FLAGS Flags;
+
+
+ ACPI_FUNCTION_TRACE (AcpiEnableGpe);
+
+ /* Parameter validation */
- ACPI_FUNCTION_TRACE (AcpiSetGpeType);
+ if (!GpeType || (GpeType & ~ACPI_GPE_TYPE_WAKE_RUN))
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+ Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
/* Ensure that we have a valid GPE number */
@@ -341,61 +354,101 @@ AcpiSetGpeType (
goto UnlockAndExit;
}
- if ((GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK) == Type)
+ if (GpeType & ACPI_GPE_TYPE_RUNTIME)
{
- return_ACPI_STATUS (AE_OK);
+ if (GpeEventInfo->RuntimeCount == ACPI_UINT8_MAX)
+ {
+ Status = AE_LIMIT; /* Too many references */
+ goto UnlockAndExit;
+ }
+
+ GpeEventInfo->RuntimeCount++;
+ if (GpeEventInfo->RuntimeCount == 1)
+ {
+ Status = AcpiEvEnableGpe (GpeEventInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ GpeEventInfo->RuntimeCount--;
+ goto UnlockAndExit;
+ }
+ }
}
- /* Set the new type (will disable GPE if currently enabled) */
+ if (GpeType & ACPI_GPE_TYPE_WAKE)
+ {
+ /* The GPE must have the ability to wake the system */
- Status = AcpiEvSetGpeType (GpeEventInfo, Type);
+ 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:
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
return_ACPI_STATUS (Status);
}
-ACPI_EXPORT_SYMBOL (AcpiSetGpeType)
+ACPI_EXPORT_SYMBOL (AcpiEnableGpe)
/*******************************************************************************
*
- * FUNCTION: 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 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: 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)
*
******************************************************************************/
ACPI_STATUS
-AcpiEnableGpe (
+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 (AcpiEnableGpe);
+ 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);
@@ -405,59 +458,92 @@ AcpiEnableGpe (
goto UnlockAndExit;
}
- /* Perform the enable */
+ /* 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;
+ }
- Status = AcpiEvEnableGpe (GpeEventInfo, TRUE);
+ GpeEventInfo->RuntimeCount--;
+ if (!GpeEventInfo->RuntimeCount)
+ {
+ Status = AcpiEvDisableGpe (GpeEventInfo);
+ if (ACPI_FAILURE (Status))
+ {
+ GpeEventInfo->RuntimeCount++;
+ goto UnlockAndExit;
+ }
+ }
+ }
-UnlockAndExit:
- if (Flags & ACPI_NOT_ISR)
+ /*
+ * 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)
{
- (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+ if (!GpeEventInfo->WakeupCount)
+ {
+ Status = AE_LIMIT; /* There are no references to remove */
+ goto UnlockAndExit;
+ }
+
+ GpeEventInfo->WakeupCount--;
+ if (!GpeEventInfo->WakeupCount)
+ {
+ (void) AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
+ }
}
+
+
+UnlockAndExit:
+ AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
return_ACPI_STATUS (Status);
}
-ACPI_EXPORT_SYMBOL (AcpiEnableGpe)
+ACPI_EXPORT_SYMBOL (AcpiDisableGpe)
/*******************************************************************************
*
- * FUNCTION: AcpiDisableGpe
+ * FUNCTION: AcpiSetGpe
*
- * 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
+ * Action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
*
* RETURN: Status
*
- * DESCRIPTION: Disable an ACPI event (general purpose)
+ * 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
-AcpiDisableGpe (
+AcpiSetGpe (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber,
- UINT32 Flags)
+ UINT8 Action)
{
- ACPI_STATUS Status = AE_OK;
ACPI_GPE_EVENT_INFO *GpeEventInfo;
+ ACPI_STATUS Status;
+ ACPI_CPU_FLAGS Flags;
- ACPI_FUNCTION_TRACE (AcpiDisableGpe);
-
+ ACPI_FUNCTION_TRACE (AcpiSetGpe);
- /* 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 */
@@ -468,17 +554,29 @@ AcpiDisableGpe (
goto UnlockAndExit;
}
- Status = AcpiEvDisableGpe (GpeEventInfo);
+ /* Perform the action */
-UnlockAndExit:
- if (Flags & ACPI_NOT_ISR)
+ switch (Action)
{
- (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+ 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 (AcpiDisableGpe)
+ACPI_EXPORT_SYMBOL (AcpiSetGpe)
/*******************************************************************************
@@ -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
@@ -235,15 +238,6 @@ 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
@@ -231,6 +231,14 @@ AcpiTbVerifyChecksum (
UINT32 Length);
void
+AcpiTbCheckDsdtHeader (
+ void);
+
+ACPI_TABLE_HEADER *
+AcpiTbCopyDsdt (
+ UINT32 TableIndex);
+
+void
AcpiTbInstallTable (
ACPI_PHYSICAL_ADDRESS Address,
char *Signature,
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
+ * +-------------- <Reserved>
*/
#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_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_CAN_WAKE (UINT8) 0x02
-#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 <sys/types.h>
#include <machine/acpica_machdep.h>
-#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 <ctype.h>
#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
@@ -395,6 +395,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
*
* PARAMETERS: Address - Physical address of DSDT or FACS
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;