]>
Commit | Line | Data |
---|---|---|
95857638 | 1 | // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 |
1da177e4 LT |
2 | /****************************************************************************** |
3 | * | |
4 | * Module Name: nsdump - table dumping routines for debug | |
5 | * | |
800ba7c5 | 6 | * Copyright (C) 2000 - 2020, Intel Corp. |
1da177e4 | 7 | * |
95857638 | 8 | *****************************************************************************/ |
1da177e4 | 9 | |
1da177e4 | 10 | #include <acpi/acpi.h> |
e2f7a777 LB |
11 | #include "accommon.h" |
12 | #include "acnamesp.h" | |
e81a52b8 | 13 | #include <acpi/acoutput.h> |
1da177e4 | 14 | |
1da177e4 | 15 | #define _COMPONENT ACPI_NAMESPACE |
4be44fcd | 16 | ACPI_MODULE_NAME("nsdump") |
1da177e4 | 17 | |
44f6c012 | 18 | /* Local prototypes */ |
44f6c012 | 19 | #ifdef ACPI_OBSOLETE_FUNCTIONS |
4be44fcd | 20 | void acpi_ns_dump_root_devices(void); |
1da177e4 | 21 | |
44f6c012 | 22 | static acpi_status |
4be44fcd LB |
23 | acpi_ns_dump_one_device(acpi_handle obj_handle, |
24 | u32 level, void *context, void **return_value); | |
44f6c012 RM |
25 | #endif |
26 | ||
44f6c012 | 27 | #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) |
424deb38 | 28 | |
424deb38 BM |
29 | static acpi_status |
30 | acpi_ns_dump_one_object_path(acpi_handle obj_handle, | |
31 | u32 level, void *context, void **return_value); | |
32 | ||
33 | static acpi_status | |
34 | acpi_ns_get_max_depth(acpi_handle obj_handle, | |
35 | u32 level, void *context, void **return_value); | |
424deb38 | 36 | |
1da177e4 LT |
37 | /******************************************************************************* |
38 | * | |
39 | * FUNCTION: acpi_ns_print_pathname | |
40 | * | |
44f6c012 | 41 | * PARAMETERS: num_segments - Number of ACPI name segments |
ba494bee | 42 | * pathname - The compressed (internal) path |
1da177e4 | 43 | * |
44f6c012 RM |
44 | * RETURN: None |
45 | * | |
1da177e4 LT |
46 | * DESCRIPTION: Print an object's full namespace pathname |
47 | * | |
48 | ******************************************************************************/ | |
49 | ||
0dfaaa3d | 50 | void acpi_ns_print_pathname(u32 num_segments, const char *pathname) |
1da177e4 | 51 | { |
67a119f9 | 52 | u32 i; |
0c9938cc | 53 | |
b229cf92 | 54 | ACPI_FUNCTION_NAME(ns_print_pathname); |
0c9938cc | 55 | |
10e9e759 BM |
56 | /* Check if debug output enabled */ |
57 | ||
58 | if (!ACPI_IS_DEBUG_ENABLED(ACPI_LV_NAMES, ACPI_NAMESPACE)) { | |
1da177e4 LT |
59 | return; |
60 | } | |
61 | ||
62 | /* Print the entire name */ | |
63 | ||
4be44fcd | 64 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "[")); |
1da177e4 LT |
65 | |
66 | while (num_segments) { | |
0c9938cc | 67 | for (i = 0; i < 4; i++) { |
4fa4616e | 68 | isprint((int)pathname[i]) ? |
4be44fcd LB |
69 | acpi_os_printf("%c", pathname[i]) : |
70 | acpi_os_printf("?"); | |
0c9938cc | 71 | } |
1da177e4 | 72 | |
32786755 | 73 | pathname += ACPI_NAMESEG_SIZE; |
1da177e4 LT |
74 | num_segments--; |
75 | if (num_segments) { | |
4be44fcd | 76 | acpi_os_printf("."); |
1da177e4 LT |
77 | } |
78 | } | |
79 | ||
4be44fcd | 80 | acpi_os_printf("]\n"); |
1da177e4 LT |
81 | } |
82 | ||
0dfaaa3d BM |
83 | #ifdef ACPI_OBSOLETE_FUNCTIONS |
84 | /* Not used at this time, perhaps later */ | |
85 | ||
1da177e4 LT |
86 | /******************************************************************************* |
87 | * | |
88 | * FUNCTION: acpi_ns_dump_pathname | |
89 | * | |
ba494bee BM |
90 | * PARAMETERS: handle - Object |
91 | * msg - Prefix message | |
92 | * level - Desired debug level | |
93 | * component - Caller's component ID | |
1da177e4 | 94 | * |
44f6c012 RM |
95 | * RETURN: None |
96 | * | |
1da177e4 LT |
97 | * DESCRIPTION: Print an object's full namespace pathname |
98 | * Manages allocation/freeing of a pathname buffer | |
99 | * | |
100 | ******************************************************************************/ | |
101 | ||
102 | void | |
0dfaaa3d BM |
103 | acpi_ns_dump_pathname(acpi_handle handle, |
104 | const char *msg, u32 level, u32 component) | |
1da177e4 LT |
105 | { |
106 | ||
b229cf92 | 107 | ACPI_FUNCTION_TRACE(ns_dump_pathname); |
1da177e4 LT |
108 | |
109 | /* Do this only if the requested debug level and component are enabled */ | |
110 | ||
10e9e759 | 111 | if (!ACPI_IS_DEBUG_ENABLED(level, component)) { |
1da177e4 LT |
112 | return_VOID; |
113 | } | |
114 | ||
115 | /* Convert handle to a full pathname and print it (with supplied message) */ | |
116 | ||
4be44fcd LB |
117 | acpi_ns_print_node_pathname(handle, msg); |
118 | acpi_os_printf("\n"); | |
1da177e4 LT |
119 | return_VOID; |
120 | } | |
0dfaaa3d | 121 | #endif |
1da177e4 | 122 | |
1da177e4 LT |
123 | /******************************************************************************* |
124 | * | |
125 | * FUNCTION: acpi_ns_dump_one_object | |
126 | * | |
44f6c012 | 127 | * PARAMETERS: obj_handle - Node to be dumped |
ba494bee BM |
128 | * level - Nesting level of the handle |
129 | * context - Passed into walk_namespace | |
44f6c012 RM |
130 | * return_value - Not used |
131 | * | |
132 | * RETURN: Status | |
1da177e4 LT |
133 | * |
134 | * DESCRIPTION: Dump a single Node | |
135 | * This procedure is a user_function called by acpi_ns_walk_namespace. | |
136 | * | |
137 | ******************************************************************************/ | |
138 | ||
139 | acpi_status | |
4be44fcd LB |
140 | acpi_ns_dump_one_object(acpi_handle obj_handle, |
141 | u32 level, void *context, void **return_value) | |
1da177e4 | 142 | { |
4be44fcd LB |
143 | struct acpi_walk_info *info = (struct acpi_walk_info *)context; |
144 | struct acpi_namespace_node *this_node; | |
145 | union acpi_operand_object *obj_desc = NULL; | |
146 | acpi_object_type obj_type; | |
147 | acpi_object_type type; | |
148 | u32 bytes_to_dump; | |
149 | u32 dbg_level; | |
150 | u32 i; | |
1da177e4 | 151 | |
b229cf92 | 152 | ACPI_FUNCTION_NAME(ns_dump_one_object); |
1da177e4 LT |
153 | |
154 | /* Is output enabled? */ | |
155 | ||
156 | if (!(acpi_dbg_level & info->debug_level)) { | |
157 | return (AE_OK); | |
158 | } | |
159 | ||
160 | if (!obj_handle) { | |
4be44fcd | 161 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Null object handle\n")); |
1da177e4 LT |
162 | return (AE_OK); |
163 | } | |
164 | ||
f24b664d | 165 | this_node = acpi_ns_validate_handle(obj_handle); |
4bbfb85d BM |
166 | if (!this_node) { |
167 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid object handle %p\n", | |
168 | obj_handle)); | |
169 | return (AE_OK); | |
170 | } | |
171 | ||
1da177e4 | 172 | type = this_node->type; |
1387cdd8 | 173 | info->count++; |
1da177e4 LT |
174 | |
175 | /* Check if the owner matches */ | |
176 | ||
f9f4601f | 177 | if ((info->owner_id != ACPI_OWNER_ID_MAX) && |
4be44fcd | 178 | (info->owner_id != this_node->owner_id)) { |
1da177e4 LT |
179 | return (AE_OK); |
180 | } | |
181 | ||
73459f73 | 182 | if (!(info->display_type & ACPI_DISPLAY_SHORT)) { |
52fc0b02 | 183 | |
73459f73 | 184 | /* Indent the object according to the level */ |
1da177e4 | 185 | |
4be44fcd | 186 | acpi_os_printf("%2d%*s", (u32) level - 1, (int)level * 2, " "); |
1da177e4 | 187 | |
73459f73 | 188 | /* Check the node type and name */ |
1da177e4 | 189 | |
73459f73 | 190 | if (type > ACPI_TYPE_LOCAL_MAX) { |
f6a22b0b BM |
191 | ACPI_WARNING((AE_INFO, |
192 | "Invalid ACPI Object Type 0x%08X", type)); | |
73459f73 RM |
193 | } |
194 | ||
4be44fcd | 195 | acpi_os_printf("%4.4s", acpi_ut_get_node_name(this_node)); |
1da177e4 LT |
196 | } |
197 | ||
d4913dc6 BM |
198 | /* Now we can print out the pertinent information */ |
199 | ||
67a72420 | 200 | acpi_os_printf(" %-12s %p %3.3X ", |
28f55ebc BM |
201 | acpi_ut_get_type_name(type), this_node, |
202 | this_node->owner_id); | |
1da177e4 LT |
203 | |
204 | dbg_level = acpi_dbg_level; | |
205 | acpi_dbg_level = 0; | |
4be44fcd | 206 | obj_desc = acpi_ns_get_attached_object(this_node); |
1da177e4 LT |
207 | acpi_dbg_level = dbg_level; |
208 | ||
d1fdda83 BM |
209 | /* Temp nodes are those nodes created by a control method */ |
210 | ||
211 | if (this_node->flags & ANOBJ_TEMPORARY) { | |
212 | acpi_os_printf("(T) "); | |
213 | } | |
214 | ||
73459f73 | 215 | switch (info->display_type & ACPI_DISPLAY_MASK) { |
1da177e4 LT |
216 | case ACPI_DISPLAY_SUMMARY: |
217 | ||
218 | if (!obj_desc) { | |
52fc0b02 | 219 | |
4acb6884 BM |
220 | /* No attached object. Some types should always have an object */ |
221 | ||
222 | switch (type) { | |
223 | case ACPI_TYPE_INTEGER: | |
224 | case ACPI_TYPE_PACKAGE: | |
225 | case ACPI_TYPE_BUFFER: | |
226 | case ACPI_TYPE_STRING: | |
227 | case ACPI_TYPE_METHOD: | |
1d1ea1b7 | 228 | |
4acb6884 BM |
229 | acpi_os_printf("<No attached object>"); |
230 | break; | |
231 | ||
232 | default: | |
1d1ea1b7 | 233 | |
4acb6884 BM |
234 | break; |
235 | } | |
1da177e4 | 236 | |
4be44fcd | 237 | acpi_os_printf("\n"); |
1da177e4 LT |
238 | return (AE_OK); |
239 | } | |
240 | ||
241 | switch (type) { | |
242 | case ACPI_TYPE_PROCESSOR: | |
243 | ||
cc2080b0 | 244 | acpi_os_printf("ID %02X Len %02X Addr %8.8X%8.8X\n", |
4be44fcd LB |
245 | obj_desc->processor.proc_id, |
246 | obj_desc->processor.length, | |
cc2080b0 LZ |
247 | ACPI_FORMAT_UINT64(obj_desc->processor. |
248 | address)); | |
1da177e4 LT |
249 | break; |
250 | ||
1da177e4 LT |
251 | case ACPI_TYPE_DEVICE: |
252 | ||
4be44fcd | 253 | acpi_os_printf("Notify Object: %p\n", obj_desc); |
1da177e4 LT |
254 | break; |
255 | ||
1da177e4 LT |
256 | case ACPI_TYPE_METHOD: |
257 | ||
4be44fcd LB |
258 | acpi_os_printf("Args %X Len %.4X Aml %p\n", |
259 | (u32) obj_desc->method.param_count, | |
260 | obj_desc->method.aml_length, | |
261 | obj_desc->method.aml_start); | |
1da177e4 LT |
262 | break; |
263 | ||
1da177e4 LT |
264 | case ACPI_TYPE_INTEGER: |
265 | ||
4be44fcd LB |
266 | acpi_os_printf("= %8.8X%8.8X\n", |
267 | ACPI_FORMAT_UINT64(obj_desc->integer. | |
268 | value)); | |
1da177e4 LT |
269 | break; |
270 | ||
1da177e4 LT |
271 | case ACPI_TYPE_PACKAGE: |
272 | ||
273 | if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { | |
4be44fcd LB |
274 | acpi_os_printf("Elements %.2X\n", |
275 | obj_desc->package.count); | |
276 | } else { | |
277 | acpi_os_printf("[Length not yet evaluated]\n"); | |
1da177e4 LT |
278 | } |
279 | break; | |
280 | ||
1da177e4 LT |
281 | case ACPI_TYPE_BUFFER: |
282 | ||
283 | if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { | |
4be44fcd LB |
284 | acpi_os_printf("Len %.2X", |
285 | obj_desc->buffer.length); | |
1da177e4 LT |
286 | |
287 | /* Dump some of the buffer */ | |
288 | ||
289 | if (obj_desc->buffer.length > 0) { | |
4be44fcd LB |
290 | acpi_os_printf(" ="); |
291 | for (i = 0; | |
292 | (i < obj_desc->buffer.length | |
293 | && i < 12); i++) { | |
edc5935e | 294 | acpi_os_printf(" %2.2X", |
4be44fcd LB |
295 | obj_desc->buffer. |
296 | pointer[i]); | |
1da177e4 LT |
297 | } |
298 | } | |
4be44fcd LB |
299 | acpi_os_printf("\n"); |
300 | } else { | |
301 | acpi_os_printf("[Length not yet evaluated]\n"); | |
1da177e4 LT |
302 | } |
303 | break; | |
304 | ||
1da177e4 LT |
305 | case ACPI_TYPE_STRING: |
306 | ||
4be44fcd | 307 | acpi_os_printf("Len %.2X ", obj_desc->string.length); |
60d836fc | 308 | acpi_ut_print_string(obj_desc->string.pointer, 80); |
4be44fcd | 309 | acpi_os_printf("\n"); |
1da177e4 LT |
310 | break; |
311 | ||
1da177e4 LT |
312 | case ACPI_TYPE_REGION: |
313 | ||
4be44fcd LB |
314 | acpi_os_printf("[%s]", |
315 | acpi_ut_get_region_name(obj_desc->region. | |
316 | space_id)); | |
1da177e4 | 317 | if (obj_desc->region.flags & AOPOBJ_DATA_VALID) { |
4be44fcd | 318 | acpi_os_printf(" Addr %8.8X%8.8X Len %.4X\n", |
1d0a0b2f LZ |
319 | ACPI_FORMAT_UINT64(obj_desc-> |
320 | region. | |
321 | address), | |
4be44fcd LB |
322 | obj_desc->region.length); |
323 | } else { | |
324 | acpi_os_printf | |
325 | (" [Address/Length not yet evaluated]\n"); | |
1da177e4 LT |
326 | } |
327 | break; | |
328 | ||
1da177e4 LT |
329 | case ACPI_TYPE_LOCAL_REFERENCE: |
330 | ||
4be44fcd | 331 | acpi_os_printf("[%s]\n", |
1044f1f6 | 332 | acpi_ut_get_reference_name(obj_desc)); |
1da177e4 LT |
333 | break; |
334 | ||
1da177e4 LT |
335 | case ACPI_TYPE_BUFFER_FIELD: |
336 | ||
337 | if (obj_desc->buffer_field.buffer_obj && | |
4be44fcd LB |
338 | obj_desc->buffer_field.buffer_obj->buffer.node) { |
339 | acpi_os_printf("Buf [%4.4s]", | |
340 | acpi_ut_get_node_name(obj_desc-> | |
341 | buffer_field. | |
342 | buffer_obj-> | |
343 | buffer. | |
344 | node)); | |
1da177e4 LT |
345 | } |
346 | break; | |
347 | ||
1da177e4 LT |
348 | case ACPI_TYPE_LOCAL_REGION_FIELD: |
349 | ||
4be44fcd LB |
350 | acpi_os_printf("Rgn [%4.4s]", |
351 | acpi_ut_get_node_name(obj_desc-> | |
352 | common_field. | |
353 | region_obj->region. | |
354 | node)); | |
1da177e4 LT |
355 | break; |
356 | ||
1da177e4 LT |
357 | case ACPI_TYPE_LOCAL_BANK_FIELD: |
358 | ||
4be44fcd LB |
359 | acpi_os_printf("Rgn [%4.4s] Bnk [%4.4s]", |
360 | acpi_ut_get_node_name(obj_desc-> | |
361 | common_field. | |
362 | region_obj->region. | |
363 | node), | |
364 | acpi_ut_get_node_name(obj_desc-> | |
365 | bank_field. | |
366 | bank_obj-> | |
367 | common_field. | |
368 | node)); | |
1da177e4 LT |
369 | break; |
370 | ||
1da177e4 LT |
371 | case ACPI_TYPE_LOCAL_INDEX_FIELD: |
372 | ||
4be44fcd LB |
373 | acpi_os_printf("Idx [%4.4s] Dat [%4.4s]", |
374 | acpi_ut_get_node_name(obj_desc-> | |
375 | index_field. | |
376 | index_obj-> | |
377 | common_field.node), | |
378 | acpi_ut_get_node_name(obj_desc-> | |
379 | index_field. | |
380 | data_obj-> | |
381 | common_field. | |
382 | node)); | |
1da177e4 LT |
383 | break; |
384 | ||
1da177e4 LT |
385 | case ACPI_TYPE_LOCAL_ALIAS: |
386 | case ACPI_TYPE_LOCAL_METHOD_ALIAS: | |
387 | ||
4be44fcd LB |
388 | acpi_os_printf("Target %4.4s (%p)\n", |
389 | acpi_ut_get_node_name(obj_desc), | |
390 | obj_desc); | |
1da177e4 LT |
391 | break; |
392 | ||
393 | default: | |
394 | ||
4be44fcd | 395 | acpi_os_printf("Object %p\n", obj_desc); |
1da177e4 LT |
396 | break; |
397 | } | |
398 | ||
399 | /* Common field handling */ | |
400 | ||
401 | switch (type) { | |
402 | case ACPI_TYPE_BUFFER_FIELD: | |
403 | case ACPI_TYPE_LOCAL_REGION_FIELD: | |
404 | case ACPI_TYPE_LOCAL_BANK_FIELD: | |
405 | case ACPI_TYPE_LOCAL_INDEX_FIELD: | |
406 | ||
edc5935e | 407 | acpi_os_printf(" Off %.3X Len %.2X Acc %.2X\n", |
4be44fcd LB |
408 | (obj_desc->common_field. |
409 | base_byte_offset * 8) | |
410 | + | |
411 | obj_desc->common_field. | |
412 | start_field_bit_offset, | |
413 | obj_desc->common_field.bit_length, | |
414 | obj_desc->common_field. | |
415 | access_byte_width); | |
1da177e4 LT |
416 | break; |
417 | ||
418 | default: | |
1d1ea1b7 | 419 | |
1da177e4 LT |
420 | break; |
421 | } | |
422 | break; | |
423 | ||
1da177e4 LT |
424 | case ACPI_DISPLAY_OBJECTS: |
425 | ||
4be44fcd | 426 | acpi_os_printf("O:%p", obj_desc); |
1da177e4 | 427 | if (!obj_desc) { |
52fc0b02 | 428 | |
1da177e4 LT |
429 | /* No attached object, we are done */ |
430 | ||
4be44fcd | 431 | acpi_os_printf("\n"); |
1da177e4 LT |
432 | return (AE_OK); |
433 | } | |
434 | ||
b27d6597 | 435 | acpi_os_printf("(R%u)", obj_desc->common.reference_count); |
1da177e4 LT |
436 | |
437 | switch (type) { | |
438 | case ACPI_TYPE_METHOD: | |
439 | ||
440 | /* Name is a Method and its AML offset/length are set */ | |
441 | ||
4be44fcd LB |
442 | acpi_os_printf(" M:%p-%X\n", obj_desc->method.aml_start, |
443 | obj_desc->method.aml_length); | |
1da177e4 LT |
444 | break; |
445 | ||
446 | case ACPI_TYPE_INTEGER: | |
447 | ||
4be44fcd LB |
448 | acpi_os_printf(" I:%8.8X8.8%X\n", |
449 | ACPI_FORMAT_UINT64(obj_desc->integer. | |
450 | value)); | |
1da177e4 LT |
451 | break; |
452 | ||
453 | case ACPI_TYPE_STRING: | |
454 | ||
4be44fcd LB |
455 | acpi_os_printf(" S:%p-%X\n", obj_desc->string.pointer, |
456 | obj_desc->string.length); | |
1da177e4 LT |
457 | break; |
458 | ||
459 | case ACPI_TYPE_BUFFER: | |
460 | ||
4be44fcd LB |
461 | acpi_os_printf(" B:%p-%X\n", obj_desc->buffer.pointer, |
462 | obj_desc->buffer.length); | |
1da177e4 LT |
463 | break; |
464 | ||
465 | default: | |
466 | ||
4be44fcd | 467 | acpi_os_printf("\n"); |
1da177e4 LT |
468 | break; |
469 | } | |
470 | break; | |
471 | ||
1da177e4 | 472 | default: |
4be44fcd | 473 | acpi_os_printf("\n"); |
1da177e4 LT |
474 | break; |
475 | } | |
476 | ||
477 | /* If debug turned off, done */ | |
478 | ||
479 | if (!(acpi_dbg_level & ACPI_LV_VALUES)) { | |
480 | return (AE_OK); | |
481 | } | |
482 | ||
1da177e4 LT |
483 | /* If there is an attached object, display it */ |
484 | ||
4be44fcd | 485 | dbg_level = acpi_dbg_level; |
1da177e4 | 486 | acpi_dbg_level = 0; |
4be44fcd | 487 | obj_desc = acpi_ns_get_attached_object(this_node); |
1da177e4 LT |
488 | acpi_dbg_level = dbg_level; |
489 | ||
490 | /* Dump attached objects */ | |
491 | ||
492 | while (obj_desc) { | |
493 | obj_type = ACPI_TYPE_INVALID; | |
4be44fcd | 494 | acpi_os_printf("Attached Object %p: ", obj_desc); |
1da177e4 LT |
495 | |
496 | /* Decode the type of attached object and dump the contents */ | |
497 | ||
4be44fcd | 498 | switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) { |
1da177e4 LT |
499 | case ACPI_DESC_TYPE_NAMED: |
500 | ||
4be44fcd LB |
501 | acpi_os_printf("(Ptr to Node)\n"); |
502 | bytes_to_dump = sizeof(struct acpi_namespace_node); | |
503 | ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump); | |
1da177e4 LT |
504 | break; |
505 | ||
1da177e4 LT |
506 | case ACPI_DESC_TYPE_OPERAND: |
507 | ||
3371c19c | 508 | obj_type = obj_desc->common.type; |
1da177e4 LT |
509 | |
510 | if (obj_type > ACPI_TYPE_LOCAL_MAX) { | |
4be44fcd | 511 | acpi_os_printf |
71d993e1 | 512 | ("(Pointer to ACPI Object type %.2X [UNKNOWN])\n", |
4be44fcd | 513 | obj_type); |
1fad8738 | 514 | |
1da177e4 | 515 | bytes_to_dump = 32; |
4be44fcd LB |
516 | } else { |
517 | acpi_os_printf | |
71d993e1 | 518 | ("(Pointer to ACPI Object type %.2X [%s])\n", |
4be44fcd | 519 | obj_type, acpi_ut_get_type_name(obj_type)); |
1fad8738 | 520 | |
4be44fcd LB |
521 | bytes_to_dump = |
522 | sizeof(union acpi_operand_object); | |
1da177e4 | 523 | } |
1da177e4 | 524 | |
4be44fcd | 525 | ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump); |
6f42ccf2 | 526 | break; |
1da177e4 LT |
527 | |
528 | default: | |
529 | ||
1da177e4 LT |
530 | break; |
531 | } | |
532 | ||
1da177e4 LT |
533 | /* If value is NOT an internal object, we are done */ |
534 | ||
4be44fcd LB |
535 | if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != |
536 | ACPI_DESC_TYPE_OPERAND) { | |
1da177e4 LT |
537 | goto cleanup; |
538 | } | |
539 | ||
d4913dc6 BM |
540 | /* Valid object, get the pointer to next level, if any */ |
541 | ||
1da177e4 | 542 | switch (obj_type) { |
6f42ccf2 | 543 | case ACPI_TYPE_BUFFER: |
1da177e4 | 544 | case ACPI_TYPE_STRING: |
6f42ccf2 RM |
545 | /* |
546 | * NOTE: takes advantage of common fields between string/buffer | |
547 | */ | |
548 | bytes_to_dump = obj_desc->string.length; | |
4be44fcd | 549 | obj_desc = (void *)obj_desc->string.pointer; |
1fad8738 | 550 | |
4be44fcd LB |
551 | acpi_os_printf("(Buffer/String pointer %p length %X)\n", |
552 | obj_desc, bytes_to_dump); | |
553 | ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump); | |
6f42ccf2 | 554 | goto cleanup; |
1da177e4 LT |
555 | |
556 | case ACPI_TYPE_BUFFER_FIELD: | |
1d1ea1b7 | 557 | |
4be44fcd LB |
558 | obj_desc = |
559 | (union acpi_operand_object *)obj_desc->buffer_field. | |
560 | buffer_obj; | |
1da177e4 LT |
561 | break; |
562 | ||
563 | case ACPI_TYPE_PACKAGE: | |
1d1ea1b7 | 564 | |
4be44fcd | 565 | obj_desc = (void *)obj_desc->package.elements; |
1da177e4 LT |
566 | break; |
567 | ||
568 | case ACPI_TYPE_METHOD: | |
1d1ea1b7 | 569 | |
4be44fcd | 570 | obj_desc = (void *)obj_desc->method.aml_start; |
1da177e4 LT |
571 | break; |
572 | ||
573 | case ACPI_TYPE_LOCAL_REGION_FIELD: | |
1d1ea1b7 | 574 | |
4be44fcd | 575 | obj_desc = (void *)obj_desc->field.region_obj; |
1da177e4 LT |
576 | break; |
577 | ||
578 | case ACPI_TYPE_LOCAL_BANK_FIELD: | |
1d1ea1b7 | 579 | |
4be44fcd | 580 | obj_desc = (void *)obj_desc->bank_field.region_obj; |
1da177e4 LT |
581 | break; |
582 | ||
583 | case ACPI_TYPE_LOCAL_INDEX_FIELD: | |
1d1ea1b7 | 584 | |
4be44fcd | 585 | obj_desc = (void *)obj_desc->index_field.index_obj; |
1da177e4 LT |
586 | break; |
587 | ||
588 | default: | |
1d1ea1b7 | 589 | |
1da177e4 LT |
590 | goto cleanup; |
591 | } | |
1da177e4 LT |
592 | } |
593 | ||
10622bf8 | 594 | cleanup: |
4be44fcd | 595 | acpi_os_printf("\n"); |
1da177e4 LT |
596 | return (AE_OK); |
597 | } | |
598 | ||
1da177e4 LT |
599 | /******************************************************************************* |
600 | * | |
601 | * FUNCTION: acpi_ns_dump_objects | |
602 | * | |
ba494bee | 603 | * PARAMETERS: type - Object type to be dumped |
44f6c012 | 604 | * display_type - 0 or ACPI_DISPLAY_SUMMARY |
1da177e4 LT |
605 | * max_depth - Maximum depth of dump. Use ACPI_UINT32_MAX |
606 | * for an effectively unlimited depth. | |
d4913dc6 | 607 | * owner_id - Dump only objects owned by this ID. Use |
1da177e4 LT |
608 | * ACPI_UINT32_MAX to match all owners. |
609 | * start_handle - Where in namespace to start/end search | |
610 | * | |
44f6c012 RM |
611 | * RETURN: None |
612 | * | |
d4913dc6 BM |
613 | * DESCRIPTION: Dump typed objects within the loaded namespace. Uses |
614 | * acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object. | |
1da177e4 LT |
615 | * |
616 | ******************************************************************************/ | |
617 | ||
618 | void | |
4be44fcd LB |
619 | acpi_ns_dump_objects(acpi_object_type type, |
620 | u8 display_type, | |
621 | u32 max_depth, | |
622 | acpi_owner_id owner_id, acpi_handle start_handle) | |
1da177e4 | 623 | { |
4be44fcd | 624 | struct acpi_walk_info info; |
672af843 | 625 | acpi_status status; |
1da177e4 | 626 | |
4be44fcd | 627 | ACPI_FUNCTION_ENTRY(); |
1da177e4 | 628 | |
672af843 BM |
629 | /* |
630 | * Just lock the entire namespace for the duration of the dump. | |
631 | * We don't want any changes to the namespace during this time, | |
632 | * especially the temporary nodes since we are going to display | |
633 | * them also. | |
634 | */ | |
635 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | |
636 | if (ACPI_FAILURE(status)) { | |
637 | acpi_os_printf("Could not acquire namespace mutex\n"); | |
638 | return; | |
639 | } | |
640 | ||
1387cdd8 | 641 | info.count = 0; |
1da177e4 LT |
642 | info.debug_level = ACPI_LV_TABLES; |
643 | info.owner_id = owner_id; | |
644 | info.display_type = display_type; | |
645 | ||
4be44fcd | 646 | (void)acpi_ns_walk_namespace(type, start_handle, max_depth, |
d1fdda83 BM |
647 | ACPI_NS_WALK_NO_UNLOCK | |
648 | ACPI_NS_WALK_TEMP_NODES, | |
2263576c LM |
649 | acpi_ns_dump_one_object, NULL, |
650 | (void *)&info, NULL); | |
672af843 | 651 | |
1387cdd8 | 652 | acpi_os_printf("\nNamespace node count: %u\n\n", info.count); |
672af843 | 653 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
1da177e4 | 654 | } |
1da177e4 | 655 | |
424deb38 BM |
656 | /******************************************************************************* |
657 | * | |
658 | * FUNCTION: acpi_ns_dump_one_object_path, acpi_ns_get_max_depth | |
659 | * | |
660 | * PARAMETERS: obj_handle - Node to be dumped | |
661 | * level - Nesting level of the handle | |
662 | * context - Passed into walk_namespace | |
663 | * return_value - Not used | |
664 | * | |
665 | * RETURN: Status | |
666 | * | |
667 | * DESCRIPTION: Dump the full pathname to a namespace object. acp_ns_get_max_depth | |
668 | * computes the maximum nesting depth in the namespace tree, in | |
669 | * order to simplify formatting in acpi_ns_dump_one_object_path. | |
670 | * These procedures are user_functions called by acpi_ns_walk_namespace. | |
671 | * | |
672 | ******************************************************************************/ | |
673 | ||
674 | static acpi_status | |
675 | acpi_ns_dump_one_object_path(acpi_handle obj_handle, | |
676 | u32 level, void *context, void **return_value) | |
677 | { | |
678 | u32 max_level = *((u32 *)context); | |
679 | char *pathname; | |
680 | struct acpi_namespace_node *node; | |
681 | int path_indent; | |
682 | ||
683 | if (!obj_handle) { | |
684 | return (AE_OK); | |
685 | } | |
686 | ||
687 | node = acpi_ns_validate_handle(obj_handle); | |
48961ce6 BM |
688 | if (!node) { |
689 | ||
690 | /* Ignore bad node during namespace walk */ | |
691 | ||
692 | return (AE_OK); | |
693 | } | |
694 | ||
0e166e4f | 695 | pathname = acpi_ns_get_normalized_pathname(node, TRUE); |
424deb38 BM |
696 | |
697 | path_indent = 1; | |
698 | if (level <= max_level) { | |
699 | path_indent = max_level - level + 1; | |
700 | } | |
701 | ||
702 | acpi_os_printf("%2d%*s%-12s%*s", | |
703 | level, level, " ", acpi_ut_get_type_name(node->type), | |
704 | path_indent, " "); | |
705 | ||
706 | acpi_os_printf("%s\n", &pathname[1]); | |
707 | ACPI_FREE(pathname); | |
708 | return (AE_OK); | |
709 | } | |
710 | ||
711 | static acpi_status | |
712 | acpi_ns_get_max_depth(acpi_handle obj_handle, | |
713 | u32 level, void *context, void **return_value) | |
714 | { | |
715 | u32 *max_level = (u32 *)context; | |
716 | ||
717 | if (level > *max_level) { | |
718 | *max_level = level; | |
719 | } | |
720 | return (AE_OK); | |
721 | } | |
722 | ||
723 | /******************************************************************************* | |
724 | * | |
725 | * FUNCTION: acpi_ns_dump_object_paths | |
726 | * | |
727 | * PARAMETERS: type - Object type to be dumped | |
728 | * display_type - 0 or ACPI_DISPLAY_SUMMARY | |
729 | * max_depth - Maximum depth of dump. Use ACPI_UINT32_MAX | |
730 | * for an effectively unlimited depth. | |
731 | * owner_id - Dump only objects owned by this ID. Use | |
732 | * ACPI_UINT32_MAX to match all owners. | |
733 | * start_handle - Where in namespace to start/end search | |
734 | * | |
735 | * RETURN: None | |
736 | * | |
737 | * DESCRIPTION: Dump full object pathnames within the loaded namespace. Uses | |
738 | * acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object_path. | |
739 | * | |
740 | ******************************************************************************/ | |
741 | ||
742 | void | |
743 | acpi_ns_dump_object_paths(acpi_object_type type, | |
744 | u8 display_type, | |
745 | u32 max_depth, | |
746 | acpi_owner_id owner_id, acpi_handle start_handle) | |
747 | { | |
748 | acpi_status status; | |
749 | u32 max_level = 0; | |
750 | ||
751 | ACPI_FUNCTION_ENTRY(); | |
752 | ||
753 | /* | |
754 | * Just lock the entire namespace for the duration of the dump. | |
755 | * We don't want any changes to the namespace during this time, | |
756 | * especially the temporary nodes since we are going to display | |
757 | * them also. | |
758 | */ | |
759 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | |
760 | if (ACPI_FAILURE(status)) { | |
761 | acpi_os_printf("Could not acquire namespace mutex\n"); | |
762 | return; | |
763 | } | |
764 | ||
765 | /* Get the max depth of the namespace tree, for formatting later */ | |
766 | ||
767 | (void)acpi_ns_walk_namespace(type, start_handle, max_depth, | |
768 | ACPI_NS_WALK_NO_UNLOCK | | |
769 | ACPI_NS_WALK_TEMP_NODES, | |
770 | acpi_ns_get_max_depth, NULL, | |
771 | (void *)&max_level, NULL); | |
772 | ||
773 | /* Now dump the entire namespace */ | |
774 | ||
775 | (void)acpi_ns_walk_namespace(type, start_handle, max_depth, | |
776 | ACPI_NS_WALK_NO_UNLOCK | | |
777 | ACPI_NS_WALK_TEMP_NODES, | |
778 | acpi_ns_dump_one_object_path, NULL, | |
779 | (void *)&max_level, NULL); | |
780 | ||
781 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | |
782 | } | |
424deb38 | 783 | |
44f6c012 RM |
784 | /******************************************************************************* |
785 | * | |
786 | * FUNCTION: acpi_ns_dump_entry | |
787 | * | |
ba494bee | 788 | * PARAMETERS: handle - Node to be dumped |
44f6c012 RM |
789 | * debug_level - Output level |
790 | * | |
791 | * RETURN: None | |
792 | * | |
793 | * DESCRIPTION: Dump a single Node | |
794 | * | |
795 | ******************************************************************************/ | |
796 | ||
4be44fcd | 797 | void acpi_ns_dump_entry(acpi_handle handle, u32 debug_level) |
44f6c012 | 798 | { |
4be44fcd | 799 | struct acpi_walk_info info; |
44f6c012 | 800 | |
4be44fcd | 801 | ACPI_FUNCTION_ENTRY(); |
44f6c012 RM |
802 | |
803 | info.debug_level = debug_level; | |
f9f4601f | 804 | info.owner_id = ACPI_OWNER_ID_MAX; |
44f6c012 RM |
805 | info.display_type = ACPI_DISPLAY_SUMMARY; |
806 | ||
4be44fcd | 807 | (void)acpi_ns_dump_one_object(handle, 1, &info, NULL); |
44f6c012 RM |
808 | } |
809 | ||
73459f73 | 810 | #ifdef ACPI_ASL_COMPILER |
1da177e4 LT |
811 | /******************************************************************************* |
812 | * | |
813 | * FUNCTION: acpi_ns_dump_tables | |
814 | * | |
815 | * PARAMETERS: search_base - Root of subtree to be dumped, or | |
816 | * NS_ALL to dump the entire namespace | |
73a3090a | 817 | * max_depth - Maximum depth of dump. Use INT_MAX |
1da177e4 LT |
818 | * for an effectively unlimited depth. |
819 | * | |
44f6c012 RM |
820 | * RETURN: None |
821 | * | |
1da177e4 LT |
822 | * DESCRIPTION: Dump the name space, or a portion of it. |
823 | * | |
824 | ******************************************************************************/ | |
825 | ||
4be44fcd | 826 | void acpi_ns_dump_tables(acpi_handle search_base, u32 max_depth) |
1da177e4 | 827 | { |
4be44fcd | 828 | acpi_handle search_handle = search_base; |
1da177e4 | 829 | |
b229cf92 | 830 | ACPI_FUNCTION_TRACE(ns_dump_tables); |
1da177e4 LT |
831 | |
832 | if (!acpi_gbl_root_node) { | |
833 | /* | |
834 | * If the name space has not been initialized, | |
835 | * there is nothing to dump. | |
836 | */ | |
4be44fcd LB |
837 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, |
838 | "namespace not initialized!\n")); | |
1da177e4 LT |
839 | return_VOID; |
840 | } | |
841 | ||
842 | if (ACPI_NS_ALL == search_base) { | |
52fc0b02 | 843 | |
44f6c012 | 844 | /* Entire namespace */ |
1da177e4 LT |
845 | |
846 | search_handle = acpi_gbl_root_node; | |
4be44fcd | 847 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, "\\\n")); |
1da177e4 LT |
848 | } |
849 | ||
4be44fcd LB |
850 | acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_OBJECTS, max_depth, |
851 | ACPI_OWNER_ID_MAX, search_handle); | |
1da177e4 LT |
852 | return_VOID; |
853 | } | |
75c8044f LZ |
854 | #endif |
855 | #endif |