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 | }>>>>><> |