Import ACPICA 20100331.

This commit is contained in:
jkim 2010-04-02 16:48:51 +00:00
parent 703ec8bd78
commit 1d2da6617f
31 changed files with 911 additions and 648 deletions

View File

@ -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:

View File

@ -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)
{

View File

@ -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.

View File

@ -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,

View File

@ -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);
}

View File

@ -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,

View File

@ -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",

View File

@ -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++;

View File

@ -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))

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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)
{

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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,

View File

@ -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_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

View File

@ -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 */

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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)

View File

@ -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

View File

@ -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 */

View File

@ -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 ();

View File

@ -916,6 +916,7 @@ AcpiUtInitGlobals (
/* Miscellaneous variables */
AcpiGbl_DSDT = NULL;
AcpiGbl_CmSingleStep = FALSE;
AcpiGbl_DbTerminateThreads = FALSE;
AcpiGbl_Shutdown = FALSE;