1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2/*******************************************************************************
3 *
4 * Module Name: dbtest - Various debug-related tests
5 *
6 ******************************************************************************/
7
8#include <acpi/acpi.h>
9#include "accommon.h"
10#include "acdebug.h"
11#include "acnamesp.h"
12#include "acpredef.h"
13#include "acinterp.h"
14
15#define _COMPONENT          ACPI_CA_DEBUGGER
16ACPI_MODULE_NAME("dbtest")
17
18/* Local prototypes */
19static void acpi_db_test_all_objects(void);
20
21static acpi_status
22acpi_db_test_one_object(acpi_handle obj_handle,
23			u32 nesting_level, void *context, void **return_value);
24
25static acpi_status
26acpi_db_test_integer_type(struct acpi_namespace_node *node, u32 bit_length);
27
28static acpi_status
29acpi_db_test_buffer_type(struct acpi_namespace_node *node, u32 bit_length);
30
31static acpi_status
32acpi_db_test_string_type(struct acpi_namespace_node *node, u32 byte_length);
33
34static acpi_status acpi_db_test_package_type(struct acpi_namespace_node *node);
35
36static acpi_status
37acpi_db_test_field_unit_type(union acpi_operand_object *obj_desc);
38
39static acpi_status
40acpi_db_read_from_object(struct acpi_namespace_node *node,
41			 acpi_object_type expected_type,
42			 union acpi_object **value);
43
44static acpi_status
45acpi_db_write_to_object(struct acpi_namespace_node *node,
46			union acpi_object *value);
47
48static void acpi_db_evaluate_all_predefined_names(char *count_arg);
49
50static acpi_status
51acpi_db_evaluate_one_predefined_name(acpi_handle obj_handle,
52				     u32 nesting_level,
53				     void *context, void **return_value);
54
55/*
56 * Test subcommands
57 */
58static struct acpi_db_argument_info acpi_db_test_types[] = {
59	{"OBJECTS"},
60	{"PREDEFINED"},
61	{NULL}			/* Must be null terminated */
62};
63
64#define CMD_TEST_OBJECTS        0
65#define CMD_TEST_PREDEFINED     1
66
67#define BUFFER_FILL_VALUE       0xFF
68
69/*
70 * Support for the special debugger read/write control methods.
71 * These methods are installed into the current namespace and are
72 * used to read and write the various namespace objects. The point
73 * is to force the AML interpreter do all of the work.
74 */
75#define ACPI_DB_READ_METHOD     "\\_T98"
76#define ACPI_DB_WRITE_METHOD    "\\_T99"
77
78static acpi_handle read_handle = NULL;
79static acpi_handle write_handle = NULL;
80
81/* ASL Definitions of the debugger read/write control methods. AML below. */
82
83#if 0
84definition_block("ssdt.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
85{
86	method(_T98, 1, not_serialized) {	/* Read */
87		return (de_ref_of(arg0))
88	}
89}
90
91definition_block("ssdt2.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
92{
93	method(_T99, 2, not_serialized) {	/* Write */
94		store(arg1, arg0)
95	}
96}
97#endif
98
99static unsigned char read_method_code[] = {
100	0x53, 0x53, 0x44, 0x54, 0x2E, 0x00, 0x00, 0x00,	/* 00000000    "SSDT...." */
101	0x02, 0xC9, 0x49, 0x6E, 0x74, 0x65, 0x6C, 0x00,	/* 00000008    "..Intel." */
102	0x44, 0x45, 0x42, 0x55, 0x47, 0x00, 0x00, 0x00,	/* 00000010    "DEBUG..." */
103	0x01, 0x00, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C,	/* 00000018    "....INTL" */
104	0x18, 0x12, 0x13, 0x20, 0x14, 0x09, 0x5F, 0x54,	/* 00000020    "... .._T" */
105	0x39, 0x38, 0x01, 0xA4, 0x83, 0x68	/* 00000028    "98...h"   */
106};
107
108static unsigned char write_method_code[] = {
109	0x53, 0x53, 0x44, 0x54, 0x2E, 0x00, 0x00, 0x00,	/* 00000000    "SSDT...." */
110	0x02, 0x15, 0x49, 0x6E, 0x74, 0x65, 0x6C, 0x00,	/* 00000008    "..Intel." */
111	0x44, 0x45, 0x42, 0x55, 0x47, 0x00, 0x00, 0x00,	/* 00000010    "DEBUG..." */
112	0x01, 0x00, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C,	/* 00000018    "....INTL" */
113	0x18, 0x12, 0x13, 0x20, 0x14, 0x09, 0x5F, 0x54,	/* 00000020    "... .._T" */
114	0x39, 0x39, 0x02, 0x70, 0x69, 0x68	/* 00000028    "99.pih"   */
115};
116
117/*******************************************************************************
118 *
119 * FUNCTION:    acpi_db_execute_test
120 *
121 * PARAMETERS:  type_arg        - Subcommand
122 *
123 * RETURN:      None
124 *
125 * DESCRIPTION: Execute various debug tests.
126 *
127 * Note: Code is prepared for future expansion of the TEST command.
128 *
129 ******************************************************************************/
130
131void acpi_db_execute_test(char *type_arg)
132{
133	u32 temp;
134
135	acpi_ut_strupr(type_arg);
136	temp = acpi_db_match_argument(type_arg, acpi_db_test_types);
137	if (temp == ACPI_TYPE_NOT_FOUND) {
138		acpi_os_printf("Invalid or unsupported argument\n");
139		return;
140	}
141
142	switch (temp) {
143	case CMD_TEST_OBJECTS:
144
145		acpi_db_test_all_objects();
146		break;
147
148	case CMD_TEST_PREDEFINED:
149
150		acpi_db_evaluate_all_predefined_names(NULL);
151		break;
152
153	default:
154		break;
155	}
156}
157
158/*******************************************************************************
159 *
160 * FUNCTION:    acpi_db_test_all_objects
161 *
162 * PARAMETERS:  None
163 *
164 * RETURN:      None
165 *
166 * DESCRIPTION: This test implements the OBJECTS subcommand. It exercises the
167 *              namespace by reading/writing/comparing all data objects such
168 *              as integers, strings, buffers, fields, buffer fields, etc.
169 *
170 ******************************************************************************/
171
172static void acpi_db_test_all_objects(void)
173{
174	acpi_status status;
175
176	/* Install the debugger read-object control method if necessary */
177
178	if (!read_handle) {
179		status = acpi_install_method(read_method_code);
180		if (ACPI_FAILURE(status)) {
181			acpi_os_printf
182			    ("%s, Could not install debugger read method\n",
183			     acpi_format_exception(status));
184			return;
185		}
186
187		status =
188		    acpi_get_handle(NULL, ACPI_DB_READ_METHOD, &read_handle);
189		if (ACPI_FAILURE(status)) {
190			acpi_os_printf
191			    ("Could not obtain handle for debug method %s\n",
192			     ACPI_DB_READ_METHOD);
193			return;
194		}
195	}
196
197	/* Install the debugger write-object control method if necessary */
198
199	if (!write_handle) {
200		status = acpi_install_method(write_method_code);
201		if (ACPI_FAILURE(status)) {
202			acpi_os_printf
203			    ("%s, Could not install debugger write method\n",
204			     acpi_format_exception(status));
205			return;
206		}
207
208		status =
209		    acpi_get_handle(NULL, ACPI_DB_WRITE_METHOD, &write_handle);
210		if (ACPI_FAILURE(status)) {
211			acpi_os_printf
212			    ("Could not obtain handle for debug method %s\n",
213			     ACPI_DB_WRITE_METHOD);
214			return;
215		}
216	}
217
218	/* Walk the entire namespace, testing each supported named data object */
219
220	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
221				  ACPI_UINT32_MAX, acpi_db_test_one_object,
222				  NULL, NULL, NULL);
223}
224
225/*******************************************************************************
226 *
227 * FUNCTION:    acpi_db_test_one_object
228 *
229 * PARAMETERS:  acpi_walk_callback
230 *
231 * RETURN:      Status
232 *
233 * DESCRIPTION: Test one namespace object. Supported types are Integer,
234 *              String, Buffer, Package, buffer_field, and field_unit.
235 *              All other object types are simply ignored.
236 *
237 ******************************************************************************/
238
239static acpi_status
240acpi_db_test_one_object(acpi_handle obj_handle,
241			u32 nesting_level, void *context, void **return_value)
242{
243	struct acpi_namespace_node *node;
244	union acpi_operand_object *obj_desc;
245	acpi_object_type local_type;
246	u32 bit_length = 0;
247	u32 byte_length = 0;
248	acpi_status status = AE_OK;
249
250	node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
251	obj_desc = node->object;
252
253	/*
254	 * For the supported types, get the actual bit length or
255	 * byte length. Map the type to one of Integer/String/Buffer.
256	 */
257	switch (node->type) {
258	case ACPI_TYPE_INTEGER:
259
260		/* Integer width is either 32 or 64 */
261
262		local_type = ACPI_TYPE_INTEGER;
263		bit_length = acpi_gbl_integer_bit_width;
264		break;
265
266	case ACPI_TYPE_STRING:
267
268		local_type = ACPI_TYPE_STRING;
269		byte_length = obj_desc->string.length;
270		break;
271
272	case ACPI_TYPE_BUFFER:
273
274		local_type = ACPI_TYPE_BUFFER;
275		byte_length = obj_desc->buffer.length;
276		bit_length = byte_length * 8;
277		break;
278
279	case ACPI_TYPE_PACKAGE:
280
281		local_type = ACPI_TYPE_PACKAGE;
282		break;
283
284	case ACPI_TYPE_FIELD_UNIT:
285	case ACPI_TYPE_LOCAL_REGION_FIELD:
286	case ACPI_TYPE_LOCAL_INDEX_FIELD:
287	case ACPI_TYPE_LOCAL_BANK_FIELD:
288
289		local_type = ACPI_TYPE_FIELD_UNIT;
290		break;
291
292	case ACPI_TYPE_BUFFER_FIELD:
293		/*
294		 * The returned object will be a Buffer if the field length
295		 * is larger than the size of an Integer (32 or 64 bits
296		 * depending on the DSDT version).
297		 */
298		local_type = ACPI_TYPE_INTEGER;
299		if (obj_desc) {
300			bit_length = obj_desc->common_field.bit_length;
301			byte_length = ACPI_ROUND_BITS_UP_TO_BYTES(bit_length);
302			if (bit_length > acpi_gbl_integer_bit_width) {
303				local_type = ACPI_TYPE_BUFFER;
304			}
305		}
306		break;
307
308	default:
309
310		/* Ignore all non-data types - Methods, Devices, Scopes, etc. */
311
312		return (AE_OK);
313	}
314
315	/* Emit the common prefix: Type:Name */
316
317	acpi_os_printf("%14s: %4.4s",
318		       acpi_ut_get_type_name(node->type), node->name.ascii);
319
320	if (!obj_desc) {
321		acpi_os_printf(" No attached sub-object, ignoring\n");
322		return (AE_OK);
323	}
324
325	/* At this point, we have resolved the object to one of the major types */
326
327	switch (local_type) {
328	case ACPI_TYPE_INTEGER:
329
330		status = acpi_db_test_integer_type(node, bit_length);
331		break;
332
333	case ACPI_TYPE_STRING:
334
335		status = acpi_db_test_string_type(node, byte_length);
336		break;
337
338	case ACPI_TYPE_BUFFER:
339
340		status = acpi_db_test_buffer_type(node, bit_length);
341		break;
342
343	case ACPI_TYPE_PACKAGE:
344
345		status = acpi_db_test_package_type(node);
346		break;
347
348	case ACPI_TYPE_FIELD_UNIT:
349
350		status = acpi_db_test_field_unit_type(obj_desc);
351		break;
352
353	default:
354
355		acpi_os_printf(" Ignoring, type not implemented (%2.2X)",
356			       local_type);
357		break;
358	}
359
360	/* Exit on error, but don't abort the namespace walk */
361
362	if (ACPI_FAILURE(status)) {
363		status = AE_OK;
364	}
365
366	acpi_os_printf("\n");
367	return (status);
368}
369
370/*******************************************************************************
371 *
372 * FUNCTION:    acpi_db_test_integer_type
373 *
374 * PARAMETERS:  node                - Parent NS node for the object
375 *              bit_length          - Actual length of the object. Used for
376 *                                    support of arbitrary length field_unit
377 *                                    and buffer_field objects.
378 *
379 * RETURN:      Status
380 *
381 * DESCRIPTION: Test read/write for an Integer-valued object. Performs a
382 *              write/read/compare of an arbitrary new value, then performs
383 *              a write/read/compare of the original value.
384 *
385 ******************************************************************************/
386
387static acpi_status
388acpi_db_test_integer_type(struct acpi_namespace_node *node, u32 bit_length)
389{
390	union acpi_object *temp1 = NULL;
391	union acpi_object *temp2 = NULL;
392	union acpi_object *temp3 = NULL;
393	union acpi_object write_value;
394	u64 value_to_write;
395	acpi_status status;
396
397	if (bit_length > 64) {
398		acpi_os_printf(" Invalid length for an Integer: %u",
399			       bit_length);
400		return (AE_OK);
401	}
402
403	/* Read the original value */
404
405	status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp1);
406	if (ACPI_FAILURE(status)) {
407		return (status);
408	}
409
410	acpi_os_printf(ACPI_DEBUG_LENGTH_FORMAT " %8.8X%8.8X",
411		       bit_length, ACPI_ROUND_BITS_UP_TO_BYTES(bit_length),
412		       ACPI_FORMAT_UINT64(temp1->integer.value));
413
414	value_to_write = ACPI_UINT64_MAX >> (64 - bit_length);
415	if (temp1->integer.value == value_to_write) {
416		value_to_write = 0;
417	}
418	/* Write a new value */
419
420	write_value.type = ACPI_TYPE_INTEGER;
421	write_value.integer.value = value_to_write;
422	status = acpi_db_write_to_object(node, &write_value);
423	if (ACPI_FAILURE(status)) {
424		goto exit;
425	}
426
427	/* Ensure that we can read back the new value */
428
429	status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp2);
430	if (ACPI_FAILURE(status)) {
431		goto exit;
432	}
433
434	if (temp2->integer.value != value_to_write) {
435		acpi_os_printf(" MISMATCH 2: %8.8X%8.8X, expecting %8.8X%8.8X",
436			       ACPI_FORMAT_UINT64(temp2->integer.value),
437			       ACPI_FORMAT_UINT64(value_to_write));
438	}
439
440	/* Write back the original value */
441
442	write_value.integer.value = temp1->integer.value;
443	status = acpi_db_write_to_object(node, &write_value);
444	if (ACPI_FAILURE(status)) {
445		goto exit;
446	}
447
448	/* Ensure that we can read back the original value */
449
450	status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp3);
451	if (ACPI_FAILURE(status)) {
452		goto exit;
453	}
454
455	if (temp3->integer.value != temp1->integer.value) {
456		acpi_os_printf(" MISMATCH 3: %8.8X%8.8X, expecting %8.8X%8.8X",
457			       ACPI_FORMAT_UINT64(temp3->integer.value),
458			       ACPI_FORMAT_UINT64(temp1->integer.value));
459	}
460
461exit:
462	if (temp1) {
463		acpi_os_free(temp1);
464	}
465	if (temp2) {
466		acpi_os_free(temp2);
467	}
468	if (temp3) {
469		acpi_os_free(temp3);
470	}
471	return (AE_OK);
472}
473
474/*******************************************************************************
475 *
476 * FUNCTION:    acpi_db_test_buffer_type
477 *
478 * PARAMETERS:  node                - Parent NS node for the object
479 *              bit_length          - Actual length of the object.
480 *
481 * RETURN:      Status
482 *
483 * DESCRIPTION: Test read/write for an Buffer-valued object. Performs a
484 *              write/read/compare of an arbitrary new value, then performs
485 *              a write/read/compare of the original value.
486 *
487 ******************************************************************************/
488
489static acpi_status
490acpi_db_test_buffer_type(struct acpi_namespace_node *node, u32 bit_length)
491{
492	union acpi_object *temp1 = NULL;
493	union acpi_object *temp2 = NULL;
494	union acpi_object *temp3 = NULL;
495	u8 *buffer;
496	union acpi_object write_value;
497	acpi_status status;
498	u32 byte_length;
499	u32 i;
500	u8 extra_bits;
501
502	byte_length = ACPI_ROUND_BITS_UP_TO_BYTES(bit_length);
503	if (byte_length == 0) {
504		acpi_os_printf(" Ignoring zero length buffer");
505		return (AE_OK);
506	}
507
508	/* Allocate a local buffer */
509
510	buffer = ACPI_ALLOCATE_ZEROED(byte_length);
511	if (!buffer) {
512		return (AE_NO_MEMORY);
513	}
514
515	/* Read the original value */
516
517	status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp1);
518	if (ACPI_FAILURE(status)) {
519		goto exit;
520	}
521
522	/* Emit a few bytes of the buffer */
523
524	acpi_os_printf(ACPI_DEBUG_LENGTH_FORMAT, bit_length,
525		       temp1->buffer.length);
526	for (i = 0; ((i < 8) && (i < byte_length)); i++) {
527		acpi_os_printf(" %2.2X", temp1->buffer.pointer[i]);
528	}
529	acpi_os_printf("... ");
530
531	/*
532	 * Write a new value.
533	 *
534	 * Handle possible extra bits at the end of the buffer. Can
535	 * happen for field_units larger than an integer, but the bit
536	 * count is not an integral number of bytes. Zero out the
537	 * unused bits.
538	 */
539	memset(buffer, BUFFER_FILL_VALUE, byte_length);
540	extra_bits = bit_length % 8;
541	if (extra_bits) {
542		buffer[byte_length - 1] = ACPI_MASK_BITS_ABOVE(extra_bits);
543	}
544
545	write_value.type = ACPI_TYPE_BUFFER;
546	write_value.buffer.length = byte_length;
547	write_value.buffer.pointer = buffer;
548
549	status = acpi_db_write_to_object(node, &write_value);
550	if (ACPI_FAILURE(status)) {
551		goto exit;
552	}
553
554	/* Ensure that we can read back the new value */
555
556	status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp2);
557	if (ACPI_FAILURE(status)) {
558		goto exit;
559	}
560
561	if (memcmp(temp2->buffer.pointer, buffer, byte_length)) {
562		acpi_os_printf(" MISMATCH 2: New buffer value");
563	}
564
565	/* Write back the original value */
566
567	write_value.buffer.length = byte_length;
568	write_value.buffer.pointer = temp1->buffer.pointer;
569
570	status = acpi_db_write_to_object(node, &write_value);
571	if (ACPI_FAILURE(status)) {
572		goto exit;
573	}
574
575	/* Ensure that we can read back the original value */
576
577	status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp3);
578	if (ACPI_FAILURE(status)) {
579		goto exit;
580	}
581
582	if (memcmp(temp1->buffer.pointer, temp3->buffer.pointer, byte_length)) {
583		acpi_os_printf(" MISMATCH 3: While restoring original buffer");
584	}
585
586exit:
587	ACPI_FREE(buffer);
588	if (temp1) {
589		acpi_os_free(temp1);
590	}
591	if (temp2) {
592		acpi_os_free(temp2);
593	}
594	if (temp3) {
595		acpi_os_free(temp3);
596	}
597	return (status);
598}
599
600/*******************************************************************************
601 *
602 * FUNCTION:    acpi_db_test_string_type
603 *
604 * PARAMETERS:  node                - Parent NS node for the object
605 *              byte_length         - Actual length of the object.
606 *
607 * RETURN:      Status
608 *
609 * DESCRIPTION: Test read/write for an String-valued object. Performs a
610 *              write/read/compare of an arbitrary new value, then performs
611 *              a write/read/compare of the original value.
612 *
613 ******************************************************************************/
614
615static acpi_status
616acpi_db_test_string_type(struct acpi_namespace_node *node, u32 byte_length)
617{
618	union acpi_object *temp1 = NULL;
619	union acpi_object *temp2 = NULL;
620	union acpi_object *temp3 = NULL;
621	char *value_to_write = "Test String from AML Debugger";
622	union acpi_object write_value;
623	acpi_status status;
624
625	/* Read the original value */
626
627	status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp1);
628	if (ACPI_FAILURE(status)) {
629		return (status);
630	}
631
632	acpi_os_printf(ACPI_DEBUG_LENGTH_FORMAT " \"%s\"",
633		       (temp1->string.length * 8), temp1->string.length,
634		       temp1->string.pointer);
635
636	/* Write a new value */
637
638	write_value.type = ACPI_TYPE_STRING;
639	write_value.string.length = strlen(value_to_write);
640	write_value.string.pointer = value_to_write;
641
642	status = acpi_db_write_to_object(node, &write_value);
643	if (ACPI_FAILURE(status)) {
644		goto exit;
645	}
646
647	/* Ensure that we can read back the new value */
648
649	status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp2);
650	if (ACPI_FAILURE(status)) {
651		goto exit;
652	}
653
654	if (strcmp(temp2->string.pointer, value_to_write)) {
655		acpi_os_printf(" MISMATCH 2: %s, expecting %s",
656			       temp2->string.pointer, value_to_write);
657	}
658
659	/* Write back the original value */
660
661	write_value.string.length = strlen(temp1->string.pointer);
662	write_value.string.pointer = temp1->string.pointer;
663
664	status = acpi_db_write_to_object(node, &write_value);
665	if (ACPI_FAILURE(status)) {
666		goto exit;
667	}
668
669	/* Ensure that we can read back the original value */
670
671	status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp3);
672	if (ACPI_FAILURE(status)) {
673		goto exit;
674	}
675
676	if (strcmp(temp1->string.pointer, temp3->string.pointer)) {
677		acpi_os_printf(" MISMATCH 3: %s, expecting %s",
678			       temp3->string.pointer, temp1->string.pointer);
679	}
680
681exit:
682	if (temp1) {
683		acpi_os_free(temp1);
684	}
685	if (temp2) {
686		acpi_os_free(temp2);
687	}
688	if (temp3) {
689		acpi_os_free(temp3);
690	}
691	return (status);
692}
693
694/*******************************************************************************
695 *
696 * FUNCTION:    acpi_db_test_package_type
697 *
698 * PARAMETERS:  node                - Parent NS node for the object
699 *
700 * RETURN:      Status
701 *
702 * DESCRIPTION: Test read for a Package object.
703 *
704 ******************************************************************************/
705
706static acpi_status acpi_db_test_package_type(struct acpi_namespace_node *node)
707{
708	union acpi_object *temp1 = NULL;
709	acpi_status status;
710
711	/* Read the original value */
712
713	status = acpi_db_read_from_object(node, ACPI_TYPE_PACKAGE, &temp1);
714	if (ACPI_FAILURE(status)) {
715		return (status);
716	}
717
718	acpi_os_printf(" %.2X Elements", temp1->package.count);
719	acpi_os_free(temp1);
720	return (status);
721}
722
723/*******************************************************************************
724 *
725 * FUNCTION:    acpi_db_test_field_unit_type
726 *
727 * PARAMETERS:  obj_desc                - A field unit object
728 *
729 * RETURN:      Status
730 *
731 * DESCRIPTION: Test read/write on a named field unit.
732 *
733 ******************************************************************************/
734
735static acpi_status
736acpi_db_test_field_unit_type(union acpi_operand_object *obj_desc)
737{
738	union acpi_operand_object *region_obj;
739	u32 bit_length = 0;
740	u32 byte_length = 0;
741	acpi_status status = AE_OK;
742	union acpi_operand_object *ret_buffer_desc;
743
744	/* Supported spaces are memory/io/pci_config */
745
746	region_obj = obj_desc->field.region_obj;
747	switch (region_obj->region.space_id) {
748	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
749	case ACPI_ADR_SPACE_SYSTEM_IO:
750	case ACPI_ADR_SPACE_PCI_CONFIG:
751
752		/* Need the interpreter to execute */
753
754		acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
755		acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
756
757		/* Exercise read-then-write */
758
759		status =
760		    acpi_ex_read_data_from_field(NULL, obj_desc,
761						 &ret_buffer_desc);
762		if (status == AE_OK) {
763			acpi_ex_write_data_to_field(ret_buffer_desc, obj_desc,
764						    NULL);
765			acpi_ut_remove_reference(ret_buffer_desc);
766		}
767
768		acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
769		acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
770
771		bit_length = obj_desc->common_field.bit_length;
772		byte_length = ACPI_ROUND_BITS_UP_TO_BYTES(bit_length);
773
774		acpi_os_printf(ACPI_DEBUG_LENGTH_FORMAT " [%s]", bit_length,
775			       byte_length,
776			       acpi_ut_get_region_name(region_obj->region.
777						       space_id));
778		return (status);
779
780	default:
781
782		acpi_os_printf
783		    ("      %s address space is not supported in this command [%4.4s]",
784		     acpi_ut_get_region_name(region_obj->region.space_id),
785		     region_obj->region.node->name.ascii);
786		return (AE_OK);
787	}
788}
789
790/*******************************************************************************
791 *
792 * FUNCTION:    acpi_db_read_from_object
793 *
794 * PARAMETERS:  node                - Parent NS node for the object
795 *              expected_type       - Object type expected from the read
796 *              value               - Where the value read is returned
797 *
798 * RETURN:      Status
799 *
800 * DESCRIPTION: Performs a read from the specified object by invoking the
801 *              special debugger control method that reads the object. Thus,
802 *              the AML interpreter is doing all of the work, increasing the
803 *              validity of the test.
804 *
805 ******************************************************************************/
806
807static acpi_status
808acpi_db_read_from_object(struct acpi_namespace_node *node,
809			 acpi_object_type expected_type,
810			 union acpi_object **value)
811{
812	union acpi_object *ret_value;
813	struct acpi_object_list param_objects;
814	union acpi_object params[2];
815	struct acpi_buffer return_obj;
816	acpi_status status;
817
818	params[0].type = ACPI_TYPE_LOCAL_REFERENCE;
819	params[0].reference.actual_type = node->type;
820	params[0].reference.handle = ACPI_CAST_PTR(acpi_handle, node);
821
822	param_objects.count = 1;
823	param_objects.pointer = params;
824
825	return_obj.length = ACPI_ALLOCATE_BUFFER;
826
827	acpi_gbl_method_executing = TRUE;
828	status = acpi_evaluate_object(read_handle, NULL,
829				      &param_objects, &return_obj);
830
831	acpi_gbl_method_executing = FALSE;
832	if (ACPI_FAILURE(status)) {
833		acpi_os_printf("Could not read from object, %s",
834			       acpi_format_exception(status));
835		return (status);
836	}
837
838	ret_value = (union acpi_object *)return_obj.pointer;
839
840	switch (ret_value->type) {
841	case ACPI_TYPE_INTEGER:
842	case ACPI_TYPE_BUFFER:
843	case ACPI_TYPE_STRING:
844	case ACPI_TYPE_PACKAGE:
845		/*
846		 * Did we receive the type we wanted? Most important for the
847		 * Integer/Buffer case (when a field is larger than an Integer,
848		 * it should return a Buffer).
849		 */
850		if (ret_value->type != expected_type) {
851			acpi_os_printf
852			    (" Type mismatch: Expected %s, Received %s",
853			     acpi_ut_get_type_name(expected_type),
854			     acpi_ut_get_type_name(ret_value->type));
855
856			acpi_os_free(return_obj.pointer);
857			return (AE_TYPE);
858		}
859
860		*value = ret_value;
861		break;
862
863	default:
864
865		acpi_os_printf(" Unsupported return object type, %s",
866			       acpi_ut_get_type_name(ret_value->type));
867
868		acpi_os_free(return_obj.pointer);
869		return (AE_TYPE);
870	}
871
872	return (status);
873}
874
875/*******************************************************************************
876 *
877 * FUNCTION:    acpi_db_write_to_object
878 *
879 * PARAMETERS:  node                - Parent NS node for the object
880 *              value               - Value to be written
881 *
882 * RETURN:      Status
883 *
884 * DESCRIPTION: Performs a write to the specified object by invoking the
885 *              special debugger control method that writes the object. Thus,
886 *              the AML interpreter is doing all of the work, increasing the
887 *              validity of the test.
888 *
889 ******************************************************************************/
890
891static acpi_status
892acpi_db_write_to_object(struct acpi_namespace_node *node,
893			union acpi_object *value)
894{
895	struct acpi_object_list param_objects;
896	union acpi_object params[2];
897	acpi_status status;
898
899	params[0].type = ACPI_TYPE_LOCAL_REFERENCE;
900	params[0].reference.actual_type = node->type;
901	params[0].reference.handle = ACPI_CAST_PTR(acpi_handle, node);
902
903	/* Copy the incoming user parameter */
904
905	memcpy(&params[1], value, sizeof(union acpi_object));
906
907	param_objects.count = 2;
908	param_objects.pointer = params;
909
910	acpi_gbl_method_executing = TRUE;
911	status = acpi_evaluate_object(write_handle, NULL, &param_objects, NULL);
912	acpi_gbl_method_executing = FALSE;
913
914	if (ACPI_FAILURE(status)) {
915		acpi_os_printf("Could not write to object, %s",
916			       acpi_format_exception(status));
917	}
918
919	return (status);
920}
921
922/*******************************************************************************
923 *
924 * FUNCTION:    acpi_db_evaluate_all_predefined_names
925 *
926 * PARAMETERS:  count_arg           - Max number of methods to execute
927 *
928 * RETURN:      None
929 *
930 * DESCRIPTION: Namespace batch execution. Execute predefined names in the
931 *              namespace, up to the max count, if specified.
932 *
933 ******************************************************************************/
934
935static void acpi_db_evaluate_all_predefined_names(char *count_arg)
936{
937	struct acpi_db_execute_walk info;
938
939	info.count = 0;
940	info.max_count = ACPI_UINT32_MAX;
941
942	if (count_arg) {
943		info.max_count = strtoul(count_arg, NULL, 0);
944	}
945
946	/* Search all nodes in namespace */
947
948	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
949				  ACPI_UINT32_MAX,
950				  acpi_db_evaluate_one_predefined_name, NULL,
951				  (void *)&info, NULL);
952
953	acpi_os_printf("Evaluated %u predefined names in the namespace\n",
954		       info.count);
955}
956
957/*******************************************************************************
958 *
959 * FUNCTION:    acpi_db_evaluate_one_predefined_name
960 *
961 * PARAMETERS:  Callback from walk_namespace
962 *
963 * RETURN:      Status
964 *
965 * DESCRIPTION: Batch execution module. Currently only executes predefined
966 *              ACPI names.
967 *
968 ******************************************************************************/
969
970static acpi_status
971acpi_db_evaluate_one_predefined_name(acpi_handle obj_handle,
972				     u32 nesting_level,
973				     void *context, void **return_value)
974{
975	struct acpi_namespace_node *node =
976	    (struct acpi_namespace_node *)obj_handle;
977	struct acpi_db_execute_walk *info =
978	    (struct acpi_db_execute_walk *)context;
979	char *pathname;
980	const union acpi_predefined_info *predefined;
981	struct acpi_device_info *obj_info;
982	struct acpi_object_list param_objects;
983	union acpi_object params[ACPI_METHOD_NUM_ARGS];
984	union acpi_object *this_param;
985	struct acpi_buffer return_obj;
986	acpi_status status;
987	u16 arg_type_list;
988	u8 arg_count;
989	u8 arg_type;
990	u32 i;
991
992	/* The name must be a predefined ACPI name */
993
994	predefined = acpi_ut_match_predefined_method(node->name.ascii);
995	if (!predefined) {
996		return (AE_OK);
997	}
998
999	if (node->type == ACPI_TYPE_LOCAL_SCOPE) {
1000		return (AE_OK);
1001	}
1002
1003	pathname = acpi_ns_get_normalized_pathname(node, TRUE);
1004	if (!pathname) {
1005		return (AE_OK);
1006	}
1007
1008	/* Get the object info for number of method parameters */
1009
1010	status = acpi_get_object_info(obj_handle, &obj_info);
1011	if (ACPI_FAILURE(status)) {
1012		ACPI_FREE(pathname);
1013		return (status);
1014	}
1015
1016	param_objects.count = 0;
1017	param_objects.pointer = NULL;
1018
1019	if (obj_info->type == ACPI_TYPE_METHOD) {
1020
1021		/* Setup default parameters (with proper types) */
1022
1023		arg_type_list = predefined->info.argument_list;
1024		arg_count = METHOD_GET_ARG_COUNT(arg_type_list);
1025
1026		/*
1027		 * Setup the ACPI-required number of arguments, regardless of what
1028		 * the actual method defines. If there is a difference, then the
1029		 * method is wrong and a warning will be issued during execution.
1030		 */
1031		this_param = params;
1032		for (i = 0; i < arg_count; i++) {
1033			arg_type = METHOD_GET_NEXT_TYPE(arg_type_list);
1034			this_param->type = arg_type;
1035
1036			switch (arg_type) {
1037			case ACPI_TYPE_INTEGER:
1038
1039				this_param->integer.value = 1;
1040				break;
1041
1042			case ACPI_TYPE_STRING:
1043
1044				this_param->string.pointer =
1045				    "This is the default argument string";
1046				this_param->string.length =
1047				    strlen(this_param->string.pointer);
1048				break;
1049
1050			case ACPI_TYPE_BUFFER:
1051
1052				this_param->buffer.pointer = (u8 *)params;	/* just a garbage buffer */
1053				this_param->buffer.length = 48;
1054				break;
1055
1056			case ACPI_TYPE_PACKAGE:
1057
1058				this_param->package.elements = NULL;
1059				this_param->package.count = 0;
1060				break;
1061
1062			default:
1063
1064				acpi_os_printf
1065				    ("%s: Unsupported argument type: %u\n",
1066				     pathname, arg_type);
1067				break;
1068			}
1069
1070			this_param++;
1071		}
1072
1073		param_objects.count = arg_count;
1074		param_objects.pointer = params;
1075	}
1076
1077	ACPI_FREE(obj_info);
1078	return_obj.pointer = NULL;
1079	return_obj.length = ACPI_ALLOCATE_BUFFER;
1080
1081	/* Do the actual method execution */
1082
1083	acpi_gbl_method_executing = TRUE;
1084
1085	status = acpi_evaluate_object(node, NULL, &param_objects, &return_obj);
1086
1087	acpi_os_printf("%-32s returned %s\n",
1088		       pathname, acpi_format_exception(status));
1089	acpi_gbl_method_executing = FALSE;
1090	ACPI_FREE(pathname);
1091
1092	/* Ignore status from method execution */
1093
1094	status = AE_OK;
1095
1096	/* Update count, check if we have executed enough methods */
1097
1098	info->count++;
1099	if (info->count >= info->max_count) {
1100		status = AE_CTRL_TERMINATE;
1101	}
1102
1103	return (status);
1104}
1105