brintos

brintos / linux-shallow public Read only

0
0
Text · 10.0 KiB · 8638efa Raw
383 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/*******************************************************************************3 *4 * Module Name: utmisc - common utility procedures5 *6 ******************************************************************************/7 8#include <acpi/acpi.h>9#include "accommon.h"10#include "acnamesp.h"11 12#define _COMPONENT          ACPI_UTILITIES13ACPI_MODULE_NAME("utmisc")14 15/*******************************************************************************16 *17 * FUNCTION:    acpi_ut_is_pci_root_bridge18 *19 * PARAMETERS:  id              - The HID/CID in string format20 *21 * RETURN:      TRUE if the Id is a match for a PCI/PCI-Express Root Bridge22 *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_table46 *47 * PARAMETERS:  table               - An ACPI table48 *49 * RETURN:      TRUE if table contains executable AML; FALSE otherwise50 *51 * DESCRIPTION: Check ACPI Signature for a table that contains AML code.52 *              Currently, these are DSDT,SSDT,PSDT. All other table types are53 *              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#endif73 74/*******************************************************************************75 *76 * FUNCTION:    acpi_ut_dword_byte_swap77 *78 * PARAMETERS:  value           - Value to be converted79 *80 * RETURN:      u32 integer with bytes swapped81 *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_width112 *113 * PARAMETERS:  Revision            From DSDT header114 *115 * RETURN:      None116 *117 * DESCRIPTION: Set the global integer bit width based upon the revision118 *              of the DSDT. For Revision 1 and 0, Integers are 32 bits.119 *              For Revision 2 and above, Integers are 64 bits. Yes, this120 *              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_push146 *147 * PARAMETERS:  object          - Object to be added to the new state148 *              action          - Increment/Decrement149 *              state_list      - List the state will be added to150 *151 * RETURN:      Status152 *153 * DESCRIPTION: Create a new state and push it154 *155 ******************************************************************************/156 157acpi_status158acpi_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_tree184 *185 * PARAMETERS:  source_object       - The package to walk186 *              target_object       - Target object (if package is being copied)187 *              walk_callback       - Called once for each package element188 *              context             - Passed to the callback function189 *190 * RETURN:      Status191 *192 * DESCRIPTION: Walk through a package, including subpackages193 *194 ******************************************************************************/195 196acpi_status197acpi_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 completely227		 *    legal to declare a package and leave it uninitialized228		 * 2) Not an internal object - can be a namespace node instead229		 * 3) Any type other than a package. Packages are handled in else230		 *    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 means248				 * that we have just completed a package. That package may249				 * 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 level261					 * package just add the length of the package objects262					 * and exit263					 */264					return_ACPI_STATUS(AE_OK);265				}266 267				/*268				 * Go back up a level and move the index past the just269				 * 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 one285			 * 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_state299					    (&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_OUTPUT315/*******************************************************************************316 *317 * FUNCTION:    acpi_ut_display_init_pathname318 *319 * PARAMETERS:  type                - Object type of the node320 *              obj_handle          - Handle whose pathname will be displayed321 *              path                - Additional path string to be appended.322 *                                      (NULL if no extra path)323 *324 * RETURN:      acpi_status325 *326 * DESCRIPTION: Display full pathname of an object, DEBUG ONLY327 *328 ******************************************************************************/329 330void331acpi_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#endif383