Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /******************************************************************************
  2.  *
  3.  * Module Name: exstorob - AML Interpreter object store support, store to object
  4.  *
  5.  *****************************************************************************/
  6.  
  7. /*
  8.  * Copyright (C) 2000 - 2015, Intel Corp.
  9.  * All rights reserved.
  10.  *
  11.  * Redistribution and use in source and binary forms, with or without
  12.  * modification, are permitted provided that the following conditions
  13.  * are met:
  14.  * 1. Redistributions of source code must retain the above copyright
  15.  *    notice, this list of conditions, and the following disclaimer,
  16.  *    without modification.
  17.  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18.  *    substantially similar to the "NO WARRANTY" disclaimer below
  19.  *    ("Disclaimer") and any redistribution must be conditioned upon
  20.  *    including a substantially similar Disclaimer requirement for further
  21.  *    binary redistribution.
  22.  * 3. Neither the names of the above-listed copyright holders nor the names
  23.  *    of any contributors may be used to endorse or promote products derived
  24.  *    from this software without specific prior written permission.
  25.  *
  26.  * Alternatively, this software may be distributed under the terms of the
  27.  * GNU General Public License ("GPL") version 2 as published by the Free
  28.  * Software Foundation.
  29.  *
  30.  * NO WARRANTY
  31.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34.  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35.  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40.  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41.  * POSSIBILITY OF SUCH DAMAGES.
  42.  */
  43.  
  44. #include <acpi/acpi.h>
  45. #include "accommon.h"
  46. #include "acinterp.h"
  47.  
  48. #define _COMPONENT          ACPI_EXECUTER
  49. ACPI_MODULE_NAME("exstorob")
  50.  
  51. /*******************************************************************************
  52.  *
  53.  * FUNCTION:    acpi_ex_store_buffer_to_buffer
  54.  *
  55.  * PARAMETERS:  source_desc         - Source object to copy
  56.  *              target_desc         - Destination object of the copy
  57.  *
  58.  * RETURN:      Status
  59.  *
  60.  * DESCRIPTION: Copy a buffer object to another buffer object.
  61.  *
  62.  ******************************************************************************/
  63. acpi_status
  64. acpi_ex_store_buffer_to_buffer(union acpi_operand_object *source_desc,
  65.                                union acpi_operand_object *target_desc)
  66. {
  67.         u32 length;
  68.         u8 *buffer;
  69.  
  70.         ACPI_FUNCTION_TRACE_PTR(ex_store_buffer_to_buffer, source_desc);
  71.  
  72.         /* If Source and Target are the same, just return */
  73.  
  74.         if (source_desc == target_desc) {
  75.                 return_ACPI_STATUS(AE_OK);
  76.         }
  77.  
  78.         /* We know that source_desc is a buffer by now */
  79.  
  80.         buffer = ACPI_CAST_PTR(u8, source_desc->buffer.pointer);
  81.         length = source_desc->buffer.length;
  82.  
  83.         /*
  84.          * If target is a buffer of length zero or is a static buffer,
  85.          * allocate a new buffer of the proper length
  86.          */
  87.         if ((target_desc->buffer.length == 0) ||
  88.             (target_desc->common.flags & AOPOBJ_STATIC_POINTER)) {
  89.                 target_desc->buffer.pointer = ACPI_ALLOCATE(length);
  90.                 if (!target_desc->buffer.pointer) {
  91.                         return_ACPI_STATUS(AE_NO_MEMORY);
  92.                 }
  93.  
  94.                 target_desc->buffer.length = length;
  95.         }
  96.  
  97.         /* Copy source buffer to target buffer */
  98.  
  99.         if (length <= target_desc->buffer.length) {
  100.  
  101.                 /* Clear existing buffer and copy in the new one */
  102.  
  103.                 memset(target_desc->buffer.pointer, 0,
  104.                        target_desc->buffer.length);
  105.                 memcpy(target_desc->buffer.pointer, buffer, length);
  106.  
  107. #ifdef ACPI_OBSOLETE_BEHAVIOR
  108.                 /*
  109.                  * NOTE: ACPI versions up to 3.0 specified that the buffer must be
  110.                  * truncated if the string is smaller than the buffer. However, "other"
  111.                  * implementations of ACPI never did this and thus became the defacto
  112.                  * standard. ACPI 3.0A changes this behavior such that the buffer
  113.                  * is no longer truncated.
  114.                  */
  115.  
  116.                 /*
  117.                  * OBSOLETE BEHAVIOR:
  118.                  * If the original source was a string, we must truncate the buffer,
  119.                  * according to the ACPI spec. Integer-to-Buffer and Buffer-to-Buffer
  120.                  * copy must not truncate the original buffer.
  121.                  */
  122.                 if (original_src_type == ACPI_TYPE_STRING) {
  123.  
  124.                         /* Set the new length of the target */
  125.  
  126.                         target_desc->buffer.length = length;
  127.                 }
  128. #endif
  129.         } else {
  130.                 /* Truncate the source, copy only what will fit */
  131.  
  132.                 memcpy(target_desc->buffer.pointer, buffer,
  133.                        target_desc->buffer.length);
  134.  
  135.                 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  136.                                   "Truncating source buffer from %X to %X\n",
  137.                                   length, target_desc->buffer.length));
  138.         }
  139.  
  140.         /* Copy flags */
  141.  
  142.         target_desc->buffer.flags = source_desc->buffer.flags;
  143.         target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
  144.         return_ACPI_STATUS(AE_OK);
  145. }
  146.  
  147. /*******************************************************************************
  148.  *
  149.  * FUNCTION:    acpi_ex_store_string_to_string
  150.  *
  151.  * PARAMETERS:  source_desc         - Source object to copy
  152.  *              target_desc         - Destination object of the copy
  153.  *
  154.  * RETURN:      Status
  155.  *
  156.  * DESCRIPTION: Copy a String object to another String object
  157.  *
  158.  ******************************************************************************/
  159.  
  160. acpi_status
  161. acpi_ex_store_string_to_string(union acpi_operand_object *source_desc,
  162.                                union acpi_operand_object *target_desc)
  163. {
  164.         u32 length;
  165.         u8 *buffer;
  166.  
  167.         ACPI_FUNCTION_TRACE_PTR(ex_store_string_to_string, source_desc);
  168.  
  169.         /* If Source and Target are the same, just return */
  170.  
  171.         if (source_desc == target_desc) {
  172.                 return_ACPI_STATUS(AE_OK);
  173.         }
  174.  
  175.         /* We know that source_desc is a string by now */
  176.  
  177.         buffer = ACPI_CAST_PTR(u8, source_desc->string.pointer);
  178.         length = source_desc->string.length;
  179.  
  180.         /*
  181.          * Replace existing string value if it will fit and the string
  182.          * pointer is not a static pointer (part of an ACPI table)
  183.          */
  184.         if ((length < target_desc->string.length) &&
  185.             (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
  186.                 /*
  187.                  * String will fit in existing non-static buffer.
  188.                  * Clear old string and copy in the new one
  189.                  */
  190.                 memset(target_desc->string.pointer, 0,
  191.                        (acpi_size) target_desc->string.length + 1);
  192.                 memcpy(target_desc->string.pointer, buffer, length);
  193.         } else {
  194.                 /*
  195.                  * Free the current buffer, then allocate a new buffer
  196.                  * large enough to hold the value
  197.                  */
  198.                 if (target_desc->string.pointer &&
  199.                     (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
  200.  
  201.                         /* Only free if not a pointer into the DSDT */
  202.  
  203.                         ACPI_FREE(target_desc->string.pointer);
  204.                 }
  205.  
  206.                 target_desc->string.pointer = ACPI_ALLOCATE_ZEROED((acpi_size)
  207.                                                                    length + 1);
  208.                 if (!target_desc->string.pointer) {
  209.                         return_ACPI_STATUS(AE_NO_MEMORY);
  210.                 }
  211.  
  212.                 target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
  213.                 memcpy(target_desc->string.pointer, buffer, length);
  214.         }
  215.  
  216.         /* Set the new target length */
  217.  
  218.         target_desc->string.length = length;
  219.         return_ACPI_STATUS(AE_OK);
  220. }
  221.