1 /*******************************************************************************
2  *
3  * Module Name: dbtest - Various debug-related tests
4  *
5  ******************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************
115  *
116  * Alternatively, you may choose to be licensed under the terms of the
117  * following license:
118  *
119  * Redistribution and use in source and binary forms, with or without
120  * modification, are permitted provided that the following conditions
121  * are met:
122  * 1. Redistributions of source code must retain the above copyright
123  *    notice, this list of conditions, and the following disclaimer,
124  *    without modification.
125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126  *    substantially similar to the "NO WARRANTY" disclaimer below
127  *    ("Disclaimer") and any redistribution must be conditioned upon
128  *    including a substantially similar Disclaimer requirement for further
129  *    binary redistribution.
130  * 3. Neither the names of the above-listed copyright holders nor the names
131  *    of any contributors may be used to endorse or promote products derived
132  *    from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145  *
146  * Alternatively, you may choose to be licensed under the terms of the
147  * GNU General Public License ("GPL") version 2 as published by the Free
148  * Software Foundation.
149  *
150  *****************************************************************************/
151 
152 #include "acpi.h"
153 #include "accommon.h"
154 #include "acdebug.h"
155 #include "acnamesp.h"
156 #include "acpredef.h"
157 
158 #ifdef ACPI_DEBUGGER
159 
160 #define _COMPONENT          ACPI_CA_DEBUGGER
161         ACPI_MODULE_NAME    ("dbtest")
162 
163 
164 /* Local prototypes */
165 
166 static void
167 AcpiDbTestAllObjects (
168     void);
169 
170 static ACPI_STATUS
171 AcpiDbTestOneObject (
172     ACPI_HANDLE             ObjHandle,
173     UINT32                  NestingLevel,
174     void                    *Context,
175     void                    **ReturnValue);
176 
177 static ACPI_STATUS
178 AcpiDbTestIntegerType (
179     ACPI_NAMESPACE_NODE     *Node,
180     UINT32                  BitLength);
181 
182 static ACPI_STATUS
183 AcpiDbTestBufferType (
184     ACPI_NAMESPACE_NODE     *Node,
185     UINT32                  BitLength);
186 
187 static ACPI_STATUS
188 AcpiDbTestStringType (
189     ACPI_NAMESPACE_NODE     *Node,
190     UINT32                  ByteLength);
191 
192 static ACPI_STATUS
193 AcpiDbReadFromObject (
194     ACPI_NAMESPACE_NODE     *Node,
195     ACPI_OBJECT_TYPE        ExpectedType,
196     ACPI_OBJECT             **Value);
197 
198 static ACPI_STATUS
199 AcpiDbWriteToObject (
200     ACPI_NAMESPACE_NODE     *Node,
201     ACPI_OBJECT             *Value);
202 
203 static void
204 AcpiDbEvaluateAllPredefinedNames (
205     char                    *CountArg);
206 
207 static ACPI_STATUS
208 AcpiDbEvaluateOnePredefinedName (
209     ACPI_HANDLE             ObjHandle,
210     UINT32                  NestingLevel,
211     void                    *Context,
212     void                    **ReturnValue);
213 
214 /*
215  * Test subcommands
216  */
217 static ACPI_DB_ARGUMENT_INFO    AcpiDbTestTypes [] =
218 {
219     {"OBJECTS"},
220     {"PREDEFINED"},
221     {NULL}           /* Must be null terminated */
222 };
223 
224 #define CMD_TEST_OBJECTS        0
225 #define CMD_TEST_PREDEFINED     1
226 
227 #define BUFFER_FILL_VALUE       0xFF
228 
229 /*
230  * Support for the special debugger read/write control methods.
231  * These methods are installed into the current namespace and are
232  * used to read and write the various namespace objects. The point
233  * is to force the AML interpreter do all of the work.
234  */
235 #define ACPI_DB_READ_METHOD     "\\_T98"
236 #define ACPI_DB_WRITE_METHOD    "\\_T99"
237 
238 static ACPI_HANDLE          ReadHandle = NULL;
239 static ACPI_HANDLE          WriteHandle = NULL;
240 
241 /* ASL Definitions of the debugger read/write control methods */
242 
243 #if 0
244 DefinitionBlock ("ssdt.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
245 {
246     Method (_T98, 1, NotSerialized)     /* Read */
247     {
248         Return (DeRefOf (Arg0))
249     }
250 }
251 DefinitionBlock ("ssdt2.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
252 {
253     Method (_T99, 2, NotSerialized)     /* Write */
254     {
255         Store (Arg1, Arg0)
256     }
257 }
258 #endif
259 
260 static unsigned char ReadMethodCode[] =
261 {
262     0x53,0x53,0x44,0x54,0x2E,0x00,0x00,0x00,  /* 00000000    "SSDT...." */
263     0x02,0xC9,0x49,0x6E,0x74,0x65,0x6C,0x00,  /* 00000008    "..Intel." */
264     0x44,0x45,0x42,0x55,0x47,0x00,0x00,0x00,  /* 00000010    "DEBUG..." */
265     0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C,  /* 00000018    "....INTL" */
266     0x18,0x12,0x13,0x20,0x14,0x09,0x5F,0x54,  /* 00000020    "... .._T" */
267     0x39,0x38,0x01,0xA4,0x83,0x68             /* 00000028    "98...h"   */
268 };
269 
270 static unsigned char WriteMethodCode[] =
271 {
272     0x53,0x53,0x44,0x54,0x2E,0x00,0x00,0x00,  /* 00000000    "SSDT...." */
273     0x02,0x15,0x49,0x6E,0x74,0x65,0x6C,0x00,  /* 00000008    "..Intel." */
274     0x44,0x45,0x42,0x55,0x47,0x00,0x00,0x00,  /* 00000010    "DEBUG..." */
275     0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C,  /* 00000018    "....INTL" */
276     0x18,0x12,0x13,0x20,0x14,0x09,0x5F,0x54,  /* 00000020    "... .._T" */
277     0x39,0x39,0x02,0x70,0x69,0x68             /* 00000028    "99.pih"   */
278 };
279 
280 
281 /*******************************************************************************
282  *
283  * FUNCTION:    AcpiDbExecuteTest
284  *
285  * PARAMETERS:  TypeArg         - Subcommand
286  *
287  * RETURN:      None
288  *
289  * DESCRIPTION: Execute various debug tests.
290  *
291  * Note: Code is prepared for future expansion of the TEST command.
292  *
293  ******************************************************************************/
294 
295 void
296 AcpiDbExecuteTest (
297     char                    *TypeArg)
298 {
299     UINT32                  Temp;
300 
301 
302     AcpiUtStrupr (TypeArg);
303     Temp = AcpiDbMatchArgument (TypeArg, AcpiDbTestTypes);
304     if (Temp == ACPI_TYPE_NOT_FOUND)
305     {
306         AcpiOsPrintf ("Invalid or unsupported argument\n");
307         return;
308     }
309 
310     switch (Temp)
311     {
312     case CMD_TEST_OBJECTS:
313 
314         AcpiDbTestAllObjects ();
315         break;
316 
317     case CMD_TEST_PREDEFINED:
318 
319         AcpiDbEvaluateAllPredefinedNames (NULL);
320         break;
321 
322     default:
323         break;
324     }
325 }
326 
327 
328 /*******************************************************************************
329  *
330  * FUNCTION:    AcpiDbTestAllObjects
331  *
332  * PARAMETERS:  None
333  *
334  * RETURN:      None
335  *
336  * DESCRIPTION: This test implements the OBJECTS subcommand. It exercises the
337  *              namespace by reading/writing/comparing all data objects such
338  *              as integers, strings, buffers, fields, buffer fields, etc.
339  *
340  ******************************************************************************/
341 
342 static void
343 AcpiDbTestAllObjects (
344     void)
345 {
346     ACPI_STATUS             Status;
347 
348 
349     /* Install the debugger read-object control method if necessary */
350 
351     if (!ReadHandle)
352     {
353         Status = AcpiInstallMethod (ReadMethodCode);
354         if (ACPI_FAILURE (Status))
355         {
356             AcpiOsPrintf ("%s, Could not install debugger read method\n",
357                 AcpiFormatException (Status));
358             return;
359         }
360 
361         Status = AcpiGetHandle (NULL, ACPI_DB_READ_METHOD, &ReadHandle);
362         if (ACPI_FAILURE (Status))
363         {
364             AcpiOsPrintf ("Could not obtain handle for debug method %s\n",
365                 ACPI_DB_READ_METHOD);
366             return;
367         }
368     }
369 
370     /* Install the debugger write-object control method if necessary */
371 
372     if (!WriteHandle)
373     {
374         Status = AcpiInstallMethod (WriteMethodCode);
375         if (ACPI_FAILURE (Status))
376         {
377             AcpiOsPrintf ("%s, Could not install debugger write method\n",
378                 AcpiFormatException (Status));
379             return;
380         }
381 
382         Status = AcpiGetHandle (NULL, ACPI_DB_WRITE_METHOD, &WriteHandle);
383         if (ACPI_FAILURE (Status))
384         {
385             AcpiOsPrintf ("Could not obtain handle for debug method %s\n",
386                 ACPI_DB_WRITE_METHOD);
387             return;
388         }
389     }
390 
391     /* Walk the entire namespace, testing each supported named data object */
392 
393     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
394         ACPI_UINT32_MAX, AcpiDbTestOneObject, NULL, NULL, NULL);
395 }
396 
397 
398 /*******************************************************************************
399  *
400  * FUNCTION:    AcpiDbTestOneObject
401  *
402  * PARAMETERS:  ACPI_WALK_CALLBACK
403  *
404  * RETURN:      Status
405  *
406  * DESCRIPTION: Test one namespace object. Supported types are Integer,
407  *              String, Buffer, BufferField, and FieldUnit. All other object
408  *              types are simply ignored.
409  *
410  *              Note: Support for Packages is not implemented.
411  *
412  ******************************************************************************/
413 
414 static ACPI_STATUS
415 AcpiDbTestOneObject (
416     ACPI_HANDLE             ObjHandle,
417     UINT32                  NestingLevel,
418     void                    *Context,
419     void                    **ReturnValue)
420 {
421     ACPI_NAMESPACE_NODE     *Node;
422     ACPI_OPERAND_OBJECT     *ObjDesc;
423     ACPI_OPERAND_OBJECT     *RegionObj;
424     ACPI_OBJECT_TYPE        LocalType;
425     UINT32                  BitLength = 0;
426     UINT32                  ByteLength = 0;
427     ACPI_STATUS             Status = AE_OK;
428 
429 
430     Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
431     ObjDesc = Node->Object;
432 
433     /*
434      * For the supported types, get the actual bit length or
435      * byte length. Map the type to one of Integer/String/Buffer.
436      */
437     switch (Node->Type)
438     {
439     case ACPI_TYPE_INTEGER:
440 
441         /* Integer width is either 32 or 64 */
442 
443         LocalType = ACPI_TYPE_INTEGER;
444         BitLength = AcpiGbl_IntegerBitWidth;
445         break;
446 
447     case ACPI_TYPE_STRING:
448 
449         LocalType = ACPI_TYPE_STRING;
450         ByteLength = ObjDesc->String.Length;
451         break;
452 
453     case ACPI_TYPE_BUFFER:
454 
455         LocalType = ACPI_TYPE_BUFFER;
456         ByteLength = ObjDesc->Buffer.Length;
457         BitLength = ByteLength * 8;
458         break;
459 
460     case ACPI_TYPE_FIELD_UNIT:
461     case ACPI_TYPE_BUFFER_FIELD:
462     case ACPI_TYPE_LOCAL_REGION_FIELD:
463     case ACPI_TYPE_LOCAL_INDEX_FIELD:
464     case ACPI_TYPE_LOCAL_BANK_FIELD:
465 
466         LocalType = ACPI_TYPE_INTEGER;
467         if (ObjDesc)
468         {
469             /*
470              * Returned object will be a Buffer if the field length
471              * is larger than the size of an Integer (32 or 64 bits
472              * depending on the DSDT version).
473              */
474             BitLength = ObjDesc->CommonField.BitLength;
475             ByteLength = ACPI_ROUND_BITS_UP_TO_BYTES (BitLength);
476             if (BitLength > AcpiGbl_IntegerBitWidth)
477             {
478                 LocalType = ACPI_TYPE_BUFFER;
479             }
480         }
481         break;
482 
483     default:
484 
485         /* Ignore all other types */
486 
487         return (AE_OK);
488     }
489 
490     /* Emit the common prefix: Type:Name */
491 
492     AcpiOsPrintf ("%14s: %4.4s",
493         AcpiUtGetTypeName (Node->Type), Node->Name.Ascii);
494     if (!ObjDesc)
495     {
496         AcpiOsPrintf (" Ignoring, no attached object\n");
497         return (AE_OK);
498     }
499 
500     /*
501      * Check for unsupported region types. Note: AcpiExec simulates
502      * access to SystemMemory, SystemIO, PCI_Config, and EC.
503      */
504     switch (Node->Type)
505     {
506     case ACPI_TYPE_LOCAL_REGION_FIELD:
507 
508         RegionObj = ObjDesc->Field.RegionObj;
509         switch (RegionObj->Region.SpaceId)
510         {
511         case ACPI_ADR_SPACE_SYSTEM_MEMORY:
512         case ACPI_ADR_SPACE_SYSTEM_IO:
513         case ACPI_ADR_SPACE_PCI_CONFIG:
514         case ACPI_ADR_SPACE_EC:
515 
516             break;
517 
518         default:
519 
520             AcpiOsPrintf ("      %s space is not supported [%4.4s]\n",
521                 AcpiUtGetRegionName (RegionObj->Region.SpaceId),
522                 RegionObj->Region.Node->Name.Ascii);
523             return (AE_OK);
524         }
525         break;
526 
527     default:
528         break;
529     }
530 
531     /* At this point, we have resolved the object to one of the major types */
532 
533     switch (LocalType)
534     {
535     case ACPI_TYPE_INTEGER:
536 
537         Status = AcpiDbTestIntegerType (Node, BitLength);
538         break;
539 
540     case ACPI_TYPE_STRING:
541 
542         Status = AcpiDbTestStringType (Node, ByteLength);
543         break;
544 
545     case ACPI_TYPE_BUFFER:
546 
547         Status = AcpiDbTestBufferType (Node, BitLength);
548         break;
549 
550     default:
551 
552         AcpiOsPrintf (" Ignoring, type not implemented (%2.2X)",
553             LocalType);
554         break;
555     }
556 
557     switch (Node->Type)
558     {
559     case ACPI_TYPE_LOCAL_REGION_FIELD:
560 
561         RegionObj = ObjDesc->Field.RegionObj;
562         AcpiOsPrintf (" (%s)",
563             AcpiUtGetRegionName (RegionObj->Region.SpaceId));
564         break;
565 
566     default:
567         break;
568     }
569 
570     AcpiOsPrintf ("\n");
571     return (Status);
572 }
573 
574 
575 /*******************************************************************************
576  *
577  * FUNCTION:    AcpiDbTestIntegerType
578  *
579  * PARAMETERS:  Node                - Parent NS node for the object
580  *              BitLength           - Actual length of the object. Used for
581  *                                    support of arbitrary length FieldUnit
582  *                                    and BufferField objects.
583  *
584  * RETURN:      Status
585  *
586  * DESCRIPTION: Test read/write for an Integer-valued object. Performs a
587  *              write/read/compare of an arbitrary new value, then performs
588  *              a write/read/compare of the original value.
589  *
590  ******************************************************************************/
591 
592 static ACPI_STATUS
593 AcpiDbTestIntegerType (
594     ACPI_NAMESPACE_NODE     *Node,
595     UINT32                  BitLength)
596 {
597     ACPI_OBJECT             *Temp1 = NULL;
598     ACPI_OBJECT             *Temp2 = NULL;
599     ACPI_OBJECT             *Temp3 = NULL;
600     ACPI_OBJECT             WriteValue;
601     UINT64                  ValueToWrite;
602     ACPI_STATUS             Status;
603 
604 
605     if (BitLength > 64)
606     {
607         AcpiOsPrintf (" Invalid length for an Integer: %u", BitLength);
608         return (AE_OK);
609     }
610 
611     /* Read the original value */
612 
613     Status = AcpiDbReadFromObject (Node, ACPI_TYPE_INTEGER, &Temp1);
614     if (ACPI_FAILURE (Status))
615     {
616         return (Status);
617     }
618 
619     AcpiOsPrintf (" (%4.4X/%3.3X) %8.8X%8.8X",
620         BitLength, ACPI_ROUND_BITS_UP_TO_BYTES (BitLength),
621         ACPI_FORMAT_UINT64 (Temp1->Integer.Value));
622 
623     ValueToWrite = ACPI_UINT64_MAX >> (64 - BitLength);
624     if (Temp1->Integer.Value == ValueToWrite)
625     {
626         ValueToWrite = 0;
627     }
628 
629     /* Write a new value */
630 
631     WriteValue.Type = ACPI_TYPE_INTEGER;
632     WriteValue.Integer.Value = ValueToWrite;
633     Status = AcpiDbWriteToObject (Node, &WriteValue);
634     if (ACPI_FAILURE (Status))
635     {
636         goto Exit;
637     }
638 
639     /* Ensure that we can read back the new value */
640 
641     Status = AcpiDbReadFromObject (Node, ACPI_TYPE_INTEGER, &Temp2);
642     if (ACPI_FAILURE (Status))
643     {
644         goto Exit;
645     }
646 
647     if (Temp2->Integer.Value != ValueToWrite)
648     {
649         AcpiOsPrintf (" MISMATCH 2: %8.8X%8.8X, expecting %8.8X%8.8X",
650             ACPI_FORMAT_UINT64 (Temp2->Integer.Value),
651             ACPI_FORMAT_UINT64 (ValueToWrite));
652     }
653 
654     /* Write back the original value */
655 
656     WriteValue.Integer.Value = Temp1->Integer.Value;
657     Status = AcpiDbWriteToObject (Node, &WriteValue);
658     if (ACPI_FAILURE (Status))
659     {
660         goto Exit;
661     }
662 
663     /* Ensure that we can read back the original value */
664 
665     Status = AcpiDbReadFromObject (Node, ACPI_TYPE_INTEGER, &Temp3);
666     if (ACPI_FAILURE (Status))
667     {
668         goto Exit;
669     }
670 
671     if (Temp3->Integer.Value != Temp1->Integer.Value)
672     {
673         AcpiOsPrintf (" MISMATCH 3: %8.8X%8.8X, expecting %8.8X%8.8X",
674             ACPI_FORMAT_UINT64 (Temp3->Integer.Value),
675             ACPI_FORMAT_UINT64 (Temp1->Integer.Value));
676     }
677 
678 Exit:
679     if (Temp1) {AcpiOsFree (Temp1);}
680     if (Temp2) {AcpiOsFree (Temp2);}
681     if (Temp3) {AcpiOsFree (Temp3);}
682     return (AE_OK);
683 }
684 
685 
686 /*******************************************************************************
687  *
688  * FUNCTION:    AcpiDbTestBufferType
689  *
690  * PARAMETERS:  Node                - Parent NS node for the object
691  *              BitLength           - Actual length of the object.
692  *
693  * RETURN:      Status
694  *
695  * DESCRIPTION: Test read/write for an Buffer-valued object. Performs a
696  *              write/read/compare of an arbitrary new value, then performs
697  *              a write/read/compare of the original value.
698  *
699  ******************************************************************************/
700 
701 static ACPI_STATUS
702 AcpiDbTestBufferType (
703     ACPI_NAMESPACE_NODE     *Node,
704     UINT32                  BitLength)
705 {
706     ACPI_OBJECT             *Temp1 = NULL;
707     ACPI_OBJECT             *Temp2 = NULL;
708     ACPI_OBJECT             *Temp3 = NULL;
709     UINT8                   *Buffer;
710     ACPI_OBJECT             WriteValue;
711     ACPI_STATUS             Status;
712     UINT32                  ByteLength;
713     UINT32                  i;
714     UINT8                   ExtraBits;
715 
716 
717     ByteLength = ACPI_ROUND_BITS_UP_TO_BYTES (BitLength);
718     if (ByteLength == 0)
719     {
720         AcpiOsPrintf (" Ignoring zero length buffer");
721         return (AE_OK);
722     }
723 
724     /* Allocate a local buffer */
725 
726     Buffer = ACPI_ALLOCATE_ZEROED (ByteLength);
727     if (!Buffer)
728     {
729         return (AE_NO_MEMORY);
730     }
731 
732     /* Read the original value */
733 
734     Status = AcpiDbReadFromObject (Node, ACPI_TYPE_BUFFER, &Temp1);
735     if (ACPI_FAILURE (Status))
736     {
737         goto Exit;
738     }
739 
740     /* Emit a few bytes of the buffer */
741 
742     AcpiOsPrintf (" (%4.4X/%3.3X)", BitLength, Temp1->Buffer.Length);
743     for (i = 0; ((i < 4) && (i < ByteLength)); i++)
744     {
745         AcpiOsPrintf (" %2.2X", Temp1->Buffer.Pointer[i]);
746     }
747     AcpiOsPrintf ("...  ");
748 
749     /*
750      * Write a new value.
751      *
752      * Handle possible extra bits at the end of the buffer. Can
753      * happen for FieldUnits larger than an integer, but the bit
754      * count is not an integral number of bytes. Zero out the
755      * unused bits.
756      */
757     memset (Buffer, BUFFER_FILL_VALUE, ByteLength);
758     ExtraBits = BitLength % 8;
759     if (ExtraBits)
760     {
761         Buffer [ByteLength - 1] = ACPI_MASK_BITS_ABOVE (ExtraBits);
762     }
763 
764     WriteValue.Type = ACPI_TYPE_BUFFER;
765     WriteValue.Buffer.Length = ByteLength;
766     WriteValue.Buffer.Pointer = Buffer;
767 
768     Status = AcpiDbWriteToObject (Node, &WriteValue);
769     if (ACPI_FAILURE (Status))
770     {
771         goto Exit;
772     }
773 
774     /* Ensure that we can read back the new value */
775 
776     Status = AcpiDbReadFromObject (Node, ACPI_TYPE_BUFFER, &Temp2);
777     if (ACPI_FAILURE (Status))
778     {
779         goto Exit;
780     }
781 
782     if (memcmp (Temp2->Buffer.Pointer, Buffer, ByteLength))
783     {
784         AcpiOsPrintf (" MISMATCH 2: New buffer value");
785     }
786 
787     /* Write back the original value */
788 
789     WriteValue.Buffer.Length = ByteLength;
790     WriteValue.Buffer.Pointer = Temp1->Buffer.Pointer;
791 
792     Status = AcpiDbWriteToObject (Node, &WriteValue);
793     if (ACPI_FAILURE (Status))
794     {
795         goto Exit;
796     }
797 
798     /* Ensure that we can read back the original value */
799 
800     Status = AcpiDbReadFromObject (Node, ACPI_TYPE_BUFFER, &Temp3);
801     if (ACPI_FAILURE (Status))
802     {
803         goto Exit;
804     }
805 
806     if (memcmp (Temp1->Buffer.Pointer,
807             Temp3->Buffer.Pointer, ByteLength))
808     {
809         AcpiOsPrintf (" MISMATCH 3: While restoring original buffer");
810     }
811 
812 Exit:
813     ACPI_FREE (Buffer);
814     if (Temp1) {AcpiOsFree (Temp1);}
815     if (Temp2) {AcpiOsFree (Temp2);}
816     if (Temp3) {AcpiOsFree (Temp3);}
817     return (Status);
818 }
819 
820 
821 /*******************************************************************************
822  *
823  * FUNCTION:    AcpiDbTestStringType
824  *
825  * PARAMETERS:  Node                - Parent NS node for the object
826  *              ByteLength          - Actual length of the object.
827  *
828  * RETURN:      Status
829  *
830  * DESCRIPTION: Test read/write for an String-valued object. Performs a
831  *              write/read/compare of an arbitrary new value, then performs
832  *              a write/read/compare of the original value.
833  *
834  ******************************************************************************/
835 
836 static ACPI_STATUS
837 AcpiDbTestStringType (
838     ACPI_NAMESPACE_NODE     *Node,
839     UINT32                  ByteLength)
840 {
841     ACPI_OBJECT             *Temp1 = NULL;
842     ACPI_OBJECT             *Temp2 = NULL;
843     ACPI_OBJECT             *Temp3 = NULL;
844     char                    *ValueToWrite = "Test String from AML Debugger";
845     ACPI_OBJECT             WriteValue;
846     ACPI_STATUS             Status;
847 
848 
849     /* Read the original value */
850 
851     Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp1);
852     if (ACPI_FAILURE (Status))
853     {
854         return (Status);
855     }
856 
857     AcpiOsPrintf (" (%4.4X/%3.3X) \"%s\"", (Temp1->String.Length * 8),
858         Temp1->String.Length, Temp1->String.Pointer);
859 
860     /* Write a new value */
861 
862     WriteValue.Type = ACPI_TYPE_STRING;
863     WriteValue.String.Length = strlen (ValueToWrite);
864     WriteValue.String.Pointer = ValueToWrite;
865 
866     Status = AcpiDbWriteToObject (Node, &WriteValue);
867     if (ACPI_FAILURE (Status))
868     {
869         goto Exit;
870     }
871 
872     /* Ensure that we can read back the new value */
873 
874     Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp2);
875     if (ACPI_FAILURE (Status))
876     {
877         goto Exit;
878     }
879 
880     if (strcmp (Temp2->String.Pointer, ValueToWrite))
881     {
882         AcpiOsPrintf (" MISMATCH 2: %s, expecting %s",
883             Temp2->String.Pointer, ValueToWrite);
884     }
885 
886     /* Write back the original value */
887 
888     WriteValue.String.Length = strlen (Temp1->String.Pointer);
889     WriteValue.String.Pointer = Temp1->String.Pointer;
890 
891     Status = AcpiDbWriteToObject (Node, &WriteValue);
892     if (ACPI_FAILURE (Status))
893     {
894         goto Exit;
895     }
896 
897     /* Ensure that we can read back the original value */
898 
899     Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp3);
900     if (ACPI_FAILURE (Status))
901     {
902         goto Exit;
903     }
904 
905     if (strcmp (Temp1->String.Pointer, Temp3->String.Pointer))
906     {
907         AcpiOsPrintf (" MISMATCH 3: %s, expecting %s",
908             Temp3->String.Pointer, Temp1->String.Pointer);
909     }
910 
911 Exit:
912     if (Temp1) {AcpiOsFree (Temp1);}
913     if (Temp2) {AcpiOsFree (Temp2);}
914     if (Temp3) {AcpiOsFree (Temp3);}
915     return (Status);
916 }
917 
918 
919 /*******************************************************************************
920  *
921  * FUNCTION:    AcpiDbReadFromObject
922  *
923  * PARAMETERS:  Node                - Parent NS node for the object
924  *              ExpectedType        - Object type expected from the read
925  *              Value               - Where the value read is returned
926  *
927  * RETURN:      Status
928  *
929  * DESCRIPTION: Performs a read from the specified object by invoking the
930  *              special debugger control method that reads the object. Thus,
931  *              the AML interpreter is doing all of the work, increasing the
932  *              validity of the test.
933  *
934  ******************************************************************************/
935 
936 static ACPI_STATUS
937 AcpiDbReadFromObject (
938     ACPI_NAMESPACE_NODE     *Node,
939     ACPI_OBJECT_TYPE        ExpectedType,
940     ACPI_OBJECT             **Value)
941 {
942     ACPI_OBJECT             *RetValue;
943     ACPI_OBJECT_LIST        ParamObjects;
944     ACPI_OBJECT             Params[2];
945     ACPI_BUFFER             ReturnObj;
946     ACPI_STATUS             Status;
947 
948 
949     Params[0].Type = ACPI_TYPE_LOCAL_REFERENCE;
950     Params[0].Reference.ActualType = Node->Type;
951     Params[0].Reference.Handle = ACPI_CAST_PTR (ACPI_HANDLE, Node);
952 
953     ParamObjects.Count = 1;
954     ParamObjects.Pointer = Params;
955 
956     ReturnObj.Length  = ACPI_ALLOCATE_BUFFER;
957 
958     AcpiGbl_MethodExecuting = TRUE;
959     Status = AcpiEvaluateObject (ReadHandle, NULL,
960         &ParamObjects, &ReturnObj);
961     AcpiGbl_MethodExecuting = FALSE;
962 
963     if (ACPI_FAILURE (Status))
964     {
965         AcpiOsPrintf ("Could not read from object, %s",
966             AcpiFormatException (Status));
967         return (Status);
968     }
969 
970     RetValue = (ACPI_OBJECT *) ReturnObj.Pointer;
971 
972     switch (RetValue->Type)
973     {
974     case ACPI_TYPE_INTEGER:
975     case ACPI_TYPE_BUFFER:
976     case ACPI_TYPE_STRING:
977         /*
978          * Did we receive the type we wanted? Most important for the
979          * Integer/Buffer case (when a field is larger than an Integer,
980          * it should return a Buffer).
981          */
982         if (RetValue->Type != ExpectedType)
983         {
984             AcpiOsPrintf (" Type mismatch:  Expected %s, Received %s",
985                 AcpiUtGetTypeName (ExpectedType),
986                 AcpiUtGetTypeName (RetValue->Type));
987 
988             return (AE_TYPE);
989         }
990 
991         *Value = RetValue;
992         break;
993 
994     default:
995 
996         AcpiOsPrintf (" Unsupported return object type, %s",
997             AcpiUtGetTypeName (RetValue->Type));
998 
999         AcpiOsFree (ReturnObj.Pointer);
1000         return (AE_TYPE);
1001     }
1002 
1003     return (Status);
1004 }
1005 
1006 
1007 /*******************************************************************************
1008  *
1009  * FUNCTION:    AcpiDbWriteToObject
1010  *
1011  * PARAMETERS:  Node                - Parent NS node for the object
1012  *              Value               - Value to be written
1013  *
1014  * RETURN:      Status
1015  *
1016  * DESCRIPTION: Performs a write to the specified object by invoking the
1017  *              special debugger control method that writes the object. Thus,
1018  *              the AML interpreter is doing all of the work, increasing the
1019  *              validity of the test.
1020  *
1021  ******************************************************************************/
1022 
1023 static ACPI_STATUS
1024 AcpiDbWriteToObject (
1025     ACPI_NAMESPACE_NODE     *Node,
1026     ACPI_OBJECT             *Value)
1027 {
1028     ACPI_OBJECT_LIST        ParamObjects;
1029     ACPI_OBJECT             Params[2];
1030     ACPI_STATUS             Status;
1031 
1032 
1033     Params[0].Type = ACPI_TYPE_LOCAL_REFERENCE;
1034     Params[0].Reference.ActualType = Node->Type;
1035     Params[0].Reference.Handle = ACPI_CAST_PTR (ACPI_HANDLE, Node);
1036 
1037     /* Copy the incoming user parameter */
1038 
1039     memcpy (&Params[1], Value, sizeof (ACPI_OBJECT));
1040 
1041     ParamObjects.Count = 2;
1042     ParamObjects.Pointer = Params;
1043 
1044     AcpiGbl_MethodExecuting = TRUE;
1045     Status = AcpiEvaluateObject (WriteHandle, NULL, &ParamObjects, NULL);
1046     AcpiGbl_MethodExecuting = FALSE;
1047 
1048     if (ACPI_FAILURE (Status))
1049     {
1050         AcpiOsPrintf ("Could not write to object, %s",
1051             AcpiFormatException (Status));
1052     }
1053 
1054     return (Status);
1055 }
1056 
1057 
1058 /*******************************************************************************
1059  *
1060  * FUNCTION:    AcpiDbEvaluateAllPredefinedNames
1061  *
1062  * PARAMETERS:  CountArg            - Max number of methods to execute
1063  *
1064  * RETURN:      None
1065  *
1066  * DESCRIPTION: Namespace batch execution. Execute predefined names in the
1067  *              namespace, up to the max count, if specified.
1068  *
1069  ******************************************************************************/
1070 
1071 static void
1072 AcpiDbEvaluateAllPredefinedNames (
1073     char                    *CountArg)
1074 {
1075     ACPI_DB_EXECUTE_WALK    Info;
1076 
1077 
1078     Info.Count = 0;
1079     Info.MaxCount = ACPI_UINT32_MAX;
1080 
1081     if (CountArg)
1082     {
1083         Info.MaxCount = strtoul (CountArg, NULL, 0);
1084     }
1085 
1086     /* Search all nodes in namespace */
1087 
1088     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
1089         ACPI_UINT32_MAX, AcpiDbEvaluateOnePredefinedName, NULL,
1090         (void *) &Info, NULL);
1091 
1092     AcpiOsPrintf (
1093         "Evaluated %u predefined names in the namespace\n", Info.Count);
1094 }
1095 
1096 
1097 /*******************************************************************************
1098  *
1099  * FUNCTION:    AcpiDbEvaluateOnePredefinedName
1100  *
1101  * PARAMETERS:  Callback from WalkNamespace
1102  *
1103  * RETURN:      Status
1104  *
1105  * DESCRIPTION: Batch execution module. Currently only executes predefined
1106  *              ACPI names.
1107  *
1108  ******************************************************************************/
1109 
1110 static ACPI_STATUS
1111 AcpiDbEvaluateOnePredefinedName (
1112     ACPI_HANDLE             ObjHandle,
1113     UINT32                  NestingLevel,
1114     void                    *Context,
1115     void                    **ReturnValue)
1116 {
1117     ACPI_NAMESPACE_NODE         *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
1118     ACPI_DB_EXECUTE_WALK        *Info = (ACPI_DB_EXECUTE_WALK *) Context;
1119     char                        *Pathname;
1120     const ACPI_PREDEFINED_INFO  *Predefined;
1121     ACPI_DEVICE_INFO            *ObjInfo;
1122     ACPI_OBJECT_LIST            ParamObjects;
1123     ACPI_OBJECT                 Params[ACPI_METHOD_NUM_ARGS];
1124     ACPI_OBJECT                 *ThisParam;
1125     ACPI_BUFFER                 ReturnObj;
1126     ACPI_STATUS                 Status;
1127     UINT16                      ArgTypeList;
1128     UINT8                       ArgCount;
1129     UINT8                       ArgType;
1130     UINT32                      i;
1131 
1132 
1133     /* The name must be a predefined ACPI name */
1134 
1135     Predefined = AcpiUtMatchPredefinedMethod (Node->Name.Ascii);
1136     if (!Predefined)
1137     {
1138         return (AE_OK);
1139     }
1140 
1141     if (Node->Type == ACPI_TYPE_LOCAL_SCOPE)
1142     {
1143         return (AE_OK);
1144     }
1145 
1146     Pathname = AcpiNsGetNormalizedPathname (Node, TRUE);
1147     if (!Pathname)
1148     {
1149         return (AE_OK);
1150     }
1151 
1152     /* Get the object info for number of method parameters */
1153 
1154     Status = AcpiGetObjectInfo (ObjHandle, &ObjInfo);
1155     if (ACPI_FAILURE (Status))
1156     {
1157         ACPI_FREE (Pathname);
1158         return (Status);
1159     }
1160 
1161     ParamObjects.Count = 0;
1162     ParamObjects.Pointer = NULL;
1163 
1164     if (ObjInfo->Type == ACPI_TYPE_METHOD)
1165     {
1166         /* Setup default parameters (with proper types) */
1167 
1168         ArgTypeList = Predefined->Info.ArgumentList;
1169         ArgCount = METHOD_GET_ARG_COUNT (ArgTypeList);
1170 
1171         /*
1172          * Setup the ACPI-required number of arguments, regardless of what
1173          * the actual method defines. If there is a difference, then the
1174          * method is wrong and a warning will be issued during execution.
1175          */
1176         ThisParam = Params;
1177         for (i = 0; i < ArgCount; i++)
1178         {
1179             ArgType = METHOD_GET_NEXT_TYPE (ArgTypeList);
1180             ThisParam->Type = ArgType;
1181 
1182             switch (ArgType)
1183             {
1184             case ACPI_TYPE_INTEGER:
1185 
1186                 ThisParam->Integer.Value = 1;
1187                 break;
1188 
1189             case ACPI_TYPE_STRING:
1190 
1191                 ThisParam->String.Pointer =
1192                     "This is the default argument string";
1193                 ThisParam->String.Length =
1194                     strlen (ThisParam->String.Pointer);
1195                 break;
1196 
1197             case ACPI_TYPE_BUFFER:
1198 
1199                 ThisParam->Buffer.Pointer = (UINT8 *) Params; /* just a garbage buffer */
1200                 ThisParam->Buffer.Length = 48;
1201                 break;
1202 
1203              case ACPI_TYPE_PACKAGE:
1204 
1205                 ThisParam->Package.Elements = NULL;
1206                 ThisParam->Package.Count = 0;
1207                 break;
1208 
1209            default:
1210 
1211                 AcpiOsPrintf ("%s: Unsupported argument type: %u\n",
1212                     Pathname, ArgType);
1213                 break;
1214             }
1215 
1216             ThisParam++;
1217         }
1218 
1219         ParamObjects.Count = ArgCount;
1220         ParamObjects.Pointer = Params;
1221     }
1222 
1223     ACPI_FREE (ObjInfo);
1224     ReturnObj.Pointer = NULL;
1225     ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
1226 
1227     /* Do the actual method execution */
1228 
1229     AcpiGbl_MethodExecuting = TRUE;
1230 
1231     Status = AcpiEvaluateObject (Node, NULL, &ParamObjects, &ReturnObj);
1232 
1233     AcpiOsPrintf ("%-32s returned %s\n",
1234         Pathname, AcpiFormatException (Status));
1235     AcpiGbl_MethodExecuting = FALSE;
1236     ACPI_FREE (Pathname);
1237 
1238     /* Ignore status from method execution */
1239 
1240     Status = AE_OK;
1241 
1242     /* Update count, check if we have executed enough methods */
1243 
1244     Info->Count++;
1245     if (Info->Count >= Info->MaxCount)
1246     {
1247         Status = AE_CTRL_TERMINATE;
1248     }
1249 
1250     return (Status);
1251 }
1252 
1253 #endif /* ACPI_DEBUGGER */
1254