167754Smsmith/******************************************************************************
267754Smsmith *
367754Smsmith * Module Name: psxface - Parser external interfaces
467754Smsmith *
567754Smsmith *****************************************************************************/
667754Smsmith
7217365Sjkim/*
8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
970243Smsmith * All rights reserved.
1067754Smsmith *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
2567754Smsmith *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
2967754Smsmith *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
4367754Smsmith
44193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
45193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
46193341Sjkim#include <contrib/dev/acpica/include/acparser.h>
47193341Sjkim#include <contrib/dev/acpica/include/acdispat.h>
48193341Sjkim#include <contrib/dev/acpica/include/acinterp.h>
49206117Sjkim#include <contrib/dev/acpica/include/actables.h>
50306536Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
5167754Smsmith
5267754Smsmith
5377424Smsmith#define _COMPONENT          ACPI_PARSER
5491116Smsmith        ACPI_MODULE_NAME    ("psxface")
5567754Smsmith
56151937Sjkim/* Local Prototypes */
5767754Smsmith
58151937Sjkimstatic void
59151937SjkimAcpiPsUpdateParameterList (
60167802Sjkim    ACPI_EVALUATE_INFO      *Info,
61151937Sjkim    UINT16                  Action);
62151937Sjkim
63151937Sjkim
6480062Smsmith/*******************************************************************************
6567754Smsmith *
66151937Sjkim * FUNCTION:    AcpiDebugTrace
6767754Smsmith *
68151937Sjkim * PARAMETERS:  MethodName      - Valid ACPI name string
69151937Sjkim *              DebugLevel      - Optional level mask. 0 to use default
70151937Sjkim *              DebugLayer      - Optional layer mask. 0 to use default
71151937Sjkim *              Flags           - bit 1: one shot(1) or persistent(0)
7267754Smsmith *
7367754Smsmith * RETURN:      Status
7467754Smsmith *
75151937Sjkim * DESCRIPTION: External interface to enable debug tracing during control
76151937Sjkim *              method execution
7767754Smsmith *
7880062Smsmith ******************************************************************************/
7967754Smsmith
8067754SmsmithACPI_STATUS
81151937SjkimAcpiDebugTrace (
82306536Sjkim    const char              *Name,
83151937Sjkim    UINT32                  DebugLevel,
84151937Sjkim    UINT32                  DebugLayer,
85151937Sjkim    UINT32                  Flags)
86151937Sjkim{
87151937Sjkim    ACPI_STATUS             Status;
88151937Sjkim
89151937Sjkim
90151937Sjkim    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
91151937Sjkim    if (ACPI_FAILURE (Status))
92151937Sjkim    {
93151937Sjkim        return (Status);
94151937Sjkim    }
95151937Sjkim
96306536Sjkim    AcpiGbl_TraceMethodName = Name;
97151937Sjkim    AcpiGbl_TraceFlags = Flags;
98306536Sjkim    AcpiGbl_TraceDbgLevel = DebugLevel;
99306536Sjkim    AcpiGbl_TraceDbgLayer = DebugLayer;
100306536Sjkim    Status = AE_OK;
101151937Sjkim
102151937Sjkim    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
103306536Sjkim    return (Status);
104151937Sjkim}
105151937Sjkim
106151937Sjkim
107151937Sjkim/*******************************************************************************
108151937Sjkim *
109151937Sjkim * FUNCTION:    AcpiPsExecuteMethod
110151937Sjkim *
111151937Sjkim * PARAMETERS:  Info            - Method info block, contains:
112151937Sjkim *                  Node            - Method Node to execute
113151937Sjkim *                  ObjDesc         - Method object
114151937Sjkim *                  Parameters      - List of parameters to pass to the method,
115151937Sjkim *                                    terminated by NULL. Params itself may be
116151937Sjkim *                                    NULL if no parameters are being passed.
117151937Sjkim *                  ReturnObject    - Where to put method's return value (if
118151937Sjkim *                                    any). If NULL, no value is returned.
119151937Sjkim *                  ParameterType   - Type of Parameter list
120151937Sjkim *                  ReturnObject    - Where to put method's return value (if
121151937Sjkim *                                    any). If NULL, no value is returned.
122151937Sjkim *                  PassNumber      - Parse or execute pass
123151937Sjkim *
124151937Sjkim * RETURN:      Status
125151937Sjkim *
126151937Sjkim * DESCRIPTION: Execute a control method
127151937Sjkim *
128151937Sjkim ******************************************************************************/
129151937Sjkim
130151937SjkimACPI_STATUS
131151937SjkimAcpiPsExecuteMethod (
132167802Sjkim    ACPI_EVALUATE_INFO      *Info)
133151937Sjkim{
134151937Sjkim    ACPI_STATUS             Status;
135167802Sjkim    ACPI_PARSE_OBJECT       *Op;
136167802Sjkim    ACPI_WALK_STATE         *WalkState;
137151937Sjkim
138151937Sjkim
139167802Sjkim    ACPI_FUNCTION_TRACE (PsExecuteMethod);
140151937Sjkim
141151937Sjkim
142206117Sjkim    /* Quick validation of DSDT header */
143206117Sjkim
144206117Sjkim    AcpiTbCheckDsdtHeader ();
145206117Sjkim
146151937Sjkim    /* Validate the Info and method Node */
147151937Sjkim
148249663Sjkim    if (!Info || !Info->Node)
14984491Smsmith    {
150151937Sjkim        return_ACPI_STATUS (AE_NULL_ENTRY);
15184491Smsmith    }
15284491Smsmith
153151937Sjkim    /* Init for new method, wait on concurrency semaphore */
154151937Sjkim
155249663Sjkim    Status = AcpiDsBeginMethodExecution (Info->Node, Info->ObjDesc, NULL);
15684491Smsmith    if (ACPI_FAILURE (Status))
15784491Smsmith    {
158151937Sjkim        return_ACPI_STATUS (Status);
15984491Smsmith    }
16084491Smsmith
161151937Sjkim    /*
162167802Sjkim     * The caller "owns" the parameters, so give each one an extra reference
163151937Sjkim     */
164151937Sjkim    AcpiPsUpdateParameterList (Info, REF_INCREMENT);
16584491Smsmith
166151937Sjkim    /*
167167802Sjkim     * Execute the method. Performs parse simultaneously
168151937Sjkim     */
169151937Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
170167802Sjkim        "**** Begin Method Parse/Execute [%4.4s] **** Node=%p Obj=%p\n",
171249663Sjkim        Info->Node->Name.Ascii, Info->Node, Info->ObjDesc));
172151937Sjkim
173167802Sjkim    /* Create and init a Root Node */
174167802Sjkim
175306536Sjkim    Op = AcpiPsCreateScopeOp (Info->ObjDesc->Method.AmlStart);
176167802Sjkim    if (!Op)
177167802Sjkim    {
178167802Sjkim        Status = AE_NO_MEMORY;
179167802Sjkim        goto Cleanup;
180167802Sjkim    }
181167802Sjkim
182167802Sjkim    /* Create and initialize a new walk state */
183167802Sjkim
184167802Sjkim    Info->PassNumber = ACPI_IMODE_EXECUTE;
185167802Sjkim    WalkState = AcpiDsCreateWalkState (
186306536Sjkim        Info->ObjDesc->Method.OwnerId, NULL, NULL, NULL);
187167802Sjkim    if (!WalkState)
188167802Sjkim    {
189167802Sjkim        Status = AE_NO_MEMORY;
190167802Sjkim        goto Cleanup;
191167802Sjkim    }
192167802Sjkim
193249663Sjkim    Status = AcpiDsInitAmlWalk (WalkState, Op, Info->Node,
194306536Sjkim        Info->ObjDesc->Method.AmlStart,
195306536Sjkim        Info->ObjDesc->Method.AmlLength, Info, Info->PassNumber);
196123315Snjl    if (ACPI_FAILURE (Status))
197123315Snjl    {
198167802Sjkim        AcpiDsDeleteWalkState (WalkState);
199151937Sjkim        goto Cleanup;
200123315Snjl    }
201123315Snjl
202217365Sjkim    if (Info->ObjDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL)
203197104Sjkim    {
204197104Sjkim        WalkState->ParseFlags |= ACPI_PARSE_MODULE_LEVEL;
205197104Sjkim    }
206197104Sjkim
207193267Sjkim    /* Invoke an internal method if necessary */
208193267Sjkim
209217365Sjkim    if (Info->ObjDesc->Method.InfoFlags & ACPI_METHOD_INTERNAL_ONLY)
210193267Sjkim    {
211217365Sjkim        Status = Info->ObjDesc->Method.Dispatch.Implementation (WalkState);
212193267Sjkim        Info->ReturnObject = WalkState->ReturnDesc;
213193267Sjkim
214193267Sjkim        /* Cleanup states */
215193267Sjkim
216193267Sjkim        AcpiDsScopeStackClear (WalkState);
217193267Sjkim        AcpiPsCleanupScope (&WalkState->ParserState);
218193267Sjkim        AcpiDsTerminateControlMethod (WalkState->MethodDesc, WalkState);
219193267Sjkim        AcpiDsDeleteWalkState (WalkState);
220193267Sjkim        goto Cleanup;
221193267Sjkim    }
222193267Sjkim
223193267Sjkim    /*
224238381Sjkim     * Start method evaluation with an implicit return of zero.
225238381Sjkim     * This is done for Windows compatibility.
226193267Sjkim     */
227193267Sjkim    if (AcpiGbl_EnableInterpreterSlack)
228193267Sjkim    {
229193267Sjkim        WalkState->ImplicitReturnObj =
230199337Sjkim            AcpiUtCreateIntegerObject ((UINT64) 0);
231193267Sjkim        if (!WalkState->ImplicitReturnObj)
232193267Sjkim        {
233193267Sjkim            Status = AE_NO_MEMORY;
234193267Sjkim            AcpiDsDeleteWalkState (WalkState);
235193267Sjkim            goto Cleanup;
236193267Sjkim        }
237193267Sjkim    }
238193267Sjkim
239167802Sjkim    /* Parse the AML */
24084491Smsmith
241167802Sjkim    Status = AcpiPsParseAml (WalkState);
24267754Smsmith
243167802Sjkim    /* WalkState was deleted by ParseAml */
24467754Smsmith
245151937SjkimCleanup:
246167802Sjkim    AcpiPsDeleteParseTree (Op);
247167802Sjkim
248151937Sjkim    /* Take away the extra reference that we gave the parameters above */
24984491Smsmith
250151937Sjkim    AcpiPsUpdateParameterList (Info, REF_DECREMENT);
25184491Smsmith
252151937Sjkim    /* Exit now if error above */
253151937Sjkim
25484491Smsmith    if (ACPI_FAILURE (Status))
25584491Smsmith    {
256151937Sjkim        return_ACPI_STATUS (Status);
25784491Smsmith    }
25884491Smsmith
25967754Smsmith    /*
260151937Sjkim     * If the method has returned an object, signal this to the caller with
261151937Sjkim     * a control exception code
26267754Smsmith     */
263151937Sjkim    if (Info->ReturnObject)
264151937Sjkim    {
265151937Sjkim        ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Method returned ObjDesc=%p\n",
266151937Sjkim            Info->ReturnObject));
267151937Sjkim        ACPI_DUMP_STACK_ENTRY (Info->ReturnObject);
268123315Snjl
269151937Sjkim        Status = AE_CTRL_RETURN_VALUE;
270151937Sjkim    }
271123315Snjl
272151937Sjkim    return_ACPI_STATUS (Status);
273151937Sjkim}
274123315Snjl
27567754Smsmith
276151937Sjkim/*******************************************************************************
277151937Sjkim *
278151937Sjkim * FUNCTION:    AcpiPsUpdateParameterList
279151937Sjkim *
280167802Sjkim * PARAMETERS:  Info            - See ACPI_EVALUATE_INFO
281151937Sjkim *                                (Used: ParameterType and Parameters)
282151937Sjkim *              Action          - Add or Remove reference
283151937Sjkim *
284151937Sjkim * RETURN:      Status
285151937Sjkim *
286151937Sjkim * DESCRIPTION: Update reference count on all method parameter objects
287151937Sjkim *
288151937Sjkim ******************************************************************************/
289151937Sjkim
290151937Sjkimstatic void
291151937SjkimAcpiPsUpdateParameterList (
292167802Sjkim    ACPI_EVALUATE_INFO      *Info,
293151937Sjkim    UINT16                  Action)
294151937Sjkim{
295193267Sjkim    UINT32                  i;
296151937Sjkim
297151937Sjkim
298193267Sjkim    if (Info->Parameters)
29967754Smsmith    {
300151937Sjkim        /* Update reference count for each parameter */
30167754Smsmith
302129684Snjl        for (i = 0; Info->Parameters[i]; i++)
30367754Smsmith        {
30499679Siwasaki            /* Ignore errors, just do them all */
30599679Siwasaki
306306536Sjkim            (void) AcpiUtUpdateObjectReference (
307306536Sjkim                Info->Parameters[i], Action);
30867754Smsmith        }
30967754Smsmith    }
310151937Sjkim}
311