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