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