xref: /minix3/minix/drivers/power/acpi/executer/exmisc.c (revision 29492bb71c7148a089a5afafa0c99409161218df)
1433d6423SLionel Sambuc /******************************************************************************
2433d6423SLionel Sambuc  *
3433d6423SLionel Sambuc  * Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes
4433d6423SLionel Sambuc  *
5433d6423SLionel Sambuc  *****************************************************************************/
6433d6423SLionel Sambuc 
7*29492bb7SDavid van Moolenbroek /*
8*29492bb7SDavid van Moolenbroek  * Copyright (C) 2000 - 2014, Intel Corp.
9433d6423SLionel Sambuc  * All rights reserved.
10433d6423SLionel Sambuc  *
11*29492bb7SDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
12*29492bb7SDavid van Moolenbroek  * modification, are permitted provided that the following conditions
13*29492bb7SDavid van Moolenbroek  * are met:
14*29492bb7SDavid van Moolenbroek  * 1. Redistributions of source code must retain the above copyright
15*29492bb7SDavid van Moolenbroek  *    notice, this list of conditions, and the following disclaimer,
16*29492bb7SDavid van Moolenbroek  *    without modification.
17*29492bb7SDavid van Moolenbroek  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18*29492bb7SDavid van Moolenbroek  *    substantially similar to the "NO WARRANTY" disclaimer below
19*29492bb7SDavid van Moolenbroek  *    ("Disclaimer") and any redistribution must be conditioned upon
20*29492bb7SDavid van Moolenbroek  *    including a substantially similar Disclaimer requirement for further
21*29492bb7SDavid van Moolenbroek  *    binary redistribution.
22*29492bb7SDavid van Moolenbroek  * 3. Neither the names of the above-listed copyright holders nor the names
23*29492bb7SDavid van Moolenbroek  *    of any contributors may be used to endorse or promote products derived
24*29492bb7SDavid van Moolenbroek  *    from this software without specific prior written permission.
25433d6423SLionel Sambuc  *
26*29492bb7SDavid van Moolenbroek  * Alternatively, this software may be distributed under the terms of the
27*29492bb7SDavid van Moolenbroek  * GNU General Public License ("GPL") version 2 as published by the Free
28*29492bb7SDavid van Moolenbroek  * Software Foundation.
29433d6423SLionel Sambuc  *
30*29492bb7SDavid van Moolenbroek  * NO WARRANTY
31*29492bb7SDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32*29492bb7SDavid van Moolenbroek  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33*29492bb7SDavid van Moolenbroek  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34*29492bb7SDavid van Moolenbroek  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35*29492bb7SDavid van Moolenbroek  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36*29492bb7SDavid van Moolenbroek  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37*29492bb7SDavid van Moolenbroek  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38*29492bb7SDavid van Moolenbroek  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39*29492bb7SDavid van Moolenbroek  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40*29492bb7SDavid van Moolenbroek  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41*29492bb7SDavid van Moolenbroek  * POSSIBILITY OF SUCH DAMAGES.
42*29492bb7SDavid van Moolenbroek  */
43433d6423SLionel Sambuc 
44433d6423SLionel Sambuc #include "acpi.h"
45433d6423SLionel Sambuc #include "accommon.h"
46433d6423SLionel Sambuc #include "acinterp.h"
47433d6423SLionel Sambuc #include "amlcode.h"
48433d6423SLionel Sambuc #include "amlresrc.h"
49433d6423SLionel Sambuc 
50433d6423SLionel Sambuc 
51433d6423SLionel Sambuc #define _COMPONENT          ACPI_EXECUTER
52433d6423SLionel Sambuc         ACPI_MODULE_NAME    ("exmisc")
53433d6423SLionel Sambuc 
54433d6423SLionel Sambuc 
55433d6423SLionel Sambuc /*******************************************************************************
56433d6423SLionel Sambuc  *
57433d6423SLionel Sambuc  * FUNCTION:    AcpiExGetObjectReference
58433d6423SLionel Sambuc  *
59433d6423SLionel Sambuc  * PARAMETERS:  ObjDesc             - Create a reference to this object
60433d6423SLionel Sambuc  *              ReturnDesc          - Where to store the reference
61433d6423SLionel Sambuc  *              WalkState           - Current state
62433d6423SLionel Sambuc  *
63433d6423SLionel Sambuc  * RETURN:      Status
64433d6423SLionel Sambuc  *
65433d6423SLionel Sambuc  * DESCRIPTION: Obtain and return a "reference" to the target object
66433d6423SLionel Sambuc  *              Common code for the RefOfOp and the CondRefOfOp.
67433d6423SLionel Sambuc  *
68433d6423SLionel Sambuc  ******************************************************************************/
69433d6423SLionel Sambuc 
70433d6423SLionel Sambuc ACPI_STATUS
AcpiExGetObjectReference(ACPI_OPERAND_OBJECT * ObjDesc,ACPI_OPERAND_OBJECT ** ReturnDesc,ACPI_WALK_STATE * WalkState)71433d6423SLionel Sambuc AcpiExGetObjectReference (
72433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ObjDesc,
73433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     **ReturnDesc,
74433d6423SLionel Sambuc     ACPI_WALK_STATE         *WalkState)
75433d6423SLionel Sambuc {
76433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ReferenceObj;
77433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ReferencedObj;
78433d6423SLionel Sambuc 
79433d6423SLionel Sambuc 
80433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE_PTR (ExGetObjectReference, ObjDesc);
81433d6423SLionel Sambuc 
82433d6423SLionel Sambuc 
83433d6423SLionel Sambuc     *ReturnDesc = NULL;
84433d6423SLionel Sambuc 
85433d6423SLionel Sambuc     switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))
86433d6423SLionel Sambuc     {
87433d6423SLionel Sambuc     case ACPI_DESC_TYPE_OPERAND:
88433d6423SLionel Sambuc 
89433d6423SLionel Sambuc         if (ObjDesc->Common.Type != ACPI_TYPE_LOCAL_REFERENCE)
90433d6423SLionel Sambuc         {
91433d6423SLionel Sambuc             return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
92433d6423SLionel Sambuc         }
93433d6423SLionel Sambuc 
94433d6423SLionel Sambuc         /*
95433d6423SLionel Sambuc          * Must be a reference to a Local or Arg
96433d6423SLionel Sambuc          */
97433d6423SLionel Sambuc         switch (ObjDesc->Reference.Class)
98433d6423SLionel Sambuc         {
99433d6423SLionel Sambuc         case ACPI_REFCLASS_LOCAL:
100433d6423SLionel Sambuc         case ACPI_REFCLASS_ARG:
101433d6423SLionel Sambuc         case ACPI_REFCLASS_DEBUG:
102433d6423SLionel Sambuc 
103433d6423SLionel Sambuc             /* The referenced object is the pseudo-node for the local/arg */
104433d6423SLionel Sambuc 
105433d6423SLionel Sambuc             ReferencedObj = ObjDesc->Reference.Object;
106433d6423SLionel Sambuc             break;
107433d6423SLionel Sambuc 
108433d6423SLionel Sambuc         default:
109433d6423SLionel Sambuc 
110433d6423SLionel Sambuc             ACPI_ERROR ((AE_INFO, "Unknown Reference Class 0x%2.2X",
111433d6423SLionel Sambuc                 ObjDesc->Reference.Class));
112433d6423SLionel Sambuc             return_ACPI_STATUS (AE_AML_INTERNAL);
113433d6423SLionel Sambuc         }
114433d6423SLionel Sambuc         break;
115433d6423SLionel Sambuc 
116433d6423SLionel Sambuc     case ACPI_DESC_TYPE_NAMED:
117433d6423SLionel Sambuc         /*
118433d6423SLionel Sambuc          * A named reference that has already been resolved to a Node
119433d6423SLionel Sambuc          */
120433d6423SLionel Sambuc         ReferencedObj = ObjDesc;
121433d6423SLionel Sambuc         break;
122433d6423SLionel Sambuc 
123433d6423SLionel Sambuc     default:
124433d6423SLionel Sambuc 
125433d6423SLionel Sambuc         ACPI_ERROR ((AE_INFO, "Invalid descriptor type 0x%X",
126433d6423SLionel Sambuc             ACPI_GET_DESCRIPTOR_TYPE (ObjDesc)));
127433d6423SLionel Sambuc         return_ACPI_STATUS (AE_TYPE);
128433d6423SLionel Sambuc     }
129433d6423SLionel Sambuc 
130433d6423SLionel Sambuc 
131433d6423SLionel Sambuc     /* Create a new reference object */
132433d6423SLionel Sambuc 
133433d6423SLionel Sambuc     ReferenceObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_REFERENCE);
134433d6423SLionel Sambuc     if (!ReferenceObj)
135433d6423SLionel Sambuc     {
136433d6423SLionel Sambuc         return_ACPI_STATUS (AE_NO_MEMORY);
137433d6423SLionel Sambuc     }
138433d6423SLionel Sambuc 
139433d6423SLionel Sambuc     ReferenceObj->Reference.Class = ACPI_REFCLASS_REFOF;
140433d6423SLionel Sambuc     ReferenceObj->Reference.Object = ReferencedObj;
141433d6423SLionel Sambuc     *ReturnDesc = ReferenceObj;
142433d6423SLionel Sambuc 
143433d6423SLionel Sambuc     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
144433d6423SLionel Sambuc         "Object %p Type [%s], returning Reference %p\n",
145433d6423SLionel Sambuc         ObjDesc, AcpiUtGetObjectTypeName (ObjDesc), *ReturnDesc));
146433d6423SLionel Sambuc 
147433d6423SLionel Sambuc     return_ACPI_STATUS (AE_OK);
148433d6423SLionel Sambuc }
149433d6423SLionel Sambuc 
150433d6423SLionel Sambuc 
151433d6423SLionel Sambuc /*******************************************************************************
152433d6423SLionel Sambuc  *
153433d6423SLionel Sambuc  * FUNCTION:    AcpiExConcatTemplate
154433d6423SLionel Sambuc  *
155433d6423SLionel Sambuc  * PARAMETERS:  Operand0            - First source object
156433d6423SLionel Sambuc  *              Operand1            - Second source object
157433d6423SLionel Sambuc  *              ActualReturnDesc    - Where to place the return object
158433d6423SLionel Sambuc  *              WalkState           - Current walk state
159433d6423SLionel Sambuc  *
160433d6423SLionel Sambuc  * RETURN:      Status
161433d6423SLionel Sambuc  *
162433d6423SLionel Sambuc  * DESCRIPTION: Concatenate two resource templates
163433d6423SLionel Sambuc  *
164433d6423SLionel Sambuc  ******************************************************************************/
165433d6423SLionel Sambuc 
166433d6423SLionel Sambuc ACPI_STATUS
AcpiExConcatTemplate(ACPI_OPERAND_OBJECT * Operand0,ACPI_OPERAND_OBJECT * Operand1,ACPI_OPERAND_OBJECT ** ActualReturnDesc,ACPI_WALK_STATE * WalkState)167433d6423SLionel Sambuc AcpiExConcatTemplate (
168433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *Operand0,
169433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *Operand1,
170433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     **ActualReturnDesc,
171433d6423SLionel Sambuc     ACPI_WALK_STATE         *WalkState)
172433d6423SLionel Sambuc {
173433d6423SLionel Sambuc     ACPI_STATUS             Status;
174433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ReturnDesc;
175433d6423SLionel Sambuc     UINT8                   *NewBuf;
176433d6423SLionel Sambuc     UINT8                   *EndTag;
177433d6423SLionel Sambuc     ACPI_SIZE               Length0;
178433d6423SLionel Sambuc     ACPI_SIZE               Length1;
179433d6423SLionel Sambuc     ACPI_SIZE               NewLength;
180433d6423SLionel Sambuc 
181433d6423SLionel Sambuc 
182433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (ExConcatTemplate);
183433d6423SLionel Sambuc 
184433d6423SLionel Sambuc 
185433d6423SLionel Sambuc     /*
186433d6423SLionel Sambuc      * Find the EndTag descriptor in each resource template.
187433d6423SLionel Sambuc      * Note1: returned pointers point TO the EndTag, not past it.
188433d6423SLionel Sambuc      * Note2: zero-length buffers are allowed; treated like one EndTag
189433d6423SLionel Sambuc      */
190433d6423SLionel Sambuc 
191433d6423SLionel Sambuc     /* Get the length of the first resource template */
192433d6423SLionel Sambuc 
193433d6423SLionel Sambuc     Status = AcpiUtGetResourceEndTag (Operand0, &EndTag);
194433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
195433d6423SLionel Sambuc     {
196433d6423SLionel Sambuc         return_ACPI_STATUS (Status);
197433d6423SLionel Sambuc     }
198433d6423SLionel Sambuc 
199433d6423SLionel Sambuc     Length0 = ACPI_PTR_DIFF (EndTag, Operand0->Buffer.Pointer);
200433d6423SLionel Sambuc 
201433d6423SLionel Sambuc     /* Get the length of the second resource template */
202433d6423SLionel Sambuc 
203433d6423SLionel Sambuc     Status = AcpiUtGetResourceEndTag (Operand1, &EndTag);
204433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
205433d6423SLionel Sambuc     {
206433d6423SLionel Sambuc         return_ACPI_STATUS (Status);
207433d6423SLionel Sambuc     }
208433d6423SLionel Sambuc 
209433d6423SLionel Sambuc     Length1 = ACPI_PTR_DIFF (EndTag, Operand1->Buffer.Pointer);
210433d6423SLionel Sambuc 
211433d6423SLionel Sambuc     /* Combine both lengths, minimum size will be 2 for EndTag */
212433d6423SLionel Sambuc 
213433d6423SLionel Sambuc     NewLength = Length0 + Length1 + sizeof (AML_RESOURCE_END_TAG);
214433d6423SLionel Sambuc 
215433d6423SLionel Sambuc     /* Create a new buffer object for the result (with one EndTag) */
216433d6423SLionel Sambuc 
217433d6423SLionel Sambuc     ReturnDesc = AcpiUtCreateBufferObject (NewLength);
218433d6423SLionel Sambuc     if (!ReturnDesc)
219433d6423SLionel Sambuc     {
220433d6423SLionel Sambuc         return_ACPI_STATUS (AE_NO_MEMORY);
221433d6423SLionel Sambuc     }
222433d6423SLionel Sambuc 
223433d6423SLionel Sambuc     /*
224433d6423SLionel Sambuc      * Copy the templates to the new buffer, 0 first, then 1 follows. One
225433d6423SLionel Sambuc      * EndTag descriptor is copied from Operand1.
226433d6423SLionel Sambuc      */
227433d6423SLionel Sambuc     NewBuf = ReturnDesc->Buffer.Pointer;
228433d6423SLionel Sambuc     ACPI_MEMCPY (NewBuf, Operand0->Buffer.Pointer, Length0);
229433d6423SLionel Sambuc     ACPI_MEMCPY (NewBuf + Length0, Operand1->Buffer.Pointer, Length1);
230433d6423SLionel Sambuc 
231433d6423SLionel Sambuc     /* Insert EndTag and set the checksum to zero, means "ignore checksum" */
232433d6423SLionel Sambuc 
233433d6423SLionel Sambuc     NewBuf[NewLength - 1] = 0;
234433d6423SLionel Sambuc     NewBuf[NewLength - 2] = ACPI_RESOURCE_NAME_END_TAG | 1;
235433d6423SLionel Sambuc 
236433d6423SLionel Sambuc     /* Return the completed resource template */
237433d6423SLionel Sambuc 
238433d6423SLionel Sambuc     *ActualReturnDesc = ReturnDesc;
239433d6423SLionel Sambuc     return_ACPI_STATUS (AE_OK);
240433d6423SLionel Sambuc }
241433d6423SLionel Sambuc 
242433d6423SLionel Sambuc 
243433d6423SLionel Sambuc /*******************************************************************************
244433d6423SLionel Sambuc  *
245433d6423SLionel Sambuc  * FUNCTION:    AcpiExDoConcatenate
246433d6423SLionel Sambuc  *
247433d6423SLionel Sambuc  * PARAMETERS:  Operand0            - First source object
248433d6423SLionel Sambuc  *              Operand1            - Second source object
249433d6423SLionel Sambuc  *              ActualReturnDesc    - Where to place the return object
250433d6423SLionel Sambuc  *              WalkState           - Current walk state
251433d6423SLionel Sambuc  *
252433d6423SLionel Sambuc  * RETURN:      Status
253433d6423SLionel Sambuc  *
254433d6423SLionel Sambuc  * DESCRIPTION: Concatenate two objects OF THE SAME TYPE.
255433d6423SLionel Sambuc  *
256433d6423SLionel Sambuc  ******************************************************************************/
257433d6423SLionel Sambuc 
258433d6423SLionel Sambuc ACPI_STATUS
AcpiExDoConcatenate(ACPI_OPERAND_OBJECT * Operand0,ACPI_OPERAND_OBJECT * Operand1,ACPI_OPERAND_OBJECT ** ActualReturnDesc,ACPI_WALK_STATE * WalkState)259433d6423SLionel Sambuc AcpiExDoConcatenate (
260433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *Operand0,
261433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *Operand1,
262433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     **ActualReturnDesc,
263433d6423SLionel Sambuc     ACPI_WALK_STATE         *WalkState)
264433d6423SLionel Sambuc {
265433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *LocalOperand1 = Operand1;
266433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *ReturnDesc;
267433d6423SLionel Sambuc     char                    *NewBuf;
268433d6423SLionel Sambuc     ACPI_STATUS             Status;
269433d6423SLionel Sambuc 
270433d6423SLionel Sambuc 
271433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (ExDoConcatenate);
272433d6423SLionel Sambuc 
273433d6423SLionel Sambuc 
274433d6423SLionel Sambuc     /*
275433d6423SLionel Sambuc      * Convert the second operand if necessary. The first operand
276433d6423SLionel Sambuc      * determines the type of the second operand, (See the Data Types
277433d6423SLionel Sambuc      * section of the ACPI specification.)  Both object types are
278433d6423SLionel Sambuc      * guaranteed to be either Integer/String/Buffer by the operand
279433d6423SLionel Sambuc      * resolution mechanism.
280433d6423SLionel Sambuc      */
281433d6423SLionel Sambuc     switch (Operand0->Common.Type)
282433d6423SLionel Sambuc     {
283433d6423SLionel Sambuc     case ACPI_TYPE_INTEGER:
284*29492bb7SDavid van Moolenbroek 
285433d6423SLionel Sambuc         Status = AcpiExConvertToInteger (Operand1, &LocalOperand1, 16);
286433d6423SLionel Sambuc         break;
287433d6423SLionel Sambuc 
288433d6423SLionel Sambuc     case ACPI_TYPE_STRING:
289*29492bb7SDavid van Moolenbroek 
290433d6423SLionel Sambuc         Status = AcpiExConvertToString (Operand1, &LocalOperand1,
291433d6423SLionel Sambuc                     ACPI_IMPLICIT_CONVERT_HEX);
292433d6423SLionel Sambuc         break;
293433d6423SLionel Sambuc 
294433d6423SLionel Sambuc     case ACPI_TYPE_BUFFER:
295*29492bb7SDavid van Moolenbroek 
296433d6423SLionel Sambuc         Status = AcpiExConvertToBuffer (Operand1, &LocalOperand1);
297433d6423SLionel Sambuc         break;
298433d6423SLionel Sambuc 
299433d6423SLionel Sambuc     default:
300*29492bb7SDavid van Moolenbroek 
301433d6423SLionel Sambuc         ACPI_ERROR ((AE_INFO, "Invalid object type: 0x%X",
302433d6423SLionel Sambuc             Operand0->Common.Type));
303433d6423SLionel Sambuc         Status = AE_AML_INTERNAL;
304433d6423SLionel Sambuc     }
305433d6423SLionel Sambuc 
306433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
307433d6423SLionel Sambuc     {
308433d6423SLionel Sambuc         goto Cleanup;
309433d6423SLionel Sambuc     }
310433d6423SLionel Sambuc 
311433d6423SLionel Sambuc     /*
312433d6423SLionel Sambuc      * Both operands are now known to be the same object type
313433d6423SLionel Sambuc      * (Both are Integer, String, or Buffer), and we can now perform the
314433d6423SLionel Sambuc      * concatenation.
315433d6423SLionel Sambuc      */
316433d6423SLionel Sambuc 
317433d6423SLionel Sambuc     /*
318433d6423SLionel Sambuc      * There are three cases to handle:
319433d6423SLionel Sambuc      *
320433d6423SLionel Sambuc      * 1) Two Integers concatenated to produce a new Buffer
321433d6423SLionel Sambuc      * 2) Two Strings concatenated to produce a new String
322433d6423SLionel Sambuc      * 3) Two Buffers concatenated to produce a new Buffer
323433d6423SLionel Sambuc      */
324433d6423SLionel Sambuc     switch (Operand0->Common.Type)
325433d6423SLionel Sambuc     {
326433d6423SLionel Sambuc     case ACPI_TYPE_INTEGER:
327433d6423SLionel Sambuc 
328433d6423SLionel Sambuc         /* Result of two Integers is a Buffer */
329433d6423SLionel Sambuc         /* Need enough buffer space for two integers */
330433d6423SLionel Sambuc 
331433d6423SLionel Sambuc         ReturnDesc = AcpiUtCreateBufferObject ((ACPI_SIZE)
332433d6423SLionel Sambuc                             ACPI_MUL_2 (AcpiGbl_IntegerByteWidth));
333433d6423SLionel Sambuc         if (!ReturnDesc)
334433d6423SLionel Sambuc         {
335433d6423SLionel Sambuc             Status = AE_NO_MEMORY;
336433d6423SLionel Sambuc             goto Cleanup;
337433d6423SLionel Sambuc         }
338433d6423SLionel Sambuc 
339433d6423SLionel Sambuc         NewBuf = (char *) ReturnDesc->Buffer.Pointer;
340433d6423SLionel Sambuc 
341433d6423SLionel Sambuc         /* Copy the first integer, LSB first */
342433d6423SLionel Sambuc 
343433d6423SLionel Sambuc         ACPI_MEMCPY (NewBuf, &Operand0->Integer.Value,
344433d6423SLionel Sambuc                         AcpiGbl_IntegerByteWidth);
345433d6423SLionel Sambuc 
346433d6423SLionel Sambuc         /* Copy the second integer (LSB first) after the first */
347433d6423SLionel Sambuc 
348433d6423SLionel Sambuc         ACPI_MEMCPY (NewBuf + AcpiGbl_IntegerByteWidth,
349433d6423SLionel Sambuc                         &LocalOperand1->Integer.Value,
350433d6423SLionel Sambuc                         AcpiGbl_IntegerByteWidth);
351433d6423SLionel Sambuc         break;
352433d6423SLionel Sambuc 
353433d6423SLionel Sambuc     case ACPI_TYPE_STRING:
354433d6423SLionel Sambuc 
355433d6423SLionel Sambuc         /* Result of two Strings is a String */
356433d6423SLionel Sambuc 
357433d6423SLionel Sambuc         ReturnDesc = AcpiUtCreateStringObject (
358433d6423SLionel Sambuc                         ((ACPI_SIZE) Operand0->String.Length +
359433d6423SLionel Sambuc                         LocalOperand1->String.Length));
360433d6423SLionel Sambuc         if (!ReturnDesc)
361433d6423SLionel Sambuc         {
362433d6423SLionel Sambuc             Status = AE_NO_MEMORY;
363433d6423SLionel Sambuc             goto Cleanup;
364433d6423SLionel Sambuc         }
365433d6423SLionel Sambuc 
366433d6423SLionel Sambuc         NewBuf = ReturnDesc->String.Pointer;
367433d6423SLionel Sambuc 
368433d6423SLionel Sambuc         /* Concatenate the strings */
369433d6423SLionel Sambuc 
370433d6423SLionel Sambuc         ACPI_STRCPY (NewBuf, Operand0->String.Pointer);
371433d6423SLionel Sambuc         ACPI_STRCPY (NewBuf + Operand0->String.Length,
372433d6423SLionel Sambuc                         LocalOperand1->String.Pointer);
373433d6423SLionel Sambuc         break;
374433d6423SLionel Sambuc 
375433d6423SLionel Sambuc     case ACPI_TYPE_BUFFER:
376433d6423SLionel Sambuc 
377433d6423SLionel Sambuc         /* Result of two Buffers is a Buffer */
378433d6423SLionel Sambuc 
379433d6423SLionel Sambuc         ReturnDesc = AcpiUtCreateBufferObject (
380433d6423SLionel Sambuc                         ((ACPI_SIZE) Operand0->Buffer.Length +
381433d6423SLionel Sambuc                         LocalOperand1->Buffer.Length));
382433d6423SLionel Sambuc         if (!ReturnDesc)
383433d6423SLionel Sambuc         {
384433d6423SLionel Sambuc             Status = AE_NO_MEMORY;
385433d6423SLionel Sambuc             goto Cleanup;
386433d6423SLionel Sambuc         }
387433d6423SLionel Sambuc 
388433d6423SLionel Sambuc         NewBuf = (char *) ReturnDesc->Buffer.Pointer;
389433d6423SLionel Sambuc 
390433d6423SLionel Sambuc         /* Concatenate the buffers */
391433d6423SLionel Sambuc 
392433d6423SLionel Sambuc         ACPI_MEMCPY (NewBuf, Operand0->Buffer.Pointer,
393433d6423SLionel Sambuc                         Operand0->Buffer.Length);
394433d6423SLionel Sambuc         ACPI_MEMCPY (NewBuf + Operand0->Buffer.Length,
395433d6423SLionel Sambuc                         LocalOperand1->Buffer.Pointer,
396433d6423SLionel Sambuc                         LocalOperand1->Buffer.Length);
397433d6423SLionel Sambuc         break;
398433d6423SLionel Sambuc 
399433d6423SLionel Sambuc     default:
400433d6423SLionel Sambuc 
401433d6423SLionel Sambuc         /* Invalid object type, should not happen here */
402433d6423SLionel Sambuc 
403433d6423SLionel Sambuc         ACPI_ERROR ((AE_INFO, "Invalid object type: 0x%X",
404433d6423SLionel Sambuc             Operand0->Common.Type));
405433d6423SLionel Sambuc         Status =AE_AML_INTERNAL;
406433d6423SLionel Sambuc         goto Cleanup;
407433d6423SLionel Sambuc     }
408433d6423SLionel Sambuc 
409433d6423SLionel Sambuc     *ActualReturnDesc = ReturnDesc;
410433d6423SLionel Sambuc 
411433d6423SLionel Sambuc Cleanup:
412433d6423SLionel Sambuc     if (LocalOperand1 != Operand1)
413433d6423SLionel Sambuc     {
414433d6423SLionel Sambuc         AcpiUtRemoveReference (LocalOperand1);
415433d6423SLionel Sambuc     }
416433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
417433d6423SLionel Sambuc }
418433d6423SLionel Sambuc 
419433d6423SLionel Sambuc 
420433d6423SLionel Sambuc /*******************************************************************************
421433d6423SLionel Sambuc  *
422433d6423SLionel Sambuc  * FUNCTION:    AcpiExDoMathOp
423433d6423SLionel Sambuc  *
424433d6423SLionel Sambuc  * PARAMETERS:  Opcode              - AML opcode
425433d6423SLionel Sambuc  *              Integer0            - Integer operand #0
426433d6423SLionel Sambuc  *              Integer1            - Integer operand #1
427433d6423SLionel Sambuc  *
428433d6423SLionel Sambuc  * RETURN:      Integer result of the operation
429433d6423SLionel Sambuc  *
430433d6423SLionel Sambuc  * DESCRIPTION: Execute a math AML opcode. The purpose of having all of the
431433d6423SLionel Sambuc  *              math functions here is to prevent a lot of pointer dereferencing
432433d6423SLionel Sambuc  *              to obtain the operands.
433433d6423SLionel Sambuc  *
434433d6423SLionel Sambuc  ******************************************************************************/
435433d6423SLionel Sambuc 
436433d6423SLionel Sambuc UINT64
AcpiExDoMathOp(UINT16 Opcode,UINT64 Integer0,UINT64 Integer1)437433d6423SLionel Sambuc AcpiExDoMathOp (
438433d6423SLionel Sambuc     UINT16                  Opcode,
439433d6423SLionel Sambuc     UINT64                  Integer0,
440433d6423SLionel Sambuc     UINT64                  Integer1)
441433d6423SLionel Sambuc {
442433d6423SLionel Sambuc 
443433d6423SLionel Sambuc     ACPI_FUNCTION_ENTRY ();
444433d6423SLionel Sambuc 
445433d6423SLionel Sambuc 
446433d6423SLionel Sambuc     switch (Opcode)
447433d6423SLionel Sambuc     {
448433d6423SLionel Sambuc     case AML_ADD_OP:                /* Add (Integer0, Integer1, Result) */
449433d6423SLionel Sambuc 
450433d6423SLionel Sambuc         return (Integer0 + Integer1);
451433d6423SLionel Sambuc 
452433d6423SLionel Sambuc     case AML_BIT_AND_OP:            /* And (Integer0, Integer1, Result) */
453433d6423SLionel Sambuc 
454433d6423SLionel Sambuc         return (Integer0 & Integer1);
455433d6423SLionel Sambuc 
456433d6423SLionel Sambuc     case AML_BIT_NAND_OP:           /* NAnd (Integer0, Integer1, Result) */
457433d6423SLionel Sambuc 
458433d6423SLionel Sambuc         return (~(Integer0 & Integer1));
459433d6423SLionel Sambuc 
460433d6423SLionel Sambuc     case AML_BIT_OR_OP:             /* Or (Integer0, Integer1, Result) */
461433d6423SLionel Sambuc 
462433d6423SLionel Sambuc         return (Integer0 | Integer1);
463433d6423SLionel Sambuc 
464433d6423SLionel Sambuc     case AML_BIT_NOR_OP:            /* NOr (Integer0, Integer1, Result) */
465433d6423SLionel Sambuc 
466433d6423SLionel Sambuc         return (~(Integer0 | Integer1));
467433d6423SLionel Sambuc 
468433d6423SLionel Sambuc     case AML_BIT_XOR_OP:            /* XOr (Integer0, Integer1, Result) */
469433d6423SLionel Sambuc 
470433d6423SLionel Sambuc         return (Integer0 ^ Integer1);
471433d6423SLionel Sambuc 
472433d6423SLionel Sambuc     case AML_MULTIPLY_OP:           /* Multiply (Integer0, Integer1, Result) */
473433d6423SLionel Sambuc 
474433d6423SLionel Sambuc         return (Integer0 * Integer1);
475433d6423SLionel Sambuc 
476433d6423SLionel Sambuc     case AML_SHIFT_LEFT_OP:         /* ShiftLeft (Operand, ShiftCount, Result)*/
477433d6423SLionel Sambuc 
478433d6423SLionel Sambuc         /*
479433d6423SLionel Sambuc          * We need to check if the shiftcount is larger than the integer bit
480433d6423SLionel Sambuc          * width since the behavior of this is not well-defined in the C language.
481433d6423SLionel Sambuc          */
482433d6423SLionel Sambuc         if (Integer1 >= AcpiGbl_IntegerBitWidth)
483433d6423SLionel Sambuc         {
484433d6423SLionel Sambuc             return (0);
485433d6423SLionel Sambuc         }
486433d6423SLionel Sambuc         return (Integer0 << Integer1);
487433d6423SLionel Sambuc 
488433d6423SLionel Sambuc     case AML_SHIFT_RIGHT_OP:        /* ShiftRight (Operand, ShiftCount, Result) */
489433d6423SLionel Sambuc 
490433d6423SLionel Sambuc         /*
491433d6423SLionel Sambuc          * We need to check if the shiftcount is larger than the integer bit
492433d6423SLionel Sambuc          * width since the behavior of this is not well-defined in the C language.
493433d6423SLionel Sambuc          */
494433d6423SLionel Sambuc         if (Integer1 >= AcpiGbl_IntegerBitWidth)
495433d6423SLionel Sambuc         {
496433d6423SLionel Sambuc             return (0);
497433d6423SLionel Sambuc         }
498433d6423SLionel Sambuc         return (Integer0 >> Integer1);
499433d6423SLionel Sambuc 
500433d6423SLionel Sambuc     case AML_SUBTRACT_OP:           /* Subtract (Integer0, Integer1, Result) */
501433d6423SLionel Sambuc 
502433d6423SLionel Sambuc         return (Integer0 - Integer1);
503433d6423SLionel Sambuc 
504433d6423SLionel Sambuc     default:
505433d6423SLionel Sambuc 
506433d6423SLionel Sambuc         return (0);
507433d6423SLionel Sambuc     }
508433d6423SLionel Sambuc }
509433d6423SLionel Sambuc 
510433d6423SLionel Sambuc 
511433d6423SLionel Sambuc /*******************************************************************************
512433d6423SLionel Sambuc  *
513433d6423SLionel Sambuc  * FUNCTION:    AcpiExDoLogicalNumericOp
514433d6423SLionel Sambuc  *
515433d6423SLionel Sambuc  * PARAMETERS:  Opcode              - AML opcode
516433d6423SLionel Sambuc  *              Integer0            - Integer operand #0
517433d6423SLionel Sambuc  *              Integer1            - Integer operand #1
518433d6423SLionel Sambuc  *              LogicalResult       - TRUE/FALSE result of the operation
519433d6423SLionel Sambuc  *
520433d6423SLionel Sambuc  * RETURN:      Status
521433d6423SLionel Sambuc  *
522433d6423SLionel Sambuc  * DESCRIPTION: Execute a logical "Numeric" AML opcode. For these Numeric
523433d6423SLionel Sambuc  *              operators (LAnd and LOr), both operands must be integers.
524433d6423SLionel Sambuc  *
525433d6423SLionel Sambuc  *              Note: cleanest machine code seems to be produced by the code
526433d6423SLionel Sambuc  *              below, rather than using statements of the form:
527433d6423SLionel Sambuc  *                  Result = (Integer0 && Integer1);
528433d6423SLionel Sambuc  *
529433d6423SLionel Sambuc  ******************************************************************************/
530433d6423SLionel Sambuc 
531433d6423SLionel Sambuc ACPI_STATUS
AcpiExDoLogicalNumericOp(UINT16 Opcode,UINT64 Integer0,UINT64 Integer1,BOOLEAN * LogicalResult)532433d6423SLionel Sambuc AcpiExDoLogicalNumericOp (
533433d6423SLionel Sambuc     UINT16                  Opcode,
534433d6423SLionel Sambuc     UINT64                  Integer0,
535433d6423SLionel Sambuc     UINT64                  Integer1,
536433d6423SLionel Sambuc     BOOLEAN                 *LogicalResult)
537433d6423SLionel Sambuc {
538433d6423SLionel Sambuc     ACPI_STATUS             Status = AE_OK;
539433d6423SLionel Sambuc     BOOLEAN                 LocalResult = FALSE;
540433d6423SLionel Sambuc 
541433d6423SLionel Sambuc 
542433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (ExDoLogicalNumericOp);
543433d6423SLionel Sambuc 
544433d6423SLionel Sambuc 
545433d6423SLionel Sambuc     switch (Opcode)
546433d6423SLionel Sambuc     {
547433d6423SLionel Sambuc     case AML_LAND_OP:               /* LAnd (Integer0, Integer1) */
548433d6423SLionel Sambuc 
549433d6423SLionel Sambuc         if (Integer0 && Integer1)
550433d6423SLionel Sambuc         {
551433d6423SLionel Sambuc             LocalResult = TRUE;
552433d6423SLionel Sambuc         }
553433d6423SLionel Sambuc         break;
554433d6423SLionel Sambuc 
555433d6423SLionel Sambuc     case AML_LOR_OP:                /* LOr (Integer0, Integer1) */
556433d6423SLionel Sambuc 
557433d6423SLionel Sambuc         if (Integer0 || Integer1)
558433d6423SLionel Sambuc         {
559433d6423SLionel Sambuc             LocalResult = TRUE;
560433d6423SLionel Sambuc         }
561433d6423SLionel Sambuc         break;
562433d6423SLionel Sambuc 
563433d6423SLionel Sambuc     default:
564*29492bb7SDavid van Moolenbroek 
565433d6423SLionel Sambuc         Status = AE_AML_INTERNAL;
566433d6423SLionel Sambuc         break;
567433d6423SLionel Sambuc     }
568433d6423SLionel Sambuc 
569433d6423SLionel Sambuc     /* Return the logical result and status */
570433d6423SLionel Sambuc 
571433d6423SLionel Sambuc     *LogicalResult = LocalResult;
572433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
573433d6423SLionel Sambuc }
574433d6423SLionel Sambuc 
575433d6423SLionel Sambuc 
576433d6423SLionel Sambuc /*******************************************************************************
577433d6423SLionel Sambuc  *
578433d6423SLionel Sambuc  * FUNCTION:    AcpiExDoLogicalOp
579433d6423SLionel Sambuc  *
580433d6423SLionel Sambuc  * PARAMETERS:  Opcode              - AML opcode
581433d6423SLionel Sambuc  *              Operand0            - operand #0
582433d6423SLionel Sambuc  *              Operand1            - operand #1
583433d6423SLionel Sambuc  *              LogicalResult       - TRUE/FALSE result of the operation
584433d6423SLionel Sambuc  *
585433d6423SLionel Sambuc  * RETURN:      Status
586433d6423SLionel Sambuc  *
587433d6423SLionel Sambuc  * DESCRIPTION: Execute a logical AML opcode. The purpose of having all of the
588433d6423SLionel Sambuc  *              functions here is to prevent a lot of pointer dereferencing
589433d6423SLionel Sambuc  *              to obtain the operands and to simplify the generation of the
590433d6423SLionel Sambuc  *              logical value. For the Numeric operators (LAnd and LOr), both
591433d6423SLionel Sambuc  *              operands must be integers. For the other logical operators,
592433d6423SLionel Sambuc  *              operands can be any combination of Integer/String/Buffer. The
593433d6423SLionel Sambuc  *              first operand determines the type to which the second operand
594433d6423SLionel Sambuc  *              will be converted.
595433d6423SLionel Sambuc  *
596433d6423SLionel Sambuc  *              Note: cleanest machine code seems to be produced by the code
597433d6423SLionel Sambuc  *              below, rather than using statements of the form:
598433d6423SLionel Sambuc  *                  Result = (Operand0 == Operand1);
599433d6423SLionel Sambuc  *
600433d6423SLionel Sambuc  ******************************************************************************/
601433d6423SLionel Sambuc 
602433d6423SLionel Sambuc ACPI_STATUS
AcpiExDoLogicalOp(UINT16 Opcode,ACPI_OPERAND_OBJECT * Operand0,ACPI_OPERAND_OBJECT * Operand1,BOOLEAN * LogicalResult)603433d6423SLionel Sambuc AcpiExDoLogicalOp (
604433d6423SLionel Sambuc     UINT16                  Opcode,
605433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *Operand0,
606433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *Operand1,
607433d6423SLionel Sambuc     BOOLEAN                 *LogicalResult)
608433d6423SLionel Sambuc {
609433d6423SLionel Sambuc     ACPI_OPERAND_OBJECT     *LocalOperand1 = Operand1;
610433d6423SLionel Sambuc     UINT64                  Integer0;
611433d6423SLionel Sambuc     UINT64                  Integer1;
612433d6423SLionel Sambuc     UINT32                  Length0;
613433d6423SLionel Sambuc     UINT32                  Length1;
614433d6423SLionel Sambuc     ACPI_STATUS             Status = AE_OK;
615433d6423SLionel Sambuc     BOOLEAN                 LocalResult = FALSE;
616433d6423SLionel Sambuc     int                     Compare;
617433d6423SLionel Sambuc 
618433d6423SLionel Sambuc 
619433d6423SLionel Sambuc     ACPI_FUNCTION_TRACE (ExDoLogicalOp);
620433d6423SLionel Sambuc 
621433d6423SLionel Sambuc 
622433d6423SLionel Sambuc     /*
623433d6423SLionel Sambuc      * Convert the second operand if necessary. The first operand
624433d6423SLionel Sambuc      * determines the type of the second operand, (See the Data Types
625433d6423SLionel Sambuc      * section of the ACPI 3.0+ specification.)  Both object types are
626433d6423SLionel Sambuc      * guaranteed to be either Integer/String/Buffer by the operand
627433d6423SLionel Sambuc      * resolution mechanism.
628433d6423SLionel Sambuc      */
629433d6423SLionel Sambuc     switch (Operand0->Common.Type)
630433d6423SLionel Sambuc     {
631433d6423SLionel Sambuc     case ACPI_TYPE_INTEGER:
632*29492bb7SDavid van Moolenbroek 
633433d6423SLionel Sambuc         Status = AcpiExConvertToInteger (Operand1, &LocalOperand1, 16);
634433d6423SLionel Sambuc         break;
635433d6423SLionel Sambuc 
636433d6423SLionel Sambuc     case ACPI_TYPE_STRING:
637*29492bb7SDavid van Moolenbroek 
638433d6423SLionel Sambuc         Status = AcpiExConvertToString (Operand1, &LocalOperand1,
639433d6423SLionel Sambuc                     ACPI_IMPLICIT_CONVERT_HEX);
640433d6423SLionel Sambuc         break;
641433d6423SLionel Sambuc 
642433d6423SLionel Sambuc     case ACPI_TYPE_BUFFER:
643*29492bb7SDavid van Moolenbroek 
644433d6423SLionel Sambuc         Status = AcpiExConvertToBuffer (Operand1, &LocalOperand1);
645433d6423SLionel Sambuc         break;
646433d6423SLionel Sambuc 
647433d6423SLionel Sambuc     default:
648*29492bb7SDavid van Moolenbroek 
649433d6423SLionel Sambuc         Status = AE_AML_INTERNAL;
650433d6423SLionel Sambuc         break;
651433d6423SLionel Sambuc     }
652433d6423SLionel Sambuc 
653433d6423SLionel Sambuc     if (ACPI_FAILURE (Status))
654433d6423SLionel Sambuc     {
655433d6423SLionel Sambuc         goto Cleanup;
656433d6423SLionel Sambuc     }
657433d6423SLionel Sambuc 
658433d6423SLionel Sambuc     /*
659433d6423SLionel Sambuc      * Two cases: 1) Both Integers, 2) Both Strings or Buffers
660433d6423SLionel Sambuc      */
661433d6423SLionel Sambuc     if (Operand0->Common.Type == ACPI_TYPE_INTEGER)
662433d6423SLionel Sambuc     {
663433d6423SLionel Sambuc         /*
664433d6423SLionel Sambuc          * 1) Both operands are of type integer
665433d6423SLionel Sambuc          *    Note: LocalOperand1 may have changed above
666433d6423SLionel Sambuc          */
667433d6423SLionel Sambuc         Integer0 = Operand0->Integer.Value;
668433d6423SLionel Sambuc         Integer1 = LocalOperand1->Integer.Value;
669433d6423SLionel Sambuc 
670433d6423SLionel Sambuc         switch (Opcode)
671433d6423SLionel Sambuc         {
672433d6423SLionel Sambuc         case AML_LEQUAL_OP:             /* LEqual (Operand0, Operand1) */
673433d6423SLionel Sambuc 
674433d6423SLionel Sambuc             if (Integer0 == Integer1)
675433d6423SLionel Sambuc             {
676433d6423SLionel Sambuc                 LocalResult = TRUE;
677433d6423SLionel Sambuc             }
678433d6423SLionel Sambuc             break;
679433d6423SLionel Sambuc 
680433d6423SLionel Sambuc         case AML_LGREATER_OP:           /* LGreater (Operand0, Operand1) */
681433d6423SLionel Sambuc 
682433d6423SLionel Sambuc             if (Integer0 > Integer1)
683433d6423SLionel Sambuc             {
684433d6423SLionel Sambuc                 LocalResult = TRUE;
685433d6423SLionel Sambuc             }
686433d6423SLionel Sambuc             break;
687433d6423SLionel Sambuc 
688433d6423SLionel Sambuc         case AML_LLESS_OP:              /* LLess (Operand0, Operand1) */
689433d6423SLionel Sambuc 
690433d6423SLionel Sambuc             if (Integer0 < Integer1)
691433d6423SLionel Sambuc             {
692433d6423SLionel Sambuc                 LocalResult = TRUE;
693433d6423SLionel Sambuc             }
694433d6423SLionel Sambuc             break;
695433d6423SLionel Sambuc 
696433d6423SLionel Sambuc         default:
697*29492bb7SDavid van Moolenbroek 
698433d6423SLionel Sambuc             Status = AE_AML_INTERNAL;
699433d6423SLionel Sambuc             break;
700433d6423SLionel Sambuc         }
701433d6423SLionel Sambuc     }
702433d6423SLionel Sambuc     else
703433d6423SLionel Sambuc     {
704433d6423SLionel Sambuc         /*
705433d6423SLionel Sambuc          * 2) Both operands are Strings or both are Buffers
706433d6423SLionel Sambuc          *    Note: Code below takes advantage of common Buffer/String
707433d6423SLionel Sambuc          *          object fields. LocalOperand1 may have changed above. Use
708433d6423SLionel Sambuc          *          memcmp to handle nulls in buffers.
709433d6423SLionel Sambuc          */
710433d6423SLionel Sambuc         Length0 = Operand0->Buffer.Length;
711433d6423SLionel Sambuc         Length1 = LocalOperand1->Buffer.Length;
712433d6423SLionel Sambuc 
713433d6423SLionel Sambuc         /* Lexicographic compare: compare the data bytes */
714433d6423SLionel Sambuc 
715433d6423SLionel Sambuc         Compare = ACPI_MEMCMP (Operand0->Buffer.Pointer,
716433d6423SLionel Sambuc                     LocalOperand1->Buffer.Pointer,
717433d6423SLionel Sambuc                     (Length0 > Length1) ? Length1 : Length0);
718433d6423SLionel Sambuc 
719433d6423SLionel Sambuc         switch (Opcode)
720433d6423SLionel Sambuc         {
721433d6423SLionel Sambuc         case AML_LEQUAL_OP:             /* LEqual (Operand0, Operand1) */
722433d6423SLionel Sambuc 
723433d6423SLionel Sambuc             /* Length and all bytes must be equal */
724433d6423SLionel Sambuc 
725433d6423SLionel Sambuc             if ((Length0 == Length1) &&
726433d6423SLionel Sambuc                 (Compare == 0))
727433d6423SLionel Sambuc             {
728433d6423SLionel Sambuc                 /* Length and all bytes match ==> TRUE */
729433d6423SLionel Sambuc 
730433d6423SLionel Sambuc                 LocalResult = TRUE;
731433d6423SLionel Sambuc             }
732433d6423SLionel Sambuc             break;
733433d6423SLionel Sambuc 
734433d6423SLionel Sambuc         case AML_LGREATER_OP:           /* LGreater (Operand0, Operand1) */
735433d6423SLionel Sambuc 
736433d6423SLionel Sambuc             if (Compare > 0)
737433d6423SLionel Sambuc             {
738433d6423SLionel Sambuc                 LocalResult = TRUE;
739433d6423SLionel Sambuc                 goto Cleanup;   /* TRUE */
740433d6423SLionel Sambuc             }
741433d6423SLionel Sambuc             if (Compare < 0)
742433d6423SLionel Sambuc             {
743433d6423SLionel Sambuc                 goto Cleanup;   /* FALSE */
744433d6423SLionel Sambuc             }
745433d6423SLionel Sambuc 
746433d6423SLionel Sambuc             /* Bytes match (to shortest length), compare lengths */
747433d6423SLionel Sambuc 
748433d6423SLionel Sambuc             if (Length0 > Length1)
749433d6423SLionel Sambuc             {
750433d6423SLionel Sambuc                 LocalResult = TRUE;
751433d6423SLionel Sambuc             }
752433d6423SLionel Sambuc             break;
753433d6423SLionel Sambuc 
754433d6423SLionel Sambuc         case AML_LLESS_OP:              /* LLess (Operand0, Operand1) */
755433d6423SLionel Sambuc 
756433d6423SLionel Sambuc             if (Compare > 0)
757433d6423SLionel Sambuc             {
758433d6423SLionel Sambuc                 goto Cleanup;   /* FALSE */
759433d6423SLionel Sambuc             }
760433d6423SLionel Sambuc             if (Compare < 0)
761433d6423SLionel Sambuc             {
762433d6423SLionel Sambuc                 LocalResult = TRUE;
763433d6423SLionel Sambuc                 goto Cleanup;   /* TRUE */
764433d6423SLionel Sambuc             }
765433d6423SLionel Sambuc 
766433d6423SLionel Sambuc             /* Bytes match (to shortest length), compare lengths */
767433d6423SLionel Sambuc 
768433d6423SLionel Sambuc             if (Length0 < Length1)
769433d6423SLionel Sambuc             {
770433d6423SLionel Sambuc                 LocalResult = TRUE;
771433d6423SLionel Sambuc             }
772433d6423SLionel Sambuc             break;
773433d6423SLionel Sambuc 
774433d6423SLionel Sambuc         default:
775*29492bb7SDavid van Moolenbroek 
776433d6423SLionel Sambuc             Status = AE_AML_INTERNAL;
777433d6423SLionel Sambuc             break;
778433d6423SLionel Sambuc         }
779433d6423SLionel Sambuc     }
780433d6423SLionel Sambuc 
781433d6423SLionel Sambuc Cleanup:
782433d6423SLionel Sambuc 
783433d6423SLionel Sambuc     /* New object was created if implicit conversion performed - delete */
784433d6423SLionel Sambuc 
785433d6423SLionel Sambuc     if (LocalOperand1 != Operand1)
786433d6423SLionel Sambuc     {
787433d6423SLionel Sambuc         AcpiUtRemoveReference (LocalOperand1);
788433d6423SLionel Sambuc     }
789433d6423SLionel Sambuc 
790433d6423SLionel Sambuc     /* Return the logical result and status */
791433d6423SLionel Sambuc 
792433d6423SLionel Sambuc     *LogicalResult = LocalResult;
793433d6423SLionel Sambuc     return_ACPI_STATUS (Status);
794433d6423SLionel Sambuc }
795