2
/******************************************************************************
4
* Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes
6
*****************************************************************************/
9
* Copyright (C) 2000 - 2011, Intel Corp.
10
* All rights reserved.
12
* Redistribution and use in source and binary forms, with or without
13
* modification, are permitted provided that the following conditions
15
* 1. Redistributions of source code must retain the above copyright
16
* notice, this list of conditions, and the following disclaimer,
17
* without modification.
18
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
19
* substantially similar to the "NO WARRANTY" disclaimer below
20
* ("Disclaimer") and any redistribution must be conditioned upon
21
* including a substantially similar Disclaimer requirement for further
22
* binary redistribution.
23
* 3. Neither the names of the above-listed copyright holders nor the names
24
* of any contributors may be used to endorse or promote products derived
25
* from this software without specific prior written permission.
27
* Alternatively, this software may be distributed under the terms of the
28
* GNU General Public License ("GPL") version 2 as published by the Free
29
* Software Foundation.
32
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42
* POSSIBILITY OF SUCH DAMAGES.
45
#include <acpi/acpi.h>
51
#define _COMPONENT ACPI_EXECUTER
52
ACPI_MODULE_NAME("exmisc")
54
/*******************************************************************************
56
* FUNCTION: acpi_ex_get_object_reference
58
* PARAMETERS: obj_desc - Create a reference to this object
59
* return_desc - Where to store the reference
60
* walk_state - Current state
64
* DESCRIPTION: Obtain and return a "reference" to the target object
65
* Common code for the ref_of_op and the cond_ref_of_op.
67
******************************************************************************/
69
acpi_ex_get_object_reference(union acpi_operand_object *obj_desc,
70
union acpi_operand_object **return_desc,
71
struct acpi_walk_state *walk_state)
73
union acpi_operand_object *reference_obj;
74
union acpi_operand_object *referenced_obj;
76
ACPI_FUNCTION_TRACE_PTR(ex_get_object_reference, obj_desc);
80
switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
81
case ACPI_DESC_TYPE_OPERAND:
83
if (obj_desc->common.type != ACPI_TYPE_LOCAL_REFERENCE) {
84
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
88
* Must be a reference to a Local or Arg
90
switch (obj_desc->reference.class) {
91
case ACPI_REFCLASS_LOCAL:
92
case ACPI_REFCLASS_ARG:
93
case ACPI_REFCLASS_DEBUG:
95
/* The referenced object is the pseudo-node for the local/arg */
97
referenced_obj = obj_desc->reference.object;
102
ACPI_ERROR((AE_INFO, "Unknown Reference Class 0x%2.2X",
103
obj_desc->reference.class));
104
return_ACPI_STATUS(AE_AML_INTERNAL);
108
case ACPI_DESC_TYPE_NAMED:
111
* A named reference that has already been resolved to a Node
113
referenced_obj = obj_desc;
118
ACPI_ERROR((AE_INFO, "Invalid descriptor type 0x%X",
119
ACPI_GET_DESCRIPTOR_TYPE(obj_desc)));
120
return_ACPI_STATUS(AE_TYPE);
123
/* Create a new reference object */
126
acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_REFERENCE);
127
if (!reference_obj) {
128
return_ACPI_STATUS(AE_NO_MEMORY);
131
reference_obj->reference.class = ACPI_REFCLASS_REFOF;
132
reference_obj->reference.object = referenced_obj;
133
*return_desc = reference_obj;
135
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
136
"Object %p Type [%s], returning Reference %p\n",
137
obj_desc, acpi_ut_get_object_type_name(obj_desc),
140
return_ACPI_STATUS(AE_OK);
143
/*******************************************************************************
145
* FUNCTION: acpi_ex_concat_template
147
* PARAMETERS: Operand0 - First source object
148
* Operand1 - Second source object
149
* actual_return_desc - Where to place the return object
150
* walk_state - Current walk state
154
* DESCRIPTION: Concatenate two resource templates
156
******************************************************************************/
159
acpi_ex_concat_template(union acpi_operand_object *operand0,
160
union acpi_operand_object *operand1,
161
union acpi_operand_object **actual_return_desc,
162
struct acpi_walk_state *walk_state)
165
union acpi_operand_object *return_desc;
170
acpi_size new_length;
172
ACPI_FUNCTION_TRACE(ex_concat_template);
175
* Find the end_tag descriptor in each resource template.
176
* Note1: returned pointers point TO the end_tag, not past it.
177
* Note2: zero-length buffers are allowed; treated like one end_tag
180
/* Get the length of the first resource template */
182
status = acpi_ut_get_resource_end_tag(operand0, &end_tag);
183
if (ACPI_FAILURE(status)) {
184
return_ACPI_STATUS(status);
187
length0 = ACPI_PTR_DIFF(end_tag, operand0->buffer.pointer);
189
/* Get the length of the second resource template */
191
status = acpi_ut_get_resource_end_tag(operand1, &end_tag);
192
if (ACPI_FAILURE(status)) {
193
return_ACPI_STATUS(status);
196
length1 = ACPI_PTR_DIFF(end_tag, operand1->buffer.pointer);
198
/* Combine both lengths, minimum size will be 2 for end_tag */
200
new_length = length0 + length1 + sizeof(struct aml_resource_end_tag);
202
/* Create a new buffer object for the result (with one end_tag) */
204
return_desc = acpi_ut_create_buffer_object(new_length);
206
return_ACPI_STATUS(AE_NO_MEMORY);
210
* Copy the templates to the new buffer, 0 first, then 1 follows. One
211
* end_tag descriptor is copied from Operand1.
213
new_buf = return_desc->buffer.pointer;
214
ACPI_MEMCPY(new_buf, operand0->buffer.pointer, length0);
215
ACPI_MEMCPY(new_buf + length0, operand1->buffer.pointer, length1);
217
/* Insert end_tag and set the checksum to zero, means "ignore checksum" */
219
new_buf[new_length - 1] = 0;
220
new_buf[new_length - 2] = ACPI_RESOURCE_NAME_END_TAG | 1;
222
/* Return the completed resource template */
224
*actual_return_desc = return_desc;
225
return_ACPI_STATUS(AE_OK);
228
/*******************************************************************************
230
* FUNCTION: acpi_ex_do_concatenate
232
* PARAMETERS: Operand0 - First source object
233
* Operand1 - Second source object
234
* actual_return_desc - Where to place the return object
235
* walk_state - Current walk state
239
* DESCRIPTION: Concatenate two objects OF THE SAME TYPE.
241
******************************************************************************/
244
acpi_ex_do_concatenate(union acpi_operand_object *operand0,
245
union acpi_operand_object *operand1,
246
union acpi_operand_object **actual_return_desc,
247
struct acpi_walk_state *walk_state)
249
union acpi_operand_object *local_operand1 = operand1;
250
union acpi_operand_object *return_desc;
254
ACPI_FUNCTION_TRACE(ex_do_concatenate);
257
* Convert the second operand if necessary. The first operand
258
* determines the type of the second operand, (See the Data Types
259
* section of the ACPI specification.) Both object types are
260
* guaranteed to be either Integer/String/Buffer by the operand
261
* resolution mechanism.
263
switch (operand0->common.type) {
264
case ACPI_TYPE_INTEGER:
266
acpi_ex_convert_to_integer(operand1, &local_operand1, 16);
269
case ACPI_TYPE_STRING:
270
status = acpi_ex_convert_to_string(operand1, &local_operand1,
271
ACPI_IMPLICIT_CONVERT_HEX);
274
case ACPI_TYPE_BUFFER:
275
status = acpi_ex_convert_to_buffer(operand1, &local_operand1);
279
ACPI_ERROR((AE_INFO, "Invalid object type: 0x%X",
280
operand0->common.type));
281
status = AE_AML_INTERNAL;
284
if (ACPI_FAILURE(status)) {
289
* Both operands are now known to be the same object type
290
* (Both are Integer, String, or Buffer), and we can now perform the
295
* There are three cases to handle:
297
* 1) Two Integers concatenated to produce a new Buffer
298
* 2) Two Strings concatenated to produce a new String
299
* 3) Two Buffers concatenated to produce a new Buffer
301
switch (operand0->common.type) {
302
case ACPI_TYPE_INTEGER:
304
/* Result of two Integers is a Buffer */
305
/* Need enough buffer space for two integers */
307
return_desc = acpi_ut_create_buffer_object((acpi_size)
309
(acpi_gbl_integer_byte_width));
311
status = AE_NO_MEMORY;
315
new_buf = (char *)return_desc->buffer.pointer;
317
/* Copy the first integer, LSB first */
319
ACPI_MEMCPY(new_buf, &operand0->integer.value,
320
acpi_gbl_integer_byte_width);
322
/* Copy the second integer (LSB first) after the first */
324
ACPI_MEMCPY(new_buf + acpi_gbl_integer_byte_width,
325
&local_operand1->integer.value,
326
acpi_gbl_integer_byte_width);
329
case ACPI_TYPE_STRING:
331
/* Result of two Strings is a String */
333
return_desc = acpi_ut_create_string_object(((acpi_size)
339
status = AE_NO_MEMORY;
343
new_buf = return_desc->string.pointer;
345
/* Concatenate the strings */
347
ACPI_STRCPY(new_buf, operand0->string.pointer);
348
ACPI_STRCPY(new_buf + operand0->string.length,
349
local_operand1->string.pointer);
352
case ACPI_TYPE_BUFFER:
354
/* Result of two Buffers is a Buffer */
356
return_desc = acpi_ut_create_buffer_object(((acpi_size)
362
status = AE_NO_MEMORY;
366
new_buf = (char *)return_desc->buffer.pointer;
368
/* Concatenate the buffers */
370
ACPI_MEMCPY(new_buf, operand0->buffer.pointer,
371
operand0->buffer.length);
372
ACPI_MEMCPY(new_buf + operand0->buffer.length,
373
local_operand1->buffer.pointer,
374
local_operand1->buffer.length);
379
/* Invalid object type, should not happen here */
381
ACPI_ERROR((AE_INFO, "Invalid object type: 0x%X",
382
operand0->common.type));
383
status = AE_AML_INTERNAL;
387
*actual_return_desc = return_desc;
390
if (local_operand1 != operand1) {
391
acpi_ut_remove_reference(local_operand1);
393
return_ACPI_STATUS(status);
396
/*******************************************************************************
398
* FUNCTION: acpi_ex_do_math_op
400
* PARAMETERS: Opcode - AML opcode
401
* Integer0 - Integer operand #0
402
* Integer1 - Integer operand #1
404
* RETURN: Integer result of the operation
406
* DESCRIPTION: Execute a math AML opcode. The purpose of having all of the
407
* math functions here is to prevent a lot of pointer dereferencing
408
* to obtain the operands.
410
******************************************************************************/
412
u64 acpi_ex_do_math_op(u16 opcode, u64 integer0, u64 integer1)
415
ACPI_FUNCTION_ENTRY();
418
case AML_ADD_OP: /* Add (Integer0, Integer1, Result) */
420
return (integer0 + integer1);
422
case AML_BIT_AND_OP: /* And (Integer0, Integer1, Result) */
424
return (integer0 & integer1);
426
case AML_BIT_NAND_OP: /* NAnd (Integer0, Integer1, Result) */
428
return (~(integer0 & integer1));
430
case AML_BIT_OR_OP: /* Or (Integer0, Integer1, Result) */
432
return (integer0 | integer1);
434
case AML_BIT_NOR_OP: /* NOr (Integer0, Integer1, Result) */
436
return (~(integer0 | integer1));
438
case AML_BIT_XOR_OP: /* XOr (Integer0, Integer1, Result) */
440
return (integer0 ^ integer1);
442
case AML_MULTIPLY_OP: /* Multiply (Integer0, Integer1, Result) */
444
return (integer0 * integer1);
446
case AML_SHIFT_LEFT_OP: /* shift_left (Operand, shift_count, Result) */
449
* We need to check if the shiftcount is larger than the integer bit
450
* width since the behavior of this is not well-defined in the C language.
452
if (integer1 >= acpi_gbl_integer_bit_width) {
455
return (integer0 << integer1);
457
case AML_SHIFT_RIGHT_OP: /* shift_right (Operand, shift_count, Result) */
460
* We need to check if the shiftcount is larger than the integer bit
461
* width since the behavior of this is not well-defined in the C language.
463
if (integer1 >= acpi_gbl_integer_bit_width) {
466
return (integer0 >> integer1);
468
case AML_SUBTRACT_OP: /* Subtract (Integer0, Integer1, Result) */
470
return (integer0 - integer1);
478
/*******************************************************************************
480
* FUNCTION: acpi_ex_do_logical_numeric_op
482
* PARAMETERS: Opcode - AML opcode
483
* Integer0 - Integer operand #0
484
* Integer1 - Integer operand #1
485
* logical_result - TRUE/FALSE result of the operation
489
* DESCRIPTION: Execute a logical "Numeric" AML opcode. For these Numeric
490
* operators (LAnd and LOr), both operands must be integers.
492
* Note: cleanest machine code seems to be produced by the code
493
* below, rather than using statements of the form:
494
* Result = (Integer0 && Integer1);
496
******************************************************************************/
499
acpi_ex_do_logical_numeric_op(u16 opcode,
500
u64 integer0, u64 integer1, u8 *logical_result)
502
acpi_status status = AE_OK;
503
u8 local_result = FALSE;
505
ACPI_FUNCTION_TRACE(ex_do_logical_numeric_op);
508
case AML_LAND_OP: /* LAnd (Integer0, Integer1) */
510
if (integer0 && integer1) {
515
case AML_LOR_OP: /* LOr (Integer0, Integer1) */
517
if (integer0 || integer1) {
523
status = AE_AML_INTERNAL;
527
/* Return the logical result and status */
529
*logical_result = local_result;
530
return_ACPI_STATUS(status);
533
/*******************************************************************************
535
* FUNCTION: acpi_ex_do_logical_op
537
* PARAMETERS: Opcode - AML opcode
538
* Operand0 - operand #0
539
* Operand1 - operand #1
540
* logical_result - TRUE/FALSE result of the operation
544
* DESCRIPTION: Execute a logical AML opcode. The purpose of having all of the
545
* functions here is to prevent a lot of pointer dereferencing
546
* to obtain the operands and to simplify the generation of the
547
* logical value. For the Numeric operators (LAnd and LOr), both
548
* operands must be integers. For the other logical operators,
549
* operands can be any combination of Integer/String/Buffer. The
550
* first operand determines the type to which the second operand
553
* Note: cleanest machine code seems to be produced by the code
554
* below, rather than using statements of the form:
555
* Result = (Operand0 == Operand1);
557
******************************************************************************/
560
acpi_ex_do_logical_op(u16 opcode,
561
union acpi_operand_object *operand0,
562
union acpi_operand_object *operand1, u8 * logical_result)
564
union acpi_operand_object *local_operand1 = operand1;
569
acpi_status status = AE_OK;
570
u8 local_result = FALSE;
573
ACPI_FUNCTION_TRACE(ex_do_logical_op);
576
* Convert the second operand if necessary. The first operand
577
* determines the type of the second operand, (See the Data Types
578
* section of the ACPI 3.0+ specification.) Both object types are
579
* guaranteed to be either Integer/String/Buffer by the operand
580
* resolution mechanism.
582
switch (operand0->common.type) {
583
case ACPI_TYPE_INTEGER:
585
acpi_ex_convert_to_integer(operand1, &local_operand1, 16);
588
case ACPI_TYPE_STRING:
589
status = acpi_ex_convert_to_string(operand1, &local_operand1,
590
ACPI_IMPLICIT_CONVERT_HEX);
593
case ACPI_TYPE_BUFFER:
594
status = acpi_ex_convert_to_buffer(operand1, &local_operand1);
598
status = AE_AML_INTERNAL;
602
if (ACPI_FAILURE(status)) {
607
* Two cases: 1) Both Integers, 2) Both Strings or Buffers
609
if (operand0->common.type == ACPI_TYPE_INTEGER) {
611
* 1) Both operands are of type integer
612
* Note: local_operand1 may have changed above
614
integer0 = operand0->integer.value;
615
integer1 = local_operand1->integer.value;
618
case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */
620
if (integer0 == integer1) {
625
case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */
627
if (integer0 > integer1) {
632
case AML_LLESS_OP: /* LLess (Operand0, Operand1) */
634
if (integer0 < integer1) {
640
status = AE_AML_INTERNAL;
645
* 2) Both operands are Strings or both are Buffers
646
* Note: Code below takes advantage of common Buffer/String
647
* object fields. local_operand1 may have changed above. Use
648
* memcmp to handle nulls in buffers.
650
length0 = operand0->buffer.length;
651
length1 = local_operand1->buffer.length;
653
/* Lexicographic compare: compare the data bytes */
655
compare = ACPI_MEMCMP(operand0->buffer.pointer,
656
local_operand1->buffer.pointer,
657
(length0 > length1) ? length1 : length0);
660
case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */
662
/* Length and all bytes must be equal */
664
if ((length0 == length1) && (compare == 0)) {
666
/* Length and all bytes match ==> TRUE */
672
case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */
676
goto cleanup; /* TRUE */
679
goto cleanup; /* FALSE */
682
/* Bytes match (to shortest length), compare lengths */
684
if (length0 > length1) {
689
case AML_LLESS_OP: /* LLess (Operand0, Operand1) */
692
goto cleanup; /* FALSE */
696
goto cleanup; /* TRUE */
699
/* Bytes match (to shortest length), compare lengths */
701
if (length0 < length1) {
707
status = AE_AML_INTERNAL;
714
/* New object was created if implicit conversion performed - delete */
716
if (local_operand1 != operand1) {
717
acpi_ut_remove_reference(local_operand1);
720
/* Return the logical result and status */
722
*logical_result = local_result;
723
return_ACPI_STATUS(status);