xref: /freebsd/sys/contrib/dev/acpica/components/executer/exmisc.c (revision a159c266a93c3c4f229864954c5f963acd8f60f2)
1*a159c266SJung-uk Kim 
2*a159c266SJung-uk Kim /******************************************************************************
3*a159c266SJung-uk Kim  *
4*a159c266SJung-uk Kim  * Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes
5*a159c266SJung-uk Kim  *
6*a159c266SJung-uk Kim  *****************************************************************************/
7*a159c266SJung-uk Kim 
8*a159c266SJung-uk Kim /*
9*a159c266SJung-uk Kim  * Copyright (C) 2000 - 2012, Intel Corp.
10*a159c266SJung-uk Kim  * All rights reserved.
11*a159c266SJung-uk Kim  *
12*a159c266SJung-uk Kim  * Redistribution and use in source and binary forms, with or without
13*a159c266SJung-uk Kim  * modification, are permitted provided that the following conditions
14*a159c266SJung-uk Kim  * are met:
15*a159c266SJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
16*a159c266SJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
17*a159c266SJung-uk Kim  *    without modification.
18*a159c266SJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19*a159c266SJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
20*a159c266SJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
21*a159c266SJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
22*a159c266SJung-uk Kim  *    binary redistribution.
23*a159c266SJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
24*a159c266SJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
25*a159c266SJung-uk Kim  *    from this software without specific prior written permission.
26*a159c266SJung-uk Kim  *
27*a159c266SJung-uk Kim  * Alternatively, this software may be distributed under the terms of the
28*a159c266SJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
29*a159c266SJung-uk Kim  * Software Foundation.
30*a159c266SJung-uk Kim  *
31*a159c266SJung-uk Kim  * NO WARRANTY
32*a159c266SJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33*a159c266SJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34*a159c266SJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35*a159c266SJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36*a159c266SJung-uk Kim  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37*a159c266SJung-uk Kim  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38*a159c266SJung-uk Kim  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39*a159c266SJung-uk Kim  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40*a159c266SJung-uk Kim  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41*a159c266SJung-uk Kim  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42*a159c266SJung-uk Kim  * POSSIBILITY OF SUCH DAMAGES.
43*a159c266SJung-uk Kim  */
44*a159c266SJung-uk Kim 
45*a159c266SJung-uk Kim #define __EXMISC_C__
46*a159c266SJung-uk Kim 
47*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h>
48*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h>
49*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acinterp.h>
50*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h>
51*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/amlresrc.h>
52*a159c266SJung-uk Kim 
53*a159c266SJung-uk Kim 
54*a159c266SJung-uk Kim #define _COMPONENT          ACPI_EXECUTER
55*a159c266SJung-uk Kim         ACPI_MODULE_NAME    ("exmisc")
56*a159c266SJung-uk Kim 
57*a159c266SJung-uk Kim 
58*a159c266SJung-uk Kim /*******************************************************************************
59*a159c266SJung-uk Kim  *
60*a159c266SJung-uk Kim  * FUNCTION:    AcpiExGetObjectReference
61*a159c266SJung-uk Kim  *
62*a159c266SJung-uk Kim  * PARAMETERS:  ObjDesc             - Create a reference to this object
63*a159c266SJung-uk Kim  *              ReturnDesc          - Where to store the reference
64*a159c266SJung-uk Kim  *              WalkState           - Current state
65*a159c266SJung-uk Kim  *
66*a159c266SJung-uk Kim  * RETURN:      Status
67*a159c266SJung-uk Kim  *
68*a159c266SJung-uk Kim  * DESCRIPTION: Obtain and return a "reference" to the target object
69*a159c266SJung-uk Kim  *              Common code for the RefOfOp and the CondRefOfOp.
70*a159c266SJung-uk Kim  *
71*a159c266SJung-uk Kim  ******************************************************************************/
72*a159c266SJung-uk Kim 
73*a159c266SJung-uk Kim ACPI_STATUS
74*a159c266SJung-uk Kim AcpiExGetObjectReference (
75*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *ObjDesc,
76*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     **ReturnDesc,
77*a159c266SJung-uk Kim     ACPI_WALK_STATE         *WalkState)
78*a159c266SJung-uk Kim {
79*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *ReferenceObj;
80*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *ReferencedObj;
81*a159c266SJung-uk Kim 
82*a159c266SJung-uk Kim 
83*a159c266SJung-uk Kim     ACPI_FUNCTION_TRACE_PTR (ExGetObjectReference, ObjDesc);
84*a159c266SJung-uk Kim 
85*a159c266SJung-uk Kim 
86*a159c266SJung-uk Kim     *ReturnDesc = NULL;
87*a159c266SJung-uk Kim 
88*a159c266SJung-uk Kim     switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))
89*a159c266SJung-uk Kim     {
90*a159c266SJung-uk Kim     case ACPI_DESC_TYPE_OPERAND:
91*a159c266SJung-uk Kim 
92*a159c266SJung-uk Kim         if (ObjDesc->Common.Type != ACPI_TYPE_LOCAL_REFERENCE)
93*a159c266SJung-uk Kim         {
94*a159c266SJung-uk Kim             return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
95*a159c266SJung-uk Kim         }
96*a159c266SJung-uk Kim 
97*a159c266SJung-uk Kim         /*
98*a159c266SJung-uk Kim          * Must be a reference to a Local or Arg
99*a159c266SJung-uk Kim          */
100*a159c266SJung-uk Kim         switch (ObjDesc->Reference.Class)
101*a159c266SJung-uk Kim         {
102*a159c266SJung-uk Kim         case ACPI_REFCLASS_LOCAL:
103*a159c266SJung-uk Kim         case ACPI_REFCLASS_ARG:
104*a159c266SJung-uk Kim         case ACPI_REFCLASS_DEBUG:
105*a159c266SJung-uk Kim 
106*a159c266SJung-uk Kim             /* The referenced object is the pseudo-node for the local/arg */
107*a159c266SJung-uk Kim 
108*a159c266SJung-uk Kim             ReferencedObj = ObjDesc->Reference.Object;
109*a159c266SJung-uk Kim             break;
110*a159c266SJung-uk Kim 
111*a159c266SJung-uk Kim         default:
112*a159c266SJung-uk Kim 
113*a159c266SJung-uk Kim             ACPI_ERROR ((AE_INFO, "Unknown Reference Class 0x%2.2X",
114*a159c266SJung-uk Kim                 ObjDesc->Reference.Class));
115*a159c266SJung-uk Kim             return_ACPI_STATUS (AE_AML_INTERNAL);
116*a159c266SJung-uk Kim         }
117*a159c266SJung-uk Kim         break;
118*a159c266SJung-uk Kim 
119*a159c266SJung-uk Kim 
120*a159c266SJung-uk Kim     case ACPI_DESC_TYPE_NAMED:
121*a159c266SJung-uk Kim 
122*a159c266SJung-uk Kim         /*
123*a159c266SJung-uk Kim          * A named reference that has already been resolved to a Node
124*a159c266SJung-uk Kim          */
125*a159c266SJung-uk Kim         ReferencedObj = ObjDesc;
126*a159c266SJung-uk Kim         break;
127*a159c266SJung-uk Kim 
128*a159c266SJung-uk Kim 
129*a159c266SJung-uk Kim     default:
130*a159c266SJung-uk Kim 
131*a159c266SJung-uk Kim         ACPI_ERROR ((AE_INFO, "Invalid descriptor type 0x%X",
132*a159c266SJung-uk Kim             ACPI_GET_DESCRIPTOR_TYPE (ObjDesc)));
133*a159c266SJung-uk Kim         return_ACPI_STATUS (AE_TYPE);
134*a159c266SJung-uk Kim     }
135*a159c266SJung-uk Kim 
136*a159c266SJung-uk Kim 
137*a159c266SJung-uk Kim     /* Create a new reference object */
138*a159c266SJung-uk Kim 
139*a159c266SJung-uk Kim     ReferenceObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_REFERENCE);
140*a159c266SJung-uk Kim     if (!ReferenceObj)
141*a159c266SJung-uk Kim     {
142*a159c266SJung-uk Kim         return_ACPI_STATUS (AE_NO_MEMORY);
143*a159c266SJung-uk Kim     }
144*a159c266SJung-uk Kim 
145*a159c266SJung-uk Kim     ReferenceObj->Reference.Class = ACPI_REFCLASS_REFOF;
146*a159c266SJung-uk Kim     ReferenceObj->Reference.Object = ReferencedObj;
147*a159c266SJung-uk Kim     *ReturnDesc = ReferenceObj;
148*a159c266SJung-uk Kim 
149*a159c266SJung-uk Kim     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
150*a159c266SJung-uk Kim         "Object %p Type [%s], returning Reference %p\n",
151*a159c266SJung-uk Kim         ObjDesc, AcpiUtGetObjectTypeName (ObjDesc), *ReturnDesc));
152*a159c266SJung-uk Kim 
153*a159c266SJung-uk Kim     return_ACPI_STATUS (AE_OK);
154*a159c266SJung-uk Kim }
155*a159c266SJung-uk Kim 
156*a159c266SJung-uk Kim 
157*a159c266SJung-uk Kim /*******************************************************************************
158*a159c266SJung-uk Kim  *
159*a159c266SJung-uk Kim  * FUNCTION:    AcpiExConcatTemplate
160*a159c266SJung-uk Kim  *
161*a159c266SJung-uk Kim  * PARAMETERS:  Operand0            - First source object
162*a159c266SJung-uk Kim  *              Operand1            - Second source object
163*a159c266SJung-uk Kim  *              ActualReturnDesc    - Where to place the return object
164*a159c266SJung-uk Kim  *              WalkState           - Current walk state
165*a159c266SJung-uk Kim  *
166*a159c266SJung-uk Kim  * RETURN:      Status
167*a159c266SJung-uk Kim  *
168*a159c266SJung-uk Kim  * DESCRIPTION: Concatenate two resource templates
169*a159c266SJung-uk Kim  *
170*a159c266SJung-uk Kim  ******************************************************************************/
171*a159c266SJung-uk Kim 
172*a159c266SJung-uk Kim ACPI_STATUS
173*a159c266SJung-uk Kim AcpiExConcatTemplate (
174*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *Operand0,
175*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *Operand1,
176*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     **ActualReturnDesc,
177*a159c266SJung-uk Kim     ACPI_WALK_STATE         *WalkState)
178*a159c266SJung-uk Kim {
179*a159c266SJung-uk Kim     ACPI_STATUS             Status;
180*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *ReturnDesc;
181*a159c266SJung-uk Kim     UINT8                   *NewBuf;
182*a159c266SJung-uk Kim     UINT8                   *EndTag;
183*a159c266SJung-uk Kim     ACPI_SIZE               Length0;
184*a159c266SJung-uk Kim     ACPI_SIZE               Length1;
185*a159c266SJung-uk Kim     ACPI_SIZE               NewLength;
186*a159c266SJung-uk Kim 
187*a159c266SJung-uk Kim 
188*a159c266SJung-uk Kim     ACPI_FUNCTION_TRACE (ExConcatTemplate);
189*a159c266SJung-uk Kim 
190*a159c266SJung-uk Kim 
191*a159c266SJung-uk Kim     /*
192*a159c266SJung-uk Kim      * Find the EndTag descriptor in each resource template.
193*a159c266SJung-uk Kim      * Note1: returned pointers point TO the EndTag, not past it.
194*a159c266SJung-uk Kim      * Note2: zero-length buffers are allowed; treated like one EndTag
195*a159c266SJung-uk Kim      */
196*a159c266SJung-uk Kim 
197*a159c266SJung-uk Kim     /* Get the length of the first resource template */
198*a159c266SJung-uk Kim 
199*a159c266SJung-uk Kim     Status = AcpiUtGetResourceEndTag (Operand0, &EndTag);
200*a159c266SJung-uk Kim     if (ACPI_FAILURE (Status))
201*a159c266SJung-uk Kim     {
202*a159c266SJung-uk Kim         return_ACPI_STATUS (Status);
203*a159c266SJung-uk Kim     }
204*a159c266SJung-uk Kim 
205*a159c266SJung-uk Kim     Length0 = ACPI_PTR_DIFF (EndTag, Operand0->Buffer.Pointer);
206*a159c266SJung-uk Kim 
207*a159c266SJung-uk Kim     /* Get the length of the second resource template */
208*a159c266SJung-uk Kim 
209*a159c266SJung-uk Kim     Status = AcpiUtGetResourceEndTag (Operand1, &EndTag);
210*a159c266SJung-uk Kim     if (ACPI_FAILURE (Status))
211*a159c266SJung-uk Kim     {
212*a159c266SJung-uk Kim         return_ACPI_STATUS (Status);
213*a159c266SJung-uk Kim     }
214*a159c266SJung-uk Kim 
215*a159c266SJung-uk Kim     Length1 = ACPI_PTR_DIFF (EndTag, Operand1->Buffer.Pointer);
216*a159c266SJung-uk Kim 
217*a159c266SJung-uk Kim     /* Combine both lengths, minimum size will be 2 for EndTag */
218*a159c266SJung-uk Kim 
219*a159c266SJung-uk Kim     NewLength = Length0 + Length1 + sizeof (AML_RESOURCE_END_TAG);
220*a159c266SJung-uk Kim 
221*a159c266SJung-uk Kim     /* Create a new buffer object for the result (with one EndTag) */
222*a159c266SJung-uk Kim 
223*a159c266SJung-uk Kim     ReturnDesc = AcpiUtCreateBufferObject (NewLength);
224*a159c266SJung-uk Kim     if (!ReturnDesc)
225*a159c266SJung-uk Kim     {
226*a159c266SJung-uk Kim         return_ACPI_STATUS (AE_NO_MEMORY);
227*a159c266SJung-uk Kim     }
228*a159c266SJung-uk Kim 
229*a159c266SJung-uk Kim     /*
230*a159c266SJung-uk Kim      * Copy the templates to the new buffer, 0 first, then 1 follows. One
231*a159c266SJung-uk Kim      * EndTag descriptor is copied from Operand1.
232*a159c266SJung-uk Kim      */
233*a159c266SJung-uk Kim     NewBuf = ReturnDesc->Buffer.Pointer;
234*a159c266SJung-uk Kim     ACPI_MEMCPY (NewBuf, Operand0->Buffer.Pointer, Length0);
235*a159c266SJung-uk Kim     ACPI_MEMCPY (NewBuf + Length0, Operand1->Buffer.Pointer, Length1);
236*a159c266SJung-uk Kim 
237*a159c266SJung-uk Kim     /* Insert EndTag and set the checksum to zero, means "ignore checksum" */
238*a159c266SJung-uk Kim 
239*a159c266SJung-uk Kim     NewBuf[NewLength - 1] = 0;
240*a159c266SJung-uk Kim     NewBuf[NewLength - 2] = ACPI_RESOURCE_NAME_END_TAG | 1;
241*a159c266SJung-uk Kim 
242*a159c266SJung-uk Kim     /* Return the completed resource template */
243*a159c266SJung-uk Kim 
244*a159c266SJung-uk Kim     *ActualReturnDesc = ReturnDesc;
245*a159c266SJung-uk Kim     return_ACPI_STATUS (AE_OK);
246*a159c266SJung-uk Kim }
247*a159c266SJung-uk Kim 
248*a159c266SJung-uk Kim 
249*a159c266SJung-uk Kim /*******************************************************************************
250*a159c266SJung-uk Kim  *
251*a159c266SJung-uk Kim  * FUNCTION:    AcpiExDoConcatenate
252*a159c266SJung-uk Kim  *
253*a159c266SJung-uk Kim  * PARAMETERS:  Operand0            - First source object
254*a159c266SJung-uk Kim  *              Operand1            - Second source object
255*a159c266SJung-uk Kim  *              ActualReturnDesc    - Where to place the return object
256*a159c266SJung-uk Kim  *              WalkState           - Current walk state
257*a159c266SJung-uk Kim  *
258*a159c266SJung-uk Kim  * RETURN:      Status
259*a159c266SJung-uk Kim  *
260*a159c266SJung-uk Kim  * DESCRIPTION: Concatenate two objects OF THE SAME TYPE.
261*a159c266SJung-uk Kim  *
262*a159c266SJung-uk Kim  ******************************************************************************/
263*a159c266SJung-uk Kim 
264*a159c266SJung-uk Kim ACPI_STATUS
265*a159c266SJung-uk Kim AcpiExDoConcatenate (
266*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *Operand0,
267*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *Operand1,
268*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     **ActualReturnDesc,
269*a159c266SJung-uk Kim     ACPI_WALK_STATE         *WalkState)
270*a159c266SJung-uk Kim {
271*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *LocalOperand1 = Operand1;
272*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *ReturnDesc;
273*a159c266SJung-uk Kim     char                    *NewBuf;
274*a159c266SJung-uk Kim     ACPI_STATUS             Status;
275*a159c266SJung-uk Kim 
276*a159c266SJung-uk Kim 
277*a159c266SJung-uk Kim     ACPI_FUNCTION_TRACE (ExDoConcatenate);
278*a159c266SJung-uk Kim 
279*a159c266SJung-uk Kim 
280*a159c266SJung-uk Kim     /*
281*a159c266SJung-uk Kim      * Convert the second operand if necessary.  The first operand
282*a159c266SJung-uk Kim      * determines the type of the second operand, (See the Data Types
283*a159c266SJung-uk Kim      * section of the ACPI specification.)  Both object types are
284*a159c266SJung-uk Kim      * guaranteed to be either Integer/String/Buffer by the operand
285*a159c266SJung-uk Kim      * resolution mechanism.
286*a159c266SJung-uk Kim      */
287*a159c266SJung-uk Kim     switch (Operand0->Common.Type)
288*a159c266SJung-uk Kim     {
289*a159c266SJung-uk Kim     case ACPI_TYPE_INTEGER:
290*a159c266SJung-uk Kim         Status = AcpiExConvertToInteger (Operand1, &LocalOperand1, 16);
291*a159c266SJung-uk Kim         break;
292*a159c266SJung-uk Kim 
293*a159c266SJung-uk Kim     case ACPI_TYPE_STRING:
294*a159c266SJung-uk Kim         Status = AcpiExConvertToString (Operand1, &LocalOperand1,
295*a159c266SJung-uk Kim                     ACPI_IMPLICIT_CONVERT_HEX);
296*a159c266SJung-uk Kim         break;
297*a159c266SJung-uk Kim 
298*a159c266SJung-uk Kim     case ACPI_TYPE_BUFFER:
299*a159c266SJung-uk Kim         Status = AcpiExConvertToBuffer (Operand1, &LocalOperand1);
300*a159c266SJung-uk Kim         break;
301*a159c266SJung-uk Kim 
302*a159c266SJung-uk Kim     default:
303*a159c266SJung-uk Kim         ACPI_ERROR ((AE_INFO, "Invalid object type: 0x%X",
304*a159c266SJung-uk Kim             Operand0->Common.Type));
305*a159c266SJung-uk Kim         Status = AE_AML_INTERNAL;
306*a159c266SJung-uk Kim     }
307*a159c266SJung-uk Kim 
308*a159c266SJung-uk Kim     if (ACPI_FAILURE (Status))
309*a159c266SJung-uk Kim     {
310*a159c266SJung-uk Kim         goto Cleanup;
311*a159c266SJung-uk Kim     }
312*a159c266SJung-uk Kim 
313*a159c266SJung-uk Kim     /*
314*a159c266SJung-uk Kim      * Both operands are now known to be the same object type
315*a159c266SJung-uk Kim      * (Both are Integer, String, or Buffer), and we can now perform the
316*a159c266SJung-uk Kim      * concatenation.
317*a159c266SJung-uk Kim      */
318*a159c266SJung-uk Kim 
319*a159c266SJung-uk Kim     /*
320*a159c266SJung-uk Kim      * There are three cases to handle:
321*a159c266SJung-uk Kim      *
322*a159c266SJung-uk Kim      * 1) Two Integers concatenated to produce a new Buffer
323*a159c266SJung-uk Kim      * 2) Two Strings concatenated to produce a new String
324*a159c266SJung-uk Kim      * 3) Two Buffers concatenated to produce a new Buffer
325*a159c266SJung-uk Kim      */
326*a159c266SJung-uk Kim     switch (Operand0->Common.Type)
327*a159c266SJung-uk Kim     {
328*a159c266SJung-uk Kim     case ACPI_TYPE_INTEGER:
329*a159c266SJung-uk Kim 
330*a159c266SJung-uk Kim         /* Result of two Integers is a Buffer */
331*a159c266SJung-uk Kim         /* Need enough buffer space for two integers */
332*a159c266SJung-uk Kim 
333*a159c266SJung-uk Kim         ReturnDesc = AcpiUtCreateBufferObject ((ACPI_SIZE)
334*a159c266SJung-uk Kim                             ACPI_MUL_2 (AcpiGbl_IntegerByteWidth));
335*a159c266SJung-uk Kim         if (!ReturnDesc)
336*a159c266SJung-uk Kim         {
337*a159c266SJung-uk Kim             Status = AE_NO_MEMORY;
338*a159c266SJung-uk Kim             goto Cleanup;
339*a159c266SJung-uk Kim         }
340*a159c266SJung-uk Kim 
341*a159c266SJung-uk Kim         NewBuf = (char *) ReturnDesc->Buffer.Pointer;
342*a159c266SJung-uk Kim 
343*a159c266SJung-uk Kim         /* Copy the first integer, LSB first */
344*a159c266SJung-uk Kim 
345*a159c266SJung-uk Kim         ACPI_MEMCPY (NewBuf, &Operand0->Integer.Value,
346*a159c266SJung-uk Kim                         AcpiGbl_IntegerByteWidth);
347*a159c266SJung-uk Kim 
348*a159c266SJung-uk Kim         /* Copy the second integer (LSB first) after the first */
349*a159c266SJung-uk Kim 
350*a159c266SJung-uk Kim         ACPI_MEMCPY (NewBuf + AcpiGbl_IntegerByteWidth,
351*a159c266SJung-uk Kim                         &LocalOperand1->Integer.Value,
352*a159c266SJung-uk Kim                         AcpiGbl_IntegerByteWidth);
353*a159c266SJung-uk Kim         break;
354*a159c266SJung-uk Kim 
355*a159c266SJung-uk Kim     case ACPI_TYPE_STRING:
356*a159c266SJung-uk Kim 
357*a159c266SJung-uk Kim         /* Result of two Strings is a String */
358*a159c266SJung-uk Kim 
359*a159c266SJung-uk Kim         ReturnDesc = AcpiUtCreateStringObject (
360*a159c266SJung-uk Kim                         ((ACPI_SIZE) Operand0->String.Length +
361*a159c266SJung-uk Kim                         LocalOperand1->String.Length));
362*a159c266SJung-uk Kim         if (!ReturnDesc)
363*a159c266SJung-uk Kim         {
364*a159c266SJung-uk Kim             Status = AE_NO_MEMORY;
365*a159c266SJung-uk Kim             goto Cleanup;
366*a159c266SJung-uk Kim         }
367*a159c266SJung-uk Kim 
368*a159c266SJung-uk Kim         NewBuf = ReturnDesc->String.Pointer;
369*a159c266SJung-uk Kim 
370*a159c266SJung-uk Kim         /* Concatenate the strings */
371*a159c266SJung-uk Kim 
372*a159c266SJung-uk Kim         ACPI_STRCPY (NewBuf, Operand0->String.Pointer);
373*a159c266SJung-uk Kim         ACPI_STRCPY (NewBuf + Operand0->String.Length,
374*a159c266SJung-uk Kim                         LocalOperand1->String.Pointer);
375*a159c266SJung-uk Kim         break;
376*a159c266SJung-uk Kim 
377*a159c266SJung-uk Kim     case ACPI_TYPE_BUFFER:
378*a159c266SJung-uk Kim 
379*a159c266SJung-uk Kim         /* Result of two Buffers is a Buffer */
380*a159c266SJung-uk Kim 
381*a159c266SJung-uk Kim         ReturnDesc = AcpiUtCreateBufferObject (
382*a159c266SJung-uk Kim                         ((ACPI_SIZE) Operand0->Buffer.Length +
383*a159c266SJung-uk Kim                         LocalOperand1->Buffer.Length));
384*a159c266SJung-uk Kim         if (!ReturnDesc)
385*a159c266SJung-uk Kim         {
386*a159c266SJung-uk Kim             Status = AE_NO_MEMORY;
387*a159c266SJung-uk Kim             goto Cleanup;
388*a159c266SJung-uk Kim         }
389*a159c266SJung-uk Kim 
390*a159c266SJung-uk Kim         NewBuf = (char *) ReturnDesc->Buffer.Pointer;
391*a159c266SJung-uk Kim 
392*a159c266SJung-uk Kim         /* Concatenate the buffers */
393*a159c266SJung-uk Kim 
394*a159c266SJung-uk Kim         ACPI_MEMCPY (NewBuf, Operand0->Buffer.Pointer,
395*a159c266SJung-uk Kim                         Operand0->Buffer.Length);
396*a159c266SJung-uk Kim         ACPI_MEMCPY (NewBuf + Operand0->Buffer.Length,
397*a159c266SJung-uk Kim                         LocalOperand1->Buffer.Pointer,
398*a159c266SJung-uk Kim                         LocalOperand1->Buffer.Length);
399*a159c266SJung-uk Kim         break;
400*a159c266SJung-uk Kim 
401*a159c266SJung-uk Kim     default:
402*a159c266SJung-uk Kim 
403*a159c266SJung-uk Kim         /* Invalid object type, should not happen here */
404*a159c266SJung-uk Kim 
405*a159c266SJung-uk Kim         ACPI_ERROR ((AE_INFO, "Invalid object type: 0x%X",
406*a159c266SJung-uk Kim             Operand0->Common.Type));
407*a159c266SJung-uk Kim         Status =AE_AML_INTERNAL;
408*a159c266SJung-uk Kim         goto Cleanup;
409*a159c266SJung-uk Kim     }
410*a159c266SJung-uk Kim 
411*a159c266SJung-uk Kim     *ActualReturnDesc = ReturnDesc;
412*a159c266SJung-uk Kim 
413*a159c266SJung-uk Kim Cleanup:
414*a159c266SJung-uk Kim     if (LocalOperand1 != Operand1)
415*a159c266SJung-uk Kim     {
416*a159c266SJung-uk Kim         AcpiUtRemoveReference (LocalOperand1);
417*a159c266SJung-uk Kim     }
418*a159c266SJung-uk Kim     return_ACPI_STATUS (Status);
419*a159c266SJung-uk Kim }
420*a159c266SJung-uk Kim 
421*a159c266SJung-uk Kim 
422*a159c266SJung-uk Kim /*******************************************************************************
423*a159c266SJung-uk Kim  *
424*a159c266SJung-uk Kim  * FUNCTION:    AcpiExDoMathOp
425*a159c266SJung-uk Kim  *
426*a159c266SJung-uk Kim  * PARAMETERS:  Opcode              - AML opcode
427*a159c266SJung-uk Kim  *              Integer0            - Integer operand #0
428*a159c266SJung-uk Kim  *              Integer1            - Integer operand #1
429*a159c266SJung-uk Kim  *
430*a159c266SJung-uk Kim  * RETURN:      Integer result of the operation
431*a159c266SJung-uk Kim  *
432*a159c266SJung-uk Kim  * DESCRIPTION: Execute a math AML opcode. The purpose of having all of the
433*a159c266SJung-uk Kim  *              math functions here is to prevent a lot of pointer dereferencing
434*a159c266SJung-uk Kim  *              to obtain the operands.
435*a159c266SJung-uk Kim  *
436*a159c266SJung-uk Kim  ******************************************************************************/
437*a159c266SJung-uk Kim 
438*a159c266SJung-uk Kim UINT64
439*a159c266SJung-uk Kim AcpiExDoMathOp (
440*a159c266SJung-uk Kim     UINT16                  Opcode,
441*a159c266SJung-uk Kim     UINT64                  Integer0,
442*a159c266SJung-uk Kim     UINT64                  Integer1)
443*a159c266SJung-uk Kim {
444*a159c266SJung-uk Kim 
445*a159c266SJung-uk Kim     ACPI_FUNCTION_ENTRY ();
446*a159c266SJung-uk Kim 
447*a159c266SJung-uk Kim 
448*a159c266SJung-uk Kim     switch (Opcode)
449*a159c266SJung-uk Kim     {
450*a159c266SJung-uk Kim     case AML_ADD_OP:                /* Add (Integer0, Integer1, Result) */
451*a159c266SJung-uk Kim 
452*a159c266SJung-uk Kim         return (Integer0 + Integer1);
453*a159c266SJung-uk Kim 
454*a159c266SJung-uk Kim 
455*a159c266SJung-uk Kim     case AML_BIT_AND_OP:            /* And (Integer0, Integer1, Result) */
456*a159c266SJung-uk Kim 
457*a159c266SJung-uk Kim         return (Integer0 & Integer1);
458*a159c266SJung-uk Kim 
459*a159c266SJung-uk Kim 
460*a159c266SJung-uk Kim     case AML_BIT_NAND_OP:           /* NAnd (Integer0, Integer1, Result) */
461*a159c266SJung-uk Kim 
462*a159c266SJung-uk Kim         return (~(Integer0 & Integer1));
463*a159c266SJung-uk Kim 
464*a159c266SJung-uk Kim 
465*a159c266SJung-uk Kim     case AML_BIT_OR_OP:             /* Or (Integer0, Integer1, Result) */
466*a159c266SJung-uk Kim 
467*a159c266SJung-uk Kim         return (Integer0 | Integer1);
468*a159c266SJung-uk Kim 
469*a159c266SJung-uk Kim 
470*a159c266SJung-uk Kim     case AML_BIT_NOR_OP:            /* NOr (Integer0, Integer1, Result) */
471*a159c266SJung-uk Kim 
472*a159c266SJung-uk Kim         return (~(Integer0 | Integer1));
473*a159c266SJung-uk Kim 
474*a159c266SJung-uk Kim 
475*a159c266SJung-uk Kim     case AML_BIT_XOR_OP:            /* XOr (Integer0, Integer1, Result) */
476*a159c266SJung-uk Kim 
477*a159c266SJung-uk Kim         return (Integer0 ^ Integer1);
478*a159c266SJung-uk Kim 
479*a159c266SJung-uk Kim 
480*a159c266SJung-uk Kim     case AML_MULTIPLY_OP:           /* Multiply (Integer0, Integer1, Result) */
481*a159c266SJung-uk Kim 
482*a159c266SJung-uk Kim         return (Integer0 * Integer1);
483*a159c266SJung-uk Kim 
484*a159c266SJung-uk Kim 
485*a159c266SJung-uk Kim     case AML_SHIFT_LEFT_OP:         /* ShiftLeft (Operand, ShiftCount, Result)*/
486*a159c266SJung-uk Kim 
487*a159c266SJung-uk Kim         /*
488*a159c266SJung-uk Kim          * We need to check if the shiftcount is larger than the integer bit
489*a159c266SJung-uk Kim          * width since the behavior of this is not well-defined in the C language.
490*a159c266SJung-uk Kim          */
491*a159c266SJung-uk Kim         if (Integer1 >= AcpiGbl_IntegerBitWidth)
492*a159c266SJung-uk Kim         {
493*a159c266SJung-uk Kim             return (0);
494*a159c266SJung-uk Kim         }
495*a159c266SJung-uk Kim         return (Integer0 << Integer1);
496*a159c266SJung-uk Kim 
497*a159c266SJung-uk Kim 
498*a159c266SJung-uk Kim     case AML_SHIFT_RIGHT_OP:        /* ShiftRight (Operand, ShiftCount, Result) */
499*a159c266SJung-uk Kim 
500*a159c266SJung-uk Kim         /*
501*a159c266SJung-uk Kim          * We need to check if the shiftcount is larger than the integer bit
502*a159c266SJung-uk Kim          * width since the behavior of this is not well-defined in the C language.
503*a159c266SJung-uk Kim          */
504*a159c266SJung-uk Kim         if (Integer1 >= AcpiGbl_IntegerBitWidth)
505*a159c266SJung-uk Kim         {
506*a159c266SJung-uk Kim             return (0);
507*a159c266SJung-uk Kim         }
508*a159c266SJung-uk Kim         return (Integer0 >> Integer1);
509*a159c266SJung-uk Kim 
510*a159c266SJung-uk Kim 
511*a159c266SJung-uk Kim     case AML_SUBTRACT_OP:           /* Subtract (Integer0, Integer1, Result) */
512*a159c266SJung-uk Kim 
513*a159c266SJung-uk Kim         return (Integer0 - Integer1);
514*a159c266SJung-uk Kim 
515*a159c266SJung-uk Kim     default:
516*a159c266SJung-uk Kim 
517*a159c266SJung-uk Kim         return (0);
518*a159c266SJung-uk Kim     }
519*a159c266SJung-uk Kim }
520*a159c266SJung-uk Kim 
521*a159c266SJung-uk Kim 
522*a159c266SJung-uk Kim /*******************************************************************************
523*a159c266SJung-uk Kim  *
524*a159c266SJung-uk Kim  * FUNCTION:    AcpiExDoLogicalNumericOp
525*a159c266SJung-uk Kim  *
526*a159c266SJung-uk Kim  * PARAMETERS:  Opcode              - AML opcode
527*a159c266SJung-uk Kim  *              Integer0            - Integer operand #0
528*a159c266SJung-uk Kim  *              Integer1            - Integer operand #1
529*a159c266SJung-uk Kim  *              LogicalResult       - TRUE/FALSE result of the operation
530*a159c266SJung-uk Kim  *
531*a159c266SJung-uk Kim  * RETURN:      Status
532*a159c266SJung-uk Kim  *
533*a159c266SJung-uk Kim  * DESCRIPTION: Execute a logical "Numeric" AML opcode. For these Numeric
534*a159c266SJung-uk Kim  *              operators (LAnd and LOr), both operands must be integers.
535*a159c266SJung-uk Kim  *
536*a159c266SJung-uk Kim  *              Note: cleanest machine code seems to be produced by the code
537*a159c266SJung-uk Kim  *              below, rather than using statements of the form:
538*a159c266SJung-uk Kim  *                  Result = (Integer0 && Integer1);
539*a159c266SJung-uk Kim  *
540*a159c266SJung-uk Kim  ******************************************************************************/
541*a159c266SJung-uk Kim 
542*a159c266SJung-uk Kim ACPI_STATUS
543*a159c266SJung-uk Kim AcpiExDoLogicalNumericOp (
544*a159c266SJung-uk Kim     UINT16                  Opcode,
545*a159c266SJung-uk Kim     UINT64                  Integer0,
546*a159c266SJung-uk Kim     UINT64                  Integer1,
547*a159c266SJung-uk Kim     BOOLEAN                 *LogicalResult)
548*a159c266SJung-uk Kim {
549*a159c266SJung-uk Kim     ACPI_STATUS             Status = AE_OK;
550*a159c266SJung-uk Kim     BOOLEAN                 LocalResult = FALSE;
551*a159c266SJung-uk Kim 
552*a159c266SJung-uk Kim 
553*a159c266SJung-uk Kim     ACPI_FUNCTION_TRACE (ExDoLogicalNumericOp);
554*a159c266SJung-uk Kim 
555*a159c266SJung-uk Kim 
556*a159c266SJung-uk Kim     switch (Opcode)
557*a159c266SJung-uk Kim     {
558*a159c266SJung-uk Kim     case AML_LAND_OP:               /* LAnd (Integer0, Integer1) */
559*a159c266SJung-uk Kim 
560*a159c266SJung-uk Kim         if (Integer0 && Integer1)
561*a159c266SJung-uk Kim         {
562*a159c266SJung-uk Kim             LocalResult = TRUE;
563*a159c266SJung-uk Kim         }
564*a159c266SJung-uk Kim         break;
565*a159c266SJung-uk Kim 
566*a159c266SJung-uk Kim     case AML_LOR_OP:                /* LOr (Integer0, Integer1) */
567*a159c266SJung-uk Kim 
568*a159c266SJung-uk Kim         if (Integer0 || Integer1)
569*a159c266SJung-uk Kim         {
570*a159c266SJung-uk Kim             LocalResult = TRUE;
571*a159c266SJung-uk Kim         }
572*a159c266SJung-uk Kim         break;
573*a159c266SJung-uk Kim 
574*a159c266SJung-uk Kim     default:
575*a159c266SJung-uk Kim         Status = AE_AML_INTERNAL;
576*a159c266SJung-uk Kim         break;
577*a159c266SJung-uk Kim     }
578*a159c266SJung-uk Kim 
579*a159c266SJung-uk Kim     /* Return the logical result and status */
580*a159c266SJung-uk Kim 
581*a159c266SJung-uk Kim     *LogicalResult = LocalResult;
582*a159c266SJung-uk Kim     return_ACPI_STATUS (Status);
583*a159c266SJung-uk Kim }
584*a159c266SJung-uk Kim 
585*a159c266SJung-uk Kim 
586*a159c266SJung-uk Kim /*******************************************************************************
587*a159c266SJung-uk Kim  *
588*a159c266SJung-uk Kim  * FUNCTION:    AcpiExDoLogicalOp
589*a159c266SJung-uk Kim  *
590*a159c266SJung-uk Kim  * PARAMETERS:  Opcode              - AML opcode
591*a159c266SJung-uk Kim  *              Operand0            - operand #0
592*a159c266SJung-uk Kim  *              Operand1            - operand #1
593*a159c266SJung-uk Kim  *              LogicalResult       - TRUE/FALSE result of the operation
594*a159c266SJung-uk Kim  *
595*a159c266SJung-uk Kim  * RETURN:      Status
596*a159c266SJung-uk Kim  *
597*a159c266SJung-uk Kim  * DESCRIPTION: Execute a logical AML opcode. The purpose of having all of the
598*a159c266SJung-uk Kim  *              functions here is to prevent a lot of pointer dereferencing
599*a159c266SJung-uk Kim  *              to obtain the operands and to simplify the generation of the
600*a159c266SJung-uk Kim  *              logical value. For the Numeric operators (LAnd and LOr), both
601*a159c266SJung-uk Kim  *              operands must be integers. For the other logical operators,
602*a159c266SJung-uk Kim  *              operands can be any combination of Integer/String/Buffer. The
603*a159c266SJung-uk Kim  *              first operand determines the type to which the second operand
604*a159c266SJung-uk Kim  *              will be converted.
605*a159c266SJung-uk Kim  *
606*a159c266SJung-uk Kim  *              Note: cleanest machine code seems to be produced by the code
607*a159c266SJung-uk Kim  *              below, rather than using statements of the form:
608*a159c266SJung-uk Kim  *                  Result = (Operand0 == Operand1);
609*a159c266SJung-uk Kim  *
610*a159c266SJung-uk Kim  ******************************************************************************/
611*a159c266SJung-uk Kim 
612*a159c266SJung-uk Kim ACPI_STATUS
613*a159c266SJung-uk Kim AcpiExDoLogicalOp (
614*a159c266SJung-uk Kim     UINT16                  Opcode,
615*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *Operand0,
616*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *Operand1,
617*a159c266SJung-uk Kim     BOOLEAN                 *LogicalResult)
618*a159c266SJung-uk Kim {
619*a159c266SJung-uk Kim     ACPI_OPERAND_OBJECT     *LocalOperand1 = Operand1;
620*a159c266SJung-uk Kim     UINT64                  Integer0;
621*a159c266SJung-uk Kim     UINT64                  Integer1;
622*a159c266SJung-uk Kim     UINT32                  Length0;
623*a159c266SJung-uk Kim     UINT32                  Length1;
624*a159c266SJung-uk Kim     ACPI_STATUS             Status = AE_OK;
625*a159c266SJung-uk Kim     BOOLEAN                 LocalResult = FALSE;
626*a159c266SJung-uk Kim     int                     Compare;
627*a159c266SJung-uk Kim 
628*a159c266SJung-uk Kim 
629*a159c266SJung-uk Kim     ACPI_FUNCTION_TRACE (ExDoLogicalOp);
630*a159c266SJung-uk Kim 
631*a159c266SJung-uk Kim 
632*a159c266SJung-uk Kim     /*
633*a159c266SJung-uk Kim      * Convert the second operand if necessary.  The first operand
634*a159c266SJung-uk Kim      * determines the type of the second operand, (See the Data Types
635*a159c266SJung-uk Kim      * section of the ACPI 3.0+ specification.)  Both object types are
636*a159c266SJung-uk Kim      * guaranteed to be either Integer/String/Buffer by the operand
637*a159c266SJung-uk Kim      * resolution mechanism.
638*a159c266SJung-uk Kim      */
639*a159c266SJung-uk Kim     switch (Operand0->Common.Type)
640*a159c266SJung-uk Kim     {
641*a159c266SJung-uk Kim     case ACPI_TYPE_INTEGER:
642*a159c266SJung-uk Kim         Status = AcpiExConvertToInteger (Operand1, &LocalOperand1, 16);
643*a159c266SJung-uk Kim         break;
644*a159c266SJung-uk Kim 
645*a159c266SJung-uk Kim     case ACPI_TYPE_STRING:
646*a159c266SJung-uk Kim         Status = AcpiExConvertToString (Operand1, &LocalOperand1,
647*a159c266SJung-uk Kim                     ACPI_IMPLICIT_CONVERT_HEX);
648*a159c266SJung-uk Kim         break;
649*a159c266SJung-uk Kim 
650*a159c266SJung-uk Kim     case ACPI_TYPE_BUFFER:
651*a159c266SJung-uk Kim         Status = AcpiExConvertToBuffer (Operand1, &LocalOperand1);
652*a159c266SJung-uk Kim         break;
653*a159c266SJung-uk Kim 
654*a159c266SJung-uk Kim     default:
655*a159c266SJung-uk Kim         Status = AE_AML_INTERNAL;
656*a159c266SJung-uk Kim         break;
657*a159c266SJung-uk Kim     }
658*a159c266SJung-uk Kim 
659*a159c266SJung-uk Kim     if (ACPI_FAILURE (Status))
660*a159c266SJung-uk Kim     {
661*a159c266SJung-uk Kim         goto Cleanup;
662*a159c266SJung-uk Kim     }
663*a159c266SJung-uk Kim 
664*a159c266SJung-uk Kim     /*
665*a159c266SJung-uk Kim      * Two cases: 1) Both Integers, 2) Both Strings or Buffers
666*a159c266SJung-uk Kim      */
667*a159c266SJung-uk Kim     if (Operand0->Common.Type == ACPI_TYPE_INTEGER)
668*a159c266SJung-uk Kim     {
669*a159c266SJung-uk Kim         /*
670*a159c266SJung-uk Kim          * 1) Both operands are of type integer
671*a159c266SJung-uk Kim          *    Note: LocalOperand1 may have changed above
672*a159c266SJung-uk Kim          */
673*a159c266SJung-uk Kim         Integer0 = Operand0->Integer.Value;
674*a159c266SJung-uk Kim         Integer1 = LocalOperand1->Integer.Value;
675*a159c266SJung-uk Kim 
676*a159c266SJung-uk Kim         switch (Opcode)
677*a159c266SJung-uk Kim         {
678*a159c266SJung-uk Kim         case AML_LEQUAL_OP:             /* LEqual (Operand0, Operand1) */
679*a159c266SJung-uk Kim 
680*a159c266SJung-uk Kim             if (Integer0 == Integer1)
681*a159c266SJung-uk Kim             {
682*a159c266SJung-uk Kim                 LocalResult = TRUE;
683*a159c266SJung-uk Kim             }
684*a159c266SJung-uk Kim             break;
685*a159c266SJung-uk Kim 
686*a159c266SJung-uk Kim         case AML_LGREATER_OP:           /* LGreater (Operand0, Operand1) */
687*a159c266SJung-uk Kim 
688*a159c266SJung-uk Kim             if (Integer0 > Integer1)
689*a159c266SJung-uk Kim             {
690*a159c266SJung-uk Kim                 LocalResult = TRUE;
691*a159c266SJung-uk Kim             }
692*a159c266SJung-uk Kim             break;
693*a159c266SJung-uk Kim 
694*a159c266SJung-uk Kim         case AML_LLESS_OP:              /* LLess (Operand0, Operand1) */
695*a159c266SJung-uk Kim 
696*a159c266SJung-uk Kim             if (Integer0 < Integer1)
697*a159c266SJung-uk Kim             {
698*a159c266SJung-uk Kim                 LocalResult = TRUE;
699*a159c266SJung-uk Kim             }
700*a159c266SJung-uk Kim             break;
701*a159c266SJung-uk Kim 
702*a159c266SJung-uk Kim         default:
703*a159c266SJung-uk Kim             Status = AE_AML_INTERNAL;
704*a159c266SJung-uk Kim             break;
705*a159c266SJung-uk Kim         }
706*a159c266SJung-uk Kim     }
707*a159c266SJung-uk Kim     else
708*a159c266SJung-uk Kim     {
709*a159c266SJung-uk Kim         /*
710*a159c266SJung-uk Kim          * 2) Both operands are Strings or both are Buffers
711*a159c266SJung-uk Kim          *    Note: Code below takes advantage of common Buffer/String
712*a159c266SJung-uk Kim          *          object fields. LocalOperand1 may have changed above. Use
713*a159c266SJung-uk Kim          *          memcmp to handle nulls in buffers.
714*a159c266SJung-uk Kim          */
715*a159c266SJung-uk Kim         Length0 = Operand0->Buffer.Length;
716*a159c266SJung-uk Kim         Length1 = LocalOperand1->Buffer.Length;
717*a159c266SJung-uk Kim 
718*a159c266SJung-uk Kim         /* Lexicographic compare: compare the data bytes */
719*a159c266SJung-uk Kim 
720*a159c266SJung-uk Kim         Compare = ACPI_MEMCMP (Operand0->Buffer.Pointer,
721*a159c266SJung-uk Kim                     LocalOperand1->Buffer.Pointer,
722*a159c266SJung-uk Kim                     (Length0 > Length1) ? Length1 : Length0);
723*a159c266SJung-uk Kim 
724*a159c266SJung-uk Kim         switch (Opcode)
725*a159c266SJung-uk Kim         {
726*a159c266SJung-uk Kim         case AML_LEQUAL_OP:             /* LEqual (Operand0, Operand1) */
727*a159c266SJung-uk Kim 
728*a159c266SJung-uk Kim             /* Length and all bytes must be equal */
729*a159c266SJung-uk Kim 
730*a159c266SJung-uk Kim             if ((Length0 == Length1) &&
731*a159c266SJung-uk Kim                 (Compare == 0))
732*a159c266SJung-uk Kim             {
733*a159c266SJung-uk Kim                 /* Length and all bytes match ==> TRUE */
734*a159c266SJung-uk Kim 
735*a159c266SJung-uk Kim                 LocalResult = TRUE;
736*a159c266SJung-uk Kim             }
737*a159c266SJung-uk Kim             break;
738*a159c266SJung-uk Kim 
739*a159c266SJung-uk Kim         case AML_LGREATER_OP:           /* LGreater (Operand0, Operand1) */
740*a159c266SJung-uk Kim 
741*a159c266SJung-uk Kim             if (Compare > 0)
742*a159c266SJung-uk Kim             {
743*a159c266SJung-uk Kim                 LocalResult = TRUE;
744*a159c266SJung-uk Kim                 goto Cleanup;   /* TRUE */
745*a159c266SJung-uk Kim             }
746*a159c266SJung-uk Kim             if (Compare < 0)
747*a159c266SJung-uk Kim             {
748*a159c266SJung-uk Kim                 goto Cleanup;   /* FALSE */
749*a159c266SJung-uk Kim             }
750*a159c266SJung-uk Kim 
751*a159c266SJung-uk Kim             /* Bytes match (to shortest length), compare lengths */
752*a159c266SJung-uk Kim 
753*a159c266SJung-uk Kim             if (Length0 > Length1)
754*a159c266SJung-uk Kim             {
755*a159c266SJung-uk Kim                 LocalResult = TRUE;
756*a159c266SJung-uk Kim             }
757*a159c266SJung-uk Kim             break;
758*a159c266SJung-uk Kim 
759*a159c266SJung-uk Kim         case AML_LLESS_OP:              /* LLess (Operand0, Operand1) */
760*a159c266SJung-uk Kim 
761*a159c266SJung-uk Kim             if (Compare > 0)
762*a159c266SJung-uk Kim             {
763*a159c266SJung-uk Kim                 goto Cleanup;   /* FALSE */
764*a159c266SJung-uk Kim             }
765*a159c266SJung-uk Kim             if (Compare < 0)
766*a159c266SJung-uk Kim             {
767*a159c266SJung-uk Kim                 LocalResult = TRUE;
768*a159c266SJung-uk Kim                 goto Cleanup;   /* TRUE */
769*a159c266SJung-uk Kim             }
770*a159c266SJung-uk Kim 
771*a159c266SJung-uk Kim             /* Bytes match (to shortest length), compare lengths */
772*a159c266SJung-uk Kim 
773*a159c266SJung-uk Kim             if (Length0 < Length1)
774*a159c266SJung-uk Kim             {
775*a159c266SJung-uk Kim                 LocalResult = TRUE;
776*a159c266SJung-uk Kim             }
777*a159c266SJung-uk Kim             break;
778*a159c266SJung-uk Kim 
779*a159c266SJung-uk Kim         default:
780*a159c266SJung-uk Kim             Status = AE_AML_INTERNAL;
781*a159c266SJung-uk Kim             break;
782*a159c266SJung-uk Kim         }
783*a159c266SJung-uk Kim     }
784*a159c266SJung-uk Kim 
785*a159c266SJung-uk Kim Cleanup:
786*a159c266SJung-uk Kim 
787*a159c266SJung-uk Kim     /* New object was created if implicit conversion performed - delete */
788*a159c266SJung-uk Kim 
789*a159c266SJung-uk Kim     if (LocalOperand1 != Operand1)
790*a159c266SJung-uk Kim     {
791*a159c266SJung-uk Kim         AcpiUtRemoveReference (LocalOperand1);
792*a159c266SJung-uk Kim     }
793*a159c266SJung-uk Kim 
794*a159c266SJung-uk Kim     /* Return the logical result and status */
795*a159c266SJung-uk Kim 
796*a159c266SJung-uk Kim     *LogicalResult = LocalResult;
797*a159c266SJung-uk Kim     return_ACPI_STATUS (Status);
798*a159c266SJung-uk Kim }
799*a159c266SJung-uk Kim 
800*a159c266SJung-uk Kim 
801