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