linux/drivers/acpi/acpica/utmisc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2/*******************************************************************************
   3 *
   4 * Module Name: utmisc - common utility procedures
   5 *
   6 ******************************************************************************/
   7
   8#include <acpi/acpi.h>
   9#include "accommon.h"
  10#include "acnamesp.h"
  11
  12#define _COMPONENT          ACPI_UTILITIES
  13ACPI_MODULE_NAME("utmisc")
  14
  15/*******************************************************************************
  16 *
  17 * FUNCTION:    acpi_ut_is_pci_root_bridge
  18 *
  19 * PARAMETERS:  id              - The HID/CID in string format
  20 *
  21 * RETURN:      TRUE if the Id is a match for a PCI/PCI-Express Root Bridge
  22 *
  23 * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID.
  24 *
  25 ******************************************************************************/
  26u8 acpi_ut_is_pci_root_bridge(char *id)
  27{
  28
  29        /*
  30         * Check if this is a PCI root bridge.
  31         * ACPI 3.0+: check for a PCI Express root also.
  32         */
  33        if (!(strcmp(id,
  34                     PCI_ROOT_HID_STRING)) ||
  35            !(strcmp(id, PCI_EXPRESS_ROOT_HID_STRING))) {
  36                return (TRUE);
  37        }
  38
  39        return (FALSE);
  40}
  41
  42#if (defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP || defined ACPI_NAMES_APP)
  43/*******************************************************************************
  44 *
  45 * FUNCTION:    acpi_ut_is_aml_table
  46 *
  47 * PARAMETERS:  table               - An ACPI table
  48 *
  49 * RETURN:      TRUE if table contains executable AML; FALSE otherwise
  50 *
  51 * DESCRIPTION: Check ACPI Signature for a table that contains AML code.
  52 *              Currently, these are DSDT,SSDT,PSDT. All other table types are
  53 *              data tables that do not contain AML code.
  54 *
  55 ******************************************************************************/
  56
  57u8 acpi_ut_is_aml_table(struct acpi_table_header *table)
  58{
  59
  60        /* These are the only tables that contain executable AML */
  61
  62        if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_DSDT) ||
  63            ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_PSDT) ||
  64            ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_SSDT) ||
  65            ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_OSDT) ||
  66            ACPI_IS_OEM_SIG(table->signature)) {
  67                return (TRUE);
  68        }
  69
  70        return (FALSE);
  71}
  72#endif
  73
  74/*******************************************************************************
  75 *
  76 * FUNCTION:    acpi_ut_dword_byte_swap
  77 *
  78 * PARAMETERS:  value           - Value to be converted
  79 *
  80 * RETURN:      u32 integer with bytes swapped
  81 *
  82 * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes)
  83 *
  84 ******************************************************************************/
  85
  86u32 acpi_ut_dword_byte_swap(u32 value)
  87{
  88        union {
  89                u32 value;
  90                u8 bytes[4];
  91        } out;
  92        union {
  93                u32 value;
  94                u8 bytes[4];
  95        } in;
  96
  97        ACPI_FUNCTION_ENTRY();
  98
  99        in.value = value;
 100
 101        out.bytes[0] = in.bytes[3];
 102        out.bytes[1] = in.bytes[2];
 103        out.bytes[2] = in.bytes[1];
 104        out.bytes[3] = in.bytes[0];
 105
 106        return (out.value);
 107}
 108
 109/*******************************************************************************
 110 *
 111 * FUNCTION:    acpi_ut_set_integer_width
 112 *
 113 * PARAMETERS:  Revision            From DSDT header
 114 *
 115 * RETURN:      None
 116 *
 117 * DESCRIPTION: Set the global integer bit width based upon the revision
 118 *              of the DSDT. For Revision 1 and 0, Integers are 32 bits.
 119 *              For Revision 2 and above, Integers are 64 bits. Yes, this
 120 *              makes a difference.
 121 *
 122 ******************************************************************************/
 123
 124void acpi_ut_set_integer_width(u8 revision)
 125{
 126
 127        if (revision < 2) {
 128
 129                /* 32-bit case */
 130
 131                acpi_gbl_integer_bit_width = 32;
 132                acpi_gbl_integer_nybble_width = 8;
 133                acpi_gbl_integer_byte_width = 4;
 134        } else {
 135                /* 64-bit case (ACPI 2.0+) */
 136
 137                acpi_gbl_integer_bit_width = 64;
 138                acpi_gbl_integer_nybble_width = 16;
 139                acpi_gbl_integer_byte_width = 8;
 140        }
 141}
 142
 143/*******************************************************************************
 144 *
 145 * FUNCTION:    acpi_ut_create_update_state_and_push
 146 *
 147 * PARAMETERS:  object          - Object to be added to the new state
 148 *              action          - Increment/Decrement
 149 *              state_list      - List the state will be added to
 150 *
 151 * RETURN:      Status
 152 *
 153 * DESCRIPTION: Create a new state and push it
 154 *
 155 ******************************************************************************/
 156
 157acpi_status
 158acpi_ut_create_update_state_and_push(union acpi_operand_object *object,
 159                                     u16 action,
 160                                     union acpi_generic_state **state_list)
 161{
 162        union acpi_generic_state *state;
 163
 164        ACPI_FUNCTION_ENTRY();
 165
 166        /* Ignore null objects; these are expected */
 167
 168        if (!object) {
 169                return (AE_OK);
 170        }
 171
 172        state = acpi_ut_create_update_state(object, action);
 173        if (!state) {
 174                return (AE_NO_MEMORY);
 175        }
 176
 177        acpi_ut_push_generic_state(state_list, state);
 178        return (AE_OK);
 179}
 180
 181/*******************************************************************************
 182 *
 183 * FUNCTION:    acpi_ut_walk_package_tree
 184 *
 185 * PARAMETERS:  source_object       - The package to walk
 186 *              target_object       - Target object (if package is being copied)
 187 *              walk_callback       - Called once for each package element
 188 *              context             - Passed to the callback function
 189 *
 190 * RETURN:      Status
 191 *
 192 * DESCRIPTION: Walk through a package, including subpackages
 193 *
 194 ******************************************************************************/
 195
 196acpi_status
 197acpi_ut_walk_package_tree(union acpi_operand_object *source_object,
 198                          void *target_object,
 199                          acpi_pkg_callback walk_callback, void *context)
 200{
 201        acpi_status status = AE_OK;
 202        union acpi_generic_state *state_list = NULL;
 203        union acpi_generic_state *state;
 204        union acpi_operand_object *this_source_obj;
 205        u32 this_index;
 206
 207        ACPI_FUNCTION_TRACE(ut_walk_package_tree);
 208
 209        state = acpi_ut_create_pkg_state(source_object, target_object, 0);
 210        if (!state) {
 211                return_ACPI_STATUS(AE_NO_MEMORY);
 212        }
 213
 214        while (state) {
 215
 216                /* Get one element of the package */
 217
 218                this_index = state->pkg.index;
 219                this_source_obj =
 220                    state->pkg.source_object->package.elements[this_index];
 221                state->pkg.this_target_obj =
 222                    &state->pkg.source_object->package.elements[this_index];
 223
 224                /*
 225                 * Check for:
 226                 * 1) An uninitialized package element. It is completely
 227                 *    legal to declare a package and leave it uninitialized
 228                 * 2) Not an internal object - can be a namespace node instead
 229                 * 3) Any type other than a package. Packages are handled in else
 230                 *    case below.
 231                 */
 232                if ((!this_source_obj) ||
 233                    (ACPI_GET_DESCRIPTOR_TYPE(this_source_obj) !=
 234                     ACPI_DESC_TYPE_OPERAND) ||
 235                    (this_source_obj->common.type != ACPI_TYPE_PACKAGE)) {
 236                        status =
 237                            walk_callback(ACPI_COPY_TYPE_SIMPLE,
 238                                          this_source_obj, state, context);
 239                        if (ACPI_FAILURE(status)) {
 240                                return_ACPI_STATUS(status);
 241                        }
 242
 243                        state->pkg.index++;
 244                        while (state->pkg.index >=
 245                               state->pkg.source_object->package.count) {
 246                                /*
 247                                 * We've handled all of the objects at this level,  This means
 248                                 * that we have just completed a package. That package may
 249                                 * have contained one or more packages itself.
 250                                 *
 251                                 * Delete this state and pop the previous state (package).
 252                                 */
 253                                acpi_ut_delete_generic_state(state);
 254                                state = acpi_ut_pop_generic_state(&state_list);
 255
 256                                /* Finished when there are no more states */
 257
 258                                if (!state) {
 259                                        /*
 260                                         * We have handled all of the objects in the top level
 261                                         * package just add the length of the package objects
 262                                         * and exit
 263                                         */
 264                                        return_ACPI_STATUS(AE_OK);
 265                                }
 266
 267                                /*
 268                                 * Go back up a level and move the index past the just
 269                                 * completed package object.
 270                                 */
 271                                state->pkg.index++;
 272                        }
 273                } else {
 274                        /* This is a subobject of type package */
 275
 276                        status =
 277                            walk_callback(ACPI_COPY_TYPE_PACKAGE,
 278                                          this_source_obj, state, context);
 279                        if (ACPI_FAILURE(status)) {
 280                                return_ACPI_STATUS(status);
 281                        }
 282
 283                        /*
 284                         * Push the current state and create a new one
 285                         * The callback above returned a new target package object.
 286                         */
 287                        acpi_ut_push_generic_state(&state_list, state);
 288                        state =
 289                            acpi_ut_create_pkg_state(this_source_obj,
 290                                                     state->pkg.this_target_obj,
 291                                                     0);
 292                        if (!state) {
 293
 294                                /* Free any stacked Update State objects */
 295
 296                                while (state_list) {
 297                                        state =
 298                                            acpi_ut_pop_generic_state
 299                                            (&state_list);
 300                                        acpi_ut_delete_generic_state(state);
 301                                }
 302                                return_ACPI_STATUS(AE_NO_MEMORY);
 303                        }
 304                }
 305        }
 306
 307        /* We should never get here */
 308
 309        ACPI_ERROR((AE_INFO, "State list did not terminate correctly"));
 310
 311        return_ACPI_STATUS(AE_AML_INTERNAL);
 312}
 313
 314#ifdef ACPI_DEBUG_OUTPUT
 315/*******************************************************************************
 316 *
 317 * FUNCTION:    acpi_ut_display_init_pathname
 318 *
 319 * PARAMETERS:  type                - Object type of the node
 320 *              obj_handle          - Handle whose pathname will be displayed
 321 *              path                - Additional path string to be appended.
 322 *                                      (NULL if no extra path)
 323 *
 324 * RETURN:      acpi_status
 325 *
 326 * DESCRIPTION: Display full pathname of an object, DEBUG ONLY
 327 *
 328 ******************************************************************************/
 329
 330void
 331acpi_ut_display_init_pathname(u8 type,
 332                              struct acpi_namespace_node *obj_handle,
 333                              const char *path)
 334{
 335        acpi_status status;
 336        struct acpi_buffer buffer;
 337
 338        ACPI_FUNCTION_ENTRY();
 339
 340        /* Only print the path if the appropriate debug level is enabled */
 341
 342        if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
 343                return;
 344        }
 345
 346        /* Get the full pathname to the node */
 347
 348        buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
 349        status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
 350        if (ACPI_FAILURE(status)) {
 351                return;
 352        }
 353
 354        /* Print what we're doing */
 355
 356        switch (type) {
 357        case ACPI_TYPE_METHOD:
 358
 359                acpi_os_printf("Executing  ");
 360                break;
 361
 362        default:
 363
 364                acpi_os_printf("Initializing ");
 365                break;
 366        }
 367
 368        /* Print the object type and pathname */
 369
 370        acpi_os_printf("%-12s %s",
 371                       acpi_ut_get_type_name(type), (char *)buffer.pointer);
 372
 373        /* Extra path is used to append names like _STA, _INI, etc. */
 374
 375        if (path) {
 376                acpi_os_printf(".%s", path);
 377        }
 378        acpi_os_printf("\n");
 379
 380        ACPI_FREE(buffer.pointer);
 381}
 382#endif
 383