Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /******************************************************************************
0003  *
0004  * Module Name: utobject - ACPI object create/delete/size/cache routines
0005  *
0006  * Copyright (C) 2000 - 2022, Intel Corp.
0007  *
0008  *****************************************************************************/
0009 
0010 #include <acpi/acpi.h>
0011 #include <linux/kmemleak.h>
0012 #include "accommon.h"
0013 #include "acnamesp.h"
0014 
0015 #define _COMPONENT          ACPI_UTILITIES
0016 ACPI_MODULE_NAME("utobject")
0017 
0018 /* Local prototypes */
0019 static acpi_status
0020 acpi_ut_get_simple_object_size(union acpi_operand_object *obj,
0021                    acpi_size *obj_length);
0022 
0023 static acpi_status
0024 acpi_ut_get_package_object_size(union acpi_operand_object *obj,
0025                 acpi_size *obj_length);
0026 
0027 static acpi_status
0028 acpi_ut_get_element_length(u8 object_type,
0029                union acpi_operand_object *source_object,
0030                union acpi_generic_state *state, void *context);
0031 
0032 /*******************************************************************************
0033  *
0034  * FUNCTION:    acpi_ut_create_internal_object_dbg
0035  *
0036  * PARAMETERS:  module_name         - Source file name of caller
0037  *              line_number         - Line number of caller
0038  *              component_id        - Component type of caller
0039  *              type                - ACPI Type of the new object
0040  *
0041  * RETURN:      A new internal object, null on failure
0042  *
0043  * DESCRIPTION: Create and initialize a new internal object.
0044  *
0045  * NOTE:        We always allocate the worst-case object descriptor because
0046  *              these objects are cached, and we want them to be
0047  *              one-size-satisfies-any-request. This in itself may not be
0048  *              the most memory efficient, but the efficiency of the object
0049  *              cache should more than make up for this!
0050  *
0051  ******************************************************************************/
0052 
0053 union acpi_operand_object *acpi_ut_create_internal_object_dbg(const char
0054                                   *module_name,
0055                                   u32 line_number,
0056                                   u32 component_id,
0057                                   acpi_object_type
0058                                   type)
0059 {
0060     union acpi_operand_object *object;
0061     union acpi_operand_object *second_object;
0062 
0063     ACPI_FUNCTION_TRACE_STR(ut_create_internal_object_dbg,
0064                 acpi_ut_get_type_name(type));
0065 
0066     /* Allocate the raw object descriptor */
0067 
0068     object =
0069         acpi_ut_allocate_object_desc_dbg(module_name, line_number,
0070                          component_id);
0071     if (!object) {
0072         return_PTR(NULL);
0073     }
0074     kmemleak_not_leak(object);
0075 
0076     switch (type) {
0077     case ACPI_TYPE_REGION:
0078     case ACPI_TYPE_BUFFER_FIELD:
0079     case ACPI_TYPE_LOCAL_BANK_FIELD:
0080 
0081         /* These types require a secondary object */
0082 
0083         second_object =
0084             acpi_ut_allocate_object_desc_dbg(module_name, line_number,
0085                              component_id);
0086         if (!second_object) {
0087             acpi_ut_delete_object_desc(object);
0088             return_PTR(NULL);
0089         }
0090 
0091         second_object->common.type = ACPI_TYPE_LOCAL_EXTRA;
0092         second_object->common.reference_count = 1;
0093 
0094         /* Link the second object to the first */
0095 
0096         object->common.next_object = second_object;
0097         break;
0098 
0099     default:
0100 
0101         /* All others have no secondary object */
0102         break;
0103     }
0104 
0105     /* Save the object type in the object descriptor */
0106 
0107     object->common.type = (u8) type;
0108 
0109     /* Init the reference count */
0110 
0111     object->common.reference_count = 1;
0112 
0113     /* Any per-type initialization should go here */
0114 
0115     return_PTR(object);
0116 }
0117 
0118 /*******************************************************************************
0119  *
0120  * FUNCTION:    acpi_ut_create_package_object
0121  *
0122  * PARAMETERS:  count               - Number of package elements
0123  *
0124  * RETURN:      Pointer to a new Package object, null on failure
0125  *
0126  * DESCRIPTION: Create a fully initialized package object
0127  *
0128  ******************************************************************************/
0129 
0130 union acpi_operand_object *acpi_ut_create_package_object(u32 count)
0131 {
0132     union acpi_operand_object *package_desc;
0133     union acpi_operand_object **package_elements;
0134 
0135     ACPI_FUNCTION_TRACE_U32(ut_create_package_object, count);
0136 
0137     /* Create a new Package object */
0138 
0139     package_desc = acpi_ut_create_internal_object(ACPI_TYPE_PACKAGE);
0140     if (!package_desc) {
0141         return_PTR(NULL);
0142     }
0143 
0144     /*
0145      * Create the element array. Count+1 allows the array to be null
0146      * terminated.
0147      */
0148     package_elements = ACPI_ALLOCATE_ZEROED(((acpi_size)count +
0149                          1) * sizeof(void *));
0150     if (!package_elements) {
0151         ACPI_FREE(package_desc);
0152         return_PTR(NULL);
0153     }
0154 
0155     package_desc->package.count = count;
0156     package_desc->package.elements = package_elements;
0157     return_PTR(package_desc);
0158 }
0159 
0160 /*******************************************************************************
0161  *
0162  * FUNCTION:    acpi_ut_create_integer_object
0163  *
0164  * PARAMETERS:  initial_value       - Initial value for the integer
0165  *
0166  * RETURN:      Pointer to a new Integer object, null on failure
0167  *
0168  * DESCRIPTION: Create an initialized integer object
0169  *
0170  ******************************************************************************/
0171 
0172 union acpi_operand_object *acpi_ut_create_integer_object(u64 initial_value)
0173 {
0174     union acpi_operand_object *integer_desc;
0175 
0176     ACPI_FUNCTION_TRACE(ut_create_integer_object);
0177 
0178     /* Create and initialize a new integer object */
0179 
0180     integer_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
0181     if (!integer_desc) {
0182         return_PTR(NULL);
0183     }
0184 
0185     integer_desc->integer.value = initial_value;
0186     return_PTR(integer_desc);
0187 }
0188 
0189 /*******************************************************************************
0190  *
0191  * FUNCTION:    acpi_ut_create_buffer_object
0192  *
0193  * PARAMETERS:  buffer_size            - Size of buffer to be created
0194  *
0195  * RETURN:      Pointer to a new Buffer object, null on failure
0196  *
0197  * DESCRIPTION: Create a fully initialized buffer object
0198  *
0199  ******************************************************************************/
0200 
0201 union acpi_operand_object *acpi_ut_create_buffer_object(acpi_size buffer_size)
0202 {
0203     union acpi_operand_object *buffer_desc;
0204     u8 *buffer = NULL;
0205 
0206     ACPI_FUNCTION_TRACE_U32(ut_create_buffer_object, buffer_size);
0207 
0208     /* Create a new Buffer object */
0209 
0210     buffer_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER);
0211     if (!buffer_desc) {
0212         return_PTR(NULL);
0213     }
0214 
0215     /* Create an actual buffer only if size > 0 */
0216 
0217     if (buffer_size > 0) {
0218 
0219         /* Allocate the actual buffer */
0220 
0221         buffer = ACPI_ALLOCATE_ZEROED(buffer_size);
0222         if (!buffer) {
0223             ACPI_ERROR((AE_INFO, "Could not allocate size %u",
0224                     (u32)buffer_size));
0225 
0226             acpi_ut_remove_reference(buffer_desc);
0227             return_PTR(NULL);
0228         }
0229     }
0230 
0231     /* Complete buffer object initialization */
0232 
0233     buffer_desc->buffer.flags |= AOPOBJ_DATA_VALID;
0234     buffer_desc->buffer.pointer = buffer;
0235     buffer_desc->buffer.length = (u32) buffer_size;
0236 
0237     /* Return the new buffer descriptor */
0238 
0239     return_PTR(buffer_desc);
0240 }
0241 
0242 /*******************************************************************************
0243  *
0244  * FUNCTION:    acpi_ut_create_string_object
0245  *
0246  * PARAMETERS:  string_size         - Size of string to be created. Does not
0247  *                                    include NULL terminator, this is added
0248  *                                    automatically.
0249  *
0250  * RETURN:      Pointer to a new String object
0251  *
0252  * DESCRIPTION: Create a fully initialized string object
0253  *
0254  ******************************************************************************/
0255 
0256 union acpi_operand_object *acpi_ut_create_string_object(acpi_size string_size)
0257 {
0258     union acpi_operand_object *string_desc;
0259     char *string;
0260 
0261     ACPI_FUNCTION_TRACE_U32(ut_create_string_object, string_size);
0262 
0263     /* Create a new String object */
0264 
0265     string_desc = acpi_ut_create_internal_object(ACPI_TYPE_STRING);
0266     if (!string_desc) {
0267         return_PTR(NULL);
0268     }
0269 
0270     /*
0271      * Allocate the actual string buffer -- (Size + 1) for NULL terminator.
0272      * NOTE: Zero-length strings are NULL terminated
0273      */
0274     string = ACPI_ALLOCATE_ZEROED(string_size + 1);
0275     if (!string) {
0276         ACPI_ERROR((AE_INFO, "Could not allocate size %u",
0277                 (u32)string_size));
0278 
0279         acpi_ut_remove_reference(string_desc);
0280         return_PTR(NULL);
0281     }
0282 
0283     /* Complete string object initialization */
0284 
0285     string_desc->string.pointer = string;
0286     string_desc->string.length = (u32) string_size;
0287 
0288     /* Return the new string descriptor */
0289 
0290     return_PTR(string_desc);
0291 }
0292 
0293 /*******************************************************************************
0294  *
0295  * FUNCTION:    acpi_ut_valid_internal_object
0296  *
0297  * PARAMETERS:  object              - Object to be validated
0298  *
0299  * RETURN:      TRUE if object is valid, FALSE otherwise
0300  *
0301  * DESCRIPTION: Validate a pointer to be of type union acpi_operand_object
0302  *
0303  ******************************************************************************/
0304 
0305 u8 acpi_ut_valid_internal_object(void *object)
0306 {
0307 
0308     ACPI_FUNCTION_NAME(ut_valid_internal_object);
0309 
0310     /* Check for a null pointer */
0311 
0312     if (!object) {
0313         ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "**** Null Object Ptr\n"));
0314         return (FALSE);
0315     }
0316 
0317     /* Check the descriptor type field */
0318 
0319     switch (ACPI_GET_DESCRIPTOR_TYPE(object)) {
0320     case ACPI_DESC_TYPE_OPERAND:
0321 
0322         /* The object appears to be a valid union acpi_operand_object */
0323 
0324         return (TRUE);
0325 
0326     default:
0327 
0328         ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
0329                   "%p is not an ACPI operand obj [%s]\n",
0330                   object, acpi_ut_get_descriptor_name(object)));
0331         break;
0332     }
0333 
0334     return (FALSE);
0335 }
0336 
0337 /*******************************************************************************
0338  *
0339  * FUNCTION:    acpi_ut_allocate_object_desc_dbg
0340  *
0341  * PARAMETERS:  module_name         - Caller's module name (for error output)
0342  *              line_number         - Caller's line number (for error output)
0343  *              component_id        - Caller's component ID (for error output)
0344  *
0345  * RETURN:      Pointer to newly allocated object descriptor. Null on error
0346  *
0347  * DESCRIPTION: Allocate a new object descriptor. Gracefully handle
0348  *              error conditions.
0349  *
0350  ******************************************************************************/
0351 
0352 void *acpi_ut_allocate_object_desc_dbg(const char *module_name,
0353                        u32 line_number, u32 component_id)
0354 {
0355     union acpi_operand_object *object;
0356 
0357     ACPI_FUNCTION_TRACE(ut_allocate_object_desc_dbg);
0358 
0359     object = acpi_os_acquire_object(acpi_gbl_operand_cache);
0360     if (!object) {
0361         ACPI_ERROR((module_name, line_number,
0362                 "Could not allocate an object descriptor"));
0363 
0364         return_PTR(NULL);
0365     }
0366 
0367     /* Mark the descriptor type */
0368 
0369     ACPI_SET_DESCRIPTOR_TYPE(object, ACPI_DESC_TYPE_OPERAND);
0370 
0371     ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "%p Size %X\n",
0372               object, (u32) sizeof(union acpi_operand_object)));
0373 
0374     return_PTR(object);
0375 }
0376 
0377 /*******************************************************************************
0378  *
0379  * FUNCTION:    acpi_ut_delete_object_desc
0380  *
0381  * PARAMETERS:  object          - An Acpi internal object to be deleted
0382  *
0383  * RETURN:      None.
0384  *
0385  * DESCRIPTION: Free an ACPI object descriptor or add it to the object cache
0386  *
0387  ******************************************************************************/
0388 
0389 void acpi_ut_delete_object_desc(union acpi_operand_object *object)
0390 {
0391     ACPI_FUNCTION_TRACE_PTR(ut_delete_object_desc, object);
0392 
0393     /* Object must be of type union acpi_operand_object */
0394 
0395     if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) {
0396         ACPI_ERROR((AE_INFO,
0397                 "%p is not an ACPI Operand object [%s]", object,
0398                 acpi_ut_get_descriptor_name(object)));
0399         return_VOID;
0400     }
0401 
0402     (void)acpi_os_release_object(acpi_gbl_operand_cache, object);
0403     return_VOID;
0404 }
0405 
0406 /*******************************************************************************
0407  *
0408  * FUNCTION:    acpi_ut_get_simple_object_size
0409  *
0410  * PARAMETERS:  internal_object    - An ACPI operand object
0411  *              obj_length         - Where the length is returned
0412  *
0413  * RETURN:      Status
0414  *
0415  * DESCRIPTION: This function is called to determine the space required to
0416  *              contain a simple object for return to an external user.
0417  *
0418  *              The length includes the object structure plus any additional
0419  *              needed space.
0420  *
0421  ******************************************************************************/
0422 
0423 static acpi_status
0424 acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
0425                    acpi_size *obj_length)
0426 {
0427     acpi_size length;
0428     acpi_size size;
0429     acpi_status status = AE_OK;
0430 
0431     ACPI_FUNCTION_TRACE_PTR(ut_get_simple_object_size, internal_object);
0432 
0433     /* Start with the length of the (external) Acpi object */
0434 
0435     length = sizeof(union acpi_object);
0436 
0437     /* A NULL object is allowed, can be a legal uninitialized package element */
0438 
0439     if (!internal_object) {
0440     /*
0441          * Object is NULL, just return the length of union acpi_object
0442          * (A NULL union acpi_object is an object of all zeroes.)
0443      */
0444         *obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD(length);
0445         return_ACPI_STATUS(AE_OK);
0446     }
0447 
0448     /* A Namespace Node should never appear here */
0449 
0450     if (ACPI_GET_DESCRIPTOR_TYPE(internal_object) == ACPI_DESC_TYPE_NAMED) {
0451 
0452         /* A namespace node should never get here */
0453 
0454         ACPI_ERROR((AE_INFO,
0455                 "Received a namespace node [%4.4s] "
0456                 "where an operand object is required",
0457                 ACPI_CAST_PTR(struct acpi_namespace_node,
0458                       internal_object)->name.ascii));
0459         return_ACPI_STATUS(AE_AML_INTERNAL);
0460     }
0461 
0462     /*
0463      * The final length depends on the object type
0464      * Strings and Buffers are packed right up against the parent object and
0465      * must be accessed bytewise or there may be alignment problems on
0466      * certain processors
0467      */
0468     switch (internal_object->common.type) {
0469     case ACPI_TYPE_STRING:
0470 
0471         length += (acpi_size)internal_object->string.length + 1;
0472         break;
0473 
0474     case ACPI_TYPE_BUFFER:
0475 
0476         length += (acpi_size)internal_object->buffer.length;
0477         break;
0478 
0479     case ACPI_TYPE_INTEGER:
0480     case ACPI_TYPE_PROCESSOR:
0481     case ACPI_TYPE_POWER:
0482 
0483         /* No extra data for these types */
0484 
0485         break;
0486 
0487     case ACPI_TYPE_LOCAL_REFERENCE:
0488 
0489         switch (internal_object->reference.class) {
0490         case ACPI_REFCLASS_NAME:
0491             /*
0492              * Get the actual length of the full pathname to this object.
0493              * The reference will be converted to the pathname to the object
0494              */
0495             size =
0496                 acpi_ns_get_pathname_length(internal_object->
0497                             reference.node);
0498             if (!size) {
0499                 return_ACPI_STATUS(AE_BAD_PARAMETER);
0500             }
0501 
0502             length += ACPI_ROUND_UP_TO_NATIVE_WORD(size);
0503             break;
0504 
0505         default:
0506             /*
0507              * No other reference opcodes are supported.
0508              * Notably, Locals and Args are not supported, but this may be
0509              * required eventually.
0510              */
0511             ACPI_ERROR((AE_INFO,
0512                     "Cannot convert to external object - "
0513                     "unsupported Reference Class [%s] 0x%X in object %p",
0514                     acpi_ut_get_reference_name(internal_object),
0515                     internal_object->reference.class,
0516                     internal_object));
0517             status = AE_TYPE;
0518             break;
0519         }
0520         break;
0521 
0522     default:
0523 
0524         ACPI_ERROR((AE_INFO, "Cannot convert to external object - "
0525                 "unsupported type [%s] 0x%X in object %p",
0526                 acpi_ut_get_object_type_name(internal_object),
0527                 internal_object->common.type, internal_object));
0528         status = AE_TYPE;
0529         break;
0530     }
0531 
0532     /*
0533      * Account for the space required by the object rounded up to the next
0534      * multiple of the machine word size. This keeps each object aligned
0535      * on a machine word boundary. (preventing alignment faults on some
0536      * machines.)
0537      */
0538     *obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD(length);
0539     return_ACPI_STATUS(status);
0540 }
0541 
0542 /*******************************************************************************
0543  *
0544  * FUNCTION:    acpi_ut_get_element_length
0545  *
0546  * PARAMETERS:  acpi_pkg_callback
0547  *
0548  * RETURN:      Status
0549  *
0550  * DESCRIPTION: Get the length of one package element.
0551  *
0552  ******************************************************************************/
0553 
0554 static acpi_status
0555 acpi_ut_get_element_length(u8 object_type,
0556                union acpi_operand_object *source_object,
0557                union acpi_generic_state *state, void *context)
0558 {
0559     acpi_status status = AE_OK;
0560     struct acpi_pkg_info *info = (struct acpi_pkg_info *)context;
0561     acpi_size object_space;
0562 
0563     switch (object_type) {
0564     case ACPI_COPY_TYPE_SIMPLE:
0565         /*
0566          * Simple object - just get the size (Null object/entry is handled
0567          * here also) and sum it into the running package length
0568          */
0569         status =
0570             acpi_ut_get_simple_object_size(source_object,
0571                            &object_space);
0572         if (ACPI_FAILURE(status)) {
0573             return (status);
0574         }
0575 
0576         info->length += object_space;
0577         break;
0578 
0579     case ACPI_COPY_TYPE_PACKAGE:
0580 
0581         /* Package object - nothing much to do here, let the walk handle it */
0582 
0583         info->num_packages++;
0584         state->pkg.this_target_obj = NULL;
0585         break;
0586 
0587     default:
0588 
0589         /* No other types allowed */
0590 
0591         return (AE_BAD_PARAMETER);
0592     }
0593 
0594     return (status);
0595 }
0596 
0597 /*******************************************************************************
0598  *
0599  * FUNCTION:    acpi_ut_get_package_object_size
0600  *
0601  * PARAMETERS:  internal_object     - An ACPI internal object
0602  *              obj_length          - Where the length is returned
0603  *
0604  * RETURN:      Status
0605  *
0606  * DESCRIPTION: This function is called to determine the space required to
0607  *              contain a package object for return to an external user.
0608  *
0609  *              This is moderately complex since a package contains other
0610  *              objects including packages.
0611  *
0612  ******************************************************************************/
0613 
0614 static acpi_status
0615 acpi_ut_get_package_object_size(union acpi_operand_object *internal_object,
0616                 acpi_size *obj_length)
0617 {
0618     acpi_status status;
0619     struct acpi_pkg_info info;
0620 
0621     ACPI_FUNCTION_TRACE_PTR(ut_get_package_object_size, internal_object);
0622 
0623     info.length = 0;
0624     info.object_space = 0;
0625     info.num_packages = 1;
0626 
0627     status =
0628         acpi_ut_walk_package_tree(internal_object, NULL,
0629                       acpi_ut_get_element_length, &info);
0630     if (ACPI_FAILURE(status)) {
0631         return_ACPI_STATUS(status);
0632     }
0633 
0634     /*
0635      * We have handled all of the objects in all levels of the package.
0636      * just add the length of the package objects themselves.
0637      * Round up to the next machine word.
0638      */
0639     info.length +=
0640         ACPI_ROUND_UP_TO_NATIVE_WORD(sizeof(union acpi_object)) *
0641         (acpi_size)info.num_packages;
0642 
0643     /* Return the total package length */
0644 
0645     *obj_length = info.length;
0646     return_ACPI_STATUS(status);
0647 }
0648 
0649 /*******************************************************************************
0650  *
0651  * FUNCTION:    acpi_ut_get_object_size
0652  *
0653  * PARAMETERS:  internal_object     - An ACPI internal object
0654  *              obj_length          - Where the length will be returned
0655  *
0656  * RETURN:      Status
0657  *
0658  * DESCRIPTION: This function is called to determine the space required to
0659  *              contain an object for return to an API user.
0660  *
0661  ******************************************************************************/
0662 
0663 acpi_status
0664 acpi_ut_get_object_size(union acpi_operand_object *internal_object,
0665             acpi_size *obj_length)
0666 {
0667     acpi_status status;
0668 
0669     ACPI_FUNCTION_ENTRY();
0670 
0671     if ((ACPI_GET_DESCRIPTOR_TYPE(internal_object) ==
0672          ACPI_DESC_TYPE_OPERAND) &&
0673         (internal_object->common.type == ACPI_TYPE_PACKAGE)) {
0674         status =
0675             acpi_ut_get_package_object_size(internal_object,
0676                             obj_length);
0677     } else {
0678         status =
0679             acpi_ut_get_simple_object_size(internal_object, obj_length);
0680     }
0681 
0682     return (status);
0683 }