xref: /netbsd-src/sys/external/bsd/acpica/dist/debugger/dbtest.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
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