Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
exmisc.c
Go to the documentation of this file.
1 
2 /******************************************************************************
3  *
4  * Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes
5  *
6  *****************************************************************************/
7 
8 /*
9  * Copyright (C) 2000 - 2012, Intel Corp.
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
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.
26  *
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.
30  *
31  * NO WARRANTY
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.
43  */
44 
45 #include <acpi/acpi.h>
46 #include "accommon.h"
47 #include "acinterp.h"
48 #include "amlcode.h"
49 #include "amlresrc.h"
50 
51 #define _COMPONENT ACPI_EXECUTER
52 ACPI_MODULE_NAME("exmisc")
53 
54 /*******************************************************************************
55  *
56  * FUNCTION: acpi_ex_get_object_reference
57  *
58  * PARAMETERS: obj_desc - Create a reference to this object
59  * return_desc - Where to store the reference
60  * walk_state - Current state
61  *
62  * RETURN: Status
63  *
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.
66  *
67  ******************************************************************************/
70  union acpi_operand_object **return_desc,
71  struct acpi_walk_state *walk_state)
72 {
73  union acpi_operand_object *reference_obj;
74  union acpi_operand_object *referenced_obj;
75 
76  ACPI_FUNCTION_TRACE_PTR(ex_get_object_reference, obj_desc);
77 
78  *return_desc = NULL;
79 
80  switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
82 
83  if (obj_desc->common.type != ACPI_TYPE_LOCAL_REFERENCE) {
85  }
86 
87  /*
88  * Must be a reference to a Local or Arg
89  */
90  switch (obj_desc->reference.class) {
92  case ACPI_REFCLASS_ARG:
94 
95  /* The referenced object is the pseudo-node for the local/arg */
96 
97  referenced_obj = obj_desc->reference.object;
98  break;
99 
100  default:
101 
102  ACPI_ERROR((AE_INFO, "Unknown Reference Class 0x%2.2X",
103  obj_desc->reference.class));
105  }
106  break;
107 
109 
110  /*
111  * A named reference that has already been resolved to a Node
112  */
113  referenced_obj = obj_desc;
114  break;
115 
116  default:
117 
118  ACPI_ERROR((AE_INFO, "Invalid descriptor type 0x%X",
119  ACPI_GET_DESCRIPTOR_TYPE(obj_desc)));
121  }
122 
123  /* Create a new reference object */
124 
125  reference_obj =
127  if (!reference_obj) {
129  }
130 
131  reference_obj->reference.class = ACPI_REFCLASS_REFOF;
132  reference_obj->reference.object = referenced_obj;
133  *return_desc = reference_obj;
134 
136  "Object %p Type [%s], returning Reference %p\n",
137  obj_desc, acpi_ut_get_object_type_name(obj_desc),
138  *return_desc));
139 
141 }
142 
143 /*******************************************************************************
144  *
145  * FUNCTION: acpi_ex_concat_template
146  *
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
151  *
152  * RETURN: Status
153  *
154  * DESCRIPTION: Concatenate two resource templates
155  *
156  ******************************************************************************/
157 
160  union acpi_operand_object *operand1,
161  union acpi_operand_object **actual_return_desc,
162  struct acpi_walk_state *walk_state)
163 {
165  union acpi_operand_object *return_desc;
166  u8 *new_buf;
167  u8 *end_tag;
168  acpi_size length0;
169  acpi_size length1;
170  acpi_size new_length;
171 
172  ACPI_FUNCTION_TRACE(ex_concat_template);
173 
174  /*
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
178  */
179 
180  /* Get the length of the first resource template */
181 
182  status = acpi_ut_get_resource_end_tag(operand0, &end_tag);
183  if (ACPI_FAILURE(status)) {
184  return_ACPI_STATUS(status);
185  }
186 
187  length0 = ACPI_PTR_DIFF(end_tag, operand0->buffer.pointer);
188 
189  /* Get the length of the second resource template */
190 
191  status = acpi_ut_get_resource_end_tag(operand1, &end_tag);
192  if (ACPI_FAILURE(status)) {
193  return_ACPI_STATUS(status);
194  }
195 
196  length1 = ACPI_PTR_DIFF(end_tag, operand1->buffer.pointer);
197 
198  /* Combine both lengths, minimum size will be 2 for end_tag */
199 
200  new_length = length0 + length1 + sizeof(struct aml_resource_end_tag);
201 
202  /* Create a new buffer object for the result (with one end_tag) */
203 
204  return_desc = acpi_ut_create_buffer_object(new_length);
205  if (!return_desc) {
207  }
208 
209  /*
210  * Copy the templates to the new buffer, 0 first, then 1 follows. One
211  * end_tag descriptor is copied from Operand1.
212  */
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);
216 
217  /* Insert end_tag and set the checksum to zero, means "ignore checksum" */
218 
219  new_buf[new_length - 1] = 0;
220  new_buf[new_length - 2] = ACPI_RESOURCE_NAME_END_TAG | 1;
221 
222  /* Return the completed resource template */
223 
224  *actual_return_desc = return_desc;
226 }
227 
228 /*******************************************************************************
229  *
230  * FUNCTION: acpi_ex_do_concatenate
231  *
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
236  *
237  * RETURN: Status
238  *
239  * DESCRIPTION: Concatenate two objects OF THE SAME TYPE.
240  *
241  ******************************************************************************/
242 
245  union acpi_operand_object *operand1,
246  union acpi_operand_object **actual_return_desc,
247  struct acpi_walk_state *walk_state)
248 {
249  union acpi_operand_object *local_operand1 = operand1;
250  union acpi_operand_object *return_desc;
251  char *new_buf;
253 
254  ACPI_FUNCTION_TRACE(ex_do_concatenate);
255 
256  /*
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.
262  */
263  switch (operand0->common.type) {
264  case ACPI_TYPE_INTEGER:
265  status =
266  acpi_ex_convert_to_integer(operand1, &local_operand1, 16);
267  break;
268 
269  case ACPI_TYPE_STRING:
270  status = acpi_ex_convert_to_string(operand1, &local_operand1,
272  break;
273 
274  case ACPI_TYPE_BUFFER:
275  status = acpi_ex_convert_to_buffer(operand1, &local_operand1);
276  break;
277 
278  default:
279  ACPI_ERROR((AE_INFO, "Invalid object type: 0x%X",
280  operand0->common.type));
281  status = AE_AML_INTERNAL;
282  }
283 
284  if (ACPI_FAILURE(status)) {
285  goto cleanup;
286  }
287 
288  /*
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
291  * concatenation.
292  */
293 
294  /*
295  * There are three cases to handle:
296  *
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
300  */
301  switch (operand0->common.type) {
302  case ACPI_TYPE_INTEGER:
303 
304  /* Result of two Integers is a Buffer */
305  /* Need enough buffer space for two integers */
306 
307  return_desc = acpi_ut_create_buffer_object((acpi_size)
308  ACPI_MUL_2
310  if (!return_desc) {
311  status = AE_NO_MEMORY;
312  goto cleanup;
313  }
314 
315  new_buf = (char *)return_desc->buffer.pointer;
316 
317  /* Copy the first integer, LSB first */
318 
319  ACPI_MEMCPY(new_buf, &operand0->integer.value,
321 
322  /* Copy the second integer (LSB first) after the first */
323 
325  &local_operand1->integer.value,
327  break;
328 
329  case ACPI_TYPE_STRING:
330 
331  /* Result of two Strings is a String */
332 
333  return_desc = acpi_ut_create_string_object(((acpi_size)
334  operand0->string.
335  length +
336  local_operand1->
337  string.length));
338  if (!return_desc) {
339  status = AE_NO_MEMORY;
340  goto cleanup;
341  }
342 
343  new_buf = return_desc->string.pointer;
344 
345  /* Concatenate the strings */
346 
347  ACPI_STRCPY(new_buf, operand0->string.pointer);
348  ACPI_STRCPY(new_buf + operand0->string.length,
349  local_operand1->string.pointer);
350  break;
351 
352  case ACPI_TYPE_BUFFER:
353 
354  /* Result of two Buffers is a Buffer */
355 
356  return_desc = acpi_ut_create_buffer_object(((acpi_size)
357  operand0->buffer.
358  length +
359  local_operand1->
360  buffer.length));
361  if (!return_desc) {
362  status = AE_NO_MEMORY;
363  goto cleanup;
364  }
365 
366  new_buf = (char *)return_desc->buffer.pointer;
367 
368  /* Concatenate the buffers */
369 
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);
375  break;
376 
377  default:
378 
379  /* Invalid object type, should not happen here */
380 
381  ACPI_ERROR((AE_INFO, "Invalid object type: 0x%X",
382  operand0->common.type));
383  status = AE_AML_INTERNAL;
384  goto cleanup;
385  }
386 
387  *actual_return_desc = return_desc;
388 
389  cleanup:
390  if (local_operand1 != operand1) {
391  acpi_ut_remove_reference(local_operand1);
392  }
393  return_ACPI_STATUS(status);
394 }
395 
396 /*******************************************************************************
397  *
398  * FUNCTION: acpi_ex_do_math_op
399  *
400  * PARAMETERS: opcode - AML opcode
401  * integer0 - Integer operand #0
402  * integer1 - Integer operand #1
403  *
404  * RETURN: Integer result of the operation
405  *
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.
409  *
410  ******************************************************************************/
411 
412 u64 acpi_ex_do_math_op(u16 opcode, u64 integer0, u64 integer1)
413 {
414 
416 
417  switch (opcode) {
418  case AML_ADD_OP: /* Add (Integer0, Integer1, Result) */
419 
420  return (integer0 + integer1);
421 
422  case AML_BIT_AND_OP: /* And (Integer0, Integer1, Result) */
423 
424  return (integer0 & integer1);
425 
426  case AML_BIT_NAND_OP: /* NAnd (Integer0, Integer1, Result) */
427 
428  return (~(integer0 & integer1));
429 
430  case AML_BIT_OR_OP: /* Or (Integer0, Integer1, Result) */
431 
432  return (integer0 | integer1);
433 
434  case AML_BIT_NOR_OP: /* NOr (Integer0, Integer1, Result) */
435 
436  return (~(integer0 | integer1));
437 
438  case AML_BIT_XOR_OP: /* XOr (Integer0, Integer1, Result) */
439 
440  return (integer0 ^ integer1);
441 
442  case AML_MULTIPLY_OP: /* Multiply (Integer0, Integer1, Result) */
443 
444  return (integer0 * integer1);
445 
446  case AML_SHIFT_LEFT_OP: /* shift_left (Operand, shift_count, Result) */
447 
448  /*
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.
451  */
452  if (integer1 >= acpi_gbl_integer_bit_width) {
453  return (0);
454  }
455  return (integer0 << integer1);
456 
457  case AML_SHIFT_RIGHT_OP: /* shift_right (Operand, shift_count, Result) */
458 
459  /*
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.
462  */
463  if (integer1 >= acpi_gbl_integer_bit_width) {
464  return (0);
465  }
466  return (integer0 >> integer1);
467 
468  case AML_SUBTRACT_OP: /* Subtract (Integer0, Integer1, Result) */
469 
470  return (integer0 - integer1);
471 
472  default:
473 
474  return (0);
475  }
476 }
477 
478 /*******************************************************************************
479  *
480  * FUNCTION: acpi_ex_do_logical_numeric_op
481  *
482  * PARAMETERS: opcode - AML opcode
483  * integer0 - Integer operand #0
484  * integer1 - Integer operand #1
485  * logical_result - TRUE/FALSE result of the operation
486  *
487  * RETURN: Status
488  *
489  * DESCRIPTION: Execute a logical "Numeric" AML opcode. For these Numeric
490  * operators (LAnd and LOr), both operands must be integers.
491  *
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);
495  *
496  ******************************************************************************/
497 
500  u64 integer0, u64 integer1, u8 *logical_result)
501 {
503  u8 local_result = FALSE;
504 
505  ACPI_FUNCTION_TRACE(ex_do_logical_numeric_op);
506 
507  switch (opcode) {
508  case AML_LAND_OP: /* LAnd (Integer0, Integer1) */
509 
510  if (integer0 && integer1) {
511  local_result = TRUE;
512  }
513  break;
514 
515  case AML_LOR_OP: /* LOr (Integer0, Integer1) */
516 
517  if (integer0 || integer1) {
518  local_result = TRUE;
519  }
520  break;
521 
522  default:
523  status = AE_AML_INTERNAL;
524  break;
525  }
526 
527  /* Return the logical result and status */
528 
529  *logical_result = local_result;
530  return_ACPI_STATUS(status);
531 }
532 
533 /*******************************************************************************
534  *
535  * FUNCTION: acpi_ex_do_logical_op
536  *
537  * PARAMETERS: opcode - AML opcode
538  * operand0 - operand #0
539  * operand1 - operand #1
540  * logical_result - TRUE/FALSE result of the operation
541  *
542  * RETURN: Status
543  *
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
551  * will be converted.
552  *
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);
556  *
557  ******************************************************************************/
558 
561  union acpi_operand_object *operand0,
562  union acpi_operand_object *operand1, u8 * logical_result)
563 {
564  union acpi_operand_object *local_operand1 = operand1;
565  u64 integer0;
566  u64 integer1;
567  u32 length0;
568  u32 length1;
570  u8 local_result = FALSE;
571  int compare;
572 
573  ACPI_FUNCTION_TRACE(ex_do_logical_op);
574 
575  /*
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.
581  */
582  switch (operand0->common.type) {
583  case ACPI_TYPE_INTEGER:
584  status =
585  acpi_ex_convert_to_integer(operand1, &local_operand1, 16);
586  break;
587 
588  case ACPI_TYPE_STRING:
589  status = acpi_ex_convert_to_string(operand1, &local_operand1,
591  break;
592 
593  case ACPI_TYPE_BUFFER:
594  status = acpi_ex_convert_to_buffer(operand1, &local_operand1);
595  break;
596 
597  default:
598  status = AE_AML_INTERNAL;
599  break;
600  }
601 
602  if (ACPI_FAILURE(status)) {
603  goto cleanup;
604  }
605 
606  /*
607  * Two cases: 1) Both Integers, 2) Both Strings or Buffers
608  */
609  if (operand0->common.type == ACPI_TYPE_INTEGER) {
610  /*
611  * 1) Both operands are of type integer
612  * Note: local_operand1 may have changed above
613  */
614  integer0 = operand0->integer.value;
615  integer1 = local_operand1->integer.value;
616 
617  switch (opcode) {
618  case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */
619 
620  if (integer0 == integer1) {
621  local_result = TRUE;
622  }
623  break;
624 
625  case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */
626 
627  if (integer0 > integer1) {
628  local_result = TRUE;
629  }
630  break;
631 
632  case AML_LLESS_OP: /* LLess (Operand0, Operand1) */
633 
634  if (integer0 < integer1) {
635  local_result = TRUE;
636  }
637  break;
638 
639  default:
640  status = AE_AML_INTERNAL;
641  break;
642  }
643  } else {
644  /*
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.
649  */
650  length0 = operand0->buffer.length;
651  length1 = local_operand1->buffer.length;
652 
653  /* Lexicographic compare: compare the data bytes */
654 
655  compare = ACPI_MEMCMP(operand0->buffer.pointer,
656  local_operand1->buffer.pointer,
657  (length0 > length1) ? length1 : length0);
658 
659  switch (opcode) {
660  case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */
661 
662  /* Length and all bytes must be equal */
663 
664  if ((length0 == length1) && (compare == 0)) {
665 
666  /* Length and all bytes match ==> TRUE */
667 
668  local_result = TRUE;
669  }
670  break;
671 
672  case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */
673 
674  if (compare > 0) {
675  local_result = TRUE;
676  goto cleanup; /* TRUE */
677  }
678  if (compare < 0) {
679  goto cleanup; /* FALSE */
680  }
681 
682  /* Bytes match (to shortest length), compare lengths */
683 
684  if (length0 > length1) {
685  local_result = TRUE;
686  }
687  break;
688 
689  case AML_LLESS_OP: /* LLess (Operand0, Operand1) */
690 
691  if (compare > 0) {
692  goto cleanup; /* FALSE */
693  }
694  if (compare < 0) {
695  local_result = TRUE;
696  goto cleanup; /* TRUE */
697  }
698 
699  /* Bytes match (to shortest length), compare lengths */
700 
701  if (length0 < length1) {
702  local_result = TRUE;
703  }
704  break;
705 
706  default:
707  status = AE_AML_INTERNAL;
708  break;
709  }
710  }
711 
712  cleanup:
713 
714  /* New object was created if implicit conversion performed - delete */
715 
716  if (local_operand1 != operand1) {
717  acpi_ut_remove_reference(local_operand1);
718  }
719 
720  /* Return the logical result and status */
721 
722  *logical_result = local_result;
723  return_ACPI_STATUS(status);
724 }