Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /******************************************************************************
0003  *
0004  * Module Name: utalloc - local memory allocation routines
0005  *
0006  * Copyright (C) 2000 - 2022, Intel Corp.
0007  *
0008  *****************************************************************************/
0009 
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acdebug.h"
0013 
0014 #define _COMPONENT          ACPI_UTILITIES
0015 ACPI_MODULE_NAME("utalloc")
0016 
0017 #if !defined (USE_NATIVE_ALLOCATE_ZEROED)
0018 /*******************************************************************************
0019  *
0020  * FUNCTION:    acpi_os_allocate_zeroed
0021  *
0022  * PARAMETERS:  size                - Size of the allocation
0023  *
0024  * RETURN:      Address of the allocated memory on success, NULL on failure.
0025  *
0026  * DESCRIPTION: Subsystem equivalent of calloc. Allocate and zero memory.
0027  *              This is the default implementation. Can be overridden via the
0028  *              USE_NATIVE_ALLOCATE_ZEROED flag.
0029  *
0030  ******************************************************************************/
0031 void *acpi_os_allocate_zeroed(acpi_size size)
0032 {
0033     void *allocation;
0034 
0035     ACPI_FUNCTION_ENTRY();
0036 
0037     allocation = acpi_os_allocate(size);
0038     if (allocation) {
0039 
0040         /* Clear the memory block */
0041 
0042         memset(allocation, 0, size);
0043     }
0044 
0045     return (allocation);
0046 }
0047 
0048 #endif              /* !USE_NATIVE_ALLOCATE_ZEROED */
0049 
0050 /*******************************************************************************
0051  *
0052  * FUNCTION:    acpi_ut_create_caches
0053  *
0054  * PARAMETERS:  None
0055  *
0056  * RETURN:      Status
0057  *
0058  * DESCRIPTION: Create all local caches
0059  *
0060  ******************************************************************************/
0061 
0062 acpi_status acpi_ut_create_caches(void)
0063 {
0064     acpi_status status;
0065 
0066     /* Object Caches, for frequently used objects */
0067 
0068     status =
0069         acpi_os_create_cache("Acpi-Namespace",
0070                  sizeof(struct acpi_namespace_node),
0071                  ACPI_MAX_NAMESPACE_CACHE_DEPTH,
0072                  &acpi_gbl_namespace_cache);
0073     if (ACPI_FAILURE(status)) {
0074         return (status);
0075     }
0076 
0077     status =
0078         acpi_os_create_cache("Acpi-State", sizeof(union acpi_generic_state),
0079                  ACPI_MAX_STATE_CACHE_DEPTH,
0080                  &acpi_gbl_state_cache);
0081     if (ACPI_FAILURE(status)) {
0082         return (status);
0083     }
0084 
0085     status =
0086         acpi_os_create_cache("Acpi-Parse",
0087                  sizeof(struct acpi_parse_obj_common),
0088                  ACPI_MAX_PARSE_CACHE_DEPTH,
0089                  &acpi_gbl_ps_node_cache);
0090     if (ACPI_FAILURE(status)) {
0091         return (status);
0092     }
0093 
0094     status =
0095         acpi_os_create_cache("Acpi-ParseExt",
0096                  sizeof(struct acpi_parse_obj_named),
0097                  ACPI_MAX_EXTPARSE_CACHE_DEPTH,
0098                  &acpi_gbl_ps_node_ext_cache);
0099     if (ACPI_FAILURE(status)) {
0100         return (status);
0101     }
0102 
0103     status =
0104         acpi_os_create_cache("Acpi-Operand",
0105                  sizeof(union acpi_operand_object),
0106                  ACPI_MAX_OBJECT_CACHE_DEPTH,
0107                  &acpi_gbl_operand_cache);
0108     if (ACPI_FAILURE(status)) {
0109         return (status);
0110     }
0111 #ifdef ACPI_ASL_COMPILER
0112     /*
0113      * For use with the ASL-/ASL+ option. This cache keeps track of regular
0114      * 0xA9 0x01 comments.
0115      */
0116     status =
0117         acpi_os_create_cache("Acpi-Comment",
0118                  sizeof(struct acpi_comment_node),
0119                  ACPI_MAX_COMMENT_CACHE_DEPTH,
0120                  &acpi_gbl_reg_comment_cache);
0121     if (ACPI_FAILURE(status)) {
0122         return (status);
0123     }
0124 
0125     /*
0126      * This cache keeps track of the starting addresses of where the comments
0127      * lie. This helps prevent duplication of comments.
0128      */
0129     status =
0130         acpi_os_create_cache("Acpi-Comment-Addr",
0131                  sizeof(struct acpi_comment_addr_node),
0132                  ACPI_MAX_COMMENT_CACHE_DEPTH,
0133                  &acpi_gbl_comment_addr_cache);
0134     if (ACPI_FAILURE(status)) {
0135         return (status);
0136     }
0137 
0138     /*
0139      * This cache will be used for nodes that represent files.
0140      */
0141     status =
0142         acpi_os_create_cache("Acpi-File", sizeof(struct acpi_file_node),
0143                  ACPI_MAX_COMMENT_CACHE_DEPTH,
0144                  &acpi_gbl_file_cache);
0145     if (ACPI_FAILURE(status)) {
0146         return (status);
0147     }
0148 #endif
0149 
0150 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
0151 
0152     /* Memory allocation lists */
0153 
0154     status = acpi_ut_create_list("Acpi-Global", 0, &acpi_gbl_global_list);
0155     if (ACPI_FAILURE(status)) {
0156         return (status);
0157     }
0158 
0159     status =
0160         acpi_ut_create_list("Acpi-Namespace",
0161                 sizeof(struct acpi_namespace_node),
0162                 &acpi_gbl_ns_node_list);
0163     if (ACPI_FAILURE(status)) {
0164         return (status);
0165     }
0166 #endif
0167 
0168     return (AE_OK);
0169 }
0170 
0171 /*******************************************************************************
0172  *
0173  * FUNCTION:    acpi_ut_delete_caches
0174  *
0175  * PARAMETERS:  None
0176  *
0177  * RETURN:      Status
0178  *
0179  * DESCRIPTION: Purge and delete all local caches
0180  *
0181  ******************************************************************************/
0182 
0183 acpi_status acpi_ut_delete_caches(void)
0184 {
0185 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
0186     char buffer[7];
0187 
0188     if (acpi_gbl_display_final_mem_stats) {
0189         strcpy(buffer, "MEMORY");
0190         (void)acpi_db_display_statistics(buffer);
0191     }
0192 #endif
0193 
0194     (void)acpi_os_delete_cache(acpi_gbl_namespace_cache);
0195     acpi_gbl_namespace_cache = NULL;
0196 
0197     (void)acpi_os_delete_cache(acpi_gbl_state_cache);
0198     acpi_gbl_state_cache = NULL;
0199 
0200     (void)acpi_os_delete_cache(acpi_gbl_operand_cache);
0201     acpi_gbl_operand_cache = NULL;
0202 
0203     (void)acpi_os_delete_cache(acpi_gbl_ps_node_cache);
0204     acpi_gbl_ps_node_cache = NULL;
0205 
0206     (void)acpi_os_delete_cache(acpi_gbl_ps_node_ext_cache);
0207     acpi_gbl_ps_node_ext_cache = NULL;
0208 
0209 #ifdef ACPI_ASL_COMPILER
0210     (void)acpi_os_delete_cache(acpi_gbl_reg_comment_cache);
0211     acpi_gbl_reg_comment_cache = NULL;
0212 
0213     (void)acpi_os_delete_cache(acpi_gbl_comment_addr_cache);
0214     acpi_gbl_comment_addr_cache = NULL;
0215 
0216     (void)acpi_os_delete_cache(acpi_gbl_file_cache);
0217     acpi_gbl_file_cache = NULL;
0218 #endif
0219 
0220 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
0221 
0222     /* Debug only - display leftover memory allocation, if any */
0223 
0224     acpi_ut_dump_allocations(ACPI_UINT32_MAX, NULL);
0225 
0226     /* Free memory lists */
0227 
0228     acpi_os_free(acpi_gbl_global_list);
0229     acpi_gbl_global_list = NULL;
0230 
0231     acpi_os_free(acpi_gbl_ns_node_list);
0232     acpi_gbl_ns_node_list = NULL;
0233 #endif
0234 
0235     return (AE_OK);
0236 }
0237 
0238 /*******************************************************************************
0239  *
0240  * FUNCTION:    acpi_ut_validate_buffer
0241  *
0242  * PARAMETERS:  buffer              - Buffer descriptor to be validated
0243  *
0244  * RETURN:      Status
0245  *
0246  * DESCRIPTION: Perform parameter validation checks on an struct acpi_buffer
0247  *
0248  ******************************************************************************/
0249 
0250 acpi_status acpi_ut_validate_buffer(struct acpi_buffer *buffer)
0251 {
0252 
0253     /* Obviously, the structure pointer must be valid */
0254 
0255     if (!buffer) {
0256         return (AE_BAD_PARAMETER);
0257     }
0258 
0259     /* Special semantics for the length */
0260 
0261     if ((buffer->length == ACPI_NO_BUFFER) ||
0262         (buffer->length == ACPI_ALLOCATE_BUFFER) ||
0263         (buffer->length == ACPI_ALLOCATE_LOCAL_BUFFER)) {
0264         return (AE_OK);
0265     }
0266 
0267     /* Length is valid, the buffer pointer must be also */
0268 
0269     if (!buffer->pointer) {
0270         return (AE_BAD_PARAMETER);
0271     }
0272 
0273     return (AE_OK);
0274 }
0275 
0276 /*******************************************************************************
0277  *
0278  * FUNCTION:    acpi_ut_initialize_buffer
0279  *
0280  * PARAMETERS:  buffer              - Buffer to be validated
0281  *              required_length     - Length needed
0282  *
0283  * RETURN:      Status
0284  *
0285  * DESCRIPTION: Validate that the buffer is of the required length or
0286  *              allocate a new buffer. Returned buffer is always zeroed.
0287  *
0288  ******************************************************************************/
0289 
0290 acpi_status
0291 acpi_ut_initialize_buffer(struct acpi_buffer *buffer, acpi_size required_length)
0292 {
0293     acpi_size input_buffer_length;
0294 
0295     /* Parameter validation */
0296 
0297     if (!buffer || !required_length) {
0298         return (AE_BAD_PARAMETER);
0299     }
0300 
0301     /*
0302      * Buffer->Length is used as both an input and output parameter. Get the
0303      * input actual length and set the output required buffer length.
0304      */
0305     input_buffer_length = buffer->length;
0306     buffer->length = required_length;
0307 
0308     /*
0309      * The input buffer length contains the actual buffer length, or the type
0310      * of buffer to be allocated by this routine.
0311      */
0312     switch (input_buffer_length) {
0313     case ACPI_NO_BUFFER:
0314 
0315         /* Return the exception (and the required buffer length) */
0316 
0317         return (AE_BUFFER_OVERFLOW);
0318 
0319     case ACPI_ALLOCATE_BUFFER:
0320         /*
0321          * Allocate a new buffer. We directectly call acpi_os_allocate here to
0322          * purposefully bypass the (optionally enabled) internal allocation
0323          * tracking mechanism since we only want to track internal
0324          * allocations. Note: The caller should use acpi_os_free to free this
0325          * buffer created via ACPI_ALLOCATE_BUFFER.
0326          */
0327         buffer->pointer = acpi_os_allocate(required_length);
0328         break;
0329 
0330     case ACPI_ALLOCATE_LOCAL_BUFFER:
0331 
0332         /* Allocate a new buffer with local interface to allow tracking */
0333 
0334         buffer->pointer = ACPI_ALLOCATE(required_length);
0335         break;
0336 
0337     default:
0338 
0339         /* Existing buffer: Validate the size of the buffer */
0340 
0341         if (input_buffer_length < required_length) {
0342             return (AE_BUFFER_OVERFLOW);
0343         }
0344         break;
0345     }
0346 
0347     /* Validate allocation from above or input buffer pointer */
0348 
0349     if (!buffer->pointer) {
0350         return (AE_NO_MEMORY);
0351     }
0352 
0353     /* Have a valid buffer, clear it */
0354 
0355     memset(buffer->pointer, 0, required_length);
0356     return (AE_OK);
0357 }