1260659Sjkim/*******************************************************************************
2260659Sjkim *
3260659Sjkim * Module Name: dbtest - Various debug-related tests
4260659Sjkim *
5260659Sjkim ******************************************************************************/
6260659Sjkim
7260659Sjkim/*
8298714Sjkim * Copyright (C) 2000 - 2016, Intel Corp.
9260659Sjkim * All rights reserved.
10260659Sjkim *
11260659Sjkim * Redistribution and use in source and binary forms, with or without
12260659Sjkim * modification, are permitted provided that the following conditions
13260659Sjkim * are met:
14260659Sjkim * 1. Redistributions of source code must retain the above copyright
15260659Sjkim *    notice, this list of conditions, and the following disclaimer,
16260659Sjkim *    without modification.
17260659Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18260659Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19260659Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20260659Sjkim *    including a substantially similar Disclaimer requirement for further
21260659Sjkim *    binary redistribution.
22260659Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23260659Sjkim *    of any contributors may be used to endorse or promote products derived
24260659Sjkim *    from this software without specific prior written permission.
25260659Sjkim *
26260659Sjkim * Alternatively, this software may be distributed under the terms of the
27260659Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28260659Sjkim * Software Foundation.
29260659Sjkim *
30260659Sjkim * NO WARRANTY
31260659Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32260659Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33260659Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34260659Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35260659Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36260659Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37260659Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38260659Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39260659Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40260659Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41260659Sjkim * POSSIBILITY OF SUCH DAMAGES.
42260659Sjkim */
43260659Sjkim
44272444Sjkim#include <contrib/dev/acpica/include/acpi.h>
45272444Sjkim#include <contrib/dev/acpica/include/accommon.h>
46272444Sjkim#include <contrib/dev/acpica/include/acdebug.h>
47272444Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
48272444Sjkim#include <contrib/dev/acpica/include/acpredef.h>
49260659Sjkim
50260659Sjkim
51260659Sjkim#define _COMPONENT          ACPI_CA_DEBUGGER
52260659Sjkim        ACPI_MODULE_NAME    ("dbtest")
53260659Sjkim
54260659Sjkim
55260659Sjkim/* Local prototypes */
56260659Sjkim
57260659Sjkimstatic void
58260659SjkimAcpiDbTestAllObjects (
59260659Sjkim    void);
60260659Sjkim
61260659Sjkimstatic ACPI_STATUS
62260659SjkimAcpiDbTestOneObject (
63260659Sjkim    ACPI_HANDLE             ObjHandle,
64260659Sjkim    UINT32                  NestingLevel,
65260659Sjkim    void                    *Context,
66260659Sjkim    void                    **ReturnValue);
67260659Sjkim
68260659Sjkimstatic ACPI_STATUS
69260659SjkimAcpiDbTestIntegerType (
70260659Sjkim    ACPI_NAMESPACE_NODE     *Node,
71260659Sjkim    UINT32                  BitLength);
72260659Sjkim
73260659Sjkimstatic ACPI_STATUS
74260659SjkimAcpiDbTestBufferType (
75260659Sjkim    ACPI_NAMESPACE_NODE     *Node,
76260659Sjkim    UINT32                  BitLength);
77260659Sjkim
78260659Sjkimstatic ACPI_STATUS
79260659SjkimAcpiDbTestStringType (
80260659Sjkim    ACPI_NAMESPACE_NODE     *Node,
81260659Sjkim    UINT32                  ByteLength);
82260659Sjkim
83260659Sjkimstatic ACPI_STATUS
84260659SjkimAcpiDbReadFromObject (
85260659Sjkim    ACPI_NAMESPACE_NODE     *Node,
86260659Sjkim    ACPI_OBJECT_TYPE        ExpectedType,
87260659Sjkim    ACPI_OBJECT             **Value);
88260659Sjkim
89260659Sjkimstatic ACPI_STATUS
90260659SjkimAcpiDbWriteToObject (
91260659Sjkim    ACPI_NAMESPACE_NODE     *Node,
92260659Sjkim    ACPI_OBJECT             *Value);
93260659Sjkim
94260659Sjkimstatic void
95260659SjkimAcpiDbEvaluateAllPredefinedNames (
96260659Sjkim    char                    *CountArg);
97260659Sjkim
98260659Sjkimstatic ACPI_STATUS
99260659SjkimAcpiDbEvaluateOnePredefinedName (
100260659Sjkim    ACPI_HANDLE             ObjHandle,
101260659Sjkim    UINT32                  NestingLevel,
102260659Sjkim    void                    *Context,
103260659Sjkim    void                    **ReturnValue);
104260659Sjkim
105260659Sjkim/*
106260659Sjkim * Test subcommands
107260659Sjkim */
108260659Sjkimstatic ACPI_DB_ARGUMENT_INFO    AcpiDbTestTypes [] =
109260659Sjkim{
110260659Sjkim    {"OBJECTS"},
111260659Sjkim    {"PREDEFINED"},
112260659Sjkim    {NULL}           /* Must be null terminated */
113260659Sjkim};
114260659Sjkim
115260659Sjkim#define CMD_TEST_OBJECTS        0
116260659Sjkim#define CMD_TEST_PREDEFINED     1
117260659Sjkim
118260659Sjkim#define BUFFER_FILL_VALUE       0xFF
119260659Sjkim
120260659Sjkim/*
121260659Sjkim * Support for the special debugger read/write control methods.
122260659Sjkim * These methods are installed into the current namespace and are
123260659Sjkim * used to read and write the various namespace objects. The point
124260659Sjkim * is to force the AML interpreter do all of the work.
125260659Sjkim */
126287168Sjkim#define ACPI_DB_READ_METHOD     "\\_T98"
127287168Sjkim#define ACPI_DB_WRITE_METHOD    "\\_T99"
128260659Sjkim
129260659Sjkimstatic ACPI_HANDLE          ReadHandle = NULL;
130260659Sjkimstatic ACPI_HANDLE          WriteHandle = NULL;
131260659Sjkim
132260659Sjkim/* ASL Definitions of the debugger read/write control methods */
133260659Sjkim
134260659Sjkim#if 0
135260659SjkimDefinitionBlock ("ssdt.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
136260659Sjkim{
137260659Sjkim    Method (_T98, 1, NotSerialized)     /* Read */
138260659Sjkim    {
139260659Sjkim        Return (DeRefOf (Arg0))
140260659Sjkim    }
141260659Sjkim}
142260659SjkimDefinitionBlock ("ssdt2.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
143260659Sjkim{
144260659Sjkim    Method (_T99, 2, NotSerialized)     /* Write */
145260659Sjkim    {
146260659Sjkim        Store (Arg1, Arg0)
147260659Sjkim    }
148260659Sjkim}
149260659Sjkim#endif
150260659Sjkim
151260659Sjkimstatic unsigned char ReadMethodCode[] =
152260659Sjkim{
153260659Sjkim    0x53,0x53,0x44,0x54,0x2E,0x00,0x00,0x00,  /* 00000000    "SSDT...." */
154260659Sjkim    0x02,0xC9,0x49,0x6E,0x74,0x65,0x6C,0x00,  /* 00000008    "..Intel." */
155260659Sjkim    0x44,0x45,0x42,0x55,0x47,0x00,0x00,0x00,  /* 00000010    "DEBUG..." */
156260659Sjkim    0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C,  /* 00000018    "....INTL" */
157260659Sjkim    0x18,0x12,0x13,0x20,0x14,0x09,0x5F,0x54,  /* 00000020    "... .._T" */
158260659Sjkim    0x39,0x38,0x01,0xA4,0x83,0x68             /* 00000028    "98...h"   */
159260659Sjkim};
160260659Sjkim
161260659Sjkimstatic unsigned char WriteMethodCode[] =
162260659Sjkim{
163260659Sjkim    0x53,0x53,0x44,0x54,0x2E,0x00,0x00,0x00,  /* 00000000    "SSDT...." */
164260659Sjkim    0x02,0x15,0x49,0x6E,0x74,0x65,0x6C,0x00,  /* 00000008    "..Intel." */
165260659Sjkim    0x44,0x45,0x42,0x55,0x47,0x00,0x00,0x00,  /* 00000010    "DEBUG..." */
166260659Sjkim    0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C,  /* 00000018    "....INTL" */
167260659Sjkim    0x18,0x12,0x13,0x20,0x14,0x09,0x5F,0x54,  /* 00000020    "... .._T" */
168260659Sjkim    0x39,0x39,0x02,0x70,0x69,0x68             /* 00000028    "99.pih"   */
169260659Sjkim};
170260659Sjkim
171260659Sjkim
172260659Sjkim/*******************************************************************************
173260659Sjkim *
174260659Sjkim * FUNCTION:    AcpiDbExecuteTest
175260659Sjkim *
176260659Sjkim * PARAMETERS:  TypeArg         - Subcommand
177260659Sjkim *
178260659Sjkim * RETURN:      None
179260659Sjkim *
180260659Sjkim * DESCRIPTION: Execute various debug tests.
181260659Sjkim *
182260659Sjkim * Note: Code is prepared for future expansion of the TEST command.
183260659Sjkim *
184260659Sjkim ******************************************************************************/
185260659Sjkim
186260659Sjkimvoid
187260659SjkimAcpiDbExecuteTest (
188260659Sjkim    char                    *TypeArg)
189260659Sjkim{
190260659Sjkim    UINT32                  Temp;
191260659Sjkim
192260659Sjkim
193260659Sjkim    AcpiUtStrupr (TypeArg);
194260659Sjkim    Temp = AcpiDbMatchArgument (TypeArg, AcpiDbTestTypes);
195260659Sjkim    if (Temp == ACPI_TYPE_NOT_FOUND)
196260659Sjkim    {
197260659Sjkim        AcpiOsPrintf ("Invalid or unsupported argument\n");
198260659Sjkim        return;
199260659Sjkim    }
200260659Sjkim
201260659Sjkim    switch (Temp)
202260659Sjkim    {
203260659Sjkim    case CMD_TEST_OBJECTS:
204260659Sjkim
205260659Sjkim        AcpiDbTestAllObjects ();
206260659Sjkim        break;
207260659Sjkim
208260659Sjkim    case CMD_TEST_PREDEFINED:
209260659Sjkim
210260659Sjkim        AcpiDbEvaluateAllPredefinedNames (NULL);
211260659Sjkim        break;
212260659Sjkim
213260659Sjkim    default:
214260659Sjkim        break;
215260659Sjkim    }
216260659Sjkim}
217260659Sjkim
218260659Sjkim
219260659Sjkim/*******************************************************************************
220260659Sjkim *
221260659Sjkim * FUNCTION:    AcpiDbTestAllObjects
222260659Sjkim *
223260659Sjkim * PARAMETERS:  None
224260659Sjkim *
225260659Sjkim * RETURN:      None
226260659Sjkim *
227260659Sjkim * DESCRIPTION: This test implements the OBJECTS subcommand. It exercises the
228260659Sjkim *              namespace by reading/writing/comparing all data objects such
229260659Sjkim *              as integers, strings, buffers, fields, buffer fields, etc.
230260659Sjkim *
231260659Sjkim ******************************************************************************/
232260659Sjkim
233260659Sjkimstatic void
234260659SjkimAcpiDbTestAllObjects (
235260659Sjkim    void)
236260659Sjkim{
237260659Sjkim    ACPI_STATUS             Status;
238260659Sjkim
239260659Sjkim
240260659Sjkim    /* Install the debugger read-object control method if necessary */
241260659Sjkim
242260659Sjkim    if (!ReadHandle)
243260659Sjkim    {
244260659Sjkim        Status = AcpiInstallMethod (ReadMethodCode);
245260659Sjkim        if (ACPI_FAILURE (Status))
246260659Sjkim        {
247260659Sjkim            AcpiOsPrintf ("%s, Could not install debugger read method\n",
248260659Sjkim                AcpiFormatException (Status));
249260659Sjkim            return;
250260659Sjkim        }
251260659Sjkim
252260659Sjkim        Status = AcpiGetHandle (NULL, ACPI_DB_READ_METHOD, &ReadHandle);
253260659Sjkim        if (ACPI_FAILURE (Status))
254260659Sjkim        {
255260659Sjkim            AcpiOsPrintf ("Could not obtain handle for debug method %s\n",
256260659Sjkim                ACPI_DB_READ_METHOD);
257260659Sjkim            return;
258260659Sjkim        }
259260659Sjkim    }
260260659Sjkim
261260659Sjkim    /* Install the debugger write-object control method if necessary */
262260659Sjkim
263260659Sjkim    if (!WriteHandle)
264260659Sjkim    {
265260659Sjkim        Status = AcpiInstallMethod (WriteMethodCode);
266260659Sjkim        if (ACPI_FAILURE (Status))
267260659Sjkim        {
268260659Sjkim            AcpiOsPrintf ("%s, Could not install debugger write method\n",
269260659Sjkim                AcpiFormatException (Status));
270260659Sjkim            return;
271260659Sjkim        }
272260659Sjkim
273260659Sjkim        Status = AcpiGetHandle (NULL, ACPI_DB_WRITE_METHOD, &WriteHandle);
274260659Sjkim        if (ACPI_FAILURE (Status))
275260659Sjkim        {
276260659Sjkim            AcpiOsPrintf ("Could not obtain handle for debug method %s\n",
277260659Sjkim                ACPI_DB_WRITE_METHOD);
278260659Sjkim            return;
279260659Sjkim        }
280260659Sjkim    }
281260659Sjkim
282260659Sjkim    /* Walk the entire namespace, testing each supported named data object */
283260659Sjkim
284260659Sjkim    (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
285287168Sjkim        ACPI_UINT32_MAX, AcpiDbTestOneObject, NULL, NULL, NULL);
286260659Sjkim}
287260659Sjkim
288260659Sjkim
289260659Sjkim/*******************************************************************************
290260659Sjkim *
291260659Sjkim * FUNCTION:    AcpiDbTestOneObject
292260659Sjkim *
293260659Sjkim * PARAMETERS:  ACPI_WALK_CALLBACK
294260659Sjkim *
295260659Sjkim * RETURN:      Status
296260659Sjkim *
297260659Sjkim * DESCRIPTION: Test one namespace object. Supported types are Integer,
298260659Sjkim *              String, Buffer, BufferField, and FieldUnit. All other object
299260659Sjkim *              types are simply ignored.
300260659Sjkim *
301260659Sjkim *              Note: Support for Packages is not implemented.
302260659Sjkim *
303260659Sjkim ******************************************************************************/
304260659Sjkim
305260659Sjkimstatic ACPI_STATUS
306260659SjkimAcpiDbTestOneObject (
307260659Sjkim    ACPI_HANDLE             ObjHandle,
308260659Sjkim    UINT32                  NestingLevel,
309260659Sjkim    void                    *Context,
310260659Sjkim    void                    **ReturnValue)
311260659Sjkim{
312260659Sjkim    ACPI_NAMESPACE_NODE     *Node;
313260659Sjkim    ACPI_OPERAND_OBJECT     *ObjDesc;
314260659Sjkim    ACPI_OPERAND_OBJECT     *RegionObj;
315260659Sjkim    ACPI_OBJECT_TYPE        LocalType;
316260659Sjkim    UINT32                  BitLength = 0;
317260659Sjkim    UINT32                  ByteLength = 0;
318260659Sjkim    ACPI_STATUS             Status = AE_OK;
319260659Sjkim
320260659Sjkim
321260659Sjkim    Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
322260659Sjkim    ObjDesc = Node->Object;
323260659Sjkim
324260659Sjkim    /*
325260659Sjkim     * For the supported types, get the actual bit length or
326260659Sjkim     * byte length. Map the type to one of Integer/String/Buffer.
327260659Sjkim     */
328260659Sjkim    switch (Node->Type)
329260659Sjkim    {
330260659Sjkim    case ACPI_TYPE_INTEGER:
331260659Sjkim
332260659Sjkim        /* Integer width is either 32 or 64 */
333260659Sjkim
334260659Sjkim        LocalType = ACPI_TYPE_INTEGER;
335260659Sjkim        BitLength = AcpiGbl_IntegerBitWidth;
336260659Sjkim        break;
337260659Sjkim
338260659Sjkim    case ACPI_TYPE_STRING:
339260659Sjkim
340260659Sjkim        LocalType = ACPI_TYPE_STRING;
341260659Sjkim        ByteLength = ObjDesc->String.Length;
342260659Sjkim        break;
343260659Sjkim
344260659Sjkim    case ACPI_TYPE_BUFFER:
345260659Sjkim
346260659Sjkim        LocalType = ACPI_TYPE_BUFFER;
347260659Sjkim        ByteLength = ObjDesc->Buffer.Length;
348260659Sjkim        BitLength = ByteLength * 8;
349260659Sjkim        break;
350260659Sjkim
351260659Sjkim    case ACPI_TYPE_FIELD_UNIT:
352260659Sjkim    case ACPI_TYPE_BUFFER_FIELD:
353260659Sjkim    case ACPI_TYPE_LOCAL_REGION_FIELD:
354260659Sjkim    case ACPI_TYPE_LOCAL_INDEX_FIELD:
355260659Sjkim    case ACPI_TYPE_LOCAL_BANK_FIELD:
356260659Sjkim
357260659Sjkim        LocalType = ACPI_TYPE_INTEGER;
358260659Sjkim        if (ObjDesc)
359260659Sjkim        {
360260659Sjkim            /*
361260659Sjkim             * Returned object will be a Buffer if the field length
362260659Sjkim             * is larger than the size of an Integer (32 or 64 bits
363260659Sjkim             * depending on the DSDT version).
364260659Sjkim             */
365260659Sjkim            BitLength = ObjDesc->CommonField.BitLength;
366260659Sjkim            ByteLength = ACPI_ROUND_BITS_UP_TO_BYTES (BitLength);
367260659Sjkim            if (BitLength > AcpiGbl_IntegerBitWidth)
368260659Sjkim            {
369260659Sjkim                LocalType = ACPI_TYPE_BUFFER;
370260659Sjkim            }
371260659Sjkim        }
372260659Sjkim        break;
373260659Sjkim
374260659Sjkim    default:
375260659Sjkim
376260659Sjkim        /* Ignore all other types */
377260659Sjkim
378260659Sjkim        return (AE_OK);
379260659Sjkim    }
380260659Sjkim
381260659Sjkim    /* Emit the common prefix: Type:Name */
382260659Sjkim
383260659Sjkim    AcpiOsPrintf ("%14s: %4.4s",
384260659Sjkim        AcpiUtGetTypeName (Node->Type), Node->Name.Ascii);
385260659Sjkim    if (!ObjDesc)
386260659Sjkim    {
387260659Sjkim        AcpiOsPrintf (" Ignoring, no attached object\n");
388260659Sjkim        return (AE_OK);
389260659Sjkim    }
390260659Sjkim
391260659Sjkim    /*
392260659Sjkim     * Check for unsupported region types. Note: AcpiExec simulates
393260659Sjkim     * access to SystemMemory, SystemIO, PCI_Config, and EC.
394260659Sjkim     */
395260659Sjkim    switch (Node->Type)
396260659Sjkim    {
397260659Sjkim    case ACPI_TYPE_LOCAL_REGION_FIELD:
398260659Sjkim
399260659Sjkim        RegionObj = ObjDesc->Field.RegionObj;
400260659Sjkim        switch (RegionObj->Region.SpaceId)
401260659Sjkim        {
402260659Sjkim        case ACPI_ADR_SPACE_SYSTEM_MEMORY:
403260659Sjkim        case ACPI_ADR_SPACE_SYSTEM_IO:
404260659Sjkim        case ACPI_ADR_SPACE_PCI_CONFIG:
405260659Sjkim        case ACPI_ADR_SPACE_EC:
406260659Sjkim
407260659Sjkim            break;
408260659Sjkim
409260659Sjkim        default:
410260659Sjkim
411260659Sjkim            AcpiOsPrintf ("      %s space is not supported [%4.4s]\n",
412260659Sjkim                AcpiUtGetRegionName (RegionObj->Region.SpaceId),
413260659Sjkim                RegionObj->Region.Node->Name.Ascii);
414260659Sjkim            return (AE_OK);
415260659Sjkim        }
416260659Sjkim        break;
417260659Sjkim
418260659Sjkim    default:
419260659Sjkim        break;
420260659Sjkim    }
421260659Sjkim
422260659Sjkim    /* At this point, we have resolved the object to one of the major types */
423260659Sjkim
424260659Sjkim    switch (LocalType)
425260659Sjkim    {
426260659Sjkim    case ACPI_TYPE_INTEGER:
427260659Sjkim
428260659Sjkim        Status = AcpiDbTestIntegerType (Node, BitLength);
429260659Sjkim        break;
430260659Sjkim
431260659Sjkim    case ACPI_TYPE_STRING:
432260659Sjkim
433260659Sjkim        Status = AcpiDbTestStringType (Node, ByteLength);
434260659Sjkim        break;
435260659Sjkim
436260659Sjkim    case ACPI_TYPE_BUFFER:
437260659Sjkim
438260659Sjkim        Status = AcpiDbTestBufferType (Node, BitLength);
439260659Sjkim        break;
440260659Sjkim
441260659Sjkim    default:
442260659Sjkim
443260659Sjkim        AcpiOsPrintf (" Ignoring, type not implemented (%2.2X)",
444260659Sjkim            LocalType);
445260659Sjkim        break;
446260659Sjkim    }
447260659Sjkim
448260659Sjkim    switch (Node->Type)
449260659Sjkim    {
450260659Sjkim    case ACPI_TYPE_LOCAL_REGION_FIELD:
451260659Sjkim
452260659Sjkim        RegionObj = ObjDesc->Field.RegionObj;
453260659Sjkim        AcpiOsPrintf (" (%s)",
454260659Sjkim            AcpiUtGetRegionName (RegionObj->Region.SpaceId));
455260659Sjkim        break;
456260659Sjkim
457260659Sjkim    default:
458260659Sjkim        break;
459260659Sjkim    }
460260659Sjkim
461260659Sjkim    AcpiOsPrintf ("\n");
462260659Sjkim    return (Status);
463260659Sjkim}
464260659Sjkim
465260659Sjkim
466260659Sjkim/*******************************************************************************
467260659Sjkim *
468260659Sjkim * FUNCTION:    AcpiDbTestIntegerType
469260659Sjkim *
470260659Sjkim * PARAMETERS:  Node                - Parent NS node for the object
471260659Sjkim *              BitLength           - Actual length of the object. Used for
472260659Sjkim *                                    support of arbitrary length FieldUnit
473260659Sjkim *                                    and BufferField objects.
474260659Sjkim *
475260659Sjkim * RETURN:      Status
476260659Sjkim *
477260659Sjkim * DESCRIPTION: Test read/write for an Integer-valued object. Performs a
478260659Sjkim *              write/read/compare of an arbitrary new value, then performs
479260659Sjkim *              a write/read/compare of the original value.
480260659Sjkim *
481260659Sjkim ******************************************************************************/
482260659Sjkim
483260659Sjkimstatic ACPI_STATUS
484260659SjkimAcpiDbTestIntegerType (
485260659Sjkim    ACPI_NAMESPACE_NODE     *Node,
486260659Sjkim    UINT32                  BitLength)
487260659Sjkim{
488260659Sjkim    ACPI_OBJECT             *Temp1 = NULL;
489260659Sjkim    ACPI_OBJECT             *Temp2 = NULL;
490260659Sjkim    ACPI_OBJECT             *Temp3 = NULL;
491260659Sjkim    ACPI_OBJECT             WriteValue;
492260659Sjkim    UINT64                  ValueToWrite;
493260659Sjkim    ACPI_STATUS             Status;
494260659Sjkim
495260659Sjkim
496260659Sjkim    if (BitLength > 64)
497260659Sjkim    {
498260659Sjkim        AcpiOsPrintf (" Invalid length for an Integer: %u", BitLength);
499260659Sjkim        return (AE_OK);
500260659Sjkim    }
501260659Sjkim
502260659Sjkim    /* Read the original value */
503260659Sjkim
504260659Sjkim    Status = AcpiDbReadFromObject (Node, ACPI_TYPE_INTEGER, &Temp1);
505260659Sjkim    if (ACPI_FAILURE (Status))
506260659Sjkim    {
507260659Sjkim        return (Status);
508260659Sjkim    }
509260659Sjkim
510260659Sjkim    AcpiOsPrintf (" (%4.4X/%3.3X) %8.8X%8.8X",
511260659Sjkim        BitLength, ACPI_ROUND_BITS_UP_TO_BYTES (BitLength),
512260659Sjkim        ACPI_FORMAT_UINT64 (Temp1->Integer.Value));
513260659Sjkim
514260659Sjkim    ValueToWrite = ACPI_UINT64_MAX >> (64 - BitLength);
515260659Sjkim    if (Temp1->Integer.Value == ValueToWrite)
516260659Sjkim    {
517260659Sjkim        ValueToWrite = 0;
518260659Sjkim    }
519260659Sjkim
520260659Sjkim    /* Write a new value */
521260659Sjkim
522260659Sjkim    WriteValue.Type = ACPI_TYPE_INTEGER;
523260659Sjkim    WriteValue.Integer.Value = ValueToWrite;
524260659Sjkim    Status = AcpiDbWriteToObject (Node, &WriteValue);
525260659Sjkim    if (ACPI_FAILURE (Status))
526260659Sjkim    {
527260659Sjkim        goto Exit;
528260659Sjkim    }
529260659Sjkim
530260659Sjkim    /* Ensure that we can read back the new value */
531260659Sjkim
532260659Sjkim    Status = AcpiDbReadFromObject (Node, ACPI_TYPE_INTEGER, &Temp2);
533260659Sjkim    if (ACPI_FAILURE (Status))
534260659Sjkim    {
535260659Sjkim        goto Exit;
536260659Sjkim    }
537260659Sjkim
538260659Sjkim    if (Temp2->Integer.Value != ValueToWrite)
539260659Sjkim    {
540260659Sjkim        AcpiOsPrintf (" MISMATCH 2: %8.8X%8.8X, expecting %8.8X%8.8X",
541260659Sjkim            ACPI_FORMAT_UINT64 (Temp2->Integer.Value),
542260659Sjkim            ACPI_FORMAT_UINT64 (ValueToWrite));
543260659Sjkim    }
544260659Sjkim
545260659Sjkim    /* Write back the original value */
546260659Sjkim
547260659Sjkim    WriteValue.Integer.Value = Temp1->Integer.Value;
548260659Sjkim    Status = AcpiDbWriteToObject (Node, &WriteValue);
549260659Sjkim    if (ACPI_FAILURE (Status))
550260659Sjkim    {
551260659Sjkim        goto Exit;
552260659Sjkim    }
553260659Sjkim
554260659Sjkim    /* Ensure that we can read back the original value */
555260659Sjkim
556260659Sjkim    Status = AcpiDbReadFromObject (Node, ACPI_TYPE_INTEGER, &Temp3);
557260659Sjkim    if (ACPI_FAILURE (Status))
558260659Sjkim    {
559260659Sjkim        goto Exit;
560260659Sjkim    }
561260659Sjkim
562260659Sjkim    if (Temp3->Integer.Value != Temp1->Integer.Value)
563260659Sjkim    {
564260659Sjkim        AcpiOsPrintf (" MISMATCH 3: %8.8X%8.8X, expecting %8.8X%8.8X",
565260659Sjkim            ACPI_FORMAT_UINT64 (Temp3->Integer.Value),
566260659Sjkim            ACPI_FORMAT_UINT64 (Temp1->Integer.Value));
567260659Sjkim    }
568260659Sjkim
569260659SjkimExit:
570260659Sjkim    if (Temp1) {AcpiOsFree (Temp1);}
571260659Sjkim    if (Temp2) {AcpiOsFree (Temp2);}
572260659Sjkim    if (Temp3) {AcpiOsFree (Temp3);}
573260659Sjkim    return (AE_OK);
574260659Sjkim}
575260659Sjkim
576260659Sjkim
577260659Sjkim/*******************************************************************************
578260659Sjkim *
579260659Sjkim * FUNCTION:    AcpiDbTestBufferType
580260659Sjkim *
581260659Sjkim * PARAMETERS:  Node                - Parent NS node for the object
582260659Sjkim *              BitLength           - Actual length of the object.
583260659Sjkim *
584260659Sjkim * RETURN:      Status
585260659Sjkim *
586260659Sjkim * DESCRIPTION: Test read/write for an Buffer-valued object. Performs a
587260659Sjkim *              write/read/compare of an arbitrary new value, then performs
588260659Sjkim *              a write/read/compare of the original value.
589260659Sjkim *
590260659Sjkim ******************************************************************************/
591260659Sjkim
592260659Sjkimstatic ACPI_STATUS
593260659SjkimAcpiDbTestBufferType (
594260659Sjkim    ACPI_NAMESPACE_NODE     *Node,
595260659Sjkim    UINT32                  BitLength)
596260659Sjkim{
597260659Sjkim    ACPI_OBJECT             *Temp1 = NULL;
598260659Sjkim    ACPI_OBJECT             *Temp2 = NULL;
599260659Sjkim    ACPI_OBJECT             *Temp3 = NULL;
600260659Sjkim    UINT8                   *Buffer;
601260659Sjkim    ACPI_OBJECT             WriteValue;
602260659Sjkim    ACPI_STATUS             Status;
603260659Sjkim    UINT32                  ByteLength;
604260659Sjkim    UINT32                  i;
605260659Sjkim    UINT8                   ExtraBits;
606260659Sjkim
607260659Sjkim
608260659Sjkim    ByteLength = ACPI_ROUND_BITS_UP_TO_BYTES (BitLength);
609260659Sjkim    if (ByteLength == 0)
610260659Sjkim    {
611260659Sjkim        AcpiOsPrintf (" Ignoring zero length buffer");
612260659Sjkim        return (AE_OK);
613260659Sjkim    }
614260659Sjkim
615260659Sjkim    /* Allocate a local buffer */
616260659Sjkim
617260659Sjkim    Buffer = ACPI_ALLOCATE_ZEROED (ByteLength);
618260659Sjkim    if (!Buffer)
619260659Sjkim    {
620260659Sjkim        return (AE_NO_MEMORY);
621260659Sjkim    }
622260659Sjkim
623260659Sjkim    /* Read the original value */
624260659Sjkim
625260659Sjkim    Status = AcpiDbReadFromObject (Node, ACPI_TYPE_BUFFER, &Temp1);
626260659Sjkim    if (ACPI_FAILURE (Status))
627260659Sjkim    {
628260659Sjkim        goto Exit;
629260659Sjkim    }
630260659Sjkim
631260659Sjkim    /* Emit a few bytes of the buffer */
632260659Sjkim
633260659Sjkim    AcpiOsPrintf (" (%4.4X/%3.3X)", BitLength, Temp1->Buffer.Length);
634260659Sjkim    for (i = 0; ((i < 4) && (i < ByteLength)); i++)
635260659Sjkim    {
636260659Sjkim        AcpiOsPrintf (" %2.2X", Temp1->Buffer.Pointer[i]);
637260659Sjkim    }
638260659Sjkim    AcpiOsPrintf ("...  ");
639260659Sjkim
640260659Sjkim    /*
641260659Sjkim     * Write a new value.
642260659Sjkim     *
643260659Sjkim     * Handle possible extra bits at the end of the buffer. Can
644260659Sjkim     * happen for FieldUnits larger than an integer, but the bit
645260659Sjkim     * count is not an integral number of bytes. Zero out the
646260659Sjkim     * unused bits.
647260659Sjkim     */
648284583Sjkim    memset (Buffer, BUFFER_FILL_VALUE, ByteLength);
649260659Sjkim    ExtraBits = BitLength % 8;
650260659Sjkim    if (ExtraBits)
651260659Sjkim    {
652260659Sjkim        Buffer [ByteLength - 1] = ACPI_MASK_BITS_ABOVE (ExtraBits);
653260659Sjkim    }
654260659Sjkim
655260659Sjkim    WriteValue.Type = ACPI_TYPE_BUFFER;
656260659Sjkim    WriteValue.Buffer.Length = ByteLength;
657260659Sjkim    WriteValue.Buffer.Pointer = Buffer;
658260659Sjkim
659260659Sjkim    Status = AcpiDbWriteToObject (Node, &WriteValue);
660260659Sjkim    if (ACPI_FAILURE (Status))
661260659Sjkim    {
662260659Sjkim        goto Exit;
663260659Sjkim    }
664260659Sjkim
665260659Sjkim    /* Ensure that we can read back the new value */
666260659Sjkim
667260659Sjkim    Status = AcpiDbReadFromObject (Node, ACPI_TYPE_BUFFER, &Temp2);
668260659Sjkim    if (ACPI_FAILURE (Status))
669260659Sjkim    {
670260659Sjkim        goto Exit;
671260659Sjkim    }
672260659Sjkim
673284583Sjkim    if (memcmp (Temp2->Buffer.Pointer, Buffer, ByteLength))
674260659Sjkim    {
675260659Sjkim        AcpiOsPrintf (" MISMATCH 2: New buffer value");
676260659Sjkim    }
677260659Sjkim
678260659Sjkim    /* Write back the original value */
679260659Sjkim
680260659Sjkim    WriteValue.Buffer.Length = ByteLength;
681260659Sjkim    WriteValue.Buffer.Pointer = Temp1->Buffer.Pointer;
682260659Sjkim
683260659Sjkim    Status = AcpiDbWriteToObject (Node, &WriteValue);
684260659Sjkim    if (ACPI_FAILURE (Status))
685260659Sjkim    {
686260659Sjkim        goto Exit;
687260659Sjkim    }
688260659Sjkim
689260659Sjkim    /* Ensure that we can read back the original value */
690260659Sjkim
691260659Sjkim    Status = AcpiDbReadFromObject (Node, ACPI_TYPE_BUFFER, &Temp3);
692260659Sjkim    if (ACPI_FAILURE (Status))
693260659Sjkim    {
694260659Sjkim        goto Exit;
695260659Sjkim    }
696260659Sjkim
697287168Sjkim    if (memcmp (Temp1->Buffer.Pointer,
698287168Sjkim            Temp3->Buffer.Pointer, ByteLength))
699260659Sjkim    {
700260659Sjkim        AcpiOsPrintf (" MISMATCH 3: While restoring original buffer");
701260659Sjkim    }
702260659Sjkim
703260659SjkimExit:
704260659Sjkim    ACPI_FREE (Buffer);
705260659Sjkim    if (Temp1) {AcpiOsFree (Temp1);}
706260659Sjkim    if (Temp2) {AcpiOsFree (Temp2);}
707260659Sjkim    if (Temp3) {AcpiOsFree (Temp3);}
708260659Sjkim    return (Status);
709260659Sjkim}
710260659Sjkim
711260659Sjkim
712260659Sjkim/*******************************************************************************
713260659Sjkim *
714260659Sjkim * FUNCTION:    AcpiDbTestStringType
715260659Sjkim *
716260659Sjkim * PARAMETERS:  Node                - Parent NS node for the object
717260659Sjkim *              ByteLength          - Actual length of the object.
718260659Sjkim *
719260659Sjkim * RETURN:      Status
720260659Sjkim *
721260659Sjkim * DESCRIPTION: Test read/write for an String-valued object. Performs a
722260659Sjkim *              write/read/compare of an arbitrary new value, then performs
723260659Sjkim *              a write/read/compare of the original value.
724260659Sjkim *
725260659Sjkim ******************************************************************************/
726260659Sjkim
727260659Sjkimstatic ACPI_STATUS
728260659SjkimAcpiDbTestStringType (
729260659Sjkim    ACPI_NAMESPACE_NODE     *Node,
730260659Sjkim    UINT32                  ByteLength)
731260659Sjkim{
732260659Sjkim    ACPI_OBJECT             *Temp1 = NULL;
733260659Sjkim    ACPI_OBJECT             *Temp2 = NULL;
734260659Sjkim    ACPI_OBJECT             *Temp3 = NULL;
735260659Sjkim    char                    *ValueToWrite = "Test String from AML Debugger";
736260659Sjkim    ACPI_OBJECT             WriteValue;
737260659Sjkim    ACPI_STATUS             Status;
738260659Sjkim
739260659Sjkim
740260659Sjkim    /* Read the original value */
741260659Sjkim
742260659Sjkim    Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp1);
743260659Sjkim    if (ACPI_FAILURE (Status))
744260659Sjkim    {
745260659Sjkim        return (Status);
746260659Sjkim    }
747260659Sjkim
748260659Sjkim    AcpiOsPrintf (" (%4.4X/%3.3X) \"%s\"", (Temp1->String.Length * 8),
749260659Sjkim        Temp1->String.Length, Temp1->String.Pointer);
750260659Sjkim
751260659Sjkim    /* Write a new value */
752260659Sjkim
753260659Sjkim    WriteValue.Type = ACPI_TYPE_STRING;
754284583Sjkim    WriteValue.String.Length = strlen (ValueToWrite);
755260659Sjkim    WriteValue.String.Pointer = ValueToWrite;
756260659Sjkim
757260659Sjkim    Status = AcpiDbWriteToObject (Node, &WriteValue);
758260659Sjkim    if (ACPI_FAILURE (Status))
759260659Sjkim    {
760260659Sjkim        goto Exit;
761260659Sjkim    }
762260659Sjkim
763260659Sjkim    /* Ensure that we can read back the new value */
764260659Sjkim
765260659Sjkim    Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp2);
766260659Sjkim    if (ACPI_FAILURE (Status))
767260659Sjkim    {
768260659Sjkim        goto Exit;
769260659Sjkim    }
770260659Sjkim
771284583Sjkim    if (strcmp (Temp2->String.Pointer, ValueToWrite))
772260659Sjkim    {
773260659Sjkim        AcpiOsPrintf (" MISMATCH 2: %s, expecting %s",
774260659Sjkim            Temp2->String.Pointer, ValueToWrite);
775260659Sjkim    }
776260659Sjkim
777260659Sjkim    /* Write back the original value */
778260659Sjkim
779284583Sjkim    WriteValue.String.Length = strlen (Temp1->String.Pointer);
780260659Sjkim    WriteValue.String.Pointer = Temp1->String.Pointer;
781260659Sjkim
782260659Sjkim    Status = AcpiDbWriteToObject (Node, &WriteValue);
783260659Sjkim    if (ACPI_FAILURE (Status))
784260659Sjkim    {
785260659Sjkim        goto Exit;
786260659Sjkim    }
787260659Sjkim
788260659Sjkim    /* Ensure that we can read back the original value */
789260659Sjkim
790260659Sjkim    Status = AcpiDbReadFromObject (Node, ACPI_TYPE_STRING, &Temp3);
791260659Sjkim    if (ACPI_FAILURE (Status))
792260659Sjkim    {
793260659Sjkim        goto Exit;
794260659Sjkim    }
795260659Sjkim
796284583Sjkim    if (strcmp (Temp1->String.Pointer, Temp3->String.Pointer))
797260659Sjkim    {
798260659Sjkim        AcpiOsPrintf (" MISMATCH 3: %s, expecting %s",
799260659Sjkim            Temp3->String.Pointer, Temp1->String.Pointer);
800260659Sjkim    }
801260659Sjkim
802260659SjkimExit:
803260659Sjkim    if (Temp1) {AcpiOsFree (Temp1);}
804260659Sjkim    if (Temp2) {AcpiOsFree (Temp2);}
805260659Sjkim    if (Temp3) {AcpiOsFree (Temp3);}
806260659Sjkim    return (Status);
807260659Sjkim}
808260659Sjkim
809260659Sjkim
810260659Sjkim/*******************************************************************************
811260659Sjkim *
812260659Sjkim * FUNCTION:    AcpiDbReadFromObject
813260659Sjkim *
814260659Sjkim * PARAMETERS:  Node                - Parent NS node for the object
815260659Sjkim *              ExpectedType        - Object type expected from the read
816260659Sjkim *              Value               - Where the value read is returned
817260659Sjkim *
818260659Sjkim * RETURN:      Status
819260659Sjkim *
820260659Sjkim * DESCRIPTION: Performs a read from the specified object by invoking the
821260659Sjkim *              special debugger control method that reads the object. Thus,
822260659Sjkim *              the AML interpreter is doing all of the work, increasing the
823260659Sjkim *              validity of the test.
824260659Sjkim *
825260659Sjkim ******************************************************************************/
826260659Sjkim
827260659Sjkimstatic ACPI_STATUS
828260659SjkimAcpiDbReadFromObject (
829260659Sjkim    ACPI_NAMESPACE_NODE     *Node,
830260659Sjkim    ACPI_OBJECT_TYPE        ExpectedType,
831260659Sjkim    ACPI_OBJECT             **Value)
832260659Sjkim{
833260659Sjkim    ACPI_OBJECT             *RetValue;
834260659Sjkim    ACPI_OBJECT_LIST        ParamObjects;
835260659Sjkim    ACPI_OBJECT             Params[2];
836260659Sjkim    ACPI_BUFFER             ReturnObj;
837260659Sjkim    ACPI_STATUS             Status;
838260659Sjkim
839260659Sjkim
840260659Sjkim    Params[0].Type = ACPI_TYPE_LOCAL_REFERENCE;
841260659Sjkim    Params[0].Reference.ActualType = Node->Type;
842260659Sjkim    Params[0].Reference.Handle = ACPI_CAST_PTR (ACPI_HANDLE, Node);
843260659Sjkim
844260659Sjkim    ParamObjects.Count = 1;
845260659Sjkim    ParamObjects.Pointer = Params;
846260659Sjkim
847260659Sjkim    ReturnObj.Length  = ACPI_ALLOCATE_BUFFER;
848260659Sjkim
849260659Sjkim    AcpiGbl_MethodExecuting = TRUE;
850287168Sjkim    Status = AcpiEvaluateObject (ReadHandle, NULL,
851287168Sjkim        &ParamObjects, &ReturnObj);
852260659Sjkim    AcpiGbl_MethodExecuting = FALSE;
853260659Sjkim
854260659Sjkim    if (ACPI_FAILURE (Status))
855260659Sjkim    {
856260659Sjkim        AcpiOsPrintf ("Could not read from object, %s",
857260659Sjkim            AcpiFormatException (Status));
858260659Sjkim        return (Status);
859260659Sjkim    }
860260659Sjkim
861260659Sjkim    RetValue = (ACPI_OBJECT *) ReturnObj.Pointer;
862260659Sjkim
863260659Sjkim    switch (RetValue->Type)
864260659Sjkim    {
865260659Sjkim    case ACPI_TYPE_INTEGER:
866260659Sjkim    case ACPI_TYPE_BUFFER:
867260659Sjkim    case ACPI_TYPE_STRING:
868260659Sjkim        /*
869260659Sjkim         * Did we receive the type we wanted? Most important for the
870260659Sjkim         * Integer/Buffer case (when a field is larger than an Integer,
871260659Sjkim         * it should return a Buffer).
872260659Sjkim         */
873260659Sjkim        if (RetValue->Type != ExpectedType)
874260659Sjkim        {
875260659Sjkim            AcpiOsPrintf (" Type mismatch:  Expected %s, Received %s",
876260659Sjkim                AcpiUtGetTypeName (ExpectedType),
877260659Sjkim                AcpiUtGetTypeName (RetValue->Type));
878260659Sjkim
879260659Sjkim            return (AE_TYPE);
880260659Sjkim        }
881260659Sjkim
882260659Sjkim        *Value = RetValue;
883260659Sjkim        break;
884260659Sjkim
885260659Sjkim    default:
886260659Sjkim
887260659Sjkim        AcpiOsPrintf (" Unsupported return object type, %s",
888260659Sjkim            AcpiUtGetTypeName (RetValue->Type));
889287168Sjkim
890260659Sjkim        AcpiOsFree (ReturnObj.Pointer);
891260659Sjkim        return (AE_TYPE);
892260659Sjkim    }
893260659Sjkim
894260659Sjkim    return (Status);
895260659Sjkim}
896260659Sjkim
897260659Sjkim
898260659Sjkim/*******************************************************************************
899260659Sjkim *
900260659Sjkim * FUNCTION:    AcpiDbWriteToObject
901260659Sjkim *
902260659Sjkim * PARAMETERS:  Node                - Parent NS node for the object
903260659Sjkim *              Value               - Value to be written
904260659Sjkim *
905260659Sjkim * RETURN:      Status
906260659Sjkim *
907260659Sjkim * DESCRIPTION: Performs a write to the specified object by invoking the
908260659Sjkim *              special debugger control method that writes the object. Thus,
909260659Sjkim *              the AML interpreter is doing all of the work, increasing the
910260659Sjkim *              validity of the test.
911260659Sjkim *
912260659Sjkim ******************************************************************************/
913260659Sjkim
914260659Sjkimstatic ACPI_STATUS
915260659SjkimAcpiDbWriteToObject (
916260659Sjkim    ACPI_NAMESPACE_NODE     *Node,
917260659Sjkim    ACPI_OBJECT             *Value)
918260659Sjkim{
919260659Sjkim    ACPI_OBJECT_LIST        ParamObjects;
920260659Sjkim    ACPI_OBJECT             Params[2];
921260659Sjkim    ACPI_STATUS             Status;
922260659Sjkim
923260659Sjkim
924260659Sjkim    Params[0].Type = ACPI_TYPE_LOCAL_REFERENCE;
925260659Sjkim    Params[0].Reference.ActualType = Node->Type;
926260659Sjkim    Params[0].Reference.Handle = ACPI_CAST_PTR (ACPI_HANDLE, Node);
927260659Sjkim
928260659Sjkim    /* Copy the incoming user parameter */
929260659Sjkim
930284583Sjkim    memcpy (&Params[1], Value, sizeof (ACPI_OBJECT));
931260659Sjkim
932260659Sjkim    ParamObjects.Count = 2;
933260659Sjkim    ParamObjects.Pointer = Params;
934260659Sjkim
935260659Sjkim    AcpiGbl_MethodExecuting = TRUE;
936260659Sjkim    Status = AcpiEvaluateObject (WriteHandle, NULL, &ParamObjects, NULL);
937260659Sjkim    AcpiGbl_MethodExecuting = FALSE;
938260659Sjkim
939260659Sjkim    if (ACPI_FAILURE (Status))
940260659Sjkim    {
941260659Sjkim        AcpiOsPrintf ("Could not write to object, %s",
942260659Sjkim            AcpiFormatException (Status));
943260659Sjkim    }
944260659Sjkim
945260659Sjkim    return (Status);
946260659Sjkim}
947260659Sjkim
948260659Sjkim
949260659Sjkim/*******************************************************************************
950260659Sjkim *
951260659Sjkim * FUNCTION:    AcpiDbEvaluateAllPredefinedNames
952260659Sjkim *
953260659Sjkim * PARAMETERS:  CountArg            - Max number of methods to execute
954260659Sjkim *
955260659Sjkim * RETURN:      None
956260659Sjkim *
957260659Sjkim * DESCRIPTION: Namespace batch execution. Execute predefined names in the
958260659Sjkim *              namespace, up to the max count, if specified.
959260659Sjkim *
960260659Sjkim ******************************************************************************/
961260659Sjkim
962260659Sjkimstatic void
963260659SjkimAcpiDbEvaluateAllPredefinedNames (
964260659Sjkim    char                    *CountArg)
965260659Sjkim{
966260659Sjkim    ACPI_DB_EXECUTE_WALK    Info;
967260659Sjkim
968260659Sjkim
969260659Sjkim    Info.Count = 0;
970260659Sjkim    Info.MaxCount = ACPI_UINT32_MAX;
971260659Sjkim
972260659Sjkim    if (CountArg)
973260659Sjkim    {
974284583Sjkim        Info.MaxCount = strtoul (CountArg, NULL, 0);
975260659Sjkim    }
976260659Sjkim
977260659Sjkim    /* Search all nodes in namespace */
978260659Sjkim
979287168Sjkim    (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
980287168Sjkim        ACPI_UINT32_MAX, AcpiDbEvaluateOnePredefinedName, NULL,
981287168Sjkim        (void *) &Info, NULL);
982260659Sjkim
983298714Sjkim    AcpiOsPrintf (
984298714Sjkim        "Evaluated %u predefined names in the namespace\n", Info.Count);
985260659Sjkim}
986260659Sjkim
987260659Sjkim
988260659Sjkim/*******************************************************************************
989260659Sjkim *
990260659Sjkim * FUNCTION:    AcpiDbEvaluateOnePredefinedName
991260659Sjkim *
992260659Sjkim * PARAMETERS:  Callback from WalkNamespace
993260659Sjkim *
994260659Sjkim * RETURN:      Status
995260659Sjkim *
996260659Sjkim * DESCRIPTION: Batch execution module. Currently only executes predefined
997260659Sjkim *              ACPI names.
998260659Sjkim *
999260659Sjkim ******************************************************************************/
1000260659Sjkim
1001260659Sjkimstatic ACPI_STATUS
1002260659SjkimAcpiDbEvaluateOnePredefinedName (
1003260659Sjkim    ACPI_HANDLE             ObjHandle,
1004260659Sjkim    UINT32                  NestingLevel,
1005260659Sjkim    void                    *Context,
1006260659Sjkim    void                    **ReturnValue)
1007260659Sjkim{
1008260659Sjkim    ACPI_NAMESPACE_NODE         *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
1009260659Sjkim    ACPI_DB_EXECUTE_WALK        *Info = (ACPI_DB_EXECUTE_WALK *) Context;
1010260659Sjkim    char                        *Pathname;
1011260659Sjkim    const ACPI_PREDEFINED_INFO  *Predefined;
1012260659Sjkim    ACPI_DEVICE_INFO            *ObjInfo;
1013260659Sjkim    ACPI_OBJECT_LIST            ParamObjects;
1014260659Sjkim    ACPI_OBJECT                 Params[ACPI_METHOD_NUM_ARGS];
1015260659Sjkim    ACPI_OBJECT                 *ThisParam;
1016260659Sjkim    ACPI_BUFFER                 ReturnObj;
1017260659Sjkim    ACPI_STATUS                 Status;
1018260659Sjkim    UINT16                      ArgTypeList;
1019260659Sjkim    UINT8                       ArgCount;
1020260659Sjkim    UINT8                       ArgType;
1021260659Sjkim    UINT32                      i;
1022260659Sjkim
1023260659Sjkim
1024260659Sjkim    /* The name must be a predefined ACPI name */
1025260659Sjkim
1026260659Sjkim    Predefined = AcpiUtMatchPredefinedMethod (Node->Name.Ascii);
1027260659Sjkim    if (!Predefined)
1028260659Sjkim    {
1029260659Sjkim        return (AE_OK);
1030260659Sjkim    }
1031260659Sjkim
1032260659Sjkim    if (Node->Type == ACPI_TYPE_LOCAL_SCOPE)
1033260659Sjkim    {
1034260659Sjkim        return (AE_OK);
1035260659Sjkim    }
1036260659Sjkim
1037298714Sjkim    Pathname = AcpiNsGetNormalizedPathname (Node, TRUE);
1038260659Sjkim    if (!Pathname)
1039260659Sjkim    {
1040260659Sjkim        return (AE_OK);
1041260659Sjkim    }
1042260659Sjkim
1043260659Sjkim    /* Get the object info for number of method parameters */
1044260659Sjkim
1045260659Sjkim    Status = AcpiGetObjectInfo (ObjHandle, &ObjInfo);
1046260659Sjkim    if (ACPI_FAILURE (Status))
1047260659Sjkim    {
1048272444Sjkim        ACPI_FREE (Pathname);
1049260659Sjkim        return (Status);
1050260659Sjkim    }
1051260659Sjkim
1052260659Sjkim    ParamObjects.Count = 0;
1053260659Sjkim    ParamObjects.Pointer = NULL;
1054260659Sjkim
1055260659Sjkim    if (ObjInfo->Type == ACPI_TYPE_METHOD)
1056260659Sjkim    {
1057260659Sjkim        /* Setup default parameters (with proper types) */
1058260659Sjkim
1059260659Sjkim        ArgTypeList = Predefined->Info.ArgumentList;
1060260659Sjkim        ArgCount = METHOD_GET_ARG_COUNT (ArgTypeList);
1061260659Sjkim
1062260659Sjkim        /*
1063260659Sjkim         * Setup the ACPI-required number of arguments, regardless of what
1064260659Sjkim         * the actual method defines. If there is a difference, then the
1065260659Sjkim         * method is wrong and a warning will be issued during execution.
1066260659Sjkim         */
1067260659Sjkim        ThisParam = Params;
1068260659Sjkim        for (i = 0; i < ArgCount; i++)
1069260659Sjkim        {
1070260659Sjkim            ArgType = METHOD_GET_NEXT_TYPE (ArgTypeList);
1071260659Sjkim            ThisParam->Type = ArgType;
1072260659Sjkim
1073260659Sjkim            switch (ArgType)
1074260659Sjkim            {
1075260659Sjkim            case ACPI_TYPE_INTEGER:
1076260659Sjkim
1077260659Sjkim                ThisParam->Integer.Value = 1;
1078260659Sjkim                break;
1079260659Sjkim
1080260659Sjkim            case ACPI_TYPE_STRING:
1081260659Sjkim
1082287168Sjkim                ThisParam->String.Pointer =
1083287168Sjkim                    "This is the default argument string";
1084287168Sjkim                ThisParam->String.Length =
1085287168Sjkim                    strlen (ThisParam->String.Pointer);
1086260659Sjkim                break;
1087260659Sjkim
1088260659Sjkim            case ACPI_TYPE_BUFFER:
1089260659Sjkim
1090260659Sjkim                ThisParam->Buffer.Pointer = (UINT8 *) Params; /* just a garbage buffer */
1091260659Sjkim                ThisParam->Buffer.Length = 48;
1092260659Sjkim                break;
1093260659Sjkim
1094260659Sjkim             case ACPI_TYPE_PACKAGE:
1095260659Sjkim
1096260659Sjkim                ThisParam->Package.Elements = NULL;
1097260659Sjkim                ThisParam->Package.Count = 0;
1098260659Sjkim                break;
1099260659Sjkim
1100260659Sjkim           default:
1101260659Sjkim
1102260659Sjkim                AcpiOsPrintf ("%s: Unsupported argument type: %u\n",
1103260659Sjkim                    Pathname, ArgType);
1104260659Sjkim                break;
1105260659Sjkim            }
1106260659Sjkim
1107260659Sjkim            ThisParam++;
1108260659Sjkim        }
1109260659Sjkim
1110260659Sjkim        ParamObjects.Count = ArgCount;
1111260659Sjkim        ParamObjects.Pointer = Params;
1112260659Sjkim    }
1113260659Sjkim
1114260659Sjkim    ACPI_FREE (ObjInfo);
1115260659Sjkim    ReturnObj.Pointer = NULL;
1116260659Sjkim    ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
1117260659Sjkim
1118260659Sjkim    /* Do the actual method execution */
1119260659Sjkim
1120260659Sjkim    AcpiGbl_MethodExecuting = TRUE;
1121260659Sjkim
1122260659Sjkim    Status = AcpiEvaluateObject (Node, NULL, &ParamObjects, &ReturnObj);
1123260659Sjkim
1124287168Sjkim    AcpiOsPrintf ("%-32s returned %s\n",
1125287168Sjkim        Pathname, AcpiFormatException (Status));
1126260659Sjkim    AcpiGbl_MethodExecuting = FALSE;
1127260659Sjkim    ACPI_FREE (Pathname);
1128260659Sjkim
1129260659Sjkim    /* Ignore status from method execution */
1130260659Sjkim
1131260659Sjkim    Status = AE_OK;
1132260659Sjkim
1133260659Sjkim    /* Update count, check if we have executed enough methods */
1134260659Sjkim
1135260659Sjkim    Info->Count++;
1136260659Sjkim    if (Info->Count >= Info->MaxCount)
1137260659Sjkim    {
1138260659Sjkim        Status = AE_CTRL_TERMINATE;
1139260659Sjkim    }
1140260659Sjkim
1141260659Sjkim    return (Status);
1142260659Sjkim}
1143