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