diff options
author | jkim <jkim@FreeBSD.org> | 2010-12-15 23:48:45 +0000 |
---|---|---|
committer | jkim <jkim@FreeBSD.org> | 2010-12-15 23:48:45 +0000 |
commit | 2fc3b5748a5d4d10201709860b52976d8ca9e54d (patch) | |
tree | 19ec6d7c2b2313528bbf1a21e92ad809001eb2bb /sys/contrib | |
parent | b3be4af10ab7b7e0bb1d47b76abf259823cf5699 (diff) | |
parent | 3fe23e61bda19d3fc57ff6366b5cf43d1aa422e1 (diff) | |
download | FreeBSD-src-2fc3b5748a5d4d10201709860b52976d8ca9e54d.zip FreeBSD-src-2fc3b5748a5d4d10201709860b52976d8ca9e54d.tar.gz |
Merge ACPICA 20101209.
Diffstat (limited to 'sys/contrib')
30 files changed, 1786 insertions, 1357 deletions
diff --git a/sys/contrib/dev/acpica/changes.txt b/sys/contrib/dev/acpica/changes.txt index 2153841..c586108 100644 --- a/sys/contrib/dev/acpica/changes.txt +++ b/sys/contrib/dev/acpica/changes.txt @@ -1,4 +1,76 @@ ---------------------------------------- +09 December 2010. Summary of changes for version 20101209: + +This release is available at www.acpica.org/downloads + +1) ACPI CA Core Subsystem: + +Completed the major overhaul of the GPE support code that was begun in July +2010. Major features include: removal of _PRW execution in ACPICA (host +executes _PRWs anyway), cleanup of "wake" GPE interfaces and processing, +changes to existing interfaces, simplification of GPE handler operation, and +a handful of new interfaces: + + AcpiUpdateAllGpes + AcpiFinishGpe + AcpiSetupGpeForWake + AcpiSetGpeWakeMask + One new file, evxfgpe.c to consolidate all external GPE interfaces. + +See the ACPICA Programmer Reference for full details and programming +information. See the new section 4.4 "General Purpose Event (GPE) Support" +for a full overview, and section 8.7 "ACPI General Purpose Event Management" +for programming details. ACPICA BZ 858,870,877. Matthew Garrett, Lin Ming, +Bob Moore, Rafael Wysocki. + +Implemented a new GPE feature for Windows compatibility, the "Implicit Wake +GPE Notify". This feature will automatically issue a Notify(2) on a device +when a Wake GPE is received if there is no corresponding GPE method or +handler. ACPICA BZ 870. + +Fixed a problem with the Scope() operator during table parse and load phase. +During load phase (table load or method execution), the scope operator should +not enter the target into the namespace. Instead, it should open a new scope +at the target location. Linux BZ 19462, ACPICA BZ 882. + +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: 89.8K Code, 18.9K Data, 108.7K Total + Debug Version: 166.6K Code, 52.1K Data, 218.7K Total + Current Release: + Non-Debug Version: 89.9K Code, 19.0K Data, 108.9K Total + Debug Version: 166.3K Code, 52.1K Data, 218.4K Total + +2) iASL Compiler/Disassembler and Tools: + +iASL: Relax the alphanumeric restriction on _CID strings. These strings are +"bus-specific" per the ACPI specification, and therefore any characters are +acceptable. The only checks that can be performed are for a null string and +perhaps for a leading asterisk. ACPICA BZ 886. + +iASL: Fixed a problem where a syntax error that caused a premature EOF +condition on the source file emitted a very confusing error message. The +premature EOF is now detected correctly. ACPICA BZ 891. + +Disassembler: Decode the AccessSize within a Generic Address Structure (byte +access, word access, etc.) Note, this field does not allow arbitrary bit +access, the size is encoded as 1=byte, 2=word, 3=dword, and 4=qword. + +New: AcpiNames utility - Example namespace dump utility. Shows an example of +ACPICA configuration for a minimal namespace dump utility. Uses table and +namespace managers, but no AML interpreter. Does not add any functionality +over AcpiExec, it is a subset of AcpiExec. The purpose is to show how to +partition and configure ACPICA. ACPICA BZ 883. + +AML Debugger: Increased the debugger buffer size for method return objects. +Was 4K, increased to 16K. Also enhanced error messages for debugger method +execution, including the buffer overflow case. + +---------------------------------------- 13 October 2010. Summary of changes for version 20101013: This release is available at www.acpica.org/downloads diff --git a/sys/contrib/dev/acpica/common/dmtable.c b/sys/contrib/dev/acpica/common/dmtable.c index a706453..240d878 100644 --- a/sys/contrib/dev/acpica/common/dmtable.c +++ b/sys/contrib/dev/acpica/common/dmtable.c @@ -295,6 +295,19 @@ static const char *AcpiDmFadtProfiles[] = "Unknown Profile Type" }; +#define ACPI_GAS_WIDTH_RESERVED 5 + +static const char *AcpiDmGasAccessWidth[] = +{ + "Undefined/Legacy", + "Byte Access:8", + "Word Access:16", + "DWord Access:32", + "QWord Access:64", + "Unknown Width Encoding" +}; + + /******************************************************************************* * * ACPI Table Data, indexed by signature. @@ -669,6 +682,7 @@ AcpiDmDumpTable ( case ACPI_DMT_UINT8: case ACPI_DMT_CHKSUM: case ACPI_DMT_SPACEID: + case ACPI_DMT_ACCWIDTH: case ACPI_DMT_IVRS: case ACPI_DMT_MADT: case ACPI_DMT_SRAT: @@ -884,6 +898,19 @@ AcpiDmDumpTable ( AcpiOsPrintf ("%2.2X (%s)\n", *Target, AcpiUtGetRegionName (*Target)); break; + case ACPI_DMT_ACCWIDTH: + + /* Encoded Access Width */ + + Temp8 = *Target; + if (Temp8 > ACPI_GAS_WIDTH_RESERVED) + { + Temp8 = ACPI_GAS_WIDTH_RESERVED; + } + + AcpiOsPrintf ("%2.2X (%s)\n", Temp8, AcpiDmGasAccessWidth[Temp8]); + break; + case ACPI_DMT_GAS: /* Generic Address Structure */ diff --git a/sys/contrib/dev/acpica/common/dmtbinfo.c b/sys/contrib/dev/acpica/common/dmtbinfo.c index 0e19311..207bc04 100644 --- a/sys/contrib/dev/acpica/common/dmtbinfo.c +++ b/sys/contrib/dev/acpica/common/dmtbinfo.c @@ -282,7 +282,7 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoGas[] = {ACPI_DMT_SPACEID, ACPI_GAS_OFFSET (SpaceId), "Space ID", 0}, {ACPI_DMT_UINT8, ACPI_GAS_OFFSET (BitWidth), "Bit Width", 0}, {ACPI_DMT_UINT8, ACPI_GAS_OFFSET (BitOffset), "Bit Offset", 0}, - {ACPI_DMT_UINT8, ACPI_GAS_OFFSET (AccessWidth), "Access Width", 0}, + {ACPI_DMT_ACCWIDTH, ACPI_GAS_OFFSET (AccessWidth), "Encoded Access Width", 0}, {ACPI_DMT_UINT64, ACPI_GAS_OFFSET (Address), "Address", 0}, ACPI_DMT_TERMINATOR }; diff --git a/sys/contrib/dev/acpica/compiler/aslanalyze.c b/sys/contrib/dev/acpica/compiler/aslanalyze.c index 20a2e1b..f7e1db2 100644 --- a/sys/contrib/dev/acpica/compiler/aslanalyze.c +++ b/sys/contrib/dev/acpica/compiler/aslanalyze.c @@ -684,19 +684,45 @@ AnCheckId ( UINT32 AlphaPrefixLength; + /* Only care about string versions of _HID/_CID (integers are legal) */ + if (Op->Asl.ParseOpcode != PARSEOP_STRING_LITERAL) { return; } + /* For both _HID and _CID, the string must be non-null */ + Length = strlen (Op->Asl.Value.String); + if (!Length) + { + AslError (ASL_ERROR, ASL_MSG_NULL_STRING, + Op, NULL); + return; + } /* - * If _HID/_CID is a string, all characters must be alphanumeric. - * One of the things we want to catch here is the use of - * a leading asterisk in the string -- an odd construct - * that certain platform manufacturers are fond of. + * One of the things we want to catch here is the use of a leading + * asterisk in the string -- an odd construct that certain platform + * manufacturers are fond of. Technically, a leading asterisk is OK + * for _CID, but a valid use of this has not been seen. */ + if (*Op->Asl.Value.String == '*') + { + AslError (ASL_ERROR, ASL_MSG_LEADING_ASTERISK, + Op, Op->Asl.Value.String); + return; + } + + /* _CID strings are bus-specific, no more checks can be performed */ + + if (Type == ASL_TYPE_CID) + { + return; + } + + /* For _HID, all characters must be alphanumeric */ + for (i = 0; Op->Asl.Value.String[i]; i++) { if (!isalnum ((int) Op->Asl.Value.String[i])) @@ -707,13 +733,6 @@ AnCheckId ( } } - if (Type == ASL_TYPE_CID) - { - /* _CID strings are bus-specific, no more checks can be performed */ - - return; - } - /* _HID String must be of the form "XXX####" or "ACPI####" */ if ((Length < 7) || (Length > 8)) diff --git a/sys/contrib/dev/acpica/compiler/aslerror.c b/sys/contrib/dev/acpica/compiler/aslerror.c index 383e617..cabbcc0 100644 --- a/sys/contrib/dev/acpica/compiler/aslerror.c +++ b/sys/contrib/dev/acpica/compiler/aslerror.c @@ -241,6 +241,8 @@ AePrintException ( UINT32 ErrorColumn; FILE *OutputFile; FILE *SourceFile; + long FileSize; + BOOLEAN PrematureEOF = FALSE; if (Gbl_NoErrors) @@ -289,6 +291,19 @@ AePrintException ( SourceFile = Gbl_Files[ASL_FILE_INPUT].Handle; } + if (SourceFile) + { + /* Determine if the error occurred at source file EOF */ + + fseek (SourceFile, 0, SEEK_END); + FileSize = ftell (SourceFile); + + if ((long) Enode->LogicalByteOffset >= FileSize) + { + PrematureEOF = TRUE; + } + } + if (Header) { fprintf (OutputFile, "%s", Header); @@ -307,33 +322,42 @@ AePrintException ( fprintf (OutputFile, " %6u: ", Enode->LineNumber); /* - * Seek to the offset in the combined source file, read the source - * line, and write it to the output. + * If not at EOF, get the corresponding source code line and + * display it. Don't attempt this if we have a premature EOF + * condition. */ - Actual = fseek (SourceFile, (long) Enode->LogicalByteOffset, - (int) SEEK_SET); - if (Actual) - { - fprintf (OutputFile, - "[*** iASL: Seek error on source code temp file %s ***]", - Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename); - } - else + if (!PrematureEOF) { - RActual = fread (&SourceByte, 1, 1, SourceFile); - if (!RActual) + /* + * Seek to the offset in the combined source file, read + * the source line, and write it to the output. + */ + Actual = fseek (SourceFile, (long) Enode->LogicalByteOffset, + (int) SEEK_SET); + if (Actual) { fprintf (OutputFile, - "[*** iASL: Read error on source code temp file %s ***]", + "[*** iASL: Seek error on source code temp file %s ***]", Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename); } - - else while (RActual && SourceByte && (SourceByte != '\n')) + else { - fwrite (&SourceByte, 1, 1, OutputFile); RActual = fread (&SourceByte, 1, 1, SourceFile); + if (!RActual) + { + fprintf (OutputFile, + "[*** iASL: Read error on source code temp file %s ***]", + Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename); + } + + else while (RActual && SourceByte && (SourceByte != '\n')) + { + fwrite (&SourceByte, 1, 1, OutputFile); + RActual = fread (&SourceByte, 1, 1, SourceFile); + } } } + fprintf (OutputFile, "\n"); } } @@ -376,7 +400,7 @@ AePrintException ( ExtraMessage = NULL; } - if (Gbl_VerboseErrors) + if (Gbl_VerboseErrors && !PrematureEOF) { SourceColumn = Enode->Column + Enode->FilenameLength + 6 + 2; ErrorColumn = ASL_ERROR_LEVEL_LENGTH + 5 + 2 + 1; @@ -406,6 +430,11 @@ AePrintException ( fprintf (OutputFile, " (%s)", ExtraMessage); } + if (PrematureEOF) + { + fprintf (OutputFile, " and premature End-Of-File"); + } + fprintf (OutputFile, "\n"); if (Gbl_VerboseErrors) { diff --git a/sys/contrib/dev/acpica/compiler/aslmessages.h b/sys/contrib/dev/acpica/compiler/aslmessages.h index 0457800..c69f7a2 100644 --- a/sys/contrib/dev/acpica/compiler/aslmessages.h +++ b/sys/contrib/dev/acpica/compiler/aslmessages.h @@ -258,6 +258,9 @@ typedef enum ASL_MSG_NULL_DESCRIPTOR, ASL_MSG_UPPER_CASE, ASL_MSG_HID_LENGTH, + ASL_MSG_NULL_STRING, + ASL_MSG_LEADING_ASTERISK, + ASL_MSG_INVALID_FIELD_NAME, ASL_MSG_INTEGER_SIZE, ASL_MSG_INVALID_HEX_INTEGER, @@ -382,7 +385,7 @@ char *AslMessages [] = { /* ASL_MSG_VENDOR_LIST */ "Too many vendor data bytes (7 max)", /* ASL_MSG_WRITE */ "Could not write file", /* ASL_MSG_MULTIPLE_DEFAULT */ "More than one Default statement within Switch construct", -/* ASL_MSG_TIMEOUT */ "Possible operator timeout is ignored", +/* ASL_MSG_TIMEOUT */ "Result is not used, possible operator timeout will be missed", /* ASL_MSG_RESULT_NOT_USED */ "Result is not used, operator has no effect", /* ASL_MSG_NOT_REFERENCED */ "Namespace object is not referenced", /* ASL_MSG_NON_ZERO */ "Operand evaluates to zero", @@ -403,6 +406,8 @@ char *AslMessages [] = { /* ASL_MSG_NULL_DESCRIPTOR */ "Min/Max/Length/Gran are all zero, but no resource tag", /* ASL_MSG_UPPER_CASE */ "Non-hex letters must be upper case", /* ASL_MSG_HID_LENGTH */ "_HID string must be exactly 7 or 8 characters", +/* ASL_MSG_NULL_STRING */ "Invalid zero-length (null) string", +/* ASL_MSG_LEADING_ASTERISK */ "Invalid leading asterisk", /* These messages are used by the data table compiler only */ diff --git a/sys/contrib/dev/acpica/compiler/dtutils.c b/sys/contrib/dev/acpica/compiler/dtutils.c index 56ef05b..1414446 100644 --- a/sys/contrib/dev/acpica/compiler/dtutils.c +++ b/sys/contrib/dev/acpica/compiler/dtutils.c @@ -573,6 +573,7 @@ DtGetFieldLength ( case ACPI_DMT_UINT8: case ACPI_DMT_CHKSUM: case ACPI_DMT_SPACEID: + case ACPI_DMT_ACCWIDTH: case ACPI_DMT_IVRS: case ACPI_DMT_MADT: case ACPI_DMT_SRAT: diff --git a/sys/contrib/dev/acpica/debugger/dbcmds.c b/sys/contrib/dev/acpica/debugger/dbcmds.c index e31e1c1..d302ba6 100644 --- a/sys/contrib/dev/acpica/debugger/dbcmds.c +++ b/sys/contrib/dev/acpica/debugger/dbcmds.c @@ -2075,7 +2075,7 @@ AcpiDbGenerateGpe ( return; } - (void) AcpiEvGpeDispatch (GpeEventInfo, GpeNumber); + (void) AcpiEvGpeDispatch (NULL, GpeEventInfo, GpeNumber); } diff --git a/sys/contrib/dev/acpica/debugger/dbdisply.c b/sys/contrib/dev/acpica/debugger/dbdisply.c index ffd5d70..184a1ff 100644 --- a/sys/contrib/dev/acpica/debugger/dbdisply.c +++ b/sys/contrib/dev/acpica/debugger/dbdisply.c @@ -896,7 +896,8 @@ AcpiDbDisplayGpes ( GpeIndex = (i * ACPI_GPE_REGISTER_WIDTH) + j; GpeEventInfo = &GpeBlock->EventInfo[GpeIndex]; - if (!(GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK)) + if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == + ACPI_GPE_DISPATCH_NONE) { /* This GPE is not used (no method or handler), ignore it */ @@ -906,8 +907,7 @@ AcpiDbDisplayGpes ( AcpiOsPrintf ( " GPE %.2X: %p RunRefs %2.2X Flags %2.2X (", GpeBlock->BlockBaseNumber + GpeIndex, GpeEventInfo, - GpeEventInfo->RuntimeCount, - GpeEventInfo->Flags); + GpeEventInfo->RuntimeCount, GpeEventInfo->Flags); /* Decode the flags byte */ @@ -931,14 +931,17 @@ AcpiDbDisplayGpes ( switch (GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) { - case ACPI_GPE_DISPATCH_NOT_USED: + case ACPI_GPE_DISPATCH_NONE: AcpiOsPrintf ("NotUsed"); break; + case ACPI_GPE_DISPATCH_METHOD: + AcpiOsPrintf ("Method"); + break; case ACPI_GPE_DISPATCH_HANDLER: AcpiOsPrintf ("Handler"); break; - case ACPI_GPE_DISPATCH_METHOD: - AcpiOsPrintf ("Method"); + case ACPI_GPE_DISPATCH_NOTIFY: + AcpiOsPrintf ("Notify"); break; default: AcpiOsPrintf ("UNKNOWN: %X", diff --git a/sys/contrib/dev/acpica/debugger/dbexec.c b/sys/contrib/dev/acpica/debugger/dbexec.c index 07b6ad9..282212a 100644 --- a/sys/contrib/dev/acpica/debugger/dbexec.c +++ b/sys/contrib/dev/acpica/debugger/dbexec.c @@ -180,6 +180,9 @@ AcpiDbExecuteMethod ( ACPI_DEVICE_INFO *ObjInfo; + ACPI_FUNCTION_TRACE (DbExecuteMethod); + + if (AcpiGbl_DbOutputToFile && !AcpiDbgLevel) { AcpiOsPrintf ("Warning: debug output is not enabled!\n"); @@ -190,7 +193,7 @@ AcpiDbExecuteMethod ( Status = AcpiGetHandle (NULL, Info->Pathname, &Handle); if (ACPI_FAILURE (Status)) { - return (Status); + return_ACPI_STATUS (Status); } /* Get the object info for number of method parameters */ @@ -198,7 +201,7 @@ AcpiDbExecuteMethod ( Status = AcpiGetObjectInfo (Handle, &ObjInfo); if (ACPI_FAILURE (Status)) { - return (Status); + return_ACPI_STATUS (Status); } ParamObjects.Pointer = NULL; @@ -269,7 +272,20 @@ AcpiDbExecuteMethod ( AcpiGbl_CmSingleStep = FALSE; AcpiGbl_MethodExecuting = FALSE; - return (Status); + if (ACPI_FAILURE (Status)) + { + ACPI_EXCEPTION ((AE_INFO, Status, + "while executing %s from debugger", Info->Pathname)); + + if (Status == AE_BUFFER_OVERFLOW) + { + ACPI_ERROR ((AE_INFO, + "Possible overflow of internal debugger buffer (size 0x%X needed 0x%X)", + ACPI_DEBUG_BUFFER_SIZE, (UINT32) ReturnObj->Length)); + } + } + + return_ACPI_STATUS (Status); } diff --git a/sys/contrib/dev/acpica/dispatcher/dswexec.c b/sys/contrib/dev/acpica/dispatcher/dswexec.c index 61a7e1c..818e7ef 100644 --- a/sys/contrib/dev/acpica/dispatcher/dswexec.c +++ b/sys/contrib/dev/acpica/dispatcher/dswexec.c @@ -400,10 +400,26 @@ AcpiDsExecBeginOp ( * we must enter this object into the namespace. The created * object is temporary and will be deleted upon completion of * the execution of this method. + * + * Note 10/2010: Except for the Scope() op. This opcode does + * not actually create a new object, it refers to an existing + * object. However, for Scope(), we want to indeed open a + * new scope. */ - Status = AcpiDsLoad2BeginOp (WalkState, NULL); + if (Op->Common.AmlOpcode != AML_SCOPE_OP) + { + Status = AcpiDsLoad2BeginOp (WalkState, NULL); + } + else + { + Status = AcpiDsScopeStackPush (Op->Named.Node, + Op->Named.Node->Type, WalkState); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + } } - break; diff --git a/sys/contrib/dev/acpica/events/evevent.c b/sys/contrib/dev/acpica/events/evevent.c index d743051..7398309 100644 --- a/sys/contrib/dev/acpica/events/evevent.c +++ b/sys/contrib/dev/acpica/events/evevent.c @@ -180,54 +180,6 @@ AcpiEvInitializeEvents ( /******************************************************************************* * - * FUNCTION: AcpiEvInstallFadtGpes - * - * PARAMETERS: None - * - * RETURN: Status - * - * DESCRIPTION: Completes initialization of the FADT-defined GPE blocks - * (0 and 1). This causes the _PRW methods to be run, so the HW - * must be fully initialized at this point, including global lock - * support. - * - ******************************************************************************/ - -ACPI_STATUS -AcpiEvInstallFadtGpes ( - void) -{ - ACPI_STATUS Status; - - - ACPI_FUNCTION_TRACE (EvInstallFadtGpes); - - - /* Namespace must be locked */ - - Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (Status)) - { - return (Status); - } - - /* FADT GPE Block 0 */ - - (void) AcpiEvInitializeGpeBlock ( - AcpiGbl_FadtGpeDevice, AcpiGbl_GpeFadtBlocks[0]); - - /* FADT GPE Block 1 */ - - (void) AcpiEvInitializeGpeBlock ( - AcpiGbl_FadtGpeDevice, AcpiGbl_GpeFadtBlocks[1]); - - (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); - return_ACPI_STATUS (AE_OK); -} - - -/******************************************************************************* - * * FUNCTION: AcpiEvInstallXruptHandlers * * PARAMETERS: None @@ -366,9 +318,17 @@ AcpiEvFixedEventDetect ( if ((FixedStatus & AcpiGbl_FixedEventInfo[i].StatusBitMask) && (FixedEnable & AcpiGbl_FixedEventInfo[i].EnableBitMask)) { - /* Found an active (signalled) event */ - + /* + * Found an active (signalled) event. Invoke global event + * handler if present. + */ AcpiFixedEventCount[i]++; + if (AcpiGbl_GlobalEventHandler) + { + AcpiGbl_GlobalEventHandler (ACPI_EVENT_TYPE_FIXED, NULL, + i, AcpiGbl_GlobalEventHandlerContext); + } + IntStatus |= AcpiEvFixedEventDispatch (i); } } diff --git a/sys/contrib/dev/acpica/events/evgpe.c b/sys/contrib/dev/acpica/events/evgpe.c index 7998ea9..e6cd3e13 100644 --- a/sys/contrib/dev/acpica/events/evgpe.c +++ b/sys/contrib/dev/acpica/events/evgpe.c @@ -202,12 +202,13 @@ AcpiEvEnableGpe ( /* - * 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. + * We will only allow a GPE to be enabled if it has either an associated + * method (_Lxx/_Exx) or a handler, or is using the implicit notify + * feature. Otherwise, the GPE will be immediately disabled by + * AcpiEvGpeDispatch the first time it fires. */ - if (!(GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK)) + if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == + ACPI_GPE_DISPATCH_NONE) { return_ACPI_STATUS (AE_NO_HANDLER); } @@ -229,6 +230,104 @@ AcpiEvEnableGpe ( /******************************************************************************* * + * FUNCTION: AcpiEvAddGpeReference + * + * PARAMETERS: GpeEventInfo - Add a reference to this GPE + * + * RETURN: Status + * + * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is + * hardware-enabled. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiEvAddGpeReference ( + ACPI_GPE_EVENT_INFO *GpeEventInfo) +{ + ACPI_STATUS Status = AE_OK; + + + ACPI_FUNCTION_TRACE (EvAddGpeReference); + + + if (GpeEventInfo->RuntimeCount == ACPI_UINT8_MAX) + { + return_ACPI_STATUS (AE_LIMIT); + } + + GpeEventInfo->RuntimeCount++; + if (GpeEventInfo->RuntimeCount == 1) + { + /* Enable on first reference */ + + Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo); + if (ACPI_SUCCESS (Status)) + { + Status = AcpiEvEnableGpe (GpeEventInfo); + } + + if (ACPI_FAILURE (Status)) + { + GpeEventInfo->RuntimeCount--; + } + } + + return_ACPI_STATUS (Status); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiEvRemoveGpeReference + * + * PARAMETERS: GpeEventInfo - Remove a reference to this GPE + * + * RETURN: Status + * + * DESCRIPTION: Remove a reference to a GPE. When the last reference is + * removed, the GPE is hardware-disabled. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiEvRemoveGpeReference ( + ACPI_GPE_EVENT_INFO *GpeEventInfo) +{ + ACPI_STATUS Status = AE_OK; + + + ACPI_FUNCTION_TRACE (EvRemoveGpeReference); + + + if (!GpeEventInfo->RuntimeCount) + { + return_ACPI_STATUS (AE_LIMIT); + } + + GpeEventInfo->RuntimeCount--; + if (!GpeEventInfo->RuntimeCount) + { + /* Disable on last reference */ + + Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo); + if (ACPI_SUCCESS (Status)) + { + Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE); + } + + if (ACPI_FAILURE (Status)) + { + GpeEventInfo->RuntimeCount++; + } + } + + return_ACPI_STATUS (Status); +} + + +/******************************************************************************* + * * FUNCTION: AcpiEvLowGetGpeInfo * * PARAMETERS: GpeNumber - Raw GPE number @@ -412,7 +511,7 @@ AcpiEvGpeDetect ( } ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS, - "Read GPE Register at GPE%X: Status=%02X, Enable=%02X\n", + "Read GPE Register at GPE%02X: Status=%02X, Enable=%02X\n", GpeRegisterInfo->BaseGpeNumber, StatusReg, EnableReg)); /* Check if there is anything active at all in this register */ @@ -437,7 +536,7 @@ AcpiEvGpeDetect ( * Found an active GPE. Dispatch the event to a handler * or method. */ - IntStatus |= AcpiEvGpeDispatch ( + IntStatus |= AcpiEvGpeDispatch (GpeBlock->Node, &GpeBlock->EventInfo[((ACPI_SIZE) i * ACPI_GPE_REGISTER_WIDTH) + j], j + GpeRegisterInfo->BaseGpeNumber); @@ -521,13 +620,27 @@ AcpiEvAsynchExecuteGpeMethod ( return_VOID; } - /* - * Must check for control method type dispatch one more time to avoid a - * race with EvGpeInstallHandler - */ - if ((LocalGpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == - ACPI_GPE_DISPATCH_METHOD) + /* Do the correct dispatch - normal method or implicit notify */ + + switch (LocalGpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) { + case ACPI_GPE_DISPATCH_NOTIFY: + + /* + * Implicit notify. + * Dispatch a DEVICE_WAKE notify to the appropriate handler. + * NOTE: the request is queued for execution after this method + * completes. The notify handlers are NOT invoked synchronously + * from this thread -- because handlers may in turn run other + * control methods. + */ + Status = AcpiEvQueueNotifyRequest ( + LocalGpeEventInfo->Dispatch.DeviceNode, + ACPI_NOTIFY_DEVICE_WAKE); + break; + + case ACPI_GPE_DISPATCH_METHOD: + /* Allocate the evaluation information block */ Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO)); @@ -538,8 +651,8 @@ AcpiEvAsynchExecuteGpeMethod ( else { /* - * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx - * control method that corresponds to this GPE + * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the + * _Lxx/_Exx control method that corresponds to this GPE */ Info->PrefixNode = LocalGpeEventInfo->Dispatch.MethodNode; Info->Flags = ACPI_IGNORE_RETURN_VALUE; @@ -554,6 +667,11 @@ AcpiEvAsynchExecuteGpeMethod ( "while evaluating GPE method [%4.4s]", AcpiUtGetNodeName (LocalGpeEventInfo->Dispatch.MethodNode))); } + + break; + + default: + return_VOID; /* Should never happen */ } /* Defer enabling of GPE until all notify handlers are done */ @@ -573,6 +691,7 @@ AcpiEvAsynchExecuteGpeMethod ( * FUNCTION: AcpiEvAsynchEnableGpe * * PARAMETERS: Context (GpeEventInfo) - Info for this GPE + * Callback from AcpiOsExecute * * RETURN: None * @@ -586,6 +705,32 @@ AcpiEvAsynchEnableGpe ( void *Context) { ACPI_GPE_EVENT_INFO *GpeEventInfo = Context; + + + (void) AcpiEvFinishGpe (GpeEventInfo); + + ACPI_FREE (GpeEventInfo); + return; +} + + +/******************************************************************************* + * + * FUNCTION: AcpiEvFinishGpe + * + * PARAMETERS: GpeEventInfo - Info for this GPE + * + * RETURN: Status + * + * DESCRIPTION: Clear/Enable a GPE. Common code that is used after execution + * of a GPE method or a synchronous or asynchronous GPE handler. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiEvFinishGpe ( + ACPI_GPE_EVENT_INFO *GpeEventInfo) +{ ACPI_STATUS Status; @@ -593,25 +738,23 @@ AcpiEvAsynchEnableGpe ( ACPI_GPE_LEVEL_TRIGGERED) { /* - * GPE is level-triggered, we clear the GPE status bit after handling - * the event. + * GPE is level-triggered, we clear the GPE status bit after + * handling the event. */ Status = AcpiHwClearGpe (GpeEventInfo); if (ACPI_FAILURE (Status)) { - goto Exit; + return (Status); } } /* - * Enable this GPE, conditionally. This means that the GPE will only be - * physically enabled if the EnableForRun bit is set in the EventInfo + * Enable this GPE, conditionally. This means that the GPE will + * only be physically enabled if the EnableForRun bit is set + * in the EventInfo. */ (void) AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_CONDITIONAL_ENABLE); - -Exit: - ACPI_FREE (GpeEventInfo); - return; + return (AE_OK); } @@ -619,8 +762,9 @@ Exit: * * FUNCTION: AcpiEvGpeDispatch * - * PARAMETERS: GpeEventInfo - Info for this GPE - * GpeNumber - Number relative to the parent GPE block + * PARAMETERS: GpeDevice - Device node. NULL for GPE0/GPE1 + * GpeEventInfo - Info for this GPE + * GpeNumber - Number relative to the parent GPE block * * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED * @@ -633,16 +777,25 @@ Exit: UINT32 AcpiEvGpeDispatch ( + ACPI_NAMESPACE_NODE *GpeDevice, ACPI_GPE_EVENT_INFO *GpeEventInfo, UINT32 GpeNumber) { ACPI_STATUS Status; + UINT32 ReturnValue; ACPI_FUNCTION_TRACE (EvGpeDispatch); + /* Invoke global event handler if present */ + AcpiGpeCount++; + if (AcpiGbl_GlobalEventHandler) + { + AcpiGbl_GlobalEventHandler (ACPI_EVENT_TYPE_GPE, GpeDevice, + GpeNumber, AcpiGbl_GlobalEventHandlerContext); + } /* * If edge-triggered, clear the GPE status bit now. Note that @@ -655,58 +808,55 @@ AcpiEvGpeDispatch ( if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, - "Unable to clear GPE[0x%2X]", GpeNumber)); + "Unable to clear GPE%02X", GpeNumber)); return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED); } } /* - * Dispatch the GPE to either an installed handler, or the control method - * associated with this GPE (_Lxx or _Exx). If a handler exists, we invoke - * it and do not attempt to run the method. If there is neither a handler - * nor a method, we disable this GPE to prevent further such pointless - * events from firing. + * Always disable the GPE so that it does not keep firing before + * any asynchronous activity completes (either from the execution + * of a GPE method or an asynchronous GPE handler.) + * + * If there is no handler or method to run, just disable the + * GPE and leave it disabled permanently to prevent further such + * pointless events from firing. + */ + Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE); + if (ACPI_FAILURE (Status)) + { + ACPI_EXCEPTION ((AE_INFO, Status, + "Unable to disable GPE%02X", GpeNumber)); + return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED); + } + + /* + * Dispatch the GPE to either an installed handler or the control + * method associated with this GPE (_Lxx or _Exx). If a handler + * exists, we invoke it and do not attempt to run the method. + * If there is neither a handler nor a method, leave the GPE + * disabled. */ switch (GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) { case ACPI_GPE_DISPATCH_HANDLER: - /* - * Invoke the installed handler (at interrupt level) - * Ignore return status for now. - * TBD: leave GPE disabled on error? - */ - (void) GpeEventInfo->Dispatch.Handler->Address ( - GpeEventInfo->Dispatch.Handler->Context); + /* Invoke the installed handler (at interrupt level) */ - /* It is now safe to clear level-triggered events. */ + ReturnValue = GpeEventInfo->Dispatch.Handler->Address ( + GpeDevice, GpeNumber, + GpeEventInfo->Dispatch.Handler->Context); - if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) == - ACPI_GPE_LEVEL_TRIGGERED) + /* If requested, clear (if level-triggered) and reenable the GPE */ + + if (ReturnValue & ACPI_REENABLE_GPE) { - Status = AcpiHwClearGpe (GpeEventInfo); - if (ACPI_FAILURE (Status)) - { - ACPI_EXCEPTION ((AE_INFO, Status, - "Unable to clear GPE[0x%2X]", GpeNumber)); - return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED); - } + (void) AcpiEvFinishGpe (GpeEventInfo); } break; case ACPI_GPE_DISPATCH_METHOD: - - /* - * Disable the GPE, so it doesn't keep firing before the method has a - * chance to run (it runs asynchronously with interrupts enabled). - */ - Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE); - if (ACPI_FAILURE (Status)) - { - ACPI_EXCEPTION ((AE_INFO, Status, - "Unable to disable GPE[0x%2X]", GpeNumber)); - return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED); - } + case ACPI_GPE_DISPATCH_NOTIFY: /* * Execute the method associated with the GPE @@ -717,7 +867,7 @@ AcpiEvGpeDispatch ( if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, - "Unable to queue handler for GPE[0x%2X] - event disabled", + "Unable to queue handler for GPE%02X - event disabled", GpeNumber)); } break; @@ -730,20 +880,8 @@ AcpiEvGpeDispatch ( * 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", + "No handler or method for GPE%02X, disabling event", GpeNumber)); - - /* - * Disable the GPE. The GPE will remain disabled until a handler - * is installed or ACPICA is restarted. - */ - Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE); - if (ACPI_FAILURE (Status)) - { - ACPI_EXCEPTION ((AE_INFO, Status, - "Unable to disable GPE[0x%2X]", GpeNumber)); - return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED); - } break; } diff --git a/sys/contrib/dev/acpica/events/evgpeblk.c b/sys/contrib/dev/acpica/events/evgpeblk.c index f434fb5..3e0ae35 100644 --- a/sys/contrib/dev/acpica/events/evgpeblk.c +++ b/sys/contrib/dev/acpica/events/evgpeblk.c @@ -467,6 +467,7 @@ AcpiEvCreateGpeBlock ( GpeBlock->Node = GpeDevice; GpeBlock->GpeCount = (UINT16) (RegisterCount * ACPI_GPE_REGISTER_WIDTH); + GpeBlock->Initialized = FALSE; GpeBlock->RegisterCount = RegisterCount; GpeBlock->BlockBaseNumber = GpeBlockBaseNumber; @@ -493,11 +494,12 @@ AcpiEvCreateGpeBlock ( return_ACPI_STATUS (Status); } + AcpiGbl_AllGpesInitialized = FALSE; + /* Find all GPE methods (_Lxx or_Exx) for this block */ WalkInfo.GpeBlock = GpeBlock; WalkInfo.GpeDevice = GpeDevice; - WalkInfo.EnableThisGpe = FALSE; WalkInfo.ExecuteByOwnerId = FALSE; Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD, GpeDevice, @@ -529,30 +531,26 @@ AcpiEvCreateGpeBlock ( * * FUNCTION: AcpiEvInitializeGpeBlock * - * PARAMETERS: GpeDevice - Handle to the parent GPE block - * GpeBlock - Gpe Block info + * PARAMETERS: ACPI_GPE_CALLBACK * * RETURN: Status * - * DESCRIPTION: Initialize and enable a GPE block. First find and run any - * _PRT methods associated with the block, then enable the - * appropriate GPEs. + * DESCRIPTION: Initialize and enable a GPE block. Enable GPEs that have + * associated methods. * Note: Assumes namespace is locked. * ******************************************************************************/ ACPI_STATUS AcpiEvInitializeGpeBlock ( - ACPI_NAMESPACE_NODE *GpeDevice, - ACPI_GPE_BLOCK_INFO *GpeBlock) + ACPI_GPE_XRUPT_INFO *GpeXruptInfo, + ACPI_GPE_BLOCK_INFO *GpeBlock, + void *Ignored) { ACPI_STATUS Status; ACPI_GPE_EVENT_INFO *GpeEventInfo; - ACPI_GPE_WALK_INFO WalkInfo; - UINT32 WakeGpeCount; UINT32 GpeEnabledCount; UINT32 GpeIndex; - UINT32 GpeNumber; UINT32 i; UINT32 j; @@ -560,51 +558,22 @@ AcpiEvInitializeGpeBlock ( ACPI_FUNCTION_TRACE (EvInitializeGpeBlock); - /* Ignore a null GPE block (e.g., if no GPE block 1 exists) */ - - if (!GpeBlock) - { - return_ACPI_STATUS (AE_OK); - } - /* - * Runtime option: Should wake GPEs be enabled at runtime? The default - * is no, they should only be enabled just as the machine goes to sleep. + * Ignore a null GPE block (e.g., if no GPE block 1 exists), and + * any GPE blocks that have been initialized already. */ - if (AcpiGbl_LeaveWakeGpesDisabled) + if (!GpeBlock || GpeBlock->Initialized) { - /* - * Differentiate runtime vs wake GPEs, via the _PRW control methods. - * Each GPE that has one or more _PRWs that reference it is by - * definition a wake GPE and will not be enabled while the machine - * is running. - */ - WalkInfo.GpeBlock = GpeBlock; - WalkInfo.GpeDevice = GpeDevice; - WalkInfo.ExecuteByOwnerId = FALSE; - - Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, - AcpiEvMatchPrwAndGpe, NULL, &WalkInfo, NULL); - if (ACPI_FAILURE (Status)) - { - ACPI_EXCEPTION ((AE_INFO, Status, "While executing _PRW methods")); - } + return_ACPI_STATUS (AE_OK); } /* - * 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. + * Enable all GPEs that have a corresponding method and have the + * ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block + * must be enabled via the acpi_enable_gpe() interface. */ - WakeGpeCount = 0; GpeEnabledCount = 0; - if (GpeDevice == AcpiGbl_FadtGpeDevice) - { - GpeDevice = NULL; - } - for (i = 0; i < GpeBlock->RegisterCount; i++) { for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) @@ -613,45 +582,24 @@ AcpiEvInitializeGpeBlock ( GpeIndex = (i * ACPI_GPE_REGISTER_WIDTH) + j; GpeEventInfo = &GpeBlock->EventInfo[GpeIndex]; - GpeNumber = GpeIndex + GpeBlock->BlockBaseNumber; /* - * If the GPE has already been enabled for runtime - * signalling, make sure that it remains enabled, but - * do not increment its reference count. + * Ignore GPEs that have no corresponding _Lxx/_Exx method + * and GPEs that are used to wake the system */ - if (GpeEventInfo->RuntimeCount) - { - Status = AcpiEvEnableGpe (GpeEventInfo); - goto Enabled; - } - - /* Ignore GPEs that can wake the system */ - - 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)) + if (((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_NONE) || + ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_HANDLER) || + (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)) { continue; } - /* Enable this GPE */ - - Status = AcpiEnableGpe (GpeDevice, GpeNumber); -Enabled: + Status = AcpiEvAddGpeReference (GpeEventInfo); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, - "Could not enable GPE 0x%02X", GpeNumber)); + "Could not enable GPE 0x%02X", + GpeIndex + GpeBlock->BlockBaseNumber)); continue; } @@ -659,13 +607,13 @@ Enabled: } } - if (GpeEnabledCount || WakeGpeCount) + if (GpeEnabledCount) { ACPI_DEBUG_PRINT ((ACPI_DB_INIT, - "Enabled %u Runtime GPEs, added %u Wake GPEs in this block\n", - GpeEnabledCount, WakeGpeCount)); + "Enabled %u GPEs in this block\n", GpeEnabledCount)); } + GpeBlock->Initialized = TRUE; return_ACPI_STATUS (AE_OK); } diff --git a/sys/contrib/dev/acpica/events/evgpeinit.c b/sys/contrib/dev/acpica/events/evgpeinit.c index e60ffa9..083c92e 100644 --- a/sys/contrib/dev/acpica/events/evgpeinit.c +++ b/sys/contrib/dev/acpica/events/evgpeinit.c @@ -118,12 +118,28 @@ #include <contrib/dev/acpica/include/accommon.h> #include <contrib/dev/acpica/include/acevents.h> #include <contrib/dev/acpica/include/acnamesp.h> -#include <contrib/dev/acpica/include/acinterp.h> #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME ("evgpeinit") +/* + * Note: History of _PRW support in ACPICA + * + * Originally (2000 - 2010), the GPE initialization code performed a walk of + * the entire namespace to execute the _PRW methods and detect all GPEs + * capable of waking the system. + * + * As of 10/2010, the _PRW method execution has been removed since it is + * actually unnecessary. The host OS must in fact execute all _PRW methods + * in order to identify the device/power-resource dependencies. We now put + * the onus on the host OS to identify the wake GPEs as part of this process + * and to inform ACPICA of these GPEs via the AcpiSetupGpeForWake interface. This + * not only reduces the complexity of the ACPICA initialization code, but in + * some cases (on systems with very large namespaces) it should reduce the + * kernel boot time as well. + */ + /******************************************************************************* * * FUNCTION: AcpiEvGpeInitialize @@ -288,10 +304,7 @@ Cleanup: * * DESCRIPTION: Check for new GPE methods (_Lxx/_Exx) made available as a * result of a Load() or LoadTable() operation. If new GPE - * methods have been installed, register the new methods and - * enable and runtime GPEs that are associated with them. Also, - * run any newly loaded _PRW methods in order to discover any - * new CAN_WAKE GPEs. + * methods have been installed, register the new methods. * ******************************************************************************/ @@ -303,49 +316,13 @@ AcpiEvUpdateGpes ( ACPI_GPE_BLOCK_INFO *GpeBlock; ACPI_GPE_WALK_INFO WalkInfo; ACPI_STATUS Status = AE_OK; - UINT32 NewWakeGpeCount = 0; - - - /* We will examine only _PRW/_Lxx/_Exx methods owned by this table */ - - WalkInfo.OwnerId = TableOwnerId; - WalkInfo.ExecuteByOwnerId = TRUE; - WalkInfo.Count = 0; - if (AcpiGbl_LeaveWakeGpesDisabled) - { - /* - * 1) Run any newly-loaded _PRW methods to find any GPEs that - * can now be marked as CAN_WAKE GPEs. Note: We must run the - * _PRW methods before we process the _Lxx/_Exx methods because - * we will enable all runtime GPEs associated with the new - * _Lxx/_Exx methods at the time we process those methods. - * - * Unlock interpreter so that we can run the _PRW methods. - */ - WalkInfo.GpeBlock = NULL; - WalkInfo.GpeDevice = NULL; - - AcpiExExitInterpreter (); - - Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, - AcpiEvMatchPrwAndGpe, NULL, &WalkInfo, NULL); - if (ACPI_FAILURE (Status)) - { - ACPI_EXCEPTION ((AE_INFO, Status, - "While executing _PRW methods")); - } - - AcpiExEnterInterpreter (); - NewWakeGpeCount = WalkInfo.Count; - } /* - * 2) Find any _Lxx/_Exx GPE methods that have just been loaded. + * Find any _Lxx/_Exx GPE methods that have just been loaded. * - * Any GPEs that correspond to new _Lxx/_Exx methods and are not - * marked as CAN_WAKE are immediately enabled. + * Any GPEs that correspond to new _Lxx/_Exx methods are immediately + * enabled. * * Examine the namespace underneath each GpeDevice within the * GpeBlock lists. @@ -357,7 +334,8 @@ AcpiEvUpdateGpes ( } WalkInfo.Count = 0; - WalkInfo.EnableThisGpe = TRUE; + WalkInfo.OwnerId = TableOwnerId; + WalkInfo.ExecuteByOwnerId = TRUE; /* Walk the interrupt level descriptor list */ @@ -388,11 +366,9 @@ AcpiEvUpdateGpes ( GpeXruptInfo = GpeXruptInfo->Next; } - if (WalkInfo.Count || NewWakeGpeCount) + if (WalkInfo.Count) { - ACPI_INFO ((AE_INFO, - "Enabled %u new runtime GPEs, added %u new wakeup GPEs", - WalkInfo.Count, NewWakeGpeCount)); + ACPI_INFO ((AE_INFO, "Enabled %u new GPEs", WalkInfo.Count)); } (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); @@ -422,9 +398,7 @@ AcpiEvUpdateGpes ( * xx - is the GPE number [in HEX] * * If WalkInfo->ExecuteByOwnerId is TRUE, we only execute examine GPE methods - * with that owner. - * If WalkInfo->EnableThisGpe is TRUE, the GPE that is referred to by a GPE - * method is immediately enabled (Used for Load/LoadTable operators) + * with that owner. * ******************************************************************************/ @@ -438,8 +412,6 @@ AcpiEvMatchGpeMethod ( ACPI_NAMESPACE_NODE *MethodNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle); ACPI_GPE_WALK_INFO *WalkInfo = ACPI_CAST_PTR (ACPI_GPE_WALK_INFO, Context); ACPI_GPE_EVENT_INFO *GpeEventInfo; - ACPI_NAMESPACE_NODE *GpeDevice; - ACPI_STATUS Status; UINT32 GpeNumber; char Name[ACPI_NAME_SIZE + 1]; UINT8 Type; @@ -474,9 +446,6 @@ AcpiEvMatchGpeMethod ( /* * 3) Edge/Level determination is based on the 2nd character * of the method name - * - * 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]) { @@ -551,212 +520,12 @@ AcpiEvMatchGpeMethod ( * Add the GPE information from above to the GpeEventInfo block for * use during dispatch of this GPE. */ + GpeEventInfo->Flags &= ~(ACPI_GPE_DISPATCH_MASK); GpeEventInfo->Flags |= (UINT8) (Type | ACPI_GPE_DISPATCH_METHOD); GpeEventInfo->Dispatch.MethodNode = MethodNode; - /* - * Enable this GPE if requested. This only happens when during the - * execution of a Load or LoadTable operator. We have found a new - * GPE method and want to immediately enable the GPE if it is a - * runtime GPE. - */ - if (WalkInfo->EnableThisGpe) - { - /* Ignore GPEs that can wake the system */ - - if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE) || - !AcpiGbl_LeaveWakeGpesDisabled) - { - WalkInfo->Count++; - GpeDevice = WalkInfo->GpeDevice; - - if (GpeDevice == AcpiGbl_FadtGpeDevice) - { - GpeDevice = NULL; - } - - Status = AcpiEnableGpe (GpeDevice, GpeNumber); - if (ACPI_FAILURE (Status)) - { - ACPI_EXCEPTION ((AE_INFO, Status, - "Could not enable GPE 0x%02X", GpeNumber)); - } - } - } - ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "Registered GPE method %s as GPE number 0x%.2X\n", Name, GpeNumber)); return_ACPI_STATUS (AE_OK); } - - -/******************************************************************************* - * - * FUNCTION: AcpiEvMatchPrwAndGpe - * - * PARAMETERS: Callback from WalkNamespace - * - * RETURN: Status. NOTE: We ignore errors so that the _PRW walk is - * not aborted on a single _PRW failure. - * - * 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 CAN_WAKE GPE. Allows a - * per-OwnerId execution if ExecuteByOwnerId is TRUE in the - * WalkInfo parameter block. - * - * If WalkInfo->ExecuteByOwnerId is TRUE, we only execute _PRWs with that - * owner. - * If WalkInfo->GpeDevice is NULL, we execute every _PRW found. Otherwise, - * we only execute _PRWs that refer to the input GpeDevice. - * - ******************************************************************************/ - -ACPI_STATUS -AcpiEvMatchPrwAndGpe ( - ACPI_HANDLE ObjHandle, - UINT32 Level, - void *Context, - void **ReturnValue) -{ - ACPI_GPE_WALK_INFO *WalkInfo = ACPI_CAST_PTR (ACPI_GPE_WALK_INFO, Context); - ACPI_NAMESPACE_NODE *GpeDevice; - ACPI_GPE_BLOCK_INFO *GpeBlock; - ACPI_NAMESPACE_NODE *TargetGpeDevice; - ACPI_NAMESPACE_NODE *PrwNode; - ACPI_GPE_EVENT_INFO *GpeEventInfo; - ACPI_OPERAND_OBJECT *PkgDesc; - ACPI_OPERAND_OBJECT *ObjDesc; - UINT32 GpeNumber; - ACPI_STATUS Status; - - - ACPI_FUNCTION_TRACE (EvMatchPrwAndGpe); - - - /* Check for a _PRW method under this device */ - - Status = AcpiNsGetNode (ObjHandle, METHOD_NAME__PRW, - ACPI_NS_NO_UPSEARCH, &PrwNode); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (AE_OK); - } - - /* Check if requested OwnerId matches this OwnerId */ - - if ((WalkInfo->ExecuteByOwnerId) && - (PrwNode->OwnerId != WalkInfo->OwnerId)) - { - return_ACPI_STATUS (AE_OK); - } - - /* Execute the _PRW */ - - Status = AcpiUtEvaluateObject (PrwNode, NULL, - ACPI_BTYPE_PACKAGE, &PkgDesc); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (AE_OK); - } - - /* The returned _PRW package must have at least two elements */ - - if (PkgDesc->Package.Count < 2) - { - goto Cleanup; - } - - /* Extract pointers from the input context */ - - GpeDevice = WalkInfo->GpeDevice; - GpeBlock = WalkInfo->GpeBlock; - - /* - * The _PRW object must return a package, we are only interested - * in the first element - */ - ObjDesc = PkgDesc->Package.Elements[0]; - - if (ObjDesc->Common.Type == ACPI_TYPE_INTEGER) - { - /* Use FADT-defined GPE device (from definition of _PRW) */ - - TargetGpeDevice = NULL; - if (GpeDevice) - { - TargetGpeDevice = AcpiGbl_FadtGpeDevice; - } - - /* Integer is the GPE number in the FADT described GPE blocks */ - - GpeNumber = (UINT32) ObjDesc->Integer.Value; - } - else if (ObjDesc->Common.Type == ACPI_TYPE_PACKAGE) - { - /* Package contains a GPE reference and GPE number within a GPE block */ - - if ((ObjDesc->Package.Count < 2) || - ((ObjDesc->Package.Elements[0])->Common.Type != - ACPI_TYPE_LOCAL_REFERENCE) || - ((ObjDesc->Package.Elements[1])->Common.Type != - ACPI_TYPE_INTEGER)) - { - goto Cleanup; - } - - /* Get GPE block reference and decode */ - - TargetGpeDevice = ObjDesc->Package.Elements[0]->Reference.Node; - GpeNumber = (UINT32) ObjDesc->Package.Elements[1]->Integer.Value; - } - else - { - /* Unknown type, just ignore it */ - - goto Cleanup; - } - - /* Get the GpeEventInfo for this GPE */ - - if (GpeDevice) - { - /* - * Is this GPE within this block? - * - * TRUE if and only if these conditions are true: - * 1) The GPE devices match. - * 2) The GPE index(number) is within the range of the Gpe Block - * associated with the GPE device. - */ - if (GpeDevice != TargetGpeDevice) - { - goto Cleanup; - } - - GpeEventInfo = AcpiEvLowGetGpeInfo (GpeNumber, GpeBlock); - } - else - { - /* GpeDevice is NULL, just match the TargetDevice and GpeNumber */ - - GpeEventInfo = AcpiEvGetGpeEventInfo (TargetGpeDevice, GpeNumber); - } - - if (GpeEventInfo) - { - if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)) - { - /* This GPE can wake the system */ - - GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE; - WalkInfo->Count++; - } - } - -Cleanup: - AcpiUtRemoveReference (PkgDesc); - return_ACPI_STATUS (AE_OK); -} - diff --git a/sys/contrib/dev/acpica/events/evgpeutil.c b/sys/contrib/dev/acpica/events/evgpeutil.c index c93a348..b7fd74a 100644 --- a/sys/contrib/dev/acpica/events/evgpeutil.c +++ b/sys/contrib/dev/acpica/events/evgpeutil.c @@ -241,6 +241,51 @@ AcpiEvValidGpeEvent ( /******************************************************************************* * + * FUNCTION: AcpiEvGetGpeDevice + * + * PARAMETERS: GPE_WALK_CALLBACK + * + * RETURN: Status + * + * DESCRIPTION: Matches the input GPE index (0-CurrentGpeCount) with a GPE + * block device. NULL if the GPE is one of the FADT-defined GPEs. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiEvGetGpeDevice ( + ACPI_GPE_XRUPT_INFO *GpeXruptInfo, + ACPI_GPE_BLOCK_INFO *GpeBlock, + void *Context) +{ + ACPI_GPE_DEVICE_INFO *Info = Context; + + + /* Increment Index by the number of GPEs in this block */ + + Info->NextBlockBaseIndex += GpeBlock->GpeCount; + + if (Info->Index < Info->NextBlockBaseIndex) + { + /* + * The GPE index is within this block, get the node. Leave the node + * NULL for the FADT-defined GPEs + */ + if ((GpeBlock->Node)->Type == ACPI_TYPE_DEVICE) + { + Info->GpeDevice = GpeBlock->Node; + } + + Info->Status = AE_OK; + return (AE_CTRL_END); + } + + return (AE_OK); +} + + +/******************************************************************************* + * * FUNCTION: AcpiEvGetGpeXruptBlock * * PARAMETERS: InterruptNumber - Interrupt for a GPE block diff --git a/sys/contrib/dev/acpica/events/evxface.c b/sys/contrib/dev/acpica/events/evxface.c index d68057a..b40d80d 100644 --- a/sys/contrib/dev/acpica/events/evxface.c +++ b/sys/contrib/dev/acpica/events/evxface.c @@ -177,6 +177,66 @@ ACPI_EXPORT_SYMBOL (AcpiInstallExceptionHandler) /******************************************************************************* * + * FUNCTION: AcpiInstallGlobalEventHandler + * + * PARAMETERS: Handler - Pointer to the global event handler function + * Context - Value passed to the handler on each event + * + * RETURN: Status + * + * DESCRIPTION: Saves the pointer to the handler function. The global handler + * is invoked upon each incoming GPE and Fixed Event. It is + * invoked at interrupt level at the time of the event dispatch. + * Can be used to update event counters, etc. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiInstallGlobalEventHandler ( + ACPI_GBL_EVENT_HANDLER Handler, + void *Context) +{ + ACPI_STATUS Status; + + + ACPI_FUNCTION_TRACE (AcpiInstallGlobalEventHandler); + + + /* Parameter validation */ + + if (!Handler) + { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + + /* Don't allow two handlers. */ + + if (AcpiGbl_GlobalEventHandler) + { + Status = AE_ALREADY_EXISTS; + goto Cleanup; + } + + AcpiGbl_GlobalEventHandler = Handler; + AcpiGbl_GlobalEventHandlerContext = Context; + + +Cleanup: + (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); + return_ACPI_STATUS (Status); +} + +ACPI_EXPORT_SYMBOL (AcpiInstallGlobalEventHandler) + + +/******************************************************************************* + * * FUNCTION: AcpiInstallFixedEventHandler * * PARAMETERS: Event - Event type to enable. @@ -691,11 +751,11 @@ AcpiInstallGpeHandler ( ACPI_HANDLE GpeDevice, UINT32 GpeNumber, UINT32 Type, - ACPI_EVENT_HANDLER Address, + ACPI_GPE_HANDLER Address, void *Context) { ACPI_GPE_EVENT_INFO *GpeEventInfo; - ACPI_HANDLER_INFO *Handler; + ACPI_GPE_HANDLER_INFO *Handler; ACPI_STATUS Status; ACPI_CPU_FLAGS Flags; @@ -716,13 +776,24 @@ AcpiInstallGpeHandler ( return_ACPI_STATUS (Status); } + /* Allocate and init handler object (before lock) */ + + Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_HANDLER_INFO)); + if (!Handler) + { + Status = AE_NO_MEMORY; + goto UnlockAndExit; + } + + Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); + /* Ensure that we have a valid GPE number */ GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); if (!GpeEventInfo) { Status = AE_BAD_PARAMETER; - goto UnlockAndExit; + goto FreeAndExit; } /* Make sure that there isn't a handler there already */ @@ -731,28 +802,40 @@ AcpiInstallGpeHandler ( ACPI_GPE_DISPATCH_HANDLER) { Status = AE_ALREADY_EXISTS; - goto UnlockAndExit; + goto FreeAndExit; } - /* Allocate and init handler object */ + Handler->Address = Address; + Handler->Context = Context; + Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode; + Handler->OriginalFlags = (UINT8) (GpeEventInfo->Flags & + (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK)); - Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_HANDLER_INFO)); - if (!Handler) + /* + * If the GPE is associated with a method, it may have been enabled + * automatically during initialization, in which case it has to be + * disabled now to avoid spurious execution of the handler. + */ + if (((Handler->OriginalFlags & ACPI_GPE_DISPATCH_METHOD) || + (Handler->OriginalFlags & ACPI_GPE_DISPATCH_NOTIFY)) && + GpeEventInfo->RuntimeCount) { - Status = AE_NO_MEMORY; - goto UnlockAndExit; - } + Handler->OriginallyEnabled = TRUE; + (void) AcpiEvRemoveGpeReference (GpeEventInfo); - Handler->Address = Address; - Handler->Context = Context; - Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode; + /* Sanity check of original type against new type */ + + if (Type != (UINT32) (GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK)) + { + ACPI_WARNING ((AE_INFO, "GPE type mismatch (level/edge)")); + } + } /* Install the handler */ - Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); GpeEventInfo->Dispatch.Handler = Handler; - /* Setup up dispatch flags to indicate handler (vs. method) */ + /* Setup up dispatch flags to indicate handler (vs. method/notify) */ GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); GpeEventInfo->Flags |= (UINT8) (Type | ACPI_GPE_DISPATCH_HANDLER); @@ -763,6 +846,11 @@ AcpiInstallGpeHandler ( UnlockAndExit: (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); return_ACPI_STATUS (Status); + +FreeAndExit: + AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); + ACPI_FREE (Handler); + goto UnlockAndExit; } ACPI_EXPORT_SYMBOL (AcpiInstallGpeHandler) @@ -787,10 +875,10 @@ ACPI_STATUS AcpiRemoveGpeHandler ( ACPI_HANDLE GpeDevice, UINT32 GpeNumber, - ACPI_EVENT_HANDLER Address) + ACPI_GPE_HANDLER Address) { ACPI_GPE_EVENT_INFO *GpeEventInfo; - ACPI_HANDLER_INFO *Handler; + ACPI_GPE_HANDLER_INFO *Handler; ACPI_STATUS Status; ACPI_CPU_FLAGS Flags; @@ -811,6 +899,8 @@ AcpiRemoveGpeHandler ( return_ACPI_STATUS (Status); } + Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); + /* Ensure that we have a valid GPE number */ GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); @@ -839,18 +929,25 @@ AcpiRemoveGpeHandler ( /* Remove the handler */ - Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); Handler = GpeEventInfo->Dispatch.Handler; /* Restore Method node (if any), set dispatch flags */ GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode; - GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK; /* Clear bits */ - if (Handler->MethodNode) + GpeEventInfo->Flags &= + ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); + GpeEventInfo->Flags |= Handler->OriginalFlags; + + /* + * If the GPE was previously associated with a method and it was + * enabled, it should be enabled at this point to restore the + * post-initialization configuration. + */ + if ((Handler->OriginalFlags & ACPI_GPE_DISPATCH_METHOD) && + Handler->OriginallyEnabled) { - GpeEventInfo->Flags |= ACPI_GPE_DISPATCH_METHOD; + (void) AcpiEvAddGpeReference (GpeEventInfo); } - AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); /* Now we can free the handler object */ @@ -858,6 +955,7 @@ AcpiRemoveGpeHandler ( UnlockAndExit: + AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); return_ACPI_STATUS (Status); } diff --git a/sys/contrib/dev/acpica/events/evxfevnt.c b/sys/contrib/dev/acpica/events/evxfevnt.c index 4cdacd0..5771a00 100644 --- a/sys/contrib/dev/acpica/events/evxfevnt.c +++ b/sys/contrib/dev/acpica/events/evxfevnt.c @@ -118,21 +118,11 @@ #include <contrib/dev/acpica/include/acpi.h> #include <contrib/dev/acpica/include/accommon.h> -#include <contrib/dev/acpica/include/acevents.h> -#include <contrib/dev/acpica/include/acnamesp.h> #include <contrib/dev/acpica/include/actables.h> #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME ("evxfevnt") -/* Local prototypes */ - -static ACPI_STATUS -AcpiEvGetGpeDevice ( - ACPI_GPE_XRUPT_INFO *GpeXruptInfo, - ACPI_GPE_BLOCK_INFO *GpeBlock, - void *Context); - /******************************************************************************* * @@ -307,290 +297,9 @@ ACPI_EXPORT_SYMBOL (AcpiEnableEvent) /******************************************************************************* * - * FUNCTION: AcpiGpeWakeup - * - * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 - * GpeNumber - GPE level within the GPE block - * Action - Enable or Disable - * - * RETURN: Status - * - * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. - * - ******************************************************************************/ - -ACPI_STATUS -AcpiGpeWakeup ( - ACPI_HANDLE GpeDevice, - UINT32 GpeNumber, - UINT8 Action) -{ - ACPI_STATUS Status = AE_OK; - ACPI_GPE_EVENT_INFO *GpeEventInfo; - ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; - ACPI_CPU_FLAGS Flags; - UINT32 RegisterBit; - - - ACPI_FUNCTION_TRACE (AcpiGpeWakeup); - - - Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); - - /* Ensure that we have a valid GPE number */ - - GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); - if (!GpeEventInfo) - { - Status = AE_BAD_PARAMETER; - goto UnlockAndExit; - } - - GpeRegisterInfo = GpeEventInfo->RegisterInfo; - if (!GpeRegisterInfo) - { - Status = AE_NOT_EXIST; - goto UnlockAndExit; - } - - RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo, GpeRegisterInfo); - - /* Perform the action */ - - switch (Action) - { - case ACPI_GPE_ENABLE: - ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit); - break; - - case ACPI_GPE_DISABLE: - ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit); - break; - - default: - ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action)); - Status = AE_BAD_PARAMETER; - break; - } - -UnlockAndExit: - AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); - return_ACPI_STATUS (Status); -} - -ACPI_EXPORT_SYMBOL (AcpiGpeWakeup) - - -/******************************************************************************* - * - * FUNCTION: AcpiEnableGpe - * - * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 - * GpeNumber - GPE level within the GPE block - * - * RETURN: Status - * - * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is - * hardware-enabled. - * - ******************************************************************************/ - -ACPI_STATUS -AcpiEnableGpe ( - ACPI_HANDLE GpeDevice, - UINT32 GpeNumber) -{ - ACPI_STATUS Status = AE_OK; - ACPI_GPE_EVENT_INFO *GpeEventInfo; - ACPI_CPU_FLAGS Flags; - - - ACPI_FUNCTION_TRACE (AcpiEnableGpe); - - - Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); - - /* Ensure that we have a valid GPE number */ - - GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); - if (!GpeEventInfo) - { - Status = AE_BAD_PARAMETER; - goto UnlockAndExit; - } - - if (GpeEventInfo->RuntimeCount == ACPI_UINT8_MAX) - { - Status = AE_LIMIT; /* Too many references */ - goto UnlockAndExit; - } - - GpeEventInfo->RuntimeCount++; - if (GpeEventInfo->RuntimeCount == 1) - { - Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo); - if (ACPI_SUCCESS (Status)) - { - Status = AcpiEvEnableGpe (GpeEventInfo); - } - if (ACPI_FAILURE (Status)) - { - GpeEventInfo->RuntimeCount--; - } - } - -UnlockAndExit: - AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); - return_ACPI_STATUS (Status); -} - -ACPI_EXPORT_SYMBOL (AcpiEnableGpe) - - -/******************************************************************************* - * - * FUNCTION: AcpiDisableGpe - * - * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 - * GpeNumber - GPE level within the GPE block - * - * RETURN: Status - * - * 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 -AcpiDisableGpe ( - ACPI_HANDLE GpeDevice, - UINT32 GpeNumber) -{ - ACPI_STATUS Status = AE_OK; - ACPI_GPE_EVENT_INFO *GpeEventInfo; - ACPI_CPU_FLAGS Flags; - - - ACPI_FUNCTION_TRACE (AcpiDisableGpe); - - - Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); - - /* Ensure that we have a valid GPE number */ - - GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); - if (!GpeEventInfo) - { - Status = AE_BAD_PARAMETER; - goto UnlockAndExit; - } - - /* Hardware-disable a runtime GPE on removal of the last reference */ - - if (!GpeEventInfo->RuntimeCount) - { - Status = AE_LIMIT; /* There are no references to remove */ - goto UnlockAndExit; - } - - GpeEventInfo->RuntimeCount--; - if (!GpeEventInfo->RuntimeCount) - { - Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo); - if (ACPI_SUCCESS (Status)) - { - Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE); - } - if (ACPI_FAILURE (Status)) - { - GpeEventInfo->RuntimeCount++; - } - } - -UnlockAndExit: - 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 = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE); - break; - - default: - Status = AE_BAD_PARAMETER; - break; - } - -UnlockAndExit: - AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); - return_ACPI_STATUS (Status); -} - -ACPI_EXPORT_SYMBOL (AcpiSetGpe) - - -/******************************************************************************* - * * FUNCTION: AcpiDisableEvent * - * PARAMETERS: Event - The fixed eventto be enabled + * PARAMETERS: Event - The fixed event to be disabled * Flags - Reserved * * RETURN: Status @@ -695,53 +404,6 @@ ACPI_EXPORT_SYMBOL (AcpiClearEvent) /******************************************************************************* * - * FUNCTION: AcpiClearGpe - * - * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 - * GpeNumber - GPE level within the GPE block - * - * RETURN: Status - * - * DESCRIPTION: Clear an ACPI event (general purpose) - * - ******************************************************************************/ - -ACPI_STATUS -AcpiClearGpe ( - ACPI_HANDLE GpeDevice, - UINT32 GpeNumber) -{ - ACPI_STATUS Status = AE_OK; - ACPI_GPE_EVENT_INFO *GpeEventInfo; - ACPI_CPU_FLAGS Flags; - - - ACPI_FUNCTION_TRACE (AcpiClearGpe); - - - Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); - - /* Ensure that we have a valid GPE number */ - - GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); - if (!GpeEventInfo) - { - Status = AE_BAD_PARAMETER; - goto UnlockAndExit; - } - - Status = AcpiHwClearGpe (GpeEventInfo); - -UnlockAndExit: - AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); - return_ACPI_STATUS (Status); -} - -ACPI_EXPORT_SYMBOL (AcpiClearGpe) - - -/******************************************************************************* - * * FUNCTION: AcpiGetEventStatus * * PARAMETERS: Event - The fixed event @@ -788,400 +450,3 @@ AcpiGetEventStatus ( ACPI_EXPORT_SYMBOL (AcpiGetEventStatus) -/******************************************************************************* - * - * FUNCTION: AcpiGetGpeStatus - * - * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 - * GpeNumber - GPE level within the GPE block - * EventStatus - Where the current status of the event will - * be returned - * - * RETURN: Status - * - * DESCRIPTION: Get status of an event (general purpose) - * - ******************************************************************************/ - -ACPI_STATUS -AcpiGetGpeStatus ( - ACPI_HANDLE GpeDevice, - UINT32 GpeNumber, - ACPI_EVENT_STATUS *EventStatus) -{ - ACPI_STATUS Status = AE_OK; - ACPI_GPE_EVENT_INFO *GpeEventInfo; - ACPI_CPU_FLAGS Flags; - - - ACPI_FUNCTION_TRACE (AcpiGetGpeStatus); - - - Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); - - /* Ensure that we have a valid GPE number */ - - GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); - if (!GpeEventInfo) - { - Status = AE_BAD_PARAMETER; - goto UnlockAndExit; - } - - /* Obtain status on the requested GPE number */ - - Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus); - -UnlockAndExit: - AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); - return_ACPI_STATUS (Status); -} - -ACPI_EXPORT_SYMBOL (AcpiGetGpeStatus) - - -/******************************************************************************* - * - * FUNCTION: AcpiInstallGpeBlock - * - * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device - * GpeBlockAddress - Address and SpaceID - * RegisterCount - Number of GPE register pairs in the block - * InterruptNumber - H/W interrupt for the block - * - * RETURN: Status - * - * DESCRIPTION: Create and Install a block of GPE registers - * - ******************************************************************************/ - -ACPI_STATUS -AcpiInstallGpeBlock ( - ACPI_HANDLE GpeDevice, - ACPI_GENERIC_ADDRESS *GpeBlockAddress, - UINT32 RegisterCount, - UINT32 InterruptNumber) -{ - ACPI_STATUS Status; - ACPI_OPERAND_OBJECT *ObjDesc; - ACPI_NAMESPACE_NODE *Node; - ACPI_GPE_BLOCK_INFO *GpeBlock; - - - ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock); - - - if ((!GpeDevice) || - (!GpeBlockAddress) || - (!RegisterCount)) - { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } - - Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (Status)) - { - return (Status); - } - - Node = AcpiNsValidateHandle (GpeDevice); - if (!Node) - { - Status = AE_BAD_PARAMETER; - goto UnlockAndExit; - } - - /* - * For user-installed GPE Block Devices, the GpeBlockBaseNumber - * is always zero - */ - Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress, RegisterCount, - 0, InterruptNumber, &GpeBlock); - if (ACPI_FAILURE (Status)) - { - goto UnlockAndExit; - } - - /* Install block in the DeviceObject attached to the node */ - - ObjDesc = AcpiNsGetAttachedObject (Node); - if (!ObjDesc) - { - /* - * No object, create a new one (Device nodes do not always have - * an attached object) - */ - ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE); - if (!ObjDesc) - { - Status = AE_NO_MEMORY; - goto UnlockAndExit; - } - - Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE); - - /* Remove local reference to the object */ - - AcpiUtRemoveReference (ObjDesc); - if (ACPI_FAILURE (Status)) - { - goto UnlockAndExit; - } - } - - /* 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); - return_ACPI_STATUS (Status); -} - -ACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock) - - -/******************************************************************************* - * - * FUNCTION: AcpiRemoveGpeBlock - * - * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device - * - * RETURN: Status - * - * DESCRIPTION: Remove a previously installed block of GPE registers - * - ******************************************************************************/ - -ACPI_STATUS -AcpiRemoveGpeBlock ( - ACPI_HANDLE GpeDevice) -{ - ACPI_OPERAND_OBJECT *ObjDesc; - ACPI_STATUS Status; - ACPI_NAMESPACE_NODE *Node; - - - ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock); - - - if (!GpeDevice) - { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } - - Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (Status)) - { - return (Status); - } - - Node = AcpiNsValidateHandle (GpeDevice); - if (!Node) - { - Status = AE_BAD_PARAMETER; - goto UnlockAndExit; - } - - /* Get the DeviceObject attached to the node */ - - ObjDesc = AcpiNsGetAttachedObject (Node); - if (!ObjDesc || - !ObjDesc->Device.GpeBlock) - { - return_ACPI_STATUS (AE_NULL_OBJECT); - } - - /* Delete the GPE block (but not the DeviceObject) */ - - Status = AcpiEvDeleteGpeBlock (ObjDesc->Device.GpeBlock); - if (ACPI_SUCCESS (Status)) - { - ObjDesc->Device.GpeBlock = NULL; - } - -UnlockAndExit: - (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); - return_ACPI_STATUS (Status); -} - -ACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock) - - -/******************************************************************************* - * - * FUNCTION: AcpiGetGpeDevice - * - * PARAMETERS: Index - System GPE index (0-CurrentGpeCount) - * GpeDevice - Where the parent GPE Device is returned - * - * RETURN: Status - * - * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL - * gpe device indicates that the gpe number is contained in one of - * the FADT-defined gpe blocks. Otherwise, the GPE block device. - * - ******************************************************************************/ - -ACPI_STATUS -AcpiGetGpeDevice ( - UINT32 Index, - ACPI_HANDLE *GpeDevice) -{ - ACPI_GPE_DEVICE_INFO Info; - ACPI_STATUS Status; - - - ACPI_FUNCTION_TRACE (AcpiGetGpeDevice); - - - if (!GpeDevice) - { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } - - if (Index >= AcpiCurrentGpeCount) - { - return_ACPI_STATUS (AE_NOT_EXIST); - } - - /* Setup and walk the GPE list */ - - Info.Index = Index; - Info.Status = AE_NOT_EXIST; - Info.GpeDevice = NULL; - Info.NextBlockBaseIndex = 0; - - Status = AcpiEvWalkGpeList (AcpiEvGetGpeDevice, &Info); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } - - *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice); - return_ACPI_STATUS (Info.Status); -} - -ACPI_EXPORT_SYMBOL (AcpiGetGpeDevice) - - -/******************************************************************************* - * - * FUNCTION: AcpiEvGetGpeDevice - * - * PARAMETERS: GPE_WALK_CALLBACK - * - * RETURN: Status - * - * DESCRIPTION: Matches the input GPE index (0-CurrentGpeCount) with a GPE - * block device. NULL if the GPE is one of the FADT-defined GPEs. - * - ******************************************************************************/ - -static ACPI_STATUS -AcpiEvGetGpeDevice ( - ACPI_GPE_XRUPT_INFO *GpeXruptInfo, - ACPI_GPE_BLOCK_INFO *GpeBlock, - void *Context) -{ - ACPI_GPE_DEVICE_INFO *Info = Context; - - - /* Increment Index by the number of GPEs in this block */ - - Info->NextBlockBaseIndex += GpeBlock->GpeCount; - - if (Info->Index < Info->NextBlockBaseIndex) - { - /* - * The GPE index is within this block, get the node. Leave the node - * NULL for the FADT-defined GPEs - */ - if ((GpeBlock->Node)->Type == ACPI_TYPE_DEVICE) - { - Info->GpeDevice = GpeBlock->Node; - } - - Info->Status = AE_OK; - return (AE_CTRL_END); - } - - return (AE_OK); -} - - -/****************************************************************************** - * - * FUNCTION: AcpiDisableAllGpes - * - * PARAMETERS: None - * - * RETURN: Status - * - * DESCRIPTION: Disable and clear all GPEs in all GPE blocks - * - ******************************************************************************/ - -ACPI_STATUS -AcpiDisableAllGpes ( - void) -{ - ACPI_STATUS Status; - - - ACPI_FUNCTION_TRACE (AcpiDisableAllGpes); - - - Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } - - Status = AcpiHwDisableAllGpes (); - (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); - - return_ACPI_STATUS (Status); -} - - -/****************************************************************************** - * - * FUNCTION: AcpiEnableAllRuntimeGpes - * - * PARAMETERS: None - * - * RETURN: Status - * - * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks - * - ******************************************************************************/ - -ACPI_STATUS -AcpiEnableAllRuntimeGpes ( - void) -{ - ACPI_STATUS Status; - - - ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes); - - - Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } - - Status = AcpiHwEnableAllRuntimeGpes (); - (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); - - return_ACPI_STATUS (Status); -} - - diff --git a/sys/contrib/dev/acpica/events/evxfgpe.c b/sys/contrib/dev/acpica/events/evxfgpe.c new file mode 100644 index 0000000..d714ff6 --- /dev/null +++ b/sys/contrib/dev/acpica/events/evxfgpe.c @@ -0,0 +1,962 @@ +/****************************************************************************** + * + * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs) + * + *****************************************************************************/ + +/****************************************************************************** + * + * 1. Copyright Notice + * + * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. + * All rights reserved. + * + * 2. License + * + * 2.1. This is your license from Intel Corp. under its intellectual property + * rights. You may have additional license terms from the party that provided + * you this software, covering your right to use that party's intellectual + * property rights. + * + * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a + * copy of the source code appearing in this file ("Covered Code") an + * irrevocable, perpetual, worldwide license under Intel's copyrights in the + * base code distributed originally by Intel ("Original Intel Code") to copy, + * make derivatives, distribute, use and display any portion of the Covered + * Code in any form, with the right to sublicense such rights; and + * + * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent + * license (with the right to sublicense), under only those claims of Intel + * patents that are infringed by the Original Intel Code, to make, use, sell, + * offer to sell, and import the Covered Code and derivative works thereof + * solely to the minimum extent necessary to exercise the above copyright + * license, and in no event shall the patent license extend to any additions + * to or modifications of the Original Intel Code. No other license or right + * is granted directly or by implication, estoppel or otherwise; + * + * The above copyright and patent license is granted only if the following + * conditions are met: + * + * 3. Conditions + * + * 3.1. Redistribution of Source with Rights to Further Distribute Source. + * Redistribution of source code of any substantial portion of the Covered + * Code or modification with rights to further distribute source must include + * the above Copyright Notice, the above License, this list of Conditions, + * and the following Disclaimer and Export Compliance provision. In addition, + * Licensee must cause all Covered Code to which Licensee contributes to + * contain a file documenting the changes Licensee made to create that Covered + * Code and the date of any change. Licensee must include in that file the + * documentation of any changes made by any predecessor Licensee. Licensee + * must include a prominent statement that the modification is derived, + * directly or indirectly, from Original Intel Code. + * + * 3.2. Redistribution of Source with no Rights to Further Distribute Source. + * Redistribution of source code of any substantial portion of the Covered + * Code or modification without rights to further distribute source must + * include the following Disclaimer and Export Compliance provision in the + * documentation and/or other materials provided with distribution. In + * addition, Licensee may not authorize further sublicense of source of any + * portion of the Covered Code, and must include terms to the effect that the + * license from Licensee to its licensee is limited to the intellectual + * property embodied in the software Licensee provides to its licensee, and + * not to intellectual property embodied in modifications its licensee may + * make. + * + * 3.3. Redistribution of Executable. Redistribution in executable form of any + * substantial portion of the Covered Code or modification must reproduce the + * above Copyright Notice, and the following Disclaimer and Export Compliance + * provision in the documentation and/or other materials provided with the + * distribution. + * + * 3.4. Intel retains all right, title, and interest in and to the Original + * Intel Code. + * + * 3.5. Neither the name Intel nor any other trademark owned or controlled by + * Intel shall be used in advertising or otherwise to promote the sale, use or + * other dealings in products derived from or relating to the Covered Code + * without prior written authorization from Intel. + * + * 4. Disclaimer and Export Compliance + * + * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED + * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE + * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, + * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY + * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY + * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A + * PARTICULAR PURPOSE. + * + * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES + * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR + * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, + * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY + * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL + * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS + * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY + * LIMITED REMEDY. + * + * 4.3. Licensee shall not export, either directly or indirectly, any of this + * software or system incorporating such software without first obtaining any + * required license or other approval from the U. S. Department of Commerce or + * any other agency or department of the United States Government. In the + * event Licensee exports any such software from the United States or + * re-exports any such software from a foreign destination, Licensee shall + * ensure that the distribution and export/re-export of the software is in + * compliance with all laws, regulations, orders, or other restrictions of the + * U.S. Export Administration Regulations. Licensee agrees that neither it nor + * any of its subsidiaries will export/re-export any technical data, process, + * software, or service, directly or indirectly, to any country for which the + * United States government or any agency thereof requires an export license, + * other governmental approval, or letter of assurance, without first obtaining + * such license, approval or letter. + * + *****************************************************************************/ + + +#define __EVXFGPE_C__ + +#include <contrib/dev/acpica/include/acpi.h> +#include <contrib/dev/acpica/include/accommon.h> +#include <contrib/dev/acpica/include/acevents.h> +#include <contrib/dev/acpica/include/acnamesp.h> + +#define _COMPONENT ACPI_EVENTS + ACPI_MODULE_NAME ("evxfgpe") + + +/******************************************************************************* + * + * FUNCTION: AcpiUpdateAllGpes + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Complete GPE initialization and enable all GPEs that have + * associated _Lxx or _Exx methods and are not pointed to by any + * device _PRW methods (this indicates that these GPEs are + * generally intended for system or device wakeup. Such GPEs + * have to be enabled directly when the devices whose _PRW + * methods point to them are set up for wakeup signaling.) + * + * NOTE: Should be called after any GPEs are added to the system. Primarily, + * after the system _PRW methods have been run, but also after a GPE Block + * Device has been added or if any new GPE methods have been added via a + * dynamic table load. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiUpdateAllGpes ( + void) +{ + ACPI_STATUS Status; + + + ACPI_FUNCTION_TRACE (AcpiUpdateGpes); + + + Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + + if (AcpiGbl_AllGpesInitialized) + { + goto UnlockAndExit; + } + + Status = AcpiEvWalkGpeList (AcpiEvInitializeGpeBlock, NULL); + if (ACPI_SUCCESS (Status)) + { + AcpiGbl_AllGpesInitialized = TRUE; + } + +UnlockAndExit: + (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); + return_ACPI_STATUS (Status); +} + +ACPI_EXPORT_SYMBOL (AcpiUpdateAllGpes) + + +/******************************************************************************* + * + * FUNCTION: AcpiEnableGpe + * + * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 + * GpeNumber - GPE level within the GPE block + * + * RETURN: Status + * + * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is + * hardware-enabled. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiEnableGpe ( + ACPI_HANDLE GpeDevice, + UINT32 GpeNumber) +{ + ACPI_STATUS Status = AE_BAD_PARAMETER; + ACPI_GPE_EVENT_INFO *GpeEventInfo; + ACPI_CPU_FLAGS Flags; + + + ACPI_FUNCTION_TRACE (AcpiEnableGpe); + + + Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); + + /* Ensure that we have a valid GPE number */ + + GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); + if (GpeEventInfo) + { + Status = AcpiEvAddGpeReference (GpeEventInfo); + } + + AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); + return_ACPI_STATUS (Status); +} + +ACPI_EXPORT_SYMBOL (AcpiEnableGpe) + + +/******************************************************************************* + * + * FUNCTION: AcpiDisableGpe + * + * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 + * GpeNumber - GPE level within the GPE block + * + * RETURN: Status + * + * 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 +AcpiDisableGpe ( + ACPI_HANDLE GpeDevice, + UINT32 GpeNumber) +{ + ACPI_STATUS Status = AE_BAD_PARAMETER; + ACPI_GPE_EVENT_INFO *GpeEventInfo; + ACPI_CPU_FLAGS Flags; + + + ACPI_FUNCTION_TRACE (AcpiDisableGpe); + + + Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); + + /* Ensure that we have a valid GPE number */ + + GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); + if (GpeEventInfo) + { + Status = AcpiEvRemoveGpeReference (GpeEventInfo); + } + + 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 = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE); + break; + + default: + Status = AE_BAD_PARAMETER; + break; + } + +UnlockAndExit: + AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); + return_ACPI_STATUS (Status); +} + +ACPI_EXPORT_SYMBOL (AcpiSetGpe) + + +/******************************************************************************* + * + * FUNCTION: AcpiSetupGpeForWake + * + * PARAMETERS: WakeDevice - Device associated with the GPE (via _PRW) + * GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 + * GpeNumber - GPE level within the GPE block + * + * RETURN: Status + * + * DESCRIPTION: Mark a GPE as having the ability to wake the system. This + * interface is intended to be used as the host executes the + * _PRW methods (Power Resources for Wake) in the system tables. + * Each _PRW appears under a Device Object (The WakeDevice), and + * contains the info for the wake GPE associated with the + * WakeDevice. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiSetupGpeForWake ( + ACPI_HANDLE WakeDevice, + ACPI_HANDLE GpeDevice, + UINT32 GpeNumber) +{ + ACPI_STATUS Status = AE_BAD_PARAMETER; + ACPI_GPE_EVENT_INFO *GpeEventInfo; + ACPI_NAMESPACE_NODE *DeviceNode; + ACPI_CPU_FLAGS Flags; + + + ACPI_FUNCTION_TRACE (AcpiSetupGpeForWake); + + + /* Parameter Validation */ + + if (!WakeDevice) + { + /* + * By forcing WakeDevice to be valid, we automatically enable the + * implicit notify feature on all hosts. + */ + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + /* Validate WakeDevice is of type Device */ + + DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WakeDevice); + if (DeviceNode->Type != ACPI_TYPE_DEVICE) + { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); + + /* Ensure that we have a valid GPE number */ + + GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); + if (GpeEventInfo) + { + /* + * If there is no method or handler for this GPE, then the + * WakeDevice will be notified whenever this GPE fires (aka + * "implicit notify") Note: The GPE is assumed to be + * level-triggered (for windows compatibility). + */ + if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == + ACPI_GPE_DISPATCH_NONE) + { + GpeEventInfo->Flags = + (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED); + GpeEventInfo->Dispatch.DeviceNode = DeviceNode; + } + + GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE; + Status = AE_OK; + } + + AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); + return_ACPI_STATUS (Status); +} + +ACPI_EXPORT_SYMBOL (AcpiSetupGpeForWake) + + +/******************************************************************************* + * + * FUNCTION: AcpiSetGpeWakeMask + * + * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 + * GpeNumber - GPE level within the GPE block + * Action - Enable or Disable + * + * RETURN: Status + * + * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must + * already be marked as a WAKE GPE. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiSetGpeWakeMask ( + ACPI_HANDLE GpeDevice, + UINT32 GpeNumber, + UINT8 Action) +{ + ACPI_STATUS Status = AE_OK; + ACPI_GPE_EVENT_INFO *GpeEventInfo; + ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; + ACPI_CPU_FLAGS Flags; + UINT32 RegisterBit; + + + ACPI_FUNCTION_TRACE (AcpiSetGpeWakeMask); + + + Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); + + /* + * Ensure that we have a valid GPE number and that this GPE is in + * fact a wake GPE + */ + GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); + if (!GpeEventInfo) + { + Status = AE_BAD_PARAMETER; + goto UnlockAndExit; + } + + if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)) + { + Status = AE_TYPE; + goto UnlockAndExit; + } + + GpeRegisterInfo = GpeEventInfo->RegisterInfo; + if (!GpeRegisterInfo) + { + Status = AE_NOT_EXIST; + goto UnlockAndExit; + } + + RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo, GpeRegisterInfo); + + /* Perform the action */ + + switch (Action) + { + case ACPI_GPE_ENABLE: + ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit); + break; + + case ACPI_GPE_DISABLE: + ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit); + break; + + default: + ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action)); + Status = AE_BAD_PARAMETER; + break; + } + +UnlockAndExit: + AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); + return_ACPI_STATUS (Status); +} + +ACPI_EXPORT_SYMBOL (AcpiSetGpeWakeMask) + + +/******************************************************************************* + * + * FUNCTION: AcpiClearGpe + * + * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 + * GpeNumber - GPE level within the GPE block + * + * RETURN: Status + * + * DESCRIPTION: Clear an ACPI event (general purpose) + * + ******************************************************************************/ + +ACPI_STATUS +AcpiClearGpe ( + ACPI_HANDLE GpeDevice, + UINT32 GpeNumber) +{ + ACPI_STATUS Status = AE_OK; + ACPI_GPE_EVENT_INFO *GpeEventInfo; + ACPI_CPU_FLAGS Flags; + + + ACPI_FUNCTION_TRACE (AcpiClearGpe); + + + Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); + + /* Ensure that we have a valid GPE number */ + + GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); + if (!GpeEventInfo) + { + Status = AE_BAD_PARAMETER; + goto UnlockAndExit; + } + + Status = AcpiHwClearGpe (GpeEventInfo); + +UnlockAndExit: + AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); + return_ACPI_STATUS (Status); +} + +ACPI_EXPORT_SYMBOL (AcpiClearGpe) + + +/******************************************************************************* + * + * FUNCTION: AcpiGetGpeStatus + * + * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 + * GpeNumber - GPE level within the GPE block + * EventStatus - Where the current status of the event + * will be returned + * + * RETURN: Status + * + * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled) + * + ******************************************************************************/ + +ACPI_STATUS +AcpiGetGpeStatus ( + ACPI_HANDLE GpeDevice, + UINT32 GpeNumber, + ACPI_EVENT_STATUS *EventStatus) +{ + ACPI_STATUS Status = AE_OK; + ACPI_GPE_EVENT_INFO *GpeEventInfo; + ACPI_CPU_FLAGS Flags; + + + ACPI_FUNCTION_TRACE (AcpiGetGpeStatus); + + + Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); + + /* Ensure that we have a valid GPE number */ + + GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); + if (!GpeEventInfo) + { + Status = AE_BAD_PARAMETER; + goto UnlockAndExit; + } + + /* Obtain status on the requested GPE number */ + + Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus); + +UnlockAndExit: + AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); + return_ACPI_STATUS (Status); +} + +ACPI_EXPORT_SYMBOL (AcpiGetGpeStatus) + + +/******************************************************************************* + * + * FUNCTION: AcpiFinishGpe + * + * PARAMETERS: GpeDevice - Namespace node for the GPE Block + * (NULL for FADT defined GPEs) + * GpeNumber - GPE level within the GPE block + * + * RETURN: Status + * + * DESCRIPTION: Clear and conditionally reenable a GPE. This completes the GPE + * processing. Intended for use by asynchronous host-installed + * GPE handlers. The GPE is only reenabled if the EnableForRun bit + * is set in the GPE info. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiFinishGpe ( + ACPI_HANDLE GpeDevice, + UINT32 GpeNumber) +{ + ACPI_GPE_EVENT_INFO *GpeEventInfo; + ACPI_STATUS Status; + ACPI_CPU_FLAGS Flags; + + + ACPI_FUNCTION_TRACE (AcpiFinishGpe); + + + Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); + + /* Ensure that we have a valid GPE number */ + + GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); + if (!GpeEventInfo) + { + Status = AE_BAD_PARAMETER; + goto UnlockAndExit; + } + + Status = AcpiEvFinishGpe (GpeEventInfo); + +UnlockAndExit: + AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); + return_ACPI_STATUS (Status); +} + +ACPI_EXPORT_SYMBOL (AcpiFinishGpe) + + +/****************************************************************************** + * + * FUNCTION: AcpiDisableAllGpes + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Disable and clear all GPEs in all GPE blocks + * + ******************************************************************************/ + +ACPI_STATUS +AcpiDisableAllGpes ( + void) +{ + ACPI_STATUS Status; + + + ACPI_FUNCTION_TRACE (AcpiDisableAllGpes); + + + Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + + Status = AcpiHwDisableAllGpes (); + (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); + + return_ACPI_STATUS (Status); +} + +ACPI_EXPORT_SYMBOL (AcpiDisableAllGpes) + + +/****************************************************************************** + * + * FUNCTION: AcpiEnableAllRuntimeGpes + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks + * + ******************************************************************************/ + +ACPI_STATUS +AcpiEnableAllRuntimeGpes ( + void) +{ + ACPI_STATUS Status; + + + ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes); + + + Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + + Status = AcpiHwEnableAllRuntimeGpes (); + (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); + + return_ACPI_STATUS (Status); +} + +ACPI_EXPORT_SYMBOL (AcpiEnableAllRuntimeGpes) + + +/******************************************************************************* + * + * FUNCTION: AcpiInstallGpeBlock + * + * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device + * GpeBlockAddress - Address and SpaceID + * RegisterCount - Number of GPE register pairs in the block + * InterruptNumber - H/W interrupt for the block + * + * RETURN: Status + * + * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not + * enabled here. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiInstallGpeBlock ( + ACPI_HANDLE GpeDevice, + ACPI_GENERIC_ADDRESS *GpeBlockAddress, + UINT32 RegisterCount, + UINT32 InterruptNumber) +{ + ACPI_STATUS Status; + ACPI_OPERAND_OBJECT *ObjDesc; + ACPI_NAMESPACE_NODE *Node; + ACPI_GPE_BLOCK_INFO *GpeBlock; + + + ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock); + + + if ((!GpeDevice) || + (!GpeBlockAddress) || + (!RegisterCount)) + { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + Node = AcpiNsValidateHandle (GpeDevice); + if (!Node) + { + Status = AE_BAD_PARAMETER; + goto UnlockAndExit; + } + + /* + * For user-installed GPE Block Devices, the GpeBlockBaseNumber + * is always zero + */ + Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress, RegisterCount, + 0, InterruptNumber, &GpeBlock); + if (ACPI_FAILURE (Status)) + { + goto UnlockAndExit; + } + + /* Install block in the DeviceObject attached to the node */ + + ObjDesc = AcpiNsGetAttachedObject (Node); + if (!ObjDesc) + { + /* + * No object, create a new one (Device nodes do not always have + * an attached object) + */ + ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE); + if (!ObjDesc) + { + Status = AE_NO_MEMORY; + goto UnlockAndExit; + } + + Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE); + + /* Remove local reference to the object */ + + AcpiUtRemoveReference (ObjDesc); + if (ACPI_FAILURE (Status)) + { + goto UnlockAndExit; + } + } + + /* Now install the GPE block in the DeviceObject */ + + ObjDesc->Device.GpeBlock = GpeBlock; + + +UnlockAndExit: + (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); + return_ACPI_STATUS (Status); +} + +ACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock) + + +/******************************************************************************* + * + * FUNCTION: AcpiRemoveGpeBlock + * + * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device + * + * RETURN: Status + * + * DESCRIPTION: Remove a previously installed block of GPE registers + * + ******************************************************************************/ + +ACPI_STATUS +AcpiRemoveGpeBlock ( + ACPI_HANDLE GpeDevice) +{ + ACPI_OPERAND_OBJECT *ObjDesc; + ACPI_STATUS Status; + ACPI_NAMESPACE_NODE *Node; + + + ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock); + + + if (!GpeDevice) + { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + + Node = AcpiNsValidateHandle (GpeDevice); + if (!Node) + { + Status = AE_BAD_PARAMETER; + goto UnlockAndExit; + } + + /* Get the DeviceObject attached to the node */ + + ObjDesc = AcpiNsGetAttachedObject (Node); + if (!ObjDesc || + !ObjDesc->Device.GpeBlock) + { + return_ACPI_STATUS (AE_NULL_OBJECT); + } + + /* Delete the GPE block (but not the DeviceObject) */ + + Status = AcpiEvDeleteGpeBlock (ObjDesc->Device.GpeBlock); + if (ACPI_SUCCESS (Status)) + { + ObjDesc->Device.GpeBlock = NULL; + } + +UnlockAndExit: + (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); + return_ACPI_STATUS (Status); +} + +ACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock) + + +/******************************************************************************* + * + * FUNCTION: AcpiGetGpeDevice + * + * PARAMETERS: Index - System GPE index (0-CurrentGpeCount) + * GpeDevice - Where the parent GPE Device is returned + * + * RETURN: Status + * + * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL + * gpe device indicates that the gpe number is contained in one of + * the FADT-defined gpe blocks. Otherwise, the GPE block device. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiGetGpeDevice ( + UINT32 Index, + ACPI_HANDLE *GpeDevice) +{ + ACPI_GPE_DEVICE_INFO Info; + ACPI_STATUS Status; + + + ACPI_FUNCTION_TRACE (AcpiGetGpeDevice); + + + if (!GpeDevice) + { + return_ACPI_STATUS (AE_BAD_PARAMETER); + } + + if (Index >= AcpiCurrentGpeCount) + { + return_ACPI_STATUS (AE_NOT_EXIST); + } + + /* Setup and walk the GPE list */ + + Info.Index = Index; + Info.Status = AE_NOT_EXIST; + Info.GpeDevice = NULL; + Info.NextBlockBaseIndex = 0; + + Status = AcpiEvWalkGpeList (AcpiEvGetGpeDevice, &Info); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + + *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice); + return_ACPI_STATUS (Info.Status); +} + +ACPI_EXPORT_SYMBOL (AcpiGetGpeDevice) diff --git a/sys/contrib/dev/acpica/executer/exconfig.c b/sys/contrib/dev/acpica/executer/exconfig.c index 918fc1c..f84424b 100644 --- a/sys/contrib/dev/acpica/executer/exconfig.c +++ b/sys/contrib/dev/acpica/executer/exconfig.c @@ -206,8 +206,11 @@ AcpiExAddTable ( AcpiNsExecModuleCodeList (); AcpiExEnterInterpreter (); - /* Update GPEs for any new _PRW or _Lxx/_Exx methods. Ignore errors */ - + /* + * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is + * responsible for discovering any new wake GPEs by running _PRW methods + * that may have been loaded by this table. + */ Status = AcpiTbGetOwnerId (TableIndex, &OwnerId); if (ACPI_SUCCESS (Status)) { diff --git a/sys/contrib/dev/acpica/include/acdebug.h b/sys/contrib/dev/acpica/include/acdebug.h index 7103e4f..50d88ce 100644 --- a/sys/contrib/dev/acpica/include/acdebug.h +++ b/sys/contrib/dev/acpica/include/acdebug.h @@ -117,7 +117,7 @@ #define __ACDEBUG_H__ -#define ACPI_DEBUG_BUFFER_SIZE 4196 +#define ACPI_DEBUG_BUFFER_SIZE 0x4000 /* 16K buffer for return objects */ typedef struct CommandInfo { diff --git a/sys/contrib/dev/acpica/include/acdisasm.h b/sys/contrib/dev/acpica/include/acdisasm.h index cdd7729..e59a01b 100644 --- a/sys/contrib/dev/acpica/include/acdisasm.h +++ b/sys/contrib/dev/acpica/include/acdisasm.h @@ -189,6 +189,7 @@ typedef const struct acpi_dmtable_info #define ACPI_DMT_EINJINST 38 #define ACPI_DMT_ERSTACT 39 #define ACPI_DMT_ERSTINST 40 +#define ACPI_DMT_ACCWIDTH 41 typedef diff --git a/sys/contrib/dev/acpica/include/acevents.h b/sys/contrib/dev/acpica/include/acevents.h index c03e9e3..fe25ab2 100644 --- a/sys/contrib/dev/acpica/include/acevents.h +++ b/sys/contrib/dev/acpica/include/acevents.h @@ -128,10 +128,6 @@ ACPI_STATUS AcpiEvInstallXruptHandlers ( void); -ACPI_STATUS -AcpiEvInstallFadtGpes ( - void); - UINT32 AcpiEvFixedEventDetect ( void); @@ -181,6 +177,14 @@ ACPI_STATUS AcpiEvEnableGpe ( ACPI_GPE_EVENT_INFO *GpeEventInfo); +ACPI_STATUS +AcpiEvAddGpeReference ( + ACPI_GPE_EVENT_INFO *GpeEventInfo); + +ACPI_STATUS +AcpiEvRemoveGpeReference ( + ACPI_GPE_EVENT_INFO *GpeEventInfo); + ACPI_GPE_EVENT_INFO * AcpiEvGetGpeEventInfo ( ACPI_HANDLE GpeDevice, @@ -191,6 +195,10 @@ AcpiEvLowGetGpeInfo ( UINT32 GpeNumber, ACPI_GPE_BLOCK_INFO *GpeBlock); +ACPI_STATUS +AcpiEvFinishGpe ( + ACPI_GPE_EVENT_INFO *GpeEventInfo); + /* * evgpeblk - Upper-level GPE block support @@ -206,8 +214,9 @@ AcpiEvCreateGpeBlock ( ACPI_STATUS AcpiEvInitializeGpeBlock ( - ACPI_NAMESPACE_NODE *GpeDevice, - ACPI_GPE_BLOCK_INFO *GpeBlock); + ACPI_GPE_XRUPT_INFO *GpeXruptInfo, + ACPI_GPE_BLOCK_INFO *GpeBlock, + void *Context); ACPI_STATUS AcpiEvDeleteGpeBlock ( @@ -215,6 +224,7 @@ AcpiEvDeleteGpeBlock ( UINT32 AcpiEvGpeDispatch ( + ACPI_NAMESPACE_NODE *GpeDevice, ACPI_GPE_EVENT_INFO *GpeEventInfo, UINT32 GpeNumber); @@ -236,13 +246,6 @@ AcpiEvMatchGpeMethod ( void *Context, void **ReturnValue); -ACPI_STATUS -AcpiEvMatchPrwAndGpe ( - ACPI_HANDLE ObjHandle, - UINT32 Level, - void *Context, - void **ReturnValue); - /* * evgpeutil - GPE utilities */ @@ -255,6 +258,12 @@ BOOLEAN AcpiEvValidGpeEvent ( ACPI_GPE_EVENT_INFO *GpeEventInfo); +ACPI_STATUS +AcpiEvGetGpeDevice ( + ACPI_GPE_XRUPT_INFO *GpeXruptInfo, + ACPI_GPE_BLOCK_INFO *GpeBlock, + void *Context); + ACPI_GPE_XRUPT_INFO * AcpiEvGetGpeXruptBlock ( UINT32 InterruptNumber); diff --git a/sys/contrib/dev/acpica/include/acglobal.h b/sys/contrib/dev/acpica/include/acglobal.h index 2e158fb..68cb077 100644 --- a/sys/contrib/dev/acpica/include/acglobal.h +++ b/sys/contrib/dev/acpica/include/acglobal.h @@ -174,13 +174,6 @@ UINT8 ACPI_INIT_GLOBAL (AcpiGbl_AllMethodsSerialized, FALSE); UINT8 ACPI_INIT_GLOBAL (AcpiGbl_CreateOsiMethod, TRUE); /* - * Disable wakeup GPEs during runtime? Default is TRUE because WAKE and - * RUNTIME GPEs should never be shared, and WAKE GPEs should typically only - * be enabled just before going to sleep. - */ -UINT8 ACPI_INIT_GLOBAL (AcpiGbl_LeaveWakeGpesDisabled, TRUE); - -/* * Optionally use default values for the ACPI register widths. Set this to * TRUE to use the defaults, if an FADT contains incorrect widths/lengths. */ @@ -434,10 +427,13 @@ ACPI_EXTERN UINT8 AcpiGbl_SleepTypeB; * ****************************************************************************/ -extern ACPI_FIXED_EVENT_INFO AcpiGbl_FixedEventInfo[ACPI_NUM_FIXED_EVENTS]; -ACPI_EXTERN ACPI_FIXED_EVENT_HANDLER AcpiGbl_FixedEventHandlers[ACPI_NUM_FIXED_EVENTS]; +ACPI_EXTERN UINT8 AcpiGbl_AllGpesInitialized; ACPI_EXTERN ACPI_GPE_XRUPT_INFO *AcpiGbl_GpeXruptListHead; ACPI_EXTERN ACPI_GPE_BLOCK_INFO *AcpiGbl_GpeFadtBlocks[ACPI_MAX_GPE_BLOCKS]; +ACPI_EXTERN ACPI_GBL_EVENT_HANDLER AcpiGbl_GlobalEventHandler; +ACPI_EXTERN void *AcpiGbl_GlobalEventHandlerContext; +ACPI_EXTERN ACPI_FIXED_EVENT_HANDLER AcpiGbl_FixedEventHandlers[ACPI_NUM_FIXED_EVENTS]; +extern ACPI_FIXED_EVENT_INFO AcpiGbl_FixedEventInfo[ACPI_NUM_FIXED_EVENTS]; /***************************************************************************** diff --git a/sys/contrib/dev/acpica/include/aclocal.h b/sys/contrib/dev/acpica/include/aclocal.h index 062972f..2c755f6 100644 --- a/sys/contrib/dev/acpica/include/aclocal.h +++ b/sys/contrib/dev/acpica/include/aclocal.h @@ -537,18 +537,25 @@ typedef struct acpi_predefined_data /* Dispatch info for each GPE -- either a method or handler, cannot be both */ -typedef struct acpi_handler_info +typedef struct acpi_gpe_handler_info { - ACPI_EVENT_HANDLER Address; /* Address of handler, if any */ + ACPI_GPE_HANDLER Address; /* Address of handler, if any */ void *Context; /* Context to be passed to handler */ ACPI_NAMESPACE_NODE *MethodNode; /* Method node for this GPE level (saved) */ + UINT8 OriginalFlags; /* Original (pre-handler) GPE info */ + BOOLEAN OriginallyEnabled; /* True if GPE was originally enabled */ -} ACPI_HANDLER_INFO; +} ACPI_GPE_HANDLER_INFO; +/* + * GPE dispatch info. At any time, the GPE can have at most one type + * of dispatch - Method, Handler, or Implicit Notify. + */ typedef union acpi_gpe_dispatch_info { ACPI_NAMESPACE_NODE *MethodNode; /* Method node for this GPE level */ - struct acpi_handler_info *Handler; + struct acpi_gpe_handler_info *Handler; /* Installed GPE handler */ + ACPI_NAMESPACE_NODE *DeviceNode; /* Parent _PRW device for implicit notify */ } ACPI_GPE_DISPATCH_INFO; @@ -594,6 +601,7 @@ typedef struct acpi_gpe_block_info UINT32 RegisterCount; /* Number of register pairs in block */ UINT16 GpeCount; /* Number of individual GPEs in block */ UINT8 BlockBaseNumber;/* Base GPE number for this block */ + BOOLEAN Initialized; /* TRUE if this block is initialized */ } ACPI_GPE_BLOCK_INFO; @@ -614,7 +622,6 @@ typedef struct acpi_gpe_walk_info ACPI_GPE_BLOCK_INFO *GpeBlock; UINT16 Count; ACPI_OWNER_ID OwnerId; - BOOLEAN EnableThisGpe; BOOLEAN ExecuteByOwnerId; } ACPI_GPE_WALK_INFO; diff --git a/sys/contrib/dev/acpica/include/acpixf.h b/sys/contrib/dev/acpica/include/acpixf.h index 6d100c0..f057cf6 100644 --- a/sys/contrib/dev/acpica/include/acpixf.h +++ b/sys/contrib/dev/acpica/include/acpixf.h @@ -120,7 +120,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20101013 +#define ACPI_CA_VERSION 0x20101209 #include <contrib/dev/acpica/include/actypes.h> #include <contrib/dev/acpica/include/actbl.h> @@ -142,7 +142,6 @@ extern UINT32 AcpiDbgLayer; extern UINT8 AcpiGbl_EnableInterpreterSlack; extern UINT8 AcpiGbl_AllMethodsSerialized; extern UINT8 AcpiGbl_CreateOsiMethod; -extern UINT8 AcpiGbl_LeaveWakeGpesDisabled; extern UINT8 AcpiGbl_UseDefaultRegisterWidths; extern ACPI_NAME AcpiGbl_TraceMethodName; extern UINT32 AcpiGbl_TraceFlags; @@ -152,7 +151,7 @@ extern UINT8 AcpiGbl_TruncateIoAddresses; /* - * Global interfaces + * Initialization */ ACPI_STATUS AcpiInitializeTables ( @@ -176,10 +175,10 @@ ACPI_STATUS AcpiTerminate ( void); -ACPI_STATUS -AcpiSubsystemStatus ( - void); +/* + * Miscellaneous global interfaces + */ ACPI_STATUS AcpiEnable ( void); @@ -189,6 +188,10 @@ AcpiDisable ( void); ACPI_STATUS +AcpiSubsystemStatus ( + void); + +ACPI_STATUS AcpiGetSystemInfo ( ACPI_BUFFER *RetBuffer); @@ -212,6 +215,7 @@ ACPI_STATUS AcpiRemoveInterface ( ACPI_STRING InterfaceName); + /* * ACPI Memory management */ @@ -381,6 +385,11 @@ AcpiInstallInitializationHandler ( UINT32 Function); ACPI_STATUS +AcpiInstallGlobalEventHandler ( + ACPI_GBL_EVENT_HANDLER Handler, + void *Context); + +ACPI_STATUS AcpiInstallFixedEventHandler ( UINT32 AcpiEvent, ACPI_EVENT_HANDLER Handler, @@ -392,6 +401,20 @@ AcpiRemoveFixedEventHandler ( ACPI_EVENT_HANDLER Handler); ACPI_STATUS +AcpiInstallGpeHandler ( + ACPI_HANDLE GpeDevice, + UINT32 GpeNumber, + UINT32 Type, + ACPI_GPE_HANDLER Address, + void *Context); + +ACPI_STATUS +AcpiRemoveGpeHandler ( + ACPI_HANDLE GpeDevice, + UINT32 GpeNumber, + ACPI_GPE_HANDLER Address); + +ACPI_STATUS AcpiInstallNotifyHandler ( ACPI_HANDLE Device, UINT32 HandlerType, @@ -419,20 +442,6 @@ AcpiRemoveAddressSpaceHandler ( ACPI_ADR_SPACE_HANDLER Handler); ACPI_STATUS -AcpiInstallGpeHandler ( - ACPI_HANDLE GpeDevice, - UINT32 GpeNumber, - UINT32 Type, - ACPI_EVENT_HANDLER Address, - void *Context); - -ACPI_STATUS -AcpiRemoveGpeHandler ( - ACPI_HANDLE GpeDevice, - UINT32 GpeNumber, - ACPI_EVENT_HANDLER Address); - -ACPI_STATUS AcpiInstallExceptionHandler ( ACPI_EXCEPTION_HANDLER Handler); @@ -442,7 +451,7 @@ AcpiInstallInterfaceHandler ( /* - * Event interfaces + * Global Lock interfaces */ ACPI_STATUS AcpiAcquireGlobalLock ( @@ -453,6 +462,10 @@ ACPI_STATUS AcpiReleaseGlobalLock ( UINT32 Handle); + +/* + * Fixed Event interfaces + */ ACPI_STATUS AcpiEnableEvent ( UINT32 Event, @@ -474,13 +487,11 @@ AcpiGetEventStatus ( /* - * GPE Interfaces + * General Purpose Event (GPE) Interfaces */ ACPI_STATUS -AcpiSetGpe ( - ACPI_HANDLE GpeDevice, - UINT32 GpeNumber, - UINT8 Action); +AcpiUpdateAllGpes ( + void); ACPI_STATUS AcpiEnableGpe ( @@ -498,7 +509,24 @@ AcpiClearGpe ( UINT32 GpeNumber); ACPI_STATUS -AcpiGpeWakeup ( +AcpiSetGpe ( + ACPI_HANDLE GpeDevice, + UINT32 GpeNumber, + UINT8 Action); + +ACPI_STATUS +AcpiFinishGpe ( + ACPI_HANDLE GpeDevice, + UINT32 GpeNumber); + +ACPI_STATUS +AcpiSetupGpeForWake ( + ACPI_HANDLE ParentDevice, + ACPI_HANDLE GpeDevice, + UINT32 GpeNumber); + +ACPI_STATUS +AcpiSetGpeWakeMask ( ACPI_HANDLE GpeDevice, UINT32 GpeNumber, UINT8 Action); diff --git a/sys/contrib/dev/acpica/include/actypes.h b/sys/contrib/dev/acpica/include/actypes.h index e4290ae..3a37da0 100644 --- a/sys/contrib/dev/acpica/include/actypes.h +++ b/sys/contrib/dev/acpica/include/actypes.h @@ -738,25 +738,26 @@ typedef UINT32 ACPI_EVENT_STATUS; /* * GPE info flags - Per GPE - * +-------+---+-+-+ - * | 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> + * +-------+-+-+---+ + * | 7:4 |3|2|1:0| + * +-------+-+-+---+ + * | | | | + * | | | +-- Type of dispatch:to method, handler, notify, or none + * | | +----- Interrupt type: edge or level triggered + * | +------- Is a Wake GPE + * +------------ <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_DISPATCH_NONE (UINT8) 0x00 +#define ACPI_GPE_DISPATCH_METHOD (UINT8) 0x01 +#define ACPI_GPE_DISPATCH_HANDLER (UINT8) 0x02 +#define ACPI_GPE_DISPATCH_NOTIFY (UINT8) 0x03 +#define ACPI_GPE_DISPATCH_MASK (UINT8) 0x03 -#define ACPI_GPE_CAN_WAKE (UINT8) 0x02 +#define ACPI_GPE_LEVEL_TRIGGERED (UINT8) 0x04 +#define ACPI_GPE_EDGE_TRIGGERED (UINT8) 0x00 +#define ACPI_GPE_XRUPT_TYPE_MASK (UINT8) 0x04 -#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 +#define ACPI_GPE_CAN_WAKE (UINT8) 0x08 /* * Flags for GPE and Lock interfaces @@ -1015,10 +1016,26 @@ typedef void * Various handlers and callback procedures */ typedef +void (*ACPI_GBL_EVENT_HANDLER) ( + UINT32 EventType, + ACPI_HANDLE Device, + UINT32 EventNumber, + void *Context); + +#define ACPI_EVENT_TYPE_GPE 0 +#define ACPI_EVENT_TYPE_FIXED 1 + +typedef UINT32 (*ACPI_EVENT_HANDLER) ( void *Context); typedef +UINT32 (*ACPI_GPE_HANDLER) ( + ACPI_HANDLE GpeDevice, + UINT32 GpeNumber, + void *Context); + +typedef void (*ACPI_NOTIFY_HANDLER) ( ACPI_HANDLE Device, UINT32 Value, @@ -1098,6 +1115,11 @@ UINT32 (*ACPI_INTERFACE_HANDLER) ( #define ACPI_INTERRUPT_NOT_HANDLED 0x00 #define ACPI_INTERRUPT_HANDLED 0x01 +/* GPE handler return values */ + +#define ACPI_REENABLE_GPE 0x80 + + /* Length of 32-bit EISAID values when converted back to a string */ #define ACPI_EISAID_STRING_SIZE 8 /* Includes null terminator */ diff --git a/sys/contrib/dev/acpica/tools/acpiexec/aecommon.h b/sys/contrib/dev/acpica/tools/acpiexec/aecommon.h index 06bdece..9b35bb3 100644 --- a/sys/contrib/dev/acpica/tools/acpiexec/aecommon.h +++ b/sys/contrib/dev/acpica/tools/acpiexec/aecommon.h @@ -250,6 +250,15 @@ AeRegionHandler ( UINT32 AeGpeHandler ( + ACPI_HANDLE GpeDevice, + UINT32 GpeNumber, + void *Context); + +void +AeGlobalEventHandler ( + UINT32 Type, + ACPI_HANDLE GpeDevice, + UINT32 EventNumber, void *Context); #endif /* _AECOMMON */ diff --git a/sys/contrib/dev/acpica/utilities/utglobal.c b/sys/contrib/dev/acpica/utilities/utglobal.c index ca2ce7f..7251f65 100644 --- a/sys/contrib/dev/acpica/utilities/utglobal.c +++ b/sys/contrib/dev/acpica/utilities/utglobal.c @@ -895,6 +895,7 @@ AcpiUtInitGlobals ( /* GPE support */ + AcpiGbl_AllGpesInitialized = FALSE; AcpiGbl_GpeXruptListHead = NULL; AcpiGbl_GpeFadtBlocks[0] = NULL; AcpiGbl_GpeFadtBlocks[1] = NULL; @@ -908,6 +909,7 @@ AcpiUtInitGlobals ( AcpiGbl_InitHandler = NULL; AcpiGbl_TableHandler = NULL; AcpiGbl_InterfaceHandler = NULL; + AcpiGbl_GlobalEventHandler = NULL; /* Global Lock support */ diff --git a/sys/contrib/dev/acpica/utilities/utxface.c b/sys/contrib/dev/acpica/utilities/utxface.c index 5c130d8..bc63ee3 100644 --- a/sys/contrib/dev/acpica/utilities/utxface.c +++ b/sys/contrib/dev/acpica/utilities/utxface.c @@ -412,27 +412,6 @@ AcpiInitializeObjects ( } /* - * Initialize the GPE blocks defined in the FADT (GPE block 0 and 1). - * The runtime GPEs are enabled here. - * - * This is where the _PRW methods are executed for the GPEs. These - * methods can only be executed after the SCI and Global Lock handlers are - * installed and initialized. - * - * GPEs can only be enabled after the _REG, _STA, and _INI methods have - * been run. This ensures that all Operation Regions and all Devices have - * been initialized and are ready. - */ - if (!(Flags & ACPI_NO_EVENT_INIT)) - { - Status = AcpiEvInstallFadtGpes (); - if (ACPI_FAILURE (Status)) - { - return (Status); - } - } - - /* * Empty the caches (delete the cached objects) on the assumption that * the table load filled them up more than they will be at runtime -- * thus wasting non-paged memory. |