utalloc.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2. /******************************************************************************
  3. *
  4. * Module Name: utalloc - local memory allocation routines
  5. *
  6. * Copyright (C) 2000 - 2022, Intel Corp.
  7. *
  8. *****************************************************************************/
  9. #include <acpi/acpi.h>
  10. #include "accommon.h"
  11. #include "acdebug.h"
  12. #define _COMPONENT ACPI_UTILITIES
  13. ACPI_MODULE_NAME("utalloc")
  14. #if !defined (USE_NATIVE_ALLOCATE_ZEROED)
  15. /*******************************************************************************
  16. *
  17. * FUNCTION: acpi_os_allocate_zeroed
  18. *
  19. * PARAMETERS: size - Size of the allocation
  20. *
  21. * RETURN: Address of the allocated memory on success, NULL on failure.
  22. *
  23. * DESCRIPTION: Subsystem equivalent of calloc. Allocate and zero memory.
  24. * This is the default implementation. Can be overridden via the
  25. * USE_NATIVE_ALLOCATE_ZEROED flag.
  26. *
  27. ******************************************************************************/
  28. void *acpi_os_allocate_zeroed(acpi_size size)
  29. {
  30. void *allocation;
  31. ACPI_FUNCTION_ENTRY();
  32. allocation = acpi_os_allocate(size);
  33. if (allocation) {
  34. /* Clear the memory block */
  35. memset(allocation, 0, size);
  36. }
  37. return (allocation);
  38. }
  39. #endif /* !USE_NATIVE_ALLOCATE_ZEROED */
  40. /*******************************************************************************
  41. *
  42. * FUNCTION: acpi_ut_create_caches
  43. *
  44. * PARAMETERS: None
  45. *
  46. * RETURN: Status
  47. *
  48. * DESCRIPTION: Create all local caches
  49. *
  50. ******************************************************************************/
  51. acpi_status acpi_ut_create_caches(void)
  52. {
  53. acpi_status status;
  54. /* Object Caches, for frequently used objects */
  55. status =
  56. acpi_os_create_cache("Acpi-Namespace",
  57. sizeof(struct acpi_namespace_node),
  58. ACPI_MAX_NAMESPACE_CACHE_DEPTH,
  59. &acpi_gbl_namespace_cache);
  60. if (ACPI_FAILURE(status)) {
  61. return (status);
  62. }
  63. status =
  64. acpi_os_create_cache("Acpi-State", sizeof(union acpi_generic_state),
  65. ACPI_MAX_STATE_CACHE_DEPTH,
  66. &acpi_gbl_state_cache);
  67. if (ACPI_FAILURE(status)) {
  68. return (status);
  69. }
  70. status =
  71. acpi_os_create_cache("Acpi-Parse",
  72. sizeof(struct acpi_parse_obj_common),
  73. ACPI_MAX_PARSE_CACHE_DEPTH,
  74. &acpi_gbl_ps_node_cache);
  75. if (ACPI_FAILURE(status)) {
  76. return (status);
  77. }
  78. status =
  79. acpi_os_create_cache("Acpi-ParseExt",
  80. sizeof(struct acpi_parse_obj_named),
  81. ACPI_MAX_EXTPARSE_CACHE_DEPTH,
  82. &acpi_gbl_ps_node_ext_cache);
  83. if (ACPI_FAILURE(status)) {
  84. return (status);
  85. }
  86. status =
  87. acpi_os_create_cache("Acpi-Operand",
  88. sizeof(union acpi_operand_object),
  89. ACPI_MAX_OBJECT_CACHE_DEPTH,
  90. &acpi_gbl_operand_cache);
  91. if (ACPI_FAILURE(status)) {
  92. return (status);
  93. }
  94. #ifdef ACPI_ASL_COMPILER
  95. /*
  96. * For use with the ASL-/ASL+ option. This cache keeps track of regular
  97. * 0xA9 0x01 comments.
  98. */
  99. status =
  100. acpi_os_create_cache("Acpi-Comment",
  101. sizeof(struct acpi_comment_node),
  102. ACPI_MAX_COMMENT_CACHE_DEPTH,
  103. &acpi_gbl_reg_comment_cache);
  104. if (ACPI_FAILURE(status)) {
  105. return (status);
  106. }
  107. /*
  108. * This cache keeps track of the starting addresses of where the comments
  109. * lie. This helps prevent duplication of comments.
  110. */
  111. status =
  112. acpi_os_create_cache("Acpi-Comment-Addr",
  113. sizeof(struct acpi_comment_addr_node),
  114. ACPI_MAX_COMMENT_CACHE_DEPTH,
  115. &acpi_gbl_comment_addr_cache);
  116. if (ACPI_FAILURE(status)) {
  117. return (status);
  118. }
  119. /*
  120. * This cache will be used for nodes that represent files.
  121. */
  122. status =
  123. acpi_os_create_cache("Acpi-File", sizeof(struct acpi_file_node),
  124. ACPI_MAX_COMMENT_CACHE_DEPTH,
  125. &acpi_gbl_file_cache);
  126. if (ACPI_FAILURE(status)) {
  127. return (status);
  128. }
  129. #endif
  130. #ifdef ACPI_DBG_TRACK_ALLOCATIONS
  131. /* Memory allocation lists */
  132. status = acpi_ut_create_list("Acpi-Global", 0, &acpi_gbl_global_list);
  133. if (ACPI_FAILURE(status)) {
  134. return (status);
  135. }
  136. status =
  137. acpi_ut_create_list("Acpi-Namespace",
  138. sizeof(struct acpi_namespace_node),
  139. &acpi_gbl_ns_node_list);
  140. if (ACPI_FAILURE(status)) {
  141. return (status);
  142. }
  143. #endif
  144. return (AE_OK);
  145. }
  146. /*******************************************************************************
  147. *
  148. * FUNCTION: acpi_ut_delete_caches
  149. *
  150. * PARAMETERS: None
  151. *
  152. * RETURN: Status
  153. *
  154. * DESCRIPTION: Purge and delete all local caches
  155. *
  156. ******************************************************************************/
  157. acpi_status acpi_ut_delete_caches(void)
  158. {
  159. #ifdef ACPI_DBG_TRACK_ALLOCATIONS
  160. char buffer[7];
  161. if (acpi_gbl_display_final_mem_stats) {
  162. strcpy(buffer, "MEMORY");
  163. (void)acpi_db_display_statistics(buffer);
  164. }
  165. #endif
  166. (void)acpi_os_delete_cache(acpi_gbl_namespace_cache);
  167. acpi_gbl_namespace_cache = NULL;
  168. (void)acpi_os_delete_cache(acpi_gbl_state_cache);
  169. acpi_gbl_state_cache = NULL;
  170. (void)acpi_os_delete_cache(acpi_gbl_operand_cache);
  171. acpi_gbl_operand_cache = NULL;
  172. (void)acpi_os_delete_cache(acpi_gbl_ps_node_cache);
  173. acpi_gbl_ps_node_cache = NULL;
  174. (void)acpi_os_delete_cache(acpi_gbl_ps_node_ext_cache);
  175. acpi_gbl_ps_node_ext_cache = NULL;
  176. #ifdef ACPI_ASL_COMPILER
  177. (void)acpi_os_delete_cache(acpi_gbl_reg_comment_cache);
  178. acpi_gbl_reg_comment_cache = NULL;
  179. (void)acpi_os_delete_cache(acpi_gbl_comment_addr_cache);
  180. acpi_gbl_comment_addr_cache = NULL;
  181. (void)acpi_os_delete_cache(acpi_gbl_file_cache);
  182. acpi_gbl_file_cache = NULL;
  183. #endif
  184. #ifdef ACPI_DBG_TRACK_ALLOCATIONS
  185. /* Debug only - display leftover memory allocation, if any */
  186. acpi_ut_dump_allocations(ACPI_UINT32_MAX, NULL);
  187. /* Free memory lists */
  188. acpi_os_free(acpi_gbl_global_list);
  189. acpi_gbl_global_list = NULL;
  190. acpi_os_free(acpi_gbl_ns_node_list);
  191. acpi_gbl_ns_node_list = NULL;
  192. #endif
  193. return (AE_OK);
  194. }
  195. /*******************************************************************************
  196. *
  197. * FUNCTION: acpi_ut_validate_buffer
  198. *
  199. * PARAMETERS: buffer - Buffer descriptor to be validated
  200. *
  201. * RETURN: Status
  202. *
  203. * DESCRIPTION: Perform parameter validation checks on an struct acpi_buffer
  204. *
  205. ******************************************************************************/
  206. acpi_status acpi_ut_validate_buffer(struct acpi_buffer *buffer)
  207. {
  208. /* Obviously, the structure pointer must be valid */
  209. if (!buffer) {
  210. return (AE_BAD_PARAMETER);
  211. }
  212. /* Special semantics for the length */
  213. if ((buffer->length == ACPI_NO_BUFFER) ||
  214. (buffer->length == ACPI_ALLOCATE_BUFFER) ||
  215. (buffer->length == ACPI_ALLOCATE_LOCAL_BUFFER)) {
  216. return (AE_OK);
  217. }
  218. /* Length is valid, the buffer pointer must be also */
  219. if (!buffer->pointer) {
  220. return (AE_BAD_PARAMETER);
  221. }
  222. return (AE_OK);
  223. }
  224. /*******************************************************************************
  225. *
  226. * FUNCTION: acpi_ut_initialize_buffer
  227. *
  228. * PARAMETERS: buffer - Buffer to be validated
  229. * required_length - Length needed
  230. *
  231. * RETURN: Status
  232. *
  233. * DESCRIPTION: Validate that the buffer is of the required length or
  234. * allocate a new buffer. Returned buffer is always zeroed.
  235. *
  236. ******************************************************************************/
  237. acpi_status
  238. acpi_ut_initialize_buffer(struct acpi_buffer *buffer, acpi_size required_length)
  239. {
  240. acpi_size input_buffer_length;
  241. /* Parameter validation */
  242. if (!buffer || !required_length) {
  243. return (AE_BAD_PARAMETER);
  244. }
  245. /*
  246. * Buffer->Length is used as both an input and output parameter. Get the
  247. * input actual length and set the output required buffer length.
  248. */
  249. input_buffer_length = buffer->length;
  250. buffer->length = required_length;
  251. /*
  252. * The input buffer length contains the actual buffer length, or the type
  253. * of buffer to be allocated by this routine.
  254. */
  255. switch (input_buffer_length) {
  256. case ACPI_NO_BUFFER:
  257. /* Return the exception (and the required buffer length) */
  258. return (AE_BUFFER_OVERFLOW);
  259. case ACPI_ALLOCATE_BUFFER:
  260. /*
  261. * Allocate a new buffer. We directectly call acpi_os_allocate here to
  262. * purposefully bypass the (optionally enabled) internal allocation
  263. * tracking mechanism since we only want to track internal
  264. * allocations. Note: The caller should use acpi_os_free to free this
  265. * buffer created via ACPI_ALLOCATE_BUFFER.
  266. */
  267. buffer->pointer = acpi_os_allocate(required_length);
  268. break;
  269. case ACPI_ALLOCATE_LOCAL_BUFFER:
  270. /* Allocate a new buffer with local interface to allow tracking */
  271. buffer->pointer = ACPI_ALLOCATE(required_length);
  272. break;
  273. default:
  274. /* Existing buffer: Validate the size of the buffer */
  275. if (input_buffer_length < required_length) {
  276. return (AE_BUFFER_OVERFLOW);
  277. }
  278. break;
  279. }
  280. /* Validate allocation from above or input buffer pointer */
  281. if (!buffer->pointer) {
  282. return (AE_NO_MEMORY);
  283. }
  284. /* Have a valid buffer, clear it */
  285. memset(buffer->pointer, 0, required_length);
  286. return (AE_OK);
  287. }