-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
Import ACPI drivers (bus enumerator and battery drivers) from ReactOS. We define our .clang-format file and apply clang-format to the ReactOS source code.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,124 @@ | ||
| # SPDX-License-Identifier: GPL-2.0 | ||
| # | ||
| # clang-format configuration file. Intended for clang-format >= 11. | ||
| # | ||
| # For more information, see: | ||
| # | ||
| # Documentation/process/clang-format.rst | ||
| # https://clang.llvm.org/docs/ClangFormat.html | ||
| # https://clang.llvm.org/docs/ClangFormatStyleOptions.html | ||
| # | ||
| --- | ||
| AccessModifierOffset: -4 | ||
| AlignAfterOpenBracket: Align | ||
| AlignConsecutiveAssignments: false | ||
| AlignConsecutiveDeclarations: false | ||
| AlignEscapedNewlines: Left | ||
| AlignOperands: true | ||
| AlignTrailingComments: false | ||
| AllowAllArgumentsOnNextLine: false | ||
| AllowAllParametersOfDeclarationOnNextLine: false | ||
| AllowShortBlocksOnASingleLine: false | ||
| AllowShortCaseLabelsOnASingleLine: false | ||
| AllowShortFunctionsOnASingleLine: None | ||
| AllowShortIfStatementsOnASingleLine: false | ||
| AllowShortLoopsOnASingleLine: false | ||
| AlwaysBreakAfterDefinitionReturnType: None | ||
| AlwaysBreakAfterReturnType: None | ||
| AlwaysBreakBeforeMultilineStrings: false | ||
| AlwaysBreakTemplateDeclarations: false | ||
| BinPackArguments: true | ||
| BinPackParameters: true | ||
| BraceWrapping: | ||
| AfterClass: false | ||
| AfterControlStatement: false | ||
| AfterEnum: false | ||
| AfterFunction: true | ||
| AfterNamespace: true | ||
| AfterObjCDeclaration: false | ||
| AfterStruct: false | ||
| AfterUnion: false | ||
| AfterExternBlock: false | ||
| BeforeCatch: false | ||
| BeforeElse: false | ||
| IndentBraces: false | ||
| SplitEmptyFunction: true | ||
| SplitEmptyRecord: true | ||
| SplitEmptyNamespace: true | ||
| BreakBeforeBinaryOperators: None | ||
| BreakBeforeBraces: Custom | ||
| BreakBeforeInheritanceComma: false | ||
| BreakBeforeTernaryOperators: false | ||
| BreakConstructorInitializersBeforeComma: false | ||
| BreakConstructorInitializers: BeforeComma | ||
| BreakAfterJavaFieldAnnotations: false | ||
| BreakStringLiterals: true | ||
| ColumnLimit: 90 | ||
| CommentPragmas: '^ IWYU pragma:' | ||
| CompactNamespaces: false | ||
| ConstructorInitializerAllOnOneLineOrOnePerLine: false | ||
| ConstructorInitializerIndentWidth: 4 | ||
| ContinuationIndentWidth: 4 | ||
| Cpp11BracedListStyle: false | ||
| DerivePointerAlignment: false | ||
| DisableFormat: false | ||
| ExperimentalAutoDetectBinPacking: false | ||
| FixNamespaceComments: false | ||
|
|
||
| ForEachMacros: | ||
| - 'LoopOverList' | ||
| - 'ReverseLoopOverList' | ||
|
|
||
| IncludeBlocks: Preserve | ||
| IncludeCategories: | ||
| - Regex: '.*' | ||
| Priority: 1 | ||
| IncludeIsMainRegex: '(Test)?$' | ||
| IndentCaseLabels: false | ||
| IndentGotoLabels: true | ||
| IndentPPDirectives: None | ||
| IndentWidth: 4 | ||
| IndentWrappedFunctionNames: false | ||
| JavaScriptQuotes: Leave | ||
| JavaScriptWrapImports: true | ||
| KeepEmptyLinesAtTheStartOfBlocks: false | ||
| MacroBlockBegin: '' | ||
| MacroBlockEnd: '' | ||
| MaxEmptyLinesToKeep: 1 | ||
| NamespaceIndentation: None | ||
| ObjCBinPackProtocolList: Auto | ||
| ObjCBlockIndentWidth: 8 | ||
| ObjCSpaceAfterProperty: true | ||
| ObjCSpaceBeforeProtocolList: true | ||
|
|
||
| # Taken from git's rules | ||
| PenaltyBreakAssignment: 100 | ||
| PenaltyBreakBeforeFirstCallParameter: 100 | ||
| PenaltyBreakComment: 10 | ||
| PenaltyBreakFirstLessLess: 0 | ||
| PenaltyBreakString: 10 | ||
| PenaltyExcessCharacter: 100 | ||
| PenaltyReturnTypeOnItsOwnLine: 100 | ||
|
|
||
| PointerAlignment: Right | ||
| ReflowComments: false | ||
| SortIncludes: false | ||
| SortUsingDeclarations: false | ||
| SpaceAfterCStyleCast: false | ||
| SpaceAfterTemplateKeyword: true | ||
| SpaceBeforeAssignmentOperators: true | ||
| SpaceBeforeCtorInitializerColon: true | ||
| SpaceBeforeInheritanceColon: true | ||
| SpaceBeforeParens: ControlStatementsExceptForEachMacros | ||
| SpaceBeforeRangeBasedForLoopColon: true | ||
| SpaceInEmptyParentheses: false | ||
| SpacesBeforeTrailingComments: 1 | ||
| SpacesInAngles: false | ||
| SpacesInContainerLiterals: false | ||
| SpacesInCStyleCastParentheses: false | ||
| SpacesInParentheses: false | ||
| SpacesInSquareBrackets: false | ||
| Standard: Cpp03 | ||
| TabWidth: 8 | ||
| UseTab: Always | ||
| ... |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| add_subdirectory(acpi) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,191 @@ | ||
| project(acpi C) | ||
|
|
||
| include_directories(acpica/include) | ||
|
|
||
| list(APPEND ACPICA_SOURCE | ||
| acpica/dispatcher/dsargs.c | ||
| acpica/dispatcher/dscontrol.c | ||
| acpica/dispatcher/dsdebug.c | ||
| acpica/dispatcher/dsfield.c | ||
| acpica/dispatcher/dsinit.c | ||
| acpica/dispatcher/dsmethod.c | ||
| acpica/dispatcher/dsmthdat.c | ||
| acpica/dispatcher/dsobject.c | ||
| acpica/dispatcher/dsopcode.c | ||
| acpica/dispatcher/dspkginit.c | ||
| acpica/dispatcher/dsutils.c | ||
| acpica/dispatcher/dswexec.c | ||
| acpica/dispatcher/dswload.c | ||
| acpica/dispatcher/dswload2.c | ||
| acpica/dispatcher/dswscope.c | ||
| acpica/dispatcher/dswstate.c | ||
| acpica/events/evevent.c | ||
| acpica/events/evglock.c | ||
| acpica/events/evgpe.c | ||
| acpica/events/evgpeblk.c | ||
| acpica/events/evgpeinit.c | ||
| acpica/events/evgpeutil.c | ||
| acpica/events/evhandler.c | ||
| acpica/events/evmisc.c | ||
| acpica/events/evregion.c | ||
| acpica/events/evrgnini.c | ||
| acpica/events/evsci.c | ||
| acpica/events/evxface.c | ||
| acpica/events/evxfevnt.c | ||
| acpica/events/evxfgpe.c | ||
| acpica/events/evxfregn.c | ||
| acpica/executer/exconcat.c | ||
| acpica/executer/exconfig.c | ||
| acpica/executer/exconvrt.c | ||
| acpica/executer/excreate.c | ||
| acpica/executer/exdebug.c | ||
| # acpica/executer/exdump.c | ||
| acpica/executer/exfield.c | ||
| acpica/executer/exfldio.c | ||
| acpica/executer/exmisc.c | ||
| acpica/executer/exmutex.c | ||
| acpica/executer/exnames.c | ||
| acpica/executer/exoparg1.c | ||
| acpica/executer/exoparg2.c | ||
| acpica/executer/exoparg3.c | ||
| acpica/executer/exoparg6.c | ||
| acpica/executer/exprep.c | ||
| acpica/executer/exregion.c | ||
| acpica/executer/exresnte.c | ||
| acpica/executer/exresolv.c | ||
| acpica/executer/exresop.c | ||
| acpica/executer/exserial.c | ||
| acpica/executer/exstore.c | ||
| acpica/executer/exstoren.c | ||
| acpica/executer/exstorob.c | ||
| acpica/executer/exsystem.c | ||
| acpica/executer/extrace.c | ||
| acpica/executer/exutils.c | ||
| acpica/hardware/hwacpi.c | ||
| acpica/hardware/hwesleep.c | ||
| acpica/hardware/hwgpe.c | ||
| acpica/hardware/hwpci.c | ||
| acpica/hardware/hwregs.c | ||
| acpica/hardware/hwsleep.c | ||
| acpica/hardware/hwtimer.c | ||
| acpica/hardware/hwvalid.c | ||
| acpica/hardware/hwxface.c | ||
| acpica/hardware/hwxfsleep.c | ||
| acpica/namespace/nsaccess.c | ||
| acpica/namespace/nsalloc.c | ||
| acpica/namespace/nsarguments.c | ||
| acpica/namespace/nsconvert.c | ||
| # acpica/namespace/nsdump.c | ||
| # acpica/namespace/nsdumpdv.c | ||
| acpica/namespace/nseval.c | ||
| acpica/namespace/nsinit.c | ||
| acpica/namespace/nsload.c | ||
| acpica/namespace/nsnames.c | ||
| acpica/namespace/nsobject.c | ||
| acpica/namespace/nsparse.c | ||
| acpica/namespace/nspredef.c | ||
| acpica/namespace/nsprepkg.c | ||
| acpica/namespace/nsrepair.c | ||
| acpica/namespace/nsrepair2.c | ||
| acpica/namespace/nssearch.c | ||
| acpica/namespace/nsutils.c | ||
| acpica/namespace/nswalk.c | ||
| acpica/namespace/nsxfeval.c | ||
| acpica/namespace/nsxfname.c | ||
| acpica/namespace/nsxfobj.c | ||
| acpica/parser/psargs.c | ||
| acpica/parser/psloop.c | ||
| acpica/parser/psobject.c | ||
| acpica/parser/psopcode.c | ||
| acpica/parser/psopinfo.c | ||
| acpica/parser/psparse.c | ||
| acpica/parser/psscope.c | ||
| acpica/parser/pstree.c | ||
| acpica/parser/psutils.c | ||
| acpica/parser/pswalk.c | ||
| acpica/parser/psxface.c | ||
| acpica/resources/rsaddr.c | ||
| acpica/resources/rscalc.c | ||
| acpica/resources/rscreate.c | ||
| # acpica/resources/rsdump.c | ||
| # acpica/resources/rsdumpinfo.c | ||
| acpica/resources/rsinfo.c | ||
| acpica/resources/rsio.c | ||
| acpica/resources/rsirq.c | ||
| acpica/resources/rslist.c | ||
| acpica/resources/rsmemory.c | ||
| acpica/resources/rsmisc.c | ||
| acpica/resources/rsserial.c | ||
| acpica/resources/rsutils.c | ||
| acpica/resources/rsxface.c | ||
| acpica/tables/tbdata.c | ||
| acpica/tables/tbfadt.c | ||
| acpica/tables/tbfind.c | ||
| acpica/tables/tbinstal.c | ||
| acpica/tables/tbprint.c | ||
| acpica/tables/tbutils.c | ||
| acpica/tables/tbxface.c | ||
| acpica/tables/tbxfload.c | ||
| acpica/tables/tbxfroot.c | ||
| acpica/utilities/utaddress.c | ||
| acpica/utilities/utalloc.c | ||
| acpica/utilities/utascii.c | ||
| acpica/utilities/utbuffer.c | ||
| acpica/utilities/utcache.c | ||
| acpica/utilities/utcksum.c | ||
| acpica/utilities/utcopy.c | ||
| # acpica/utilities/utdebug.c | ||
| acpica/utilities/utdecode.c | ||
| acpica/utilities/utdelete.c | ||
| acpica/utilities/uterror.c | ||
| acpica/utilities/uteval.c | ||
| acpica/utilities/utexcep.c | ||
| acpica/utilities/utglobal.c | ||
| acpica/utilities/uthex.c | ||
| acpica/utilities/utids.c | ||
| acpica/utilities/utinit.c | ||
| acpica/utilities/utlock.c | ||
| acpica/utilities/utmath.c | ||
| acpica/utilities/utmisc.c | ||
| acpica/utilities/utmutex.c | ||
| acpica/utilities/utnonansi.c | ||
| acpica/utilities/utobject.c | ||
| acpica/utilities/utosi.c | ||
| acpica/utilities/utownerid.c | ||
| acpica/utilities/utpredef.c | ||
| acpica/utilities/utprint.c | ||
| # acpica/utilities/utresdecode.c | ||
| acpica/utilities/utresrc.c | ||
| acpica/utilities/utstate.c | ||
| acpica/utilities/utstring.c | ||
| acpica/utilities/utstrtoul64.c | ||
| acpica/utilities/utstrsuppt.c | ||
| # acpica/utilities/utuuid.c | ||
| acpica/utilities/uttrack.c | ||
| acpica/utilities/utxface.c | ||
| acpica/utilities/utxferror.c | ||
| acpica/utilities/utxfinit.c | ||
| acpica/utilities/utxfmutex.c) | ||
|
|
||
| add_library(acpica ${ACPICA_SOURCE}) | ||
|
|
||
| list(APPEND ACPI_SOURCE | ||
| busmgr/bus.c | ||
| busmgr/button.c | ||
| busmgr/enum.c | ||
| busmgr/pdo.c | ||
| busmgr/power.c | ||
| busmgr/utils.c | ||
| osl.c | ||
| eval.c | ||
| pnp.c | ||
| power.c | ||
| main.c) | ||
|
|
||
| add_driver(acpi ${ACPI_SOURCE}) | ||
| add_dependencies(acpi acpica) | ||
| target_link_libraries(acpi PRIVATE acpica) | ||
|
|
||
| add_subdirectory(battc) | ||
| add_subdirectory(cmbatt) | ||
| add_subdirectory(compbatt) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,130 @@ | ||
| ; ACPI.INF | ||
|
|
||
| ; Installation file for ACPI driver | ||
|
|
||
| [Version] | ||
| Signature = "$Windows NT$" | ||
| ;Signature = "$ReactOS$" | ||
| LayoutFile = layout.inf | ||
| Class = System | ||
| ClassGUID = {4D36E97D-E325-11CE-BFC1-08002BE10318} | ||
| Provider = %ReactOS% | ||
| DriverVer = 10/11/2005,1.01.0.0 | ||
|
|
||
| [DestinationDirs] | ||
| DefaultDestDir = 12 | ||
|
|
||
| [Manufacturer] | ||
| %GenericMfg% = GenericMfg | ||
|
|
||
| [GenericMfg] | ||
| %*PNP0C08.DeviceDesc% = ACPI_Inst,*PNP0C08 | ||
| %COMPOSITE_BATTERY.DeviceDesc% = CompBatt_Inst,COMPOSITE_BATTERY | ||
|
|
||
| ;------------------------------ ACPI DRIVER ----------------------------- | ||
|
|
||
| [ACPI_Inst.NT] | ||
| CopyFiles = ACPI_CopyFiles.NT | ||
|
|
||
| [ACPI_CopyFiles.NT] | ||
| acpi.sys | ||
|
|
||
| [ACPI_Inst.NT.Services] | ||
| AddService = acpi, 0x00000002, acpi_Service_Inst | ||
|
|
||
| [acpi_Service_Inst] | ||
| ServiceType = 1 | ||
| StartType = 0 | ||
| ErrorControl = 1 | ||
| ServiceBinary = %12%\acpi.sys | ||
| LoadOrderGroup = Boot Bus Extender | ||
|
|
||
| ;---------------------------- COMPBATT DRIVER --------------------------- | ||
|
|
||
| [CompBatt_Inst.NT] | ||
| CopyFiles = CompBatt_CopyFiles.NT | ||
|
|
||
| [CompBatt_CopyFiles.NT] | ||
| compbatt.sys | ||
|
|
||
| [CompBatt_Inst.NT.Services] | ||
| AddService = compbatt, 0x00000002, compbatt_Service_Inst | ||
|
|
||
| [compbatt_Service_Inst] | ||
| ServiceType = 1 | ||
| StartType = 0 | ||
| ErrorControl = 1 | ||
| ServiceBinary = %12%\compbatt.sys | ||
| LoadOrderGroup = System Bus Extender | ||
|
|
||
| ;-------------------------------- STRINGS ------------------------------- | ||
|
|
||
| [Strings] | ||
| ; Non-localizable | ||
| ReactOS = "ReactOS Project" | ||
|
|
||
| ; Localizable | ||
| GenericMfg = "(Generic system devices)" | ||
| *PNP0C08.DeviceDesc = "ACPI hardware" | ||
| COMPOSITE_BATTERY.DeviceDesc = "Composite battery" | ||
|
|
||
| [Strings.0405] | ||
| GenericMfg = "(Generická systémová zařízení)" | ||
|
|
||
| [Strings.0404] | ||
| GenericMfg = "(標準系統裝置)" | ||
| *PNP0C08.DeviceDesc = "ACPI 硬體" | ||
|
|
||
| [Strings.0407] | ||
| GenericMfg = "(Generische Systemgeräte)" | ||
| *PNP0C08.DeviceDesc = "ACPI Hardware" | ||
|
|
||
| [Strings.0a] | ||
| GenericMfg = "(Dispositivos del sistema estándar)" | ||
| *PNP0C08.DeviceDesc = "Hardware ACPI" | ||
|
|
||
| [Strings.040C] | ||
| GenericMfg = "(Périphériques systèmes génériques)" | ||
|
|
||
| [Strings.0411] | ||
| GenericMfg = "(標準システム デバイス)" | ||
| *PNP0C08.DeviceDesc = "ACPI ハードウェア" | ||
|
|
||
| [Strings.0415] | ||
| GenericMfg = "(Standardowe urządzenia systemowe)" | ||
| *PNP0C08.DeviceDesc = "Sprzęt ACPI" | ||
|
|
||
| [Strings.0416] | ||
| GenericMfg = "(Dispositivos de sistema padrão)" | ||
| *PNP0C08.DeviceDesc = "Hardware ACPI" | ||
|
|
||
| [Strings.0418] | ||
| GenericMfg = "(dispozitiv de sistem generic)" | ||
| *PNP0C08.DeviceDesc = "Dispozitive ACPI" | ||
|
|
||
| [Strings.0419] | ||
| GenericMfg = "(Стандартные системные устройства)" | ||
| *PNP0C08.DeviceDesc = "Устройства ACPI" | ||
|
|
||
| [Strings.041B] | ||
| GenericMfg = "(Generické systémové zariadenia)" | ||
| *PNP0C08.DeviceDesc = "ACPI hardvér" | ||
|
|
||
| [Strings.041f] | ||
| GenericMfg = "(Genel Sistem Aygıtları)" | ||
| *PNP0C08.DeviceDesc = "ACPI Donanım" | ||
|
|
||
| [Strings.0422] | ||
| GenericMfg = "(Стандартні системні пристрої)" | ||
| *PNP0C08.DeviceDesc = "Пристрої ACPI" | ||
|
|
||
| [Strings.0427] | ||
| GenericMfg = "(Standartiniai sisteminiai įrenginiai)" | ||
|
|
||
| [Strings.0804] | ||
| GenericMfg = "(通用系统设备)" | ||
| *PNP0C08.DeviceDesc = "ACPI 硬件" | ||
|
|
||
| [Strings.0c04] | ||
| GenericMfg = "(標準系統裝置)" | ||
| *PNP0C08.DeviceDesc = "ACPI 硬件" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| #define REACTOS_VERSION_DLL | ||
| #define REACTOS_STR_FILE_DESCRIPTION "ReactOS ACPI Driver" | ||
| #define REACTOS_STR_INTERNAL_NAME "acpi" | ||
| #define REACTOS_STR_ORIGINAL_FILENAME "acpi.sys" | ||
| #include <reactos/version.rc> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,390 @@ | ||
| /****************************************************************************** | ||
| * | ||
| * Module Name: dsargs - Support for execution of dynamic arguments for static | ||
| * objects (regions, fields, buffer fields, etc.) | ||
| * | ||
| *****************************************************************************/ | ||
|
|
||
| /* | ||
| * Copyright (C) 2000 - 2022, Intel Corp. | ||
| * All rights reserved. | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions, and the following disclaimer, | ||
| * without modification. | ||
| * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
| * substantially similar to the "NO WARRANTY" disclaimer below | ||
| * ("Disclaimer") and any redistribution must be conditioned upon | ||
| * including a substantially similar Disclaimer requirement for further | ||
| * binary redistribution. | ||
| * 3. Neither the names of the above-listed copyright holders nor the names | ||
| * of any contributors may be used to endorse or promote products derived | ||
| * from this software without specific prior written permission. | ||
| * | ||
| * Alternatively, this software may be distributed under the terms of the | ||
| * GNU General Public License ("GPL") version 2 as published by the Free | ||
| * Software Foundation. | ||
| * | ||
| * NO WARRANTY | ||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
| * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| * POSSIBILITY OF SUCH DAMAGES. | ||
| */ | ||
|
|
||
| #include "acpi.h" | ||
| #include "accommon.h" | ||
| #include "acparser.h" | ||
| #include "amlcode.h" | ||
| #include "acdispat.h" | ||
| #include "acnamesp.h" | ||
|
|
||
| #define _COMPONENT ACPI_DISPATCHER | ||
| ACPI_MODULE_NAME("dsargs") | ||
|
|
||
| /* Local prototypes */ | ||
|
|
||
| static ACPI_STATUS AcpiDsExecuteArguments(ACPI_NAMESPACE_NODE *Node, | ||
| ACPI_NAMESPACE_NODE *ScopeNode, | ||
| UINT32 AmlLength, UINT8 *AmlStart); | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiDsExecuteArguments | ||
| * | ||
| * PARAMETERS: Node - Object NS node | ||
| * ScopeNode - Parent NS node | ||
| * AmlLength - Length of executable AML | ||
| * AmlStart - Pointer to the AML | ||
| * | ||
| * RETURN: Status. | ||
| * | ||
| * DESCRIPTION: Late (deferred) execution of region or field arguments | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| static ACPI_STATUS AcpiDsExecuteArguments(ACPI_NAMESPACE_NODE *Node, | ||
| ACPI_NAMESPACE_NODE *ScopeNode, | ||
| UINT32 AmlLength, UINT8 *AmlStart) | ||
| { | ||
| ACPI_STATUS Status; | ||
| ACPI_PARSE_OBJECT *Op; | ||
| ACPI_WALK_STATE *WalkState; | ||
|
|
||
| ACPI_FUNCTION_TRACE_PTR(DsExecuteArguments, AmlStart); | ||
|
|
||
| /* Allocate a new parser op to be the root of the parsed tree */ | ||
|
|
||
| Op = AcpiPsAllocOp(AML_INT_EVAL_SUBTREE_OP, AmlStart); | ||
| if (!Op) { | ||
| return_ACPI_STATUS(AE_NO_MEMORY); | ||
| } | ||
|
|
||
| /* Save the Node for use in AcpiPsParseAml */ | ||
|
|
||
| Op->Common.Node = ScopeNode; | ||
|
|
||
| /* Create and initialize a new parser state */ | ||
|
|
||
| WalkState = AcpiDsCreateWalkState(0, NULL, NULL, NULL); | ||
| if (!WalkState) { | ||
| Status = AE_NO_MEMORY; | ||
| goto Cleanup; | ||
| } | ||
|
|
||
| Status = AcpiDsInitAmlWalk(WalkState, Op, NULL, AmlStart, AmlLength, NULL, | ||
| ACPI_IMODE_LOAD_PASS1); | ||
| if (ACPI_FAILURE(Status)) { | ||
| AcpiDsDeleteWalkState(WalkState); | ||
| goto Cleanup; | ||
| } | ||
|
|
||
| /* Mark this parse as a deferred opcode */ | ||
|
|
||
| WalkState->ParseFlags = ACPI_PARSE_DEFERRED_OP; | ||
| WalkState->DeferredNode = Node; | ||
|
|
||
| /* Pass1: Parse the entire declaration */ | ||
|
|
||
| Status = AcpiPsParseAml(WalkState); | ||
| if (ACPI_FAILURE(Status)) { | ||
| goto Cleanup; | ||
| } | ||
|
|
||
| /* Get and init the Op created above */ | ||
|
|
||
| Op->Common.Node = Node; | ||
| AcpiPsDeleteParseTree(Op); | ||
|
|
||
| /* Evaluate the deferred arguments */ | ||
|
|
||
| Op = AcpiPsAllocOp(AML_INT_EVAL_SUBTREE_OP, AmlStart); | ||
| if (!Op) { | ||
| return_ACPI_STATUS(AE_NO_MEMORY); | ||
| } | ||
|
|
||
| Op->Common.Node = ScopeNode; | ||
|
|
||
| /* Create and initialize a new parser state */ | ||
|
|
||
| WalkState = AcpiDsCreateWalkState(0, NULL, NULL, NULL); | ||
| if (!WalkState) { | ||
| Status = AE_NO_MEMORY; | ||
| goto Cleanup; | ||
| } | ||
|
|
||
| /* Execute the opcode and arguments */ | ||
|
|
||
| Status = AcpiDsInitAmlWalk(WalkState, Op, NULL, AmlStart, AmlLength, NULL, | ||
| ACPI_IMODE_EXECUTE); | ||
| if (ACPI_FAILURE(Status)) { | ||
| AcpiDsDeleteWalkState(WalkState); | ||
| goto Cleanup; | ||
| } | ||
|
|
||
| /* Mark this execution as a deferred opcode */ | ||
|
|
||
| WalkState->DeferredNode = Node; | ||
| Status = AcpiPsParseAml(WalkState); | ||
|
|
||
| Cleanup: | ||
| AcpiPsDeleteParseTree(Op); | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiDsGetBufferFieldArguments | ||
| * | ||
| * PARAMETERS: ObjDesc - A valid BufferField object | ||
| * | ||
| * RETURN: Status. | ||
| * | ||
| * DESCRIPTION: Get BufferField Buffer and Index. This implements the late | ||
| * evaluation of these field attributes. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiDsGetBufferFieldArguments(ACPI_OPERAND_OBJECT *ObjDesc) | ||
| { | ||
| ACPI_OPERAND_OBJECT *ExtraDesc; | ||
| ACPI_NAMESPACE_NODE *Node; | ||
| ACPI_STATUS Status; | ||
|
|
||
| ACPI_FUNCTION_TRACE_PTR(DsGetBufferFieldArguments, ObjDesc); | ||
|
|
||
| if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID) { | ||
| return_ACPI_STATUS(AE_OK); | ||
| } | ||
|
|
||
| /* Get the AML pointer (method object) and BufferField node */ | ||
|
|
||
| ExtraDesc = AcpiNsGetSecondaryObject(ObjDesc); | ||
| Node = ObjDesc->BufferField.Node; | ||
|
|
||
| ACPI_DEBUG_EXEC(AcpiUtDisplayInitPathname(ACPI_TYPE_BUFFER_FIELD, Node, NULL)); | ||
|
|
||
| ACPI_DEBUG_PRINT( | ||
| (ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n", AcpiUtGetNodeName(Node))); | ||
|
|
||
| /* Execute the AML code for the TermArg arguments */ | ||
|
|
||
| Status = AcpiDsExecuteArguments(Node, Node->Parent, ExtraDesc->Extra.AmlLength, | ||
| ExtraDesc->Extra.AmlStart); | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiDsGetBankFieldArguments | ||
| * | ||
| * PARAMETERS: ObjDesc - A valid BankField object | ||
| * | ||
| * RETURN: Status. | ||
| * | ||
| * DESCRIPTION: Get BankField BankValue. This implements the late | ||
| * evaluation of these field attributes. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiDsGetBankFieldArguments(ACPI_OPERAND_OBJECT *ObjDesc) | ||
| { | ||
| ACPI_OPERAND_OBJECT *ExtraDesc; | ||
| ACPI_NAMESPACE_NODE *Node; | ||
| ACPI_STATUS Status; | ||
|
|
||
| ACPI_FUNCTION_TRACE_PTR(DsGetBankFieldArguments, ObjDesc); | ||
|
|
||
| if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID) { | ||
| return_ACPI_STATUS(AE_OK); | ||
| } | ||
|
|
||
| /* Get the AML pointer (method object) and BankField node */ | ||
|
|
||
| ExtraDesc = AcpiNsGetSecondaryObject(ObjDesc); | ||
| Node = ObjDesc->BankField.Node; | ||
|
|
||
| ACPI_DEBUG_EXEC(AcpiUtDisplayInitPathname(ACPI_TYPE_LOCAL_BANK_FIELD, Node, NULL)); | ||
|
|
||
| ACPI_DEBUG_PRINT( | ||
| (ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n", AcpiUtGetNodeName(Node))); | ||
|
|
||
| /* Execute the AML code for the TermArg arguments */ | ||
|
|
||
| Status = AcpiDsExecuteArguments(Node, Node->Parent, ExtraDesc->Extra.AmlLength, | ||
| ExtraDesc->Extra.AmlStart); | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiDsGetBufferArguments | ||
| * | ||
| * PARAMETERS: ObjDesc - A valid Buffer object | ||
| * | ||
| * RETURN: Status. | ||
| * | ||
| * DESCRIPTION: Get Buffer length and initializer byte list. This implements | ||
| * the late evaluation of these attributes. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiDsGetBufferArguments(ACPI_OPERAND_OBJECT *ObjDesc) | ||
| { | ||
| ACPI_NAMESPACE_NODE *Node; | ||
| ACPI_STATUS Status; | ||
|
|
||
| ACPI_FUNCTION_TRACE_PTR(DsGetBufferArguments, ObjDesc); | ||
|
|
||
| if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID) { | ||
| return_ACPI_STATUS(AE_OK); | ||
| } | ||
|
|
||
| /* Get the Buffer node */ | ||
|
|
||
| Node = ObjDesc->Buffer.Node; | ||
| if (!Node) { | ||
| ACPI_ERROR( | ||
| (AE_INFO, "No pointer back to namespace node in buffer object %p", ObjDesc)); | ||
| return_ACPI_STATUS(AE_AML_INTERNAL); | ||
| } | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Buffer Arg Init\n")); | ||
|
|
||
| /* Execute the AML code for the TermArg arguments */ | ||
|
|
||
| Status = AcpiDsExecuteArguments(Node, Node, ObjDesc->Buffer.AmlLength, | ||
| ObjDesc->Buffer.AmlStart); | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiDsGetPackageArguments | ||
| * | ||
| * PARAMETERS: ObjDesc - A valid Package object | ||
| * | ||
| * RETURN: Status. | ||
| * | ||
| * DESCRIPTION: Get Package length and initializer byte list. This implements | ||
| * the late evaluation of these attributes. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiDsGetPackageArguments(ACPI_OPERAND_OBJECT *ObjDesc) | ||
| { | ||
| ACPI_NAMESPACE_NODE *Node; | ||
| ACPI_STATUS Status; | ||
|
|
||
| ACPI_FUNCTION_TRACE_PTR(DsGetPackageArguments, ObjDesc); | ||
|
|
||
| if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID) { | ||
| return_ACPI_STATUS(AE_OK); | ||
| } | ||
|
|
||
| /* Get the Package node */ | ||
|
|
||
| Node = ObjDesc->Package.Node; | ||
| if (!Node) { | ||
| ACPI_ERROR((AE_INFO, "No pointer back to namespace node in package %p", ObjDesc)); | ||
| return_ACPI_STATUS(AE_AML_INTERNAL); | ||
| } | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Package Argument Init, AML Ptr: %p\n", | ||
| ObjDesc->Package.AmlStart)); | ||
|
|
||
| /* Execute the AML code for the TermArg arguments */ | ||
|
|
||
| Status = AcpiDsExecuteArguments(Node, Node, ObjDesc->Package.AmlLength, | ||
| ObjDesc->Package.AmlStart); | ||
|
|
||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiDsGetRegionArguments | ||
| * | ||
| * PARAMETERS: ObjDesc - A valid region object | ||
| * | ||
| * RETURN: Status. | ||
| * | ||
| * DESCRIPTION: Get region address and length. This implements the late | ||
| * evaluation of these region attributes. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiDsGetRegionArguments(ACPI_OPERAND_OBJECT *ObjDesc) | ||
| { | ||
| ACPI_NAMESPACE_NODE *Node; | ||
| ACPI_STATUS Status; | ||
| ACPI_OPERAND_OBJECT *ExtraDesc; | ||
|
|
||
| ACPI_FUNCTION_TRACE_PTR(DsGetRegionArguments, ObjDesc); | ||
|
|
||
| if (ObjDesc->Region.Flags & AOPOBJ_DATA_VALID) { | ||
| return_ACPI_STATUS(AE_OK); | ||
| } | ||
|
|
||
| ExtraDesc = AcpiNsGetSecondaryObject(ObjDesc); | ||
| if (!ExtraDesc) { | ||
| return_ACPI_STATUS(AE_NOT_EXIST); | ||
| } | ||
|
|
||
| /* Get the Region node */ | ||
|
|
||
| Node = ObjDesc->Region.Node; | ||
|
|
||
| ACPI_DEBUG_EXEC(AcpiUtDisplayInitPathname(ACPI_TYPE_REGION, Node, NULL)); | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n", | ||
| AcpiUtGetNodeName(Node), ExtraDesc->Extra.AmlStart)); | ||
|
|
||
| /* Execute the argument AML */ | ||
|
|
||
| Status = AcpiDsExecuteArguments(Node, ExtraDesc->Extra.ScopeNode, | ||
| ExtraDesc->Extra.AmlLength, | ||
| ExtraDesc->Extra.AmlStart); | ||
| if (ACPI_FAILURE(Status)) { | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| Status = AcpiUtAddAddressRange(ObjDesc->Region.SpaceId, ObjDesc->Region.Address, | ||
| ObjDesc->Region.Length, Node); | ||
| return_ACPI_STATUS(Status); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,373 @@ | ||
| /****************************************************************************** | ||
| * | ||
| * Module Name: dscontrol - Support for execution control opcodes - | ||
| * if/else/while/return | ||
| * | ||
| *****************************************************************************/ | ||
|
|
||
| /* | ||
| * Copyright (C) 2000 - 2022, Intel Corp. | ||
| * All rights reserved. | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions, and the following disclaimer, | ||
| * without modification. | ||
| * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
| * substantially similar to the "NO WARRANTY" disclaimer below | ||
| * ("Disclaimer") and any redistribution must be conditioned upon | ||
| * including a substantially similar Disclaimer requirement for further | ||
| * binary redistribution. | ||
| * 3. Neither the names of the above-listed copyright holders nor the names | ||
| * of any contributors may be used to endorse or promote products derived | ||
| * from this software without specific prior written permission. | ||
| * | ||
| * Alternatively, this software may be distributed under the terms of the | ||
| * GNU General Public License ("GPL") version 2 as published by the Free | ||
| * Software Foundation. | ||
| * | ||
| * NO WARRANTY | ||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
| * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| * POSSIBILITY OF SUCH DAMAGES. | ||
| */ | ||
|
|
||
| #include "acpi.h" | ||
| #include "accommon.h" | ||
| #include "amlcode.h" | ||
| #include "acdispat.h" | ||
| #include "acinterp.h" | ||
| #include "acdebug.h" | ||
|
|
||
| #define _COMPONENT ACPI_DISPATCHER | ||
| ACPI_MODULE_NAME("dscontrol") | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiDsExecBeginControlOp | ||
| * | ||
| * PARAMETERS: WalkList - The list that owns the walk stack | ||
| * Op - The control Op | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Handles all control ops encountered during control method | ||
| * execution. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiDsExecBeginControlOp(ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Op) | ||
| { | ||
| ACPI_STATUS Status = AE_OK; | ||
| ACPI_GENERIC_STATE *ControlState; | ||
|
|
||
| ACPI_FUNCTION_NAME(DsExecBeginControlOp); | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", Op, | ||
| Op->Common.AmlOpcode, WalkState)); | ||
|
|
||
| switch (Op->Common.AmlOpcode) { | ||
| case AML_WHILE_OP: | ||
| /* | ||
| * If this is an additional iteration of a while loop, continue. | ||
| * There is no need to allocate a new control state. | ||
| */ | ||
| if (WalkState->ControlState) { | ||
| if (WalkState->ControlState->Control.AmlPredicateStart == | ||
| (WalkState->ParserState.Aml - 1)) { | ||
| /* Reset the state to start-of-loop */ | ||
|
|
||
| WalkState->ControlState->Common.State = ACPI_CONTROL_CONDITIONAL_EXECUTING; | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| ACPI_FALLTHROUGH; | ||
|
|
||
| case AML_IF_OP: | ||
| /* | ||
| * IF/WHILE: Create a new control state to manage these | ||
| * constructs. We need to manage these as a stack, in order | ||
| * to handle nesting. | ||
| */ | ||
| ControlState = AcpiUtCreateControlState(); | ||
| if (!ControlState) { | ||
| Status = AE_NO_MEMORY; | ||
| break; | ||
| } | ||
| /* | ||
| * Save a pointer to the predicate for multiple executions | ||
| * of a loop | ||
| */ | ||
| ControlState->Control.AmlPredicateStart = WalkState->ParserState.Aml - 1; | ||
| ControlState->Control.PackageEnd = WalkState->ParserState.PkgEnd; | ||
| ControlState->Control.Opcode = Op->Common.AmlOpcode; | ||
| ControlState->Control.LoopTimeout = AcpiOsGetTimer() + | ||
| ((UINT64)AcpiGbl_MaxLoopIterations * | ||
| ACPI_100NSEC_PER_SEC); | ||
|
|
||
| /* Push the control state on this walk's control stack */ | ||
|
|
||
| AcpiUtPushGenericState(&WalkState->ControlState, ControlState); | ||
| break; | ||
|
|
||
| case AML_ELSE_OP: | ||
|
|
||
| /* Predicate is in the state object */ | ||
| /* If predicate is true, the IF was executed, ignore ELSE part */ | ||
|
|
||
| if (WalkState->LastPredicate) { | ||
| Status = AE_CTRL_TRUE; | ||
| } | ||
|
|
||
| break; | ||
|
|
||
| case AML_RETURN_OP: | ||
|
|
||
| break; | ||
|
|
||
| default: | ||
|
|
||
| break; | ||
| } | ||
|
|
||
| return (Status); | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiDsExecEndControlOp | ||
| * | ||
| * PARAMETERS: WalkList - The list that owns the walk stack | ||
| * Op - The control Op | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Handles all control ops encountered during control method | ||
| * execution. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiDsExecEndControlOp(ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Op) | ||
| { | ||
| ACPI_STATUS Status = AE_OK; | ||
| ACPI_GENERIC_STATE *ControlState; | ||
|
|
||
| ACPI_FUNCTION_NAME(DsExecEndControlOp); | ||
|
|
||
| switch (Op->Common.AmlOpcode) { | ||
| case AML_IF_OP: | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", Op)); | ||
|
|
||
| /* | ||
| * Save the result of the predicate in case there is an | ||
| * ELSE to come | ||
| */ | ||
| WalkState->LastPredicate = (BOOLEAN)WalkState->ControlState->Common.Value; | ||
|
|
||
| /* | ||
| * Pop the control state that was created at the start | ||
| * of the IF and free it | ||
| */ | ||
| ControlState = AcpiUtPopGenericState(&WalkState->ControlState); | ||
| AcpiUtDeleteGenericState(ControlState); | ||
| break; | ||
|
|
||
| case AML_ELSE_OP: | ||
|
|
||
| break; | ||
|
|
||
| case AML_WHILE_OP: | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", Op)); | ||
|
|
||
| ControlState = WalkState->ControlState; | ||
| if (ControlState->Common.Value) { | ||
| /* Predicate was true, the body of the loop was just executed */ | ||
|
|
||
| /* | ||
| * This infinite loop detection mechanism allows the interpreter | ||
| * to escape possibly infinite loops. This can occur in poorly | ||
| * written AML when the hardware does not respond within a while | ||
| * loop and the loop does not implement a timeout. | ||
| */ | ||
| if (ACPI_TIME_AFTER(AcpiOsGetTimer(), ControlState->Control.LoopTimeout)) { | ||
| Status = AE_AML_LOOP_TIMEOUT; | ||
| break; | ||
| } | ||
|
|
||
| /* | ||
| * Go back and evaluate the predicate and maybe execute the loop | ||
| * another time | ||
| */ | ||
| Status = AE_CTRL_PENDING; | ||
| WalkState->AmlLastWhile = ControlState->Control.AmlPredicateStart; | ||
| break; | ||
| } | ||
|
|
||
| /* Predicate was false, terminate this while loop */ | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[WHILE_OP] termination! Op=%p\n", Op)); | ||
|
|
||
| /* Pop this control state and free it */ | ||
|
|
||
| ControlState = AcpiUtPopGenericState(&WalkState->ControlState); | ||
| AcpiUtDeleteGenericState(ControlState); | ||
| break; | ||
|
|
||
| case AML_RETURN_OP: | ||
|
|
||
| ACPI_DEBUG_PRINT( | ||
| (ACPI_DB_DISPATCH, "[RETURN_OP] Op=%p Arg=%p\n", Op, Op->Common.Value.Arg)); | ||
|
|
||
| /* | ||
| * One optional operand -- the return value | ||
| * It can be either an immediate operand or a result that | ||
| * has been bubbled up the tree | ||
| */ | ||
| if (Op->Common.Value.Arg) { | ||
| /* Since we have a real Return(), delete any implicit return */ | ||
|
|
||
| AcpiDsClearImplicitReturn(WalkState); | ||
|
|
||
| /* Return statement has an immediate operand */ | ||
|
|
||
| Status = AcpiDsCreateOperands(WalkState, Op->Common.Value.Arg); | ||
| if (ACPI_FAILURE(Status)) { | ||
| return (Status); | ||
| } | ||
|
|
||
| /* | ||
| * If value being returned is a Reference (such as | ||
| * an arg or local), resolve it now because it may | ||
| * cease to exist at the end of the method. | ||
| */ | ||
| Status = AcpiExResolveToValue(&WalkState->Operands[0], WalkState); | ||
| if (ACPI_FAILURE(Status)) { | ||
| return (Status); | ||
| } | ||
|
|
||
| /* | ||
| * Get the return value and save as the last result | ||
| * value. This is the only place where WalkState->ReturnDesc | ||
| * is set to anything other than zero! | ||
| */ | ||
| WalkState->ReturnDesc = WalkState->Operands[0]; | ||
| } else if (WalkState->ResultCount) { | ||
| /* Since we have a real Return(), delete any implicit return */ | ||
|
|
||
| AcpiDsClearImplicitReturn(WalkState); | ||
|
|
||
| /* | ||
| * The return value has come from a previous calculation. | ||
| * | ||
| * If value being returned is a Reference (such as | ||
| * an arg or local), resolve it now because it may | ||
| * cease to exist at the end of the method. | ||
| * | ||
| * Allow references created by the Index operator to return | ||
| * unchanged. | ||
| */ | ||
| if ((ACPI_GET_DESCRIPTOR_TYPE(WalkState->Results->Results.ObjDesc[0]) == | ||
| ACPI_DESC_TYPE_OPERAND) && | ||
| ((WalkState->Results->Results.ObjDesc[0])->Common.Type == | ||
| ACPI_TYPE_LOCAL_REFERENCE) && | ||
| ((WalkState->Results->Results.ObjDesc[0])->Reference.Class != | ||
| ACPI_REFCLASS_INDEX)) { | ||
| Status = AcpiExResolveToValue(&WalkState->Results->Results.ObjDesc[0], | ||
| WalkState); | ||
| if (ACPI_FAILURE(Status)) { | ||
| return (Status); | ||
| } | ||
| } | ||
|
|
||
| WalkState->ReturnDesc = WalkState->Results->Results.ObjDesc[0]; | ||
| } else { | ||
| /* No return operand */ | ||
|
|
||
| if (WalkState->NumOperands) { | ||
| AcpiUtRemoveReference(WalkState->Operands[0]); | ||
| } | ||
|
|
||
| WalkState->Operands[0] = NULL; | ||
| WalkState->NumOperands = 0; | ||
| WalkState->ReturnDesc = NULL; | ||
| } | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Completed RETURN_OP State=%p, RetVal=%p\n", | ||
| WalkState, WalkState->ReturnDesc)); | ||
|
|
||
| /* End the control method execution right now */ | ||
|
|
||
| Status = AE_CTRL_TERMINATE; | ||
| break; | ||
|
|
||
| case AML_NOOP_OP: | ||
|
|
||
| /* Just do nothing! */ | ||
|
|
||
| break; | ||
|
|
||
| case AML_BREAKPOINT_OP: | ||
|
|
||
| AcpiDbSignalBreakPoint(WalkState); | ||
|
|
||
| /* Call to the OSL in case OS wants a piece of the action */ | ||
|
|
||
| Status = AcpiOsSignal(ACPI_SIGNAL_BREAKPOINT, "Executed AML Breakpoint opcode"); | ||
| break; | ||
|
|
||
| case AML_BREAK_OP: | ||
| case AML_CONTINUE_OP: /* ACPI 2.0 */ | ||
|
|
||
| /* Pop and delete control states until we find a while */ | ||
|
|
||
| while (WalkState->ControlState && | ||
| (WalkState->ControlState->Control.Opcode != AML_WHILE_OP)) { | ||
| ControlState = AcpiUtPopGenericState(&WalkState->ControlState); | ||
| AcpiUtDeleteGenericState(ControlState); | ||
| } | ||
|
|
||
| /* No while found? */ | ||
|
|
||
| if (!WalkState->ControlState) { | ||
| return (AE_AML_NO_WHILE); | ||
| } | ||
|
|
||
| /* Was: WalkState->AmlLastWhile = WalkState->ControlState->Control.AmlPredicateStart; */ | ||
|
|
||
| WalkState->AmlLastWhile = WalkState->ControlState->Control.PackageEnd; | ||
|
|
||
| /* Return status depending on opcode */ | ||
|
|
||
| if (Op->Common.AmlOpcode == AML_BREAK_OP) { | ||
| Status = AE_CTRL_BREAK; | ||
| } else { | ||
| Status = AE_CTRL_CONTINUE; | ||
| } | ||
| break; | ||
|
|
||
| default: | ||
|
|
||
| ACPI_ERROR( | ||
| (AE_INFO, "Unknown control opcode=0x%X Op=%p", Op->Common.AmlOpcode, Op)); | ||
|
|
||
| Status = AE_AML_BAD_OPCODE; | ||
| break; | ||
| } | ||
|
|
||
| return (Status); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,221 @@ | ||
| /****************************************************************************** | ||
| * | ||
| * Module Name: dsdebug - Parser/Interpreter interface - debugging | ||
| * | ||
| *****************************************************************************/ | ||
|
|
||
| /* | ||
| * Copyright (C) 2000 - 2022, Intel Corp. | ||
| * All rights reserved. | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions, and the following disclaimer, | ||
| * without modification. | ||
| * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
| * substantially similar to the "NO WARRANTY" disclaimer below | ||
| * ("Disclaimer") and any redistribution must be conditioned upon | ||
| * including a substantially similar Disclaimer requirement for further | ||
| * binary redistribution. | ||
| * 3. Neither the names of the above-listed copyright holders nor the names | ||
| * of any contributors may be used to endorse or promote products derived | ||
| * from this software without specific prior written permission. | ||
| * | ||
| * Alternatively, this software may be distributed under the terms of the | ||
| * GNU General Public License ("GPL") version 2 as published by the Free | ||
| * Software Foundation. | ||
| * | ||
| * NO WARRANTY | ||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
| * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| * POSSIBILITY OF SUCH DAMAGES. | ||
| */ | ||
|
|
||
| #include "acpi.h" | ||
| #include "accommon.h" | ||
| #include "acdispat.h" | ||
| #include "acnamesp.h" | ||
| #include "acdisasm.h" | ||
| #include "acinterp.h" | ||
|
|
||
| #define _COMPONENT ACPI_DISPATCHER | ||
| ACPI_MODULE_NAME("dsdebug") | ||
|
|
||
| #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) | ||
|
|
||
| /* Local prototypes */ | ||
|
|
||
| static void AcpiDsPrintNodePathname(ACPI_NAMESPACE_NODE *Node, const char *Message); | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiDsPrintNodePathname | ||
| * | ||
| * PARAMETERS: Node - Object | ||
| * Message - Prefix message | ||
| * | ||
| * DESCRIPTION: Print an object's full namespace pathname | ||
| * Manages allocation/freeing of a pathname buffer | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| static void AcpiDsPrintNodePathname(ACPI_NAMESPACE_NODE *Node, const char *Message) | ||
| { | ||
| ACPI_BUFFER Buffer; | ||
| ACPI_STATUS Status; | ||
|
|
||
| ACPI_FUNCTION_TRACE(DsPrintNodePathname); | ||
|
|
||
| if (!Node) { | ||
| ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "[NULL NAME]")); | ||
| return_VOID; | ||
| } | ||
|
|
||
| /* Convert handle to full pathname and print it (with supplied message) */ | ||
|
|
||
| Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; | ||
|
|
||
| Status = AcpiNsHandleToPathname(Node, &Buffer, TRUE); | ||
| if (ACPI_SUCCESS(Status)) { | ||
| if (Message) { | ||
| ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "%s ", Message)); | ||
| } | ||
|
|
||
| ACPI_DEBUG_PRINT_RAW( | ||
| (ACPI_DB_DISPATCH, "[%s] (Node %p)", (char *)Buffer.Pointer, Node)); | ||
| ACPI_FREE(Buffer.Pointer); | ||
| } | ||
|
|
||
| return_VOID; | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiDsDumpMethodStack | ||
| * | ||
| * PARAMETERS: Status - Method execution status | ||
| * WalkState - Current state of the parse tree walk | ||
| * Op - Executing parse op | ||
| * | ||
| * RETURN: None | ||
| * | ||
| * DESCRIPTION: Called when a method has been aborted because of an error. | ||
| * Dumps the method execution stack. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| void AcpiDsDumpMethodStack(ACPI_STATUS Status, ACPI_WALK_STATE *WalkState, | ||
| ACPI_PARSE_OBJECT *Op) | ||
| { | ||
| ACPI_PARSE_OBJECT *Next; | ||
| ACPI_THREAD_STATE *Thread; | ||
| ACPI_WALK_STATE *NextWalkState; | ||
| ACPI_NAMESPACE_NODE *PreviousMethod = NULL; | ||
| ACPI_OPERAND_OBJECT *MethodDesc; | ||
|
|
||
| ACPI_FUNCTION_TRACE(DsDumpMethodStack); | ||
|
|
||
| /* Ignore control codes, they are not errors */ | ||
|
|
||
| if (ACPI_CNTL_EXCEPTION(Status)) { | ||
| return_VOID; | ||
| } | ||
|
|
||
| /* We may be executing a deferred opcode */ | ||
|
|
||
| if (WalkState->DeferredNode) { | ||
| ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Executing subtree for " | ||
| "Buffer/Package/Region\n")); | ||
| return_VOID; | ||
| } | ||
|
|
||
| /* | ||
| * If there is no Thread, we are not actually executing a method. | ||
| * This can happen when the iASL compiler calls the interpreter | ||
| * to perform constant folding. | ||
| */ | ||
| Thread = WalkState->Thread; | ||
| if (!Thread) { | ||
| return_VOID; | ||
| } | ||
|
|
||
| /* Display exception and method name */ | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "\n**** Exception %s during execution of method ", | ||
| AcpiFormatException(Status))); | ||
|
|
||
| AcpiDsPrintNodePathname(WalkState->MethodNode, NULL); | ||
|
|
||
| /* Display stack of executing methods */ | ||
|
|
||
| ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "\n\nMethod Execution Stack:\n")); | ||
| NextWalkState = Thread->WalkStateList; | ||
|
|
||
| /* Walk list of linked walk states */ | ||
|
|
||
| while (NextWalkState) { | ||
| MethodDesc = NextWalkState->MethodDesc; | ||
| if (MethodDesc) { | ||
| AcpiExStopTraceMethod((ACPI_NAMESPACE_NODE *)MethodDesc->Method.Node, | ||
| MethodDesc, WalkState); | ||
| } | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, " Method [%4.4s] executing: ", | ||
| AcpiUtGetNodeName(NextWalkState->MethodNode))); | ||
|
|
||
| /* First method is the currently executing method */ | ||
|
|
||
| if (NextWalkState == WalkState) { | ||
| if (Op) { | ||
| /* Display currently executing ASL statement */ | ||
|
|
||
| Next = Op->Common.Next; | ||
| Op->Common.Next = NULL; | ||
|
|
||
| #ifdef ACPI_DISASSEMBLER | ||
| if (WalkState->MethodNode != AcpiGbl_RootNode) { | ||
| /* More verbose if not module-level code */ | ||
|
|
||
| AcpiOsPrintf("Failed at "); | ||
| AcpiDmDisassemble(NextWalkState, Op, ACPI_UINT32_MAX); | ||
| } | ||
| #endif | ||
| Op->Common.Next = Next; | ||
| } | ||
| } else { | ||
| /* | ||
| * This method has called another method | ||
| * NOTE: the method call parse subtree is already deleted at | ||
| * this point, so we cannot disassemble the method invocation. | ||
| */ | ||
| ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "Call to method ")); | ||
| AcpiDsPrintNodePathname(PreviousMethod, NULL); | ||
| } | ||
|
|
||
| PreviousMethod = NextWalkState->MethodNode; | ||
| NextWalkState = NextWalkState->Next; | ||
| ACPI_DEBUG_PRINT_RAW((ACPI_DB_DISPATCH, "\n")); | ||
| } | ||
|
|
||
| return_VOID; | ||
| } | ||
|
|
||
| #else | ||
|
|
||
| void AcpiDsDumpMethodStack(ACPI_STATUS Status, ACPI_WALK_STATE *WalkState, | ||
| ACPI_PARSE_OBJECT *Op) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| #endif |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,246 @@ | ||
| /****************************************************************************** | ||
| * | ||
| * Module Name: dsinit - Object initialization namespace walk | ||
| * | ||
| *****************************************************************************/ | ||
|
|
||
| /* | ||
| * Copyright (C) 2000 - 2022, Intel Corp. | ||
| * All rights reserved. | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions, and the following disclaimer, | ||
| * without modification. | ||
| * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
| * substantially similar to the "NO WARRANTY" disclaimer below | ||
| * ("Disclaimer") and any redistribution must be conditioned upon | ||
| * including a substantially similar Disclaimer requirement for further | ||
| * binary redistribution. | ||
| * 3. Neither the names of the above-listed copyright holders nor the names | ||
| * of any contributors may be used to endorse or promote products derived | ||
| * from this software without specific prior written permission. | ||
| * | ||
| * Alternatively, this software may be distributed under the terms of the | ||
| * GNU General Public License ("GPL") version 2 as published by the Free | ||
| * Software Foundation. | ||
| * | ||
| * NO WARRANTY | ||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
| * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| * POSSIBILITY OF SUCH DAMAGES. | ||
| */ | ||
|
|
||
| #include "acpi.h" | ||
| #include "accommon.h" | ||
| #include "acdispat.h" | ||
| #include "acnamesp.h" | ||
| #include "actables.h" | ||
| #include "acinterp.h" | ||
|
|
||
| #define _COMPONENT ACPI_DISPATCHER | ||
| ACPI_MODULE_NAME("dsinit") | ||
|
|
||
| /* Local prototypes */ | ||
|
|
||
| static ACPI_STATUS AcpiDsInitOneObject(ACPI_HANDLE ObjHandle, UINT32 Level, void *Context, | ||
| void **ReturnValue); | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiDsInitOneObject | ||
| * | ||
| * PARAMETERS: ObjHandle - Node for the object | ||
| * Level - Current nesting level | ||
| * Context - Points to a init info struct | ||
| * ReturnValue - Not used | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Callback from AcpiWalkNamespace. Invoked for every object | ||
| * within the namespace. | ||
| * | ||
| * Currently, the only objects that require initialization are: | ||
| * 1) Methods | ||
| * 2) Operation Regions | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| static ACPI_STATUS AcpiDsInitOneObject(ACPI_HANDLE ObjHandle, UINT32 Level, void *Context, | ||
| void **ReturnValue) | ||
| { | ||
| ACPI_INIT_WALK_INFO *Info = (ACPI_INIT_WALK_INFO *)Context; | ||
| ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *)ObjHandle; | ||
| ACPI_STATUS Status; | ||
| ACPI_OPERAND_OBJECT *ObjDesc; | ||
|
|
||
| ACPI_FUNCTION_ENTRY(); | ||
|
|
||
| /* | ||
| * We are only interested in NS nodes owned by the table that | ||
| * was just loaded | ||
| */ | ||
| if (Node->OwnerId != Info->OwnerId) { | ||
| return (AE_OK); | ||
| } | ||
|
|
||
| Info->ObjectCount++; | ||
|
|
||
| /* And even then, we are only interested in a few object types */ | ||
|
|
||
| switch (AcpiNsGetType(ObjHandle)) { | ||
| case ACPI_TYPE_REGION: | ||
|
|
||
| Status = AcpiDsInitializeRegion(ObjHandle); | ||
| if (ACPI_FAILURE(Status)) { | ||
| ACPI_EXCEPTION((AE_INFO, Status, "During Region initialization %p [%4.4s]", | ||
| ObjHandle, AcpiUtGetNodeName(ObjHandle))); | ||
| } | ||
|
|
||
| Info->OpRegionCount++; | ||
| break; | ||
|
|
||
| case ACPI_TYPE_METHOD: | ||
| /* | ||
| * Auto-serialization support. We will examine each method that is | ||
| * NotSerialized to determine if it creates any Named objects. If | ||
| * it does, it will be marked serialized to prevent problems if | ||
| * the method is entered by two or more threads and an attempt is | ||
| * made to create the same named object twice -- which results in | ||
| * an AE_ALREADY_EXISTS exception and method abort. | ||
| */ | ||
| Info->MethodCount++; | ||
| ObjDesc = AcpiNsGetAttachedObject(Node); | ||
| if (!ObjDesc) { | ||
| break; | ||
| } | ||
|
|
||
| /* Ignore if already serialized */ | ||
|
|
||
| if (ObjDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED) { | ||
| Info->SerialMethodCount++; | ||
| break; | ||
| } | ||
|
|
||
| if (AcpiGbl_AutoSerializeMethods) { | ||
| /* Parse/scan method and serialize it if necessary */ | ||
|
|
||
| AcpiDsAutoSerializeMethod(Node, ObjDesc); | ||
| if (ObjDesc->Method.InfoFlags & ACPI_METHOD_SERIALIZED) { | ||
| /* Method was just converted to Serialized */ | ||
|
|
||
| Info->SerialMethodCount++; | ||
| Info->SerializedMethodCount++; | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| Info->NonSerialMethodCount++; | ||
| break; | ||
|
|
||
| case ACPI_TYPE_DEVICE: | ||
|
|
||
| Info->DeviceCount++; | ||
| break; | ||
|
|
||
| default: | ||
|
|
||
| break; | ||
| } | ||
|
|
||
| /* | ||
| * We ignore errors from above, and always return OK, since | ||
| * we don't want to abort the walk on a single error. | ||
| */ | ||
| return (AE_OK); | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiDsInitializeObjects | ||
| * | ||
| * PARAMETERS: TableDesc - Descriptor for parent ACPI table | ||
| * StartNode - Root of subtree to be initialized. | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Walk the namespace starting at "StartNode" and perform any | ||
| * necessary initialization on the objects found therein | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiDsInitializeObjects(UINT32 TableIndex, ACPI_NAMESPACE_NODE *StartNode) | ||
| { | ||
| ACPI_STATUS Status; | ||
| ACPI_INIT_WALK_INFO Info; | ||
| ACPI_TABLE_HEADER *Table; | ||
| ACPI_OWNER_ID OwnerId; | ||
|
|
||
| ACPI_FUNCTION_TRACE(DsInitializeObjects); | ||
|
|
||
| Status = AcpiTbGetOwnerId(TableIndex, &OwnerId); | ||
| if (ACPI_FAILURE(Status)) { | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "**** Starting initialization of namespace " | ||
| "objects ****\n")); | ||
|
|
||
| /* Set all init info to zero */ | ||
|
|
||
| memset(&Info, 0, sizeof(ACPI_INIT_WALK_INFO)); | ||
|
|
||
| Info.OwnerId = OwnerId; | ||
| Info.TableIndex = TableIndex; | ||
|
|
||
| /* Walk entire namespace from the supplied root */ | ||
|
|
||
| /* | ||
| * We don't use AcpiWalkNamespace since we do not want to acquire | ||
| * the namespace reader lock. | ||
| */ | ||
| Status = AcpiNsWalkNamespace(ACPI_TYPE_ANY, StartNode, ACPI_UINT32_MAX, | ||
| ACPI_NS_WALK_NO_UNLOCK, AcpiDsInitOneObject, NULL, &Info, | ||
| NULL); | ||
| if (ACPI_FAILURE(Status)) { | ||
| ACPI_EXCEPTION((AE_INFO, Status, "During WalkNamespace")); | ||
| } | ||
|
|
||
| Status = AcpiGetTableByIndex(TableIndex, &Table); | ||
| if (ACPI_FAILURE(Status)) { | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| /* DSDT is always the first AML table */ | ||
|
|
||
| if (ACPI_COMPARE_NAMESEG(Table->Signature, ACPI_SIG_DSDT)) { | ||
| ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "\nACPI table initialization:\n")); | ||
| } | ||
|
|
||
| /* Summary of objects initialized */ | ||
|
|
||
| ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, | ||
| "Table [%4.4s: %-8.8s] (id %.2X) - %4u Objects with %3u " | ||
| "Devices, " | ||
| "%3u Regions, %4u Methods (%u/%u/%u Serial/Non/Cvt)\n", | ||
| Table->Signature, Table->OemTableId, OwnerId, Info.ObjectCount, | ||
| Info.DeviceCount, Info.OpRegionCount, Info.MethodCount, | ||
| Info.SerialMethodCount, Info.NonSerialMethodCount, | ||
| Info.SerializedMethodCount)); | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "%u Methods, %u Regions\n", Info.MethodCount, | ||
| Info.OpRegionCount)); | ||
|
|
||
| return_ACPI_STATUS(AE_OK); | ||
| } |
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,203 @@ | ||
| /****************************************************************************** | ||
| * | ||
| * Module Name: dswscope - Scope stack manipulation | ||
| * | ||
| *****************************************************************************/ | ||
|
|
||
| /* | ||
| * Copyright (C) 2000 - 2022, Intel Corp. | ||
| * All rights reserved. | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions, and the following disclaimer, | ||
| * without modification. | ||
| * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
| * substantially similar to the "NO WARRANTY" disclaimer below | ||
| * ("Disclaimer") and any redistribution must be conditioned upon | ||
| * including a substantially similar Disclaimer requirement for further | ||
| * binary redistribution. | ||
| * 3. Neither the names of the above-listed copyright holders nor the names | ||
| * of any contributors may be used to endorse or promote products derived | ||
| * from this software without specific prior written permission. | ||
| * | ||
| * Alternatively, this software may be distributed under the terms of the | ||
| * GNU General Public License ("GPL") version 2 as published by the Free | ||
| * Software Foundation. | ||
| * | ||
| * NO WARRANTY | ||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
| * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| * POSSIBILITY OF SUCH DAMAGES. | ||
| */ | ||
|
|
||
| #include "acpi.h" | ||
| #include "accommon.h" | ||
| #include "acdispat.h" | ||
|
|
||
| #define _COMPONENT ACPI_DISPATCHER | ||
| ACPI_MODULE_NAME("dswscope") | ||
|
|
||
| /**************************************************************************** | ||
| * | ||
| * FUNCTION: AcpiDsScopeStackClear | ||
| * | ||
| * PARAMETERS: WalkState - Current state | ||
| * | ||
| * RETURN: None | ||
| * | ||
| * DESCRIPTION: Pop (and free) everything on the scope stack except the | ||
| * root scope object (which remains at the stack top.) | ||
| * | ||
| ***************************************************************************/ | ||
|
|
||
| void AcpiDsScopeStackClear(ACPI_WALK_STATE *WalkState) | ||
| { | ||
| ACPI_GENERIC_STATE *ScopeInfo; | ||
|
|
||
| ACPI_FUNCTION_NAME(DsScopeStackClear); | ||
|
|
||
| while (WalkState->ScopeInfo) { | ||
| /* Pop a scope off the stack */ | ||
|
|
||
| ScopeInfo = WalkState->ScopeInfo; | ||
| WalkState->ScopeInfo = ScopeInfo->Scope.Next; | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Popped object type (%s)\n", | ||
| AcpiUtGetTypeName(ScopeInfo->Common.Value))); | ||
|
|
||
| AcpiUtDeleteGenericState(ScopeInfo); | ||
| } | ||
| } | ||
|
|
||
| /**************************************************************************** | ||
| * | ||
| * FUNCTION: AcpiDsScopeStackPush | ||
| * | ||
| * PARAMETERS: Node - Name to be made current | ||
| * Type - Type of frame being pushed | ||
| * WalkState - Current state | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Push the current scope on the scope stack, and make the | ||
| * passed Node current. | ||
| * | ||
| ***************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiDsScopeStackPush(ACPI_NAMESPACE_NODE *Node, ACPI_OBJECT_TYPE Type, | ||
| ACPI_WALK_STATE *WalkState) | ||
| { | ||
| ACPI_GENERIC_STATE *ScopeInfo; | ||
| ACPI_GENERIC_STATE *OldScopeInfo; | ||
|
|
||
| ACPI_FUNCTION_TRACE(DsScopeStackPush); | ||
|
|
||
| if (!Node) { | ||
| /* Invalid scope */ | ||
|
|
||
| ACPI_ERROR((AE_INFO, "Null scope parameter")); | ||
| return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
| } | ||
|
|
||
| /* Make sure object type is valid */ | ||
|
|
||
| if (!AcpiUtValidObjectType(Type)) { | ||
| ACPI_WARNING((AE_INFO, "Invalid object type: 0x%X", Type)); | ||
| } | ||
|
|
||
| /* Allocate a new scope object */ | ||
|
|
||
| ScopeInfo = AcpiUtCreateGenericState(); | ||
| if (!ScopeInfo) { | ||
| return_ACPI_STATUS(AE_NO_MEMORY); | ||
| } | ||
|
|
||
| /* Init new scope object */ | ||
|
|
||
| ScopeInfo->Common.DescriptorType = ACPI_DESC_TYPE_STATE_WSCOPE; | ||
| ScopeInfo->Scope.Node = Node; | ||
| ScopeInfo->Common.Value = (UINT16)Type; | ||
|
|
||
| WalkState->ScopeDepth++; | ||
|
|
||
| ACPI_DEBUG_PRINT( | ||
| (ACPI_DB_EXEC, "[%.2d] Pushed scope ", (UINT32)WalkState->ScopeDepth)); | ||
|
|
||
| OldScopeInfo = WalkState->ScopeInfo; | ||
| if (OldScopeInfo) { | ||
| ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "[%4.4s] (%s)", | ||
| AcpiUtGetNodeName(OldScopeInfo->Scope.Node), | ||
| AcpiUtGetTypeName(OldScopeInfo->Common.Value))); | ||
| } else { | ||
| ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, ACPI_NAMESPACE_ROOT)); | ||
| } | ||
|
|
||
| ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, ", New scope -> [%4.4s] (%s)\n", | ||
| AcpiUtGetNodeName(ScopeInfo->Scope.Node), | ||
| AcpiUtGetTypeName(ScopeInfo->Common.Value))); | ||
|
|
||
| /* Push new scope object onto stack */ | ||
|
|
||
| AcpiUtPushGenericState(&WalkState->ScopeInfo, ScopeInfo); | ||
| return_ACPI_STATUS(AE_OK); | ||
| } | ||
|
|
||
| /**************************************************************************** | ||
| * | ||
| * FUNCTION: AcpiDsScopeStackPop | ||
| * | ||
| * PARAMETERS: WalkState - Current state | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Pop the scope stack once. | ||
| * | ||
| ***************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiDsScopeStackPop(ACPI_WALK_STATE *WalkState) | ||
| { | ||
| ACPI_GENERIC_STATE *ScopeInfo; | ||
| ACPI_GENERIC_STATE *NewScopeInfo; | ||
|
|
||
| ACPI_FUNCTION_TRACE(DsScopeStackPop); | ||
|
|
||
| /* | ||
| * Pop scope info object off the stack. | ||
| */ | ||
| ScopeInfo = AcpiUtPopGenericState(&WalkState->ScopeInfo); | ||
| if (!ScopeInfo) { | ||
| return_ACPI_STATUS(AE_STACK_UNDERFLOW); | ||
| } | ||
|
|
||
| WalkState->ScopeDepth--; | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%.2d] Popped scope [%4.4s] (%s), New scope -> ", | ||
| (UINT32)WalkState->ScopeDepth, | ||
| AcpiUtGetNodeName(ScopeInfo->Scope.Node), | ||
| AcpiUtGetTypeName(ScopeInfo->Common.Value))); | ||
|
|
||
| NewScopeInfo = WalkState->ScopeInfo; | ||
| if (NewScopeInfo) { | ||
| ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "[%4.4s] (%s)\n", | ||
| AcpiUtGetNodeName(NewScopeInfo->Scope.Node), | ||
| AcpiUtGetTypeName(NewScopeInfo->Common.Value))); | ||
| } else { | ||
| ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "%s\n", ACPI_NAMESPACE_ROOT)); | ||
| } | ||
|
|
||
| AcpiUtDeleteGenericState(ScopeInfo); | ||
| return_ACPI_STATUS(AE_OK); | ||
| } |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,302 @@ | ||
| /****************************************************************************** | ||
| * | ||
| * Module Name: evevent - Fixed Event handling and dispatch | ||
| * | ||
| *****************************************************************************/ | ||
|
|
||
| /* | ||
| * Copyright (C) 2000 - 2022, Intel Corp. | ||
| * All rights reserved. | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions, and the following disclaimer, | ||
| * without modification. | ||
| * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
| * substantially similar to the "NO WARRANTY" disclaimer below | ||
| * ("Disclaimer") and any redistribution must be conditioned upon | ||
| * including a substantially similar Disclaimer requirement for further | ||
| * binary redistribution. | ||
| * 3. Neither the names of the above-listed copyright holders nor the names | ||
| * of any contributors may be used to endorse or promote products derived | ||
| * from this software without specific prior written permission. | ||
| * | ||
| * Alternatively, this software may be distributed under the terms of the | ||
| * GNU General Public License ("GPL") version 2 as published by the Free | ||
| * Software Foundation. | ||
| * | ||
| * NO WARRANTY | ||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
| * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| * POSSIBILITY OF SUCH DAMAGES. | ||
| */ | ||
|
|
||
| #include "acpi.h" | ||
| #include "accommon.h" | ||
| #include "acevents.h" | ||
|
|
||
| #define _COMPONENT ACPI_EVENTS | ||
| ACPI_MODULE_NAME("evevent") | ||
|
|
||
| #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ | ||
|
|
||
| /* Local prototypes */ | ||
|
|
||
| static ACPI_STATUS AcpiEvFixedEventInitialize(void); | ||
|
|
||
| static UINT32 AcpiEvFixedEventDispatch(UINT32 Event); | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiEvInitializeEvents | ||
| * | ||
| * PARAMETERS: None | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Initialize global data structures for ACPI events (Fixed, GPE) | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiEvInitializeEvents(void) | ||
| { | ||
| ACPI_STATUS Status; | ||
|
|
||
| ACPI_FUNCTION_TRACE(EvInitializeEvents); | ||
|
|
||
| /* If Hardware Reduced flag is set, there are no fixed events */ | ||
|
|
||
| if (AcpiGbl_ReducedHardware) { | ||
| return_ACPI_STATUS(AE_OK); | ||
| } | ||
|
|
||
| /* | ||
| * Initialize the Fixed and General Purpose Events. This is done prior to | ||
| * enabling SCIs to prevent interrupts from occurring before the handlers | ||
| * are installed. | ||
| */ | ||
| Status = AcpiEvFixedEventInitialize(); | ||
| if (ACPI_FAILURE(Status)) { | ||
| ACPI_EXCEPTION((AE_INFO, Status, "Unable to initialize fixed events")); | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| Status = AcpiEvGpeInitialize(); | ||
| if (ACPI_FAILURE(Status)) { | ||
| ACPI_EXCEPTION((AE_INFO, Status, "Unable to initialize general purpose events")); | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiEvInstallXruptHandlers | ||
| * | ||
| * PARAMETERS: None | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Install interrupt handlers for the SCI and Global Lock | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiEvInstallXruptHandlers(void) | ||
| { | ||
| ACPI_STATUS Status; | ||
|
|
||
| ACPI_FUNCTION_TRACE(EvInstallXruptHandlers); | ||
|
|
||
| /* If Hardware Reduced flag is set, there is no ACPI h/w */ | ||
|
|
||
| if (AcpiGbl_ReducedHardware) { | ||
| return_ACPI_STATUS(AE_OK); | ||
| } | ||
|
|
||
| /* Install the SCI handler */ | ||
|
|
||
| Status = AcpiEvInstallSciHandler(); | ||
| if (ACPI_FAILURE(Status)) { | ||
| ACPI_EXCEPTION( | ||
| (AE_INFO, Status, "Unable to install System Control Interrupt handler")); | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| /* Install the handler for the Global Lock */ | ||
|
|
||
| Status = AcpiEvInitGlobalLockHandler(); | ||
| if (ACPI_FAILURE(Status)) { | ||
| ACPI_EXCEPTION((AE_INFO, Status, "Unable to initialize Global Lock handler")); | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| AcpiGbl_EventsInitialized = TRUE; | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiEvFixedEventInitialize | ||
| * | ||
| * PARAMETERS: None | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Install the fixed event handlers and disable all fixed events. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| static ACPI_STATUS AcpiEvFixedEventInitialize(void) | ||
| { | ||
| UINT32 i; | ||
| ACPI_STATUS Status; | ||
|
|
||
| /* | ||
| * Initialize the structure that keeps track of fixed event handlers and | ||
| * disable all of the fixed events. | ||
| */ | ||
| for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { | ||
| AcpiGbl_FixedEventHandlers[i].Handler = NULL; | ||
| AcpiGbl_FixedEventHandlers[i].Context = NULL; | ||
|
|
||
| /* Disable the fixed event */ | ||
|
|
||
| if (AcpiGbl_FixedEventInfo[i].EnableRegisterId != 0xFF) { | ||
| Status = AcpiWriteBitRegister(AcpiGbl_FixedEventInfo[i].EnableRegisterId, | ||
| (i == ACPI_EVENT_PCIE_WAKE) ? | ||
| ACPI_ENABLE_EVENT : | ||
| ACPI_DISABLE_EVENT); | ||
| if (ACPI_FAILURE(Status)) { | ||
| return (Status); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return (AE_OK); | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiEvFixedEventDetect | ||
| * | ||
| * PARAMETERS: None | ||
| * | ||
| * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED | ||
| * | ||
| * DESCRIPTION: Checks the PM status register for active fixed events | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| UINT32 | ||
| AcpiEvFixedEventDetect(void) | ||
| { | ||
| UINT32 IntStatus = ACPI_INTERRUPT_NOT_HANDLED; | ||
| UINT32 FixedStatus; | ||
| UINT32 FixedEnable; | ||
| UINT32 i; | ||
| ACPI_STATUS Status; | ||
|
|
||
| ACPI_FUNCTION_NAME(EvFixedEventDetect); | ||
|
|
||
| /* | ||
| * Read the fixed feature status and enable registers, as all the cases | ||
| * depend on their values. Ignore errors here. | ||
| */ | ||
| Status = AcpiHwRegisterRead(ACPI_REGISTER_PM1_STATUS, &FixedStatus); | ||
| Status |= AcpiHwRegisterRead(ACPI_REGISTER_PM1_ENABLE, &FixedEnable); | ||
| if (ACPI_FAILURE(Status)) { | ||
| return (IntStatus); | ||
| } | ||
|
|
||
| if (FixedEnable & ACPI_BITMASK_PCIEXP_WAKE_DISABLE) | ||
| FixedEnable &= ~ACPI_BITMASK_PCIEXP_WAKE_DISABLE; | ||
| else | ||
| FixedEnable |= ACPI_BITMASK_PCIEXP_WAKE_DISABLE; | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, "Fixed Event Block: Enable %08X Status %08X\n", | ||
| FixedEnable, FixedStatus)); | ||
|
|
||
| /* | ||
| * Check for all possible Fixed Events and dispatch those that are active | ||
| */ | ||
| for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { | ||
| /* Both the status and enable bits must be on for this event */ | ||
|
|
||
| if ((FixedStatus & AcpiGbl_FixedEventInfo[i].StatusBitMask) && | ||
| (FixedEnable & AcpiGbl_FixedEventInfo[i].EnableBitMask)) { | ||
| /* | ||
| * 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); | ||
| } | ||
| } | ||
|
|
||
| return (IntStatus); | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiEvFixedEventDispatch | ||
| * | ||
| * PARAMETERS: Event - Event type | ||
| * | ||
| * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED | ||
| * | ||
| * DESCRIPTION: Clears the status bit for the requested event, calls the | ||
| * handler that previously registered for the event. | ||
| * NOTE: If there is no handler for the event, the event is | ||
| * disabled to prevent further interrupts. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| static UINT32 AcpiEvFixedEventDispatch(UINT32 Event) | ||
| { | ||
| ACPI_FUNCTION_ENTRY(); | ||
|
|
||
| /* Clear the status bit */ | ||
|
|
||
| (void)AcpiWriteBitRegister(AcpiGbl_FixedEventInfo[Event].StatusRegisterId, | ||
| ACPI_CLEAR_STATUS); | ||
|
|
||
| /* | ||
| * Make sure that a handler exists. If not, report an error | ||
| * and disable the event to prevent further interrupts. | ||
| */ | ||
| if (!AcpiGbl_FixedEventHandlers[Event].Handler) { | ||
| (void)AcpiWriteBitRegister(AcpiGbl_FixedEventInfo[Event].EnableRegisterId, | ||
| (Event == ACPI_EVENT_PCIE_WAKE) ? ACPI_ENABLE_EVENT : | ||
| ACPI_DISABLE_EVENT); | ||
|
|
||
| ACPI_ERROR((AE_INFO, "No installed handler for fixed event - %s (%u), disabling", | ||
| AcpiUtGetEventName(Event), Event)); | ||
|
|
||
| return (ACPI_INTERRUPT_NOT_HANDLED); | ||
| } | ||
|
|
||
| /* Invoke the Fixed Event handler */ | ||
|
|
||
| return ((AcpiGbl_FixedEventHandlers[Event].Handler)( | ||
| AcpiGbl_FixedEventHandlers[Event].Context)); | ||
| } | ||
|
|
||
| #endif /* !ACPI_REDUCED_HARDWARE */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,338 @@ | ||
| /****************************************************************************** | ||
| * | ||
| * Module Name: evglock - Global Lock support | ||
| * | ||
| *****************************************************************************/ | ||
|
|
||
| /* | ||
| * Copyright (C) 2000 - 2022, Intel Corp. | ||
| * All rights reserved. | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions, and the following disclaimer, | ||
| * without modification. | ||
| * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
| * substantially similar to the "NO WARRANTY" disclaimer below | ||
| * ("Disclaimer") and any redistribution must be conditioned upon | ||
| * including a substantially similar Disclaimer requirement for further | ||
| * binary redistribution. | ||
| * 3. Neither the names of the above-listed copyright holders nor the names | ||
| * of any contributors may be used to endorse or promote products derived | ||
| * from this software without specific prior written permission. | ||
| * | ||
| * Alternatively, this software may be distributed under the terms of the | ||
| * GNU General Public License ("GPL") version 2 as published by the Free | ||
| * Software Foundation. | ||
| * | ||
| * NO WARRANTY | ||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
| * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| * POSSIBILITY OF SUCH DAMAGES. | ||
| */ | ||
|
|
||
| #include "acpi.h" | ||
| #include "accommon.h" | ||
| #include "acevents.h" | ||
| #include "acinterp.h" | ||
|
|
||
| #define _COMPONENT ACPI_EVENTS | ||
| ACPI_MODULE_NAME("evglock") | ||
|
|
||
| #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ | ||
|
|
||
| /* Local prototypes */ | ||
|
|
||
| static UINT32 AcpiEvGlobalLockHandler(void *Context); | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiEvInitGlobalLockHandler | ||
| * | ||
| * PARAMETERS: None | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Install a handler for the global lock release event | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiEvInitGlobalLockHandler(void) | ||
| { | ||
| ACPI_STATUS Status; | ||
|
|
||
| ACPI_FUNCTION_TRACE(EvInitGlobalLockHandler); | ||
|
|
||
| /* If Hardware Reduced flag is set, there is no global lock */ | ||
|
|
||
| if (AcpiGbl_ReducedHardware) { | ||
| return_ACPI_STATUS(AE_OK); | ||
| } | ||
|
|
||
| /* Attempt installation of the global lock handler */ | ||
|
|
||
| Status = AcpiInstallFixedEventHandler(ACPI_EVENT_GLOBAL, AcpiEvGlobalLockHandler, | ||
| NULL); | ||
|
|
||
| /* | ||
| * If the global lock does not exist on this platform, the attempt to | ||
| * enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick). | ||
| * Map to AE_OK, but mark global lock as not present. Any attempt to | ||
| * actually use the global lock will be flagged with an error. | ||
| */ | ||
| AcpiGbl_GlobalLockPresent = FALSE; | ||
| if (Status == AE_NO_HARDWARE_RESPONSE) { | ||
| ACPI_ERROR((AE_INFO, "No response from Global Lock hardware, disabling lock")); | ||
|
|
||
| return_ACPI_STATUS(AE_OK); | ||
| } | ||
|
|
||
| Status = AcpiOsCreateLock(&AcpiGbl_GlobalLockPendingLock); | ||
| if (ACPI_FAILURE(Status)) { | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| AcpiGbl_GlobalLockPending = FALSE; | ||
| AcpiGbl_GlobalLockPresent = TRUE; | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiEvRemoveGlobalLockHandler | ||
| * | ||
| * PARAMETERS: None | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Remove the handler for the Global Lock | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiEvRemoveGlobalLockHandler(void) | ||
| { | ||
| ACPI_STATUS Status; | ||
|
|
||
| ACPI_FUNCTION_TRACE(EvRemoveGlobalLockHandler); | ||
|
|
||
| AcpiGbl_GlobalLockPresent = FALSE; | ||
| Status = AcpiRemoveFixedEventHandler(ACPI_EVENT_GLOBAL, AcpiEvGlobalLockHandler); | ||
|
|
||
| AcpiOsDeleteLock(AcpiGbl_GlobalLockPendingLock); | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiEvGlobalLockHandler | ||
| * | ||
| * PARAMETERS: Context - From thread interface, not used | ||
| * | ||
| * RETURN: ACPI_INTERRUPT_HANDLED | ||
| * | ||
| * DESCRIPTION: Invoked directly from the SCI handler when a global lock | ||
| * release interrupt occurs. If there is actually a pending | ||
| * request for the lock, signal the waiting thread. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| static UINT32 AcpiEvGlobalLockHandler(void *Context) | ||
| { | ||
| ACPI_STATUS Status; | ||
| ACPI_CPU_FLAGS Flags; | ||
|
|
||
| Flags = AcpiOsAcquireLock(AcpiGbl_GlobalLockPendingLock); | ||
|
|
||
| /* | ||
| * If a request for the global lock is not actually pending, | ||
| * we are done. This handles "spurious" global lock interrupts | ||
| * which are possible (and have been seen) with bad BIOSs. | ||
| */ | ||
| if (!AcpiGbl_GlobalLockPending) { | ||
| goto CleanupAndExit; | ||
| } | ||
|
|
||
| /* | ||
| * Send a unit to the global lock semaphore. The actual acquisition | ||
| * of the global lock will be performed by the waiting thread. | ||
| */ | ||
| Status = AcpiOsSignalSemaphore(AcpiGbl_GlobalLockSemaphore, 1); | ||
| if (ACPI_FAILURE(Status)) { | ||
| ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore")); | ||
| } | ||
|
|
||
| AcpiGbl_GlobalLockPending = FALSE; | ||
|
|
||
| CleanupAndExit: | ||
|
|
||
| AcpiOsReleaseLock(AcpiGbl_GlobalLockPendingLock, Flags); | ||
| return (ACPI_INTERRUPT_HANDLED); | ||
| } | ||
|
|
||
| /****************************************************************************** | ||
| * | ||
| * FUNCTION: AcpiEvAcquireGlobalLock | ||
| * | ||
| * PARAMETERS: Timeout - Max time to wait for the lock, in millisec. | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Attempt to gain ownership of the Global Lock. | ||
| * | ||
| * MUTEX: Interpreter must be locked | ||
| * | ||
| * Note: The original implementation allowed multiple threads to "acquire" the | ||
| * Global Lock, and the OS would hold the lock until the last thread had | ||
| * released it. However, this could potentially starve the BIOS out of the | ||
| * lock, especially in the case where there is a tight handshake between the | ||
| * Embedded Controller driver and the BIOS. Therefore, this implementation | ||
| * allows only one thread to acquire the HW Global Lock at a time, and makes | ||
| * the global lock appear as a standard mutex on the OS side. | ||
| * | ||
| *****************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiEvAcquireGlobalLock(UINT16 Timeout) | ||
| { | ||
| ACPI_CPU_FLAGS Flags; | ||
| ACPI_STATUS Status; | ||
| BOOLEAN Acquired = FALSE; | ||
|
|
||
| ACPI_FUNCTION_TRACE(EvAcquireGlobalLock); | ||
|
|
||
| /* | ||
| * Only one thread can acquire the GL at a time, the GlobalLockMutex | ||
| * enforces this. This interface releases the interpreter if we must wait. | ||
| */ | ||
| Status = AcpiExSystemWaitMutex(AcpiGbl_GlobalLockMutex->Mutex.OsMutex, Timeout); | ||
| if (ACPI_FAILURE(Status)) { | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| /* | ||
| * Update the global lock handle and check for wraparound. The handle is | ||
| * only used for the external global lock interfaces, but it is updated | ||
| * here to properly handle the case where a single thread may acquire the | ||
| * lock via both the AML and the AcpiAcquireGlobalLock interfaces. The | ||
| * handle is therefore updated on the first acquire from a given thread | ||
| * regardless of where the acquisition request originated. | ||
| */ | ||
| AcpiGbl_GlobalLockHandle++; | ||
| if (AcpiGbl_GlobalLockHandle == 0) { | ||
| AcpiGbl_GlobalLockHandle = 1; | ||
| } | ||
|
|
||
| /* | ||
| * Make sure that a global lock actually exists. If not, just | ||
| * treat the lock as a standard mutex. | ||
| */ | ||
| if (!AcpiGbl_GlobalLockPresent) { | ||
| AcpiGbl_GlobalLockAcquired = TRUE; | ||
| return_ACPI_STATUS(AE_OK); | ||
| } | ||
|
|
||
| Flags = AcpiOsAcquireLock(AcpiGbl_GlobalLockPendingLock); | ||
|
|
||
| do { | ||
| /* Attempt to acquire the actual hardware lock */ | ||
|
|
||
| ACPI_ACQUIRE_GLOBAL_LOCK(AcpiGbl_FACS, Acquired); | ||
| if (Acquired) { | ||
| AcpiGbl_GlobalLockAcquired = TRUE; | ||
| ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Acquired hardware Global Lock\n")); | ||
| break; | ||
| } | ||
|
|
||
| /* | ||
| * Did not get the lock. The pending bit was set above, and | ||
| * we must now wait until we receive the global lock | ||
| * released interrupt. | ||
| */ | ||
| AcpiGbl_GlobalLockPending = TRUE; | ||
| AcpiOsReleaseLock(AcpiGbl_GlobalLockPendingLock, Flags); | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n")); | ||
|
|
||
| /* | ||
| * Wait for handshake with the global lock interrupt handler. | ||
| * This interface releases the interpreter if we must wait. | ||
| */ | ||
| Status = AcpiExSystemWaitSemaphore(AcpiGbl_GlobalLockSemaphore, | ||
| ACPI_WAIT_FOREVER); | ||
|
|
||
| Flags = AcpiOsAcquireLock(AcpiGbl_GlobalLockPendingLock); | ||
|
|
||
| } while (ACPI_SUCCESS(Status)); | ||
|
|
||
| AcpiGbl_GlobalLockPending = FALSE; | ||
| AcpiOsReleaseLock(AcpiGbl_GlobalLockPendingLock, Flags); | ||
|
|
||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiEvReleaseGlobalLock | ||
| * | ||
| * PARAMETERS: None | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Releases ownership of the Global Lock. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiEvReleaseGlobalLock(void) | ||
| { | ||
| BOOLEAN Pending = FALSE; | ||
| ACPI_STATUS Status = AE_OK; | ||
|
|
||
| ACPI_FUNCTION_TRACE(EvReleaseGlobalLock); | ||
|
|
||
| /* Lock must be already acquired */ | ||
|
|
||
| if (!AcpiGbl_GlobalLockAcquired) { | ||
| ACPI_WARNING((AE_INFO, "Cannot release the ACPI Global Lock, it has not been " | ||
| "acquired")); | ||
| return_ACPI_STATUS(AE_NOT_ACQUIRED); | ||
| } | ||
|
|
||
| if (AcpiGbl_GlobalLockPresent) { | ||
| /* Allow any thread to release the lock */ | ||
|
|
||
| ACPI_RELEASE_GLOBAL_LOCK(AcpiGbl_FACS, Pending); | ||
|
|
||
| /* | ||
| * If the pending bit was set, we must write GBL_RLS to the control | ||
| * register | ||
| */ | ||
| if (Pending) { | ||
| Status = AcpiWriteBitRegister(ACPI_BITREG_GLOBAL_LOCK_RELEASE, | ||
| ACPI_ENABLE_EVENT); | ||
| } | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Released hardware Global Lock\n")); | ||
| } | ||
|
|
||
| AcpiGbl_GlobalLockAcquired = FALSE; | ||
|
|
||
| /* Release the local GL mutex */ | ||
|
|
||
| AcpiOsReleaseMutex(AcpiGbl_GlobalLockMutex->Mutex.OsMutex); | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| #endif /* !ACPI_REDUCED_HARDWARE */ |
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,349 @@ | ||
| /****************************************************************************** | ||
| * | ||
| * Module Name: evgpeutil - GPE utilities | ||
| * | ||
| *****************************************************************************/ | ||
|
|
||
| /* | ||
| * Copyright (C) 2000 - 2022, Intel Corp. | ||
| * All rights reserved. | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions, and the following disclaimer, | ||
| * without modification. | ||
| * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
| * substantially similar to the "NO WARRANTY" disclaimer below | ||
| * ("Disclaimer") and any redistribution must be conditioned upon | ||
| * including a substantially similar Disclaimer requirement for further | ||
| * binary redistribution. | ||
| * 3. Neither the names of the above-listed copyright holders nor the names | ||
| * of any contributors may be used to endorse or promote products derived | ||
| * from this software without specific prior written permission. | ||
| * | ||
| * Alternatively, this software may be distributed under the terms of the | ||
| * GNU General Public License ("GPL") version 2 as published by the Free | ||
| * Software Foundation. | ||
| * | ||
| * NO WARRANTY | ||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
| * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| * POSSIBILITY OF SUCH DAMAGES. | ||
| */ | ||
|
|
||
| #include "acpi.h" | ||
| #include "accommon.h" | ||
| #include "acevents.h" | ||
|
|
||
| #define _COMPONENT ACPI_EVENTS | ||
| ACPI_MODULE_NAME("evgpeutil") | ||
|
|
||
| #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ | ||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiEvWalkGpeList | ||
| * | ||
| * PARAMETERS: GpeWalkCallback - Routine called for each GPE block | ||
| * Context - Value passed to callback | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Walk the GPE lists. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiEvWalkGpeList(ACPI_GPE_CALLBACK GpeWalkCallback, void *Context) | ||
| { | ||
| ACPI_GPE_BLOCK_INFO *GpeBlock; | ||
| ACPI_GPE_XRUPT_INFO *GpeXruptInfo; | ||
| ACPI_STATUS Status = AE_OK; | ||
| ACPI_CPU_FLAGS Flags; | ||
|
|
||
| ACPI_FUNCTION_TRACE(EvWalkGpeList); | ||
|
|
||
| Flags = AcpiOsAcquireLock(AcpiGbl_GpeLock); | ||
|
|
||
| /* Walk the interrupt level descriptor list */ | ||
|
|
||
| GpeXruptInfo = AcpiGbl_GpeXruptListHead; | ||
| while (GpeXruptInfo) { | ||
| /* Walk all Gpe Blocks attached to this interrupt level */ | ||
|
|
||
| GpeBlock = GpeXruptInfo->GpeBlockListHead; | ||
| while (GpeBlock) { | ||
| /* One callback per GPE block */ | ||
|
|
||
| Status = GpeWalkCallback(GpeXruptInfo, GpeBlock, Context); | ||
| if (ACPI_FAILURE(Status)) { | ||
| if (Status == AE_CTRL_END) /* Callback abort */ | ||
| { | ||
| Status = AE_OK; | ||
| } | ||
| goto UnlockAndExit; | ||
| } | ||
|
|
||
| GpeBlock = GpeBlock->Next; | ||
| } | ||
|
|
||
| GpeXruptInfo = GpeXruptInfo->Next; | ||
| } | ||
|
|
||
| UnlockAndExit: | ||
| AcpiOsReleaseLock(AcpiGbl_GpeLock, Flags); | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * 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 | ||
| * GpeXruptBlock - Where the block is returned | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Get or Create a GPE interrupt block. There is one interrupt | ||
| * block per unique interrupt level used for GPEs. Should be | ||
| * called only when the GPE lists are semaphore locked and not | ||
| * subject to change. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiEvGetGpeXruptBlock(UINT32 InterruptNumber, ACPI_GPE_XRUPT_INFO **GpeXruptBlock) | ||
| { | ||
| ACPI_GPE_XRUPT_INFO *NextGpeXrupt; | ||
| ACPI_GPE_XRUPT_INFO *GpeXrupt; | ||
| ACPI_STATUS Status; | ||
| ACPI_CPU_FLAGS Flags; | ||
|
|
||
| ACPI_FUNCTION_TRACE(EvGetGpeXruptBlock); | ||
|
|
||
| /* No need for lock since we are not changing any list elements here */ | ||
|
|
||
| NextGpeXrupt = AcpiGbl_GpeXruptListHead; | ||
| while (NextGpeXrupt) { | ||
| if (NextGpeXrupt->InterruptNumber == InterruptNumber) { | ||
| *GpeXruptBlock = NextGpeXrupt; | ||
| return_ACPI_STATUS(AE_OK); | ||
| } | ||
|
|
||
| NextGpeXrupt = NextGpeXrupt->Next; | ||
| } | ||
|
|
||
| /* Not found, must allocate a new xrupt descriptor */ | ||
|
|
||
| GpeXrupt = ACPI_ALLOCATE_ZEROED(sizeof(ACPI_GPE_XRUPT_INFO)); | ||
| if (!GpeXrupt) { | ||
| return_ACPI_STATUS(AE_NO_MEMORY); | ||
| } | ||
|
|
||
| GpeXrupt->InterruptNumber = InterruptNumber; | ||
|
|
||
| /* Install new interrupt descriptor with spin lock */ | ||
|
|
||
| Flags = AcpiOsAcquireLock(AcpiGbl_GpeLock); | ||
| if (AcpiGbl_GpeXruptListHead) { | ||
| NextGpeXrupt = AcpiGbl_GpeXruptListHead; | ||
| while (NextGpeXrupt->Next) { | ||
| NextGpeXrupt = NextGpeXrupt->Next; | ||
| } | ||
|
|
||
| NextGpeXrupt->Next = GpeXrupt; | ||
| GpeXrupt->Previous = NextGpeXrupt; | ||
| } else { | ||
| AcpiGbl_GpeXruptListHead = GpeXrupt; | ||
| } | ||
|
|
||
| AcpiOsReleaseLock(AcpiGbl_GpeLock, Flags); | ||
|
|
||
| /* Install new interrupt handler if not SCI_INT */ | ||
|
|
||
| if (InterruptNumber != AcpiGbl_FADT.SciInterrupt) { | ||
| Status = AcpiOsInstallInterruptHandler(InterruptNumber, AcpiEvGpeXruptHandler, | ||
| GpeXrupt); | ||
| if (ACPI_FAILURE(Status)) { | ||
| ACPI_EXCEPTION((AE_INFO, Status, | ||
| "Could not install GPE interrupt handler at level 0x%X", | ||
| InterruptNumber)); | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
| } | ||
|
|
||
| *GpeXruptBlock = GpeXrupt; | ||
| return_ACPI_STATUS(AE_OK); | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiEvDeleteGpeXrupt | ||
| * | ||
| * PARAMETERS: GpeXrupt - A GPE interrupt info block | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Remove and free a GpeXrupt block. Remove an associated | ||
| * interrupt handler if not the SCI interrupt. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiEvDeleteGpeXrupt(ACPI_GPE_XRUPT_INFO *GpeXrupt) | ||
| { | ||
| ACPI_STATUS Status; | ||
| ACPI_CPU_FLAGS Flags; | ||
|
|
||
| ACPI_FUNCTION_TRACE(EvDeleteGpeXrupt); | ||
|
|
||
| /* We never want to remove the SCI interrupt handler */ | ||
|
|
||
| if (GpeXrupt->InterruptNumber == AcpiGbl_FADT.SciInterrupt) { | ||
| GpeXrupt->GpeBlockListHead = NULL; | ||
| return_ACPI_STATUS(AE_OK); | ||
| } | ||
|
|
||
| /* Disable this interrupt */ | ||
|
|
||
| Status = AcpiOsRemoveInterruptHandler(GpeXrupt->InterruptNumber, | ||
| AcpiEvGpeXruptHandler); | ||
| if (ACPI_FAILURE(Status)) { | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| /* Unlink the interrupt block with lock */ | ||
|
|
||
| Flags = AcpiOsAcquireLock(AcpiGbl_GpeLock); | ||
| if (GpeXrupt->Previous) { | ||
| GpeXrupt->Previous->Next = GpeXrupt->Next; | ||
| } else { | ||
| /* No previous, update list head */ | ||
|
|
||
| AcpiGbl_GpeXruptListHead = GpeXrupt->Next; | ||
| } | ||
|
|
||
| if (GpeXrupt->Next) { | ||
| GpeXrupt->Next->Previous = GpeXrupt->Previous; | ||
| } | ||
| AcpiOsReleaseLock(AcpiGbl_GpeLock, Flags); | ||
|
|
||
| /* Free the block */ | ||
|
|
||
| ACPI_FREE(GpeXrupt); | ||
| return_ACPI_STATUS(AE_OK); | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiEvDeleteGpeHandlers | ||
| * | ||
| * PARAMETERS: GpeXruptInfo - GPE Interrupt info | ||
| * GpeBlock - Gpe Block info | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Delete all Handler objects found in the GPE data structs. | ||
| * Used only prior to termination. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiEvDeleteGpeHandlers(ACPI_GPE_XRUPT_INFO *GpeXruptInfo, ACPI_GPE_BLOCK_INFO *GpeBlock, | ||
| void *Context) | ||
| { | ||
| ACPI_GPE_EVENT_INFO *GpeEventInfo; | ||
| ACPI_GPE_NOTIFY_INFO *Notify; | ||
| ACPI_GPE_NOTIFY_INFO *Next; | ||
| UINT32 i; | ||
| UINT32 j; | ||
|
|
||
| ACPI_FUNCTION_TRACE(EvDeleteGpeHandlers); | ||
|
|
||
| /* Examine each GPE Register within the block */ | ||
|
|
||
| for (i = 0; i < GpeBlock->RegisterCount; i++) { | ||
| /* Now look at the individual GPEs in this byte register */ | ||
|
|
||
| for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { | ||
| GpeEventInfo = | ||
| &GpeBlock->EventInfo[((ACPI_SIZE)i * ACPI_GPE_REGISTER_WIDTH) + j]; | ||
|
|
||
| if ((ACPI_GPE_DISPATCH_TYPE(GpeEventInfo->Flags) == | ||
| ACPI_GPE_DISPATCH_HANDLER) || | ||
| (ACPI_GPE_DISPATCH_TYPE(GpeEventInfo->Flags) == | ||
| ACPI_GPE_DISPATCH_RAW_HANDLER)) { | ||
| /* Delete an installed handler block */ | ||
|
|
||
| ACPI_FREE(GpeEventInfo->Dispatch.Handler); | ||
| GpeEventInfo->Dispatch.Handler = NULL; | ||
| GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK; | ||
| } else if (ACPI_GPE_DISPATCH_TYPE(GpeEventInfo->Flags) == | ||
| ACPI_GPE_DISPATCH_NOTIFY) { | ||
| /* Delete the implicit notification device list */ | ||
|
|
||
| Notify = GpeEventInfo->Dispatch.NotifyList; | ||
| while (Notify) { | ||
| Next = Notify->Next; | ||
| ACPI_FREE(Notify); | ||
| Notify = Next; | ||
| } | ||
|
|
||
| GpeEventInfo->Dispatch.NotifyList = NULL; | ||
| GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return_ACPI_STATUS(AE_OK); | ||
| } | ||
|
|
||
| #endif /* !ACPI_REDUCED_HARDWARE */ |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,293 @@ | ||
| /****************************************************************************** | ||
| * | ||
| * Module Name: evmisc - Miscellaneous event manager support functions | ||
| * | ||
| *****************************************************************************/ | ||
|
|
||
| /* | ||
| * Copyright (C) 2000 - 2022, Intel Corp. | ||
| * All rights reserved. | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions, and the following disclaimer, | ||
| * without modification. | ||
| * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
| * substantially similar to the "NO WARRANTY" disclaimer below | ||
| * ("Disclaimer") and any redistribution must be conditioned upon | ||
| * including a substantially similar Disclaimer requirement for further | ||
| * binary redistribution. | ||
| * 3. Neither the names of the above-listed copyright holders nor the names | ||
| * of any contributors may be used to endorse or promote products derived | ||
| * from this software without specific prior written permission. | ||
| * | ||
| * Alternatively, this software may be distributed under the terms of the | ||
| * GNU General Public License ("GPL") version 2 as published by the Free | ||
| * Software Foundation. | ||
| * | ||
| * NO WARRANTY | ||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
| * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| * POSSIBILITY OF SUCH DAMAGES. | ||
| */ | ||
|
|
||
| #include "acpi.h" | ||
| #include "accommon.h" | ||
| #include "acevents.h" | ||
| #include "acnamesp.h" | ||
|
|
||
| #define _COMPONENT ACPI_EVENTS | ||
| ACPI_MODULE_NAME("evmisc") | ||
|
|
||
| /* Local prototypes */ | ||
|
|
||
| static void ACPI_SYSTEM_XFACE AcpiEvNotifyDispatch(void *Context); | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiEvIsNotifyObject | ||
| * | ||
| * PARAMETERS: Node - Node to check | ||
| * | ||
| * RETURN: TRUE if notifies allowed on this object | ||
| * | ||
| * DESCRIPTION: Check type of node for a object that supports notifies. | ||
| * | ||
| * TBD: This could be replaced by a flag bit in the node. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| BOOLEAN | ||
| AcpiEvIsNotifyObject(ACPI_NAMESPACE_NODE *Node) | ||
| { | ||
| switch (Node->Type) { | ||
| case ACPI_TYPE_DEVICE: | ||
| case ACPI_TYPE_PROCESSOR: | ||
| case ACPI_TYPE_THERMAL: | ||
| /* | ||
| * These are the ONLY objects that can receive ACPI notifications | ||
| */ | ||
| return (TRUE); | ||
|
|
||
| default: | ||
|
|
||
| return (FALSE); | ||
| } | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiEvQueueNotifyRequest | ||
| * | ||
| * PARAMETERS: Node - NS node for the notified object | ||
| * NotifyValue - Value from the Notify() request | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Dispatch a device notification event to a previously | ||
| * installed handler. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiEvQueueNotifyRequest(ACPI_NAMESPACE_NODE *Node, UINT32 NotifyValue) | ||
| { | ||
| ACPI_OPERAND_OBJECT *ObjDesc; | ||
| ACPI_OPERAND_OBJECT *HandlerListHead = NULL; | ||
| ACPI_GENERIC_STATE *Info; | ||
| UINT8 HandlerListId = 0; | ||
| ACPI_STATUS Status = AE_OK; | ||
|
|
||
| ACPI_FUNCTION_NAME(EvQueueNotifyRequest); | ||
|
|
||
| /* Are Notifies allowed on this object? */ | ||
|
|
||
| if (!AcpiEvIsNotifyObject(Node)) { | ||
| return (AE_TYPE); | ||
| } | ||
|
|
||
| /* Get the correct notify list type (System or Device) */ | ||
|
|
||
| if (NotifyValue <= ACPI_MAX_SYS_NOTIFY) { | ||
| HandlerListId = ACPI_SYSTEM_HANDLER_LIST; | ||
| } else { | ||
| HandlerListId = ACPI_DEVICE_HANDLER_LIST; | ||
| } | ||
|
|
||
| /* Get the notify object attached to the namespace Node */ | ||
|
|
||
| ObjDesc = AcpiNsGetAttachedObject(Node); | ||
| if (ObjDesc) { | ||
| /* We have an attached object, Get the correct handler list */ | ||
|
|
||
| HandlerListHead = ObjDesc->CommonNotify.NotifyList[HandlerListId]; | ||
| } | ||
|
|
||
| /* | ||
| * If there is no notify handler (Global or Local) | ||
| * for this object, just ignore the notify | ||
| */ | ||
| if (!AcpiGbl_GlobalNotify[HandlerListId].Handler && !HandlerListHead) { | ||
| ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
| "No notify handler for Notify, ignoring (%4.4s, %X) node %p\n", | ||
| AcpiUtGetNodeName(Node), NotifyValue, Node)); | ||
|
|
||
| return (AE_OK); | ||
| } | ||
|
|
||
| /* Setup notify info and schedule the notify dispatcher */ | ||
|
|
||
| Info = AcpiUtCreateGenericState(); | ||
| if (!Info) { | ||
| return (AE_NO_MEMORY); | ||
| } | ||
|
|
||
| Info->Common.DescriptorType = ACPI_DESC_TYPE_STATE_NOTIFY; | ||
|
|
||
| Info->Notify.Node = Node; | ||
| Info->Notify.Value = (UINT16)NotifyValue; | ||
| Info->Notify.HandlerListId = HandlerListId; | ||
| Info->Notify.HandlerListHead = HandlerListHead; | ||
| Info->Notify.Global = &AcpiGbl_GlobalNotify[HandlerListId]; | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
| "Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n", | ||
| AcpiUtGetNodeName(Node), AcpiUtGetTypeName(Node->Type), NotifyValue, | ||
| AcpiUtGetNotifyName(NotifyValue, ACPI_TYPE_ANY), Node)); | ||
|
|
||
| Status = AcpiOsExecute(OSL_NOTIFY_HANDLER, AcpiEvNotifyDispatch, Info); | ||
| if (ACPI_FAILURE(Status)) { | ||
| AcpiUtDeleteGenericState(Info); | ||
| } | ||
|
|
||
| return (Status); | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiEvNotifyDispatch | ||
| * | ||
| * PARAMETERS: Context - To be passed to the notify handler | ||
| * | ||
| * RETURN: None. | ||
| * | ||
| * DESCRIPTION: Dispatch a device notification event to a previously | ||
| * installed handler. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| static void ACPI_SYSTEM_XFACE AcpiEvNotifyDispatch(void *Context) | ||
| { | ||
| ACPI_GENERIC_STATE *Info = (ACPI_GENERIC_STATE *)Context; | ||
| ACPI_OPERAND_OBJECT *HandlerObj; | ||
|
|
||
| ACPI_FUNCTION_ENTRY(); | ||
|
|
||
| /* Invoke a global notify handler if installed */ | ||
|
|
||
| if (Info->Notify.Global->Handler) { | ||
| Info->Notify.Global->Handler(Info->Notify.Node, Info->Notify.Value, | ||
| Info->Notify.Global->Context); | ||
| } | ||
|
|
||
| /* Now invoke the local notify handler(s) if any are installed */ | ||
|
|
||
| HandlerObj = Info->Notify.HandlerListHead; | ||
| while (HandlerObj) { | ||
| HandlerObj->Notify.Handler(Info->Notify.Node, Info->Notify.Value, | ||
| HandlerObj->Notify.Context); | ||
|
|
||
| HandlerObj = HandlerObj->Notify.Next[Info->Notify.HandlerListId]; | ||
| } | ||
|
|
||
| /* All done with the info object */ | ||
|
|
||
| AcpiUtDeleteGenericState(Info); | ||
| } | ||
|
|
||
| #if (!ACPI_REDUCED_HARDWARE) | ||
| /****************************************************************************** | ||
| * | ||
| * FUNCTION: AcpiEvTerminate | ||
| * | ||
| * PARAMETERS: none | ||
| * | ||
| * RETURN: none | ||
| * | ||
| * DESCRIPTION: Disable events and free memory allocated for table storage. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| void AcpiEvTerminate(void) | ||
| { | ||
| UINT32 i; | ||
| ACPI_STATUS Status; | ||
|
|
||
| ACPI_FUNCTION_TRACE(EvTerminate); | ||
|
|
||
| if (AcpiGbl_EventsInitialized) { | ||
| /* | ||
| * Disable all event-related functionality. In all cases, on error, | ||
| * print a message but obviously we don't abort. | ||
| */ | ||
|
|
||
| /* Disable all fixed events */ | ||
|
|
||
| for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { | ||
| Status = AcpiDisableEvent(i, 0); | ||
| if (ACPI_FAILURE(Status)) { | ||
| ACPI_ERROR((AE_INFO, "Could not disable fixed event %u", (UINT32)i)); | ||
| } | ||
| } | ||
|
|
||
| /* Disable all GPEs in all GPE blocks */ | ||
|
|
||
| Status = AcpiEvWalkGpeList(AcpiHwDisableGpeBlock, NULL); | ||
| if (ACPI_FAILURE(Status)) { | ||
| ACPI_EXCEPTION((AE_INFO, Status, "Could not disable GPEs in GPE block")); | ||
| } | ||
|
|
||
| Status = AcpiEvRemoveGlobalLockHandler(); | ||
| if (ACPI_FAILURE(Status)) { | ||
| ACPI_EXCEPTION((AE_INFO, Status, "Could not remove Global Lock handler")); | ||
| } | ||
|
|
||
| AcpiGbl_EventsInitialized = FALSE; | ||
| } | ||
|
|
||
| /* Remove SCI handlers */ | ||
|
|
||
| Status = AcpiEvRemoveAllSciHandlers(); | ||
| if (ACPI_FAILURE(Status)) { | ||
| ACPI_ERROR((AE_INFO, "Could not remove SCI handler")); | ||
| } | ||
|
|
||
| /* Deallocate all handler objects installed within GPE info structs */ | ||
|
|
||
| Status = AcpiEvWalkGpeList(AcpiEvDeleteGpeHandlers, NULL); | ||
| if (ACPI_FAILURE(Status)) { | ||
| ACPI_EXCEPTION((AE_INFO, Status, "Could not delete GPE handlers")); | ||
| } | ||
|
|
||
| /* Return to original mode if necessary */ | ||
|
|
||
| if (AcpiGbl_OriginalMode == ACPI_SYS_MODE_LEGACY) { | ||
| Status = AcpiDisable(); | ||
| if (ACPI_FAILURE(Status)) { | ||
| ACPI_WARNING((AE_INFO, "AcpiDisable failed")); | ||
| } | ||
| } | ||
| return_VOID; | ||
| } | ||
|
|
||
| #endif /* !ACPI_REDUCED_HARDWARE */ |
Large diffs are not rendered by default.
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,253 @@ | ||
| /******************************************************************************* | ||
| * | ||
| * Module Name: evsci - System Control Interrupt configuration and | ||
| * legacy to ACPI mode state transition functions | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| /* | ||
| * Copyright (C) 2000 - 2022, Intel Corp. | ||
| * All rights reserved. | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions, and the following disclaimer, | ||
| * without modification. | ||
| * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
| * substantially similar to the "NO WARRANTY" disclaimer below | ||
| * ("Disclaimer") and any redistribution must be conditioned upon | ||
| * including a substantially similar Disclaimer requirement for further | ||
| * binary redistribution. | ||
| * 3. Neither the names of the above-listed copyright holders nor the names | ||
| * of any contributors may be used to endorse or promote products derived | ||
| * from this software without specific prior written permission. | ||
| * | ||
| * Alternatively, this software may be distributed under the terms of the | ||
| * GNU General Public License ("GPL") version 2 as published by the Free | ||
| * Software Foundation. | ||
| * | ||
| * NO WARRANTY | ||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
| * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| * POSSIBILITY OF SUCH DAMAGES. | ||
| */ | ||
|
|
||
| #include "acpi.h" | ||
| #include "accommon.h" | ||
| #include "acevents.h" | ||
|
|
||
| #define _COMPONENT ACPI_EVENTS | ||
| ACPI_MODULE_NAME("evsci") | ||
|
|
||
| #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ | ||
|
|
||
| /* Local prototypes */ | ||
|
|
||
| static UINT32 ACPI_SYSTEM_XFACE AcpiEvSciXruptHandler(void *Context); | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiEvSciDispatch | ||
| * | ||
| * PARAMETERS: None | ||
| * | ||
| * RETURN: Status code indicates whether interrupt was handled. | ||
| * | ||
| * DESCRIPTION: Dispatch the SCI to all host-installed SCI handlers. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| UINT32 | ||
| AcpiEvSciDispatch(void) | ||
| { | ||
| ACPI_SCI_HANDLER_INFO *SciHandler; | ||
| ACPI_CPU_FLAGS Flags; | ||
| UINT32 IntStatus = ACPI_INTERRUPT_NOT_HANDLED; | ||
|
|
||
| ACPI_FUNCTION_NAME(EvSciDispatch); | ||
|
|
||
| /* Are there any host-installed SCI handlers? */ | ||
|
|
||
| if (!AcpiGbl_SciHandlerList) { | ||
| return (IntStatus); | ||
| } | ||
|
|
||
| Flags = AcpiOsAcquireLock(AcpiGbl_GpeLock); | ||
|
|
||
| /* Invoke all host-installed SCI handlers */ | ||
|
|
||
| SciHandler = AcpiGbl_SciHandlerList; | ||
| while (SciHandler) { | ||
| /* Invoke the installed handler (at interrupt level) */ | ||
|
|
||
| IntStatus |= SciHandler->Address(SciHandler->Context); | ||
|
|
||
| SciHandler = SciHandler->Next; | ||
| } | ||
|
|
||
| AcpiOsReleaseLock(AcpiGbl_GpeLock, Flags); | ||
| return (IntStatus); | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiEvSciXruptHandler | ||
| * | ||
| * PARAMETERS: Context - Calling Context | ||
| * | ||
| * RETURN: Status code indicates whether interrupt was handled. | ||
| * | ||
| * DESCRIPTION: Interrupt handler that will figure out what function or | ||
| * control method to call to deal with a SCI. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| static UINT32 ACPI_SYSTEM_XFACE AcpiEvSciXruptHandler(void *Context) | ||
| { | ||
| ACPI_GPE_XRUPT_INFO *GpeXruptList = Context; | ||
| UINT32 InterruptHandled = ACPI_INTERRUPT_NOT_HANDLED; | ||
|
|
||
| ACPI_FUNCTION_TRACE(EvSciXruptHandler); | ||
|
|
||
| /* | ||
| * We are guaranteed by the ACPICA initialization/shutdown code that | ||
| * if this interrupt handler is installed, ACPI is enabled. | ||
| */ | ||
|
|
||
| /* | ||
| * Fixed Events: | ||
| * Check for and dispatch any Fixed Events that have occurred | ||
| */ | ||
| InterruptHandled |= AcpiEvFixedEventDetect(); | ||
|
|
||
| /* | ||
| * General Purpose Events: | ||
| * Check for and dispatch any GPEs that have occurred | ||
| */ | ||
| InterruptHandled |= AcpiEvGpeDetect(GpeXruptList); | ||
|
|
||
| /* Invoke all host-installed SCI handlers */ | ||
|
|
||
| InterruptHandled |= AcpiEvSciDispatch(); | ||
|
|
||
| AcpiSciCount++; | ||
| return_UINT32(InterruptHandled); | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiEvGpeXruptHandler | ||
| * | ||
| * PARAMETERS: Context - Calling Context | ||
| * | ||
| * RETURN: Status code indicates whether interrupt was handled. | ||
| * | ||
| * DESCRIPTION: Handler for GPE Block Device interrupts | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| UINT32 ACPI_SYSTEM_XFACE AcpiEvGpeXruptHandler(void *Context) | ||
| { | ||
| ACPI_GPE_XRUPT_INFO *GpeXruptList = Context; | ||
| UINT32 InterruptHandled = ACPI_INTERRUPT_NOT_HANDLED; | ||
|
|
||
| ACPI_FUNCTION_TRACE(EvGpeXruptHandler); | ||
|
|
||
| /* | ||
| * We are guaranteed by the ACPICA initialization/shutdown code that | ||
| * if this interrupt handler is installed, ACPI is enabled. | ||
| */ | ||
|
|
||
| /* GPEs: Check for and dispatch any GPEs that have occurred */ | ||
|
|
||
| InterruptHandled |= AcpiEvGpeDetect(GpeXruptList); | ||
| return_UINT32(InterruptHandled); | ||
| } | ||
|
|
||
| /****************************************************************************** | ||
| * | ||
| * FUNCTION: AcpiEvInstallSciHandler | ||
| * | ||
| * PARAMETERS: none | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Installs SCI handler. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| UINT32 | ||
| AcpiEvInstallSciHandler(void) | ||
| { | ||
| UINT32 Status = AE_OK; | ||
|
|
||
| ACPI_FUNCTION_TRACE(EvInstallSciHandler); | ||
|
|
||
| Status = AcpiOsInstallInterruptHandler((UINT32)AcpiGbl_FADT.SciInterrupt, | ||
| AcpiEvSciXruptHandler, | ||
| AcpiGbl_GpeXruptListHead); | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| /****************************************************************************** | ||
| * | ||
| * FUNCTION: AcpiEvRemoveAllSciHandlers | ||
| * | ||
| * PARAMETERS: none | ||
| * | ||
| * RETURN: AE_OK if handler uninstalled, AE_ERROR if handler was not | ||
| * installed to begin with | ||
| * | ||
| * DESCRIPTION: Remove the SCI interrupt handler. No further SCIs will be | ||
| * taken. Remove all host-installed SCI handlers. | ||
| * | ||
| * Note: It doesn't seem important to disable all events or set the event | ||
| * enable registers to their original values. The OS should disable | ||
| * the SCI interrupt level when the handler is removed, so no more | ||
| * events will come in. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiEvRemoveAllSciHandlers(void) | ||
| { | ||
| ACPI_SCI_HANDLER_INFO *SciHandler; | ||
| ACPI_CPU_FLAGS Flags; | ||
| ACPI_STATUS Status; | ||
|
|
||
| ACPI_FUNCTION_TRACE(EvRemoveAllSciHandlers); | ||
|
|
||
| /* Just let the OS remove the handler and disable the level */ | ||
|
|
||
| Status = AcpiOsRemoveInterruptHandler((UINT32)AcpiGbl_FADT.SciInterrupt, | ||
| AcpiEvSciXruptHandler); | ||
|
|
||
| if (!AcpiGbl_SciHandlerList) { | ||
| return (Status); | ||
| } | ||
|
|
||
| Flags = AcpiOsAcquireLock(AcpiGbl_GpeLock); | ||
|
|
||
| /* Free all host-installed SCI handlers */ | ||
|
|
||
| while (AcpiGbl_SciHandlerList) { | ||
| SciHandler = AcpiGbl_SciHandlerList; | ||
| AcpiGbl_SciHandlerList = SciHandler->Next; | ||
| ACPI_FREE(SciHandler); | ||
| } | ||
|
|
||
| AcpiOsReleaseLock(AcpiGbl_GpeLock, Flags); | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| #endif /* !ACPI_REDUCED_HARDWARE */ |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,379 @@ | ||
| /****************************************************************************** | ||
| * | ||
| * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable | ||
| * | ||
| *****************************************************************************/ | ||
|
|
||
| /* | ||
| * Copyright (C) 2000 - 2022, Intel Corp. | ||
| * All rights reserved. | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions, and the following disclaimer, | ||
| * without modification. | ||
| * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
| * substantially similar to the "NO WARRANTY" disclaimer below | ||
| * ("Disclaimer") and any redistribution must be conditioned upon | ||
| * including a substantially similar Disclaimer requirement for further | ||
| * binary redistribution. | ||
| * 3. Neither the names of the above-listed copyright holders nor the names | ||
| * of any contributors may be used to endorse or promote products derived | ||
| * from this software without specific prior written permission. | ||
| * | ||
| * Alternatively, this software may be distributed under the terms of the | ||
| * GNU General Public License ("GPL") version 2 as published by the Free | ||
| * Software Foundation. | ||
| * | ||
| * NO WARRANTY | ||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
| * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| * POSSIBILITY OF SUCH DAMAGES. | ||
| */ | ||
|
|
||
| #define EXPORT_ACPI_INTERFACES | ||
|
|
||
| #include "acpi.h" | ||
| #include "accommon.h" | ||
| #include "actables.h" | ||
|
|
||
| #define _COMPONENT ACPI_EVENTS | ||
| ACPI_MODULE_NAME("evxfevnt") | ||
|
|
||
| #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ | ||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiEnable | ||
| * | ||
| * PARAMETERS: None | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Transfers the system into ACPI mode. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiEnable(void) | ||
| { | ||
| ACPI_STATUS Status = AE_OK; | ||
|
|
||
| ACPI_FUNCTION_TRACE(AcpiEnable); | ||
|
|
||
| /* ACPI tables must be present */ | ||
|
|
||
| if (AcpiGbl_FadtIndex == ACPI_INVALID_TABLE_INDEX) { | ||
| return_ACPI_STATUS(AE_NO_ACPI_TABLES); | ||
| } | ||
|
|
||
| /* If the Hardware Reduced flag is set, machine is always in acpi mode */ | ||
|
|
||
| if (AcpiGbl_ReducedHardware) { | ||
| return_ACPI_STATUS(AE_OK); | ||
| } | ||
|
|
||
| /* Check current mode */ | ||
|
|
||
| if (AcpiHwGetMode() == ACPI_SYS_MODE_ACPI) { | ||
| ACPI_DEBUG_PRINT((ACPI_DB_INIT, "System is already in ACPI mode\n")); | ||
| } else { | ||
| /* Transition to ACPI mode */ | ||
|
|
||
| Status = AcpiHwSetMode(ACPI_SYS_MODE_ACPI); | ||
| if (ACPI_FAILURE(Status)) { | ||
| ACPI_ERROR((AE_INFO, "Could not transition to ACPI mode")); | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_INIT, "Transition to ACPI mode successful\n")); | ||
| } | ||
|
|
||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| ACPI_EXPORT_SYMBOL(AcpiEnable) | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiDisable | ||
| * | ||
| * PARAMETERS: None | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiDisable(void) | ||
| { | ||
| ACPI_STATUS Status = AE_OK; | ||
|
|
||
| ACPI_FUNCTION_TRACE(AcpiDisable); | ||
|
|
||
| /* If the Hardware Reduced flag is set, machine is always in acpi mode */ | ||
|
|
||
| if (AcpiGbl_ReducedHardware) { | ||
| return_ACPI_STATUS(AE_OK); | ||
| } | ||
|
|
||
| if (AcpiHwGetMode() == ACPI_SYS_MODE_LEGACY) { | ||
| ACPI_DEBUG_PRINT((ACPI_DB_INIT, "System is already in legacy (non-ACPI) mode\n")); | ||
| } else { | ||
| /* Transition to LEGACY mode */ | ||
|
|
||
| Status = AcpiHwSetMode(ACPI_SYS_MODE_LEGACY); | ||
|
|
||
| if (ACPI_FAILURE(Status)) { | ||
| ACPI_ERROR((AE_INFO, "Could not exit ACPI mode to legacy mode")); | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI mode disabled\n")); | ||
| } | ||
|
|
||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| ACPI_EXPORT_SYMBOL(AcpiDisable) | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiEnableEvent | ||
| * | ||
| * PARAMETERS: Event - The fixed eventto be enabled | ||
| * Flags - Reserved | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Enable an ACPI event (fixed) | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiEnableEvent(UINT32 Event, UINT32 Flags) | ||
| { | ||
| ACPI_STATUS Status = AE_OK; | ||
| UINT32 Value; | ||
|
|
||
| ACPI_FUNCTION_TRACE(AcpiEnableEvent); | ||
|
|
||
| /* If Hardware Reduced flag is set, there are no fixed events */ | ||
|
|
||
| if (AcpiGbl_ReducedHardware) { | ||
| return_ACPI_STATUS(AE_OK); | ||
| } | ||
|
|
||
| /* Decode the Fixed Event */ | ||
|
|
||
| if (Event > ACPI_EVENT_MAX) { | ||
| return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
| } | ||
|
|
||
| /* | ||
| * Enable the requested fixed event (by writing a one to the enable | ||
| * register bit) | ||
| */ | ||
| Status = AcpiWriteBitRegister(AcpiGbl_FixedEventInfo[Event].EnableRegisterId, | ||
| ACPI_ENABLE_EVENT); | ||
| if (ACPI_FAILURE(Status)) { | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| /* Make sure that the hardware responded */ | ||
|
|
||
| Status = AcpiReadBitRegister(AcpiGbl_FixedEventInfo[Event].EnableRegisterId, &Value); | ||
| if (ACPI_FAILURE(Status)) { | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| if (Value != 1) { | ||
| ACPI_ERROR((AE_INFO, "Could not enable %s event", AcpiUtGetEventName(Event))); | ||
| return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); | ||
| } | ||
|
|
||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| ACPI_EXPORT_SYMBOL(AcpiEnableEvent) | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiDisableEvent | ||
| * | ||
| * PARAMETERS: Event - The fixed event to be disabled | ||
| * Flags - Reserved | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Disable an ACPI event (fixed) | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiDisableEvent(UINT32 Event, UINT32 Flags) | ||
| { | ||
| ACPI_STATUS Status = AE_OK; | ||
| UINT32 Value; | ||
|
|
||
| ACPI_FUNCTION_TRACE(AcpiDisableEvent); | ||
|
|
||
| /* If Hardware Reduced flag is set, there are no fixed events */ | ||
|
|
||
| if (AcpiGbl_ReducedHardware) { | ||
| return_ACPI_STATUS(AE_OK); | ||
| } | ||
|
|
||
| /* Decode the Fixed Event */ | ||
|
|
||
| if (Event > ACPI_EVENT_MAX) { | ||
| return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
| } | ||
|
|
||
| /* | ||
| * Disable the requested fixed event (by writing a zero to the enable | ||
| * register bit) | ||
| */ | ||
| Status = AcpiWriteBitRegister(AcpiGbl_FixedEventInfo[Event].EnableRegisterId, | ||
| ACPI_DISABLE_EVENT); | ||
| if (ACPI_FAILURE(Status)) { | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| Status = AcpiReadBitRegister(AcpiGbl_FixedEventInfo[Event].EnableRegisterId, &Value); | ||
| if (ACPI_FAILURE(Status)) { | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| if (Value != 0) { | ||
| ACPI_ERROR((AE_INFO, "Could not disable %s events", AcpiUtGetEventName(Event))); | ||
| return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); | ||
| } | ||
|
|
||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| ACPI_EXPORT_SYMBOL(AcpiDisableEvent) | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiClearEvent | ||
| * | ||
| * PARAMETERS: Event - The fixed event to be cleared | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Clear an ACPI event (fixed) | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiClearEvent(UINT32 Event) | ||
| { | ||
| ACPI_STATUS Status = AE_OK; | ||
|
|
||
| ACPI_FUNCTION_TRACE(AcpiClearEvent); | ||
|
|
||
| /* If Hardware Reduced flag is set, there are no fixed events */ | ||
|
|
||
| if (AcpiGbl_ReducedHardware) { | ||
| return_ACPI_STATUS(AE_OK); | ||
| } | ||
|
|
||
| /* Decode the Fixed Event */ | ||
|
|
||
| if (Event > ACPI_EVENT_MAX) { | ||
| return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
| } | ||
|
|
||
| /* | ||
| * Clear the requested fixed event (By writing a one to the status | ||
| * register bit) | ||
| */ | ||
| Status = AcpiWriteBitRegister(AcpiGbl_FixedEventInfo[Event].StatusRegisterId, | ||
| ACPI_CLEAR_STATUS); | ||
|
|
||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| ACPI_EXPORT_SYMBOL(AcpiClearEvent) | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiGetEventStatus | ||
| * | ||
| * PARAMETERS: Event - The fixed event | ||
| * EventStatus - Where the current status of the event will | ||
| * be returned | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Obtains and returns the current status of the event | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiGetEventStatus(UINT32 Event, ACPI_EVENT_STATUS *EventStatus) | ||
| { | ||
| ACPI_STATUS Status; | ||
| ACPI_EVENT_STATUS LocalEventStatus = 0; | ||
| UINT32 InByte; | ||
|
|
||
| ACPI_FUNCTION_TRACE(AcpiGetEventStatus); | ||
|
|
||
| if (!EventStatus) { | ||
| return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
| } | ||
|
|
||
| /* Decode the Fixed Event */ | ||
|
|
||
| if (Event > ACPI_EVENT_MAX) { | ||
| return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
| } | ||
|
|
||
| /* Fixed event currently can be dispatched? */ | ||
|
|
||
| if (AcpiGbl_FixedEventHandlers[Event].Handler) { | ||
| LocalEventStatus |= ACPI_EVENT_FLAG_HAS_HANDLER; | ||
| } | ||
|
|
||
| /* Fixed event currently enabled? */ | ||
|
|
||
| Status = AcpiReadBitRegister(AcpiGbl_FixedEventInfo[Event].EnableRegisterId, &InByte); | ||
| if (ACPI_FAILURE(Status)) { | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| if (InByte) { | ||
| LocalEventStatus |= (ACPI_EVENT_FLAG_ENABLED | ACPI_EVENT_FLAG_ENABLE_SET); | ||
| } | ||
|
|
||
| /* Fixed event currently active? */ | ||
|
|
||
| Status = AcpiReadBitRegister(AcpiGbl_FixedEventInfo[Event].StatusRegisterId, &InByte); | ||
| if (ACPI_FAILURE(Status)) { | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| if (InByte) { | ||
| LocalEventStatus |= ACPI_EVENT_FLAG_STATUS_SET; | ||
| } | ||
|
|
||
| (*EventStatus) = LocalEventStatus; | ||
| return_ACPI_STATUS(AE_OK); | ||
| } | ||
|
|
||
| ACPI_EXPORT_SYMBOL(AcpiGetEventStatus) | ||
|
|
||
| #endif /* !ACPI_REDUCED_HARDWARE */ |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,255 @@ | ||
| /****************************************************************************** | ||
| * | ||
| * Module Name: evxfregn - External Interfaces, ACPI Operation Regions and | ||
| * Address Spaces. | ||
| * | ||
| *****************************************************************************/ | ||
|
|
||
| /* | ||
| * Copyright (C) 2000 - 2022, Intel Corp. | ||
| * All rights reserved. | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions, and the following disclaimer, | ||
| * without modification. | ||
| * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
| * substantially similar to the "NO WARRANTY" disclaimer below | ||
| * ("Disclaimer") and any redistribution must be conditioned upon | ||
| * including a substantially similar Disclaimer requirement for further | ||
| * binary redistribution. | ||
| * 3. Neither the names of the above-listed copyright holders nor the names | ||
| * of any contributors may be used to endorse or promote products derived | ||
| * from this software without specific prior written permission. | ||
| * | ||
| * Alternatively, this software may be distributed under the terms of the | ||
| * GNU General Public License ("GPL") version 2 as published by the Free | ||
| * Software Foundation. | ||
| * | ||
| * NO WARRANTY | ||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
| * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| * POSSIBILITY OF SUCH DAMAGES. | ||
| */ | ||
|
|
||
| #define EXPORT_ACPI_INTERFACES | ||
|
|
||
| #include "acpi.h" | ||
| #include "accommon.h" | ||
| #include "acnamesp.h" | ||
| #include "acevents.h" | ||
|
|
||
| #define _COMPONENT ACPI_EVENTS | ||
| ACPI_MODULE_NAME("evxfregn") | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiInstallAddressSpaceHandler | ||
| * | ||
| * PARAMETERS: Device - Handle for the device | ||
| * SpaceId - The address space ID | ||
| * Handler - Address of the handler | ||
| * Setup - Address of the setup function | ||
| * Context - Value passed to the handler on each access | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Install a handler for all OpRegions of a given SpaceId. | ||
| * | ||
| * NOTE: This function should only be called after AcpiEnableSubsystem has | ||
| * been called. This is because any _REG methods associated with the Space ID | ||
| * are executed here, and these methods can only be safely executed after | ||
| * the default handlers have been installed and the hardware has been | ||
| * initialized (via AcpiEnableSubsystem.) | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiInstallAddressSpaceHandler(ACPI_HANDLE Device, ACPI_ADR_SPACE_TYPE SpaceId, | ||
| ACPI_ADR_SPACE_HANDLER Handler, ACPI_ADR_SPACE_SETUP Setup, | ||
| void *Context) | ||
| { | ||
| ACPI_NAMESPACE_NODE *Node; | ||
| ACPI_STATUS Status; | ||
|
|
||
| ACPI_FUNCTION_TRACE(AcpiInstallAddressSpaceHandler); | ||
|
|
||
| /* Parameter validation */ | ||
|
|
||
| if (!Device) { | ||
| return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
| } | ||
|
|
||
| Status = AcpiUtAcquireMutex(ACPI_MTX_NAMESPACE); | ||
| if (ACPI_FAILURE(Status)) { | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| /* Convert and validate the device handle */ | ||
|
|
||
| Node = AcpiNsValidateHandle(Device); | ||
| if (!Node) { | ||
| Status = AE_BAD_PARAMETER; | ||
| goto UnlockAndExit; | ||
| } | ||
|
|
||
| /* Install the handler for all Regions for this Space ID */ | ||
|
|
||
| Status = AcpiEvInstallSpaceHandler(Node, SpaceId, Handler, Setup, Context); | ||
| if (ACPI_FAILURE(Status)) { | ||
| goto UnlockAndExit; | ||
| } | ||
|
|
||
| /* Run all _REG methods for this address space */ | ||
|
|
||
| AcpiEvExecuteRegMethods(Node, SpaceId, ACPI_REG_CONNECT); | ||
|
|
||
| UnlockAndExit: | ||
| (void)AcpiUtReleaseMutex(ACPI_MTX_NAMESPACE); | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| ACPI_EXPORT_SYMBOL(AcpiInstallAddressSpaceHandler) | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiRemoveAddressSpaceHandler | ||
| * | ||
| * PARAMETERS: Device - Handle for the device | ||
| * SpaceId - The address space ID | ||
| * Handler - Address of the handler | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Remove a previously installed handler. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiRemoveAddressSpaceHandler(ACPI_HANDLE Device, ACPI_ADR_SPACE_TYPE SpaceId, | ||
| ACPI_ADR_SPACE_HANDLER Handler) | ||
| { | ||
| ACPI_OPERAND_OBJECT *ObjDesc; | ||
| ACPI_OPERAND_OBJECT *HandlerObj; | ||
| ACPI_OPERAND_OBJECT *RegionObj; | ||
| ACPI_OPERAND_OBJECT **LastObjPtr; | ||
| ACPI_NAMESPACE_NODE *Node; | ||
| ACPI_STATUS Status; | ||
|
|
||
| ACPI_FUNCTION_TRACE(AcpiRemoveAddressSpaceHandler); | ||
|
|
||
| /* Parameter validation */ | ||
|
|
||
| if (!Device) { | ||
| return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
| } | ||
|
|
||
| Status = AcpiUtAcquireMutex(ACPI_MTX_NAMESPACE); | ||
| if (ACPI_FAILURE(Status)) { | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| /* Convert and validate the device handle */ | ||
|
|
||
| Node = AcpiNsValidateHandle(Device); | ||
| if (!Node || | ||
| ((Node->Type != ACPI_TYPE_DEVICE) && (Node->Type != ACPI_TYPE_PROCESSOR) && | ||
| (Node->Type != ACPI_TYPE_THERMAL) && (Node != AcpiGbl_RootNode))) { | ||
| Status = AE_BAD_PARAMETER; | ||
| goto UnlockAndExit; | ||
| } | ||
|
|
||
| /* Make sure the internal object exists */ | ||
|
|
||
| ObjDesc = AcpiNsGetAttachedObject(Node); | ||
| if (!ObjDesc) { | ||
| Status = AE_NOT_EXIST; | ||
| goto UnlockAndExit; | ||
| } | ||
|
|
||
| /* Find the address handler the user requested */ | ||
|
|
||
| HandlerObj = ObjDesc->CommonNotify.Handler; | ||
| LastObjPtr = &ObjDesc->CommonNotify.Handler; | ||
| while (HandlerObj) { | ||
| /* We have a handler, see if user requested this one */ | ||
|
|
||
| if (HandlerObj->AddressSpace.SpaceId == SpaceId) { | ||
| /* Handler must be the same as the installed handler */ | ||
|
|
||
| if (HandlerObj->AddressSpace.Handler != Handler) { | ||
| Status = AE_BAD_PARAMETER; | ||
| goto UnlockAndExit; | ||
| } | ||
|
|
||
| /* Matched SpaceId, first dereference this in the Regions */ | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, | ||
| "Removing address handler %p(%p) for region %s " | ||
| "on Device %p(%p)\n", | ||
| HandlerObj, Handler, AcpiUtGetRegionName(SpaceId), Node, | ||
| ObjDesc)); | ||
|
|
||
| RegionObj = HandlerObj->AddressSpace.RegionList; | ||
|
|
||
| /* Walk the handler's region list */ | ||
|
|
||
| while (RegionObj) { | ||
| /* | ||
| * First disassociate the handler from the region. | ||
| * | ||
| * NOTE: this doesn't mean that the region goes away | ||
| * The region is just inaccessible as indicated to | ||
| * the _REG method | ||
| */ | ||
| AcpiEvDetachRegion(RegionObj, TRUE); | ||
|
|
||
| /* | ||
| * Walk the list: Just grab the head because the | ||
| * DetachRegion removed the previous head. | ||
| */ | ||
| RegionObj = HandlerObj->AddressSpace.RegionList; | ||
| } | ||
|
|
||
| /* Remove this Handler object from the list */ | ||
|
|
||
| *LastObjPtr = HandlerObj->AddressSpace.Next; | ||
|
|
||
| /* Now we can delete the handler object */ | ||
|
|
||
| AcpiOsReleaseMutex(HandlerObj->AddressSpace.ContextMutex); | ||
| AcpiUtRemoveReference(HandlerObj); | ||
| goto UnlockAndExit; | ||
| } | ||
|
|
||
| /* Walk the linked list of handlers */ | ||
|
|
||
| LastObjPtr = &HandlerObj->AddressSpace.Next; | ||
| HandlerObj = HandlerObj->AddressSpace.Next; | ||
| } | ||
|
|
||
| /* The handler does not exist */ | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, | ||
| "Unable to remove address handler %p for %s(%X), DevNode %p, obj " | ||
| "%p\n", | ||
| Handler, AcpiUtGetRegionName(SpaceId), SpaceId, Node, ObjDesc)); | ||
|
|
||
| Status = AE_NOT_EXIST; | ||
|
|
||
| UnlockAndExit: | ||
| (void)AcpiUtReleaseMutex(ACPI_MTX_NAMESPACE); | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| ACPI_EXPORT_SYMBOL(AcpiRemoveAddressSpaceHandler) |
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,302 @@ | ||
| /****************************************************************************** | ||
| * | ||
| * Module Name: exdebug - Support for stores to the AML Debug Object | ||
| * | ||
| *****************************************************************************/ | ||
|
|
||
| /* | ||
| * Copyright (C) 2000 - 2022, Intel Corp. | ||
| * All rights reserved. | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions, and the following disclaimer, | ||
| * without modification. | ||
| * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
| * substantially similar to the "NO WARRANTY" disclaimer below | ||
| * ("Disclaimer") and any redistribution must be conditioned upon | ||
| * including a substantially similar Disclaimer requirement for further | ||
| * binary redistribution. | ||
| * 3. Neither the names of the above-listed copyright holders nor the names | ||
| * of any contributors may be used to endorse or promote products derived | ||
| * from this software without specific prior written permission. | ||
| * | ||
| * Alternatively, this software may be distributed under the terms of the | ||
| * GNU General Public License ("GPL") version 2 as published by the Free | ||
| * Software Foundation. | ||
| * | ||
| * NO WARRANTY | ||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
| * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| * POSSIBILITY OF SUCH DAMAGES. | ||
| */ | ||
|
|
||
| #include "acpi.h" | ||
| #include "accommon.h" | ||
| #include "acinterp.h" | ||
|
|
||
| #define _COMPONENT ACPI_EXECUTER | ||
| ACPI_MODULE_NAME("exdebug") | ||
|
|
||
| #ifndef ACPI_NO_ERROR_MESSAGES | ||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiExDoDebugObject | ||
| * | ||
| * PARAMETERS: SourceDesc - Object to be output to "Debug Object" | ||
| * Level - Indentation level (used for packages) | ||
| * Index - Current package element, zero if not pkg | ||
| * | ||
| * RETURN: None | ||
| * | ||
| * DESCRIPTION: Handles stores to the AML Debug Object. For example: | ||
| * Store(INT1, Debug) | ||
| * | ||
| * This function is not compiled if ACPI_NO_ERROR_MESSAGES is set. | ||
| * | ||
| * This function is only enabled if AcpiGbl_EnableAmlDebugObject is set, or | ||
| * if ACPI_LV_DEBUG_OBJECT is set in the AcpiDbgLevel. Thus, in the normal | ||
| * operational case, stores to the debug object are ignored but can be easily | ||
| * enabled if necessary. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| void AcpiExDoDebugObject(ACPI_OPERAND_OBJECT *SourceDesc, UINT32 Level, UINT32 Index) | ||
| { | ||
| UINT32 i; | ||
| UINT32 Timer; | ||
| ACPI_OPERAND_OBJECT *ObjectDesc; | ||
| UINT32 Value; | ||
|
|
||
| ACPI_FUNCTION_TRACE_PTR(ExDoDebugObject, SourceDesc); | ||
|
|
||
| /* Output must be enabled via the DebugObject global or the DbgLevel */ | ||
|
|
||
| if (!AcpiGbl_EnableAmlDebugObject && !(AcpiDbgLevel & ACPI_LV_DEBUG_OBJECT)) { | ||
| return_VOID; | ||
| } | ||
|
|
||
| /* Newline -- don't emit the line header */ | ||
|
|
||
| if (SourceDesc && (ACPI_GET_DESCRIPTOR_TYPE(SourceDesc) == ACPI_DESC_TYPE_OPERAND) && | ||
| (SourceDesc->Common.Type == ACPI_TYPE_STRING)) { | ||
| if ((SourceDesc->String.Length == 1) && (*SourceDesc->String.Pointer == '\n')) { | ||
| AcpiOsPrintf("\n"); | ||
| return_VOID; | ||
| } | ||
| } | ||
|
|
||
| /* | ||
| * Print line header as long as we are not in the middle of an | ||
| * object display | ||
| */ | ||
| if (!((Level > 0) && Index == 0)) { | ||
| if (AcpiGbl_DisplayDebugTimer) { | ||
| /* | ||
| * We will emit the current timer value (in microseconds) with each | ||
| * debug output. Only need the lower 26 bits. This allows for 67 | ||
| * million microseconds or 67 seconds before rollover. | ||
| * | ||
| * Convert 100 nanosecond units to microseconds | ||
| */ | ||
| Timer = ((UINT32)AcpiOsGetTimer() / 10); | ||
| Timer &= 0x03FFFFFF; | ||
|
|
||
| AcpiOsPrintf("ACPI Debug: T=0x%8.8X %*s", Timer, Level, " "); | ||
| } else { | ||
| AcpiOsPrintf("ACPI Debug: %*s", Level, " "); | ||
| } | ||
| } | ||
|
|
||
| /* Display the index for package output only */ | ||
|
|
||
| if (Index > 0) { | ||
| AcpiOsPrintf("(%.2u) ", Index - 1); | ||
| } | ||
|
|
||
| if (!SourceDesc) { | ||
| AcpiOsPrintf("[Null Object]\n"); | ||
| return_VOID; | ||
| } | ||
|
|
||
| if (ACPI_GET_DESCRIPTOR_TYPE(SourceDesc) == ACPI_DESC_TYPE_OPERAND) { | ||
| /* No object type prefix needed for integers and strings */ | ||
|
|
||
| if ((SourceDesc->Common.Type != ACPI_TYPE_INTEGER) && | ||
| (SourceDesc->Common.Type != ACPI_TYPE_STRING)) { | ||
| AcpiOsPrintf("%s ", AcpiUtGetObjectTypeName(SourceDesc)); | ||
| } | ||
|
|
||
| if (!AcpiUtValidInternalObject(SourceDesc)) { | ||
| AcpiOsPrintf("%p, Invalid Internal Object!\n", SourceDesc); | ||
| return_VOID; | ||
| } | ||
| } else if (ACPI_GET_DESCRIPTOR_TYPE(SourceDesc) == ACPI_DESC_TYPE_NAMED) { | ||
| AcpiOsPrintf("%s (Node %p)\n", | ||
| AcpiUtGetTypeName(((ACPI_NAMESPACE_NODE *)SourceDesc)->Type), | ||
| SourceDesc); | ||
| return_VOID; | ||
| } else { | ||
| return_VOID; | ||
| } | ||
|
|
||
| /* SourceDesc is of type ACPI_DESC_TYPE_OPERAND */ | ||
|
|
||
| switch (SourceDesc->Common.Type) { | ||
| case ACPI_TYPE_INTEGER: | ||
|
|
||
| /* Output correct integer width */ | ||
|
|
||
| if (AcpiGbl_IntegerByteWidth == 4) { | ||
| AcpiOsPrintf("0x%8.8X\n", (UINT32)SourceDesc->Integer.Value); | ||
| } else { | ||
| AcpiOsPrintf("0x%8.8X%8.8X\n", ACPI_FORMAT_UINT64(SourceDesc->Integer.Value)); | ||
| } | ||
| break; | ||
|
|
||
| case ACPI_TYPE_BUFFER: | ||
|
|
||
| AcpiOsPrintf("[0x%.2X]\n", (UINT32)SourceDesc->Buffer.Length); | ||
| AcpiUtDumpBuffer(SourceDesc->Buffer.Pointer, | ||
| (SourceDesc->Buffer.Length < 256) ? SourceDesc->Buffer.Length : | ||
| 256, | ||
| DB_BYTE_DISPLAY, 0); | ||
| break; | ||
|
|
||
| case ACPI_TYPE_STRING: | ||
|
|
||
| AcpiOsPrintf("\"%s\"\n", SourceDesc->String.Pointer); | ||
| break; | ||
|
|
||
| case ACPI_TYPE_PACKAGE: | ||
|
|
||
| AcpiOsPrintf("(Contains 0x%.2X Elements):\n", SourceDesc->Package.Count); | ||
|
|
||
| /* Output the entire contents of the package */ | ||
|
|
||
| for (i = 0; i < SourceDesc->Package.Count; i++) { | ||
| AcpiExDoDebugObject(SourceDesc->Package.Elements[i], Level + 4, i + 1); | ||
| } | ||
| break; | ||
|
|
||
| case ACPI_TYPE_LOCAL_REFERENCE: | ||
|
|
||
| AcpiOsPrintf("[%s] ", AcpiUtGetReferenceName(SourceDesc)); | ||
|
|
||
| /* Decode the reference */ | ||
|
|
||
| switch (SourceDesc->Reference.Class) { | ||
| case ACPI_REFCLASS_INDEX: | ||
|
|
||
| AcpiOsPrintf("0x%X\n", SourceDesc->Reference.Value); | ||
| break; | ||
|
|
||
| case ACPI_REFCLASS_TABLE: | ||
|
|
||
| /* Case for DdbHandle */ | ||
|
|
||
| AcpiOsPrintf("Table Index 0x%X\n", SourceDesc->Reference.Value); | ||
| return_VOID; | ||
|
|
||
| default: | ||
|
|
||
| break; | ||
| } | ||
|
|
||
| AcpiOsPrintf(" "); | ||
|
|
||
| /* Check for valid node first, then valid object */ | ||
|
|
||
| if (SourceDesc->Reference.Node) { | ||
| if (ACPI_GET_DESCRIPTOR_TYPE(SourceDesc->Reference.Node) != | ||
| ACPI_DESC_TYPE_NAMED) { | ||
| AcpiOsPrintf(" %p - Not a valid namespace node\n", | ||
| SourceDesc->Reference.Node); | ||
| } else { | ||
| AcpiOsPrintf("Node %p [%4.4s] ", SourceDesc->Reference.Node, | ||
| (SourceDesc->Reference.Node)->Name.Ascii); | ||
|
|
||
| switch ((SourceDesc->Reference.Node)->Type) { | ||
| /* These types have no attached object */ | ||
|
|
||
| case ACPI_TYPE_DEVICE: | ||
| AcpiOsPrintf("Device\n"); | ||
| break; | ||
|
|
||
| case ACPI_TYPE_THERMAL: | ||
| AcpiOsPrintf("Thermal Zone\n"); | ||
| break; | ||
|
|
||
| default: | ||
|
|
||
| AcpiExDoDebugObject((SourceDesc->Reference.Node)->Object, Level + 4, | ||
| 0); | ||
| break; | ||
| } | ||
| } | ||
| } else if (SourceDesc->Reference.Object) { | ||
| if (ACPI_GET_DESCRIPTOR_TYPE(SourceDesc->Reference.Object) == | ||
| ACPI_DESC_TYPE_NAMED) { | ||
| /* Reference object is a namespace node */ | ||
|
|
||
| AcpiExDoDebugObject(ACPI_CAST_PTR(ACPI_OPERAND_OBJECT, | ||
| SourceDesc->Reference.Object), | ||
| Level + 4, 0); | ||
| } else { | ||
| ObjectDesc = SourceDesc->Reference.Object; | ||
| Value = SourceDesc->Reference.Value; | ||
|
|
||
| switch (ObjectDesc->Common.Type) { | ||
| case ACPI_TYPE_BUFFER: | ||
|
|
||
| AcpiOsPrintf("Buffer[%u] = 0x%2.2X\n", Value, | ||
| *SourceDesc->Reference.IndexPointer); | ||
| break; | ||
|
|
||
| case ACPI_TYPE_STRING: | ||
|
|
||
| AcpiOsPrintf("String[%u] = \"%c\" (0x%2.2X)\n", Value, | ||
| *SourceDesc->Reference.IndexPointer, | ||
| *SourceDesc->Reference.IndexPointer); | ||
| break; | ||
|
|
||
| case ACPI_TYPE_PACKAGE: | ||
|
|
||
| AcpiOsPrintf("Package[%u] = ", Value); | ||
| if (!(*SourceDesc->Reference.Where)) { | ||
| AcpiOsPrintf("[Uninitialized Package Element]\n"); | ||
| } else { | ||
| AcpiExDoDebugObject(*SourceDesc->Reference.Where, Level + 4, 0); | ||
| } | ||
| break; | ||
|
|
||
| default: | ||
|
|
||
| AcpiOsPrintf("Unknown Reference object type %X\n", | ||
| ObjectDesc->Common.Type); | ||
| break; | ||
| } | ||
| } | ||
| } | ||
| break; | ||
|
|
||
| default: | ||
|
|
||
| AcpiOsPrintf("(Descriptor %p)\n", SourceDesc); | ||
| break; | ||
| } | ||
|
|
||
| ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "\n")); | ||
| return_VOID; | ||
| } | ||
| #endif |
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,399 @@ | ||
| /****************************************************************************** | ||
| * | ||
| * Module Name: exnames - interpreter/scanner name load/execute | ||
| * | ||
| *****************************************************************************/ | ||
|
|
||
| /* | ||
| * Copyright (C) 2000 - 2022, Intel Corp. | ||
| * All rights reserved. | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions, and the following disclaimer, | ||
| * without modification. | ||
| * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
| * substantially similar to the "NO WARRANTY" disclaimer below | ||
| * ("Disclaimer") and any redistribution must be conditioned upon | ||
| * including a substantially similar Disclaimer requirement for further | ||
| * binary redistribution. | ||
| * 3. Neither the names of the above-listed copyright holders nor the names | ||
| * of any contributors may be used to endorse or promote products derived | ||
| * from this software without specific prior written permission. | ||
| * | ||
| * Alternatively, this software may be distributed under the terms of the | ||
| * GNU General Public License ("GPL") version 2 as published by the Free | ||
| * Software Foundation. | ||
| * | ||
| * NO WARRANTY | ||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
| * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| * POSSIBILITY OF SUCH DAMAGES. | ||
| */ | ||
|
|
||
| #include "acpi.h" | ||
| #include "accommon.h" | ||
| #include "acinterp.h" | ||
| #include "amlcode.h" | ||
|
|
||
| #define _COMPONENT ACPI_EXECUTER | ||
| ACPI_MODULE_NAME("exnames") | ||
|
|
||
| /* Local prototypes */ | ||
|
|
||
| static char *AcpiExAllocateNameString(UINT32 PrefixCount, UINT32 NumNameSegs); | ||
|
|
||
| static ACPI_STATUS AcpiExNameSegment(UINT8 **InAmlAddress, char *NameString); | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiExAllocateNameString | ||
| * | ||
| * PARAMETERS: PrefixCount - Count of parent levels. Special cases: | ||
| * (-1)==root, 0==none | ||
| * NumNameSegs - count of 4-character name segments | ||
| * | ||
| * RETURN: A pointer to the allocated string segment. This segment must | ||
| * be deleted by the caller. | ||
| * | ||
| * DESCRIPTION: Allocate a buffer for a name string. Ensure allocated name | ||
| * string is long enough, and set up prefix if any. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| static char *AcpiExAllocateNameString(UINT32 PrefixCount, UINT32 NumNameSegs) | ||
| { | ||
| char *TempPtr; | ||
| char *NameString; | ||
| UINT32 SizeNeeded; | ||
|
|
||
| ACPI_FUNCTION_TRACE(ExAllocateNameString); | ||
|
|
||
| /* | ||
| * Allow room for all \ and ^ prefixes, all segments and a MultiNamePrefix. | ||
| * Also, one byte for the null terminator. | ||
| * This may actually be somewhat longer than needed. | ||
| */ | ||
| if (PrefixCount == ACPI_UINT32_MAX) { | ||
| /* Special case for root */ | ||
|
|
||
| SizeNeeded = 1 + (ACPI_NAMESEG_SIZE * NumNameSegs) + 2 + 1; | ||
| } else { | ||
| SizeNeeded = PrefixCount + (ACPI_NAMESEG_SIZE * NumNameSegs) + 2 + 1; | ||
| } | ||
|
|
||
| /* | ||
| * Allocate a buffer for the name. | ||
| * This buffer must be deleted by the caller! | ||
| */ | ||
| NameString = ACPI_ALLOCATE(SizeNeeded); | ||
| if (!NameString) { | ||
| ACPI_ERROR((AE_INFO, "Could not allocate size %u", SizeNeeded)); | ||
| return_PTR(NULL); | ||
| } | ||
|
|
||
| TempPtr = NameString; | ||
|
|
||
| /* Set up Root or Parent prefixes if needed */ | ||
|
|
||
| if (PrefixCount == ACPI_UINT32_MAX) { | ||
| *TempPtr++ = AML_ROOT_PREFIX; | ||
| } else { | ||
| while (PrefixCount--) { | ||
| *TempPtr++ = AML_PARENT_PREFIX; | ||
| } | ||
| } | ||
|
|
||
| /* Set up Dual or Multi prefixes if needed */ | ||
|
|
||
| if (NumNameSegs > 2) { | ||
| /* Set up multi prefixes */ | ||
|
|
||
| *TempPtr++ = AML_MULTI_NAME_PREFIX; | ||
| *TempPtr++ = (char)NumNameSegs; | ||
| } else if (2 == NumNameSegs) { | ||
| /* Set up dual prefixes */ | ||
|
|
||
| *TempPtr++ = AML_DUAL_NAME_PREFIX; | ||
| } | ||
|
|
||
| /* | ||
| * Terminate string following prefixes. AcpiExNameSegment() will | ||
| * append the segment(s) | ||
| */ | ||
| *TempPtr = 0; | ||
|
|
||
| return_PTR(NameString); | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiExNameSegment | ||
| * | ||
| * PARAMETERS: InAmlAddress - Pointer to the name in the AML code | ||
| * NameString - Where to return the name. The name is appended | ||
| * to any existing string to form a namepath | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Extract an ACPI name (4 bytes) from the AML byte stream | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| static ACPI_STATUS AcpiExNameSegment(UINT8 **InAmlAddress, char *NameString) | ||
| { | ||
| char *AmlAddress = (void *)*InAmlAddress; | ||
| ACPI_STATUS Status = AE_OK; | ||
| UINT32 Index; | ||
| char CharBuf[5]; | ||
|
|
||
| ACPI_FUNCTION_TRACE(ExNameSegment); | ||
|
|
||
| /* | ||
| * If first character is a digit, then we know that we aren't looking | ||
| * at a valid name segment | ||
| */ | ||
| CharBuf[0] = *AmlAddress; | ||
|
|
||
| if ('0' <= CharBuf[0] && CharBuf[0] <= '9') { | ||
| ACPI_ERROR((AE_INFO, "Invalid leading digit: %c", CharBuf[0])); | ||
| return_ACPI_STATUS(AE_CTRL_PENDING); | ||
| } | ||
|
|
||
| for (Index = 0; (Index < ACPI_NAMESEG_SIZE) && (AcpiUtValidNameChar(*AmlAddress, 0)); | ||
| Index++) { | ||
| CharBuf[Index] = *AmlAddress++; | ||
| } | ||
|
|
||
| /* Valid name segment */ | ||
|
|
||
| if (Index == 4) { | ||
| /* Found 4 valid characters */ | ||
|
|
||
| CharBuf[4] = '\0'; | ||
|
|
||
| if (NameString) { | ||
| ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Appending NameSeg %s\n", CharBuf)); | ||
| strcat(NameString, CharBuf); | ||
| } else { | ||
| ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "No Name string - %s\n", CharBuf)); | ||
| } | ||
| } else if (Index == 0) { | ||
| /* | ||
| * First character was not a valid name character, | ||
| * so we are looking at something other than a name. | ||
| */ | ||
| ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
| "Leading character is not alpha: %02Xh (not a name)\n", | ||
| CharBuf[0])); | ||
| Status = AE_CTRL_PENDING; | ||
| } else { | ||
| /* | ||
| * Segment started with one or more valid characters, but fewer than | ||
| * the required 4 | ||
| */ | ||
| Status = AE_AML_BAD_NAME; | ||
| ACPI_ERROR( | ||
| (AE_INFO, "Bad character 0x%02x in name, at %p", *AmlAddress, AmlAddress)); | ||
| } | ||
|
|
||
| *InAmlAddress = ACPI_CAST_PTR(UINT8, AmlAddress); | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiExGetNameString | ||
| * | ||
| * PARAMETERS: DataType - Object type to be associated with this | ||
| * name | ||
| * InAmlAddress - Pointer to the namestring in the AML code | ||
| * OutNameString - Where the namestring is returned | ||
| * OutNameLength - Length of the returned string | ||
| * | ||
| * RETURN: Status, namestring and length | ||
| * | ||
| * DESCRIPTION: Extract a full namepath from the AML byte stream, | ||
| * including any prefixes. | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiExGetNameString(ACPI_OBJECT_TYPE DataType, UINT8 *InAmlAddress, char **OutNameString, | ||
| UINT32 *OutNameLength) | ||
| { | ||
| ACPI_STATUS Status = AE_OK; | ||
| UINT8 *AmlAddress = InAmlAddress; | ||
| char *NameString = NULL; | ||
| UINT32 NumSegments; | ||
| UINT32 PrefixCount = 0; | ||
| BOOLEAN HasPrefix = FALSE; | ||
|
|
||
| ACPI_FUNCTION_TRACE_PTR(ExGetNameString, AmlAddress); | ||
|
|
||
| if (ACPI_TYPE_LOCAL_REGION_FIELD == DataType || | ||
| ACPI_TYPE_LOCAL_BANK_FIELD == DataType || | ||
| ACPI_TYPE_LOCAL_INDEX_FIELD == DataType) { | ||
| /* Disallow prefixes for types associated with FieldUnit names */ | ||
|
|
||
| NameString = AcpiExAllocateNameString(0, 1); | ||
| if (!NameString) { | ||
| Status = AE_NO_MEMORY; | ||
| } else { | ||
| Status = AcpiExNameSegment(&AmlAddress, NameString); | ||
| } | ||
| } else { | ||
| /* | ||
| * DataType is not a field name. | ||
| * Examine first character of name for root or parent prefix operators | ||
| */ | ||
| switch (*AmlAddress) { | ||
| case AML_ROOT_PREFIX: | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_LOAD, "RootPrefix(\\) at %p\n", AmlAddress)); | ||
|
|
||
| /* | ||
| * Remember that we have a RootPrefix -- | ||
| * see comment in AcpiExAllocateNameString() | ||
| */ | ||
| AmlAddress++; | ||
| PrefixCount = ACPI_UINT32_MAX; | ||
| HasPrefix = TRUE; | ||
| break; | ||
|
|
||
| case AML_PARENT_PREFIX: | ||
|
|
||
| /* Increment past possibly multiple parent prefixes */ | ||
|
|
||
| do { | ||
| ACPI_DEBUG_PRINT((ACPI_DB_LOAD, "ParentPrefix (^) at %p\n", AmlAddress)); | ||
|
|
||
| AmlAddress++; | ||
| PrefixCount++; | ||
|
|
||
| } while (*AmlAddress == AML_PARENT_PREFIX); | ||
|
|
||
| HasPrefix = TRUE; | ||
| break; | ||
|
|
||
| default: | ||
|
|
||
| /* Not a prefix character */ | ||
|
|
||
| break; | ||
| } | ||
|
|
||
| /* Examine first character of name for name segment prefix operator */ | ||
|
|
||
| switch (*AmlAddress) { | ||
| case AML_DUAL_NAME_PREFIX: | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_LOAD, "DualNamePrefix at %p\n", AmlAddress)); | ||
|
|
||
| AmlAddress++; | ||
| NameString = AcpiExAllocateNameString(PrefixCount, 2); | ||
| if (!NameString) { | ||
| Status = AE_NO_MEMORY; | ||
| break; | ||
| } | ||
|
|
||
| /* Indicate that we processed a prefix */ | ||
|
|
||
| HasPrefix = TRUE; | ||
|
|
||
| Status = AcpiExNameSegment(&AmlAddress, NameString); | ||
| if (ACPI_SUCCESS(Status)) { | ||
| Status = AcpiExNameSegment(&AmlAddress, NameString); | ||
| } | ||
| break; | ||
|
|
||
| case AML_MULTI_NAME_PREFIX: | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_LOAD, "MultiNamePrefix at %p\n", AmlAddress)); | ||
|
|
||
| /* Fetch count of segments remaining in name path */ | ||
|
|
||
| AmlAddress++; | ||
| NumSegments = *AmlAddress; | ||
|
|
||
| NameString = AcpiExAllocateNameString(PrefixCount, NumSegments); | ||
| if (!NameString) { | ||
| Status = AE_NO_MEMORY; | ||
| break; | ||
| } | ||
|
|
||
| /* Indicate that we processed a prefix */ | ||
|
|
||
| AmlAddress++; | ||
| HasPrefix = TRUE; | ||
|
|
||
| while (NumSegments && | ||
| (Status = AcpiExNameSegment(&AmlAddress, NameString)) == AE_OK) { | ||
| NumSegments--; | ||
| } | ||
|
|
||
| break; | ||
|
|
||
| case 0: | ||
|
|
||
| /* NullName valid as of 8-12-98 ASL/AML Grammar Update */ | ||
|
|
||
| if (PrefixCount == ACPI_UINT32_MAX) { | ||
| ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "NameSeg is \"\\\" followed by NULL\n")); | ||
| } | ||
|
|
||
| /* Consume the NULL byte */ | ||
|
|
||
| AmlAddress++; | ||
| NameString = AcpiExAllocateNameString(PrefixCount, 0); | ||
| if (!NameString) { | ||
| Status = AE_NO_MEMORY; | ||
| break; | ||
| } | ||
|
|
||
| break; | ||
|
|
||
| default: | ||
|
|
||
| /* Name segment string */ | ||
|
|
||
| NameString = AcpiExAllocateNameString(PrefixCount, 1); | ||
| if (!NameString) { | ||
| Status = AE_NO_MEMORY; | ||
| break; | ||
| } | ||
|
|
||
| Status = AcpiExNameSegment(&AmlAddress, NameString); | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| if (AE_CTRL_PENDING == Status && HasPrefix) { | ||
| /* Ran out of segments after processing a prefix */ | ||
|
|
||
| ACPI_ERROR((AE_INFO, "Malformed Name at %p", NameString)); | ||
| Status = AE_AML_BAD_NAME; | ||
| } | ||
|
|
||
| if (ACPI_FAILURE(Status)) { | ||
| if (NameString) { | ||
| ACPI_FREE(NameString); | ||
| } | ||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| *OutNameString = NameString; | ||
| *OutNameLength = (UINT32)(AmlAddress - InAmlAddress); | ||
|
|
||
| return_ACPI_STATUS(Status); | ||
| } |
Large diffs are not rendered by default.
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,280 @@ | ||
| /****************************************************************************** | ||
| * | ||
| * Module Name: exoparg3 - AML execution - opcodes with 3 arguments | ||
| * | ||
| *****************************************************************************/ | ||
|
|
||
| /* | ||
| * Copyright (C) 2000 - 2022, Intel Corp. | ||
| * All rights reserved. | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions, and the following disclaimer, | ||
| * without modification. | ||
| * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
| * substantially similar to the "NO WARRANTY" disclaimer below | ||
| * ("Disclaimer") and any redistribution must be conditioned upon | ||
| * including a substantially similar Disclaimer requirement for further | ||
| * binary redistribution. | ||
| * 3. Neither the names of the above-listed copyright holders nor the names | ||
| * of any contributors may be used to endorse or promote products derived | ||
| * from this software without specific prior written permission. | ||
| * | ||
| * Alternatively, this software may be distributed under the terms of the | ||
| * GNU General Public License ("GPL") version 2 as published by the Free | ||
| * Software Foundation. | ||
| * | ||
| * NO WARRANTY | ||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
| * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| * POSSIBILITY OF SUCH DAMAGES. | ||
| */ | ||
|
|
||
| #include "acpi.h" | ||
| #include "accommon.h" | ||
| #include "acinterp.h" | ||
| #include "acparser.h" | ||
| #include "amlcode.h" | ||
|
|
||
| #define _COMPONENT ACPI_EXECUTER | ||
| ACPI_MODULE_NAME("exoparg3") | ||
|
|
||
| /*! | ||
| * Naming convention for AML interpreter execution routines. | ||
| * | ||
| * The routines that begin execution of AML opcodes are named with a common | ||
| * convention based upon the number of arguments, the number of target operands, | ||
| * and whether or not a value is returned: | ||
| * | ||
| * AcpiExOpcode_xA_yT_zR | ||
| * | ||
| * Where: | ||
| * | ||
| * xA - ARGUMENTS: The number of arguments (input operands) that are | ||
| * required for this opcode type (1 through 6 args). | ||
| * yT - TARGETS: The number of targets (output operands) that are required | ||
| * for this opcode type (0, 1, or 2 targets). | ||
| * zR - RETURN VALUE: Indicates whether this opcode type returns a value | ||
| * as the function return (0 or 1). | ||
| * | ||
| * The AcpiExOpcode* functions are called via the Dispatcher component with | ||
| * fully resolved operands. | ||
| !*/ | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiExOpcode_3A_0T_0R | ||
| * | ||
| * PARAMETERS: WalkState - Current walk state | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Execute Triadic operator (3 operands) | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiExOpcode_3A_0T_0R(ACPI_WALK_STATE *WalkState) | ||
| { | ||
| ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; | ||
| ACPI_SIGNAL_FATAL_INFO *Fatal; | ||
| ACPI_STATUS Status = AE_OK; | ||
|
|
||
| ACPI_FUNCTION_TRACE_STR(ExOpcode_3A_0T_0R, AcpiPsGetOpcodeName(WalkState->Opcode)); | ||
|
|
||
| switch (WalkState->Opcode) { | ||
| case AML_FATAL_OP: /* Fatal (FatalType FatalCode FatalArg) */ | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
| "FatalOp: Type %X Code %X Arg %X " | ||
| "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", | ||
| (UINT32)Operand[0]->Integer.Value, | ||
| (UINT32)Operand[1]->Integer.Value, | ||
| (UINT32)Operand[2]->Integer.Value)); | ||
|
|
||
| Fatal = ACPI_ALLOCATE(sizeof(ACPI_SIGNAL_FATAL_INFO)); | ||
| if (Fatal) { | ||
| Fatal->Type = (UINT32)Operand[0]->Integer.Value; | ||
| Fatal->Code = (UINT32)Operand[1]->Integer.Value; | ||
| Fatal->Argument = (UINT32)Operand[2]->Integer.Value; | ||
| } | ||
|
|
||
| /* Always signal the OS! */ | ||
|
|
||
| Status = AcpiOsSignal(ACPI_SIGNAL_FATAL, Fatal); | ||
|
|
||
| /* Might return while OS is shutting down, just continue */ | ||
|
|
||
| ACPI_FREE(Fatal); | ||
| goto Cleanup; | ||
|
|
||
| case AML_EXTERNAL_OP: | ||
| /* | ||
| * If the interpreter sees this opcode, just ignore it. The External | ||
| * op is intended for use by disassemblers in order to properly | ||
| * disassemble control method invocations. The opcode or group of | ||
| * opcodes should be surrounded by an "if (0)" clause to ensure that | ||
| * AML interpreters never see the opcode. Thus, something is | ||
| * wrong if an external opcode ever gets here. | ||
| */ | ||
| ACPI_ERROR((AE_INFO, "Executed External Op")); | ||
| Status = AE_OK; | ||
| goto Cleanup; | ||
|
|
||
| default: | ||
|
|
||
| ACPI_ERROR((AE_INFO, "Unknown AML opcode 0x%X", WalkState->Opcode)); | ||
|
|
||
| Status = AE_AML_BAD_OPCODE; | ||
| goto Cleanup; | ||
| } | ||
|
|
||
| Cleanup: | ||
|
|
||
| return_ACPI_STATUS(Status); | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiExOpcode_3A_1T_1R | ||
| * | ||
| * PARAMETERS: WalkState - Current walk state | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Execute Triadic operator (3 operands) | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiExOpcode_3A_1T_1R(ACPI_WALK_STATE *WalkState) | ||
| { | ||
| ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; | ||
| ACPI_OPERAND_OBJECT *ReturnDesc = NULL; | ||
| char *Buffer = NULL; | ||
| ACPI_STATUS Status = AE_OK; | ||
| UINT64 Index; | ||
| ACPI_SIZE Length; | ||
|
|
||
| ACPI_FUNCTION_TRACE_STR(ExOpcode_3A_1T_1R, AcpiPsGetOpcodeName(WalkState->Opcode)); | ||
|
|
||
| switch (WalkState->Opcode) { | ||
| case AML_MID_OP: /* Mid (Source[0], Index[1], Length[2], Result[3]) */ | ||
| /* | ||
| * Create the return object. The Source operand is guaranteed to be | ||
| * either a String or a Buffer, so just use its type. | ||
| */ | ||
| ReturnDesc = AcpiUtCreateInternalObject((Operand[0])->Common.Type); | ||
| if (!ReturnDesc) { | ||
| Status = AE_NO_MEMORY; | ||
| goto Cleanup; | ||
| } | ||
|
|
||
| /* Get the Integer values from the objects */ | ||
|
|
||
| Index = Operand[1]->Integer.Value; | ||
| Length = (ACPI_SIZE)Operand[2]->Integer.Value; | ||
|
|
||
| /* | ||
| * If the index is beyond the length of the String/Buffer, or if the | ||
| * requested length is zero, return a zero-length String/Buffer | ||
| */ | ||
| if (Index >= Operand[0]->String.Length) { | ||
| Length = 0; | ||
| } | ||
|
|
||
| /* Truncate request if larger than the actual String/Buffer */ | ||
|
|
||
| else if ((Index + Length) > Operand[0]->String.Length) { | ||
| Length = (ACPI_SIZE)Operand[0]->String.Length - (ACPI_SIZE)Index; | ||
| } | ||
|
|
||
| /* Strings always have a sub-pointer, not so for buffers */ | ||
|
|
||
| switch ((Operand[0])->Common.Type) { | ||
| case ACPI_TYPE_STRING: | ||
|
|
||
| /* Always allocate a new buffer for the String */ | ||
|
|
||
| Buffer = ACPI_ALLOCATE_ZEROED((ACPI_SIZE)Length + 1); | ||
| if (!Buffer) { | ||
| Status = AE_NO_MEMORY; | ||
| goto Cleanup; | ||
| } | ||
| break; | ||
|
|
||
| case ACPI_TYPE_BUFFER: | ||
|
|
||
| /* If the requested length is zero, don't allocate a buffer */ | ||
|
|
||
| if (Length > 0) { | ||
| /* Allocate a new buffer for the Buffer */ | ||
|
|
||
| Buffer = ACPI_ALLOCATE_ZEROED(Length); | ||
| if (!Buffer) { | ||
| Status = AE_NO_MEMORY; | ||
| goto Cleanup; | ||
| } | ||
| } | ||
| break; | ||
|
|
||
| default: /* Should not happen */ | ||
|
|
||
| Status = AE_AML_OPERAND_TYPE; | ||
| goto Cleanup; | ||
| } | ||
|
|
||
| if (Buffer) { | ||
| /* We have a buffer, copy the portion requested */ | ||
|
|
||
| memcpy(Buffer, Operand[0]->String.Pointer + Index, Length); | ||
| } | ||
|
|
||
| /* Set the length of the new String/Buffer */ | ||
|
|
||
| ReturnDesc->String.Pointer = Buffer; | ||
| ReturnDesc->String.Length = (UINT32)Length; | ||
|
|
||
| /* Mark buffer initialized */ | ||
|
|
||
| ReturnDesc->Buffer.Flags |= AOPOBJ_DATA_VALID; | ||
| break; | ||
|
|
||
| default: | ||
|
|
||
| ACPI_ERROR((AE_INFO, "Unknown AML opcode 0x%X", WalkState->Opcode)); | ||
|
|
||
| Status = AE_AML_BAD_OPCODE; | ||
| goto Cleanup; | ||
| } | ||
|
|
||
| /* Store the result in the target */ | ||
|
|
||
| Status = AcpiExStore(ReturnDesc, Operand[3], WalkState); | ||
|
|
||
| Cleanup: | ||
|
|
||
| /* Delete return object on error */ | ||
|
|
||
| if (ACPI_FAILURE(Status) || WalkState->ResultObj) { | ||
| AcpiUtRemoveReference(ReturnDesc); | ||
| WalkState->ResultObj = NULL; | ||
| } else { | ||
| /* Set the return object and exit */ | ||
|
|
||
| WalkState->ResultObj = ReturnDesc; | ||
| } | ||
|
|
||
| return_ACPI_STATUS(Status); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,321 @@ | ||
| /****************************************************************************** | ||
| * | ||
| * Module Name: exoparg6 - AML execution - opcodes with 6 arguments | ||
| * | ||
| *****************************************************************************/ | ||
|
|
||
| /* | ||
| * Copyright (C) 2000 - 2022, Intel Corp. | ||
| * All rights reserved. | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions, and the following disclaimer, | ||
| * without modification. | ||
| * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
| * substantially similar to the "NO WARRANTY" disclaimer below | ||
| * ("Disclaimer") and any redistribution must be conditioned upon | ||
| * including a substantially similar Disclaimer requirement for further | ||
| * binary redistribution. | ||
| * 3. Neither the names of the above-listed copyright holders nor the names | ||
| * of any contributors may be used to endorse or promote products derived | ||
| * from this software without specific prior written permission. | ||
| * | ||
| * Alternatively, this software may be distributed under the terms of the | ||
| * GNU General Public License ("GPL") version 2 as published by the Free | ||
| * Software Foundation. | ||
| * | ||
| * NO WARRANTY | ||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
| * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| * POSSIBILITY OF SUCH DAMAGES. | ||
| */ | ||
|
|
||
| #include "acpi.h" | ||
| #include "accommon.h" | ||
| #include "acinterp.h" | ||
| #include "acparser.h" | ||
| #include "amlcode.h" | ||
|
|
||
| #define _COMPONENT ACPI_EXECUTER | ||
| ACPI_MODULE_NAME("exoparg6") | ||
|
|
||
| /*! | ||
| * Naming convention for AML interpreter execution routines. | ||
| * | ||
| * The routines that begin execution of AML opcodes are named with a common | ||
| * convention based upon the number of arguments, the number of target operands, | ||
| * and whether or not a value is returned: | ||
| * | ||
| * AcpiExOpcode_xA_yT_zR | ||
| * | ||
| * Where: | ||
| * | ||
| * xA - ARGUMENTS: The number of arguments (input operands) that are | ||
| * required for this opcode type (1 through 6 args). | ||
| * yT - TARGETS: The number of targets (output operands) that are required | ||
| * for this opcode type (0, 1, or 2 targets). | ||
| * zR - RETURN VALUE: Indicates whether this opcode type returns a value | ||
| * as the function return (0 or 1). | ||
| * | ||
| * The AcpiExOpcode* functions are called via the Dispatcher component with | ||
| * fully resolved operands. | ||
| !*/ | ||
|
|
||
| /* Local prototypes */ | ||
|
|
||
| static BOOLEAN AcpiExDoMatch(UINT32 MatchOp, ACPI_OPERAND_OBJECT *PackageObj, | ||
| ACPI_OPERAND_OBJECT *MatchObj); | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiExDoMatch | ||
| * | ||
| * PARAMETERS: MatchOp - The AML match operand | ||
| * PackageObj - Object from the target package | ||
| * MatchObj - Object to be matched | ||
| * | ||
| * RETURN: TRUE if the match is successful, FALSE otherwise | ||
| * | ||
| * DESCRIPTION: Implements the low-level match for the ASL Match operator. | ||
| * Package elements will be implicitly converted to the type of | ||
| * the match object (Integer/Buffer/String). | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| static BOOLEAN AcpiExDoMatch(UINT32 MatchOp, ACPI_OPERAND_OBJECT *PackageObj, | ||
| ACPI_OPERAND_OBJECT *MatchObj) | ||
| { | ||
| BOOLEAN LogicalResult = TRUE; | ||
| ACPI_STATUS Status; | ||
|
|
||
| /* | ||
| * Note: Since the PackageObj/MatchObj ordering is opposite to that of | ||
| * the standard logical operators, we have to reverse them when we call | ||
| * DoLogicalOp in order to make the implicit conversion rules work | ||
| * correctly. However, this means we have to flip the entire equation | ||
| * also. A bit ugly perhaps, but overall, better than fussing the | ||
| * parameters around at runtime, over and over again. | ||
| * | ||
| * Below, P[i] refers to the package element, M refers to the Match object. | ||
| */ | ||
| switch (MatchOp) { | ||
| case MATCH_MTR: | ||
|
|
||
| /* Always true */ | ||
|
|
||
| break; | ||
|
|
||
| case MATCH_MEQ: | ||
| /* | ||
| * True if equal: (P[i] == M) | ||
| * Change to: (M == P[i]) | ||
| */ | ||
| Status = AcpiExDoLogicalOp(AML_LOGICAL_EQUAL_OP, MatchObj, PackageObj, | ||
| &LogicalResult); | ||
| if (ACPI_FAILURE(Status)) { | ||
| return (FALSE); | ||
| } | ||
| break; | ||
|
|
||
| case MATCH_MLE: | ||
| /* | ||
| * True if less than or equal: (P[i] <= M) (P[i] NotGreater than M) | ||
| * Change to: (M >= P[i]) (M NotLess than P[i]) | ||
| */ | ||
| Status = AcpiExDoLogicalOp(AML_LOGICAL_LESS_OP, MatchObj, PackageObj, | ||
| &LogicalResult); | ||
| if (ACPI_FAILURE(Status)) { | ||
| return (FALSE); | ||
| } | ||
| LogicalResult = (BOOLEAN)!LogicalResult; | ||
| break; | ||
|
|
||
| case MATCH_MLT: | ||
| /* | ||
| * True if less than: (P[i] < M) | ||
| * Change to: (M > P[i]) | ||
| */ | ||
| Status = AcpiExDoLogicalOp(AML_LOGICAL_GREATER_OP, MatchObj, PackageObj, | ||
| &LogicalResult); | ||
| if (ACPI_FAILURE(Status)) { | ||
| return (FALSE); | ||
| } | ||
| break; | ||
|
|
||
| case MATCH_MGE: | ||
| /* | ||
| * True if greater than or equal: (P[i] >= M) (P[i] NotLess than M) | ||
| * Change to: (M <= P[i]) (M NotGreater than P[i]) | ||
| */ | ||
| Status = AcpiExDoLogicalOp(AML_LOGICAL_GREATER_OP, MatchObj, PackageObj, | ||
| &LogicalResult); | ||
| if (ACPI_FAILURE(Status)) { | ||
| return (FALSE); | ||
| } | ||
| LogicalResult = (BOOLEAN)!LogicalResult; | ||
| break; | ||
|
|
||
| case MATCH_MGT: | ||
| /* | ||
| * True if greater than: (P[i] > M) | ||
| * Change to: (M < P[i]) | ||
| */ | ||
| Status = AcpiExDoLogicalOp(AML_LOGICAL_LESS_OP, MatchObj, PackageObj, | ||
| &LogicalResult); | ||
| if (ACPI_FAILURE(Status)) { | ||
| return (FALSE); | ||
| } | ||
| break; | ||
|
|
||
| default: | ||
|
|
||
| /* Undefined */ | ||
|
|
||
| return (FALSE); | ||
| } | ||
|
|
||
| return (LogicalResult); | ||
| } | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiExOpcode_6A_0T_1R | ||
| * | ||
| * PARAMETERS: WalkState - Current walk state | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Execute opcode with 6 arguments, no target, and a return value | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiExOpcode_6A_0T_1R(ACPI_WALK_STATE *WalkState) | ||
| { | ||
| ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; | ||
| ACPI_OPERAND_OBJECT *ReturnDesc = NULL; | ||
| ACPI_STATUS Status = AE_OK; | ||
| UINT64 Index; | ||
| ACPI_OPERAND_OBJECT *ThisElement; | ||
|
|
||
| ACPI_FUNCTION_TRACE_STR(ExOpcode_6A_0T_1R, AcpiPsGetOpcodeName(WalkState->Opcode)); | ||
|
|
||
| switch (WalkState->Opcode) { | ||
| case AML_MATCH_OP: | ||
| /* | ||
| * Match (SearchPkg[0], MatchOp1[1], MatchObj1[2], | ||
| * MatchOp2[3], MatchObj2[4], StartIndex[5]) | ||
| */ | ||
|
|
||
| /* Validate both Match Term Operators (MTR, MEQ, etc.) */ | ||
|
|
||
| if ((Operand[1]->Integer.Value > MAX_MATCH_OPERATOR) || | ||
| (Operand[3]->Integer.Value > MAX_MATCH_OPERATOR)) { | ||
| ACPI_ERROR((AE_INFO, "Match operator out of range")); | ||
| Status = AE_AML_OPERAND_VALUE; | ||
| goto Cleanup; | ||
| } | ||
|
|
||
| /* Get the package StartIndex, validate against the package length */ | ||
|
|
||
| Index = Operand[5]->Integer.Value; | ||
| if (Index >= Operand[0]->Package.Count) { | ||
| ACPI_ERROR((AE_INFO, "Index (0x%8.8X%8.8X) beyond package end (0x%X)", | ||
| ACPI_FORMAT_UINT64(Index), Operand[0]->Package.Count)); | ||
| Status = AE_AML_PACKAGE_LIMIT; | ||
| goto Cleanup; | ||
| } | ||
|
|
||
| /* Create an integer for the return value */ | ||
| /* Default return value is ACPI_UINT64_MAX if no match found */ | ||
|
|
||
| ReturnDesc = AcpiUtCreateIntegerObject(ACPI_UINT64_MAX); | ||
| if (!ReturnDesc) { | ||
| Status = AE_NO_MEMORY; | ||
| goto Cleanup; | ||
| } | ||
|
|
||
| /* | ||
| * Examine each element until a match is found. Both match conditions | ||
| * must be satisfied for a match to occur. Within the loop, | ||
| * "continue" signifies that the current element does not match | ||
| * and the next should be examined. | ||
| * | ||
| * Upon finding a match, the loop will terminate via "break" at | ||
| * the bottom. If it terminates "normally", MatchValue will be | ||
| * ACPI_UINT64_MAX (Ones) (its initial value) indicating that no | ||
| * match was found. | ||
| */ | ||
| for (; Index < Operand[0]->Package.Count; Index++) { | ||
| /* Get the current package element */ | ||
|
|
||
| ThisElement = Operand[0]->Package.Elements[Index]; | ||
|
|
||
| /* Treat any uninitialized (NULL) elements as non-matching */ | ||
|
|
||
| if (!ThisElement) { | ||
| continue; | ||
| } | ||
|
|
||
| /* | ||
| * Both match conditions must be satisfied. Execution of a continue | ||
| * (proceed to next iteration of enclosing for loop) signifies a | ||
| * non-match. | ||
| */ | ||
| if (!AcpiExDoMatch((UINT32)Operand[1]->Integer.Value, ThisElement, | ||
| Operand[2])) { | ||
| continue; | ||
| } | ||
|
|
||
| if (!AcpiExDoMatch((UINT32)Operand[3]->Integer.Value, ThisElement, | ||
| Operand[4])) { | ||
| continue; | ||
| } | ||
|
|
||
| /* Match found: Index is the return value */ | ||
|
|
||
| ReturnDesc->Integer.Value = Index; | ||
| break; | ||
| } | ||
| break; | ||
|
|
||
| case AML_LOAD_TABLE_OP: | ||
|
|
||
| Status = AcpiExLoadTableOp(WalkState, &ReturnDesc); | ||
| break; | ||
|
|
||
| default: | ||
|
|
||
| ACPI_ERROR((AE_INFO, "Unknown AML opcode 0x%X", WalkState->Opcode)); | ||
|
|
||
| Status = AE_AML_BAD_OPCODE; | ||
| goto Cleanup; | ||
| } | ||
|
|
||
| Cleanup: | ||
|
|
||
| /* Delete return object on error */ | ||
|
|
||
| if (ACPI_FAILURE(Status)) { | ||
| AcpiUtRemoveReference(ReturnDesc); | ||
| } | ||
|
|
||
| /* Save return object on success */ | ||
|
|
||
| else { | ||
| WalkState->ResultObj = ReturnDesc; | ||
| } | ||
|
|
||
| return_ACPI_STATUS(Status); | ||
| } |
Large diffs are not rendered by default.
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,268 @@ | ||
| /****************************************************************************** | ||
| * | ||
| * Module Name: exresnte - AML Interpreter object resolution | ||
| * | ||
| *****************************************************************************/ | ||
|
|
||
| /* | ||
| * Copyright (C) 2000 - 2022, Intel Corp. | ||
| * All rights reserved. | ||
| * | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions | ||
| * are met: | ||
| * 1. Redistributions of source code must retain the above copyright | ||
| * notice, this list of conditions, and the following disclaimer, | ||
| * without modification. | ||
| * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
| * substantially similar to the "NO WARRANTY" disclaimer below | ||
| * ("Disclaimer") and any redistribution must be conditioned upon | ||
| * including a substantially similar Disclaimer requirement for further | ||
| * binary redistribution. | ||
| * 3. Neither the names of the above-listed copyright holders nor the names | ||
| * of any contributors may be used to endorse or promote products derived | ||
| * from this software without specific prior written permission. | ||
| * | ||
| * Alternatively, this software may be distributed under the terms of the | ||
| * GNU General Public License ("GPL") version 2 as published by the Free | ||
| * Software Foundation. | ||
| * | ||
| * NO WARRANTY | ||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
| * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
| * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| * POSSIBILITY OF SUCH DAMAGES. | ||
| */ | ||
|
|
||
| #include "acpi.h" | ||
| #include "accommon.h" | ||
| #include "acdispat.h" | ||
| #include "acinterp.h" | ||
| #include "acnamesp.h" | ||
|
|
||
| #define _COMPONENT ACPI_EXECUTER | ||
| ACPI_MODULE_NAME("exresnte") | ||
|
|
||
| /******************************************************************************* | ||
| * | ||
| * FUNCTION: AcpiExResolveNodeToValue | ||
| * | ||
| * PARAMETERS: ObjectPtr - Pointer to a location that contains | ||
| * a pointer to a NS node, and will receive a | ||
| * pointer to the resolved object. | ||
| * WalkState - Current state. Valid only if executing AML | ||
| * code. NULL if simply resolving an object | ||
| * | ||
| * RETURN: Status | ||
| * | ||
| * DESCRIPTION: Resolve a Namespace node to a valued object | ||
| * | ||
| * Note: for some of the data types, the pointer attached to the Node | ||
| * can be either a pointer to an actual internal object or a pointer into the | ||
| * AML stream itself. These types are currently: | ||
| * | ||
| * ACPI_TYPE_INTEGER | ||
| * ACPI_TYPE_STRING | ||
| * ACPI_TYPE_BUFFER | ||
| * ACPI_TYPE_MUTEX | ||
| * ACPI_TYPE_PACKAGE | ||
| * | ||
| ******************************************************************************/ | ||
|
|
||
| ACPI_STATUS | ||
| AcpiExResolveNodeToValue(ACPI_NAMESPACE_NODE **ObjectPtr, ACPI_WALK_STATE *WalkState) | ||
|
|
||
| { | ||
| ACPI_STATUS Status = AE_OK; | ||
| ACPI_OPERAND_OBJECT *SourceDesc; | ||
| ACPI_OPERAND_OBJECT *ObjDesc = NULL; | ||
| ACPI_NAMESPACE_NODE *Node; | ||
| ACPI_OBJECT_TYPE EntryType; | ||
|
|
||
| ACPI_FUNCTION_TRACE(ExResolveNodeToValue); | ||
|
|
||
| /* | ||
| * The stack pointer points to a ACPI_NAMESPACE_NODE (Node). Get the | ||
| * object that is attached to the Node. | ||
| */ | ||
| Node = *ObjectPtr; | ||
| SourceDesc = AcpiNsGetAttachedObject(Node); | ||
| EntryType = AcpiNsGetType((ACPI_HANDLE)Node); | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Entry=%p SourceDesc=%p [%s]\n", Node, SourceDesc, | ||
| AcpiUtGetTypeName(EntryType))); | ||
|
|
||
| if ((EntryType == ACPI_TYPE_LOCAL_ALIAS) || | ||
| (EntryType == ACPI_TYPE_LOCAL_METHOD_ALIAS)) { | ||
| /* There is always exactly one level of indirection */ | ||
|
|
||
| Node = ACPI_CAST_PTR(ACPI_NAMESPACE_NODE, Node->Object); | ||
| SourceDesc = AcpiNsGetAttachedObject(Node); | ||
| EntryType = AcpiNsGetType((ACPI_HANDLE)Node); | ||
| *ObjectPtr = Node; | ||
| } | ||
|
|
||
| /* | ||
| * Several object types require no further processing: | ||
| * 1) Device/Thermal objects don't have a "real" subobject, return Node | ||
| * 2) Method locals and arguments have a pseudo-Node | ||
| * 3) 10/2007: Added method type to assist with Package construction. | ||
| */ | ||
| if ((EntryType == ACPI_TYPE_DEVICE) || (EntryType == ACPI_TYPE_THERMAL) || | ||
| (EntryType == ACPI_TYPE_METHOD) || | ||
| (Node->Flags & (ANOBJ_METHOD_ARG | ANOBJ_METHOD_LOCAL))) { | ||
| return_ACPI_STATUS(AE_OK); | ||
| } | ||
|
|
||
| if (!SourceDesc) { | ||
| ACPI_ERROR( | ||
| (AE_INFO, "No object attached to node [%4.4s] %p", Node->Name.Ascii, Node)); | ||
| return_ACPI_STATUS(AE_AML_UNINITIALIZED_NODE); | ||
| } | ||
|
|
||
| /* | ||
| * Action is based on the type of the Node, which indicates the type | ||
| * of the attached object or pointer | ||
| */ | ||
| switch (EntryType) { | ||
| case ACPI_TYPE_PACKAGE: | ||
|
|
||
| if (SourceDesc->Common.Type != ACPI_TYPE_PACKAGE) { | ||
| ACPI_ERROR((AE_INFO, "Object not a Package, type %s", | ||
| AcpiUtGetObjectTypeName(SourceDesc))); | ||
| return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | ||
| } | ||
|
|
||
| Status = AcpiDsGetPackageArguments(SourceDesc); | ||
| if (ACPI_SUCCESS(Status)) { | ||
| /* Return an additional reference to the object */ | ||
|
|
||
| ObjDesc = SourceDesc; | ||
| AcpiUtAddReference(ObjDesc); | ||
| } | ||
| break; | ||
|
|
||
| case ACPI_TYPE_BUFFER: | ||
|
|
||
| if (SourceDesc->Common.Type != ACPI_TYPE_BUFFER) { | ||
| ACPI_ERROR((AE_INFO, "Object not a Buffer, type %s", | ||
| AcpiUtGetObjectTypeName(SourceDesc))); | ||
| return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | ||
| } | ||
|
|
||
| Status = AcpiDsGetBufferArguments(SourceDesc); | ||
| if (ACPI_SUCCESS(Status)) { | ||
| /* Return an additional reference to the object */ | ||
|
|
||
| ObjDesc = SourceDesc; | ||
| AcpiUtAddReference(ObjDesc); | ||
| } | ||
| break; | ||
|
|
||
| case ACPI_TYPE_STRING: | ||
|
|
||
| if (SourceDesc->Common.Type != ACPI_TYPE_STRING) { | ||
| ACPI_ERROR((AE_INFO, "Object not a String, type %s", | ||
| AcpiUtGetObjectTypeName(SourceDesc))); | ||
| return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | ||
| } | ||
|
|
||
| /* Return an additional reference to the object */ | ||
|
|
||
| ObjDesc = SourceDesc; | ||
| AcpiUtAddReference(ObjDesc); | ||
| break; | ||
|
|
||
| case ACPI_TYPE_INTEGER: | ||
|
|
||
| if (SourceDesc->Common.Type != ACPI_TYPE_INTEGER) { | ||
| ACPI_ERROR((AE_INFO, "Object not a Integer, type %s", | ||
| AcpiUtGetObjectTypeName(SourceDesc))); | ||
| return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | ||
| } | ||
|
|
||
| /* Return an additional reference to the object */ | ||
|
|
||
| ObjDesc = SourceDesc; | ||
| AcpiUtAddReference(ObjDesc); | ||
| break; | ||
|
|
||
| case ACPI_TYPE_BUFFER_FIELD: | ||
| case ACPI_TYPE_LOCAL_REGION_FIELD: | ||
| case ACPI_TYPE_LOCAL_BANK_FIELD: | ||
| case ACPI_TYPE_LOCAL_INDEX_FIELD: | ||
|
|
||
| ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "FieldRead Node=%p SourceDesc=%p Type=%X\n", Node, | ||
| SourceDesc, EntryType)); | ||
|
|
||
| Status = AcpiExReadDataFromField(WalkState, SourceDesc, &ObjDesc); | ||
| break; | ||
|
|
||
| /* For these objects, just return the object attached to the Node */ | ||
|
|
||
| case ACPI_TYPE_MUTEX: | ||
| case ACPI_TYPE_POWER: | ||
| case ACPI_TYPE_PROCESSOR: | ||
| case ACPI_TYPE_EVENT: | ||
| case ACPI_TYPE_REGION: | ||
|
|
||
| /* Return an additional reference to the object */ | ||
|
|
||
| ObjDesc = SourceDesc; | ||
| AcpiUtAddReference(ObjDesc); | ||
| break; | ||
|
|
||
| /* TYPE_ANY is untyped, and thus there is no object associated with it */ | ||
|
|
||
| case ACPI_TYPE_ANY: | ||
|
|
||
| ACPI_ERROR((AE_INFO, "Untyped entry %p, no attached object!", Node)); | ||
|
|
||
| return_ACPI_STATUS(AE_AML_OPERAND_TYPE); /* Cannot be AE_TYPE */ | ||
|
|
||
| case ACPI_TYPE_LOCAL_REFERENCE: | ||
|
|
||
| switch (SourceDesc->Reference.Class) { | ||
| case ACPI_REFCLASS_TABLE: /* This is a DdbHandle */ | ||
| case ACPI_REFCLASS_REFOF: | ||
| case ACPI_REFCLASS_INDEX: | ||
|
|
||
| /* Return an additional reference to the object */ | ||
|
|
||
| ObjDesc = SourceDesc; | ||
| AcpiUtAddReference(ObjDesc); | ||
| break; | ||
|
|
||
| default: | ||
|
|
||
| /* No named references are allowed here */ | ||
|
|
||
| ACPI_ERROR((AE_INFO, "Unsupported Reference type 0x%X", | ||
| SourceDesc->Reference.Class)); | ||
|
|
||
| return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | ||
| } | ||
| break; | ||
|
|
||
| default: | ||
|
|
||
| /* Default case is for unknown types */ | ||
|
|
||
| ACPI_ERROR((AE_INFO, "Node %p - Unknown object type 0x%X", Node, EntryType)); | ||
|
|
||
| return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | ||
|
|
||
| } /* switch (EntryType) */ | ||
|
|
||
| /* Return the object descriptor */ | ||
|
|
||
| *ObjectPtr = (void *)ObjDesc; | ||
| return_ACPI_STATUS(Status); | ||
| } |
This file was deleted.
This file was deleted.
This file was deleted.