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