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