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