d88372b9253944b1479e12dbed3ffd414ad40870
[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 - 2014, 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     ACPI_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 (ACPI_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 (ACPI_MEMCMP (Temp1->Buffer.Pointer, Temp3->Buffer.Pointer, ByteLength))
699     {
700         AcpiOsPrintf (" MISMATCH 3: While restoring original buffer");
701     }
702
703 Exit:
704     ACPI_FREE (Buffer);
705     if (Temp1) {AcpiOsFree (Temp1);}
706     if (Temp2) {AcpiOsFree (Temp2);}
707     if (Temp3) {AcpiOsFree (Temp3);}
708     return (Status);
709 }
710
711
712 /*******************************************************************************
713  *
714  * FUNCTION:    AcpiDbTestStringType
715  *
716  * PARAMETERS:  Node                - Parent NS node for the object
717  *              ByteLength          - Actual length of the object.
718  *
719  * RETURN:      Status
720  *
721  * DESCRIPTION: Test read/write for an String-valued object. Performs a
722  *              write/read/compare of an arbitrary new value, then performs
723  *              a write/read/compare of the original value.
724  *
725  ******************************************************************************/
726
727 static ACPI_STATUS
728 AcpiDbTestStringType (
729     ACPI_NAMESPACE_NODE     *Node,
730     UINT32                  ByteLength)
731 {
732     ACPI_OBJECT             *Temp1 = NULL;
733     ACPI_OBJECT             *Temp2 = NULL;
734     ACPI_OBJECT             *Temp3 = NULL;
735     char                    *ValueToWrite = "Test String from AML Debugger";
736     ACPI_OBJECT             WriteValue;
737     ACPI_STATUS             Status;
738
739
740     /* Read the original value */
741
742     Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp1);
743     if (ACPI_FAILURE (Status))
744     {
745         return (Status);
746     }
747
748     AcpiOsPrintf (" (%4.4X/%3.3X) \"%s\"", (Temp1->String.Length * 8),
749         Temp1->String.Length, Temp1->String.Pointer);
750
751     /* Write a new value */
752
753     WriteValue.Type = ACPI_TYPE_STRING;
754     WriteValue.String.Length = ACPI_STRLEN (ValueToWrite);
755     WriteValue.String.Pointer = ValueToWrite;
756
757     Status = AcpiDbWriteToObject (Node, &WriteValue);
758     if (ACPI_FAILURE (Status))
759     {
760         goto Exit;
761     }
762
763     /* Ensure that we can read back the new value */
764
765     Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp2);
766     if (ACPI_FAILURE (Status))
767     {
768         goto Exit;
769     }
770
771     if (ACPI_STRCMP (Temp2->String.Pointer, ValueToWrite))
772     {
773         AcpiOsPrintf (" MISMATCH 2: %s, expecting %s",
774             Temp2->String.Pointer, ValueToWrite);
775     }
776
777     /* Write back the original value */
778
779     WriteValue.String.Length = ACPI_STRLEN (Temp1->String.Pointer);
780     WriteValue.String.Pointer = Temp1->String.Pointer;
781
782     Status = AcpiDbWriteToObject (Node, &WriteValue);
783     if (ACPI_FAILURE (Status))
784     {
785         goto Exit;
786     }
787
788     /* Ensure that we can read back the original value */
789
790     Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp3);
791     if (ACPI_FAILURE (Status))
792     {
793         goto Exit;
794     }
795
796     if (ACPI_STRCMP (Temp1->String.Pointer, Temp3->String.Pointer))
797     {
798         AcpiOsPrintf (" MISMATCH 3: %s, expecting %s",
799             Temp3->String.Pointer, Temp1->String.Pointer);
800     }
801
802 Exit:
803     if (Temp1) {AcpiOsFree (Temp1);}
804     if (Temp2) {AcpiOsFree (Temp2);}
805     if (Temp3) {AcpiOsFree (Temp3);}
806     return (Status);
807 }
808
809
810 /*******************************************************************************
811  *
812  * FUNCTION:    AcpiDbReadFromObject
813  *
814  * PARAMETERS:  Node                - Parent NS node for the object
815  *              ExpectedType        - Object type expected from the read
816  *              Value               - Where the value read is returned
817  *
818  * RETURN:      Status
819  *
820  * DESCRIPTION: Performs a read from the specified object by invoking the
821  *              special debugger control method that reads the object. Thus,
822  *              the AML interpreter is doing all of the work, increasing the
823  *              validity of the test.
824  *
825  ******************************************************************************/
826
827 static ACPI_STATUS
828 AcpiDbReadFromObject (
829     ACPI_NAMESPACE_NODE     *Node,
830     ACPI_OBJECT_TYPE        ExpectedType,
831     ACPI_OBJECT             **Value)
832 {
833     ACPI_OBJECT             *RetValue;
834     ACPI_OBJECT_LIST        ParamObjects;
835     ACPI_OBJECT             Params[2];
836     ACPI_BUFFER             ReturnObj;
837     ACPI_STATUS             Status;
838
839
840     Params[0].Type = ACPI_TYPE_LOCAL_REFERENCE;
841     Params[0].Reference.ActualType = Node->Type;
842     Params[0].Reference.Handle = ACPI_CAST_PTR (ACPI_HANDLE, Node);
843
844     ParamObjects.Count = 1;
845     ParamObjects.Pointer = Params;
846
847     ReturnObj.Length  = ACPI_ALLOCATE_BUFFER;
848
849     AcpiGbl_MethodExecuting = TRUE;
850     Status = AcpiEvaluateObject (ReadHandle, NULL, &ParamObjects, &ReturnObj);
851     AcpiGbl_MethodExecuting = FALSE;
852
853     if (ACPI_FAILURE (Status))
854     {
855         AcpiOsPrintf ("Could not read from object, %s",
856             AcpiFormatException (Status));
857         return (Status);
858     }
859
860     RetValue = (ACPI_OBJECT *) ReturnObj.Pointer;
861
862     switch (RetValue->Type)
863     {
864     case ACPI_TYPE_INTEGER:
865     case ACPI_TYPE_BUFFER:
866     case ACPI_TYPE_STRING:
867         /*
868          * Did we receive the type we wanted? Most important for the
869          * Integer/Buffer case (when a field is larger than an Integer,
870          * it should return a Buffer).
871          */
872         if (RetValue->Type != ExpectedType)
873         {
874             AcpiOsPrintf (" Type mismatch:  Expected %s, Received %s",
875                 AcpiUtGetTypeName (ExpectedType),
876                 AcpiUtGetTypeName (RetValue->Type));
877
878             return (AE_TYPE);
879         }
880
881         *Value = RetValue;
882         break;
883
884     default:
885
886         AcpiOsPrintf (" Unsupported return object type, %s",
887             AcpiUtGetTypeName (RetValue->Type));
888         AcpiOsFree (ReturnObj.Pointer);
889
890         return (AE_TYPE);
891     }
892
893     return (Status);
894 }
895
896
897 /*******************************************************************************
898  *
899  * FUNCTION:    AcpiDbWriteToObject
900  *
901  * PARAMETERS:  Node                - Parent NS node for the object
902  *              Value               - Value to be written
903  *
904  * RETURN:      Status
905  *
906  * DESCRIPTION: Performs a write to the specified object by invoking the
907  *              special debugger control method that writes the object. Thus,
908  *              the AML interpreter is doing all of the work, increasing the
909  *              validity of the test.
910  *
911  ******************************************************************************/
912
913 static ACPI_STATUS
914 AcpiDbWriteToObject (
915     ACPI_NAMESPACE_NODE     *Node,
916     ACPI_OBJECT             *Value)
917 {
918     ACPI_OBJECT_LIST        ParamObjects;
919     ACPI_OBJECT             Params[2];
920     ACPI_STATUS             Status;
921
922
923     Params[0].Type = ACPI_TYPE_LOCAL_REFERENCE;
924     Params[0].Reference.ActualType = Node->Type;
925     Params[0].Reference.Handle = ACPI_CAST_PTR (ACPI_HANDLE, Node);
926
927     /* Copy the incoming user parameter */
928
929     ACPI_MEMCPY (&Params[1], Value, sizeof (ACPI_OBJECT));
930
931     ParamObjects.Count = 2;
932     ParamObjects.Pointer = Params;
933
934     AcpiGbl_MethodExecuting = TRUE;
935     Status = AcpiEvaluateObject (WriteHandle, NULL, &ParamObjects, NULL);
936     AcpiGbl_MethodExecuting = FALSE;
937
938     if (ACPI_FAILURE (Status))
939     {
940         AcpiOsPrintf ("Could not write to object, %s",
941             AcpiFormatException (Status));
942     }
943
944     return (Status);
945 }
946
947
948 /*******************************************************************************
949  *
950  * FUNCTION:    AcpiDbEvaluateAllPredefinedNames
951  *
952  * PARAMETERS:  CountArg            - Max number of methods to execute
953  *
954  * RETURN:      None
955  *
956  * DESCRIPTION: Namespace batch execution. Execute predefined names in the
957  *              namespace, up to the max count, if specified.
958  *
959  ******************************************************************************/
960
961 static void
962 AcpiDbEvaluateAllPredefinedNames (
963     char                    *CountArg)
964 {
965     ACPI_DB_EXECUTE_WALK    Info;
966
967
968     Info.Count = 0;
969     Info.MaxCount = ACPI_UINT32_MAX;
970
971     if (CountArg)
972     {
973         Info.MaxCount = ACPI_STRTOUL (CountArg, NULL, 0);
974     }
975
976     /* Search all nodes in namespace */
977
978     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
979                 AcpiDbEvaluateOnePredefinedName, NULL, (void *) &Info, NULL);
980
981     AcpiOsPrintf ("Evaluated %u predefined names in the namespace\n", Info.Count);
982 }
983
984
985 /*******************************************************************************
986  *
987  * FUNCTION:    AcpiDbEvaluateOnePredefinedName
988  *
989  * PARAMETERS:  Callback from WalkNamespace
990  *
991  * RETURN:      Status
992  *
993  * DESCRIPTION: Batch execution module. Currently only executes predefined
994  *              ACPI names.
995  *
996  ******************************************************************************/
997
998 static ACPI_STATUS
999 AcpiDbEvaluateOnePredefinedName (
1000     ACPI_HANDLE             ObjHandle,
1001     UINT32                  NestingLevel,
1002     void                    *Context,
1003     void                    **ReturnValue)
1004 {
1005     ACPI_NAMESPACE_NODE         *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
1006     ACPI_DB_EXECUTE_WALK        *Info = (ACPI_DB_EXECUTE_WALK *) Context;
1007     char                        *Pathname;
1008     const ACPI_PREDEFINED_INFO  *Predefined;
1009     ACPI_DEVICE_INFO            *ObjInfo;
1010     ACPI_OBJECT_LIST            ParamObjects;
1011     ACPI_OBJECT                 Params[ACPI_METHOD_NUM_ARGS];
1012     ACPI_OBJECT                 *ThisParam;
1013     ACPI_BUFFER                 ReturnObj;
1014     ACPI_STATUS                 Status;
1015     UINT16                      ArgTypeList;
1016     UINT8                       ArgCount;
1017     UINT8                       ArgType;
1018     UINT32                      i;
1019
1020
1021     /* The name must be a predefined ACPI name */
1022
1023     Predefined = AcpiUtMatchPredefinedMethod (Node->Name.Ascii);
1024     if (!Predefined)
1025     {
1026         return (AE_OK);
1027     }
1028
1029     if (Node->Type == ACPI_TYPE_LOCAL_SCOPE)
1030     {
1031         return (AE_OK);
1032     }
1033
1034     Pathname = AcpiNsGetExternalPathname (Node);
1035     if (!Pathname)
1036     {
1037         return (AE_OK);
1038     }
1039
1040     /* Get the object info for number of method parameters */
1041
1042     Status = AcpiGetObjectInfo (ObjHandle, &ObjInfo);
1043     if (ACPI_FAILURE (Status))
1044     {
1045         return (Status);
1046     }
1047
1048     ParamObjects.Count = 0;
1049     ParamObjects.Pointer = NULL;
1050
1051     if (ObjInfo->Type == ACPI_TYPE_METHOD)
1052     {
1053         /* Setup default parameters (with proper types) */
1054
1055         ArgTypeList = Predefined->Info.ArgumentList;
1056         ArgCount = METHOD_GET_ARG_COUNT (ArgTypeList);
1057
1058         /*
1059          * Setup the ACPI-required number of arguments, regardless of what
1060          * the actual method defines. If there is a difference, then the
1061          * method is wrong and a warning will be issued during execution.
1062          */
1063         ThisParam = Params;
1064         for (i = 0; i < ArgCount; i++)
1065         {
1066             ArgType = METHOD_GET_NEXT_TYPE (ArgTypeList);
1067             ThisParam->Type = ArgType;
1068
1069             switch (ArgType)
1070             {
1071             case ACPI_TYPE_INTEGER:
1072
1073                 ThisParam->Integer.Value = 1;
1074                 break;
1075
1076             case ACPI_TYPE_STRING:
1077
1078                 ThisParam->String.Pointer = "This is the default argument string";
1079                 ThisParam->String.Length = ACPI_STRLEN (ThisParam->String.Pointer);
1080                 break;
1081
1082             case ACPI_TYPE_BUFFER:
1083
1084                 ThisParam->Buffer.Pointer = (UINT8 *) Params; /* just a garbage buffer */
1085                 ThisParam->Buffer.Length = 48;
1086                 break;
1087
1088              case ACPI_TYPE_PACKAGE:
1089
1090                 ThisParam->Package.Elements = NULL;
1091                 ThisParam->Package.Count = 0;
1092                 break;
1093
1094            default:
1095
1096                 AcpiOsPrintf ("%s: Unsupported argument type: %u\n",
1097                     Pathname, ArgType);
1098                 break;
1099             }
1100
1101             ThisParam++;
1102         }
1103
1104         ParamObjects.Count = ArgCount;
1105         ParamObjects.Pointer = Params;
1106     }
1107
1108     ACPI_FREE (ObjInfo);
1109     ReturnObj.Pointer = NULL;
1110     ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
1111
1112     /* Do the actual method execution */
1113
1114     AcpiGbl_MethodExecuting = TRUE;
1115
1116     Status = AcpiEvaluateObject (Node, NULL, &ParamObjects, &ReturnObj);
1117
1118     AcpiOsPrintf ("%-32s returned %s\n", Pathname, AcpiFormatException (Status));
1119     AcpiGbl_MethodExecuting = FALSE;
1120     ACPI_FREE (Pathname);
1121
1122     /* Ignore status from method execution */
1123
1124     Status = AE_OK;
1125
1126     /* Update count, check if we have executed enough methods */
1127
1128     Info->Count++;
1129     if (Info->Count >= Info->MaxCount)
1130     {
1131         Status = AE_CTRL_TERMINATE;
1132     }
1133
1134     return (Status);
1135 }
1136
1137 #endif /* ACPI_DEBUGGER */