exstorob.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2. /******************************************************************************
  3. *
  4. * Module Name: exstorob - AML object store support, store to object
  5. *
  6. * Copyright (C) 2000 - 2022, Intel Corp.
  7. *
  8. *****************************************************************************/
  9. #include <acpi/acpi.h>
  10. #include "accommon.h"
  11. #include "acinterp.h"
  12. #define _COMPONENT ACPI_EXECUTER
  13. ACPI_MODULE_NAME("exstorob")
  14. /*******************************************************************************
  15. *
  16. * FUNCTION: acpi_ex_store_buffer_to_buffer
  17. *
  18. * PARAMETERS: source_desc - Source object to copy
  19. * target_desc - Destination object of the copy
  20. *
  21. * RETURN: Status
  22. *
  23. * DESCRIPTION: Copy a buffer object to another buffer object.
  24. *
  25. ******************************************************************************/
  26. acpi_status
  27. acpi_ex_store_buffer_to_buffer(union acpi_operand_object *source_desc,
  28. union acpi_operand_object *target_desc)
  29. {
  30. u32 length;
  31. u8 *buffer;
  32. ACPI_FUNCTION_TRACE_PTR(ex_store_buffer_to_buffer, source_desc);
  33. /* If Source and Target are the same, just return */
  34. if (source_desc == target_desc) {
  35. return_ACPI_STATUS(AE_OK);
  36. }
  37. /* We know that source_desc is a buffer by now */
  38. buffer = ACPI_CAST_PTR(u8, source_desc->buffer.pointer);
  39. length = source_desc->buffer.length;
  40. /*
  41. * If target is a buffer of length zero or is a static buffer,
  42. * allocate a new buffer of the proper length
  43. */
  44. if ((target_desc->buffer.length == 0) ||
  45. (target_desc->common.flags & AOPOBJ_STATIC_POINTER)) {
  46. target_desc->buffer.pointer = ACPI_ALLOCATE(length);
  47. if (!target_desc->buffer.pointer) {
  48. return_ACPI_STATUS(AE_NO_MEMORY);
  49. }
  50. target_desc->buffer.length = length;
  51. }
  52. /* Copy source buffer to target buffer */
  53. if (length <= target_desc->buffer.length) {
  54. /* Clear existing buffer and copy in the new one */
  55. memset(target_desc->buffer.pointer, 0,
  56. target_desc->buffer.length);
  57. memcpy(target_desc->buffer.pointer, buffer, length);
  58. #ifdef ACPI_OBSOLETE_BEHAVIOR
  59. /*
  60. * NOTE: ACPI versions up to 3.0 specified that the buffer must be
  61. * truncated if the string is smaller than the buffer. However, "other"
  62. * implementations of ACPI never did this and thus became the defacto
  63. * standard. ACPI 3.0A changes this behavior such that the buffer
  64. * is no longer truncated.
  65. */
  66. /*
  67. * OBSOLETE BEHAVIOR:
  68. * If the original source was a string, we must truncate the buffer,
  69. * according to the ACPI spec. Integer-to-Buffer and Buffer-to-Buffer
  70. * copy must not truncate the original buffer.
  71. */
  72. if (original_src_type == ACPI_TYPE_STRING) {
  73. /* Set the new length of the target */
  74. target_desc->buffer.length = length;
  75. }
  76. #endif
  77. } else {
  78. /* Truncate the source, copy only what will fit */
  79. memcpy(target_desc->buffer.pointer, buffer,
  80. target_desc->buffer.length);
  81. ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  82. "Truncating source buffer from %X to %X\n",
  83. length, target_desc->buffer.length));
  84. }
  85. /* Copy flags */
  86. target_desc->buffer.flags = source_desc->buffer.flags;
  87. target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
  88. return_ACPI_STATUS(AE_OK);
  89. }
  90. /*******************************************************************************
  91. *
  92. * FUNCTION: acpi_ex_store_string_to_string
  93. *
  94. * PARAMETERS: source_desc - Source object to copy
  95. * target_desc - Destination object of the copy
  96. *
  97. * RETURN: Status
  98. *
  99. * DESCRIPTION: Copy a String object to another String object
  100. *
  101. ******************************************************************************/
  102. acpi_status
  103. acpi_ex_store_string_to_string(union acpi_operand_object *source_desc,
  104. union acpi_operand_object *target_desc)
  105. {
  106. u32 length;
  107. u8 *buffer;
  108. ACPI_FUNCTION_TRACE_PTR(ex_store_string_to_string, source_desc);
  109. /* If Source and Target are the same, just return */
  110. if (source_desc == target_desc) {
  111. return_ACPI_STATUS(AE_OK);
  112. }
  113. /* We know that source_desc is a string by now */
  114. buffer = ACPI_CAST_PTR(u8, source_desc->string.pointer);
  115. length = source_desc->string.length;
  116. /*
  117. * Replace existing string value if it will fit and the string
  118. * pointer is not a static pointer (part of an ACPI table)
  119. */
  120. if ((length < target_desc->string.length) &&
  121. (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
  122. /*
  123. * String will fit in existing non-static buffer.
  124. * Clear old string and copy in the new one
  125. */
  126. memset(target_desc->string.pointer, 0,
  127. (acpi_size)target_desc->string.length + 1);
  128. memcpy(target_desc->string.pointer, buffer, length);
  129. } else {
  130. /*
  131. * Free the current buffer, then allocate a new buffer
  132. * large enough to hold the value
  133. */
  134. if (target_desc->string.pointer &&
  135. (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
  136. /* Only free if not a pointer into the DSDT */
  137. ACPI_FREE(target_desc->string.pointer);
  138. }
  139. target_desc->string.pointer =
  140. ACPI_ALLOCATE_ZEROED((acpi_size)length + 1);
  141. if (!target_desc->string.pointer) {
  142. return_ACPI_STATUS(AE_NO_MEMORY);
  143. }
  144. target_desc->common.flags &= ~AOPOBJ_STATIC_POINTER;
  145. memcpy(target_desc->string.pointer, buffer, length);
  146. }
  147. /* Set the new target length */
  148. target_desc->string.length = length;
  149. return_ACPI_STATUS(AE_OK);
  150. }