1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2/******************************************************************************
3 *
4 * Module Name: exdump - Interpreter debug output routines
5 *
6 * Copyright (C) 2000 - 2023, Intel Corp.
7 *
8 *****************************************************************************/
9
10#include <acpi/acpi.h>
11#include "accommon.h"
12#include "acinterp.h"
13#include "amlcode.h"
14#include "acnamesp.h"
15
16#define _COMPONENT          ACPI_EXECUTER
17ACPI_MODULE_NAME("exdump")
18
19/*
20 * The following routines are used for debug output only
21 */
22#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
23/* Local prototypes */
24static void acpi_ex_out_string(const char *title, const char *value);
25
26static void acpi_ex_out_pointer(const char *title, const void *value);
27
28static void
29acpi_ex_dump_object(union acpi_operand_object *obj_desc,
30		    struct acpi_exdump_info *info);
31
32static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc);
33
34static void
35acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc,
36			 u32 level, u32 index);
37
38/*******************************************************************************
39 *
40 * Object Descriptor info tables
41 *
42 * Note: The first table entry must be an INIT opcode and must contain
43 * the table length (number of table entries)
44 *
45 ******************************************************************************/
46
47static struct acpi_exdump_info acpi_ex_dump_integer[2] = {
48	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_integer), NULL},
49	{ACPI_EXD_UINT64, ACPI_EXD_OFFSET(integer.value), "Value"}
50};
51
52static struct acpi_exdump_info acpi_ex_dump_string[4] = {
53	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_string), NULL},
54	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(string.length), "Length"},
55	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(string.pointer), "Pointer"},
56	{ACPI_EXD_STRING, 0, NULL}
57};
58
59static struct acpi_exdump_info acpi_ex_dump_buffer[5] = {
60	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_buffer), NULL},
61	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(buffer.length), "Length"},
62	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(buffer.pointer), "Pointer"},
63	{ACPI_EXD_NODE, ACPI_EXD_OFFSET(buffer.node), "Parent Node"},
64	{ACPI_EXD_BUFFER, 0, NULL}
65};
66
67static struct acpi_exdump_info acpi_ex_dump_package[6] = {
68	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_package), NULL},
69	{ACPI_EXD_NODE, ACPI_EXD_OFFSET(package.node), "Parent Node"},
70	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(package.flags), "Flags"},
71	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(package.count), "Element Count"},
72	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(package.elements), "Element List"},
73	{ACPI_EXD_PACKAGE, 0, NULL}
74};
75
76static struct acpi_exdump_info acpi_ex_dump_device[4] = {
77	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_device), NULL},
78	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(device.notify_list[0]),
79	 "System Notify"},
80	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(device.notify_list[1]),
81	 "Device Notify"},
82	{ACPI_EXD_HDLR_LIST, ACPI_EXD_OFFSET(device.handler), "Handler"}
83};
84
85static struct acpi_exdump_info acpi_ex_dump_event[2] = {
86	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_event), NULL},
87	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(event.os_semaphore), "OsSemaphore"}
88};
89
90static struct acpi_exdump_info acpi_ex_dump_method[9] = {
91	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_method), NULL},
92	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.info_flags), "Info Flags"},
93	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.param_count),
94	 "Parameter Count"},
95	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.sync_level), "Sync Level"},
96	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.mutex), "Mutex"},
97	{ACPI_EXD_UINT16, ACPI_EXD_OFFSET(method.owner_id), "Owner Id"},
98	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.thread_count), "Thread Count"},
99	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(method.aml_length), "Aml Length"},
100	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.aml_start), "Aml Start"}
101};
102
103static struct acpi_exdump_info acpi_ex_dump_mutex[6] = {
104	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_mutex), NULL},
105	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.sync_level), "Sync Level"},
106	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.original_sync_level),
107	 "Original Sync Level"},
108	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread), "Owner Thread"},
109	{ACPI_EXD_UINT16, ACPI_EXD_OFFSET(mutex.acquisition_depth),
110	 "Acquire Depth"},
111	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.os_mutex), "OsMutex"}
112};
113
114static struct acpi_exdump_info acpi_ex_dump_region[8] = {
115	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_region), NULL},
116	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(region.space_id), "Space Id"},
117	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(region.flags), "Flags"},
118	{ACPI_EXD_NODE, ACPI_EXD_OFFSET(region.node), "Parent Node"},
119	{ACPI_EXD_ADDRESS, ACPI_EXD_OFFSET(region.address), "Address"},
120	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(region.length), "Length"},
121	{ACPI_EXD_HDLR_LIST, ACPI_EXD_OFFSET(region.handler), "Handler"},
122	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(region.next), "Next"}
123};
124
125static struct acpi_exdump_info acpi_ex_dump_power[6] = {
126	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_power), NULL},
127	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(power_resource.system_level),
128	 "System Level"},
129	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(power_resource.resource_order),
130	 "Resource Order"},
131	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(power_resource.notify_list[0]),
132	 "System Notify"},
133	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(power_resource.notify_list[1]),
134	 "Device Notify"},
135	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(power_resource.handler), "Handler"}
136};
137
138static struct acpi_exdump_info acpi_ex_dump_processor[7] = {
139	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_processor), NULL},
140	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(processor.proc_id), "Processor ID"},
141	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(processor.length), "Length"},
142	{ACPI_EXD_ADDRESS, ACPI_EXD_OFFSET(processor.address), "Address"},
143	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.notify_list[0]),
144	 "System Notify"},
145	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.notify_list[1]),
146	 "Device Notify"},
147	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(processor.handler), "Handler"}
148};
149
150static struct acpi_exdump_info acpi_ex_dump_thermal[4] = {
151	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_thermal), NULL},
152	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(thermal_zone.notify_list[0]),
153	 "System Notify"},
154	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(thermal_zone.notify_list[1]),
155	 "Device Notify"},
156	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(thermal_zone.handler), "Handler"}
157};
158
159static struct acpi_exdump_info acpi_ex_dump_buffer_field[3] = {
160	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_buffer_field), NULL},
161	{ACPI_EXD_FIELD, 0, NULL},
162	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(buffer_field.buffer_obj),
163	 "Buffer Object"}
164};
165
166static struct acpi_exdump_info acpi_ex_dump_region_field[5] = {
167	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_region_field), NULL},
168	{ACPI_EXD_FIELD, 0, NULL},
169	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(field.access_length), "AccessLength"},
170	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(field.region_obj), "Region Object"},
171	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(field.resource_buffer),
172	 "ResourceBuffer"}
173};
174
175static struct acpi_exdump_info acpi_ex_dump_bank_field[5] = {
176	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_bank_field), NULL},
177	{ACPI_EXD_FIELD, 0, NULL},
178	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(bank_field.value), "Value"},
179	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(bank_field.region_obj),
180	 "Region Object"},
181	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(bank_field.bank_obj), "Bank Object"}
182};
183
184static struct acpi_exdump_info acpi_ex_dump_index_field[5] = {
185	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_bank_field), NULL},
186	{ACPI_EXD_FIELD, 0, NULL},
187	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(index_field.value), "Value"},
188	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(index_field.index_obj),
189	 "Index Object"},
190	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(index_field.data_obj), "Data Object"}
191};
192
193static struct acpi_exdump_info acpi_ex_dump_reference[9] = {
194	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_reference), NULL},
195	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(reference.class), "Class"},
196	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(reference.target_type), "Target Type"},
197	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(reference.value), "Value"},
198	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.object), "Object Desc"},
199	{ACPI_EXD_NODE, ACPI_EXD_OFFSET(reference.node), "Node"},
200	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.where), "Where"},
201	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.index_pointer),
202	 "Index Pointer"},
203	{ACPI_EXD_REFERENCE, 0, NULL}
204};
205
206static struct acpi_exdump_info acpi_ex_dump_address_handler[6] = {
207	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_address_handler),
208	 NULL},
209	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(address_space.space_id), "Space Id"},
210	{ACPI_EXD_HDLR_LIST, ACPI_EXD_OFFSET(address_space.next), "Next"},
211	{ACPI_EXD_RGN_LIST, ACPI_EXD_OFFSET(address_space.region_list),
212	 "Region List"},
213	{ACPI_EXD_NODE, ACPI_EXD_OFFSET(address_space.node), "Node"},
214	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(address_space.context), "Context"}
215};
216
217static struct acpi_exdump_info acpi_ex_dump_notify[7] = {
218	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_notify), NULL},
219	{ACPI_EXD_NODE, ACPI_EXD_OFFSET(notify.node), "Node"},
220	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(notify.handler_type), "Handler Type"},
221	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(notify.handler), "Handler"},
222	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(notify.context), "Context"},
223	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(notify.next[0]),
224	 "Next System Notify"},
225	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(notify.next[1]), "Next Device Notify"}
226};
227
228static struct acpi_exdump_info acpi_ex_dump_extra[6] = {
229	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_extra), NULL},
230	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(extra.method_REG), "_REG Method"},
231	{ACPI_EXD_NODE, ACPI_EXD_OFFSET(extra.scope_node), "Scope Node"},
232	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(extra.region_context),
233	 "Region Context"},
234	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(extra.aml_start), "Aml Start"},
235	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(extra.aml_length), "Aml Length"}
236};
237
238static struct acpi_exdump_info acpi_ex_dump_data[3] = {
239	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_data), NULL},
240	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(data.handler), "Handler"},
241	{ACPI_EXD_POINTER, ACPI_EXD_OFFSET(data.pointer), "Raw Data"}
242};
243
244/* Miscellaneous tables */
245
246static struct acpi_exdump_info acpi_ex_dump_common[5] = {
247	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_common), NULL},
248	{ACPI_EXD_TYPE, 0, NULL},
249	{ACPI_EXD_UINT16, ACPI_EXD_OFFSET(common.reference_count),
250	 "Reference Count"},
251	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(common.flags), "Flags"},
252	{ACPI_EXD_LIST, ACPI_EXD_OFFSET(common.next_object), "Object List"}
253};
254
255static struct acpi_exdump_info acpi_ex_dump_field_common[7] = {
256	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_field_common), NULL},
257	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(common_field.field_flags),
258	 "Field Flags"},
259	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(common_field.access_byte_width),
260	 "Access Byte Width"},
261	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(common_field.bit_length),
262	 "Bit Length"},
263	{ACPI_EXD_UINT8, ACPI_EXD_OFFSET(common_field.start_field_bit_offset),
264	 "Field Bit Offset"},
265	{ACPI_EXD_UINT32, ACPI_EXD_OFFSET(common_field.base_byte_offset),
266	 "Base Byte Offset"},
267	{ACPI_EXD_NODE, ACPI_EXD_OFFSET(common_field.node), "Parent Node"}
268};
269
270static struct acpi_exdump_info acpi_ex_dump_node[7] = {
271	{ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_node), NULL},
272	{ACPI_EXD_UINT16, ACPI_EXD_NSOFFSET(flags), "Flags"},
273	{ACPI_EXD_UINT16, ACPI_EXD_NSOFFSET(owner_id), "Owner Id"},
274	{ACPI_EXD_LIST, ACPI_EXD_NSOFFSET(object), "Object List"},
275	{ACPI_EXD_NODE, ACPI_EXD_NSOFFSET(parent), "Parent"},
276	{ACPI_EXD_NODE, ACPI_EXD_NSOFFSET(child), "Child"},
277	{ACPI_EXD_NODE, ACPI_EXD_NSOFFSET(peer), "Peer"}
278};
279
280/* Dispatch table, indexed by object type */
281
282static struct acpi_exdump_info *acpi_ex_dump_info[] = {
283	NULL,
284	acpi_ex_dump_integer,
285	acpi_ex_dump_string,
286	acpi_ex_dump_buffer,
287	acpi_ex_dump_package,
288	NULL,
289	acpi_ex_dump_device,
290	acpi_ex_dump_event,
291	acpi_ex_dump_method,
292	acpi_ex_dump_mutex,
293	acpi_ex_dump_region,
294	acpi_ex_dump_power,
295	acpi_ex_dump_processor,
296	acpi_ex_dump_thermal,
297	acpi_ex_dump_buffer_field,
298	NULL,
299	NULL,
300	acpi_ex_dump_region_field,
301	acpi_ex_dump_bank_field,
302	acpi_ex_dump_index_field,
303	acpi_ex_dump_reference,
304	NULL,
305	NULL,
306	acpi_ex_dump_notify,
307	acpi_ex_dump_address_handler,
308	NULL,
309	NULL,
310	NULL,
311	acpi_ex_dump_extra,
312	acpi_ex_dump_data
313};
314
315/*******************************************************************************
316 *
317 * FUNCTION:    acpi_ex_dump_object
318 *
319 * PARAMETERS:  obj_desc            - Descriptor to dump
320 *              info                - Info table corresponding to this object
321 *                                    type
322 *
323 * RETURN:      None
324 *
325 * DESCRIPTION: Walk the info table for this object
326 *
327 ******************************************************************************/
328
329static void
330acpi_ex_dump_object(union acpi_operand_object *obj_desc,
331		    struct acpi_exdump_info *info)
332{
333	u8 *target;
334	const char *name;
335	u8 count;
336	union acpi_operand_object *start;
337	union acpi_operand_object *data = NULL;
338	union acpi_operand_object *next;
339	struct acpi_namespace_node *node;
340
341	if (!info) {
342		acpi_os_printf
343		    ("ExDumpObject: Display not implemented for object type %s\n",
344		     acpi_ut_get_object_type_name(obj_desc));
345		return;
346	}
347
348	/* First table entry must contain the table length (# of table entries) */
349
350	count = info->offset;
351
352	while (count) {
353		if (!obj_desc) {
354			return;
355		}
356
357		target = ACPI_ADD_PTR(u8, obj_desc, info->offset);
358		name = info->name;
359
360		switch (info->opcode) {
361		case ACPI_EXD_INIT:
362
363			break;
364
365		case ACPI_EXD_TYPE:
366
367			acpi_os_printf("%20s : %2.2X [%s]\n", "Type",
368				       obj_desc->common.type,
369				       acpi_ut_get_object_type_name(obj_desc));
370			break;
371
372		case ACPI_EXD_UINT8:
373
374			acpi_os_printf("%20s : %2.2X\n", name, *target);
375			break;
376
377		case ACPI_EXD_UINT16:
378
379			acpi_os_printf("%20s : %4.4X\n", name,
380				       ACPI_GET16(target));
381			break;
382
383		case ACPI_EXD_UINT32:
384
385			acpi_os_printf("%20s : %8.8X\n", name,
386				       ACPI_GET32(target));
387			break;
388
389		case ACPI_EXD_UINT64:
390
391			acpi_os_printf("%20s : %8.8X%8.8X\n", "Value",
392				       ACPI_FORMAT_UINT64(ACPI_GET64(target)));
393			break;
394
395		case ACPI_EXD_POINTER:
396		case ACPI_EXD_ADDRESS:
397
398			acpi_ex_out_pointer(name,
399					    *ACPI_CAST_PTR(void *, target));
400			break;
401
402		case ACPI_EXD_STRING:
403
404			acpi_ut_print_string(obj_desc->string.pointer,
405					     ACPI_UINT8_MAX);
406			acpi_os_printf("\n");
407			break;
408
409		case ACPI_EXD_BUFFER:
410
411			ACPI_DUMP_BUFFER(obj_desc->buffer.pointer,
412					 obj_desc->buffer.length);
413			break;
414
415		case ACPI_EXD_PACKAGE:
416
417			/* Dump the package contents */
418
419			acpi_os_printf("\nPackage Contents:\n");
420			acpi_ex_dump_package_obj(obj_desc, 0, 0);
421			break;
422
423		case ACPI_EXD_FIELD:
424
425			acpi_ex_dump_object(obj_desc,
426					    acpi_ex_dump_field_common);
427			break;
428
429		case ACPI_EXD_REFERENCE:
430
431			acpi_ex_out_string("Class Name",
432					   acpi_ut_get_reference_name
433					   (obj_desc));
434			acpi_ex_dump_reference_obj(obj_desc);
435			break;
436
437		case ACPI_EXD_LIST:
438
439			start = *ACPI_CAST_PTR(void *, target);
440			next = start;
441
442			acpi_os_printf("%20s : %p ", name, next);
443			if (next) {
444				acpi_os_printf("%s (Type %2.2X)",
445					       acpi_ut_get_object_type_name
446					       (next), next->common.type);
447
448				while (next->common.next_object) {
449					if ((next->common.type ==
450					     ACPI_TYPE_LOCAL_DATA) && !data) {
451						data = next;
452					}
453
454					next = next->common.next_object;
455					acpi_os_printf("->%p(%s %2.2X)", next,
456						       acpi_ut_get_object_type_name
457						       (next),
458						       next->common.type);
459
460					if ((next == start) || (next == data)) {
461						acpi_os_printf
462						    ("\n**** Error: Object list appears to be circular linked");
463						break;
464					}
465				}
466			} else {
467				acpi_os_printf("- No attached objects");
468			}
469
470			acpi_os_printf("\n");
471			break;
472
473		case ACPI_EXD_HDLR_LIST:
474
475			start = *ACPI_CAST_PTR(void *, target);
476			next = start;
477
478			acpi_os_printf("%20s : %p", name, next);
479			if (next) {
480				acpi_os_printf("(%s %2.2X)",
481					       acpi_ut_get_object_type_name
482					       (next),
483					       next->address_space.space_id);
484
485				while (next->address_space.next) {
486					if ((next->common.type ==
487					     ACPI_TYPE_LOCAL_DATA) && !data) {
488						data = next;
489					}
490
491					next = next->address_space.next;
492					acpi_os_printf("->%p(%s %2.2X)", next,
493						       acpi_ut_get_object_type_name
494						       (next),
495						       next->address_space.
496						       space_id);
497
498					if ((next == start) || (next == data)) {
499						acpi_os_printf
500						    ("\n**** Error: Handler list appears to be circular linked");
501						break;
502					}
503				}
504			}
505
506			acpi_os_printf("\n");
507			break;
508
509		case ACPI_EXD_RGN_LIST:
510
511			start = *ACPI_CAST_PTR(void *, target);
512			next = start;
513
514			acpi_os_printf("%20s : %p", name, next);
515			if (next) {
516				acpi_os_printf("(%s %2.2X)",
517					       acpi_ut_get_object_type_name
518					       (next), next->common.type);
519
520				while (next->region.next) {
521					if ((next->common.type ==
522					     ACPI_TYPE_LOCAL_DATA) && !data) {
523						data = next;
524					}
525
526					next = next->region.next;
527					acpi_os_printf("->%p(%s %2.2X)", next,
528						       acpi_ut_get_object_type_name
529						       (next),
530						       next->common.type);
531
532					if ((next == start) || (next == data)) {
533						acpi_os_printf
534						    ("\n**** Error: Region list appears to be circular linked");
535						break;
536					}
537				}
538			}
539
540			acpi_os_printf("\n");
541			break;
542
543		case ACPI_EXD_NODE:
544
545			node =
546			    *ACPI_CAST_PTR(struct acpi_namespace_node *,
547					   target);
548
549			acpi_os_printf("%20s : %p", name, node);
550			if (node) {
551				acpi_os_printf(" [%4.4s]", node->name.ascii);
552			}
553			acpi_os_printf("\n");
554			break;
555
556		default:
557
558			acpi_os_printf("**** Invalid table opcode [%X] ****\n",
559				       info->opcode);
560			return;
561		}
562
563		info++;
564		count--;
565	}
566}
567
568/*******************************************************************************
569 *
570 * FUNCTION:    acpi_ex_dump_operand
571 *
572 * PARAMETERS:  *obj_desc       - Pointer to entry to be dumped
573 *              depth           - Current nesting depth
574 *
575 * RETURN:      None
576 *
577 * DESCRIPTION: Dump an operand object
578 *
579 ******************************************************************************/
580
581void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
582{
583	u32 length;
584	u32 index;
585
586	ACPI_FUNCTION_NAME(ex_dump_operand);
587
588	/* Check if debug output enabled */
589
590	if (!ACPI_IS_DEBUG_ENABLED(ACPI_LV_EXEC, _COMPONENT)) {
591		return;
592	}
593
594	if (!obj_desc) {
595
596		/* This could be a null element of a package */
597
598		ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Null Object Descriptor\n"));
599		return;
600	}
601
602	if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_NAMED) {
603		ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%p Namespace Node: ",
604				  obj_desc));
605		ACPI_DUMP_ENTRY(obj_desc, ACPI_LV_EXEC);
606		return;
607	}
608
609	if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) {
610		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
611				  "%p is not a node or operand object: [%s]\n",
612				  obj_desc,
613				  acpi_ut_get_descriptor_name(obj_desc)));
614		ACPI_DUMP_BUFFER(obj_desc, sizeof(union acpi_operand_object));
615		return;
616	}
617
618	/* obj_desc is a valid object */
619
620	if (depth > 0) {
621		ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%*s[%u] %p Refs=%u ",
622				  depth, " ", depth, obj_desc,
623				  obj_desc->common.reference_count));
624	} else {
625		ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%p Refs=%u ",
626				  obj_desc, obj_desc->common.reference_count));
627	}
628
629	/* Decode object type */
630
631	switch (obj_desc->common.type) {
632	case ACPI_TYPE_LOCAL_REFERENCE:
633
634		acpi_os_printf("Reference: [%s] ",
635			       acpi_ut_get_reference_name(obj_desc));
636
637		switch (obj_desc->reference.class) {
638		case ACPI_REFCLASS_DEBUG:
639
640			acpi_os_printf("\n");
641			break;
642
643		case ACPI_REFCLASS_INDEX:
644
645			acpi_os_printf("%p\n", obj_desc->reference.object);
646			break;
647
648		case ACPI_REFCLASS_TABLE:
649
650			acpi_os_printf("Table Index %X\n",
651				       obj_desc->reference.value);
652			break;
653
654		case ACPI_REFCLASS_REFOF:
655
656			acpi_os_printf("%p [%s]\n", obj_desc->reference.object,
657				       acpi_ut_get_type_name(((union
658							       acpi_operand_object
659							       *)
660							      obj_desc->
661							      reference.
662							      object)->common.
663							     type));
664			break;
665
666		case ACPI_REFCLASS_NAME:
667
668			acpi_ut_repair_name(obj_desc->reference.node->name.
669					    ascii);
670			acpi_os_printf("- [%4.4s] (Node %p)\n",
671				       obj_desc->reference.node->name.ascii,
672				       obj_desc->reference.node);
673			break;
674
675		case ACPI_REFCLASS_ARG:
676		case ACPI_REFCLASS_LOCAL:
677
678			acpi_os_printf("%X\n", obj_desc->reference.value);
679			break;
680
681		default:	/* Unknown reference class */
682
683			acpi_os_printf("%2.2X\n", obj_desc->reference.class);
684			break;
685		}
686		break;
687
688	case ACPI_TYPE_BUFFER:
689
690		acpi_os_printf("Buffer length %.2X @ %p\n",
691			       obj_desc->buffer.length,
692			       obj_desc->buffer.pointer);
693
694		/* Debug only -- dump the buffer contents */
695
696		if (obj_desc->buffer.pointer) {
697			length = obj_desc->buffer.length;
698			if (length > 128) {
699				length = 128;
700			}
701
702			acpi_os_printf
703			    ("Buffer Contents: (displaying length 0x%.2X)\n",
704			     length);
705			ACPI_DUMP_BUFFER(obj_desc->buffer.pointer, length);
706		}
707		break;
708
709	case ACPI_TYPE_INTEGER:
710
711		acpi_os_printf("Integer %8.8X%8.8X\n",
712			       ACPI_FORMAT_UINT64(obj_desc->integer.value));
713		break;
714
715	case ACPI_TYPE_PACKAGE:
716
717		acpi_os_printf("Package [Len %X] ElementArray %p\n",
718			       obj_desc->package.count,
719			       obj_desc->package.elements);
720
721		/*
722		 * If elements exist, package element pointer is valid,
723		 * and debug_level exceeds 1, dump package's elements.
724		 */
725		if (obj_desc->package.count &&
726		    obj_desc->package.elements && acpi_dbg_level > 1) {
727			for (index = 0; index < obj_desc->package.count;
728			     index++) {
729				acpi_ex_dump_operand(obj_desc->package.
730						     elements[index],
731						     depth + 1);
732			}
733		}
734		break;
735
736	case ACPI_TYPE_REGION:
737
738		acpi_os_printf("Region %s (%X)",
739			       acpi_ut_get_region_name(obj_desc->region.
740						       space_id),
741			       obj_desc->region.space_id);
742
743		/*
744		 * If the address and length have not been evaluated,
745		 * don't print them.
746		 */
747		if (!(obj_desc->region.flags & AOPOBJ_DATA_VALID)) {
748			acpi_os_printf("\n");
749		} else {
750			acpi_os_printf(" base %8.8X%8.8X Length %X\n",
751				       ACPI_FORMAT_UINT64(obj_desc->region.
752							  address),
753				       obj_desc->region.length);
754		}
755		break;
756
757	case ACPI_TYPE_STRING:
758
759		acpi_os_printf("String length %X @ %p ",
760			       obj_desc->string.length,
761			       obj_desc->string.pointer);
762
763		acpi_ut_print_string(obj_desc->string.pointer, ACPI_UINT8_MAX);
764		acpi_os_printf("\n");
765		break;
766
767	case ACPI_TYPE_LOCAL_BANK_FIELD:
768
769		acpi_os_printf("BankField\n");
770		break;
771
772	case ACPI_TYPE_LOCAL_REGION_FIELD:
773
774		acpi_os_printf
775		    ("RegionField: Bits=%X AccWidth=%X Lock=%X Update=%X at "
776		     "byte=%X bit=%X of below:\n", obj_desc->field.bit_length,
777		     obj_desc->field.access_byte_width,
778		     obj_desc->field.field_flags & AML_FIELD_LOCK_RULE_MASK,
779		     obj_desc->field.field_flags & AML_FIELD_UPDATE_RULE_MASK,
780		     obj_desc->field.base_byte_offset,
781		     obj_desc->field.start_field_bit_offset);
782
783		acpi_ex_dump_operand(obj_desc->field.region_obj, depth + 1);
784		break;
785
786	case ACPI_TYPE_LOCAL_INDEX_FIELD:
787
788		acpi_os_printf("IndexField\n");
789		break;
790
791	case ACPI_TYPE_BUFFER_FIELD:
792
793		acpi_os_printf("BufferField: %X bits at byte %X bit %X of\n",
794			       obj_desc->buffer_field.bit_length,
795			       obj_desc->buffer_field.base_byte_offset,
796			       obj_desc->buffer_field.start_field_bit_offset);
797
798		if (!obj_desc->buffer_field.buffer_obj) {
799			ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "*NULL*\n"));
800		} else if ((obj_desc->buffer_field.buffer_obj)->common.type !=
801			   ACPI_TYPE_BUFFER) {
802			acpi_os_printf("*not a Buffer*\n");
803		} else {
804			acpi_ex_dump_operand(obj_desc->buffer_field.buffer_obj,
805					     depth + 1);
806		}
807		break;
808
809	case ACPI_TYPE_EVENT:
810
811		acpi_os_printf("Event\n");
812		break;
813
814	case ACPI_TYPE_METHOD:
815
816		acpi_os_printf("Method(%X) @ %p:%X\n",
817			       obj_desc->method.param_count,
818			       obj_desc->method.aml_start,
819			       obj_desc->method.aml_length);
820		break;
821
822	case ACPI_TYPE_MUTEX:
823
824		acpi_os_printf("Mutex\n");
825		break;
826
827	case ACPI_TYPE_DEVICE:
828
829		acpi_os_printf("Device\n");
830		break;
831
832	case ACPI_TYPE_POWER:
833
834		acpi_os_printf("Power\n");
835		break;
836
837	case ACPI_TYPE_PROCESSOR:
838
839		acpi_os_printf("Processor\n");
840		break;
841
842	case ACPI_TYPE_THERMAL:
843
844		acpi_os_printf("Thermal\n");
845		break;
846
847	default:
848
849		/* Unknown Type */
850
851		acpi_os_printf("Unknown Type %X\n", obj_desc->common.type);
852		break;
853	}
854
855	return;
856}
857
858/*******************************************************************************
859 *
860 * FUNCTION:    acpi_ex_dump_operands
861 *
862 * PARAMETERS:  operands            - A list of Operand objects
863 *		opcode_name	    - AML opcode name
864 *		num_operands	    - Operand count for this opcode
865 *
866 * DESCRIPTION: Dump the operands associated with the opcode
867 *
868 ******************************************************************************/
869
870void
871acpi_ex_dump_operands(union acpi_operand_object **operands,
872		      const char *opcode_name, u32 num_operands)
873{
874	ACPI_FUNCTION_TRACE(ex_dump_operands);
875
876	if (!opcode_name) {
877		opcode_name = "UNKNOWN";
878	}
879
880	ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
881			  "**** Start operand dump for opcode [%s], %u operands\n",
882			  opcode_name, num_operands));
883
884	if (num_operands == 0) {
885		num_operands = 1;
886	}
887
888	/* Dump the individual operands */
889
890	while (num_operands) {
891		acpi_ex_dump_operand(*operands, 0);
892		operands++;
893		num_operands--;
894	}
895
896	ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
897			  "**** End operand dump for [%s]\n", opcode_name));
898	return_VOID;
899}
900
901/*******************************************************************************
902 *
903 * FUNCTION:    acpi_ex_out* functions
904 *
905 * PARAMETERS:  title               - Descriptive text
906 *              value               - Value to be displayed
907 *
908 * DESCRIPTION: Object dump output formatting functions. These functions
909 *              reduce the number of format strings required and keeps them
910 *              all in one place for easy modification.
911 *
912 ******************************************************************************/
913
914static void acpi_ex_out_string(const char *title, const char *value)
915{
916	acpi_os_printf("%20s : %s\n", title, value);
917}
918
919static void acpi_ex_out_pointer(const char *title, const void *value)
920{
921	acpi_os_printf("%20s : %p\n", title, value);
922}
923
924/*******************************************************************************
925 *
926 * FUNCTION:    acpi_ex_dump_namespace_node
927 *
928 * PARAMETERS:  node                - Descriptor to dump
929 *              flags               - Force display if TRUE
930 *
931 * DESCRIPTION: Dumps the members of the given.Node
932 *
933 ******************************************************************************/
934
935void acpi_ex_dump_namespace_node(struct acpi_namespace_node *node, u32 flags)
936{
937
938	ACPI_FUNCTION_ENTRY();
939
940	if (!flags) {
941
942		/* Check if debug output enabled */
943
944		if (!ACPI_IS_DEBUG_ENABLED(ACPI_LV_OBJECTS, _COMPONENT)) {
945			return;
946		}
947	}
948
949	acpi_os_printf("%20s : %4.4s\n", "Name", acpi_ut_get_node_name(node));
950	acpi_os_printf("%20s : %2.2X [%s]\n", "Type",
951		       node->type, acpi_ut_get_type_name(node->type));
952
953	acpi_ex_dump_object(ACPI_CAST_PTR(union acpi_operand_object, node),
954			    acpi_ex_dump_node);
955}
956
957/*******************************************************************************
958 *
959 * FUNCTION:    acpi_ex_dump_reference_obj
960 *
961 * PARAMETERS:  object              - Descriptor to dump
962 *
963 * DESCRIPTION: Dumps a reference object
964 *
965 ******************************************************************************/
966
967static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc)
968{
969	struct acpi_buffer ret_buf;
970	acpi_status status;
971
972	ret_buf.length = ACPI_ALLOCATE_LOCAL_BUFFER;
973
974	if (obj_desc->reference.class == ACPI_REFCLASS_NAME) {
975		acpi_os_printf(" %p ", obj_desc->reference.node);
976
977		status = acpi_ns_handle_to_pathname(obj_desc->reference.node,
978						    &ret_buf, TRUE);
979		if (ACPI_FAILURE(status)) {
980			acpi_os_printf
981			    (" Could not convert name to pathname: %s\n",
982			     acpi_format_exception(status));
983		} else {
984			acpi_os_printf("%s: %s\n",
985				       acpi_ut_get_type_name(obj_desc->
986							     reference.node->
987							     type),
988				       (char *)ret_buf.pointer);
989			ACPI_FREE(ret_buf.pointer);
990		}
991	} else if (obj_desc->reference.object) {
992		if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) ==
993		    ACPI_DESC_TYPE_OPERAND) {
994			acpi_os_printf("%22s %p", "Target :",
995				       obj_desc->reference.object);
996			if (obj_desc->reference.class == ACPI_REFCLASS_TABLE) {
997				acpi_os_printf(" Table Index: %X\n",
998					       obj_desc->reference.value);
999			} else {
1000				acpi_os_printf(" [%s]\n",
1001					       acpi_ut_get_type_name(((union
1002								       acpi_operand_object
1003								       *)
1004								      obj_desc->
1005								      reference.
1006								      object)->
1007								     common.
1008								     type));
1009			}
1010		} else {
1011			acpi_os_printf(" Target: %p\n",
1012				       obj_desc->reference.object);
1013		}
1014	}
1015}
1016
1017/*******************************************************************************
1018 *
1019 * FUNCTION:    acpi_ex_dump_package_obj
1020 *
1021 * PARAMETERS:  obj_desc            - Descriptor to dump
1022 *              level               - Indentation Level
1023 *              index               - Package index for this object
1024 *
1025 * DESCRIPTION: Dumps the elements of the package
1026 *
1027 ******************************************************************************/
1028
1029static void
1030acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc,
1031			 u32 level, u32 index)
1032{
1033	u32 i;
1034
1035	/* Indentation and index output */
1036
1037	if (level > 0) {
1038		for (i = 0; i < level; i++) {
1039			acpi_os_printf(" ");
1040		}
1041
1042		acpi_os_printf("[%.2d] ", index);
1043	}
1044
1045	acpi_os_printf("%p ", obj_desc);
1046
1047	/* Null package elements are allowed */
1048
1049	if (!obj_desc) {
1050		acpi_os_printf("[Null Object]\n");
1051		return;
1052	}
1053
1054	/* Packages may only contain a few object types */
1055
1056	switch (obj_desc->common.type) {
1057	case ACPI_TYPE_INTEGER:
1058
1059		acpi_os_printf("[Integer] = %8.8X%8.8X\n",
1060			       ACPI_FORMAT_UINT64(obj_desc->integer.value));
1061		break;
1062
1063	case ACPI_TYPE_STRING:
1064
1065		acpi_os_printf("[String] Value: ");
1066		acpi_ut_print_string(obj_desc->string.pointer, ACPI_UINT8_MAX);
1067		acpi_os_printf("\n");
1068		break;
1069
1070	case ACPI_TYPE_BUFFER:
1071
1072		acpi_os_printf("[Buffer] Length %.2X = ",
1073			       obj_desc->buffer.length);
1074		if (obj_desc->buffer.length) {
1075			acpi_ut_debug_dump_buffer(ACPI_CAST_PTR
1076						  (u8,
1077						   obj_desc->buffer.pointer),
1078						  obj_desc->buffer.length,
1079						  DB_DWORD_DISPLAY, _COMPONENT);
1080		} else {
1081			acpi_os_printf("\n");
1082		}
1083		break;
1084
1085	case ACPI_TYPE_PACKAGE:
1086
1087		acpi_os_printf("[Package] Contains %u Elements:\n",
1088			       obj_desc->package.count);
1089
1090		for (i = 0; i < obj_desc->package.count; i++) {
1091			acpi_ex_dump_package_obj(obj_desc->package.elements[i],
1092						 level + 1, i);
1093		}
1094		break;
1095
1096	case ACPI_TYPE_LOCAL_REFERENCE:
1097
1098		acpi_os_printf("[Object Reference] Class [%s]",
1099			       acpi_ut_get_reference_name(obj_desc));
1100		acpi_ex_dump_reference_obj(obj_desc);
1101		break;
1102
1103	default:
1104
1105		acpi_os_printf("[%s] Type: %2.2X\n",
1106			       acpi_ut_get_type_name(obj_desc->common.type),
1107			       obj_desc->common.type);
1108		break;
1109	}
1110}
1111
1112/*******************************************************************************
1113 *
1114 * FUNCTION:    acpi_ex_dump_object_descriptor
1115 *
1116 * PARAMETERS:  obj_desc            - Descriptor to dump
1117 *              flags               - Force display if TRUE
1118 *
1119 * DESCRIPTION: Dumps the members of the object descriptor given.
1120 *
1121 ******************************************************************************/
1122
1123void
1124acpi_ex_dump_object_descriptor(union acpi_operand_object *obj_desc, u32 flags)
1125{
1126	ACPI_FUNCTION_TRACE(ex_dump_object_descriptor);
1127
1128	if (!obj_desc) {
1129		return_VOID;
1130	}
1131
1132	if (!flags) {
1133
1134		/* Check if debug output enabled */
1135
1136		if (!ACPI_IS_DEBUG_ENABLED(ACPI_LV_OBJECTS, _COMPONENT)) {
1137			return_VOID;
1138		}
1139	}
1140
1141	if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_NAMED) {
1142		acpi_ex_dump_namespace_node((struct acpi_namespace_node *)
1143					    obj_desc, flags);
1144
1145		obj_desc = ((struct acpi_namespace_node *)obj_desc)->object;
1146		if (!obj_desc) {
1147			return_VOID;
1148		}
1149
1150		acpi_os_printf("\nAttached Object %p", obj_desc);
1151		if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_NAMED) {
1152			acpi_os_printf(" - Namespace Node");
1153		}
1154
1155		acpi_os_printf(":\n");
1156		goto dump_object;
1157	}
1158
1159	if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) {
1160		acpi_os_printf("%p is not an ACPI operand object: [%s]\n",
1161			       obj_desc, acpi_ut_get_descriptor_name(obj_desc));
1162		return_VOID;
1163	}
1164
1165	/* Validate the object type */
1166
1167	if (obj_desc->common.type > ACPI_TYPE_LOCAL_MAX) {
1168		acpi_os_printf("Not a known object type: %2.2X\n",
1169			       obj_desc->common.type);
1170		return_VOID;
1171	}
1172
1173dump_object:
1174
1175	if (!obj_desc) {
1176		return_VOID;
1177	}
1178
1179	/* Common Fields */
1180
1181	acpi_ex_dump_object(obj_desc, acpi_ex_dump_common);
1182
1183	/* Object-specific fields */
1184
1185	acpi_ex_dump_object(obj_desc, acpi_ex_dump_info[obj_desc->common.type]);
1186
1187	if (obj_desc->common.type == ACPI_TYPE_REGION) {
1188		obj_desc = obj_desc->common.next_object;
1189		if (obj_desc->common.type > ACPI_TYPE_LOCAL_MAX) {
1190			acpi_os_printf
1191			    ("Secondary object is not a known object type: %2.2X\n",
1192			     obj_desc->common.type);
1193
1194			return_VOID;
1195		}
1196
1197		acpi_os_printf("\nExtra attached Object (%p):\n", obj_desc);
1198		acpi_ex_dump_object(obj_desc,
1199				    acpi_ex_dump_info[obj_desc->common.type]);
1200	}
1201
1202	return_VOID;
1203}
1204
1205#endif
1206