xref: /onnv-gate/usr/src/uts/intel/io/acpica/executer/exmisc.c (revision 7851:e828bbb1689c)
1*7851SDana.Myers@Sun.COM 
2*7851SDana.Myers@Sun.COM /******************************************************************************
3*7851SDana.Myers@Sun.COM  *
4*7851SDana.Myers@Sun.COM  * Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes
5*7851SDana.Myers@Sun.COM  *              $Revision: 1.145 $
6*7851SDana.Myers@Sun.COM  *
7*7851SDana.Myers@Sun.COM  *****************************************************************************/
8*7851SDana.Myers@Sun.COM 
9*7851SDana.Myers@Sun.COM /******************************************************************************
10*7851SDana.Myers@Sun.COM  *
11*7851SDana.Myers@Sun.COM  * 1. Copyright Notice
12*7851SDana.Myers@Sun.COM  *
13*7851SDana.Myers@Sun.COM  * Some or all of this work - Copyright (c) 1999 - 2008, Intel Corp.
14*7851SDana.Myers@Sun.COM  * All rights reserved.
15*7851SDana.Myers@Sun.COM  *
16*7851SDana.Myers@Sun.COM  * 2. License
17*7851SDana.Myers@Sun.COM  *
18*7851SDana.Myers@Sun.COM  * 2.1. This is your license from Intel Corp. under its intellectual property
19*7851SDana.Myers@Sun.COM  * rights.  You may have additional license terms from the party that provided
20*7851SDana.Myers@Sun.COM  * you this software, covering your right to use that party's intellectual
21*7851SDana.Myers@Sun.COM  * property rights.
22*7851SDana.Myers@Sun.COM  *
23*7851SDana.Myers@Sun.COM  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24*7851SDana.Myers@Sun.COM  * copy of the source code appearing in this file ("Covered Code") an
25*7851SDana.Myers@Sun.COM  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26*7851SDana.Myers@Sun.COM  * base code distributed originally by Intel ("Original Intel Code") to copy,
27*7851SDana.Myers@Sun.COM  * make derivatives, distribute, use and display any portion of the Covered
28*7851SDana.Myers@Sun.COM  * Code in any form, with the right to sublicense such rights; and
29*7851SDana.Myers@Sun.COM  *
30*7851SDana.Myers@Sun.COM  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31*7851SDana.Myers@Sun.COM  * license (with the right to sublicense), under only those claims of Intel
32*7851SDana.Myers@Sun.COM  * patents that are infringed by the Original Intel Code, to make, use, sell,
33*7851SDana.Myers@Sun.COM  * offer to sell, and import the Covered Code and derivative works thereof
34*7851SDana.Myers@Sun.COM  * solely to the minimum extent necessary to exercise the above copyright
35*7851SDana.Myers@Sun.COM  * license, and in no event shall the patent license extend to any additions
36*7851SDana.Myers@Sun.COM  * to or modifications of the Original Intel Code.  No other license or right
37*7851SDana.Myers@Sun.COM  * is granted directly or by implication, estoppel or otherwise;
38*7851SDana.Myers@Sun.COM  *
39*7851SDana.Myers@Sun.COM  * The above copyright and patent license is granted only if the following
40*7851SDana.Myers@Sun.COM  * conditions are met:
41*7851SDana.Myers@Sun.COM  *
42*7851SDana.Myers@Sun.COM  * 3. Conditions
43*7851SDana.Myers@Sun.COM  *
44*7851SDana.Myers@Sun.COM  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45*7851SDana.Myers@Sun.COM  * Redistribution of source code of any substantial portion of the Covered
46*7851SDana.Myers@Sun.COM  * Code or modification with rights to further distribute source must include
47*7851SDana.Myers@Sun.COM  * the above Copyright Notice, the above License, this list of Conditions,
48*7851SDana.Myers@Sun.COM  * and the following Disclaimer and Export Compliance provision.  In addition,
49*7851SDana.Myers@Sun.COM  * Licensee must cause all Covered Code to which Licensee contributes to
50*7851SDana.Myers@Sun.COM  * contain a file documenting the changes Licensee made to create that Covered
51*7851SDana.Myers@Sun.COM  * Code and the date of any change.  Licensee must include in that file the
52*7851SDana.Myers@Sun.COM  * documentation of any changes made by any predecessor Licensee.  Licensee
53*7851SDana.Myers@Sun.COM  * must include a prominent statement that the modification is derived,
54*7851SDana.Myers@Sun.COM  * directly or indirectly, from Original Intel Code.
55*7851SDana.Myers@Sun.COM  *
56*7851SDana.Myers@Sun.COM  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57*7851SDana.Myers@Sun.COM  * Redistribution of source code of any substantial portion of the Covered
58*7851SDana.Myers@Sun.COM  * Code or modification without rights to further distribute source must
59*7851SDana.Myers@Sun.COM  * include the following Disclaimer and Export Compliance provision in the
60*7851SDana.Myers@Sun.COM  * documentation and/or other materials provided with distribution.  In
61*7851SDana.Myers@Sun.COM  * addition, Licensee may not authorize further sublicense of source of any
62*7851SDana.Myers@Sun.COM  * portion of the Covered Code, and must include terms to the effect that the
63*7851SDana.Myers@Sun.COM  * license from Licensee to its licensee is limited to the intellectual
64*7851SDana.Myers@Sun.COM  * property embodied in the software Licensee provides to its licensee, and
65*7851SDana.Myers@Sun.COM  * not to intellectual property embodied in modifications its licensee may
66*7851SDana.Myers@Sun.COM  * make.
67*7851SDana.Myers@Sun.COM  *
68*7851SDana.Myers@Sun.COM  * 3.3. Redistribution of Executable. Redistribution in executable form of any
69*7851SDana.Myers@Sun.COM  * substantial portion of the Covered Code or modification must reproduce the
70*7851SDana.Myers@Sun.COM  * above Copyright Notice, and the following Disclaimer and Export Compliance
71*7851SDana.Myers@Sun.COM  * provision in the documentation and/or other materials provided with the
72*7851SDana.Myers@Sun.COM  * distribution.
73*7851SDana.Myers@Sun.COM  *
74*7851SDana.Myers@Sun.COM  * 3.4. Intel retains all right, title, and interest in and to the Original
75*7851SDana.Myers@Sun.COM  * Intel Code.
76*7851SDana.Myers@Sun.COM  *
77*7851SDana.Myers@Sun.COM  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78*7851SDana.Myers@Sun.COM  * Intel shall be used in advertising or otherwise to promote the sale, use or
79*7851SDana.Myers@Sun.COM  * other dealings in products derived from or relating to the Covered Code
80*7851SDana.Myers@Sun.COM  * without prior written authorization from Intel.
81*7851SDana.Myers@Sun.COM  *
82*7851SDana.Myers@Sun.COM  * 4. Disclaimer and Export Compliance
83*7851SDana.Myers@Sun.COM  *
84*7851SDana.Myers@Sun.COM  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85*7851SDana.Myers@Sun.COM  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86*7851SDana.Myers@Sun.COM  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
87*7851SDana.Myers@Sun.COM  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
88*7851SDana.Myers@Sun.COM 
89*7851SDana.Myers@Sun.COM  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
90*7851SDana.Myers@Sun.COM  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
91*7851SDana.Myers@Sun.COM  * PARTICULAR PURPOSE.
92*7851SDana.Myers@Sun.COM  *
93*7851SDana.Myers@Sun.COM  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
94*7851SDana.Myers@Sun.COM  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
95*7851SDana.Myers@Sun.COM  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
96*7851SDana.Myers@Sun.COM  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
97*7851SDana.Myers@Sun.COM  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
98*7851SDana.Myers@Sun.COM  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
99*7851SDana.Myers@Sun.COM  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
100*7851SDana.Myers@Sun.COM  * LIMITED REMEDY.
101*7851SDana.Myers@Sun.COM  *
102*7851SDana.Myers@Sun.COM  * 4.3. Licensee shall not export, either directly or indirectly, any of this
103*7851SDana.Myers@Sun.COM  * software or system incorporating such software without first obtaining any
104*7851SDana.Myers@Sun.COM  * required license or other approval from the U. S. Department of Commerce or
105*7851SDana.Myers@Sun.COM  * any other agency or department of the United States Government.  In the
106*7851SDana.Myers@Sun.COM  * event Licensee exports any such software from the United States or
107*7851SDana.Myers@Sun.COM  * re-exports any such software from a foreign destination, Licensee shall
108*7851SDana.Myers@Sun.COM  * ensure that the distribution and export/re-export of the software is in
109*7851SDana.Myers@Sun.COM  * compliance with all laws, regulations, orders, or other restrictions of the
110*7851SDana.Myers@Sun.COM  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
111*7851SDana.Myers@Sun.COM  * any of its subsidiaries will export/re-export any technical data, process,
112*7851SDana.Myers@Sun.COM  * software, or service, directly or indirectly, to any country for which the
113*7851SDana.Myers@Sun.COM  * United States government or any agency thereof requires an export license,
114*7851SDana.Myers@Sun.COM  * other governmental approval, or letter of assurance, without first obtaining
115*7851SDana.Myers@Sun.COM  * such license, approval or letter.
116*7851SDana.Myers@Sun.COM  *
117*7851SDana.Myers@Sun.COM  *****************************************************************************/
118*7851SDana.Myers@Sun.COM 
119*7851SDana.Myers@Sun.COM #define __EXMISC_C__
120*7851SDana.Myers@Sun.COM 
121*7851SDana.Myers@Sun.COM #include "acpi.h"
122*7851SDana.Myers@Sun.COM #include "acinterp.h"
123*7851SDana.Myers@Sun.COM #include "amlcode.h"
124*7851SDana.Myers@Sun.COM #include "amlresrc.h"
125*7851SDana.Myers@Sun.COM 
126*7851SDana.Myers@Sun.COM 
127*7851SDana.Myers@Sun.COM #define _COMPONENT          ACPI_EXECUTER
128*7851SDana.Myers@Sun.COM         ACPI_MODULE_NAME    ("exmisc")
129*7851SDana.Myers@Sun.COM 
130*7851SDana.Myers@Sun.COM 
131*7851SDana.Myers@Sun.COM /*******************************************************************************
132*7851SDana.Myers@Sun.COM  *
133*7851SDana.Myers@Sun.COM  * FUNCTION:    AcpiExGetObjectReference
134*7851SDana.Myers@Sun.COM  *
135*7851SDana.Myers@Sun.COM  * PARAMETERS:  ObjDesc             - Create a reference to this object
136*7851SDana.Myers@Sun.COM  *              ReturnDesc          - Where to store the reference
137*7851SDana.Myers@Sun.COM  *              WalkState           - Current state
138*7851SDana.Myers@Sun.COM  *
139*7851SDana.Myers@Sun.COM  * RETURN:      Status
140*7851SDana.Myers@Sun.COM  *
141*7851SDana.Myers@Sun.COM  * DESCRIPTION: Obtain and return a "reference" to the target object
142*7851SDana.Myers@Sun.COM  *              Common code for the RefOfOp and the CondRefOfOp.
143*7851SDana.Myers@Sun.COM  *
144*7851SDana.Myers@Sun.COM  ******************************************************************************/
145*7851SDana.Myers@Sun.COM 
146*7851SDana.Myers@Sun.COM ACPI_STATUS
147*7851SDana.Myers@Sun.COM AcpiExGetObjectReference (
148*7851SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT     *ObjDesc,
149*7851SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT     **ReturnDesc,
150*7851SDana.Myers@Sun.COM     ACPI_WALK_STATE         *WalkState)
151*7851SDana.Myers@Sun.COM {
152*7851SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT     *ReferenceObj;
153*7851SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT     *ReferencedObj;
154*7851SDana.Myers@Sun.COM 
155*7851SDana.Myers@Sun.COM 
156*7851SDana.Myers@Sun.COM     ACPI_FUNCTION_TRACE_PTR (ExGetObjectReference, ObjDesc);
157*7851SDana.Myers@Sun.COM 
158*7851SDana.Myers@Sun.COM 
159*7851SDana.Myers@Sun.COM     *ReturnDesc = NULL;
160*7851SDana.Myers@Sun.COM 
161*7851SDana.Myers@Sun.COM     switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))
162*7851SDana.Myers@Sun.COM     {
163*7851SDana.Myers@Sun.COM     case ACPI_DESC_TYPE_OPERAND:
164*7851SDana.Myers@Sun.COM 
165*7851SDana.Myers@Sun.COM         if (ACPI_GET_OBJECT_TYPE (ObjDesc) != ACPI_TYPE_LOCAL_REFERENCE)
166*7851SDana.Myers@Sun.COM         {
167*7851SDana.Myers@Sun.COM             return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
168*7851SDana.Myers@Sun.COM         }
169*7851SDana.Myers@Sun.COM 
170*7851SDana.Myers@Sun.COM         /*
171*7851SDana.Myers@Sun.COM          * Must be a reference to a Local or Arg
172*7851SDana.Myers@Sun.COM          */
173*7851SDana.Myers@Sun.COM         switch (ObjDesc->Reference.Class)
174*7851SDana.Myers@Sun.COM         {
175*7851SDana.Myers@Sun.COM         case ACPI_REFCLASS_LOCAL:
176*7851SDana.Myers@Sun.COM         case ACPI_REFCLASS_ARG:
177*7851SDana.Myers@Sun.COM         case ACPI_REFCLASS_DEBUG:
178*7851SDana.Myers@Sun.COM 
179*7851SDana.Myers@Sun.COM             /* The referenced object is the pseudo-node for the local/arg */
180*7851SDana.Myers@Sun.COM 
181*7851SDana.Myers@Sun.COM             ReferencedObj = ObjDesc->Reference.Object;
182*7851SDana.Myers@Sun.COM             break;
183*7851SDana.Myers@Sun.COM 
184*7851SDana.Myers@Sun.COM         default:
185*7851SDana.Myers@Sun.COM 
186*7851SDana.Myers@Sun.COM             ACPI_ERROR ((AE_INFO, "Unknown Reference Class %2.2X",
187*7851SDana.Myers@Sun.COM                 ObjDesc->Reference.Class));
188*7851SDana.Myers@Sun.COM             return_ACPI_STATUS (AE_AML_INTERNAL);
189*7851SDana.Myers@Sun.COM         }
190*7851SDana.Myers@Sun.COM         break;
191*7851SDana.Myers@Sun.COM 
192*7851SDana.Myers@Sun.COM 
193*7851SDana.Myers@Sun.COM     case ACPI_DESC_TYPE_NAMED:
194*7851SDana.Myers@Sun.COM 
195*7851SDana.Myers@Sun.COM         /*
196*7851SDana.Myers@Sun.COM          * A named reference that has already been resolved to a Node
197*7851SDana.Myers@Sun.COM          */
198*7851SDana.Myers@Sun.COM         ReferencedObj = ObjDesc;
199*7851SDana.Myers@Sun.COM         break;
200*7851SDana.Myers@Sun.COM 
201*7851SDana.Myers@Sun.COM 
202*7851SDana.Myers@Sun.COM     default:
203*7851SDana.Myers@Sun.COM 
204*7851SDana.Myers@Sun.COM         ACPI_ERROR ((AE_INFO, "Invalid descriptor type %X",
205*7851SDana.Myers@Sun.COM             ACPI_GET_DESCRIPTOR_TYPE (ObjDesc)));
206*7851SDana.Myers@Sun.COM         return_ACPI_STATUS (AE_TYPE);
207*7851SDana.Myers@Sun.COM     }
208*7851SDana.Myers@Sun.COM 
209*7851SDana.Myers@Sun.COM 
210*7851SDana.Myers@Sun.COM     /* Create a new reference object */
211*7851SDana.Myers@Sun.COM 
212*7851SDana.Myers@Sun.COM     ReferenceObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_REFERENCE);
213*7851SDana.Myers@Sun.COM     if (!ReferenceObj)
214*7851SDana.Myers@Sun.COM     {
215*7851SDana.Myers@Sun.COM         return_ACPI_STATUS (AE_NO_MEMORY);
216*7851SDana.Myers@Sun.COM     }
217*7851SDana.Myers@Sun.COM 
218*7851SDana.Myers@Sun.COM     ReferenceObj->Reference.Class = ACPI_REFCLASS_REFOF;
219*7851SDana.Myers@Sun.COM     ReferenceObj->Reference.Object = ReferencedObj;
220*7851SDana.Myers@Sun.COM     *ReturnDesc = ReferenceObj;
221*7851SDana.Myers@Sun.COM 
222*7851SDana.Myers@Sun.COM     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
223*7851SDana.Myers@Sun.COM         "Object %p Type [%s], returning Reference %p\n",
224*7851SDana.Myers@Sun.COM         ObjDesc, AcpiUtGetObjectTypeName (ObjDesc), *ReturnDesc));
225*7851SDana.Myers@Sun.COM 
226*7851SDana.Myers@Sun.COM     return_ACPI_STATUS (AE_OK);
227*7851SDana.Myers@Sun.COM }
228*7851SDana.Myers@Sun.COM 
229*7851SDana.Myers@Sun.COM 
230*7851SDana.Myers@Sun.COM /*******************************************************************************
231*7851SDana.Myers@Sun.COM  *
232*7851SDana.Myers@Sun.COM  * FUNCTION:    AcpiExConcatTemplate
233*7851SDana.Myers@Sun.COM  *
234*7851SDana.Myers@Sun.COM  * PARAMETERS:  Operand0            - First source object
235*7851SDana.Myers@Sun.COM  *              Operand1            - Second source object
236*7851SDana.Myers@Sun.COM  *              ActualReturnDesc    - Where to place the return object
237*7851SDana.Myers@Sun.COM  *              WalkState           - Current walk state
238*7851SDana.Myers@Sun.COM  *
239*7851SDana.Myers@Sun.COM  * RETURN:      Status
240*7851SDana.Myers@Sun.COM  *
241*7851SDana.Myers@Sun.COM  * DESCRIPTION: Concatenate two resource templates
242*7851SDana.Myers@Sun.COM  *
243*7851SDana.Myers@Sun.COM  ******************************************************************************/
244*7851SDana.Myers@Sun.COM 
245*7851SDana.Myers@Sun.COM ACPI_STATUS
246*7851SDana.Myers@Sun.COM AcpiExConcatTemplate (
247*7851SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT     *Operand0,
248*7851SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT     *Operand1,
249*7851SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT     **ActualReturnDesc,
250*7851SDana.Myers@Sun.COM     ACPI_WALK_STATE         *WalkState)
251*7851SDana.Myers@Sun.COM {
252*7851SDana.Myers@Sun.COM     ACPI_STATUS             Status;
253*7851SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT     *ReturnDesc;
254*7851SDana.Myers@Sun.COM     UINT8                   *NewBuf;
255*7851SDana.Myers@Sun.COM     UINT8                   *EndTag;
256*7851SDana.Myers@Sun.COM     ACPI_SIZE               Length0;
257*7851SDana.Myers@Sun.COM     ACPI_SIZE               Length1;
258*7851SDana.Myers@Sun.COM     ACPI_SIZE               NewLength;
259*7851SDana.Myers@Sun.COM 
260*7851SDana.Myers@Sun.COM 
261*7851SDana.Myers@Sun.COM     ACPI_FUNCTION_TRACE (ExConcatTemplate);
262*7851SDana.Myers@Sun.COM 
263*7851SDana.Myers@Sun.COM 
264*7851SDana.Myers@Sun.COM     /*
265*7851SDana.Myers@Sun.COM      * Find the EndTag descriptor in each resource template.
266*7851SDana.Myers@Sun.COM      * Note1: returned pointers point TO the EndTag, not past it.
267*7851SDana.Myers@Sun.COM      * Note2: zero-length buffers are allowed; treated like one EndTag
268*7851SDana.Myers@Sun.COM      */
269*7851SDana.Myers@Sun.COM 
270*7851SDana.Myers@Sun.COM     /* Get the length of the first resource template */
271*7851SDana.Myers@Sun.COM 
272*7851SDana.Myers@Sun.COM     Status = AcpiUtGetResourceEndTag (Operand0, &EndTag);
273*7851SDana.Myers@Sun.COM     if (ACPI_FAILURE (Status))
274*7851SDana.Myers@Sun.COM     {
275*7851SDana.Myers@Sun.COM         return_ACPI_STATUS (Status);
276*7851SDana.Myers@Sun.COM     }
277*7851SDana.Myers@Sun.COM 
278*7851SDana.Myers@Sun.COM     Length0 = ACPI_PTR_DIFF (EndTag, Operand0->Buffer.Pointer);
279*7851SDana.Myers@Sun.COM 
280*7851SDana.Myers@Sun.COM     /* Get the length of the second resource template */
281*7851SDana.Myers@Sun.COM 
282*7851SDana.Myers@Sun.COM     Status = AcpiUtGetResourceEndTag (Operand1, &EndTag);
283*7851SDana.Myers@Sun.COM     if (ACPI_FAILURE (Status))
284*7851SDana.Myers@Sun.COM     {
285*7851SDana.Myers@Sun.COM         return_ACPI_STATUS (Status);
286*7851SDana.Myers@Sun.COM     }
287*7851SDana.Myers@Sun.COM 
288*7851SDana.Myers@Sun.COM     Length1 = ACPI_PTR_DIFF (EndTag, Operand1->Buffer.Pointer);
289*7851SDana.Myers@Sun.COM 
290*7851SDana.Myers@Sun.COM     /* Combine both lengths, minimum size will be 2 for EndTag */
291*7851SDana.Myers@Sun.COM 
292*7851SDana.Myers@Sun.COM     NewLength = Length0 + Length1 + sizeof (AML_RESOURCE_END_TAG);
293*7851SDana.Myers@Sun.COM 
294*7851SDana.Myers@Sun.COM     /* Create a new buffer object for the result (with one EndTag) */
295*7851SDana.Myers@Sun.COM 
296*7851SDana.Myers@Sun.COM     ReturnDesc = AcpiUtCreateBufferObject (NewLength);
297*7851SDana.Myers@Sun.COM     if (!ReturnDesc)
298*7851SDana.Myers@Sun.COM     {
299*7851SDana.Myers@Sun.COM         return_ACPI_STATUS (AE_NO_MEMORY);
300*7851SDana.Myers@Sun.COM     }
301*7851SDana.Myers@Sun.COM 
302*7851SDana.Myers@Sun.COM     /*
303*7851SDana.Myers@Sun.COM      * Copy the templates to the new buffer, 0 first, then 1 follows. One
304*7851SDana.Myers@Sun.COM      * EndTag descriptor is copied from Operand1.
305*7851SDana.Myers@Sun.COM      */
306*7851SDana.Myers@Sun.COM     NewBuf = ReturnDesc->Buffer.Pointer;
307*7851SDana.Myers@Sun.COM     ACPI_MEMCPY (NewBuf, Operand0->Buffer.Pointer, Length0);
308*7851SDana.Myers@Sun.COM     ACPI_MEMCPY (NewBuf + Length0, Operand1->Buffer.Pointer, Length1);
309*7851SDana.Myers@Sun.COM 
310*7851SDana.Myers@Sun.COM     /* Insert EndTag and set the checksum to zero, means "ignore checksum" */
311*7851SDana.Myers@Sun.COM 
312*7851SDana.Myers@Sun.COM     NewBuf[NewLength - 1] = 0;
313*7851SDana.Myers@Sun.COM     NewBuf[NewLength - 2] = ACPI_RESOURCE_NAME_END_TAG | 1;
314*7851SDana.Myers@Sun.COM 
315*7851SDana.Myers@Sun.COM     /* Return the completed resource template */
316*7851SDana.Myers@Sun.COM 
317*7851SDana.Myers@Sun.COM     *ActualReturnDesc = ReturnDesc;
318*7851SDana.Myers@Sun.COM     return_ACPI_STATUS (AE_OK);
319*7851SDana.Myers@Sun.COM }
320*7851SDana.Myers@Sun.COM 
321*7851SDana.Myers@Sun.COM 
322*7851SDana.Myers@Sun.COM /*******************************************************************************
323*7851SDana.Myers@Sun.COM  *
324*7851SDana.Myers@Sun.COM  * FUNCTION:    AcpiExDoConcatenate
325*7851SDana.Myers@Sun.COM  *
326*7851SDana.Myers@Sun.COM  * PARAMETERS:  Operand0            - First source object
327*7851SDana.Myers@Sun.COM  *              Operand1            - Second source object
328*7851SDana.Myers@Sun.COM  *              ActualReturnDesc    - Where to place the return object
329*7851SDana.Myers@Sun.COM  *              WalkState           - Current walk state
330*7851SDana.Myers@Sun.COM  *
331*7851SDana.Myers@Sun.COM  * RETURN:      Status
332*7851SDana.Myers@Sun.COM  *
333*7851SDana.Myers@Sun.COM  * DESCRIPTION: Concatenate two objects OF THE SAME TYPE.
334*7851SDana.Myers@Sun.COM  *
335*7851SDana.Myers@Sun.COM  ******************************************************************************/
336*7851SDana.Myers@Sun.COM 
337*7851SDana.Myers@Sun.COM ACPI_STATUS
338*7851SDana.Myers@Sun.COM AcpiExDoConcatenate (
339*7851SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT     *Operand0,
340*7851SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT     *Operand1,
341*7851SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT     **ActualReturnDesc,
342*7851SDana.Myers@Sun.COM     ACPI_WALK_STATE         *WalkState)
343*7851SDana.Myers@Sun.COM {
344*7851SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT     *LocalOperand1 = Operand1;
345*7851SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT     *ReturnDesc;
346*7851SDana.Myers@Sun.COM     char                    *NewBuf;
347*7851SDana.Myers@Sun.COM     ACPI_STATUS             Status;
348*7851SDana.Myers@Sun.COM 
349*7851SDana.Myers@Sun.COM 
350*7851SDana.Myers@Sun.COM     ACPI_FUNCTION_TRACE (ExDoConcatenate);
351*7851SDana.Myers@Sun.COM 
352*7851SDana.Myers@Sun.COM 
353*7851SDana.Myers@Sun.COM     /*
354*7851SDana.Myers@Sun.COM      * Convert the second operand if necessary.  The first operand
355*7851SDana.Myers@Sun.COM      * determines the type of the second operand, (See the Data Types
356*7851SDana.Myers@Sun.COM      * section of the ACPI specification.)  Both object types are
357*7851SDana.Myers@Sun.COM      * guaranteed to be either Integer/String/Buffer by the operand
358*7851SDana.Myers@Sun.COM      * resolution mechanism.
359*7851SDana.Myers@Sun.COM      */
360*7851SDana.Myers@Sun.COM     switch (ACPI_GET_OBJECT_TYPE (Operand0))
361*7851SDana.Myers@Sun.COM     {
362*7851SDana.Myers@Sun.COM     case ACPI_TYPE_INTEGER:
363*7851SDana.Myers@Sun.COM         Status = AcpiExConvertToInteger (Operand1, &LocalOperand1, 16);
364*7851SDana.Myers@Sun.COM         break;
365*7851SDana.Myers@Sun.COM 
366*7851SDana.Myers@Sun.COM     case ACPI_TYPE_STRING:
367*7851SDana.Myers@Sun.COM         Status = AcpiExConvertToString (Operand1, &LocalOperand1,
368*7851SDana.Myers@Sun.COM                     ACPI_IMPLICIT_CONVERT_HEX);
369*7851SDana.Myers@Sun.COM         break;
370*7851SDana.Myers@Sun.COM 
371*7851SDana.Myers@Sun.COM     case ACPI_TYPE_BUFFER:
372*7851SDana.Myers@Sun.COM         Status = AcpiExConvertToBuffer (Operand1, &LocalOperand1);
373*7851SDana.Myers@Sun.COM         break;
374*7851SDana.Myers@Sun.COM 
375*7851SDana.Myers@Sun.COM     default:
376*7851SDana.Myers@Sun.COM         ACPI_ERROR ((AE_INFO, "Invalid object type: %X",
377*7851SDana.Myers@Sun.COM             ACPI_GET_OBJECT_TYPE (Operand0)));
378*7851SDana.Myers@Sun.COM         Status = AE_AML_INTERNAL;
379*7851SDana.Myers@Sun.COM     }
380*7851SDana.Myers@Sun.COM 
381*7851SDana.Myers@Sun.COM     if (ACPI_FAILURE (Status))
382*7851SDana.Myers@Sun.COM     {
383*7851SDana.Myers@Sun.COM         goto Cleanup;
384*7851SDana.Myers@Sun.COM     }
385*7851SDana.Myers@Sun.COM 
386*7851SDana.Myers@Sun.COM     /*
387*7851SDana.Myers@Sun.COM      * Both operands are now known to be the same object type
388*7851SDana.Myers@Sun.COM      * (Both are Integer, String, or Buffer), and we can now perform the
389*7851SDana.Myers@Sun.COM      * concatenation.
390*7851SDana.Myers@Sun.COM      */
391*7851SDana.Myers@Sun.COM 
392*7851SDana.Myers@Sun.COM     /*
393*7851SDana.Myers@Sun.COM      * There are three cases to handle:
394*7851SDana.Myers@Sun.COM      *
395*7851SDana.Myers@Sun.COM      * 1) Two Integers concatenated to produce a new Buffer
396*7851SDana.Myers@Sun.COM      * 2) Two Strings concatenated to produce a new String
397*7851SDana.Myers@Sun.COM      * 3) Two Buffers concatenated to produce a new Buffer
398*7851SDana.Myers@Sun.COM      */
399*7851SDana.Myers@Sun.COM     switch (ACPI_GET_OBJECT_TYPE (Operand0))
400*7851SDana.Myers@Sun.COM     {
401*7851SDana.Myers@Sun.COM     case ACPI_TYPE_INTEGER:
402*7851SDana.Myers@Sun.COM 
403*7851SDana.Myers@Sun.COM         /* Result of two Integers is a Buffer */
404*7851SDana.Myers@Sun.COM         /* Need enough buffer space for two integers */
405*7851SDana.Myers@Sun.COM 
406*7851SDana.Myers@Sun.COM         ReturnDesc = AcpiUtCreateBufferObject ((ACPI_SIZE)
407*7851SDana.Myers@Sun.COM                             ACPI_MUL_2 (AcpiGbl_IntegerByteWidth));
408*7851SDana.Myers@Sun.COM         if (!ReturnDesc)
409*7851SDana.Myers@Sun.COM         {
410*7851SDana.Myers@Sun.COM             Status = AE_NO_MEMORY;
411*7851SDana.Myers@Sun.COM             goto Cleanup;
412*7851SDana.Myers@Sun.COM         }
413*7851SDana.Myers@Sun.COM 
414*7851SDana.Myers@Sun.COM         NewBuf = (char *) ReturnDesc->Buffer.Pointer;
415*7851SDana.Myers@Sun.COM 
416*7851SDana.Myers@Sun.COM         /* Copy the first integer, LSB first */
417*7851SDana.Myers@Sun.COM 
418*7851SDana.Myers@Sun.COM         ACPI_MEMCPY (NewBuf, &Operand0->Integer.Value,
419*7851SDana.Myers@Sun.COM                         AcpiGbl_IntegerByteWidth);
420*7851SDana.Myers@Sun.COM 
421*7851SDana.Myers@Sun.COM         /* Copy the second integer (LSB first) after the first */
422*7851SDana.Myers@Sun.COM 
423*7851SDana.Myers@Sun.COM         ACPI_MEMCPY (NewBuf + AcpiGbl_IntegerByteWidth,
424*7851SDana.Myers@Sun.COM                         &LocalOperand1->Integer.Value,
425*7851SDana.Myers@Sun.COM                         AcpiGbl_IntegerByteWidth);
426*7851SDana.Myers@Sun.COM         break;
427*7851SDana.Myers@Sun.COM 
428*7851SDana.Myers@Sun.COM     case ACPI_TYPE_STRING:
429*7851SDana.Myers@Sun.COM 
430*7851SDana.Myers@Sun.COM         /* Result of two Strings is a String */
431*7851SDana.Myers@Sun.COM 
432*7851SDana.Myers@Sun.COM         ReturnDesc = AcpiUtCreateStringObject (
433*7851SDana.Myers@Sun.COM                         ((ACPI_SIZE) Operand0->String.Length +
434*7851SDana.Myers@Sun.COM                         LocalOperand1->String.Length));
435*7851SDana.Myers@Sun.COM         if (!ReturnDesc)
436*7851SDana.Myers@Sun.COM         {
437*7851SDana.Myers@Sun.COM             Status = AE_NO_MEMORY;
438*7851SDana.Myers@Sun.COM             goto Cleanup;
439*7851SDana.Myers@Sun.COM         }
440*7851SDana.Myers@Sun.COM 
441*7851SDana.Myers@Sun.COM         NewBuf = ReturnDesc->String.Pointer;
442*7851SDana.Myers@Sun.COM 
443*7851SDana.Myers@Sun.COM         /* Concatenate the strings */
444*7851SDana.Myers@Sun.COM 
445*7851SDana.Myers@Sun.COM         ACPI_STRCPY (NewBuf, Operand0->String.Pointer);
446*7851SDana.Myers@Sun.COM         ACPI_STRCPY (NewBuf + Operand0->String.Length,
447*7851SDana.Myers@Sun.COM                         LocalOperand1->String.Pointer);
448*7851SDana.Myers@Sun.COM         break;
449*7851SDana.Myers@Sun.COM 
450*7851SDana.Myers@Sun.COM     case ACPI_TYPE_BUFFER:
451*7851SDana.Myers@Sun.COM 
452*7851SDana.Myers@Sun.COM         /* Result of two Buffers is a Buffer */
453*7851SDana.Myers@Sun.COM 
454*7851SDana.Myers@Sun.COM         ReturnDesc = AcpiUtCreateBufferObject (
455*7851SDana.Myers@Sun.COM                         ((ACPI_SIZE) Operand0->Buffer.Length +
456*7851SDana.Myers@Sun.COM                         LocalOperand1->Buffer.Length));
457*7851SDana.Myers@Sun.COM         if (!ReturnDesc)
458*7851SDana.Myers@Sun.COM         {
459*7851SDana.Myers@Sun.COM             Status = AE_NO_MEMORY;
460*7851SDana.Myers@Sun.COM             goto Cleanup;
461*7851SDana.Myers@Sun.COM         }
462*7851SDana.Myers@Sun.COM 
463*7851SDana.Myers@Sun.COM         NewBuf = (char *) ReturnDesc->Buffer.Pointer;
464*7851SDana.Myers@Sun.COM 
465*7851SDana.Myers@Sun.COM         /* Concatenate the buffers */
466*7851SDana.Myers@Sun.COM 
467*7851SDana.Myers@Sun.COM         ACPI_MEMCPY (NewBuf, Operand0->Buffer.Pointer,
468*7851SDana.Myers@Sun.COM                         Operand0->Buffer.Length);
469*7851SDana.Myers@Sun.COM         ACPI_MEMCPY (NewBuf + Operand0->Buffer.Length,
470*7851SDana.Myers@Sun.COM                         LocalOperand1->Buffer.Pointer,
471*7851SDana.Myers@Sun.COM                         LocalOperand1->Buffer.Length);
472*7851SDana.Myers@Sun.COM         break;
473*7851SDana.Myers@Sun.COM 
474*7851SDana.Myers@Sun.COM     default:
475*7851SDana.Myers@Sun.COM 
476*7851SDana.Myers@Sun.COM         /* Invalid object type, should not happen here */
477*7851SDana.Myers@Sun.COM 
478*7851SDana.Myers@Sun.COM         ACPI_ERROR ((AE_INFO, "Invalid object type: %X",
479*7851SDana.Myers@Sun.COM             ACPI_GET_OBJECT_TYPE (Operand0)));
480*7851SDana.Myers@Sun.COM         Status =AE_AML_INTERNAL;
481*7851SDana.Myers@Sun.COM         goto Cleanup;
482*7851SDana.Myers@Sun.COM     }
483*7851SDana.Myers@Sun.COM 
484*7851SDana.Myers@Sun.COM     *ActualReturnDesc = ReturnDesc;
485*7851SDana.Myers@Sun.COM 
486*7851SDana.Myers@Sun.COM Cleanup:
487*7851SDana.Myers@Sun.COM     if (LocalOperand1 != Operand1)
488*7851SDana.Myers@Sun.COM     {
489*7851SDana.Myers@Sun.COM         AcpiUtRemoveReference (LocalOperand1);
490*7851SDana.Myers@Sun.COM     }
491*7851SDana.Myers@Sun.COM     return_ACPI_STATUS (Status);
492*7851SDana.Myers@Sun.COM }
493*7851SDana.Myers@Sun.COM 
494*7851SDana.Myers@Sun.COM 
495*7851SDana.Myers@Sun.COM /*******************************************************************************
496*7851SDana.Myers@Sun.COM  *
497*7851SDana.Myers@Sun.COM  * FUNCTION:    AcpiExDoMathOp
498*7851SDana.Myers@Sun.COM  *
499*7851SDana.Myers@Sun.COM  * PARAMETERS:  Opcode              - AML opcode
500*7851SDana.Myers@Sun.COM  *              Integer0            - Integer operand #0
501*7851SDana.Myers@Sun.COM  *              Integer1            - Integer operand #1
502*7851SDana.Myers@Sun.COM  *
503*7851SDana.Myers@Sun.COM  * RETURN:      Integer result of the operation
504*7851SDana.Myers@Sun.COM  *
505*7851SDana.Myers@Sun.COM  * DESCRIPTION: Execute a math AML opcode. The purpose of having all of the
506*7851SDana.Myers@Sun.COM  *              math functions here is to prevent a lot of pointer dereferencing
507*7851SDana.Myers@Sun.COM  *              to obtain the operands.
508*7851SDana.Myers@Sun.COM  *
509*7851SDana.Myers@Sun.COM  ******************************************************************************/
510*7851SDana.Myers@Sun.COM 
511*7851SDana.Myers@Sun.COM ACPI_INTEGER
512*7851SDana.Myers@Sun.COM AcpiExDoMathOp (
513*7851SDana.Myers@Sun.COM     UINT16                  Opcode,
514*7851SDana.Myers@Sun.COM     ACPI_INTEGER            Integer0,
515*7851SDana.Myers@Sun.COM     ACPI_INTEGER            Integer1)
516*7851SDana.Myers@Sun.COM {
517*7851SDana.Myers@Sun.COM 
518*7851SDana.Myers@Sun.COM     ACPI_FUNCTION_ENTRY ();
519*7851SDana.Myers@Sun.COM 
520*7851SDana.Myers@Sun.COM 
521*7851SDana.Myers@Sun.COM     switch (Opcode)
522*7851SDana.Myers@Sun.COM     {
523*7851SDana.Myers@Sun.COM     case AML_ADD_OP:                /* Add (Integer0, Integer1, Result) */
524*7851SDana.Myers@Sun.COM 
525*7851SDana.Myers@Sun.COM         return (Integer0 + Integer1);
526*7851SDana.Myers@Sun.COM 
527*7851SDana.Myers@Sun.COM 
528*7851SDana.Myers@Sun.COM     case AML_BIT_AND_OP:            /* And (Integer0, Integer1, Result) */
529*7851SDana.Myers@Sun.COM 
530*7851SDana.Myers@Sun.COM         return (Integer0 & Integer1);
531*7851SDana.Myers@Sun.COM 
532*7851SDana.Myers@Sun.COM 
533*7851SDana.Myers@Sun.COM     case AML_BIT_NAND_OP:           /* NAnd (Integer0, Integer1, Result) */
534*7851SDana.Myers@Sun.COM 
535*7851SDana.Myers@Sun.COM         return (~(Integer0 & Integer1));
536*7851SDana.Myers@Sun.COM 
537*7851SDana.Myers@Sun.COM 
538*7851SDana.Myers@Sun.COM     case AML_BIT_OR_OP:             /* Or (Integer0, Integer1, Result) */
539*7851SDana.Myers@Sun.COM 
540*7851SDana.Myers@Sun.COM         return (Integer0 | Integer1);
541*7851SDana.Myers@Sun.COM 
542*7851SDana.Myers@Sun.COM 
543*7851SDana.Myers@Sun.COM     case AML_BIT_NOR_OP:            /* NOr (Integer0, Integer1, Result) */
544*7851SDana.Myers@Sun.COM 
545*7851SDana.Myers@Sun.COM         return (~(Integer0 | Integer1));
546*7851SDana.Myers@Sun.COM 
547*7851SDana.Myers@Sun.COM 
548*7851SDana.Myers@Sun.COM     case AML_BIT_XOR_OP:            /* XOr (Integer0, Integer1, Result) */
549*7851SDana.Myers@Sun.COM 
550*7851SDana.Myers@Sun.COM         return (Integer0 ^ Integer1);
551*7851SDana.Myers@Sun.COM 
552*7851SDana.Myers@Sun.COM 
553*7851SDana.Myers@Sun.COM     case AML_MULTIPLY_OP:           /* Multiply (Integer0, Integer1, Result) */
554*7851SDana.Myers@Sun.COM 
555*7851SDana.Myers@Sun.COM         return (Integer0 * Integer1);
556*7851SDana.Myers@Sun.COM 
557*7851SDana.Myers@Sun.COM 
558*7851SDana.Myers@Sun.COM     case AML_SHIFT_LEFT_OP:         /* ShiftLeft (Operand, ShiftCount, Result)*/
559*7851SDana.Myers@Sun.COM 
560*7851SDana.Myers@Sun.COM         /*
561*7851SDana.Myers@Sun.COM          * We need to check if the shiftcount is larger than the integer bit
562*7851SDana.Myers@Sun.COM          * width since the behavior of this is not well-defined in the C language.
563*7851SDana.Myers@Sun.COM          */
564*7851SDana.Myers@Sun.COM         if (Integer1 >= AcpiGbl_IntegerBitWidth)
565*7851SDana.Myers@Sun.COM         {
566*7851SDana.Myers@Sun.COM             return (0);
567*7851SDana.Myers@Sun.COM         }
568*7851SDana.Myers@Sun.COM         return (Integer0 << Integer1);
569*7851SDana.Myers@Sun.COM 
570*7851SDana.Myers@Sun.COM 
571*7851SDana.Myers@Sun.COM     case AML_SHIFT_RIGHT_OP:        /* ShiftRight (Operand, ShiftCount, Result) */
572*7851SDana.Myers@Sun.COM 
573*7851SDana.Myers@Sun.COM         /*
574*7851SDana.Myers@Sun.COM          * We need to check if the shiftcount is larger than the integer bit
575*7851SDana.Myers@Sun.COM          * width since the behavior of this is not well-defined in the C language.
576*7851SDana.Myers@Sun.COM          */
577*7851SDana.Myers@Sun.COM         if (Integer1 >= AcpiGbl_IntegerBitWidth)
578*7851SDana.Myers@Sun.COM         {
579*7851SDana.Myers@Sun.COM             return (0);
580*7851SDana.Myers@Sun.COM         }
581*7851SDana.Myers@Sun.COM         return (Integer0 >> Integer1);
582*7851SDana.Myers@Sun.COM 
583*7851SDana.Myers@Sun.COM 
584*7851SDana.Myers@Sun.COM     case AML_SUBTRACT_OP:           /* Subtract (Integer0, Integer1, Result) */
585*7851SDana.Myers@Sun.COM 
586*7851SDana.Myers@Sun.COM         return (Integer0 - Integer1);
587*7851SDana.Myers@Sun.COM 
588*7851SDana.Myers@Sun.COM     default:
589*7851SDana.Myers@Sun.COM 
590*7851SDana.Myers@Sun.COM         return (0);
591*7851SDana.Myers@Sun.COM     }
592*7851SDana.Myers@Sun.COM }
593*7851SDana.Myers@Sun.COM 
594*7851SDana.Myers@Sun.COM 
595*7851SDana.Myers@Sun.COM /*******************************************************************************
596*7851SDana.Myers@Sun.COM  *
597*7851SDana.Myers@Sun.COM  * FUNCTION:    AcpiExDoLogicalNumericOp
598*7851SDana.Myers@Sun.COM  *
599*7851SDana.Myers@Sun.COM  * PARAMETERS:  Opcode              - AML opcode
600*7851SDana.Myers@Sun.COM  *              Integer0            - Integer operand #0
601*7851SDana.Myers@Sun.COM  *              Integer1            - Integer operand #1
602*7851SDana.Myers@Sun.COM  *              LogicalResult       - TRUE/FALSE result of the operation
603*7851SDana.Myers@Sun.COM  *
604*7851SDana.Myers@Sun.COM  * RETURN:      Status
605*7851SDana.Myers@Sun.COM  *
606*7851SDana.Myers@Sun.COM  * DESCRIPTION: Execute a logical "Numeric" AML opcode. For these Numeric
607*7851SDana.Myers@Sun.COM  *              operators (LAnd and LOr), both operands must be integers.
608*7851SDana.Myers@Sun.COM  *
609*7851SDana.Myers@Sun.COM  *              Note: cleanest machine code seems to be produced by the code
610*7851SDana.Myers@Sun.COM  *              below, rather than using statements of the form:
611*7851SDana.Myers@Sun.COM  *                  Result = (Integer0 && Integer1);
612*7851SDana.Myers@Sun.COM  *
613*7851SDana.Myers@Sun.COM  ******************************************************************************/
614*7851SDana.Myers@Sun.COM 
615*7851SDana.Myers@Sun.COM ACPI_STATUS
616*7851SDana.Myers@Sun.COM AcpiExDoLogicalNumericOp (
617*7851SDana.Myers@Sun.COM     UINT16                  Opcode,
618*7851SDana.Myers@Sun.COM     ACPI_INTEGER            Integer0,
619*7851SDana.Myers@Sun.COM     ACPI_INTEGER            Integer1,
620*7851SDana.Myers@Sun.COM     BOOLEAN                 *LogicalResult)
621*7851SDana.Myers@Sun.COM {
622*7851SDana.Myers@Sun.COM     ACPI_STATUS             Status = AE_OK;
623*7851SDana.Myers@Sun.COM     BOOLEAN                 LocalResult = FALSE;
624*7851SDana.Myers@Sun.COM 
625*7851SDana.Myers@Sun.COM 
626*7851SDana.Myers@Sun.COM     ACPI_FUNCTION_TRACE (ExDoLogicalNumericOp);
627*7851SDana.Myers@Sun.COM 
628*7851SDana.Myers@Sun.COM 
629*7851SDana.Myers@Sun.COM     switch (Opcode)
630*7851SDana.Myers@Sun.COM     {
631*7851SDana.Myers@Sun.COM     case AML_LAND_OP:               /* LAnd (Integer0, Integer1) */
632*7851SDana.Myers@Sun.COM 
633*7851SDana.Myers@Sun.COM         if (Integer0 && Integer1)
634*7851SDana.Myers@Sun.COM         {
635*7851SDana.Myers@Sun.COM             LocalResult = TRUE;
636*7851SDana.Myers@Sun.COM         }
637*7851SDana.Myers@Sun.COM         break;
638*7851SDana.Myers@Sun.COM 
639*7851SDana.Myers@Sun.COM     case AML_LOR_OP:                /* LOr (Integer0, Integer1) */
640*7851SDana.Myers@Sun.COM 
641*7851SDana.Myers@Sun.COM         if (Integer0 || Integer1)
642*7851SDana.Myers@Sun.COM         {
643*7851SDana.Myers@Sun.COM             LocalResult = TRUE;
644*7851SDana.Myers@Sun.COM         }
645*7851SDana.Myers@Sun.COM         break;
646*7851SDana.Myers@Sun.COM 
647*7851SDana.Myers@Sun.COM     default:
648*7851SDana.Myers@Sun.COM         Status = AE_AML_INTERNAL;
649*7851SDana.Myers@Sun.COM         break;
650*7851SDana.Myers@Sun.COM     }
651*7851SDana.Myers@Sun.COM 
652*7851SDana.Myers@Sun.COM     /* Return the logical result and status */
653*7851SDana.Myers@Sun.COM 
654*7851SDana.Myers@Sun.COM     *LogicalResult = LocalResult;
655*7851SDana.Myers@Sun.COM     return_ACPI_STATUS (Status);
656*7851SDana.Myers@Sun.COM }
657*7851SDana.Myers@Sun.COM 
658*7851SDana.Myers@Sun.COM 
659*7851SDana.Myers@Sun.COM /*******************************************************************************
660*7851SDana.Myers@Sun.COM  *
661*7851SDana.Myers@Sun.COM  * FUNCTION:    AcpiExDoLogicalOp
662*7851SDana.Myers@Sun.COM  *
663*7851SDana.Myers@Sun.COM  * PARAMETERS:  Opcode              - AML opcode
664*7851SDana.Myers@Sun.COM  *              Operand0            - operand #0
665*7851SDana.Myers@Sun.COM  *              Operand1            - operand #1
666*7851SDana.Myers@Sun.COM  *              LogicalResult       - TRUE/FALSE result of the operation
667*7851SDana.Myers@Sun.COM  *
668*7851SDana.Myers@Sun.COM  * RETURN:      Status
669*7851SDana.Myers@Sun.COM  *
670*7851SDana.Myers@Sun.COM  * DESCRIPTION: Execute a logical AML opcode. The purpose of having all of the
671*7851SDana.Myers@Sun.COM  *              functions here is to prevent a lot of pointer dereferencing
672*7851SDana.Myers@Sun.COM  *              to obtain the operands and to simplify the generation of the
673*7851SDana.Myers@Sun.COM  *              logical value. For the Numeric operators (LAnd and LOr), both
674*7851SDana.Myers@Sun.COM  *              operands must be integers. For the other logical operators,
675*7851SDana.Myers@Sun.COM  *              operands can be any combination of Integer/String/Buffer. The
676*7851SDana.Myers@Sun.COM  *              first operand determines the type to which the second operand
677*7851SDana.Myers@Sun.COM  *              will be converted.
678*7851SDana.Myers@Sun.COM  *
679*7851SDana.Myers@Sun.COM  *              Note: cleanest machine code seems to be produced by the code
680*7851SDana.Myers@Sun.COM  *              below, rather than using statements of the form:
681*7851SDana.Myers@Sun.COM  *                  Result = (Operand0 == Operand1);
682*7851SDana.Myers@Sun.COM  *
683*7851SDana.Myers@Sun.COM  ******************************************************************************/
684*7851SDana.Myers@Sun.COM 
685*7851SDana.Myers@Sun.COM ACPI_STATUS
686*7851SDana.Myers@Sun.COM AcpiExDoLogicalOp (
687*7851SDana.Myers@Sun.COM     UINT16                  Opcode,
688*7851SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT     *Operand0,
689*7851SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT     *Operand1,
690*7851SDana.Myers@Sun.COM     BOOLEAN                 *LogicalResult)
691*7851SDana.Myers@Sun.COM {
692*7851SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT     *LocalOperand1 = Operand1;
693*7851SDana.Myers@Sun.COM     ACPI_INTEGER            Integer0;
694*7851SDana.Myers@Sun.COM     ACPI_INTEGER            Integer1;
695*7851SDana.Myers@Sun.COM     UINT32                  Length0;
696*7851SDana.Myers@Sun.COM     UINT32                  Length1;
697*7851SDana.Myers@Sun.COM     ACPI_STATUS             Status = AE_OK;
698*7851SDana.Myers@Sun.COM     BOOLEAN                 LocalResult = FALSE;
699*7851SDana.Myers@Sun.COM     int                     Compare;
700*7851SDana.Myers@Sun.COM 
701*7851SDana.Myers@Sun.COM 
702*7851SDana.Myers@Sun.COM     ACPI_FUNCTION_TRACE (ExDoLogicalOp);
703*7851SDana.Myers@Sun.COM 
704*7851SDana.Myers@Sun.COM 
705*7851SDana.Myers@Sun.COM     /*
706*7851SDana.Myers@Sun.COM      * Convert the second operand if necessary.  The first operand
707*7851SDana.Myers@Sun.COM      * determines the type of the second operand, (See the Data Types
708*7851SDana.Myers@Sun.COM      * section of the ACPI 3.0+ specification.)  Both object types are
709*7851SDana.Myers@Sun.COM      * guaranteed to be either Integer/String/Buffer by the operand
710*7851SDana.Myers@Sun.COM      * resolution mechanism.
711*7851SDana.Myers@Sun.COM      */
712*7851SDana.Myers@Sun.COM     switch (ACPI_GET_OBJECT_TYPE (Operand0))
713*7851SDana.Myers@Sun.COM     {
714*7851SDana.Myers@Sun.COM     case ACPI_TYPE_INTEGER:
715*7851SDana.Myers@Sun.COM         Status = AcpiExConvertToInteger (Operand1, &LocalOperand1, 16);
716*7851SDana.Myers@Sun.COM         break;
717*7851SDana.Myers@Sun.COM 
718*7851SDana.Myers@Sun.COM     case ACPI_TYPE_STRING:
719*7851SDana.Myers@Sun.COM         Status = AcpiExConvertToString (Operand1, &LocalOperand1,
720*7851SDana.Myers@Sun.COM                     ACPI_IMPLICIT_CONVERT_HEX);
721*7851SDana.Myers@Sun.COM         break;
722*7851SDana.Myers@Sun.COM 
723*7851SDana.Myers@Sun.COM     case ACPI_TYPE_BUFFER:
724*7851SDana.Myers@Sun.COM         Status = AcpiExConvertToBuffer (Operand1, &LocalOperand1);
725*7851SDana.Myers@Sun.COM         break;
726*7851SDana.Myers@Sun.COM 
727*7851SDana.Myers@Sun.COM     default:
728*7851SDana.Myers@Sun.COM         Status = AE_AML_INTERNAL;
729*7851SDana.Myers@Sun.COM         break;
730*7851SDana.Myers@Sun.COM     }
731*7851SDana.Myers@Sun.COM 
732*7851SDana.Myers@Sun.COM     if (ACPI_FAILURE (Status))
733*7851SDana.Myers@Sun.COM     {
734*7851SDana.Myers@Sun.COM         goto Cleanup;
735*7851SDana.Myers@Sun.COM     }
736*7851SDana.Myers@Sun.COM 
737*7851SDana.Myers@Sun.COM     /*
738*7851SDana.Myers@Sun.COM      * Two cases: 1) Both Integers, 2) Both Strings or Buffers
739*7851SDana.Myers@Sun.COM      */
740*7851SDana.Myers@Sun.COM     if (ACPI_GET_OBJECT_TYPE (Operand0) == ACPI_TYPE_INTEGER)
741*7851SDana.Myers@Sun.COM     {
742*7851SDana.Myers@Sun.COM         /*
743*7851SDana.Myers@Sun.COM          * 1) Both operands are of type integer
744*7851SDana.Myers@Sun.COM          *    Note: LocalOperand1 may have changed above
745*7851SDana.Myers@Sun.COM          */
746*7851SDana.Myers@Sun.COM         Integer0 = Operand0->Integer.Value;
747*7851SDana.Myers@Sun.COM         Integer1 = LocalOperand1->Integer.Value;
748*7851SDana.Myers@Sun.COM 
749*7851SDana.Myers@Sun.COM         switch (Opcode)
750*7851SDana.Myers@Sun.COM         {
751*7851SDana.Myers@Sun.COM         case AML_LEQUAL_OP:             /* LEqual (Operand0, Operand1) */
752*7851SDana.Myers@Sun.COM 
753*7851SDana.Myers@Sun.COM             if (Integer0 == Integer1)
754*7851SDana.Myers@Sun.COM             {
755*7851SDana.Myers@Sun.COM                 LocalResult = TRUE;
756*7851SDana.Myers@Sun.COM             }
757*7851SDana.Myers@Sun.COM             break;
758*7851SDana.Myers@Sun.COM 
759*7851SDana.Myers@Sun.COM         case AML_LGREATER_OP:           /* LGreater (Operand0, Operand1) */
760*7851SDana.Myers@Sun.COM 
761*7851SDana.Myers@Sun.COM             if (Integer0 > Integer1)
762*7851SDana.Myers@Sun.COM             {
763*7851SDana.Myers@Sun.COM                 LocalResult = TRUE;
764*7851SDana.Myers@Sun.COM             }
765*7851SDana.Myers@Sun.COM             break;
766*7851SDana.Myers@Sun.COM 
767*7851SDana.Myers@Sun.COM         case AML_LLESS_OP:              /* LLess (Operand0, Operand1) */
768*7851SDana.Myers@Sun.COM 
769*7851SDana.Myers@Sun.COM             if (Integer0 < Integer1)
770*7851SDana.Myers@Sun.COM             {
771*7851SDana.Myers@Sun.COM                 LocalResult = TRUE;
772*7851SDana.Myers@Sun.COM             }
773*7851SDana.Myers@Sun.COM             break;
774*7851SDana.Myers@Sun.COM 
775*7851SDana.Myers@Sun.COM         default:
776*7851SDana.Myers@Sun.COM             Status = AE_AML_INTERNAL;
777*7851SDana.Myers@Sun.COM             break;
778*7851SDana.Myers@Sun.COM         }
779*7851SDana.Myers@Sun.COM     }
780*7851SDana.Myers@Sun.COM     else
781*7851SDana.Myers@Sun.COM     {
782*7851SDana.Myers@Sun.COM         /*
783*7851SDana.Myers@Sun.COM          * 2) Both operands are Strings or both are Buffers
784*7851SDana.Myers@Sun.COM          *    Note: Code below takes advantage of common Buffer/String
785*7851SDana.Myers@Sun.COM          *          object fields. LocalOperand1 may have changed above. Use
786*7851SDana.Myers@Sun.COM          *          memcmp to handle nulls in buffers.
787*7851SDana.Myers@Sun.COM          */
788*7851SDana.Myers@Sun.COM         Length0 = Operand0->Buffer.Length;
789*7851SDana.Myers@Sun.COM         Length1 = LocalOperand1->Buffer.Length;
790*7851SDana.Myers@Sun.COM 
791*7851SDana.Myers@Sun.COM         /* Lexicographic compare: compare the data bytes */
792*7851SDana.Myers@Sun.COM 
793*7851SDana.Myers@Sun.COM         Compare = ACPI_MEMCMP (Operand0->Buffer.Pointer,
794*7851SDana.Myers@Sun.COM                     LocalOperand1->Buffer.Pointer,
795*7851SDana.Myers@Sun.COM                     (Length0 > Length1) ? Length1 : Length0);
796*7851SDana.Myers@Sun.COM 
797*7851SDana.Myers@Sun.COM         switch (Opcode)
798*7851SDana.Myers@Sun.COM         {
799*7851SDana.Myers@Sun.COM         case AML_LEQUAL_OP:             /* LEqual (Operand0, Operand1) */
800*7851SDana.Myers@Sun.COM 
801*7851SDana.Myers@Sun.COM             /* Length and all bytes must be equal */
802*7851SDana.Myers@Sun.COM 
803*7851SDana.Myers@Sun.COM             if ((Length0 == Length1) &&
804*7851SDana.Myers@Sun.COM                 (Compare == 0))
805*7851SDana.Myers@Sun.COM             {
806*7851SDana.Myers@Sun.COM                 /* Length and all bytes match ==> TRUE */
807*7851SDana.Myers@Sun.COM 
808*7851SDana.Myers@Sun.COM                 LocalResult = TRUE;
809*7851SDana.Myers@Sun.COM             }
810*7851SDana.Myers@Sun.COM             break;
811*7851SDana.Myers@Sun.COM 
812*7851SDana.Myers@Sun.COM         case AML_LGREATER_OP:           /* LGreater (Operand0, Operand1) */
813*7851SDana.Myers@Sun.COM 
814*7851SDana.Myers@Sun.COM             if (Compare > 0)
815*7851SDana.Myers@Sun.COM             {
816*7851SDana.Myers@Sun.COM                 LocalResult = TRUE;
817*7851SDana.Myers@Sun.COM                 goto Cleanup;   /* TRUE */
818*7851SDana.Myers@Sun.COM             }
819*7851SDana.Myers@Sun.COM             if (Compare < 0)
820*7851SDana.Myers@Sun.COM             {
821*7851SDana.Myers@Sun.COM                 goto Cleanup;   /* FALSE */
822*7851SDana.Myers@Sun.COM             }
823*7851SDana.Myers@Sun.COM 
824*7851SDana.Myers@Sun.COM             /* Bytes match (to shortest length), compare lengths */
825*7851SDana.Myers@Sun.COM 
826*7851SDana.Myers@Sun.COM             if (Length0 > Length1)
827*7851SDana.Myers@Sun.COM             {
828*7851SDana.Myers@Sun.COM                 LocalResult = TRUE;
829*7851SDana.Myers@Sun.COM             }
830*7851SDana.Myers@Sun.COM             break;
831*7851SDana.Myers@Sun.COM 
832*7851SDana.Myers@Sun.COM         case AML_LLESS_OP:              /* LLess (Operand0, Operand1) */
833*7851SDana.Myers@Sun.COM 
834*7851SDana.Myers@Sun.COM             if (Compare > 0)
835*7851SDana.Myers@Sun.COM             {
836*7851SDana.Myers@Sun.COM                 goto Cleanup;   /* FALSE */
837*7851SDana.Myers@Sun.COM             }
838*7851SDana.Myers@Sun.COM             if (Compare < 0)
839*7851SDana.Myers@Sun.COM             {
840*7851SDana.Myers@Sun.COM                 LocalResult = TRUE;
841*7851SDana.Myers@Sun.COM                 goto Cleanup;   /* TRUE */
842*7851SDana.Myers@Sun.COM             }
843*7851SDana.Myers@Sun.COM 
844*7851SDana.Myers@Sun.COM             /* Bytes match (to shortest length), compare lengths */
845*7851SDana.Myers@Sun.COM 
846*7851SDana.Myers@Sun.COM             if (Length0 < Length1)
847*7851SDana.Myers@Sun.COM             {
848*7851SDana.Myers@Sun.COM                 LocalResult = TRUE;
849*7851SDana.Myers@Sun.COM             }
850*7851SDana.Myers@Sun.COM             break;
851*7851SDana.Myers@Sun.COM 
852*7851SDana.Myers@Sun.COM         default:
853*7851SDana.Myers@Sun.COM             Status = AE_AML_INTERNAL;
854*7851SDana.Myers@Sun.COM             break;
855*7851SDana.Myers@Sun.COM         }
856*7851SDana.Myers@Sun.COM     }
857*7851SDana.Myers@Sun.COM 
858*7851SDana.Myers@Sun.COM Cleanup:
859*7851SDana.Myers@Sun.COM 
860*7851SDana.Myers@Sun.COM     /* New object was created if implicit conversion performed - delete */
861*7851SDana.Myers@Sun.COM 
862*7851SDana.Myers@Sun.COM     if (LocalOperand1 != Operand1)
863*7851SDana.Myers@Sun.COM     {
864*7851SDana.Myers@Sun.COM         AcpiUtRemoveReference (LocalOperand1);
865*7851SDana.Myers@Sun.COM     }
866*7851SDana.Myers@Sun.COM 
867*7851SDana.Myers@Sun.COM     /* Return the logical result and status */
868*7851SDana.Myers@Sun.COM 
869*7851SDana.Myers@Sun.COM     *LogicalResult = LocalResult;
870*7851SDana.Myers@Sun.COM     return_ACPI_STATUS (Status);
871*7851SDana.Myers@Sun.COM }
872*7851SDana.Myers@Sun.COM 
873*7851SDana.Myers@Sun.COM 
874