Branch data Line data Source code
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
13 : : ACPI_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 : : ******************************************************************************/
26 : 1230 : u8 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 [ + + ]: 1230 : if (!(strcmp(id,
34 : 1140 : PCI_ROOT_HID_STRING)) ||
35 [ - + ]: 1140 : !(strcmp(id, PCI_EXPRESS_ROOT_HID_STRING))) {
36 : 90 : 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 : :
57 : : u8 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 : :
86 : 2430 : u32 acpi_ut_dword_byte_swap(u32 value)
87 : : {
88 : 2430 : union {
89 : : u32 value;
90 : : u8 bytes[4];
91 : : } out;
92 : 2430 : union {
93 : : u32 value;
94 : : u8 bytes[4];
95 : : } in;
96 : :
97 : 2430 : ACPI_FUNCTION_ENTRY();
98 : :
99 : 2430 : in.value = value;
100 : :
101 : 2430 : out.bytes[0] = in.bytes[3];
102 : 2430 : out.bytes[1] = in.bytes[2];
103 : 2430 : out.bytes[2] = in.bytes[1];
104 : 2430 : out.bytes[3] = in.bytes[0];
105 : :
106 : 2430 : 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 : :
124 : 30 : void acpi_ut_set_integer_width(u8 revision)
125 : : {
126 : :
127 [ + - ]: 30 : if (revision < 2) {
128 : :
129 : : /* 32-bit case */
130 : :
131 : 30 : acpi_gbl_integer_bit_width = 32;
132 : 30 : acpi_gbl_integer_nybble_width = 8;
133 : 30 : acpi_gbl_integer_byte_width = 4;
134 : : } else {
135 : : /* 64-bit case (ACPI 2.0+) */
136 : :
137 : 0 : acpi_gbl_integer_bit_width = 64;
138 : 0 : acpi_gbl_integer_nybble_width = 16;
139 : 0 : acpi_gbl_integer_byte_width = 8;
140 : : }
141 : 30 : }
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 : :
157 : : acpi_status
158 : 5501952 : acpi_ut_create_update_state_and_push(union acpi_operand_object *object,
159 : : u16 action,
160 : : union acpi_generic_state **state_list)
161 : : {
162 : 5501952 : union acpi_generic_state *state;
163 : :
164 : 5501952 : ACPI_FUNCTION_ENTRY();
165 : :
166 : : /* Ignore null objects; these are expected */
167 : :
168 [ + - ]: 5501952 : if (!object) {
169 : : return (AE_OK);
170 : : }
171 : :
172 : 5501952 : state = acpi_ut_create_update_state(object, action);
173 [ + - ]: 5501952 : if (!state) {
174 : : return (AE_NO_MEMORY);
175 : : }
176 : :
177 : 5501952 : acpi_ut_push_generic_state(state_list, state);
178 : 5501952 : 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 : :
196 : : acpi_status
197 : 13998 : acpi_ut_walk_package_tree(union acpi_operand_object *source_object,
198 : : void *target_object,
199 : : acpi_pkg_callback walk_callback, void *context)
200 : : {
201 : 13998 : acpi_status status = AE_OK;
202 : 13998 : union acpi_generic_state *state_list = NULL;
203 : 13998 : union acpi_generic_state *state;
204 : 13998 : union acpi_operand_object *this_source_obj;
205 : 13998 : u32 this_index;
206 : :
207 : 13998 : ACPI_FUNCTION_TRACE(ut_walk_package_tree);
208 : :
209 : 13998 : state = acpi_ut_create_pkg_state(source_object, target_object, 0);
210 [ + - ]: 13998 : if (!state) {
211 : : return_ACPI_STATUS(AE_NO_MEMORY);
212 : : }
213 : :
214 [ + - ]: 63048 : while (state) {
215 : :
216 : : /* Get one element of the package */
217 : :
218 : 63048 : this_index = state->pkg.index;
219 : 63048 : this_source_obj =
220 : 63048 : state->pkg.source_object->package.elements[this_index];
221 : 63048 : 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 [ + + ]: 63048 : if ((!this_source_obj) ||
233 [ + - ]: 56136 : (ACPI_GET_DESCRIPTOR_TYPE(this_source_obj) !=
234 : 56136 : ACPI_DESC_TYPE_OPERAND) ||
235 [ + - ]: 56136 : (this_source_obj->common.type != ACPI_TYPE_PACKAGE)) {
236 : 63048 : status =
237 : 63048 : walk_callback(ACPI_COPY_TYPE_SIMPLE,
238 : : this_source_obj, state, context);
239 [ - + ]: 63048 : if (ACPI_FAILURE(status)) {
240 : 0 : return_ACPI_STATUS(status);
241 : : }
242 : :
243 : 63048 : state->pkg.index++;
244 : 63048 : while (state->pkg.index >=
245 [ + + ]: 63048 : 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 : 13998 : acpi_ut_delete_generic_state(state);
254 : 13998 : state = acpi_ut_pop_generic_state(&state_list);
255 : :
256 : : /* Finished when there are no more states */
257 : :
258 [ - + ]: 13998 : 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 : 0 : state->pkg.index++;
272 : : }
273 : : } else {
274 : : /* This is a subobject of type package */
275 : :
276 : 0 : status =
277 : 0 : walk_callback(ACPI_COPY_TYPE_PACKAGE,
278 : : this_source_obj, state, context);
279 [ # # ]: 0 : if (ACPI_FAILURE(status)) {
280 : 0 : 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 : 0 : acpi_ut_push_generic_state(&state_list, state);
288 : 0 : state =
289 : 0 : acpi_ut_create_pkg_state(this_source_obj,
290 : : state->pkg.this_target_obj,
291 : : 0);
292 [ # # ]: 0 : if (!state) {
293 : :
294 : : /* Free any stacked Update State objects */
295 : :
296 [ # # ]: 0 : while (state_list) {
297 : 0 : state =
298 : 0 : acpi_ut_pop_generic_state
299 : : (&state_list);
300 : 0 : 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 : 0 : ACPI_ERROR((AE_INFO, "State list did not terminate correctly"));
310 : :
311 : 0 : 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 : :
330 : : void
331 : : acpi_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
|