Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
6595 | serge | 1 | /******************************************************************************* |
2 | * |
||
3 | * Module Name: utmisc - common utility procedures |
||
4 | * |
||
5 | ******************************************************************************/ |
||
6 | |||
7 | /* |
||
8 | * Copyright (C) 2000 - 2015, Intel Corp. |
||
9 | * All rights reserved. |
||
10 | * |
||
11 | * Redistribution and use in source and binary forms, with or without |
||
12 | * modification, are permitted provided that the following conditions |
||
13 | * are met: |
||
14 | * 1. Redistributions of source code must retain the above copyright |
||
15 | * notice, this list of conditions, and the following disclaimer, |
||
16 | * without modification. |
||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer |
||
18 | * substantially similar to the "NO WARRANTY" disclaimer below |
||
19 | * ("Disclaimer") and any redistribution must be conditioned upon |
||
20 | * including a substantially similar Disclaimer requirement for further |
||
21 | * binary redistribution. |
||
22 | * 3. Neither the names of the above-listed copyright holders nor the names |
||
23 | * of any contributors may be used to endorse or promote products derived |
||
24 | * from this software without specific prior written permission. |
||
25 | * |
||
26 | * Alternatively, this software may be distributed under the terms of the |
||
27 | * GNU General Public License ("GPL") version 2 as published by the Free |
||
28 | * Software Foundation. |
||
29 | * |
||
30 | * NO WARRANTY |
||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR |
||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
||
41 | * POSSIBILITY OF SUCH DAMAGES. |
||
42 | */ |
||
43 | |||
44 | #include |
||
45 | #include "accommon.h" |
||
46 | #include "acnamesp.h" |
||
47 | |||
48 | #define _COMPONENT ACPI_UTILITIES |
||
49 | ACPI_MODULE_NAME("utmisc") |
||
50 | |||
51 | /******************************************************************************* |
||
52 | * |
||
53 | * FUNCTION: acpi_ut_is_pci_root_bridge |
||
54 | * |
||
55 | * PARAMETERS: id - The HID/CID in string format |
||
56 | * |
||
57 | * RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge |
||
58 | * |
||
59 | * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID. |
||
60 | * |
||
61 | ******************************************************************************/ |
||
62 | u8 acpi_ut_is_pci_root_bridge(char *id) |
||
63 | { |
||
64 | |||
65 | /* |
||
66 | * Check if this is a PCI root bridge. |
||
67 | * ACPI 3.0+: check for a PCI Express root also. |
||
68 | */ |
||
69 | if (!(strcmp(id, |
||
70 | PCI_ROOT_HID_STRING)) || |
||
71 | !(strcmp(id, PCI_EXPRESS_ROOT_HID_STRING))) { |
||
72 | return (TRUE); |
||
73 | } |
||
74 | |||
75 | return (FALSE); |
||
76 | } |
||
77 | |||
78 | #if (defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP || defined ACPI_NAMES_APP) |
||
79 | /******************************************************************************* |
||
80 | * |
||
81 | * FUNCTION: acpi_ut_is_aml_table |
||
82 | * |
||
83 | * PARAMETERS: table - An ACPI table |
||
84 | * |
||
85 | * RETURN: TRUE if table contains executable AML; FALSE otherwise |
||
86 | * |
||
87 | * DESCRIPTION: Check ACPI Signature for a table that contains AML code. |
||
88 | * Currently, these are DSDT,SSDT,PSDT. All other table types are |
||
89 | * data tables that do not contain AML code. |
||
90 | * |
||
91 | ******************************************************************************/ |
||
92 | |||
93 | u8 acpi_ut_is_aml_table(struct acpi_table_header *table) |
||
94 | { |
||
95 | |||
96 | /* These are the only tables that contain executable AML */ |
||
97 | |||
98 | if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT) || |
||
99 | ACPI_COMPARE_NAME(table->signature, ACPI_SIG_PSDT) || |
||
100 | ACPI_COMPARE_NAME(table->signature, ACPI_SIG_SSDT) || |
||
101 | ACPI_COMPARE_NAME(table->signature, ACPI_SIG_OSDT)) { |
||
102 | return (TRUE); |
||
103 | } |
||
104 | |||
105 | return (FALSE); |
||
106 | } |
||
107 | #endif |
||
108 | |||
109 | /******************************************************************************* |
||
110 | * |
||
111 | * FUNCTION: acpi_ut_dword_byte_swap |
||
112 | * |
||
113 | * PARAMETERS: value - Value to be converted |
||
114 | * |
||
115 | * RETURN: u32 integer with bytes swapped |
||
116 | * |
||
117 | * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes) |
||
118 | * |
||
119 | ******************************************************************************/ |
||
120 | |||
121 | u32 acpi_ut_dword_byte_swap(u32 value) |
||
122 | { |
||
123 | union { |
||
124 | u32 value; |
||
125 | u8 bytes[4]; |
||
126 | } out; |
||
127 | union { |
||
128 | u32 value; |
||
129 | u8 bytes[4]; |
||
130 | } in; |
||
131 | |||
132 | ACPI_FUNCTION_ENTRY(); |
||
133 | |||
134 | in.value = value; |
||
135 | |||
136 | out.bytes[0] = in.bytes[3]; |
||
137 | out.bytes[1] = in.bytes[2]; |
||
138 | out.bytes[2] = in.bytes[1]; |
||
139 | out.bytes[3] = in.bytes[0]; |
||
140 | |||
141 | return (out.value); |
||
142 | } |
||
143 | |||
144 | /******************************************************************************* |
||
145 | * |
||
146 | * FUNCTION: acpi_ut_set_integer_width |
||
147 | * |
||
148 | * PARAMETERS: Revision From DSDT header |
||
149 | * |
||
150 | * RETURN: None |
||
151 | * |
||
152 | * DESCRIPTION: Set the global integer bit width based upon the revision |
||
153 | * of the DSDT. For Revision 1 and 0, Integers are 32 bits. |
||
154 | * For Revision 2 and above, Integers are 64 bits. Yes, this |
||
155 | * makes a difference. |
||
156 | * |
||
157 | ******************************************************************************/ |
||
158 | |||
159 | void acpi_ut_set_integer_width(u8 revision) |
||
160 | { |
||
161 | |||
162 | if (revision < 2) { |
||
163 | |||
164 | /* 32-bit case */ |
||
165 | |||
166 | acpi_gbl_integer_bit_width = 32; |
||
167 | acpi_gbl_integer_nybble_width = 8; |
||
168 | acpi_gbl_integer_byte_width = 4; |
||
169 | } else { |
||
170 | /* 64-bit case (ACPI 2.0+) */ |
||
171 | |||
172 | acpi_gbl_integer_bit_width = 64; |
||
173 | acpi_gbl_integer_nybble_width = 16; |
||
174 | acpi_gbl_integer_byte_width = 8; |
||
175 | } |
||
176 | } |
||
177 | |||
178 | /******************************************************************************* |
||
179 | * |
||
180 | * FUNCTION: acpi_ut_create_update_state_and_push |
||
181 | * |
||
182 | * PARAMETERS: object - Object to be added to the new state |
||
183 | * action - Increment/Decrement |
||
184 | * state_list - List the state will be added to |
||
185 | * |
||
186 | * RETURN: Status |
||
187 | * |
||
188 | * DESCRIPTION: Create a new state and push it |
||
189 | * |
||
190 | ******************************************************************************/ |
||
191 | |||
192 | acpi_status |
||
193 | acpi_ut_create_update_state_and_push(union acpi_operand_object *object, |
||
194 | u16 action, |
||
195 | union acpi_generic_state **state_list) |
||
196 | { |
||
197 | union acpi_generic_state *state; |
||
198 | |||
199 | ACPI_FUNCTION_ENTRY(); |
||
200 | |||
201 | /* Ignore null objects; these are expected */ |
||
202 | |||
203 | if (!object) { |
||
204 | return (AE_OK); |
||
205 | } |
||
206 | |||
207 | state = acpi_ut_create_update_state(object, action); |
||
208 | if (!state) { |
||
209 | return (AE_NO_MEMORY); |
||
210 | } |
||
211 | |||
212 | acpi_ut_push_generic_state(state_list, state); |
||
213 | return (AE_OK); |
||
214 | } |
||
215 | |||
216 | /******************************************************************************* |
||
217 | * |
||
218 | * FUNCTION: acpi_ut_walk_package_tree |
||
219 | * |
||
220 | * PARAMETERS: source_object - The package to walk |
||
221 | * target_object - Target object (if package is being copied) |
||
222 | * walk_callback - Called once for each package element |
||
223 | * context - Passed to the callback function |
||
224 | * |
||
225 | * RETURN: Status |
||
226 | * |
||
227 | * DESCRIPTION: Walk through a package |
||
228 | * |
||
229 | ******************************************************************************/ |
||
230 | |||
231 | acpi_status |
||
232 | acpi_ut_walk_package_tree(union acpi_operand_object *source_object, |
||
233 | void *target_object, |
||
234 | acpi_pkg_callback walk_callback, void *context) |
||
235 | { |
||
236 | acpi_status status = AE_OK; |
||
237 | union acpi_generic_state *state_list = NULL; |
||
238 | union acpi_generic_state *state; |
||
239 | u32 this_index; |
||
240 | union acpi_operand_object *this_source_obj; |
||
241 | |||
242 | ACPI_FUNCTION_TRACE(ut_walk_package_tree); |
||
243 | |||
244 | state = acpi_ut_create_pkg_state(source_object, target_object, 0); |
||
245 | if (!state) { |
||
246 | return_ACPI_STATUS(AE_NO_MEMORY); |
||
247 | } |
||
248 | |||
249 | while (state) { |
||
250 | |||
251 | /* Get one element of the package */ |
||
252 | |||
253 | this_index = state->pkg.index; |
||
254 | this_source_obj = (union acpi_operand_object *) |
||
255 | state->pkg.source_object->package.elements[this_index]; |
||
256 | |||
257 | /* |
||
258 | * Check for: |
||
259 | * 1) An uninitialized package element. It is completely |
||
260 | * legal to declare a package and leave it uninitialized |
||
261 | * 2) Not an internal object - can be a namespace node instead |
||
262 | * 3) Any type other than a package. Packages are handled in else |
||
263 | * case below. |
||
264 | */ |
||
265 | if ((!this_source_obj) || |
||
266 | (ACPI_GET_DESCRIPTOR_TYPE(this_source_obj) != |
||
267 | ACPI_DESC_TYPE_OPERAND) |
||
268 | || (this_source_obj->common.type != ACPI_TYPE_PACKAGE)) { |
||
269 | status = |
||
270 | walk_callback(ACPI_COPY_TYPE_SIMPLE, |
||
271 | this_source_obj, state, context); |
||
272 | if (ACPI_FAILURE(status)) { |
||
273 | return_ACPI_STATUS(status); |
||
274 | } |
||
275 | |||
276 | state->pkg.index++; |
||
277 | while (state->pkg.index >= |
||
278 | state->pkg.source_object->package.count) { |
||
279 | /* |
||
280 | * We've handled all of the objects at this level, This means |
||
281 | * that we have just completed a package. That package may |
||
282 | * have contained one or more packages itself. |
||
283 | * |
||
284 | * Delete this state and pop the previous state (package). |
||
285 | */ |
||
286 | acpi_ut_delete_generic_state(state); |
||
287 | state = acpi_ut_pop_generic_state(&state_list); |
||
288 | |||
289 | /* Finished when there are no more states */ |
||
290 | |||
291 | if (!state) { |
||
292 | /* |
||
293 | * We have handled all of the objects in the top level |
||
294 | * package just add the length of the package objects |
||
295 | * and exit |
||
296 | */ |
||
297 | return_ACPI_STATUS(AE_OK); |
||
298 | } |
||
299 | |||
300 | /* |
||
301 | * Go back up a level and move the index past the just |
||
302 | * completed package object. |
||
303 | */ |
||
304 | state->pkg.index++; |
||
305 | } |
||
306 | } else { |
||
307 | /* This is a subobject of type package */ |
||
308 | |||
309 | status = |
||
310 | walk_callback(ACPI_COPY_TYPE_PACKAGE, |
||
311 | this_source_obj, state, context); |
||
312 | if (ACPI_FAILURE(status)) { |
||
313 | return_ACPI_STATUS(status); |
||
314 | } |
||
315 | |||
316 | /* |
||
317 | * Push the current state and create a new one |
||
318 | * The callback above returned a new target package object. |
||
319 | */ |
||
320 | acpi_ut_push_generic_state(&state_list, state); |
||
321 | state = acpi_ut_create_pkg_state(this_source_obj, |
||
322 | state->pkg. |
||
323 | this_target_obj, 0); |
||
324 | if (!state) { |
||
325 | |||
326 | /* Free any stacked Update State objects */ |
||
327 | |||
328 | while (state_list) { |
||
329 | state = |
||
330 | acpi_ut_pop_generic_state |
||
331 | (&state_list); |
||
332 | acpi_ut_delete_generic_state(state); |
||
333 | } |
||
334 | return_ACPI_STATUS(AE_NO_MEMORY); |
||
335 | } |
||
336 | } |
||
337 | } |
||
338 | |||
339 | /* We should never get here */ |
||
340 | |||
341 | return_ACPI_STATUS(AE_AML_INTERNAL); |
||
342 | } |
||
343 | |||
344 | #ifdef ACPI_DEBUG_OUTPUT |
||
345 | /******************************************************************************* |
||
346 | * |
||
347 | * FUNCTION: acpi_ut_display_init_pathname |
||
348 | * |
||
349 | * PARAMETERS: type - Object type of the node |
||
350 | * obj_handle - Handle whose pathname will be displayed |
||
351 | * path - Additional path string to be appended. |
||
352 | * (NULL if no extra path) |
||
353 | * |
||
354 | * RETURN: acpi_status |
||
355 | * |
||
356 | * DESCRIPTION: Display full pathname of an object, DEBUG ONLY |
||
357 | * |
||
358 | ******************************************************************************/ |
||
359 | |||
360 | void |
||
361 | acpi_ut_display_init_pathname(u8 type, |
||
362 | struct acpi_namespace_node *obj_handle, |
||
363 | char *path) |
||
364 | { |
||
365 | acpi_status status; |
||
366 | struct acpi_buffer buffer; |
||
367 | |||
368 | ACPI_FUNCTION_ENTRY(); |
||
369 | |||
370 | /* Only print the path if the appropriate debug level is enabled */ |
||
371 | |||
372 | if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) { |
||
373 | return; |
||
374 | } |
||
375 | |||
376 | /* Get the full pathname to the node */ |
||
377 | |||
378 | buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; |
||
379 | status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE); |
||
380 | if (ACPI_FAILURE(status)) { |
||
381 | return; |
||
382 | } |
||
383 | |||
384 | /* Print what we're doing */ |
||
385 | |||
386 | switch (type) { |
||
387 | case ACPI_TYPE_METHOD: |
||
388 | |||
389 | acpi_os_printf("Executing "); |
||
390 | break; |
||
391 | |||
392 | default: |
||
393 | |||
394 | acpi_os_printf("Initializing "); |
||
395 | break; |
||
396 | } |
||
397 | |||
398 | /* Print the object type and pathname */ |
||
399 | |||
400 | acpi_os_printf("%-12s %s", |
||
401 | acpi_ut_get_type_name(type), (char *)buffer.pointer); |
||
402 | |||
403 | /* Extra path is used to append names like _STA, _INI, etc. */ |
||
404 | |||
405 | if (path) { |
||
406 | acpi_os_printf(".%s", path); |
||
407 | } |
||
408 | acpi_os_printf("\n"); |
||
409 | |||
410 | ACPI_FREE(buffer.pointer); |
||
411 | } |
||
412 | #endif> |