dbtest.c revision 1.6.14.2 1 /*******************************************************************************
2 *
3 * Module Name: dbtest - Various debug-related tests
4 *
5 ******************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2018, 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.h"
45 #include "accommon.h"
46 #include "acdebug.h"
47 #include "acnamesp.h"
48 #include "acpredef.h"
49
50
51 #define _COMPONENT ACPI_CA_DEBUGGER
52 ACPI_MODULE_NAME ("dbtest")
53
54
55 /* Local prototypes */
56
57 static void
58 AcpiDbTestAllObjects (
59 void);
60
61 static ACPI_STATUS
62 AcpiDbTestOneObject (
63 ACPI_HANDLE ObjHandle,
64 UINT32 NestingLevel,
65 void *Context,
66 void **ReturnValue);
67
68 static ACPI_STATUS
69 AcpiDbTestIntegerType (
70 ACPI_NAMESPACE_NODE *Node,
71 UINT32 BitLength);
72
73 static ACPI_STATUS
74 AcpiDbTestBufferType (
75 ACPI_NAMESPACE_NODE *Node,
76 UINT32 BitLength);
77
78 static ACPI_STATUS
79 AcpiDbTestStringType (
80 ACPI_NAMESPACE_NODE *Node,
81 UINT32 ByteLength);
82
83 static ACPI_STATUS
84 AcpiDbTestPackageType (
85 ACPI_NAMESPACE_NODE *Node);
86
87 static ACPI_STATUS
88 AcpiDbReadFromObject (
89 ACPI_NAMESPACE_NODE *Node,
90 ACPI_OBJECT_TYPE ExpectedType,
91 ACPI_OBJECT **Value);
92
93 static ACPI_STATUS
94 AcpiDbWriteToObject (
95 ACPI_NAMESPACE_NODE *Node,
96 ACPI_OBJECT *Value);
97
98 static void
99 AcpiDbEvaluateAllPredefinedNames (
100 char *CountArg);
101
102 static ACPI_STATUS
103 AcpiDbEvaluateOnePredefinedName (
104 ACPI_HANDLE ObjHandle,
105 UINT32 NestingLevel,
106 void *Context,
107 void **ReturnValue);
108
109 /*
110 * Test subcommands
111 */
112 static ACPI_DB_ARGUMENT_INFO AcpiDbTestTypes [] =
113 {
114 {"OBJECTS"},
115 {"PREDEFINED"},
116 {NULL} /* Must be null terminated */
117 };
118
119 #define CMD_TEST_OBJECTS 0
120 #define CMD_TEST_PREDEFINED 1
121
122 #define BUFFER_FILL_VALUE 0xFF
123
124 /*
125 * Support for the special debugger read/write control methods.
126 * These methods are installed into the current namespace and are
127 * used to read and write the various namespace objects. The point
128 * is to force the AML interpreter do all of the work.
129 */
130 #define ACPI_DB_READ_METHOD "\\_T98"
131 #define ACPI_DB_WRITE_METHOD "\\_T99"
132
133 static ACPI_HANDLE ReadHandle = NULL;
134 static ACPI_HANDLE WriteHandle = NULL;
135
136 /* ASL Definitions of the debugger read/write control methods */
137
138 #if 0
139 DefinitionBlock ("ssdt.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
140 {
141 Method (_T98, 1, NotSerialized) /* Read */
142 {
143 Return (DeRefOf (Arg0))
144 }
145 }
146 DefinitionBlock ("ssdt2.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
147 {
148 Method (_T99, 2, NotSerialized) /* Write */
149 {
150 Store (Arg1, Arg0)
151 }
152 }
153 #endif
154
155 static unsigned char ReadMethodCode[] =
156 {
157 0x53,0x53,0x44,0x54,0x2E,0x00,0x00,0x00, /* 00000000 "SSDT...." */
158 0x02,0xC9,0x49,0x6E,0x74,0x65,0x6C,0x00, /* 00000008 "..Intel." */
159 0x44,0x45,0x42,0x55,0x47,0x00,0x00,0x00, /* 00000010 "DEBUG..." */
160 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
161 0x18,0x12,0x13,0x20,0x14,0x09,0x5F,0x54, /* 00000020 "... .._T" */
162 0x39,0x38,0x01,0xA4,0x83,0x68 /* 00000028 "98...h" */
163 };
164
165 static unsigned char WriteMethodCode[] =
166 {
167 0x53,0x53,0x44,0x54,0x2E,0x00,0x00,0x00, /* 00000000 "SSDT...." */
168 0x02,0x15,0x49,0x6E,0x74,0x65,0x6C,0x00, /* 00000008 "..Intel." */
169 0x44,0x45,0x42,0x55,0x47,0x00,0x00,0x00, /* 00000010 "DEBUG..." */
170 0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
171 0x18,0x12,0x13,0x20,0x14,0x09,0x5F,0x54, /* 00000020 "... .._T" */
172 0x39,0x39,0x02,0x70,0x69,0x68 /* 00000028 "99.pih" */
173 };
174
175
176 /*******************************************************************************
177 *
178 * FUNCTION: AcpiDbExecuteTest
179 *
180 * PARAMETERS: TypeArg - Subcommand
181 *
182 * RETURN: None
183 *
184 * DESCRIPTION: Execute various debug tests.
185 *
186 * Note: Code is prepared for future expansion of the TEST command.
187 *
188 ******************************************************************************/
189
190 void
191 AcpiDbExecuteTest (
192 char *TypeArg)
193 {
194 UINT32 Temp;
195
196
197 AcpiUtStrupr (TypeArg);
198 Temp = AcpiDbMatchArgument (TypeArg, AcpiDbTestTypes);
199 if (Temp == ACPI_TYPE_NOT_FOUND)
200 {
201 AcpiOsPrintf ("Invalid or unsupported argument\n");
202 return;
203 }
204
205 switch (Temp)
206 {
207 case CMD_TEST_OBJECTS:
208
209 AcpiDbTestAllObjects ();
210 break;
211
212 case CMD_TEST_PREDEFINED:
213
214 AcpiDbEvaluateAllPredefinedNames (NULL);
215 break;
216
217 default:
218 break;
219 }
220 }
221
222
223 /*******************************************************************************
224 *
225 * FUNCTION: AcpiDbTestAllObjects
226 *
227 * PARAMETERS: None
228 *
229 * RETURN: None
230 *
231 * DESCRIPTION: This test implements the OBJECTS subcommand. It exercises the
232 * namespace by reading/writing/comparing all data objects such
233 * as integers, strings, buffers, fields, buffer fields, etc.
234 *
235 ******************************************************************************/
236
237 static void
238 AcpiDbTestAllObjects (
239 void)
240 {
241 ACPI_STATUS Status;
242
243
244 /* Install the debugger read-object control method if necessary */
245
246 if (!ReadHandle)
247 {
248 Status = AcpiInstallMethod (ReadMethodCode);
249 if (ACPI_FAILURE (Status))
250 {
251 AcpiOsPrintf ("%s, Could not install debugger read method\n",
252 AcpiFormatException (Status));
253 return;
254 }
255
256 Status = AcpiGetHandle (NULL, ACPI_DB_READ_METHOD, &ReadHandle);
257 if (ACPI_FAILURE (Status))
258 {
259 AcpiOsPrintf ("Could not obtain handle for debug method %s\n",
260 ACPI_DB_READ_METHOD);
261 return;
262 }
263 }
264
265 /* Install the debugger write-object control method if necessary */
266
267 if (!WriteHandle)
268 {
269 Status = AcpiInstallMethod (WriteMethodCode);
270 if (ACPI_FAILURE (Status))
271 {
272 AcpiOsPrintf ("%s, Could not install debugger write method\n",
273 AcpiFormatException (Status));
274 return;
275 }
276
277 Status = AcpiGetHandle (NULL, ACPI_DB_WRITE_METHOD, &WriteHandle);
278 if (ACPI_FAILURE (Status))
279 {
280 AcpiOsPrintf ("Could not obtain handle for debug method %s\n",
281 ACPI_DB_WRITE_METHOD);
282 return;
283 }
284 }
285
286 /* Walk the entire namespace, testing each supported named data object */
287
288 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
289 ACPI_UINT32_MAX, AcpiDbTestOneObject, NULL, NULL, NULL);
290 }
291
292
293 /*******************************************************************************
294 *
295 * FUNCTION: AcpiDbTestOneObject
296 *
297 * PARAMETERS: ACPI_WALK_CALLBACK
298 *
299 * RETURN: Status
300 *
301 * DESCRIPTION: Test one namespace object. Supported types are Integer,
302 * String, Buffer, BufferField, and FieldUnit. All other object
303 * types are simply ignored.
304 *
305 * Note: Support for Packages is not implemented.
306 *
307 ******************************************************************************/
308
309 static ACPI_STATUS
310 AcpiDbTestOneObject (
311 ACPI_HANDLE ObjHandle,
312 UINT32 NestingLevel,
313 void *Context,
314 void **ReturnValue)
315 {
316 ACPI_NAMESPACE_NODE *Node;
317 ACPI_OPERAND_OBJECT *ObjDesc;
318 ACPI_OPERAND_OBJECT *RegionObj;
319 ACPI_OBJECT_TYPE LocalType;
320 UINT32 BitLength = 0;
321 UINT32 ByteLength = 0;
322 ACPI_STATUS Status = AE_OK;
323
324
325 Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
326 ObjDesc = Node->Object;
327
328 /*
329 * For the supported types, get the actual bit length or
330 * byte length. Map the type to one of Integer/String/Buffer.
331 */
332 switch (Node->Type)
333 {
334 case ACPI_TYPE_INTEGER:
335
336 /* Integer width is either 32 or 64 */
337
338 LocalType = ACPI_TYPE_INTEGER;
339 BitLength = AcpiGbl_IntegerBitWidth;
340 break;
341
342 case ACPI_TYPE_STRING:
343
344 LocalType = ACPI_TYPE_STRING;
345 ByteLength = ObjDesc->String.Length;
346 break;
347
348 case ACPI_TYPE_BUFFER:
349
350 LocalType = ACPI_TYPE_BUFFER;
351 ByteLength = ObjDesc->Buffer.Length;
352 BitLength = ByteLength * 8;
353 break;
354
355 case ACPI_TYPE_PACKAGE:
356
357 LocalType = ACPI_TYPE_PACKAGE;
358 break;
359
360 case ACPI_TYPE_FIELD_UNIT:
361 case ACPI_TYPE_BUFFER_FIELD:
362 case ACPI_TYPE_LOCAL_REGION_FIELD:
363 case ACPI_TYPE_LOCAL_INDEX_FIELD:
364 case ACPI_TYPE_LOCAL_BANK_FIELD:
365
366 LocalType = ACPI_TYPE_INTEGER;
367 if (ObjDesc)
368 {
369 /*
370 * Returned object will be a Buffer if the field length
371 * is larger than the size of an Integer (32 or 64 bits
372 * depending on the DSDT version).
373 */
374 BitLength = ObjDesc->CommonField.BitLength;
375 ByteLength = ACPI_ROUND_BITS_UP_TO_BYTES (BitLength);
376 if (BitLength > AcpiGbl_IntegerBitWidth)
377 {
378 LocalType = ACPI_TYPE_BUFFER;
379 }
380 }
381 break;
382
383 default:
384
385 /* Ignore all other types */
386
387 return (AE_OK);
388 }
389
390 /* Emit the common prefix: Type:Name */
391
392 AcpiOsPrintf ("%14s: %4.4s",
393 AcpiUtGetTypeName (Node->Type), Node->Name.Ascii);
394
395 if (!ObjDesc)
396 {
397 AcpiOsPrintf (" Ignoring, no attached object\n");
398 return (AE_OK);
399 }
400
401 /*
402 * Check for unsupported region types. Note: AcpiExec simulates
403 * access to SystemMemory, SystemIO, PCI_Config, and EC.
404 */
405 switch (Node->Type)
406 {
407 case ACPI_TYPE_LOCAL_REGION_FIELD:
408
409 RegionObj = ObjDesc->Field.RegionObj;
410 switch (RegionObj->Region.SpaceId)
411 {
412 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
413 case ACPI_ADR_SPACE_SYSTEM_IO:
414 case ACPI_ADR_SPACE_PCI_CONFIG:
415
416 break;
417
418 default:
419
420 AcpiOsPrintf (" %s space is not supported in this command [%4.4s]\n",
421 AcpiUtGetRegionName (RegionObj->Region.SpaceId),
422 RegionObj->Region.Node->Name.Ascii);
423 return (AE_OK);
424 }
425 break;
426
427 default:
428 break;
429 }
430
431 /* At this point, we have resolved the object to one of the major types */
432
433 switch (LocalType)
434 {
435 case ACPI_TYPE_INTEGER:
436
437 Status = AcpiDbTestIntegerType (Node, BitLength);
438 break;
439
440 case ACPI_TYPE_STRING:
441
442 Status = AcpiDbTestStringType (Node, ByteLength);
443 break;
444
445 case ACPI_TYPE_BUFFER:
446
447 Status = AcpiDbTestBufferType (Node, BitLength);
448 break;
449
450 case ACPI_TYPE_PACKAGE:
451
452 Status = AcpiDbTestPackageType (Node);
453 break;
454
455 default:
456
457 AcpiOsPrintf (" Ignoring, type not implemented (%2.2X)",
458 LocalType);
459 break;
460 }
461
462 /* Exit on error, but don't abort the namespace walk */
463
464 if (ACPI_FAILURE (Status))
465 {
466 Status = AE_OK;
467 goto Exit;
468 }
469
470 switch (Node->Type)
471 {
472 case ACPI_TYPE_LOCAL_REGION_FIELD:
473
474 RegionObj = ObjDesc->Field.RegionObj;
475 AcpiOsPrintf (" (%s)",
476 AcpiUtGetRegionName (RegionObj->Region.SpaceId));
477
478 break;
479
480 default:
481 break;
482 }
483
484 Exit:
485 AcpiOsPrintf ("\n");
486 return (Status);
487 }
488
489
490 /*******************************************************************************
491 *
492 * FUNCTION: AcpiDbTestIntegerType
493 *
494 * PARAMETERS: Node - Parent NS node for the object
495 * BitLength - Actual length of the object. Used for
496 * support of arbitrary length FieldUnit
497 * and BufferField objects.
498 *
499 * RETURN: Status
500 *
501 * DESCRIPTION: Test read/write for an Integer-valued object. Performs a
502 * write/read/compare of an arbitrary new value, then performs
503 * a write/read/compare of the original value.
504 *
505 ******************************************************************************/
506
507 static ACPI_STATUS
508 AcpiDbTestIntegerType (
509 ACPI_NAMESPACE_NODE *Node,
510 UINT32 BitLength)
511 {
512 ACPI_OBJECT *Temp1 = NULL;
513 ACPI_OBJECT *Temp2 = NULL;
514 ACPI_OBJECT *Temp3 = NULL;
515 ACPI_OBJECT WriteValue;
516 UINT64 ValueToWrite;
517 ACPI_STATUS Status;
518
519
520 if (BitLength > 64)
521 {
522 AcpiOsPrintf (" Invalid length for an Integer: %u", BitLength);
523 return (AE_OK);
524 }
525
526 /* Read the original value */
527
528 Status = AcpiDbReadFromObject (Node, ACPI_TYPE_INTEGER, &Temp1);
529 if (ACPI_FAILURE (Status))
530 {
531 return (Status);
532 }
533
534 AcpiOsPrintf (" (%4.4X/%3.3X) %8.8X%8.8X",
535 BitLength, ACPI_ROUND_BITS_UP_TO_BYTES (BitLength),
536 ACPI_FORMAT_UINT64 (Temp1->Integer.Value));
537
538 ValueToWrite = ACPI_UINT64_MAX >> (64 - BitLength);
539 if (Temp1->Integer.Value == ValueToWrite)
540 {
541 ValueToWrite = 0;
542 }
543 /* Write a new value */
544
545 WriteValue.Type = ACPI_TYPE_INTEGER;
546 WriteValue.Integer.Value = ValueToWrite;
547 Status = AcpiDbWriteToObject (Node, &WriteValue);
548 if (ACPI_FAILURE (Status))
549 {
550 goto Exit;
551 }
552
553 /* Ensure that we can read back the new value */
554
555 Status = AcpiDbReadFromObject (Node, ACPI_TYPE_INTEGER, &Temp2);
556 if (ACPI_FAILURE (Status))
557 {
558 goto Exit;
559 }
560
561 if (Temp2->Integer.Value != ValueToWrite)
562 {
563 AcpiOsPrintf (" MISMATCH 2: %8.8X%8.8X, expecting %8.8X%8.8X",
564 ACPI_FORMAT_UINT64 (Temp2->Integer.Value),
565 ACPI_FORMAT_UINT64 (ValueToWrite));
566 }
567
568 /* Write back the original value */
569
570 WriteValue.Integer.Value = Temp1->Integer.Value;
571 Status = AcpiDbWriteToObject (Node, &WriteValue);
572 if (ACPI_FAILURE (Status))
573 {
574 goto Exit;
575 }
576
577 /* Ensure that we can read back the original value */
578
579 Status = AcpiDbReadFromObject (Node, ACPI_TYPE_INTEGER, &Temp3);
580 if (ACPI_FAILURE (Status))
581 {
582 goto Exit;
583 }
584
585 if (Temp3->Integer.Value != Temp1->Integer.Value)
586 {
587 AcpiOsPrintf (" MISMATCH 3: %8.8X%8.8X, expecting %8.8X%8.8X",
588 ACPI_FORMAT_UINT64 (Temp3->Integer.Value),
589 ACPI_FORMAT_UINT64 (Temp1->Integer.Value));
590 }
591
592 Exit:
593 if (Temp1) {AcpiOsFree (Temp1);}
594 if (Temp2) {AcpiOsFree (Temp2);}
595 if (Temp3) {AcpiOsFree (Temp3);}
596 return (AE_OK);
597 }
598
599
600 /*******************************************************************************
601 *
602 * FUNCTION: AcpiDbTestBufferType
603 *
604 * PARAMETERS: Node - Parent NS node for the object
605 * BitLength - Actual length of the object.
606 *
607 * RETURN: Status
608 *
609 * DESCRIPTION: Test read/write for an Buffer-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
615 static ACPI_STATUS
616 AcpiDbTestBufferType (
617 ACPI_NAMESPACE_NODE *Node,
618 UINT32 BitLength)
619 {
620 ACPI_OBJECT *Temp1 = NULL;
621 ACPI_OBJECT *Temp2 = NULL;
622 ACPI_OBJECT *Temp3 = NULL;
623 UINT8 *Buffer;
624 ACPI_OBJECT WriteValue;
625 ACPI_STATUS Status;
626 UINT32 ByteLength;
627 UINT32 i;
628 UINT8 ExtraBits;
629
630
631 ByteLength = ACPI_ROUND_BITS_UP_TO_BYTES (BitLength);
632 if (ByteLength == 0)
633 {
634 AcpiOsPrintf (" Ignoring zero length buffer");
635 return (AE_OK);
636 }
637
638 /* Allocate a local buffer */
639
640 Buffer = ACPI_ALLOCATE_ZEROED (ByteLength);
641 if (!Buffer)
642 {
643 return (AE_NO_MEMORY);
644 }
645
646 /* Read the original value */
647
648 Status = AcpiDbReadFromObject (Node, ACPI_TYPE_BUFFER, &Temp1);
649 if (ACPI_FAILURE (Status))
650 {
651 goto Exit;
652 }
653
654 /* Emit a few bytes of the buffer */
655
656 AcpiOsPrintf (" (%4.4X/%3.3X)", BitLength, Temp1->Buffer.Length);
657 for (i = 0; ((i < 4) && (i < ByteLength)); i++)
658 {
659 AcpiOsPrintf (" %2.2X", Temp1->Buffer.Pointer[i]);
660 }
661 AcpiOsPrintf ("... ");
662
663 /*
664 * Write a new value.
665 *
666 * Handle possible extra bits at the end of the buffer. Can
667 * happen for FieldUnits larger than an integer, but the bit
668 * count is not an integral number of bytes. Zero out the
669 * unused bits.
670 */
671 memset (Buffer, BUFFER_FILL_VALUE, ByteLength);
672 ExtraBits = BitLength % 8;
673 if (ExtraBits)
674 {
675 Buffer [ByteLength - 1] = ACPI_MASK_BITS_ABOVE (ExtraBits);
676 }
677
678 WriteValue.Type = ACPI_TYPE_BUFFER;
679 WriteValue.Buffer.Length = ByteLength;
680 WriteValue.Buffer.Pointer = Buffer;
681
682 Status = AcpiDbWriteToObject (Node, &WriteValue);
683 if (ACPI_FAILURE (Status))
684 {
685 goto Exit;
686 }
687
688 /* Ensure that we can read back the new value */
689
690 Status = AcpiDbReadFromObject (Node, ACPI_TYPE_BUFFER, &Temp2);
691 if (ACPI_FAILURE (Status))
692 {
693 goto Exit;
694 }
695
696 if (memcmp (Temp2->Buffer.Pointer, Buffer, ByteLength))
697 {
698 AcpiOsPrintf (" MISMATCH 2: New buffer value");
699 }
700
701 /* Write back the original value */
702
703 WriteValue.Buffer.Length = ByteLength;
704 WriteValue.Buffer.Pointer = Temp1->Buffer.Pointer;
705
706 Status = AcpiDbWriteToObject (Node, &WriteValue);
707 if (ACPI_FAILURE (Status))
708 {
709 goto Exit;
710 }
711
712 /* Ensure that we can read back the original value */
713
714 Status = AcpiDbReadFromObject (Node, ACPI_TYPE_BUFFER, &Temp3);
715 if (ACPI_FAILURE (Status))
716 {
717 goto Exit;
718 }
719
720 if (memcmp (Temp1->Buffer.Pointer,
721 Temp3->Buffer.Pointer, ByteLength))
722 {
723 AcpiOsPrintf (" MISMATCH 3: While restoring original buffer");
724 }
725
726 Exit:
727 ACPI_FREE (Buffer);
728 if (Temp1) {AcpiOsFree (Temp1);}
729 if (Temp2) {AcpiOsFree (Temp2);}
730 if (Temp3) {AcpiOsFree (Temp3);}
731 return (Status);
732 }
733
734
735 /*******************************************************************************
736 *
737 * FUNCTION: AcpiDbTestStringType
738 *
739 * PARAMETERS: Node - Parent NS node for the object
740 * ByteLength - Actual length of the object.
741 *
742 * RETURN: Status
743 *
744 * DESCRIPTION: Test read/write for an String-valued object. Performs a
745 * write/read/compare of an arbitrary new value, then performs
746 * a write/read/compare of the original value.
747 *
748 ******************************************************************************/
749
750 static ACPI_STATUS
751 AcpiDbTestStringType (
752 ACPI_NAMESPACE_NODE *Node,
753 UINT32 ByteLength)
754 {
755 ACPI_OBJECT *Temp1 = NULL;
756 ACPI_OBJECT *Temp2 = NULL;
757 ACPI_OBJECT *Temp3 = NULL;
758 char *ValueToWrite = __UNCONST("Test String from AML Debugger");
759 ACPI_OBJECT WriteValue;
760 ACPI_STATUS Status;
761
762
763 /* Read the original value */
764
765 Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp1);
766 if (ACPI_FAILURE (Status))
767 {
768 return (Status);
769 }
770
771 AcpiOsPrintf (" (%4.4X/%3.3X) \"%s\"", (Temp1->String.Length * 8),
772 Temp1->String.Length, Temp1->String.Pointer);
773
774 /* Write a new value */
775
776 WriteValue.Type = ACPI_TYPE_STRING;
777 WriteValue.String.Length = strlen (ValueToWrite);
778 WriteValue.String.Pointer = ValueToWrite;
779
780 Status = AcpiDbWriteToObject (Node, &WriteValue);
781 if (ACPI_FAILURE (Status))
782 {
783 goto Exit;
784 }
785
786 /* Ensure that we can read back the new value */
787
788 Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp2);
789 if (ACPI_FAILURE (Status))
790 {
791 goto Exit;
792 }
793
794 if (strcmp (Temp2->String.Pointer, ValueToWrite))
795 {
796 AcpiOsPrintf (" MISMATCH 2: %s, expecting %s",
797 Temp2->String.Pointer, ValueToWrite);
798 }
799
800 /* Write back the original value */
801
802 WriteValue.String.Length = strlen (Temp1->String.Pointer);
803 WriteValue.String.Pointer = Temp1->String.Pointer;
804
805 Status = AcpiDbWriteToObject (Node, &WriteValue);
806 if (ACPI_FAILURE (Status))
807 {
808 goto Exit;
809 }
810
811 /* Ensure that we can read back the original value */
812
813 Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp3);
814 if (ACPI_FAILURE (Status))
815 {
816 goto Exit;
817 }
818
819 if (strcmp (Temp1->String.Pointer, Temp3->String.Pointer))
820 {
821 AcpiOsPrintf (" MISMATCH 3: %s, expecting %s",
822 Temp3->String.Pointer, Temp1->String.Pointer);
823 }
824
825 Exit:
826 if (Temp1) {AcpiOsFree (Temp1);}
827 if (Temp2) {AcpiOsFree (Temp2);}
828 if (Temp3) {AcpiOsFree (Temp3);}
829 return (Status);
830 }
831
832
833 /*******************************************************************************
834 *
835 * FUNCTION: AcpiDbTestPackageType
836 *
837 * PARAMETERS: Node - Parent NS node for the object
838 *
839 * RETURN: Status
840 *
841 * DESCRIPTION: Test read for a Package object.
842 *
843 ******************************************************************************/
844
845 static ACPI_STATUS
846 AcpiDbTestPackageType (
847 ACPI_NAMESPACE_NODE *Node)
848 {
849 ACPI_OBJECT *Temp1 = NULL;
850 ACPI_STATUS Status;
851
852
853 /* Read the original value */
854
855 Status = AcpiDbReadFromObject (Node, ACPI_TYPE_PACKAGE, &Temp1);
856 if (ACPI_FAILURE (Status))
857 {
858 return (Status);
859 }
860
861 AcpiOsPrintf (" %8.8X Elements", Temp1->Package.Count);
862 AcpiOsFree (Temp1);
863 return (Status);
864 }
865
866
867 /*******************************************************************************
868 *
869 * FUNCTION: AcpiDbReadFromObject
870 *
871 * PARAMETERS: Node - Parent NS node for the object
872 * ExpectedType - Object type expected from the read
873 * Value - Where the value read is returned
874 *
875 * RETURN: Status
876 *
877 * DESCRIPTION: Performs a read from the specified object by invoking the
878 * special debugger control method that reads the object. Thus,
879 * the AML interpreter is doing all of the work, increasing the
880 * validity of the test.
881 *
882 ******************************************************************************/
883
884 static ACPI_STATUS
885 AcpiDbReadFromObject (
886 ACPI_NAMESPACE_NODE *Node,
887 ACPI_OBJECT_TYPE ExpectedType,
888 ACPI_OBJECT **Value)
889 {
890 ACPI_OBJECT *RetValue;
891 ACPI_OBJECT_LIST ParamObjects;
892 ACPI_OBJECT Params[2];
893 ACPI_BUFFER ReturnObj;
894 ACPI_STATUS Status;
895
896
897 Params[0].Type = ACPI_TYPE_LOCAL_REFERENCE;
898 Params[0].Reference.ActualType = Node->Type;
899 Params[0].Reference.Handle = ACPI_CAST_PTR (ACPI_HANDLE, Node);
900
901 ParamObjects.Count = 1;
902 ParamObjects.Pointer = Params;
903
904 ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
905
906 AcpiGbl_MethodExecuting = TRUE;
907 Status = AcpiEvaluateObject (ReadHandle, NULL,
908 &ParamObjects, &ReturnObj);
909
910 AcpiGbl_MethodExecuting = FALSE;
911 if (ACPI_FAILURE (Status))
912 {
913 AcpiOsPrintf ("Could not read from object, %s",
914 AcpiFormatException (Status));
915 return (Status);
916 }
917
918 RetValue = (ACPI_OBJECT *) ReturnObj.Pointer;
919
920 switch (RetValue->Type)
921 {
922 case ACPI_TYPE_INTEGER:
923 case ACPI_TYPE_BUFFER:
924 case ACPI_TYPE_STRING:
925 case ACPI_TYPE_PACKAGE:
926 /*
927 * Did we receive the type we wanted? Most important for the
928 * Integer/Buffer case (when a field is larger than an Integer,
929 * it should return a Buffer).
930 */
931 if (RetValue->Type != ExpectedType)
932 {
933 AcpiOsPrintf (" Type mismatch: Expected %s, Received %s",
934 AcpiUtGetTypeName (ExpectedType),
935 AcpiUtGetTypeName (RetValue->Type));
936
937 AcpiOsFree (ReturnObj.Pointer);
938 return (AE_TYPE);
939 }
940
941 *Value = RetValue;
942 break;
943
944 default:
945
946 AcpiOsPrintf (" Unsupported return object type, %s",
947 AcpiUtGetTypeName (RetValue->Type));
948
949 AcpiOsFree (ReturnObj.Pointer);
950 return (AE_TYPE);
951 }
952
953 return (Status);
954 }
955
956
957 /*******************************************************************************
958 *
959 * FUNCTION: AcpiDbWriteToObject
960 *
961 * PARAMETERS: Node - Parent NS node for the object
962 * Value - Value to be written
963 *
964 * RETURN: Status
965 *
966 * DESCRIPTION: Performs a write to the specified object by invoking the
967 * special debugger control method that writes the object. Thus,
968 * the AML interpreter is doing all of the work, increasing the
969 * validity of the test.
970 *
971 ******************************************************************************/
972
973 static ACPI_STATUS
974 AcpiDbWriteToObject (
975 ACPI_NAMESPACE_NODE *Node,
976 ACPI_OBJECT *Value)
977 {
978 ACPI_OBJECT_LIST ParamObjects;
979 ACPI_OBJECT Params[2];
980 ACPI_STATUS Status;
981
982
983 Params[0].Type = ACPI_TYPE_LOCAL_REFERENCE;
984 Params[0].Reference.ActualType = Node->Type;
985 Params[0].Reference.Handle = ACPI_CAST_PTR (ACPI_HANDLE, Node);
986
987 /* Copy the incoming user parameter */
988
989 memcpy (&Params[1], Value, sizeof (ACPI_OBJECT));
990
991 ParamObjects.Count = 2;
992 ParamObjects.Pointer = Params;
993
994 AcpiGbl_MethodExecuting = TRUE;
995 Status = AcpiEvaluateObject (WriteHandle, NULL, &ParamObjects, NULL);
996 AcpiGbl_MethodExecuting = FALSE;
997
998 if (ACPI_FAILURE (Status))
999 {
1000 AcpiOsPrintf ("Could not write to object, %s",
1001 AcpiFormatException (Status));
1002 }
1003
1004 return (Status);
1005 }
1006
1007
1008 /*******************************************************************************
1009 *
1010 * FUNCTION: AcpiDbEvaluateAllPredefinedNames
1011 *
1012 * PARAMETERS: CountArg - Max number of methods to execute
1013 *
1014 * RETURN: None
1015 *
1016 * DESCRIPTION: Namespace batch execution. Execute predefined names in the
1017 * namespace, up to the max count, if specified.
1018 *
1019 ******************************************************************************/
1020
1021 static void
1022 AcpiDbEvaluateAllPredefinedNames (
1023 char *CountArg)
1024 {
1025 ACPI_DB_EXECUTE_WALK Info;
1026
1027
1028 Info.Count = 0;
1029 Info.MaxCount = ACPI_UINT32_MAX;
1030
1031 if (CountArg)
1032 {
1033 Info.MaxCount = strtoul (CountArg, NULL, 0);
1034 }
1035
1036 /* Search all nodes in namespace */
1037
1038 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
1039 ACPI_UINT32_MAX, AcpiDbEvaluateOnePredefinedName, NULL,
1040 (void *) &Info, NULL);
1041
1042 AcpiOsPrintf (
1043 "Evaluated %u predefined names in the namespace\n", Info.Count);
1044 }
1045
1046
1047 /*******************************************************************************
1048 *
1049 * FUNCTION: AcpiDbEvaluateOnePredefinedName
1050 *
1051 * PARAMETERS: Callback from WalkNamespace
1052 *
1053 * RETURN: Status
1054 *
1055 * DESCRIPTION: Batch execution module. Currently only executes predefined
1056 * ACPI names.
1057 *
1058 ******************************************************************************/
1059
1060 static ACPI_STATUS
1061 AcpiDbEvaluateOnePredefinedName (
1062 ACPI_HANDLE ObjHandle,
1063 UINT32 NestingLevel,
1064 void *Context,
1065 void **ReturnValue)
1066 {
1067 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
1068 ACPI_DB_EXECUTE_WALK *Info = (ACPI_DB_EXECUTE_WALK *) Context;
1069 char *Pathname;
1070 const ACPI_PREDEFINED_INFO *Predefined;
1071 ACPI_DEVICE_INFO *ObjInfo;
1072 ACPI_OBJECT_LIST ParamObjects;
1073 ACPI_OBJECT Params[ACPI_METHOD_NUM_ARGS];
1074 ACPI_OBJECT *ThisParam;
1075 ACPI_BUFFER ReturnObj;
1076 ACPI_STATUS Status;
1077 UINT16 ArgTypeList;
1078 UINT8 ArgCount;
1079 UINT8 ArgType;
1080 UINT32 i;
1081
1082
1083 /* The name must be a predefined ACPI name */
1084
1085 Predefined = AcpiUtMatchPredefinedMethod (Node->Name.Ascii);
1086 if (!Predefined)
1087 {
1088 return (AE_OK);
1089 }
1090
1091 if (Node->Type == ACPI_TYPE_LOCAL_SCOPE)
1092 {
1093 return (AE_OK);
1094 }
1095
1096 Pathname = AcpiNsGetNormalizedPathname (Node, TRUE);
1097 if (!Pathname)
1098 {
1099 return (AE_OK);
1100 }
1101
1102 /* Get the object info for number of method parameters */
1103
1104 Status = AcpiGetObjectInfo (ObjHandle, &ObjInfo);
1105 if (ACPI_FAILURE (Status))
1106 {
1107 ACPI_FREE (Pathname);
1108 return (Status);
1109 }
1110
1111 ParamObjects.Count = 0;
1112 ParamObjects.Pointer = NULL;
1113
1114 if (ObjInfo->Type == ACPI_TYPE_METHOD)
1115 {
1116 /* Setup default parameters (with proper types) */
1117
1118 ArgTypeList = Predefined->Info.ArgumentList;
1119 ArgCount = METHOD_GET_ARG_COUNT (ArgTypeList);
1120
1121 /*
1122 * Setup the ACPI-required number of arguments, regardless of what
1123 * the actual method defines. If there is a difference, then the
1124 * method is wrong and a warning will be issued during execution.
1125 */
1126 ThisParam = Params;
1127 for (i = 0; i < ArgCount; i++)
1128 {
1129 ArgType = METHOD_GET_NEXT_TYPE (ArgTypeList);
1130 ThisParam->Type = ArgType;
1131
1132 switch (ArgType)
1133 {
1134 case ACPI_TYPE_INTEGER:
1135
1136 ThisParam->Integer.Value = 1;
1137 break;
1138
1139 case ACPI_TYPE_STRING:
1140
1141 ThisParam->String.Pointer =
1142 __UNCONST("This is the default argument string");
1143 ThisParam->String.Length =
1144 strlen (ThisParam->String.Pointer);
1145 break;
1146
1147 case ACPI_TYPE_BUFFER:
1148
1149 ThisParam->Buffer.Pointer = (UINT8 *) Params; /* just a garbage buffer */
1150 ThisParam->Buffer.Length = 48;
1151 break;
1152
1153 case ACPI_TYPE_PACKAGE:
1154
1155 ThisParam->Package.Elements = NULL;
1156 ThisParam->Package.Count = 0;
1157 break;
1158
1159 default:
1160
1161 AcpiOsPrintf ("%s: Unsupported argument type: %u\n",
1162 Pathname, ArgType);
1163 break;
1164 }
1165
1166 ThisParam++;
1167 }
1168
1169 ParamObjects.Count = ArgCount;
1170 ParamObjects.Pointer = Params;
1171 }
1172
1173 ACPI_FREE (ObjInfo);
1174 ReturnObj.Pointer = NULL;
1175 ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
1176
1177 /* Do the actual method execution */
1178
1179 AcpiGbl_MethodExecuting = TRUE;
1180
1181 Status = AcpiEvaluateObject (Node, NULL, &ParamObjects, &ReturnObj);
1182
1183 AcpiOsPrintf ("%-32s returned %s\n",
1184 Pathname, AcpiFormatException (Status));
1185 AcpiGbl_MethodExecuting = FALSE;
1186 ACPI_FREE (Pathname);
1187
1188 /* Ignore status from method execution */
1189
1190 Status = AE_OK;
1191
1192 /* Update count, check if we have executed enough methods */
1193
1194 Info->Count++;
1195 if (Info->Count >= Info->MaxCount)
1196 {
1197 Status = AE_CTRL_TERMINATE;
1198 }
1199
1200 return (Status);
1201 }
1202