Subversion Repositories Kolibri OS

Rev

Rev 1498 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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