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