1 /****************************************************************************** 2 * 3 * Module Name: utalloc - local memory allocation routines 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2018, 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 "acdebug.h" 47 48 #define _COMPONENT ACPI_UTILITIES 49 ACPI_MODULE_NAME("utalloc") 50 51 #if !defined (USE_NATIVE_ALLOCATE_ZEROED) 52 /******************************************************************************* 53 * 54 * FUNCTION: acpi_os_allocate_zeroed 55 * 56 * PARAMETERS: size - Size of the allocation 57 * 58 * RETURN: Address of the allocated memory on success, NULL on failure. 59 * 60 * DESCRIPTION: Subsystem equivalent of calloc. Allocate and zero memory. 61 * This is the default implementation. Can be overridden via the 62 * USE_NATIVE_ALLOCATE_ZEROED flag. 63 * 64 ******************************************************************************/ 65 void *acpi_os_allocate_zeroed(acpi_size size) 66 { 67 void *allocation; 68 69 ACPI_FUNCTION_ENTRY(); 70 71 allocation = acpi_os_allocate(size); 72 if (allocation) { 73 74 /* Clear the memory block */ 75 76 memset(allocation, 0, size); 77 } 78 79 return (allocation); 80 } 81 82 #endif /* !USE_NATIVE_ALLOCATE_ZEROED */ 83 84 /******************************************************************************* 85 * 86 * FUNCTION: acpi_ut_create_caches 87 * 88 * PARAMETERS: None 89 * 90 * RETURN: Status 91 * 92 * DESCRIPTION: Create all local caches 93 * 94 ******************************************************************************/ 95 96 acpi_status acpi_ut_create_caches(void) 97 { 98 acpi_status status; 99 100 /* Object Caches, for frequently used objects */ 101 102 status = 103 acpi_os_create_cache("Acpi-Namespace", 104 sizeof(struct acpi_namespace_node), 105 ACPI_MAX_NAMESPACE_CACHE_DEPTH, 106 &acpi_gbl_namespace_cache); 107 if (ACPI_FAILURE(status)) { 108 return (status); 109 } 110 111 status = 112 acpi_os_create_cache("Acpi-State", sizeof(union acpi_generic_state), 113 ACPI_MAX_STATE_CACHE_DEPTH, 114 &acpi_gbl_state_cache); 115 if (ACPI_FAILURE(status)) { 116 return (status); 117 } 118 119 status = 120 acpi_os_create_cache("Acpi-Parse", 121 sizeof(struct acpi_parse_obj_common), 122 ACPI_MAX_PARSE_CACHE_DEPTH, 123 &acpi_gbl_ps_node_cache); 124 if (ACPI_FAILURE(status)) { 125 return (status); 126 } 127 128 status = 129 acpi_os_create_cache("Acpi-ParseExt", 130 sizeof(struct acpi_parse_obj_named), 131 ACPI_MAX_EXTPARSE_CACHE_DEPTH, 132 &acpi_gbl_ps_node_ext_cache); 133 if (ACPI_FAILURE(status)) { 134 return (status); 135 } 136 137 status = 138 acpi_os_create_cache("Acpi-Operand", 139 sizeof(union acpi_operand_object), 140 ACPI_MAX_OBJECT_CACHE_DEPTH, 141 &acpi_gbl_operand_cache); 142 if (ACPI_FAILURE(status)) { 143 return (status); 144 } 145 #ifdef ACPI_ASL_COMPILER 146 /* 147 * For use with the ASL-/ASL+ option. This cache keeps track of regular 148 * 0xA9 0x01 comments. 149 */ 150 status = 151 acpi_os_create_cache("Acpi-Comment", 152 sizeof(struct acpi_comment_node), 153 ACPI_MAX_COMMENT_CACHE_DEPTH, 154 &acpi_gbl_reg_comment_cache); 155 if (ACPI_FAILURE(status)) { 156 return (status); 157 } 158 159 /* 160 * This cache keeps track of the starting addresses of where the comments 161 * lie. This helps prevent duplication of comments. 162 */ 163 status = 164 acpi_os_create_cache("Acpi-Comment-Addr", 165 sizeof(struct acpi_comment_addr_node), 166 ACPI_MAX_COMMENT_CACHE_DEPTH, 167 &acpi_gbl_comment_addr_cache); 168 if (ACPI_FAILURE(status)) { 169 return (status); 170 } 171 172 /* 173 * This cache will be used for nodes that represent files. 174 */ 175 status = 176 acpi_os_create_cache("Acpi-File", sizeof(struct acpi_file_node), 177 ACPI_MAX_COMMENT_CACHE_DEPTH, 178 &acpi_gbl_file_cache); 179 if (ACPI_FAILURE(status)) { 180 return (status); 181 } 182 #endif 183 184 #ifdef ACPI_DBG_TRACK_ALLOCATIONS 185 186 /* Memory allocation lists */ 187 188 status = acpi_ut_create_list("Acpi-Global", 0, &acpi_gbl_global_list); 189 if (ACPI_FAILURE(status)) { 190 return (status); 191 } 192 193 status = 194 acpi_ut_create_list("Acpi-Namespace", 195 sizeof(struct acpi_namespace_node), 196 &acpi_gbl_ns_node_list); 197 if (ACPI_FAILURE(status)) { 198 return (status); 199 } 200 #endif 201 202 return (AE_OK); 203 } 204 205 /******************************************************************************* 206 * 207 * FUNCTION: acpi_ut_delete_caches 208 * 209 * PARAMETERS: None 210 * 211 * RETURN: Status 212 * 213 * DESCRIPTION: Purge and delete all local caches 214 * 215 ******************************************************************************/ 216 217 acpi_status acpi_ut_delete_caches(void) 218 { 219 #ifdef ACPI_DBG_TRACK_ALLOCATIONS 220 char buffer[7]; 221 222 if (acpi_gbl_display_final_mem_stats) { 223 strcpy(buffer, "MEMORY"); 224 (void)acpi_db_display_statistics(buffer); 225 } 226 #endif 227 228 (void)acpi_os_delete_cache(acpi_gbl_namespace_cache); 229 acpi_gbl_namespace_cache = NULL; 230 231 (void)acpi_os_delete_cache(acpi_gbl_state_cache); 232 acpi_gbl_state_cache = NULL; 233 234 (void)acpi_os_delete_cache(acpi_gbl_operand_cache); 235 acpi_gbl_operand_cache = NULL; 236 237 (void)acpi_os_delete_cache(acpi_gbl_ps_node_cache); 238 acpi_gbl_ps_node_cache = NULL; 239 240 (void)acpi_os_delete_cache(acpi_gbl_ps_node_ext_cache); 241 acpi_gbl_ps_node_ext_cache = NULL; 242 243 #ifdef ACPI_ASL_COMPILER 244 (void)acpi_os_delete_cache(acpi_gbl_reg_comment_cache); 245 acpi_gbl_reg_comment_cache = NULL; 246 247 (void)acpi_os_delete_cache(acpi_gbl_comment_addr_cache); 248 acpi_gbl_comment_addr_cache = NULL; 249 250 (void)acpi_os_delete_cache(acpi_gbl_file_cache); 251 acpi_gbl_file_cache = NULL; 252 #endif 253 254 #ifdef ACPI_DBG_TRACK_ALLOCATIONS 255 256 /* Debug only - display leftover memory allocation, if any */ 257 258 acpi_ut_dump_allocations(ACPI_UINT32_MAX, NULL); 259 260 /* Free memory lists */ 261 262 acpi_os_free(acpi_gbl_global_list); 263 acpi_gbl_global_list = NULL; 264 265 acpi_os_free(acpi_gbl_ns_node_list); 266 acpi_gbl_ns_node_list = NULL; 267 #endif 268 269 return (AE_OK); 270 } 271 272 /******************************************************************************* 273 * 274 * FUNCTION: acpi_ut_validate_buffer 275 * 276 * PARAMETERS: buffer - Buffer descriptor to be validated 277 * 278 * RETURN: Status 279 * 280 * DESCRIPTION: Perform parameter validation checks on an struct acpi_buffer 281 * 282 ******************************************************************************/ 283 284 acpi_status acpi_ut_validate_buffer(struct acpi_buffer *buffer) 285 { 286 287 /* Obviously, the structure pointer must be valid */ 288 289 if (!buffer) { 290 return (AE_BAD_PARAMETER); 291 } 292 293 /* Special semantics for the length */ 294 295 if ((buffer->length == ACPI_NO_BUFFER) || 296 (buffer->length == ACPI_ALLOCATE_BUFFER) || 297 (buffer->length == ACPI_ALLOCATE_LOCAL_BUFFER)) { 298 return (AE_OK); 299 } 300 301 /* Length is valid, the buffer pointer must be also */ 302 303 if (!buffer->pointer) { 304 return (AE_BAD_PARAMETER); 305 } 306 307 return (AE_OK); 308 } 309 310 /******************************************************************************* 311 * 312 * FUNCTION: acpi_ut_initialize_buffer 313 * 314 * PARAMETERS: buffer - Buffer to be validated 315 * required_length - Length needed 316 * 317 * RETURN: Status 318 * 319 * DESCRIPTION: Validate that the buffer is of the required length or 320 * allocate a new buffer. Returned buffer is always zeroed. 321 * 322 ******************************************************************************/ 323 324 acpi_status 325 acpi_ut_initialize_buffer(struct acpi_buffer *buffer, acpi_size required_length) 326 { 327 acpi_size input_buffer_length; 328 329 /* Parameter validation */ 330 331 if (!buffer || !required_length) { 332 return (AE_BAD_PARAMETER); 333 } 334 335 /* 336 * Buffer->Length is used as both an input and output parameter. Get the 337 * input actual length and set the output required buffer length. 338 */ 339 input_buffer_length = buffer->length; 340 buffer->length = required_length; 341 342 /* 343 * The input buffer length contains the actual buffer length, or the type 344 * of buffer to be allocated by this routine. 345 */ 346 switch (input_buffer_length) { 347 case ACPI_NO_BUFFER: 348 349 /* Return the exception (and the required buffer length) */ 350 351 return (AE_BUFFER_OVERFLOW); 352 353 case ACPI_ALLOCATE_BUFFER: 354 /* 355 * Allocate a new buffer. We directectly call acpi_os_allocate here to 356 * purposefully bypass the (optionally enabled) internal allocation 357 * tracking mechanism since we only want to track internal 358 * allocations. Note: The caller should use acpi_os_free to free this 359 * buffer created via ACPI_ALLOCATE_BUFFER. 360 */ 361 buffer->pointer = acpi_os_allocate(required_length); 362 break; 363 364 case ACPI_ALLOCATE_LOCAL_BUFFER: 365 366 /* Allocate a new buffer with local interface to allow tracking */ 367 368 buffer->pointer = ACPI_ALLOCATE(required_length); 369 break; 370 371 default: 372 373 /* Existing buffer: Validate the size of the buffer */ 374 375 if (input_buffer_length < required_length) { 376 return (AE_BUFFER_OVERFLOW); 377 } 378 break; 379 } 380 381 /* Validate allocation from above or input buffer pointer */ 382 383 if (!buffer->pointer) { 384 return (AE_NO_MEMORY); 385 } 386 387 /* Have a valid buffer, clear it */ 388 389 memset(buffer->pointer, 0, required_length); 390 return (AE_OK); 391 } 392