Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /*******************************************************************************
0003  *
0004  * Module Name: utmisc - common utility procedures
0005  *
0006  ******************************************************************************/
0007 
0008 #include <acpi/acpi.h>
0009 #include "accommon.h"
0010 #include "acnamesp.h"
0011 
0012 #define _COMPONENT          ACPI_UTILITIES
0013 ACPI_MODULE_NAME("utmisc")
0014 
0015 /*******************************************************************************
0016  *
0017  * FUNCTION:    acpi_ut_is_pci_root_bridge
0018  *
0019  * PARAMETERS:  id              - The HID/CID in string format
0020  *
0021  * RETURN:      TRUE if the Id is a match for a PCI/PCI-Express Root Bridge
0022  *
0023  * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID.
0024  *
0025  ******************************************************************************/
0026 u8 acpi_ut_is_pci_root_bridge(char *id)
0027 {
0028 
0029     /*
0030      * Check if this is a PCI root bridge.
0031      * ACPI 3.0+: check for a PCI Express root also.
0032      */
0033     if (!(strcmp(id,
0034              PCI_ROOT_HID_STRING)) ||
0035         !(strcmp(id, PCI_EXPRESS_ROOT_HID_STRING))) {
0036         return (TRUE);
0037     }
0038 
0039     return (FALSE);
0040 }
0041 
0042 #if (defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP || defined ACPI_NAMES_APP)
0043 /*******************************************************************************
0044  *
0045  * FUNCTION:    acpi_ut_is_aml_table
0046  *
0047  * PARAMETERS:  table               - An ACPI table
0048  *
0049  * RETURN:      TRUE if table contains executable AML; FALSE otherwise
0050  *
0051  * DESCRIPTION: Check ACPI Signature for a table that contains AML code.
0052  *              Currently, these are DSDT,SSDT,PSDT. All other table types are
0053  *              data tables that do not contain AML code.
0054  *
0055  ******************************************************************************/
0056 
0057 u8 acpi_ut_is_aml_table(struct acpi_table_header *table)
0058 {
0059 
0060     /* These are the only tables that contain executable AML */
0061 
0062     if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_DSDT) ||
0063         ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_PSDT) ||
0064         ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_SSDT) ||
0065         ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_OSDT) ||
0066         ACPI_IS_OEM_SIG(table->signature)) {
0067         return (TRUE);
0068     }
0069 
0070     return (FALSE);
0071 }
0072 #endif
0073 
0074 /*******************************************************************************
0075  *
0076  * FUNCTION:    acpi_ut_dword_byte_swap
0077  *
0078  * PARAMETERS:  value           - Value to be converted
0079  *
0080  * RETURN:      u32 integer with bytes swapped
0081  *
0082  * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes)
0083  *
0084  ******************************************************************************/
0085 
0086 u32 acpi_ut_dword_byte_swap(u32 value)
0087 {
0088     union {
0089         u32 value;
0090         u8 bytes[4];
0091     } out;
0092     union {
0093         u32 value;
0094         u8 bytes[4];
0095     } in;
0096 
0097     ACPI_FUNCTION_ENTRY();
0098 
0099     in.value = value;
0100 
0101     out.bytes[0] = in.bytes[3];
0102     out.bytes[1] = in.bytes[2];
0103     out.bytes[2] = in.bytes[1];
0104     out.bytes[3] = in.bytes[0];
0105 
0106     return (out.value);
0107 }
0108 
0109 /*******************************************************************************
0110  *
0111  * FUNCTION:    acpi_ut_set_integer_width
0112  *
0113  * PARAMETERS:  Revision            From DSDT header
0114  *
0115  * RETURN:      None
0116  *
0117  * DESCRIPTION: Set the global integer bit width based upon the revision
0118  *              of the DSDT. For Revision 1 and 0, Integers are 32 bits.
0119  *              For Revision 2 and above, Integers are 64 bits. Yes, this
0120  *              makes a difference.
0121  *
0122  ******************************************************************************/
0123 
0124 void acpi_ut_set_integer_width(u8 revision)
0125 {
0126 
0127     if (revision < 2) {
0128 
0129         /* 32-bit case */
0130 
0131         acpi_gbl_integer_bit_width = 32;
0132         acpi_gbl_integer_nybble_width = 8;
0133         acpi_gbl_integer_byte_width = 4;
0134     } else {
0135         /* 64-bit case (ACPI 2.0+) */
0136 
0137         acpi_gbl_integer_bit_width = 64;
0138         acpi_gbl_integer_nybble_width = 16;
0139         acpi_gbl_integer_byte_width = 8;
0140     }
0141 }
0142 
0143 /*******************************************************************************
0144  *
0145  * FUNCTION:    acpi_ut_create_update_state_and_push
0146  *
0147  * PARAMETERS:  object          - Object to be added to the new state
0148  *              action          - Increment/Decrement
0149  *              state_list      - List the state will be added to
0150  *
0151  * RETURN:      Status
0152  *
0153  * DESCRIPTION: Create a new state and push it
0154  *
0155  ******************************************************************************/
0156 
0157 acpi_status
0158 acpi_ut_create_update_state_and_push(union acpi_operand_object *object,
0159                      u16 action,
0160                      union acpi_generic_state **state_list)
0161 {
0162     union acpi_generic_state *state;
0163 
0164     ACPI_FUNCTION_ENTRY();
0165 
0166     /* Ignore null objects; these are expected */
0167 
0168     if (!object) {
0169         return (AE_OK);
0170     }
0171 
0172     state = acpi_ut_create_update_state(object, action);
0173     if (!state) {
0174         return (AE_NO_MEMORY);
0175     }
0176 
0177     acpi_ut_push_generic_state(state_list, state);
0178     return (AE_OK);
0179 }
0180 
0181 /*******************************************************************************
0182  *
0183  * FUNCTION:    acpi_ut_walk_package_tree
0184  *
0185  * PARAMETERS:  source_object       - The package to walk
0186  *              target_object       - Target object (if package is being copied)
0187  *              walk_callback       - Called once for each package element
0188  *              context             - Passed to the callback function
0189  *
0190  * RETURN:      Status
0191  *
0192  * DESCRIPTION: Walk through a package, including subpackages
0193  *
0194  ******************************************************************************/
0195 
0196 acpi_status
0197 acpi_ut_walk_package_tree(union acpi_operand_object *source_object,
0198               void *target_object,
0199               acpi_pkg_callback walk_callback, void *context)
0200 {
0201     acpi_status status = AE_OK;
0202     union acpi_generic_state *state_list = NULL;
0203     union acpi_generic_state *state;
0204     union acpi_operand_object *this_source_obj;
0205     u32 this_index;
0206 
0207     ACPI_FUNCTION_TRACE(ut_walk_package_tree);
0208 
0209     state = acpi_ut_create_pkg_state(source_object, target_object, 0);
0210     if (!state) {
0211         return_ACPI_STATUS(AE_NO_MEMORY);
0212     }
0213 
0214     while (state) {
0215 
0216         /* Get one element of the package */
0217 
0218         this_index = state->pkg.index;
0219         this_source_obj =
0220             state->pkg.source_object->package.elements[this_index];
0221         state->pkg.this_target_obj =
0222             &state->pkg.source_object->package.elements[this_index];
0223 
0224         /*
0225          * Check for:
0226          * 1) An uninitialized package element. It is completely
0227          *    legal to declare a package and leave it uninitialized
0228          * 2) Not an internal object - can be a namespace node instead
0229          * 3) Any type other than a package. Packages are handled in else
0230          *    case below.
0231          */
0232         if ((!this_source_obj) ||
0233             (ACPI_GET_DESCRIPTOR_TYPE(this_source_obj) !=
0234              ACPI_DESC_TYPE_OPERAND) ||
0235             (this_source_obj->common.type != ACPI_TYPE_PACKAGE)) {
0236             status =
0237                 walk_callback(ACPI_COPY_TYPE_SIMPLE,
0238                       this_source_obj, state, context);
0239             if (ACPI_FAILURE(status)) {
0240                 return_ACPI_STATUS(status);
0241             }
0242 
0243             state->pkg.index++;
0244             while (state->pkg.index >=
0245                    state->pkg.source_object->package.count) {
0246                 /*
0247                  * We've handled all of the objects at this level,  This means
0248                  * that we have just completed a package. That package may
0249                  * have contained one or more packages itself.
0250                  *
0251                  * Delete this state and pop the previous state (package).
0252                  */
0253                 acpi_ut_delete_generic_state(state);
0254                 state = acpi_ut_pop_generic_state(&state_list);
0255 
0256                 /* Finished when there are no more states */
0257 
0258                 if (!state) {
0259                     /*
0260                      * We have handled all of the objects in the top level
0261                      * package just add the length of the package objects
0262                      * and exit
0263                      */
0264                     return_ACPI_STATUS(AE_OK);
0265                 }
0266 
0267                 /*
0268                  * Go back up a level and move the index past the just
0269                  * completed package object.
0270                  */
0271                 state->pkg.index++;
0272             }
0273         } else {
0274             /* This is a subobject of type package */
0275 
0276             status =
0277                 walk_callback(ACPI_COPY_TYPE_PACKAGE,
0278                       this_source_obj, state, context);
0279             if (ACPI_FAILURE(status)) {
0280                 return_ACPI_STATUS(status);
0281             }
0282 
0283             /*
0284              * Push the current state and create a new one
0285              * The callback above returned a new target package object.
0286              */
0287             acpi_ut_push_generic_state(&state_list, state);
0288             state =
0289                 acpi_ut_create_pkg_state(this_source_obj,
0290                              state->pkg.this_target_obj,
0291                              0);
0292             if (!state) {
0293 
0294                 /* Free any stacked Update State objects */
0295 
0296                 while (state_list) {
0297                     state =
0298                         acpi_ut_pop_generic_state
0299                         (&state_list);
0300                     acpi_ut_delete_generic_state(state);
0301                 }
0302                 return_ACPI_STATUS(AE_NO_MEMORY);
0303             }
0304         }
0305     }
0306 
0307     /* We should never get here */
0308 
0309     ACPI_ERROR((AE_INFO, "State list did not terminate correctly"));
0310 
0311     return_ACPI_STATUS(AE_AML_INTERNAL);
0312 }
0313 
0314 #ifdef ACPI_DEBUG_OUTPUT
0315 /*******************************************************************************
0316  *
0317  * FUNCTION:    acpi_ut_display_init_pathname
0318  *
0319  * PARAMETERS:  type                - Object type of the node
0320  *              obj_handle          - Handle whose pathname will be displayed
0321  *              path                - Additional path string to be appended.
0322  *                                      (NULL if no extra path)
0323  *
0324  * RETURN:      acpi_status
0325  *
0326  * DESCRIPTION: Display full pathname of an object, DEBUG ONLY
0327  *
0328  ******************************************************************************/
0329 
0330 void
0331 acpi_ut_display_init_pathname(u8 type,
0332                   struct acpi_namespace_node *obj_handle,
0333                   const char *path)
0334 {
0335     acpi_status status;
0336     struct acpi_buffer buffer;
0337 
0338     ACPI_FUNCTION_ENTRY();
0339 
0340     /* Only print the path if the appropriate debug level is enabled */
0341 
0342     if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
0343         return;
0344     }
0345 
0346     /* Get the full pathname to the node */
0347 
0348     buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
0349     status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
0350     if (ACPI_FAILURE(status)) {
0351         return;
0352     }
0353 
0354     /* Print what we're doing */
0355 
0356     switch (type) {
0357     case ACPI_TYPE_METHOD:
0358 
0359         acpi_os_printf("Executing  ");
0360         break;
0361 
0362     default:
0363 
0364         acpi_os_printf("Initializing ");
0365         break;
0366     }
0367 
0368     /* Print the object type and pathname */
0369 
0370     acpi_os_printf("%-12s %s",
0371                acpi_ut_get_type_name(type), (char *)buffer.pointer);
0372 
0373     /* Extra path is used to append names like _STA, _INI, etc. */
0374 
0375     if (path) {
0376         acpi_os_printf(".%s", path);
0377     }
0378     acpi_os_printf("\n");
0379 
0380     ACPI_FREE(buffer.pointer);
0381 }
0382 #endif