LCOV - code coverage report
Current view: top level - dev/acpi - dsdt.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 2013 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 106 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* $OpenBSD: dsdt.c,v 1.243 2018/08/19 08:23:47 kettenis Exp $ */
       2             : /*
       3             :  * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
       4             :  *
       5             :  * Permission to use, copy, modify, and distribute this software for any
       6             :  * purpose with or without fee is hereby granted, provided that the above
       7             :  * copyright notice and this permission notice appear in all copies.
       8             :  *
       9             :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      10             :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      11             :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      12             :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      13             :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      14             :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      15             :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      16             :  */
      17             : 
      18             : #include <sys/param.h>
      19             : #include <sys/systm.h>
      20             : #include <sys/kernel.h>
      21             : #include <sys/device.h>
      22             : #include <sys/malloc.h>
      23             : #include <sys/time.h>
      24             : 
      25             : #include <machine/bus.h>
      26             : 
      27             : #ifdef DDB
      28             : #include <machine/db_machdep.h>
      29             : #endif
      30             : 
      31             : #include <dev/acpi/acpireg.h>
      32             : #include <dev/acpi/acpivar.h>
      33             : #include <dev/acpi/amltypes.h>
      34             : #include <dev/acpi/dsdt.h>
      35             : 
      36             : #include <dev/i2c/i2cvar.h>
      37             : 
      38             : #ifdef SMALL_KERNEL
      39             : #undef ACPI_DEBUG
      40             : #endif
      41             : 
      42             : #define opsize(opcode) (((opcode) & 0xFF00) ? 2 : 1)
      43             : 
      44             : #define AML_FIELD_RESERVED      0x00
      45             : #define AML_FIELD_ATTRIB        0x01
      46             : 
      47             : #define AML_REVISION            0x01
      48             : #define AML_INTSTRLEN           16
      49             : #define AML_NAMESEG_LEN         4
      50             : 
      51             : struct aml_value        *aml_loadtable(struct acpi_softc *, const char *,
      52             :                             const char *, const char *, const char *,
      53             :                             const char *, struct aml_value *);
      54             : struct aml_scope        *aml_load(struct acpi_softc *, struct aml_scope *,
      55             :                             struct aml_value *, struct aml_value *);
      56             : 
      57             : void                    aml_copyvalue(struct aml_value *, struct aml_value *);
      58             : 
      59             : void                    aml_setvalue(struct aml_scope *, struct aml_value *,
      60             :                             struct aml_value *, int64_t);
      61             : void                    aml_freevalue(struct aml_value *);
      62             : struct aml_value        *aml_allocvalue(int, int64_t, const void *);
      63             : struct aml_value        *_aml_setvalue(struct aml_value *, int, int64_t,
      64             :                             const void *);
      65             : 
      66             : uint64_t                aml_convradix(uint64_t, int, int);
      67             : uint64_t                aml_evalexpr(uint64_t, uint64_t, int);
      68             : int                     aml_lsb(uint64_t);
      69             : int                     aml_msb(uint64_t);
      70             : 
      71             : int                     aml_tstbit(const uint8_t *, int);
      72             : void                    aml_setbit(uint8_t *, int, int);
      73             : 
      74             : void                    aml_addref(struct aml_value *, const char *);
      75             : void                    aml_delref(struct aml_value **, const char *);
      76             : 
      77             : void                    aml_bufcpy(void *, int, const void *, int, int);
      78             : 
      79             : int                     aml_pc(uint8_t *);
      80             : 
      81             : struct aml_value        *aml_parseop(struct aml_scope *, struct aml_value *,int);
      82             : struct aml_value        *aml_parsetarget(struct aml_scope *, struct aml_value *,
      83             :                             struct aml_value **);
      84             : struct aml_value        *aml_parseterm(struct aml_scope *, struct aml_value *);
      85             : 
      86             : struct aml_value        *aml_evaltarget(struct aml_scope *scope,
      87             :                             struct aml_value *res);
      88             : int                     aml_evalterm(struct aml_scope *scope,
      89             :                             struct aml_value *raw, struct aml_value *dst);
      90             : 
      91             : struct aml_opcode       *aml_findopcode(int);
      92             : 
      93             : #define acpi_os_malloc(sz) _acpi_os_malloc(sz, __FUNCTION__, __LINE__)
      94             : #define acpi_os_free(ptr)  _acpi_os_free(ptr, __FUNCTION__, __LINE__)
      95             : 
      96             : void                    *_acpi_os_malloc(size_t, const char *, int);
      97             : void                    _acpi_os_free(void *, const char *, int);
      98             : void                    acpi_stall(int);
      99             : 
     100             : struct aml_value        *aml_callosi(struct aml_scope *, struct aml_value *);
     101             : 
     102             : const char              *aml_getname(const char *);
     103             : int64_t                 aml_hextoint(const char *);
     104             : void                    aml_dump(int, uint8_t *);
     105             : void                    _aml_die(const char *fn, int line, const char *fmt, ...);
     106             : #define aml_die(x...)   _aml_die(__FUNCTION__, __LINE__, x)
     107             : 
     108             : void aml_notify_task(void *, int);
     109             : void acpi_poll_notify_task(void *, int);
     110             : 
     111             : extern char             *hw_vendor;
     112             : 
     113             : /*
     114             :  * @@@: Global variables
     115             :  */
     116             : int                     aml_intlen = 64;
     117             : struct aml_node         aml_root;
     118             : struct aml_value        *aml_global_lock;
     119             : 
     120             : /* Perfect Hash key */
     121             : #define HASH_OFF                6904
     122             : #define HASH_SIZE               179
     123             : #define HASH_KEY(k)             (((k) ^ HASH_OFF) % HASH_SIZE)
     124             : 
     125             : /*
     126             :  * XXX this array should be sorted, and then aml_findopcode() should
     127             :  * do a binary search
     128             :  */
     129             : struct aml_opcode **aml_ophash;
     130             : struct aml_opcode aml_table[] = {
     131             :         /* Simple types */
     132             :         { AMLOP_ZERO,           "Zero",               "c",  },
     133             :         { AMLOP_ONE,            "One",                "c",  },
     134             :         { AMLOP_ONES,           "Ones",               "c",  },
     135             :         { AMLOP_REVISION,       "Revision",   "R",  },
     136             :         { AMLOP_BYTEPREFIX,     ".Byte",      "b",  },
     137             :         { AMLOP_WORDPREFIX,     ".Word",      "w",  },
     138             :         { AMLOP_DWORDPREFIX,    ".DWord",     "d",  },
     139             :         { AMLOP_QWORDPREFIX,    ".QWord",     "q",  },
     140             :         { AMLOP_STRINGPREFIX,   ".String",    "a",  },
     141             :         { AMLOP_DEBUG,          "DebugOp",    "D",  },
     142             :         { AMLOP_BUFFER,         "Buffer",     "piB",        },
     143             :         { AMLOP_PACKAGE,        "Package",    "pbT",        },
     144             :         { AMLOP_VARPACKAGE,     "VarPackage", "piT",        },
     145             : 
     146             :         /* Simple objects */
     147             :         { AMLOP_LOCAL0,         "Local0",     "L",  },
     148             :         { AMLOP_LOCAL1,         "Local1",     "L",  },
     149             :         { AMLOP_LOCAL2,         "Local2",     "L",  },
     150             :         { AMLOP_LOCAL3,         "Local3",     "L",  },
     151             :         { AMLOP_LOCAL4,         "Local4",     "L",  },
     152             :         { AMLOP_LOCAL5,         "Local5",     "L",  },
     153             :         { AMLOP_LOCAL6,         "Local6",     "L",  },
     154             :         { AMLOP_LOCAL7,         "Local7",     "L",  },
     155             :         { AMLOP_ARG0,           "Arg0",               "A",  },
     156             :         { AMLOP_ARG1,           "Arg1",               "A",  },
     157             :         { AMLOP_ARG2,           "Arg2",               "A",  },
     158             :         { AMLOP_ARG3,           "Arg3",               "A",  },
     159             :         { AMLOP_ARG4,           "Arg4",               "A",  },
     160             :         { AMLOP_ARG5,           "Arg5",               "A",  },
     161             :         { AMLOP_ARG6,           "Arg6",               "A",  },
     162             : 
     163             :         /* Control flow */
     164             :         { AMLOP_IF,             "If",         "piI",        },
     165             :         { AMLOP_ELSE,           "Else",               "pT" },
     166             :         { AMLOP_WHILE,          "While",      "piT",        },
     167             :         { AMLOP_BREAK,          "Break",      "" },
     168             :         { AMLOP_CONTINUE,       "Continue",   "" },
     169             :         { AMLOP_RETURN,         "Return",     "t",  },
     170             :         { AMLOP_FATAL,          "Fatal",      "bdi",        },
     171             :         { AMLOP_NOP,            "Nop",                "",   },
     172             :         { AMLOP_BREAKPOINT,     "BreakPoint", "",     },
     173             : 
     174             :         /* Arithmetic operations */
     175             :         { AMLOP_INCREMENT,      "Increment",  "S",  },
     176             :         { AMLOP_DECREMENT,      "Decrement",  "S",  },
     177             :         { AMLOP_ADD,            "Add",                "iir",        },
     178             :         { AMLOP_SUBTRACT,       "Subtract",   "iir",        },
     179             :         { AMLOP_MULTIPLY,       "Multiply",   "iir",        },
     180             :         { AMLOP_DIVIDE,         "Divide",     "iirr",       },
     181             :         { AMLOP_SHL,            "ShiftLeft",  "iir",        },
     182             :         { AMLOP_SHR,            "ShiftRight", "iir",        },
     183             :         { AMLOP_AND,            "And",                "iir",        },
     184             :         { AMLOP_NAND,           "Nand",               "iir",        },
     185             :         { AMLOP_OR,             "Or",         "iir",        },
     186             :         { AMLOP_NOR,            "Nor",                "iir",        },
     187             :         { AMLOP_XOR,            "Xor",                "iir",        },
     188             :         { AMLOP_NOT,            "Not",                "ir", },
     189             :         { AMLOP_MOD,            "Mod",                "iir",        },
     190             :         { AMLOP_FINDSETLEFTBIT, "FindSetLeftBit", "ir",     },
     191             :         { AMLOP_FINDSETRIGHTBIT,"FindSetRightBit", "ir",},
     192             : 
     193             :         /* Logical test operations */
     194             :         { AMLOP_LAND,           "LAnd",               "ii", },
     195             :         { AMLOP_LOR,            "LOr",                "ii", },
     196             :         { AMLOP_LNOT,           "LNot",               "i",  },
     197             :         { AMLOP_LNOTEQUAL,      "LNotEqual",  "tt", },
     198             :         { AMLOP_LLESSEQUAL,     "LLessEqual", "tt", },
     199             :         { AMLOP_LGREATEREQUAL,  "LGreaterEqual", "tt",      },
     200             :         { AMLOP_LEQUAL,         "LEqual",     "tt", },
     201             :         { AMLOP_LGREATER,       "LGreater",   "tt", },
     202             :         { AMLOP_LLESS,          "LLess",      "tt", },
     203             : 
     204             :         /* Named objects */
     205             :         { AMLOP_NAMECHAR,       ".NameRef",   "n",  },
     206             :         { AMLOP_ALIAS,          "Alias",      "nN", },
     207             :         { AMLOP_NAME,           "Name",       "Nt", },
     208             :         { AMLOP_EVENT,          "Event",      "N",  },
     209             :         { AMLOP_MUTEX,          "Mutex",      "Nb", },
     210             :         { AMLOP_DATAREGION,     "DataRegion", "Nttt",       },
     211             :         { AMLOP_OPREGION,       "OpRegion",   "Nbii",       },
     212             :         { AMLOP_SCOPE,          "Scope",      "pnT",        },
     213             :         { AMLOP_DEVICE,         "Device",     "pNT",        },
     214             :         { AMLOP_POWERRSRC,      "Power Resource", "pNbwT",},
     215             :         { AMLOP_THERMALZONE,    "ThermalZone",        "pNT",        },
     216             :         { AMLOP_PROCESSOR,      "Processor",  "pNbdbT", },
     217             :         { AMLOP_METHOD,         "Method",     "pNbM",       },
     218             : 
     219             :         /* Field operations */
     220             :         { AMLOP_FIELD,          "Field",      "pnbF",       },
     221             :         { AMLOP_INDEXFIELD,     "IndexField", "pnnbF",},
     222             :         { AMLOP_BANKFIELD,      "BankField",  "pnnibF",},
     223             :         { AMLOP_CREATEFIELD,    "CreateField",        "tiiN",               },
     224             :         { AMLOP_CREATEQWORDFIELD, "CreateQWordField","tiN",},
     225             :         { AMLOP_CREATEDWORDFIELD, "CreateDWordField","tiN",},
     226             :         { AMLOP_CREATEWORDFIELD, "CreateWordField", "tiN",},
     227             :         { AMLOP_CREATEBYTEFIELD, "CreateByteField", "tiN",},
     228             :         { AMLOP_CREATEBITFIELD, "CreateBitField", "tiN",    },
     229             : 
     230             :         /* Conversion operations */
     231             :         { AMLOP_TOINTEGER,      "ToInteger",  "tr", },
     232             :         { AMLOP_TOBUFFER,       "ToBuffer",   "tr", },
     233             :         { AMLOP_TODECSTRING,    "ToDecString",        "ir", },
     234             :         { AMLOP_TOHEXSTRING,    "ToHexString",        "ir", },
     235             :         { AMLOP_TOSTRING,       "ToString",   "tir",        },
     236             :         { AMLOP_MID,            "Mid",                "tiir",       },
     237             :         { AMLOP_FROMBCD,        "FromBCD",    "ir", },
     238             :         { AMLOP_TOBCD,          "ToBCD",      "ir", },
     239             : 
     240             :         /* Mutex/Signal operations */
     241             :         { AMLOP_ACQUIRE,        "Acquire",    "Sw", },
     242             :         { AMLOP_RELEASE,        "Release",    "S",  },
     243             :         { AMLOP_SIGNAL,         "Signal",     "S",  },
     244             :         { AMLOP_WAIT,           "Wait",               "Si", },
     245             :         { AMLOP_RESET,          "Reset",      "S",  },
     246             : 
     247             :         { AMLOP_INDEX,          "Index",      "tir",        },
     248             :         { AMLOP_DEREFOF,        "DerefOf",    "t",  },
     249             :         { AMLOP_REFOF,          "RefOf",      "S",  },
     250             :         { AMLOP_CONDREFOF,      "CondRef",    "Sr", },
     251             : 
     252             :         { AMLOP_LOADTABLE,      "LoadTable",  "tttttt" },
     253             :         { AMLOP_STALL,          "Stall",      "i",  },
     254             :         { AMLOP_SLEEP,          "Sleep",      "i",  },
     255             :         { AMLOP_TIMER,          "Timer",      "",   },
     256             :         { AMLOP_LOAD,           "Load",               "nS", },
     257             :         { AMLOP_UNLOAD,         "Unload",     "t" },
     258             :         { AMLOP_STORE,          "Store",      "tS", },
     259             :         { AMLOP_CONCAT,         "Concat",     "ttr",        },
     260             :         { AMLOP_CONCATRES,      "ConcatRes",  "ttt" },
     261             :         { AMLOP_NOTIFY,         "Notify",     "Si", },
     262             :         { AMLOP_SIZEOF,         "Sizeof",     "S",  },
     263             :         { AMLOP_MATCH,          "Match",      "tbibii", },
     264             :         { AMLOP_OBJECTTYPE,     "ObjectType", "S",  },
     265             :         { AMLOP_COPYOBJECT,     "CopyObject", "tS", },
     266             : };
     267             : 
     268           0 : int aml_pc(uint8_t *src)
     269             : {
     270           0 :         return src - aml_root.start;
     271             : }
     272             : 
     273             : struct aml_scope *aml_lastscope;
     274             : 
     275             : void
     276           0 : _aml_die(const char *fn, int line, const char *fmt, ...)
     277             : {
     278             : #ifndef SMALL_KERNEL
     279             :         struct aml_scope *root;
     280             :         struct aml_value *sp;
     281             :         int idx;
     282             : #endif /* SMALL_KERNEL */
     283           0 :         va_list ap;
     284             : 
     285           0 :         va_start(ap, fmt);
     286           0 :         vprintf(fmt, ap);
     287           0 :         printf("\n");
     288           0 :         va_end(ap);
     289             : 
     290             : #ifndef SMALL_KERNEL
     291           0 :         for (root = aml_lastscope; root && root->pos; root = root->parent) {
     292           0 :                 printf("%.4x Called: %s\n", aml_pc(root->pos),
     293           0 :                     aml_nodename(root->node));
     294           0 :                 for (idx = 0; idx < AML_MAX_ARG; idx++) {
     295           0 :                         sp = aml_getstack(root, AMLOP_ARG0+idx);
     296           0 :                         if (sp && sp->type) {
     297           0 :                                 printf("  arg%d: ", idx);
     298           0 :                                 aml_showvalue(sp);
     299           0 :                         }
     300             :                 }
     301           0 :                 for (idx = 0; idx < AML_MAX_LOCAL; idx++) {
     302           0 :                         sp = aml_getstack(root, AMLOP_LOCAL0+idx);
     303           0 :                         if (sp && sp->type) {
     304           0 :                                 printf("  local%d: ", idx);
     305           0 :                                 aml_showvalue(sp);
     306           0 :                         }
     307             :                 }
     308             :         }
     309             : #endif /* SMALL_KERNEL */
     310             : 
     311             :         /* XXX: don't panic */
     312           0 :         panic("aml_die %s:%d", fn, line);
     313             : }
     314             : 
     315             : void
     316           0 : aml_hashopcodes(void)
     317             : {
     318             :         int i;
     319             : 
     320             :         /* Dynamically allocate hash table */
     321           0 :         aml_ophash = (struct aml_opcode **)acpi_os_malloc(HASH_SIZE *
     322             :             sizeof(struct aml_opcode *));
     323           0 :         for (i = 0; i < sizeof(aml_table) / sizeof(aml_table[0]); i++)
     324           0 :                 aml_ophash[HASH_KEY(aml_table[i].opcode)] = &aml_table[i];
     325           0 : }
     326             : 
     327             : struct aml_opcode *
     328           0 : aml_findopcode(int opcode)
     329             : {
     330             :         struct aml_opcode *hop;
     331             : 
     332           0 :         hop = aml_ophash[HASH_KEY(opcode)];
     333           0 :         if (hop && hop->opcode == opcode)
     334           0 :                 return hop;
     335           0 :         return NULL;
     336           0 : }
     337             : 
     338             : #if defined(DDB) || !defined(SMALL_KERNEL)
     339             : const char *
     340           0 : aml_mnem(int opcode, uint8_t *pos)
     341             : {
     342             :         struct aml_opcode *tab;
     343             :         static char mnemstr[32];
     344             : 
     345           0 :         if ((tab = aml_findopcode(opcode)) != NULL) {
     346           0 :                 strlcpy(mnemstr, tab->mnem, sizeof(mnemstr));
     347           0 :                 if (pos != NULL) {
     348           0 :                         switch (opcode) {
     349             :                         case AMLOP_STRINGPREFIX:
     350           0 :                                 snprintf(mnemstr, sizeof(mnemstr), "\"%s\"", pos);
     351           0 :                                 break;
     352             :                         case AMLOP_BYTEPREFIX:
     353           0 :                                 snprintf(mnemstr, sizeof(mnemstr), "0x%.2x",
     354           0 :                                          *(uint8_t *)pos);
     355           0 :                                 break;
     356             :                         case AMLOP_WORDPREFIX:
     357           0 :                                 snprintf(mnemstr, sizeof(mnemstr), "0x%.4x",
     358           0 :                                          *(uint16_t *)pos);
     359           0 :                                 break;
     360             :                         case AMLOP_DWORDPREFIX:
     361           0 :                                 snprintf(mnemstr, sizeof(mnemstr), "0x%.4x",
     362           0 :                                          *(uint16_t *)pos);
     363           0 :                                 break;
     364             :                         case AMLOP_NAMECHAR:
     365           0 :                                 strlcpy(mnemstr, aml_getname(pos), sizeof(mnemstr));
     366           0 :                                 break;
     367             :                         }
     368             :                 }
     369           0 :                 return mnemstr;
     370             :         }
     371           0 :         return ("xxx");
     372           0 : }
     373             : #endif /* defined(DDB) || !defined(SMALL_KERNEL) */
     374             : 
     375             : struct aml_notify_data {
     376             :         struct aml_node         *node;
     377             :         char                    pnpid[20];
     378             :         void                    *cbarg;
     379             :         int                     (*cbproc)(struct aml_node *, int, void *);
     380             :         int                     poll;
     381             : 
     382             :         SLIST_ENTRY(aml_notify_data) link;
     383             : };
     384             : 
     385             : SLIST_HEAD(aml_notify_head, aml_notify_data);
     386             : struct aml_notify_head aml_notify_list =
     387             :     SLIST_HEAD_INITIALIZER(aml_notify_list);
     388             : 
     389             : /*
     390             :  *  @@@: Memory management functions
     391             :  */
     392             : 
     393             : long acpi_nalloc;
     394             : 
     395             : struct acpi_memblock {
     396             :         size_t size;
     397             : #ifdef ACPI_MEMDEBUG
     398             :         const char *fn;
     399             :         int         line;
     400             :         int         sig;
     401             :         LIST_ENTRY(acpi_memblock) link;
     402             : #endif
     403             : };
     404             : 
     405             : #ifdef ACPI_MEMDEBUG
     406             : LIST_HEAD(, acpi_memblock)      acpi_memhead;
     407             : int                             acpi_memsig;
     408             : 
     409             : int
     410             : acpi_walkmem(int sig, const char *lbl)
     411             : {
     412             :         struct acpi_memblock *sptr;
     413             : 
     414             :         printf("--- walkmem:%s %x --- %lx bytes alloced\n", lbl, sig,
     415             :             acpi_nalloc);
     416             :         LIST_FOREACH(sptr, &acpi_memhead, link) {
     417             :                 if (sptr->sig < sig)
     418             :                         break;
     419             :                 printf("%.4x Alloc %.8lx bytes @ %s:%d\n",
     420             :                         sptr->sig, sptr->size, sptr->fn, sptr->line);
     421             :         }
     422             :         return acpi_memsig;
     423             : }
     424             : #endif /* ACPI_MEMDEBUG */
     425             : 
     426             : void *
     427           0 : _acpi_os_malloc(size_t size, const char *fn, int line)
     428             : {
     429             :         struct acpi_memblock *sptr;
     430             : 
     431           0 :         sptr = malloc(size+sizeof(*sptr), M_ACPI, M_WAITOK | M_ZERO);
     432             :         dnprintf(99, "alloc: %p %s:%d\n", sptr, fn, line);
     433           0 :         acpi_nalloc += size;
     434           0 :         sptr->size = size;
     435             : #ifdef ACPI_MEMDEBUG
     436             :         sptr->line = line;
     437             :         sptr->fn = fn;
     438             :         sptr->sig = ++acpi_memsig;
     439             : 
     440             :         LIST_INSERT_HEAD(&acpi_memhead, sptr, link);
     441             : #endif
     442             : 
     443           0 :         return &sptr[1];
     444             : }
     445             : 
     446             : void
     447           0 : _acpi_os_free(void *ptr, const char *fn, int line)
     448             : {
     449             :         struct acpi_memblock *sptr;
     450             : 
     451           0 :         if (ptr != NULL) {
     452           0 :                 sptr = &(((struct acpi_memblock *)ptr)[-1]);
     453           0 :                 acpi_nalloc -= sptr->size;
     454             : 
     455             : #ifdef ACPI_MEMDEBUG
     456             :                 LIST_REMOVE(sptr, link);
     457             : #endif
     458             : 
     459             :                 dnprintf(99, "free: %p %s:%d\n", sptr, fn, line);
     460           0 :                 free(sptr, M_ACPI, sizeof(*sptr) + sptr->size);
     461           0 :         }
     462           0 : }
     463             : 
     464             : void
     465           0 : acpi_sleep(int ms, char *reason)
     466             : {
     467             :         static int acpinowait;
     468           0 :         int to = ms * hz / 1000;
     469             : 
     470           0 :         if (cold)
     471           0 :                 delay(ms * 1000);
     472             :         else {
     473           0 :                 if (to <= 0)
     474           0 :                         to = 1;
     475           0 :                 tsleep(&acpinowait, PWAIT, reason, to);
     476             :         }
     477           0 : }
     478             : 
     479             : void
     480           0 : acpi_stall(int us)
     481             : {
     482           0 :         delay(us);
     483           0 : }
     484             : 
     485             : /*
     486             :  * @@@: Misc utility functions
     487             :  */
     488             : 
     489             : #ifdef ACPI_DEBUG
     490             : void
     491             : aml_dump(int len, uint8_t *buf)
     492             : {
     493             :         int             idx;
     494             : 
     495             :         dnprintf(50, "{ ");
     496             :         for (idx = 0; idx < len; idx++) {
     497             :                 dnprintf(50, "%s0x%.2x", idx ? ", " : "", buf[idx]);
     498             :         }
     499             :         dnprintf(50, " }\n");
     500             : }
     501             : #endif
     502             : 
     503             : /* Bit mangling code */
     504             : int
     505           0 : aml_tstbit(const uint8_t *pb, int bit)
     506             : {
     507           0 :         pb += aml_bytepos(bit);
     508             : 
     509           0 :         return (*pb & aml_bitmask(bit));
     510             : }
     511             : 
     512             : void
     513           0 : aml_setbit(uint8_t *pb, int bit, int val)
     514             : {
     515           0 :         pb += aml_bytepos(bit);
     516             : 
     517           0 :         if (val)
     518           0 :                 *pb |= aml_bitmask(bit);
     519             :         else
     520           0 :                 *pb &= ~aml_bitmask(bit);
     521           0 : }
     522             : 
     523             : /*
     524             :  * @@@: Notify functions
     525             :  */
     526             : void
     527           0 : acpi_poll(void *arg)
     528             : {
     529             :         int s;
     530             : 
     531           0 :         s = spltty();
     532           0 :         acpi_addtask(acpi_softc, acpi_poll_notify_task, NULL, 0);
     533           0 :         acpi_softc->sc_threadwaiting = 0;
     534           0 :         wakeup(acpi_softc);
     535           0 :         splx(s);
     536             : 
     537           0 :         timeout_add_sec(&acpi_softc->sc_dev_timeout, 10);
     538           0 : }
     539             : 
     540             : void
     541           0 : aml_notify_task(void *node, int notify_value)
     542             : {
     543             :         struct aml_notify_data  *pdata = NULL;
     544             : 
     545             :         dnprintf(10,"run notify: %s %x\n", aml_nodename(node), notify_value);
     546           0 :         SLIST_FOREACH(pdata, &aml_notify_list, link)
     547           0 :                 if (pdata->node == node)
     548           0 :                         pdata->cbproc(pdata->node, notify_value, pdata->cbarg);
     549           0 : }
     550             : 
     551             : void
     552           0 : aml_register_notify(struct aml_node *node, const char *pnpid,
     553             :     int (*proc)(struct aml_node *, int, void *), void *arg, int poll)
     554             : {
     555             :         struct aml_notify_data  *pdata;
     556             :         extern int acpi_poll_enabled;
     557             : 
     558             :         dnprintf(10, "aml_register_notify: %s %s %p\n",
     559             :             node->name, pnpid ? pnpid : "", proc);
     560             : 
     561           0 :         pdata = acpi_os_malloc(sizeof(struct aml_notify_data));
     562           0 :         pdata->node = node;
     563           0 :         pdata->cbarg = arg;
     564           0 :         pdata->cbproc = proc;
     565           0 :         pdata->poll = poll;
     566             : 
     567           0 :         if (pnpid)
     568           0 :                 strlcpy(pdata->pnpid, pnpid, sizeof(pdata->pnpid));
     569             : 
     570           0 :         SLIST_INSERT_HEAD(&aml_notify_list, pdata, link);
     571             : 
     572           0 :         if (poll && !acpi_poll_enabled)
     573           0 :                 timeout_add_sec(&acpi_softc->sc_dev_timeout, 10);
     574           0 : }
     575             : 
     576             : void
     577           0 : aml_notify(struct aml_node *node, int notify_value)
     578             : {
     579           0 :         if (node == NULL)
     580             :                 return;
     581             : 
     582             :         dnprintf(10,"queue notify: %s %x\n", aml_nodename(node), notify_value);
     583           0 :         acpi_addtask(acpi_softc, aml_notify_task, node, notify_value);
     584           0 : }
     585             : 
     586             : void
     587           0 : aml_notify_dev(const char *pnpid, int notify_value)
     588             : {
     589             :         struct aml_notify_data  *pdata = NULL;
     590             : 
     591           0 :         if (pnpid == NULL)
     592           0 :                 return;
     593             : 
     594           0 :         SLIST_FOREACH(pdata, &aml_notify_list, link)
     595           0 :                 if (strcmp(pdata->pnpid, pnpid) == 0)
     596           0 :                         pdata->cbproc(pdata->node, notify_value, pdata->cbarg);
     597           0 : }
     598             : 
     599             : void
     600           0 : acpi_poll_notify_task(void *arg0, int arg1)
     601             : {
     602             :         struct aml_notify_data  *pdata = NULL;
     603             : 
     604           0 :         SLIST_FOREACH(pdata, &aml_notify_list, link)
     605           0 :                 if (pdata->cbproc && pdata->poll)
     606           0 :                         pdata->cbproc(pdata->node, 0, pdata->cbarg);
     607           0 : }
     608             : 
     609             : /*
     610             :  * @@@: Namespace functions
     611             :  */
     612             : 
     613             : struct aml_node *__aml_search(struct aml_node *, uint8_t *, int);
     614             : struct aml_node *__aml_searchname(struct aml_node *, const void *, int);
     615             : void aml_delchildren(struct aml_node *);
     616             : 
     617             : 
     618             : /* Search for a name in children nodes */
     619             : struct aml_node *
     620           0 : __aml_search(struct aml_node *root, uint8_t *nameseg, int create)
     621             : {
     622             :         struct aml_node *node;
     623             : 
     624             :         /* XXX: Replace with SLIST/SIMPLEQ routines */
     625           0 :         if (root == NULL)
     626           0 :                 return NULL;
     627           0 :         SIMPLEQ_FOREACH(node, &root->son, sib) {
     628           0 :                 if (!strncmp(node->name, nameseg, AML_NAMESEG_LEN))
     629           0 :                         return node;
     630             :         }
     631           0 :         if (create) {
     632           0 :                 node = acpi_os_malloc(sizeof(struct aml_node));
     633           0 :                 memcpy((void *)node->name, nameseg, AML_NAMESEG_LEN);
     634           0 :                 node->value = aml_allocvalue(0,0,NULL);
     635           0 :                 node->value->node = node;
     636           0 :                 node->parent = root;
     637             : 
     638           0 :                 SIMPLEQ_INIT(&node->son);
     639           0 :                 SIMPLEQ_INSERT_TAIL(&root->son, node, sib);
     640           0 :         }
     641           0 :         return node;
     642           0 : }
     643             : 
     644             : /* Get absolute pathname of AML node */
     645             : const char *
     646           0 : aml_nodename(struct aml_node *node)
     647             : {
     648             :         static char namebuf[128];
     649             : 
     650           0 :         namebuf[0] = 0;
     651           0 :         if (node) {
     652           0 :                 aml_nodename(node->parent);
     653           0 :                 if (node->parent != &aml_root)
     654           0 :                         strlcat(namebuf, ".", sizeof(namebuf));
     655           0 :                 strlcat(namebuf, node->name, sizeof(namebuf));
     656           0 :                 return namebuf+1;
     657             :         }
     658           0 :         return namebuf;
     659           0 : }
     660             : 
     661             : const char *
     662           0 : aml_getname(const char *name)
     663             : {
     664             :         static char namebuf[128], *p;
     665             :         int count;
     666             : 
     667           0 :         p = namebuf;
     668           0 :         while (*name == AMLOP_ROOTCHAR || *name == AMLOP_PARENTPREFIX)
     669           0 :                 *(p++) = *(name++);
     670           0 :         switch (*name) {
     671             :         case 0x00:
     672             :                 count = 0;
     673           0 :                 break;
     674             :         case AMLOP_MULTINAMEPREFIX:
     675           0 :                 count = name[1];
     676           0 :                 name += 2;
     677           0 :                 break;
     678             :         case AMLOP_DUALNAMEPREFIX:
     679             :                 count = 2;
     680           0 :                 name += 1;
     681           0 :                 break;
     682             :         default:
     683             :                 count = 1;
     684           0 :         }
     685           0 :         while (count--) {
     686           0 :                 memcpy(p, name, 4);
     687           0 :                 p[4] = '.';
     688           0 :                 p += 5;
     689           0 :                 name += 4;
     690           0 :                 if (*name == '.') name++;
     691             :         }
     692           0 :         *(--p) = 0;
     693           0 :         return namebuf;
     694             : }
     695             : 
     696             : /* Free all children nodes/values */
     697             : void
     698           0 : aml_delchildren(struct aml_node *node)
     699             : {
     700             :         struct aml_node *onode;
     701             : 
     702           0 :         if (node == NULL)
     703           0 :                 return;
     704           0 :         while ((onode = SIMPLEQ_FIRST(&node->son)) != NULL) {
     705           0 :                 SIMPLEQ_REMOVE_HEAD(&node->son, sib);
     706             : 
     707           0 :                 aml_delchildren(onode);
     708             : 
     709             :                 /* Don't delete values that have references */
     710           0 :                 if (onode->value && onode->value->refcnt > 1)
     711           0 :                         onode->value->node = NULL;
     712             : 
     713             :                 /* Decrease reference count */
     714           0 :                 aml_delref(&onode->value, "");
     715             : 
     716             :                 /* Delete node */
     717           0 :                 acpi_os_free(onode);
     718             :         }
     719           0 : }
     720             : 
     721             : /*
     722             :  * @@@: Value functions
     723             :  */
     724             : 
     725             : /*
     726             :  * Field I/O code
     727             :  */
     728             : void aml_unlockfield(struct aml_scope *, struct aml_value *);
     729             : void aml_lockfield(struct aml_scope *, struct aml_value *);
     730             : 
     731             : static long global_lock_count = 0;
     732             : 
     733             : void
     734           0 : acpi_glk_enter(void)
     735             : {
     736             :         int st = 0;
     737             : 
     738             :         /* If lock is already ours, just continue. */
     739           0 :         if (global_lock_count++)
     740           0 :                 return;
     741             : 
     742             :         /* Spin to acquire the lock. */
     743           0 :         while (!st) {
     744           0 :                 st = acpi_acquire_glk(&acpi_softc->sc_facs->global_lock);
     745             :                 /* XXX - yield/delay? */
     746             :         }
     747           0 : }
     748             : 
     749             : void
     750           0 : acpi_glk_leave(void)
     751             : {
     752             :         int st, x;
     753             : 
     754             :         /* If we are the last one, turn out the lights. */
     755           0 :         if (--global_lock_count)
     756           0 :                 return;
     757             : 
     758           0 :         st = acpi_release_glk(&acpi_softc->sc_facs->global_lock);
     759           0 :         if (!st)
     760           0 :                 return;
     761             : 
     762             :         /*
     763             :          * If pending, notify the BIOS that the lock was released by
     764             :          * OSPM.  No locking is needed because nobody outside the ACPI
     765             :          * thread is supposed to touch this register.
     766             :          */
     767           0 :         x = acpi_read_pmreg(acpi_softc, ACPIREG_PM1_CNT, 0);
     768           0 :         x |= ACPI_PM1_GBL_RLS;
     769           0 :         acpi_write_pmreg(acpi_softc, ACPIREG_PM1_CNT, 0, x);
     770           0 : }
     771             : 
     772             : void
     773           0 : aml_lockfield(struct aml_scope *scope, struct aml_value *field)
     774             : {
     775           0 :         if (AML_FIELD_LOCK(field->v_field.flags) != AML_FIELD_LOCK_ON)
     776             :                 return;
     777             : 
     778           0 :         acpi_glk_enter();
     779           0 : }
     780             : 
     781             : void
     782           0 : aml_unlockfield(struct aml_scope *scope, struct aml_value *field)
     783             : {
     784           0 :         if (AML_FIELD_LOCK(field->v_field.flags) != AML_FIELD_LOCK_ON)
     785             :                 return;
     786             : 
     787           0 :         acpi_glk_leave();
     788           0 : }
     789             : 
     790             : /*
     791             :  * @@@: Value set/compare/alloc/free routines
     792             :  */
     793             : 
     794             : #ifndef SMALL_KERNEL
     795             : void
     796           0 : aml_showvalue(struct aml_value *val)
     797             : {
     798             :         int idx;
     799             : 
     800           0 :         if (val == NULL)
     801           0 :                 return;
     802             : 
     803           0 :         if (val->node)
     804           0 :                 printf(" [%s]", aml_nodename(val->node));
     805           0 :         printf(" %p cnt:%.2x stk:%.2x", val, val->refcnt, val->stack);
     806           0 :         switch (val->type) {
     807             :         case AML_OBJTYPE_INTEGER:
     808           0 :                 printf(" integer: %llx\n", val->v_integer);
     809           0 :                 break;
     810             :         case AML_OBJTYPE_STRING:
     811           0 :                 printf(" string: %s\n", val->v_string);
     812           0 :                 break;
     813             :         case AML_OBJTYPE_METHOD:
     814           0 :                 printf(" method: %.2x\n", val->v_method.flags);
     815           0 :                 break;
     816             :         case AML_OBJTYPE_PACKAGE:
     817           0 :                 printf(" package: %.2x\n", val->length);
     818           0 :                 for (idx = 0; idx < val->length; idx++)
     819           0 :                         aml_showvalue(val->v_package[idx]);
     820             :                 break;
     821             :         case AML_OBJTYPE_BUFFER:
     822           0 :                 printf(" buffer: %.2x {", val->length);
     823           0 :                 for (idx = 0; idx < val->length; idx++)
     824           0 :                         printf("%s%.2x", idx ? ", " : "", val->v_buffer[idx]);
     825           0 :                 printf("}\n");
     826           0 :                 break;
     827             :         case AML_OBJTYPE_FIELDUNIT:
     828             :         case AML_OBJTYPE_BUFFERFIELD:
     829           0 :                 printf(" field: bitpos=%.4x bitlen=%.4x ref1:%p ref2:%p [%s]\n",
     830           0 :                     val->v_field.bitpos, val->v_field.bitlen,
     831           0 :                     val->v_field.ref1, val->v_field.ref2,
     832           0 :                     aml_mnem(val->v_field.type, NULL));
     833           0 :                 if (val->v_field.ref1)
     834           0 :                         printf("  ref1: %s\n", aml_nodename(val->v_field.ref1->node));
     835           0 :                 if (val->v_field.ref2)
     836           0 :                         printf("  ref2: %s\n", aml_nodename(val->v_field.ref2->node));
     837             :                 break;
     838             :         case AML_OBJTYPE_MUTEX:
     839           0 :                 printf(" mutex: %s ref: %d\n",
     840           0 :                     val->v_mutex ?  val->v_mutex->amt_name : "",
     841           0 :                     val->v_mutex ?  val->v_mutex->amt_ref_count : 0);
     842           0 :                 break;
     843             :         case AML_OBJTYPE_EVENT:
     844           0 :                 printf(" event:\n");
     845           0 :                 break;
     846             :         case AML_OBJTYPE_OPREGION:
     847           0 :                 printf(" opregion: %.2x,%.8llx,%x\n",
     848           0 :                     val->v_opregion.iospace, val->v_opregion.iobase,
     849           0 :                     val->v_opregion.iolen);
     850           0 :                 break;
     851             :         case AML_OBJTYPE_NAMEREF:
     852           0 :                 printf(" nameref: %s\n", aml_getname(val->v_nameref));
     853           0 :                 break;
     854             :         case AML_OBJTYPE_DEVICE:
     855           0 :                 printf(" device:\n");
     856           0 :                 break;
     857             :         case AML_OBJTYPE_PROCESSOR:
     858           0 :                 printf(" cpu: %.2x,%.4x,%.2x\n",
     859           0 :                     val->v_processor.proc_id, val->v_processor.proc_addr,
     860           0 :                     val->v_processor.proc_len);
     861           0 :                 break;
     862             :         case AML_OBJTYPE_THERMZONE:
     863           0 :                 printf(" thermzone:\n");
     864           0 :                 break;
     865             :         case AML_OBJTYPE_POWERRSRC:
     866           0 :                 printf(" pwrrsrc: %.2x,%.2x\n",
     867           0 :                     val->v_powerrsrc.pwr_level, val->v_powerrsrc.pwr_order);
     868           0 :                 break;
     869             :         case AML_OBJTYPE_OBJREF:
     870           0 :                 printf(" objref: %p index:%x opcode:%s\n", val->v_objref.ref,
     871           0 :                     val->v_objref.index, aml_mnem(val->v_objref.type, 0));
     872           0 :                 aml_showvalue(val->v_objref.ref);
     873           0 :                 break;
     874             :         default:
     875           0 :                 printf(" !!type: %x\n", val->type);
     876           0 :         }
     877           0 : }
     878             : #endif /* SMALL_KERNEL */
     879             : 
     880             : int64_t
     881           0 : aml_val2int(struct aml_value *rval)
     882             : {
     883           0 :         int64_t ival = 0;
     884             : 
     885           0 :         if (rval == NULL) {
     886             :                 dnprintf(50, "null val2int\n");
     887           0 :                 return (0);
     888             :         }
     889           0 :         switch (rval->type) {
     890             :         case AML_OBJTYPE_INTEGER:
     891           0 :                 ival = rval->v_integer;
     892           0 :                 break;
     893             :         case AML_OBJTYPE_BUFFER:
     894           0 :                 aml_bufcpy(&ival, 0, rval->v_buffer, 0,
     895           0 :                     min(aml_intlen, rval->length*8));
     896           0 :                 break;
     897             :         case AML_OBJTYPE_STRING:
     898           0 :                 ival = aml_hextoint(rval->v_string);
     899           0 :                 break;
     900             :         }
     901           0 :         return (ival);
     902           0 : }
     903             : 
     904             : /* Sets value into LHS: lhs must already be cleared */
     905             : struct aml_value *
     906           0 : _aml_setvalue(struct aml_value *lhs, int type, int64_t ival, const void *bval)
     907             : {
     908           0 :         memset(&lhs->_, 0x0, sizeof(lhs->_));
     909             : 
     910           0 :         lhs->type = type;
     911           0 :         switch (lhs->type) {
     912             :         case AML_OBJTYPE_INTEGER:
     913           0 :                 lhs->length = aml_intlen>>3;
     914           0 :                 lhs->v_integer = ival;
     915           0 :                 break;
     916             :         case AML_OBJTYPE_METHOD:
     917           0 :                 lhs->v_method.flags = ival;
     918           0 :                 lhs->v_method.fneval = bval;
     919           0 :                 break;
     920             :         case AML_OBJTYPE_NAMEREF:
     921           0 :                 lhs->v_nameref = (uint8_t *)bval;
     922           0 :                 break;
     923             :         case AML_OBJTYPE_OBJREF:
     924           0 :                 lhs->v_objref.type = ival;
     925           0 :                 lhs->v_objref.ref = (struct aml_value *)bval;
     926           0 :                 break;
     927             :         case AML_OBJTYPE_BUFFER:
     928           0 :                 lhs->length = ival;
     929           0 :                 lhs->v_buffer = (uint8_t *)acpi_os_malloc(ival);
     930           0 :                 if (bval)
     931           0 :                         memcpy(lhs->v_buffer, bval, ival);
     932             :                 break;
     933             :         case AML_OBJTYPE_STRING:
     934           0 :                 if (ival == -1)
     935           0 :                         ival = strlen((const char *)bval);
     936           0 :                 lhs->length = ival;
     937           0 :                 lhs->v_string = (char *)acpi_os_malloc(ival+1);
     938           0 :                 if (bval)
     939           0 :                         strncpy(lhs->v_string, (const char *)bval, ival);
     940             :                 break;
     941             :         case AML_OBJTYPE_PACKAGE:
     942           0 :                 lhs->length = ival;
     943           0 :                 lhs->v_package = (struct aml_value **)acpi_os_malloc(ival *
     944             :                     sizeof(struct aml_value *));
     945           0 :                 for (ival = 0; ival < lhs->length; ival++)
     946           0 :                         lhs->v_package[ival] = aml_allocvalue(
     947             :                             AML_OBJTYPE_UNINITIALIZED, 0, NULL);
     948             :                 break;
     949             :         }
     950           0 :         return lhs;
     951             : }
     952             : 
     953             : /* Copy object to another value: lhs must already be cleared */
     954             : void
     955           0 : aml_copyvalue(struct aml_value *lhs, struct aml_value *rhs)
     956             : {
     957             :         int idx;
     958             : 
     959           0 :         lhs->type = rhs->type;
     960           0 :         switch (lhs->type) {
     961             :         case AML_OBJTYPE_UNINITIALIZED:
     962             :                 break;
     963             :         case AML_OBJTYPE_INTEGER:
     964           0 :                 lhs->length = aml_intlen>>3;
     965           0 :                 lhs->v_integer = rhs->v_integer;
     966           0 :                 break;
     967             :         case AML_OBJTYPE_MUTEX:
     968           0 :                 lhs->v_mutex = rhs->v_mutex;
     969           0 :                 break;
     970             :         case AML_OBJTYPE_POWERRSRC:
     971           0 :                 lhs->v_powerrsrc = rhs->v_powerrsrc;
     972           0 :                 break;
     973             :         case AML_OBJTYPE_METHOD:
     974           0 :                 lhs->v_method = rhs->v_method;
     975           0 :                 break;
     976             :         case AML_OBJTYPE_BUFFER:
     977           0 :                 _aml_setvalue(lhs, rhs->type, rhs->length, rhs->v_buffer);
     978           0 :                 break;
     979             :         case AML_OBJTYPE_STRING:
     980           0 :                 _aml_setvalue(lhs, rhs->type, rhs->length, rhs->v_string);
     981           0 :                 break;
     982             :         case AML_OBJTYPE_OPREGION:
     983           0 :                 lhs->v_opregion = rhs->v_opregion;
     984           0 :                 break;
     985             :         case AML_OBJTYPE_PROCESSOR:
     986           0 :                 lhs->v_processor = rhs->v_processor;
     987           0 :                 break;
     988             :         case AML_OBJTYPE_NAMEREF:
     989           0 :                 lhs->v_nameref = rhs->v_nameref;
     990           0 :                 break;
     991             :         case AML_OBJTYPE_PACKAGE:
     992           0 :                 _aml_setvalue(lhs, rhs->type, rhs->length, NULL);
     993           0 :                 for (idx = 0; idx < rhs->length; idx++)
     994           0 :                         aml_copyvalue(lhs->v_package[idx], rhs->v_package[idx]);
     995             :                 break;
     996             :         case AML_OBJTYPE_OBJREF:
     997           0 :                 lhs->v_objref = rhs->v_objref;
     998           0 :                 aml_addref(lhs->v_objref.ref, "");
     999           0 :                 break;
    1000             :         default:
    1001           0 :                 printf("copyvalue: %x", rhs->type);
    1002           0 :                 break;
    1003             :         }
    1004           0 : }
    1005             : 
    1006             : /* Allocate dynamic AML value
    1007             :  *   type : Type of object to allocate (AML_OBJTYPE_XXXX)
    1008             :  *   ival : Integer value (action depends on type)
    1009             :  *   bval : Buffer value (action depends on type)
    1010             :  */
    1011             : struct aml_value *
    1012           0 : aml_allocvalue(int type, int64_t ival, const void *bval)
    1013             : {
    1014             :         struct aml_value *rv;
    1015             : 
    1016           0 :         rv = (struct aml_value *)acpi_os_malloc(sizeof(struct aml_value));
    1017           0 :         if (rv != NULL) {
    1018           0 :                 aml_addref(rv, "");
    1019           0 :                 return _aml_setvalue(rv, type, ival, bval);
    1020             :         }
    1021           0 :         return NULL;
    1022           0 : }
    1023             : 
    1024             : void
    1025           0 : aml_freevalue(struct aml_value *val)
    1026             : {
    1027             :         int idx;
    1028             : 
    1029           0 :         if (val == NULL)
    1030           0 :                 return;
    1031           0 :         switch (val->type) {
    1032             :         case AML_OBJTYPE_STRING:
    1033           0 :                 acpi_os_free(val->v_string);
    1034           0 :                 break;
    1035             :         case AML_OBJTYPE_BUFFER:
    1036           0 :                 acpi_os_free(val->v_buffer);
    1037           0 :                 break;
    1038             :         case AML_OBJTYPE_PACKAGE:
    1039           0 :                 for (idx = 0; idx < val->length; idx++) {
    1040           0 :                         aml_freevalue(val->v_package[idx]);
    1041           0 :                         acpi_os_free(val->v_package[idx]);
    1042             :                 }
    1043           0 :                 acpi_os_free(val->v_package);
    1044           0 :                 break;
    1045             :         case AML_OBJTYPE_OBJREF:
    1046           0 :                 aml_delref(&val->v_objref.ref, "");
    1047           0 :                 break;
    1048             :         case AML_OBJTYPE_BUFFERFIELD:
    1049             :         case AML_OBJTYPE_FIELDUNIT:
    1050           0 :                 aml_delref(&val->v_field.ref1, "");
    1051           0 :                 aml_delref(&val->v_field.ref2, "");
    1052           0 :                 break;
    1053             :         }
    1054           0 :         val->type = 0;
    1055           0 :         memset(&val->_, 0, sizeof(val->_));
    1056           0 : }
    1057             : 
    1058             : /*
    1059             :  * @@@: Math eval routines
    1060             :  */
    1061             : 
    1062             : /* Convert number from one radix to another
    1063             :  * Used in BCD conversion routines */
    1064             : uint64_t
    1065           0 : aml_convradix(uint64_t val, int iradix, int oradix)
    1066             : {
    1067             :         uint64_t rv = 0, pwr;
    1068             : 
    1069             :         rv = 0;
    1070             :         pwr = 1;
    1071           0 :         while (val) {
    1072           0 :                 rv += (val % iradix) * pwr;
    1073           0 :                 val /= iradix;
    1074           0 :                 pwr *= oradix;
    1075             :         }
    1076           0 :         return rv;
    1077             : }
    1078             : 
    1079             : /* Calculate LSB */
    1080             : int
    1081           0 : aml_lsb(uint64_t val)
    1082             : {
    1083             :         int             lsb;
    1084             : 
    1085           0 :         if (val == 0)
    1086           0 :                 return (0);
    1087             : 
    1088           0 :         for (lsb = 1; !(val & 0x1); lsb++)
    1089           0 :                 val >>= 1;
    1090             : 
    1091           0 :         return (lsb);
    1092           0 : }
    1093             : 
    1094             : /* Calculate MSB */
    1095             : int
    1096           0 : aml_msb(uint64_t val)
    1097             : {
    1098             :         int             msb;
    1099             : 
    1100           0 :         if (val == 0)
    1101           0 :                 return (0);
    1102             : 
    1103           0 :         for (msb = 1; val != 0x1; msb++)
    1104           0 :                 val >>= 1;
    1105             : 
    1106           0 :         return (msb);
    1107           0 : }
    1108             : 
    1109             : /* Evaluate Math operands */
    1110             : uint64_t
    1111           0 : aml_evalexpr(uint64_t lhs, uint64_t rhs, int opcode)
    1112             : {
    1113             :         uint64_t res = 0;
    1114             : 
    1115           0 :         switch (opcode) {
    1116             :                 /* Math operations */
    1117             :         case AMLOP_INCREMENT:
    1118             :         case AMLOP_ADD:
    1119           0 :                 res = (lhs + rhs);
    1120           0 :                 break;
    1121             :         case AMLOP_DECREMENT:
    1122             :         case AMLOP_SUBTRACT:
    1123           0 :                 res = (lhs - rhs);
    1124           0 :                 break;
    1125             :         case AMLOP_MULTIPLY:
    1126           0 :                 res = (lhs * rhs);
    1127           0 :                 break;
    1128             :         case AMLOP_DIVIDE:
    1129           0 :                 res = (lhs / rhs);
    1130           0 :                 break;
    1131             :         case AMLOP_MOD:
    1132           0 :                 res = (lhs % rhs);
    1133           0 :                 break;
    1134             :         case AMLOP_SHL:
    1135           0 :                 res = (lhs << rhs);
    1136           0 :                 break;
    1137             :         case AMLOP_SHR:
    1138           0 :                 res = (lhs >> rhs);
    1139           0 :                 break;
    1140             :         case AMLOP_AND:
    1141           0 :                 res = (lhs & rhs);
    1142           0 :                 break;
    1143             :         case AMLOP_NAND:
    1144           0 :                 res = ~(lhs & rhs);
    1145           0 :                 break;
    1146             :         case AMLOP_OR:
    1147           0 :                 res = (lhs | rhs);
    1148           0 :                 break;
    1149             :         case AMLOP_NOR:
    1150           0 :                 res = ~(lhs | rhs);
    1151           0 :                 break;
    1152             :         case AMLOP_XOR:
    1153           0 :                 res = (lhs ^ rhs);
    1154           0 :                 break;
    1155             :         case AMLOP_NOT:
    1156           0 :                 res = ~(lhs);
    1157           0 :                 break;
    1158             : 
    1159             :                 /* Conversion/misc */
    1160             :         case AMLOP_FINDSETLEFTBIT:
    1161           0 :                 res = aml_msb(lhs);
    1162           0 :                 break;
    1163             :         case AMLOP_FINDSETRIGHTBIT:
    1164           0 :                 res = aml_lsb(lhs);
    1165           0 :                 break;
    1166             :         case AMLOP_TOINTEGER:
    1167             :                 res = (lhs);
    1168           0 :                 break;
    1169             :         case AMLOP_FROMBCD:
    1170           0 :                 res = aml_convradix(lhs, 16, 10);
    1171           0 :                 break;
    1172             :         case AMLOP_TOBCD:
    1173           0 :                 res = aml_convradix(lhs, 10, 16);
    1174           0 :                 break;
    1175             : 
    1176             :                 /* Logical/Comparison */
    1177             :         case AMLOP_LAND:
    1178           0 :                 res = -(lhs && rhs);
    1179           0 :                 break;
    1180             :         case AMLOP_LOR:
    1181           0 :                 res = -(lhs || rhs);
    1182           0 :                 break;
    1183             :         case AMLOP_LNOT:
    1184           0 :                 res = -(!lhs);
    1185           0 :                 break;
    1186             :         case AMLOP_LNOTEQUAL:
    1187           0 :                 res = -(lhs != rhs);
    1188           0 :                 break;
    1189             :         case AMLOP_LLESSEQUAL:
    1190           0 :                 res = -(lhs <= rhs);
    1191           0 :                 break;
    1192             :         case AMLOP_LGREATEREQUAL:
    1193           0 :                 res = -(lhs >= rhs);
    1194           0 :                 break;
    1195             :         case AMLOP_LEQUAL:
    1196           0 :                 res = -(lhs == rhs);
    1197           0 :                 break;
    1198             :         case AMLOP_LGREATER:
    1199           0 :                 res = -(lhs > rhs);
    1200           0 :                 break;
    1201             :         case AMLOP_LLESS:
    1202           0 :                 res = -(lhs < rhs);
    1203           0 :                 break;
    1204             :         }
    1205             : 
    1206             :         dnprintf(15,"aml_evalexpr: %s %llx %llx = %llx\n",
    1207             :                  aml_mnem(opcode, NULL), lhs, rhs, res);
    1208             : 
    1209           0 :         return res;
    1210             : }
    1211             : 
    1212             : /*
    1213             :  * aml_bufcpy copies/shifts buffer data, special case for aligned transfers
    1214             :  * dstPos/srcPos are bit positions within destination/source buffers
    1215             :  */
    1216             : void
    1217           0 : aml_bufcpy(void *pvDst, int dstPos, const void *pvSrc, int srcPos, int len)
    1218             : {
    1219             :         const uint8_t *pSrc = pvSrc;
    1220             :         uint8_t *pDst = pvDst;
    1221             :         int             idx;
    1222             : 
    1223           0 :         if (aml_bytealigned(dstPos|srcPos|len)) {
    1224             :                 /* Aligned transfer: use memcpy */
    1225           0 :                 memcpy(pDst+aml_bytepos(dstPos), pSrc+aml_bytepos(srcPos),
    1226             :                     aml_bytelen(len));
    1227           0 :                 return;
    1228             :         }
    1229             : 
    1230             :         /* Misaligned transfer: perform bitwise copy (slow) */
    1231           0 :         for (idx = 0; idx < len; idx++)
    1232           0 :                 aml_setbit(pDst, idx + dstPos, aml_tstbit(pSrc, idx + srcPos));
    1233           0 : }
    1234             : 
    1235             : /*
    1236             :  * @@@: External API
    1237             :  *
    1238             :  * evaluate an AML node
    1239             :  * Returns a copy of the value in res  (must be freed by user)
    1240             :  */
    1241             : 
    1242             : void
    1243           0 : aml_walknodes(struct aml_node *node, int mode,
    1244             :     int (*nodecb)(struct aml_node *, void *), void *arg)
    1245             : {
    1246             :         struct aml_node *child;
    1247             : 
    1248           0 :         if (node == NULL)
    1249           0 :                 return;
    1250           0 :         if (mode == AML_WALK_PRE)
    1251           0 :                 if (nodecb(node, arg))
    1252           0 :                         return;
    1253           0 :         SIMPLEQ_FOREACH(child, &node->son, sib)
    1254           0 :                 aml_walknodes(child, mode, nodecb, arg);
    1255           0 :         if (mode == AML_WALK_POST)
    1256           0 :                 nodecb(node, arg);
    1257           0 : }
    1258             : 
    1259             : void
    1260           0 : aml_find_node(struct aml_node *node, const char *name,
    1261             :     int (*cbproc)(struct aml_node *, void *arg), void *arg)
    1262             : {
    1263             :         struct aml_node *child;
    1264             :         const char *nn;
    1265             : 
    1266           0 :         SIMPLEQ_FOREACH(child, &node->son, sib) {
    1267           0 :                 nn = child->name;
    1268           0 :                 if (nn != NULL) {
    1269           0 :                         if (*nn == AMLOP_ROOTCHAR) nn++;
    1270           0 :                         while (*nn == AMLOP_PARENTPREFIX) nn++;
    1271           0 :                         if (strcmp(name, nn) == 0) {
    1272             :                                 /* Only recurse if cbproc() wants us to */
    1273           0 :                                 if (cbproc(child, arg) == 0)
    1274             :                                         continue;
    1275             :                         }
    1276             :                 }
    1277           0 :                 aml_find_node(child, name, cbproc, arg);
    1278           0 :         }
    1279           0 : }
    1280             : 
    1281             : /*
    1282             :  * @@@: Parser functions
    1283             :  */
    1284             : uint8_t *aml_parsename(struct aml_node *, uint8_t *, struct aml_value **, int);
    1285             : uint8_t *aml_parseend(struct aml_scope *scope);
    1286             : int     aml_parselength(struct aml_scope *);
    1287             : int     aml_parseopcode(struct aml_scope *);
    1288             : 
    1289             : /* Get AML Opcode */
    1290             : int
    1291           0 : aml_parseopcode(struct aml_scope *scope)
    1292             : {
    1293           0 :         int opcode = (scope->pos[0]);
    1294           0 :         int twocode = (scope->pos[0]<<8) + scope->pos[1];
    1295             : 
    1296             :         /* Check if this is an embedded name */
    1297           0 :         switch (opcode) {
    1298             :         case AMLOP_ROOTCHAR:
    1299             :         case AMLOP_PARENTPREFIX:
    1300             :         case AMLOP_MULTINAMEPREFIX:
    1301             :         case AMLOP_DUALNAMEPREFIX:
    1302             :         case AMLOP_NAMECHAR:
    1303           0 :                 return AMLOP_NAMECHAR;
    1304             :         }
    1305           0 :         if (opcode >= 'A' && opcode <= 'Z')
    1306           0 :                 return AMLOP_NAMECHAR;
    1307           0 :         if (twocode == AMLOP_LNOTEQUAL || twocode == AMLOP_LLESSEQUAL ||
    1308           0 :             twocode == AMLOP_LGREATEREQUAL || opcode == AMLOP_EXTPREFIX) {
    1309           0 :                 scope->pos += 2;
    1310           0 :                 return twocode;
    1311             :         }
    1312           0 :         scope->pos += 1;
    1313           0 :         return opcode;
    1314           0 : }
    1315             : 
    1316             : /* Decode embedded AML Namestring */
    1317             : uint8_t *
    1318           0 : aml_parsename(struct aml_node *inode, uint8_t *pos, struct aml_value **rval, int create)
    1319             : {
    1320             :         struct aml_node *relnode, *node = inode;
    1321             :         uint8_t *start = pos;
    1322             :         int i;
    1323             : 
    1324           0 :         if (*pos == AMLOP_ROOTCHAR) {
    1325           0 :                 pos++;
    1326             :                 node = &aml_root;
    1327           0 :         }
    1328           0 :         while (*pos == AMLOP_PARENTPREFIX) {
    1329           0 :                 pos++;
    1330           0 :                 if ((node = node->parent) == NULL)
    1331             :                         node = &aml_root;
    1332             :         }
    1333           0 :         switch (*pos) {
    1334             :         case 0x00:
    1335           0 :                 pos++;
    1336           0 :                 break;
    1337             :         case AMLOP_MULTINAMEPREFIX:
    1338           0 :                 for (i=0; i<pos[1]; i++)
    1339           0 :                         node = __aml_search(node, pos+2+i*AML_NAMESEG_LEN,
    1340             :                             create);
    1341           0 :                 pos += 2+i*AML_NAMESEG_LEN;
    1342           0 :                 break;
    1343             :         case AMLOP_DUALNAMEPREFIX:
    1344           0 :                 node = __aml_search(node, pos+1, create);
    1345           0 :                 node = __aml_search(node, pos+1+AML_NAMESEG_LEN, create);
    1346           0 :                 pos += 1+2*AML_NAMESEG_LEN;
    1347           0 :                 break;
    1348             :         default:
    1349             :                 /* If Relative Search (pos == start), recursively go up root */
    1350             :                 relnode = node;
    1351           0 :                 do {
    1352           0 :                         node = __aml_search(relnode, pos, create);
    1353           0 :                         relnode = relnode->parent;
    1354           0 :                 } while (!node && pos == start && relnode);
    1355           0 :                 pos += AML_NAMESEG_LEN;
    1356           0 :                 break;
    1357             :         }
    1358           0 :         if (node) {
    1359           0 :                 *rval = node->value;
    1360             : 
    1361             :                 /* Dereference ALIAS here */
    1362           0 :                 if ((*rval)->type == AML_OBJTYPE_OBJREF &&
    1363           0 :                     (*rval)->v_objref.type == AMLOP_ALIAS) {
    1364             :                         dnprintf(10, "deref alias: %s\n", aml_nodename(node));
    1365           0 :                         *rval = (*rval)->v_objref.ref;
    1366           0 :                 }
    1367           0 :                 aml_addref(*rval, 0);
    1368             : 
    1369             :                 dnprintf(10, "parsename: %s %x\n", aml_nodename(node),
    1370             :                     (*rval)->type);
    1371           0 :         } else {
    1372           0 :                 *rval = aml_allocvalue(AML_OBJTYPE_NAMEREF, 0, start);
    1373             : 
    1374             :                 dnprintf(10, "%s:%s not found\n", aml_nodename(inode),
    1375             :                     aml_getname(start));
    1376             :         }
    1377             : 
    1378           0 :         return pos;
    1379             : }
    1380             : 
    1381             : /* Decode AML Length field
    1382             :  *  AML Length field is encoded:
    1383             :  *    byte0    byte1    byte2    byte3
    1384             :  *    00xxxxxx                             : if upper bits == 00, length = xxxxxx
    1385             :  *    01--xxxx yyyyyyyy                    : if upper bits == 01, length = yyyyyyyyxxxx
    1386             :  *    10--xxxx yyyyyyyy zzzzzzzz           : if upper bits == 10, length = zzzzzzzzyyyyyyyyxxxx
    1387             :  *    11--xxxx yyyyyyyy zzzzzzzz wwwwwwww  : if upper bits == 11, length = wwwwwwwwzzzzzzzzyyyyyyyyxxxx
    1388             :  */
    1389             : int
    1390           0 : aml_parselength(struct aml_scope *scope)
    1391             : {
    1392             :         int len;
    1393             :         uint8_t lcode;
    1394             : 
    1395           0 :         lcode = *(scope->pos++);
    1396           0 :         if (lcode <= 0x3F)
    1397           0 :                 return lcode;
    1398             : 
    1399             :         /* lcode >= 0x40, multibyte length, get first byte of extended length */
    1400           0 :         len = lcode & 0xF;
    1401           0 :         len += *(scope->pos++) << 4L;
    1402           0 :         if (lcode >= 0x80)
    1403           0 :                 len += *(scope->pos++) << 12L;
    1404           0 :         if (lcode >= 0xC0)
    1405           0 :                 len += *(scope->pos++) << 20L;
    1406           0 :         return len;
    1407           0 : }
    1408             : 
    1409             : /* Get address of end of scope; based on current address */
    1410             : uint8_t *
    1411           0 : aml_parseend(struct aml_scope *scope)
    1412             : {
    1413           0 :         uint8_t *pos = scope->pos;
    1414             :         int len;
    1415             : 
    1416           0 :         len = aml_parselength(scope);
    1417           0 :         if (pos+len > scope->end) {
    1418             :                 dnprintf(10,
    1419             :                     "Bad scope... runover pos:%.4x new end:%.4x scope "
    1420             :                     "end:%.4x\n", aml_pc(pos), aml_pc(pos+len),
    1421             :                     aml_pc(scope->end));
    1422             :                 pos = scope->end;
    1423           0 :         }
    1424           0 :         return pos+len;
    1425             : }
    1426             : 
    1427             : /*
    1428             :  * @@@: Opcode utility functions
    1429             :  */
    1430             : 
    1431             : /*
    1432             :  * @@@: Opcode functions
    1433             :  */
    1434             : 
    1435             : int odp;
    1436             : 
    1437             : const char hext[] = "0123456789ABCDEF";
    1438             : 
    1439             : const char *
    1440           0 : aml_eisaid(uint32_t pid)
    1441             : {
    1442             :         static char id[8];
    1443             : 
    1444           0 :         id[0] = '@' + ((pid >> 2) & 0x1F);
    1445           0 :         id[1] = '@' + ((pid << 3) & 0x18) + ((pid >> 13) & 0x7);
    1446           0 :         id[2] = '@' + ((pid >> 8) & 0x1F);
    1447           0 :         id[3] = hext[(pid >> 20) & 0xF];
    1448           0 :         id[4] = hext[(pid >> 16) & 0xF];
    1449           0 :         id[5] = hext[(pid >> 28) & 0xF];
    1450           0 :         id[6] = hext[(pid >> 24) & 0xF];
    1451           0 :         id[7] = 0;
    1452           0 :         return id;
    1453             : }
    1454             : 
    1455             : /*
    1456             :  * @@@: Default Object creation
    1457             :  */
    1458             : static char osstring[] = "Macrosift Windogs MT";
    1459             : struct aml_defval {
    1460             :         const char              *name;
    1461             :         int                     type;
    1462             :         int64_t                 ival;
    1463             :         const void              *bval;
    1464             :         struct aml_value        **gval;
    1465             : } aml_defobj[] = {
    1466             :         { "_OS_", AML_OBJTYPE_STRING, -1, osstring },
    1467             :         { "_REV", AML_OBJTYPE_INTEGER, 2, NULL },
    1468             :         { "_GL", AML_OBJTYPE_MUTEX, 1, NULL, &aml_global_lock },
    1469             :         { "_OSI", AML_OBJTYPE_METHOD, 1, aml_callosi },
    1470             : 
    1471             :         /* Create default scopes */
    1472             :         { "_GPE" },
    1473             :         { "_PR_" },
    1474             :         { "_SB_" },
    1475             :         { "_TZ_" },
    1476             :         { "_SI_" },
    1477             : 
    1478             :         { NULL }
    1479             : };
    1480             : 
    1481             : /* _OSI Default Method:
    1482             :  * Returns True if string argument matches list of known OS strings
    1483             :  * We return True for Windows to fake out nasty bad AML
    1484             :  */
    1485             : char *aml_valid_osi[] = {
    1486             :         "Windows 2000",
    1487             :         "Windows 2001",
    1488             :         "Windows 2001.1",
    1489             :         "Windows 2001.1 SP1",
    1490             :         "Windows 2001 SP0",
    1491             :         "Windows 2001 SP1",
    1492             :         "Windows 2001 SP2",
    1493             :         "Windows 2001 SP3",
    1494             :         "Windows 2001 SP4",
    1495             :         "Windows 2006",
    1496             :         "Windows 2006.1",
    1497             :         "Windows 2006 SP1",
    1498             :         "Windows 2006 SP2",
    1499             :         "Windows 2009",
    1500             :         "Windows 2012",
    1501             :         "Windows 2013",
    1502             :         "Windows 2015",
    1503             :         NULL
    1504             : };
    1505             : 
    1506             : struct aml_value *
    1507           0 : aml_callosi(struct aml_scope *scope, struct aml_value *val)
    1508             : {
    1509             :         int idx, result=0;
    1510             :         struct aml_value *fa;
    1511             : 
    1512           0 :         fa = aml_getstack(scope, AMLOP_ARG0);
    1513             : 
    1514           0 :         if (hw_vendor != NULL &&
    1515           0 :             (strcmp(hw_vendor, "Apple Inc.") == 0 ||
    1516           0 :             strcmp(hw_vendor, "Apple Computer, Inc.") == 0)) {
    1517           0 :                 if (strcmp(fa->v_string, "Darwin") == 0) {
    1518             :                         dnprintf(10,"osi: returning 1 for %s on %s hardware\n",
    1519             :                             fa->v_string, hw_vendor);
    1520             :                         result = 1;
    1521           0 :                 } else
    1522             :                         dnprintf(10,"osi: on %s hardware, but ignoring %s\n",
    1523             :                             hw_vendor, fa->v_string);
    1524             : 
    1525           0 :                 return aml_allocvalue(AML_OBJTYPE_INTEGER, result, NULL);
    1526             :         }
    1527             : 
    1528           0 :         for (idx=0; !result && aml_valid_osi[idx] != NULL; idx++) {
    1529             :                 dnprintf(10,"osi: %s,%s\n", fa->v_string, aml_valid_osi[idx]);
    1530           0 :                 result = !strcmp(fa->v_string, aml_valid_osi[idx]);
    1531             :         }
    1532             :         dnprintf(10,"@@ OSI found: %x\n", result);
    1533           0 :         return aml_allocvalue(AML_OBJTYPE_INTEGER, result, NULL);
    1534           0 : }
    1535             : 
    1536             : void
    1537           0 : aml_create_defaultobjects(void)
    1538             : {
    1539           0 :         struct aml_value *tmp;
    1540             :         struct aml_defval *def;
    1541             : 
    1542             : #ifdef ACPI_MEMDEBUG
    1543             :         LIST_INIT(&acpi_memhead);
    1544             : #endif
    1545             : 
    1546           0 :         osstring[1] = 'i';
    1547           0 :         osstring[6] = 'o';
    1548           0 :         osstring[15] = 'w';
    1549           0 :         osstring[18] = 'N';
    1550             : 
    1551           0 :         SIMPLEQ_INIT(&aml_root.son);
    1552           0 :         strlcpy(aml_root.name, "\\", sizeof(aml_root.name));
    1553           0 :         aml_root.value = aml_allocvalue(0, 0, NULL);
    1554           0 :         aml_root.value->node = &aml_root;
    1555             : 
    1556           0 :         for (def = aml_defobj; def->name; def++) {
    1557             :                 /* Allocate object value + add to namespace */
    1558           0 :                 aml_parsename(&aml_root, (uint8_t *)def->name, &tmp, 1);
    1559           0 :                 _aml_setvalue(tmp, def->type, def->ival, def->bval);
    1560           0 :                 if (def->gval) {
    1561             :                         /* Set root object pointer */
    1562           0 :                         *def->gval = tmp;
    1563           0 :                 }
    1564           0 :                 aml_delref(&tmp, 0);
    1565             :         }
    1566           0 : }
    1567             : 
    1568             : #ifdef ACPI_DEBUG
    1569             : int
    1570             : aml_print_resource(union acpi_resource *crs, void *arg)
    1571             : {
    1572             :         int typ = AML_CRSTYPE(crs);
    1573             : 
    1574             :         switch (typ) {
    1575             :         case LR_EXTIRQ:
    1576             :                 printf("extirq\tflags:%.2x len:%.2x irq:%.4x\n",
    1577             :                     crs->lr_extirq.flags, crs->lr_extirq.irq_count,
    1578             :                     letoh32(crs->lr_extirq.irq[0]));
    1579             :                 break;
    1580             :         case SR_IRQ:
    1581             :                 printf("irq\t%.4x %.2x\n", letoh16(crs->sr_irq.irq_mask),
    1582             :                     crs->sr_irq.irq_flags);
    1583             :                 break;
    1584             :         case SR_DMA:
    1585             :                 printf("dma\t%.2x %.2x\n", crs->sr_dma.channel,
    1586             :                     crs->sr_dma.flags);
    1587             :                 break;
    1588             :         case SR_IOPORT:
    1589             :                 printf("ioport\tflags:%.2x _min:%.4x _max:%.4x _aln:%.2x _len:%.2x\n",
    1590             :                     crs->sr_ioport.flags, crs->sr_ioport._min,
    1591             :                     crs->sr_ioport._max, crs->sr_ioport._aln,
    1592             :                     crs->sr_ioport._len);
    1593             :                 break;
    1594             :         case SR_STARTDEP:
    1595             :                 printf("startdep\n");
    1596             :                 break;
    1597             :         case SR_ENDDEP:
    1598             :                 printf("enddep\n");
    1599             :                 break;
    1600             :         case LR_WORD:
    1601             :                 printf("word\ttype:%.2x flags:%.2x tflag:%.2x gra:%.4x min:%.4x max:%.4x tra:%.4x len:%.4x\n",
    1602             :                         crs->lr_word.type, crs->lr_word.flags, crs->lr_word.tflags,
    1603             :                         crs->lr_word._gra, crs->lr_word._min, crs->lr_word._max,
    1604             :                         crs->lr_word._tra, crs->lr_word._len);
    1605             :                 break;
    1606             :         case LR_DWORD:
    1607             :                 printf("dword\ttype:%.2x flags:%.2x tflag:%.2x gra:%.8x min:%.8x max:%.8x tra:%.8x len:%.8x\n",
    1608             :                         crs->lr_dword.type, crs->lr_dword.flags, crs->lr_dword.tflags,
    1609             :                         crs->lr_dword._gra, crs->lr_dword._min, crs->lr_dword._max,
    1610             :                         crs->lr_dword._tra, crs->lr_dword._len);
    1611             :                 break;
    1612             :         case LR_QWORD:
    1613             :                 printf("dword\ttype:%.2x flags:%.2x tflag:%.2x gra:%.16llx min:%.16llx max:%.16llx tra:%.16llx len:%.16llx\n",
    1614             :                         crs->lr_qword.type, crs->lr_qword.flags, crs->lr_qword.tflags,
    1615             :                         crs->lr_qword._gra, crs->lr_qword._min, crs->lr_qword._max,
    1616             :                         crs->lr_qword._tra, crs->lr_qword._len);
    1617             :                 break;
    1618             :         default:
    1619             :                 printf("unknown type: %x\n", typ);
    1620             :                 break;
    1621             :         }
    1622             :         return (0);
    1623             : }
    1624             : #endif /* ACPI_DEBUG */
    1625             : 
    1626             : union acpi_resource *aml_mapresource(union acpi_resource *);
    1627             : 
    1628             : union acpi_resource *
    1629           0 : aml_mapresource(union acpi_resource *crs)
    1630             : {
    1631             :         static union acpi_resource map;
    1632             :         int rlen;
    1633             : 
    1634           0 :         rlen = AML_CRSLEN(crs);
    1635           0 :         if (rlen >= sizeof(map))
    1636           0 :                 return crs;
    1637             : 
    1638           0 :         memset(&map, 0, sizeof(map));
    1639           0 :         memcpy(&map, crs, rlen);
    1640             : 
    1641           0 :         return &map;
    1642           0 : }
    1643             : 
    1644             : int
    1645           0 : aml_parse_resource(struct aml_value *res,
    1646             :     int (*crs_enum)(int, union acpi_resource *, void *), void *arg)
    1647             : {
    1648             :         int off, rlen, crsidx;
    1649             :         union acpi_resource *crs;
    1650             : 
    1651           0 :         if (res->type != AML_OBJTYPE_BUFFER || res->length < 5)
    1652           0 :                 return (-1);
    1653           0 :         for (off = 0, crsidx = 0; off < res->length; off += rlen, crsidx++) {
    1654           0 :                 crs = (union acpi_resource *)(res->v_buffer+off);
    1655             : 
    1656           0 :                 rlen = AML_CRSLEN(crs);
    1657           0 :                 if (crs->hdr.typecode == SRT_ENDTAG || !rlen)
    1658             :                         break;
    1659             : 
    1660           0 :                 crs = aml_mapresource(crs);
    1661             : #ifdef ACPI_DEBUG
    1662             :                 aml_print_resource(crs, NULL);
    1663             : #endif
    1664           0 :                 crs_enum(crsidx, crs, arg);
    1665             :         }
    1666             : 
    1667           0 :         return (0);
    1668           0 : }
    1669             : 
    1670             : void
    1671           0 : aml_foreachpkg(struct aml_value *pkg, int start,
    1672             :     void (*fn)(struct aml_value *, void *), void *arg)
    1673             : {
    1674             :         int idx;
    1675             : 
    1676           0 :         if (pkg->type != AML_OBJTYPE_PACKAGE)
    1677           0 :                 return;
    1678           0 :         for (idx=start; idx<pkg->length; idx++)
    1679           0 :                 fn(pkg->v_package[idx], arg);
    1680           0 : }
    1681             : 
    1682             : /*
    1683             :  * Walk nodes and perform fixups for nameref
    1684             :  */
    1685             : int aml_fixup_node(struct aml_node *, void *);
    1686             : 
    1687           0 : int aml_fixup_node(struct aml_node *node, void *arg)
    1688             : {
    1689           0 :         struct aml_value *val = arg;
    1690             :         int i;
    1691             : 
    1692           0 :         if (node->value == NULL)
    1693           0 :                 return (0);
    1694           0 :         if (arg == NULL)
    1695           0 :                 aml_fixup_node(node, node->value);
    1696           0 :         else if (val->type == AML_OBJTYPE_NAMEREF) {
    1697           0 :                 node = aml_searchname(node, val->v_nameref);
    1698           0 :                 if (node && node->value) {
    1699           0 :                         _aml_setvalue(val, AML_OBJTYPE_OBJREF, AMLOP_NAMECHAR,
    1700           0 :                             node->value);
    1701           0 :                 }
    1702           0 :         } else if (val->type == AML_OBJTYPE_PACKAGE) {
    1703           0 :                 for (i = 0; i < val->length; i++)
    1704           0 :                         aml_fixup_node(node, val->v_package[i]);
    1705             :         }
    1706           0 :         return (0);
    1707           0 : }
    1708             : 
    1709             : void
    1710           0 : aml_postparse(void)
    1711             : {
    1712           0 :         aml_walknodes(&aml_root, AML_WALK_PRE, aml_fixup_node, NULL);
    1713           0 : }
    1714             : 
    1715             : #ifndef SMALL_KERNEL
    1716             : const char *
    1717           0 : aml_val_to_string(const struct aml_value *val)
    1718             : {
    1719             :         static char buffer[256];
    1720             : 
    1721             :         int len;
    1722             : 
    1723           0 :         switch (val->type) {
    1724             :         case AML_OBJTYPE_BUFFER:
    1725           0 :                 len = val->length;
    1726           0 :                 if (len >= sizeof(buffer))
    1727             :                         len = sizeof(buffer) - 1;
    1728           0 :                 memcpy(buffer, val->v_buffer, len);
    1729           0 :                 buffer[len] = 0;
    1730           0 :                 break;
    1731             :         case AML_OBJTYPE_STRING:
    1732           0 :                 strlcpy(buffer, val->v_string, sizeof(buffer));
    1733           0 :                 break;
    1734             :         case AML_OBJTYPE_INTEGER:
    1735           0 :                 snprintf(buffer, sizeof(buffer), "%llx", val->v_integer);
    1736           0 :                 break;
    1737             :         default:
    1738           0 :                 snprintf(buffer, sizeof(buffer),
    1739             :                     "Failed to convert type %d to string!", val->type);
    1740           0 :         };
    1741             : 
    1742           0 :         return (buffer);
    1743             : }
    1744             : #endif /* SMALL_KERNEL */
    1745             : 
    1746             : int aml_error;
    1747             : 
    1748             : struct aml_value *aml_gettgt(struct aml_value *, int);
    1749             : struct aml_value *aml_eval(struct aml_scope *, struct aml_value *, int, int,
    1750             :     struct aml_value *);
    1751             : struct aml_value *aml_parsesimple(struct aml_scope *, char,
    1752             :     struct aml_value *);
    1753             : struct aml_value *aml_parse(struct aml_scope *, int, const char *);
    1754             : struct aml_value *aml_seterror(struct aml_scope *, const char *, ...);
    1755             : 
    1756             : struct aml_scope *aml_findscope(struct aml_scope *, int, int);
    1757             : struct aml_scope *aml_pushscope(struct aml_scope *, struct aml_value *,
    1758             :     struct aml_node *, int);
    1759             : struct aml_scope *aml_popscope(struct aml_scope *);
    1760             : 
    1761             : void            aml_showstack(struct aml_scope *);
    1762             : struct aml_value *aml_convert(struct aml_value *, int, int);
    1763             : 
    1764             : int             aml_matchtest(int64_t, int64_t, int);
    1765             : int             aml_match(struct aml_value *, int, int, int, int, int);
    1766             : 
    1767             : int             aml_compare(struct aml_value *, struct aml_value *, int);
    1768             : struct aml_value *aml_concat(struct aml_value *, struct aml_value *);
    1769             : struct aml_value *aml_concatres(struct aml_value *, struct aml_value *);
    1770             : struct aml_value *aml_mid(struct aml_value *, int, int);
    1771             : int             aml_ccrlen(int, union acpi_resource *, void *);
    1772             : 
    1773             : void            aml_store(struct aml_scope *, struct aml_value *, int64_t,
    1774             :     struct aml_value *);
    1775             : 
    1776             : /*
    1777             :  * Reference Count functions
    1778             :  */
    1779             : void
    1780           0 : aml_addref(struct aml_value *val, const char *lbl)
    1781             : {
    1782           0 :         if (val == NULL)
    1783             :                 return;
    1784             :         dnprintf(50, "XAddRef: %p %s:[%s] %d\n",
    1785             :             val, lbl,
    1786             :             val->node ? aml_nodename(val->node) : "INTERNAL",
    1787             :             val->refcnt);
    1788           0 :         val->refcnt++;
    1789           0 : }
    1790             : 
    1791             : /* Decrease reference counter */
    1792             : void
    1793           0 : aml_delref(struct aml_value **pv, const char *lbl)
    1794             : {
    1795             :         struct aml_value *val;
    1796             : 
    1797           0 :         if (pv == NULL || *pv == NULL)
    1798           0 :                 return;
    1799             :         val = *pv;
    1800           0 :         val->refcnt--;
    1801           0 :         if (val->refcnt == 0) {
    1802             :                 dnprintf(50, "XDelRef: %p %s %2d [%s] %s\n",
    1803             :                     val, lbl,
    1804             :                     val->refcnt,
    1805             :                     val->node ? aml_nodename(val->node) : "INTERNAL",
    1806             :                     val->refcnt ? "" : "---------------- FREEING");
    1807             : 
    1808           0 :                 aml_freevalue(val);
    1809           0 :                 acpi_os_free(val);
    1810           0 :                 *pv = NULL;
    1811           0 :         }
    1812           0 : }
    1813             : 
    1814             : /* Walk list of parent scopes until we find one of 'type'
    1815             :  * If endscope is set, mark all intermediate scopes as invalid (used for Method/While) */
    1816             : struct aml_scope *
    1817           0 : aml_findscope(struct aml_scope *scope, int type, int endscope)
    1818             : {
    1819           0 :         while (scope) {
    1820           0 :                 switch (endscope) {
    1821             :                 case AMLOP_RETURN:
    1822           0 :                         scope->pos = scope->end;
    1823           0 :                         if (scope->type == AMLOP_WHILE)
    1824           0 :                                 scope->pos = NULL;
    1825             :                         break;
    1826             :                 case AMLOP_CONTINUE:
    1827           0 :                         scope->pos = scope->end;
    1828           0 :                         break;
    1829             :                 case AMLOP_BREAK:
    1830           0 :                         scope->pos = scope->end;
    1831           0 :                         if (scope->type == type)
    1832           0 :                                 scope->parent->pos = scope->end;
    1833             :                         break;
    1834             :                 }
    1835           0 :                 if (scope->type == type)
    1836             :                         break;
    1837           0 :                 scope = scope->parent;
    1838             :         }
    1839           0 :         return scope;
    1840             : }
    1841             : 
    1842             : struct aml_value *
    1843           0 : aml_getstack(struct aml_scope *scope, int opcode)
    1844             : {
    1845             :         struct aml_value *sp;
    1846             : 
    1847             :         sp = NULL;
    1848           0 :         scope = aml_findscope(scope, AMLOP_METHOD, 0);
    1849           0 :         if (scope == NULL)
    1850           0 :                 return NULL;
    1851           0 :         if (opcode >= AMLOP_LOCAL0 && opcode <= AMLOP_LOCAL7) {
    1852           0 :                 if (scope->locals == NULL)
    1853           0 :                         scope->locals = aml_allocvalue(AML_OBJTYPE_PACKAGE, 8, NULL);
    1854           0 :                 sp = scope->locals->v_package[opcode - AMLOP_LOCAL0];
    1855           0 :                 sp->stack = opcode;
    1856           0 :         } else if (opcode >= AMLOP_ARG0 && opcode <= AMLOP_ARG6) {
    1857           0 :                 if (scope->args == NULL)
    1858           0 :                         scope->args = aml_allocvalue(AML_OBJTYPE_PACKAGE, 7, NULL);
    1859           0 :                 sp = scope->args->v_package[opcode - AMLOP_ARG0];
    1860           0 :                 if (sp->type == AML_OBJTYPE_OBJREF)
    1861           0 :                         sp = sp->v_objref.ref;
    1862             :         }
    1863           0 :         return sp;
    1864           0 : }
    1865             : 
    1866             : #ifdef ACPI_DEBUG
    1867             : /* Dump AML Stack */
    1868             : void
    1869             : aml_showstack(struct aml_scope *scope)
    1870             : {
    1871             :         struct aml_value *sp;
    1872             :         int idx;
    1873             : 
    1874             :         dnprintf(10, "===== Stack %s:%s\n", aml_nodename(scope->node),
    1875             :             aml_mnem(scope->type, 0));
    1876             :         for (idx=0; scope->args && idx<7; idx++) {
    1877             :                 sp = aml_getstack(scope, AMLOP_ARG0+idx);
    1878             :                 if (sp && sp->type) {
    1879             :                         dnprintf(10," Arg%d: ", idx);
    1880             :                         aml_showvalue(sp);
    1881             :                 }
    1882             :         }
    1883             :         for (idx=0; scope->locals && idx<8; idx++) {
    1884             :                 sp = aml_getstack(scope, AMLOP_LOCAL0+idx);
    1885             :                 if (sp && sp->type) {
    1886             :                         dnprintf(10," Local%d: ", idx);
    1887             :                         aml_showvalue(sp);
    1888             :                 }
    1889             :         }
    1890             : }
    1891             : #endif
    1892             : 
    1893             : /* Create a new scope object */
    1894             : struct aml_scope *
    1895           0 : aml_pushscope(struct aml_scope *parent, struct aml_value *range,
    1896             :     struct aml_node *node, int type)
    1897             : {
    1898             :         struct aml_scope *scope;
    1899             :         uint8_t *start, *end;
    1900             : 
    1901           0 :         if (range->type == AML_OBJTYPE_METHOD) {
    1902           0 :                 start = range->v_method.start;
    1903           0 :                 end = range->v_method.end;
    1904           0 :         } else {
    1905           0 :                 start = range->v_buffer;
    1906           0 :                 end = start + range->length;
    1907           0 :                 if (start == end)
    1908           0 :                         return NULL;
    1909             :         }
    1910           0 :         scope = acpi_os_malloc(sizeof(struct aml_scope));
    1911           0 :         if (scope == NULL)
    1912           0 :                 return NULL;
    1913             : 
    1914           0 :         scope->node = node;
    1915           0 :         scope->start = start;
    1916           0 :         scope->end = end;
    1917           0 :         scope->pos = scope->start;
    1918           0 :         scope->parent = parent;
    1919           0 :         scope->type = type;
    1920           0 :         scope->sc = acpi_softc;
    1921             : 
    1922           0 :         if (parent)
    1923           0 :                 scope->depth = parent->depth+1;
    1924             : 
    1925           0 :         aml_lastscope = scope;
    1926             : 
    1927           0 :         return scope;
    1928           0 : }
    1929             : 
    1930             : /* Free a scope object and any children */
    1931             : struct aml_scope *
    1932           0 : aml_popscope(struct aml_scope *scope)
    1933             : {
    1934             :         struct aml_scope *nscope;
    1935             : 
    1936           0 :         if (scope == NULL)
    1937           0 :                 return NULL;
    1938             : 
    1939           0 :         nscope = scope->parent;
    1940             : 
    1941           0 :         if (scope->type == AMLOP_METHOD)
    1942           0 :                 aml_delchildren(scope->node);
    1943           0 :         if (scope->locals) {
    1944           0 :                 aml_freevalue(scope->locals);
    1945           0 :                 acpi_os_free(scope->locals);
    1946           0 :                 scope->locals = NULL;
    1947           0 :         }
    1948           0 :         if (scope->args) {
    1949           0 :                 aml_freevalue(scope->args);
    1950           0 :                 acpi_os_free(scope->args);
    1951           0 :                 scope->args = NULL;
    1952           0 :         }
    1953           0 :         acpi_os_free(scope);
    1954           0 :         aml_lastscope = nscope;
    1955             : 
    1956           0 :         return nscope;
    1957           0 : }
    1958             : 
    1959             : /* Test AMLOP_MATCH codes */
    1960             : int
    1961           0 : aml_matchtest(int64_t a, int64_t b, int op)
    1962             : {
    1963           0 :         switch (op) {
    1964             :         case AML_MATCH_TR:
    1965           0 :                 return (1);
    1966             :         case AML_MATCH_EQ:
    1967           0 :                 return (a == b);
    1968             :         case AML_MATCH_LT:
    1969           0 :                 return (a < b);
    1970             :         case AML_MATCH_LE:
    1971           0 :                 return (a <= b);
    1972             :         case AML_MATCH_GE:
    1973           0 :                 return (a >= b);
    1974             :         case AML_MATCH_GT:
    1975           0 :                 return (a > b);
    1976             :         }
    1977           0 :         return (0);
    1978           0 : }
    1979             : 
    1980             : /* Search a package for a matching value */
    1981             : int
    1982           0 : aml_match(struct aml_value *pkg, int index,
    1983             :            int op1, int v1,
    1984             :            int op2, int v2)
    1985             : {
    1986           0 :         struct aml_value *tmp;
    1987             :         int flag;
    1988             : 
    1989           0 :         while (index < pkg->length) {
    1990             :                 /* Convert package value to integer */
    1991           0 :                 tmp = aml_convert(pkg->v_package[index],
    1992             :                     AML_OBJTYPE_INTEGER, -1);
    1993             : 
    1994             :                 /* Perform test */
    1995           0 :                 flag = aml_matchtest(tmp->v_integer, v1, op1) &&
    1996           0 :                     aml_matchtest(tmp->v_integer, v2, op2);
    1997           0 :                 aml_delref(&tmp, "xmatch");
    1998             : 
    1999           0 :                 if (flag)
    2000           0 :                         return index;
    2001           0 :                 index++;
    2002             :         }
    2003           0 :         return -1;
    2004           0 : }
    2005             : 
    2006             : /*
    2007             :  * Conversion routines
    2008             :  */
    2009             : int64_t
    2010           0 : aml_hextoint(const char *str)
    2011             : {
    2012             :         int64_t v = 0;
    2013             :         char c;
    2014             : 
    2015           0 :         while (*str) {
    2016           0 :                 if (*str >= '0' && *str <= '9')
    2017           0 :                         c = *(str++) - '0';
    2018           0 :                 else if (*str >= 'a' && *str <= 'f')
    2019           0 :                         c = *(str++) - 'a' + 10;
    2020           0 :                 else if (*str >= 'A' && *str <= 'F')
    2021           0 :                         c = *(str++) - 'A' + 10;
    2022             :                 else
    2023             :                         break;
    2024           0 :                 v = (v << 4) + c;
    2025             :         }
    2026           0 :         return v;
    2027             : 
    2028             : }
    2029             : 
    2030             : struct aml_value *
    2031           0 : aml_convert(struct aml_value *a, int ctype, int clen)
    2032             : {
    2033             :         struct aml_value *c = NULL;
    2034             : 
    2035             :         /* Object is already this type */
    2036           0 :         if (clen == -1)
    2037           0 :                 clen = a->length;
    2038           0 :         if (a->type == ctype) {
    2039           0 :                 aml_addref(a, "XConvert");
    2040           0 :                 return a;
    2041             :         }
    2042           0 :         switch (ctype) {
    2043             :         case AML_OBJTYPE_BUFFER:
    2044             :                 dnprintf(10,"convert to buffer\n");
    2045           0 :                 switch (a->type) {
    2046             :                 case AML_OBJTYPE_INTEGER:
    2047           0 :                         c = aml_allocvalue(AML_OBJTYPE_BUFFER, a->length,
    2048           0 :                             &a->v_integer);
    2049           0 :                         break;
    2050             :                 case AML_OBJTYPE_STRING:
    2051           0 :                         c = aml_allocvalue(AML_OBJTYPE_BUFFER, a->length,
    2052           0 :                             a->v_string);
    2053           0 :                         break;
    2054             :                 }
    2055             :                 break;
    2056             :         case AML_OBJTYPE_INTEGER:
    2057             :                 dnprintf(10,"convert to integer : %x\n", a->type);
    2058           0 :                 switch (a->type) {
    2059             :                 case AML_OBJTYPE_BUFFER:
    2060           0 :                         c = aml_allocvalue(AML_OBJTYPE_INTEGER, 0, NULL);
    2061           0 :                         memcpy(&c->v_integer, a->v_buffer,
    2062             :                             min(a->length, c->length));
    2063           0 :                         break;
    2064             :                 case AML_OBJTYPE_STRING:
    2065           0 :                         c = aml_allocvalue(AML_OBJTYPE_INTEGER, 0, NULL);
    2066           0 :                         c->v_integer = aml_hextoint(a->v_string);
    2067           0 :                         break;
    2068             :                 case AML_OBJTYPE_UNINITIALIZED:
    2069           0 :                         c = aml_allocvalue(AML_OBJTYPE_INTEGER, 0, NULL);
    2070           0 :                         break;
    2071             :                 }
    2072             :                 break;
    2073             :         case AML_OBJTYPE_STRING:
    2074             :         case AML_OBJTYPE_HEXSTRING:
    2075             :         case AML_OBJTYPE_DECSTRING:
    2076             :                 dnprintf(10,"convert to string\n");
    2077           0 :                 switch (a->type) {
    2078             :                 case AML_OBJTYPE_INTEGER:
    2079           0 :                         c = aml_allocvalue(AML_OBJTYPE_STRING, 20, NULL);
    2080           0 :                         snprintf(c->v_string, c->length, (ctype == AML_OBJTYPE_HEXSTRING) ?
    2081           0 :                             "0x%llx" : "%lld", a->v_integer);
    2082           0 :                         break;
    2083             :                 case AML_OBJTYPE_BUFFER:
    2084           0 :                         c = aml_allocvalue(AML_OBJTYPE_STRING, a->length,
    2085           0 :                             a->v_buffer);
    2086           0 :                         break;
    2087             :                 case AML_OBJTYPE_STRING:
    2088           0 :                         aml_addref(a, "XConvert");
    2089           0 :                         return a;
    2090             :                 }
    2091             :                 break;
    2092             :         }
    2093           0 :         if (c == NULL) {
    2094             : #ifndef SMALL_KERNEL
    2095           0 :                 aml_showvalue(a);
    2096             : #endif
    2097           0 :                 aml_die("Could not convert %x to %x\n", a->type, ctype);
    2098           0 :         }
    2099           0 :         return c;
    2100           0 : }
    2101             : 
    2102             : int
    2103           0 : aml_compare(struct aml_value *a1, struct aml_value *a2, int opcode)
    2104             : {
    2105             :         int rc = 0;
    2106             : 
    2107             :         /* Convert A2 to type of A1 */
    2108           0 :         a2 = aml_convert(a2, a1->type, -1);
    2109           0 :         if (a1->type == AML_OBJTYPE_INTEGER)
    2110           0 :                 rc = aml_evalexpr(a1->v_integer, a2->v_integer, opcode);
    2111             :         else {
    2112             :                 /* Perform String/Buffer comparison */
    2113           0 :                 rc = memcmp(a1->v_buffer, a2->v_buffer,
    2114             :                     min(a1->length, a2->length));
    2115           0 :                 if (rc == 0) {
    2116             :                         /* If buffers match, which one is longer */
    2117           0 :                         rc = a1->length - a2->length;
    2118           0 :                 }
    2119             :                 /* Perform comparison against zero */
    2120           0 :                 rc = aml_evalexpr(rc, 0, opcode);
    2121             :         }
    2122             :         /* Either deletes temp buffer, or decrease refcnt on original A2 */
    2123           0 :         aml_delref(&a2, "xcompare");
    2124           0 :         return rc;
    2125             : }
    2126             : 
    2127             : /* Concatenate two objects, returning pointer to new object */
    2128             : struct aml_value *
    2129           0 : aml_concat(struct aml_value *a1, struct aml_value *a2)
    2130             : {
    2131             :         struct aml_value *c = NULL;
    2132             : 
    2133             :         /* Convert arg2 to type of arg1 */
    2134           0 :         a2 = aml_convert(a2, a1->type, -1);
    2135           0 :         switch (a1->type) {
    2136             :         case AML_OBJTYPE_INTEGER:
    2137           0 :                 c = aml_allocvalue(AML_OBJTYPE_BUFFER,
    2138           0 :                     a1->length + a2->length, NULL);
    2139           0 :                 memcpy(c->v_buffer, &a1->v_integer, a1->length);
    2140           0 :                 memcpy(c->v_buffer+a1->length, &a2->v_integer, a2->length);
    2141           0 :                 break;
    2142             :         case AML_OBJTYPE_BUFFER:
    2143           0 :                 c = aml_allocvalue(AML_OBJTYPE_BUFFER,
    2144           0 :                     a1->length + a2->length, NULL);
    2145           0 :                 memcpy(c->v_buffer, a1->v_buffer, a1->length);
    2146           0 :                 memcpy(c->v_buffer+a1->length, a2->v_buffer, a2->length);
    2147           0 :                 break;
    2148             :         case AML_OBJTYPE_STRING:
    2149           0 :                 c = aml_allocvalue(AML_OBJTYPE_STRING,
    2150           0 :                     a1->length + a2->length, NULL);
    2151           0 :                 memcpy(c->v_string, a1->v_string, a1->length);
    2152           0 :                 memcpy(c->v_string+a1->length, a2->v_string, a2->length);
    2153           0 :                 break;
    2154             :         default:
    2155           0 :                 aml_die("concat type mismatch %d != %d\n", a1->type, a2->type);
    2156           0 :                 break;
    2157             :         }
    2158             :         /* Either deletes temp buffer, or decrease refcnt on original A2 */
    2159           0 :         aml_delref(&a2, "xconcat");
    2160           0 :         return c;
    2161             : }
    2162             : 
    2163             : /* Calculate length of Resource Template */
    2164             : int
    2165           0 : aml_ccrlen(int crsidx, union acpi_resource *rs, void *arg)
    2166             : {
    2167           0 :         int *plen = arg;
    2168             : 
    2169           0 :         *plen += AML_CRSLEN(rs);
    2170           0 :         return (0);
    2171             : }
    2172             : 
    2173             : /* Concatenate resource templates, returning pointer to new object */
    2174             : struct aml_value *
    2175           0 : aml_concatres(struct aml_value *a1, struct aml_value *a2)
    2176             : {
    2177             :         struct aml_value *c;
    2178           0 :         int l1 = 0, l2 = 0, l3 = 2;
    2179           0 :         uint8_t a3[] = { SRT_ENDTAG, 0x00 };
    2180             : 
    2181           0 :         if (a1->type != AML_OBJTYPE_BUFFER || a2->type != AML_OBJTYPE_BUFFER)
    2182           0 :                 aml_die("concatres: not buffers\n");
    2183             : 
    2184             :         /* Walk a1, a2, get length minus end tags, concatenate buffers, add end tag */
    2185           0 :         aml_parse_resource(a1, aml_ccrlen, &l1);
    2186           0 :         aml_parse_resource(a2, aml_ccrlen, &l2);
    2187             : 
    2188             :         /* Concatenate buffers, add end tag */
    2189           0 :         c = aml_allocvalue(AML_OBJTYPE_BUFFER, l1+l2+l3, NULL);
    2190           0 :         memcpy(c->v_buffer,    a1->v_buffer, l1);
    2191           0 :         memcpy(c->v_buffer+l1, a2->v_buffer, l2);
    2192           0 :         memcpy(c->v_buffer+l1+l2, a3,        l3);
    2193             : 
    2194           0 :         return c;
    2195           0 : }
    2196             : 
    2197             : /* Extract substring from string or buffer */
    2198             : struct aml_value *
    2199           0 : aml_mid(struct aml_value *src, int index, int length)
    2200             : {
    2201           0 :         if (index > src->length)
    2202           0 :                 index = src->length;
    2203           0 :         if ((index + length) > src->length)
    2204           0 :                 length = src->length - index;
    2205           0 :         return aml_allocvalue(src->type, length, src->v_buffer + index);
    2206             : }
    2207             : 
    2208             : /*
    2209             :  * Field I/O utility functions
    2210             :  */
    2211             : void aml_createfield(struct aml_value *, int, struct aml_value *, int, int,
    2212             :     struct aml_value *, int, int);
    2213             : void aml_parsefieldlist(struct aml_scope *, int, int,
    2214             :     struct aml_value *, struct aml_value *, int);
    2215             : 
    2216             : int
    2217           0 : aml_evalhid(struct aml_node *node, struct aml_value *val)
    2218             : {
    2219           0 :         if (aml_evalname(acpi_softc, node, "_HID", 0, NULL, val))
    2220           0 :                 return (-1);
    2221             : 
    2222             :         /* Integer _HID: convert to EISA ID */
    2223           0 :         if (val->type == AML_OBJTYPE_INTEGER)
    2224           0 :                 _aml_setvalue(val, AML_OBJTYPE_STRING, -1, aml_eisaid(val->v_integer));
    2225           0 :         return (0);
    2226           0 : }
    2227             : 
    2228             : int
    2229           0 : aml_opreg_sysmem_handler(void *cookie, int iodir, uint64_t address, int size,
    2230             :     uint64_t *value)
    2231             : {
    2232           0 :         return acpi_gasio(acpi_softc, iodir, GAS_SYSTEM_MEMORY,
    2233           0 :             address, size, size, value);
    2234             : }
    2235             : 
    2236             : int
    2237           0 : aml_opreg_sysio_handler(void *cookie, int iodir, uint64_t address, int size,
    2238             :     uint64_t *value)
    2239             : {
    2240           0 :         return acpi_gasio(acpi_softc, iodir, GAS_SYSTEM_IOSPACE,
    2241           0 :             address, size, size, value);
    2242             : }
    2243             : 
    2244             : int
    2245           0 : aml_opreg_pcicfg_handler(void *cookie, int iodir, uint64_t address, int size,
    2246             :     uint64_t *value)
    2247             : {
    2248           0 :         return acpi_gasio(acpi_softc, iodir, GAS_PCI_CFG_SPACE,
    2249           0 :             address, size, size, value);
    2250             : }
    2251             : 
    2252             : int
    2253           0 : aml_opreg_ec_handler(void *cookie, int iodir, uint64_t address, int size,
    2254             :     uint64_t *value)
    2255             : {
    2256           0 :         return acpi_gasio(acpi_softc, iodir, GAS_EMBEDDED,
    2257           0 :             address, size, size, value);
    2258             : }
    2259             : 
    2260             : struct aml_regionspace {
    2261             :         void *cookie;
    2262             :         int (*handler)(void *, int, uint64_t, int, uint64_t *);
    2263             : };
    2264             : 
    2265             : struct aml_regionspace aml_regionspace[256] = {
    2266             :         [ACPI_OPREG_SYSMEM] = { NULL, aml_opreg_sysmem_handler },
    2267             :         [ACPI_OPREG_SYSIO] = { NULL, aml_opreg_sysio_handler },
    2268             :         [ACPI_OPREG_PCICFG] = { NULL, aml_opreg_pcicfg_handler },
    2269             :         [ACPI_OPREG_EC] = { NULL, aml_opreg_ec_handler },
    2270             : };
    2271             : 
    2272             : void
    2273           0 : aml_register_regionspace(struct aml_node *node, int iospace, void *cookie,
    2274             :     int (*handler)(void *, int, uint64_t, int, uint64_t *))
    2275             : {
    2276           0 :         struct aml_value arg[2];
    2277             : 
    2278           0 :         KASSERT(iospace >= 0 && iospace < 256);
    2279             : 
    2280           0 :         aml_regionspace[iospace].cookie = cookie;
    2281           0 :         aml_regionspace[iospace].handler = handler;
    2282             : 
    2283             :         /* Register address space. */
    2284           0 :         memset(&arg, 0, sizeof(arg));
    2285           0 :         arg[0].type = AML_OBJTYPE_INTEGER;
    2286           0 :         arg[0].v_integer = iospace;
    2287           0 :         arg[1].type = AML_OBJTYPE_INTEGER;
    2288           0 :         arg[1].v_integer = 1;
    2289           0 :         node = aml_searchname(node, "_REG");
    2290           0 :         if (node)
    2291           0 :                 aml_evalnode(acpi_softc, node, 2, arg, NULL);
    2292           0 : }
    2293             : 
    2294             : void aml_rwgen(struct aml_value *, int, int, struct aml_value *, int, int);
    2295             : void aml_rwgpio(struct aml_value *, int, int, struct aml_value *, int, int);
    2296             : void aml_rwgsb(struct aml_value *, int, int, int, struct aml_value *, int, int);
    2297             : void aml_rwindexfield(struct aml_value *, struct aml_value *val, int);
    2298             : void aml_rwfield(struct aml_value *, int, int, struct aml_value *, int);
    2299             : 
    2300             : /* Get PCI address for opregion objects */
    2301             : int
    2302           0 : aml_rdpciaddr(struct aml_node *pcidev, union amlpci_t *addr)
    2303             : {
    2304           0 :         int64_t res;
    2305             : 
    2306           0 :         addr->bus = 0;
    2307           0 :         addr->seg = 0;
    2308           0 :         if (aml_evalinteger(acpi_softc, pcidev, "_ADR", 0, NULL, &res) == 0) {
    2309           0 :                 addr->fun = res & 0xFFFF;
    2310           0 :                 addr->dev = res >> 16;
    2311           0 :         }
    2312           0 :         while (pcidev != NULL) {
    2313             :                 /* HID device (PCI or PCIE root): eval _SEG and _BBN */
    2314           0 :                 if (__aml_search(pcidev, "_HID", 0)) {
    2315           0 :                         if (aml_evalinteger(acpi_softc, pcidev, "_SEG",
    2316           0 :                                 0, NULL, &res) == 0) {
    2317           0 :                                 addr->seg = res;
    2318           0 :                         }
    2319           0 :                         if (aml_evalinteger(acpi_softc, pcidev, "_BBN",
    2320           0 :                                 0, NULL, &res) == 0) {
    2321           0 :                                 addr->bus = res;
    2322           0 :                                 break;
    2323             :                         }
    2324             :                 }
    2325           0 :                 pcidev = pcidev->parent;
    2326             :         }
    2327           0 :         return (0);
    2328           0 : }
    2329             : 
    2330             : int
    2331           0 : acpi_genio(struct acpi_softc *sc, int iodir, int iospace, uint64_t address,
    2332             :     int access_size, int len, void *buffer)
    2333             : {
    2334           0 :         struct aml_regionspace *region = &aml_regionspace[iospace];
    2335             :         uint8_t *pb;
    2336             :         int reg;
    2337             : 
    2338             :         dnprintf(50, "genio: %.2x 0x%.8llx %s\n",
    2339             :             iospace, address, (iodir == ACPI_IOWRITE) ? "write" : "read");
    2340             : 
    2341           0 :         KASSERT((len % access_size) == 0);
    2342             : 
    2343             :         pb = (uint8_t *)buffer;
    2344           0 :         for (reg = 0; reg < len; reg += access_size) {
    2345           0 :                 uint64_t value;
    2346             :                 int err;
    2347             : 
    2348           0 :                 if (iodir == ACPI_IOREAD) {
    2349           0 :                         err = region->handler(region->cookie, iodir,
    2350           0 :                             address + reg, access_size, &value);
    2351           0 :                         if (err)
    2352           0 :                                 return err;
    2353           0 :                         switch (access_size) {
    2354             :                         case 1:
    2355           0 :                                 *(uint8_t *)(pb + reg) = value;
    2356           0 :                                 break;
    2357             :                         case 2:
    2358           0 :                                 *(uint16_t *)(pb + reg) = value;
    2359           0 :                                 break;
    2360             :                         case 4:
    2361           0 :                                 *(uint32_t *)(pb + reg) = value;
    2362           0 :                                 break;
    2363             :                         default:
    2364           0 :                                 printf("%s: invalid access size %d on read\n",
    2365             :                                     __func__, access_size);
    2366           0 :                                 return -1;
    2367             :                         }
    2368             :                 } else {
    2369           0 :                         switch (access_size) {
    2370             :                         case 1:
    2371           0 :                                 value = *(uint8_t *)(pb + reg);
    2372           0 :                                 break;
    2373             :                         case 2:
    2374           0 :                                 value = *(uint16_t *)(pb + reg);
    2375           0 :                                 break;
    2376             :                         case 4:
    2377           0 :                                 value = *(uint32_t *)(pb + reg);
    2378           0 :                                 break;
    2379             :                         default:
    2380           0 :                                 printf("%s: invalid access size %d on write\n",
    2381             :                                     __func__, access_size);
    2382           0 :                                 return -1;
    2383             :                         }
    2384           0 :                         err = region->handler(region->cookie, iodir,
    2385           0 :                             address + reg, access_size, &value);
    2386           0 :                         if (err)
    2387           0 :                                 return err;
    2388             :                 }
    2389           0 :         }
    2390             : 
    2391           0 :         return 0;
    2392           0 : }
    2393             : 
    2394             : /* Read/Write from opregion object */
    2395             : void
    2396           0 : aml_rwgen(struct aml_value *rgn, int bpos, int blen, struct aml_value *val,
    2397             :     int mode, int flag)
    2398             : {
    2399           0 :         struct aml_value tmp;
    2400           0 :         union amlpci_t pi;
    2401             :         void *tbit, *vbit;
    2402             :         int tlen, type, sz;
    2403             : 
    2404             :         dnprintf(10," %5s %.2x %.8llx %.4x [%s]\n",
    2405             :                 mode == ACPI_IOREAD ? "read" : "write",
    2406             :                 rgn->v_opregion.iospace,
    2407             :                 rgn->v_opregion.iobase + (bpos >> 3),
    2408             :                 blen, aml_nodename(rgn->node));
    2409           0 :         memset(&tmp, 0, sizeof(tmp));
    2410             : 
    2411             :         /* Get field access size */
    2412           0 :         switch (AML_FIELD_ACCESS(flag)) {
    2413             :         case AML_FIELD_WORDACC:
    2414             :                 sz = 2;
    2415           0 :                 break;
    2416             :         case AML_FIELD_DWORDACC:
    2417             :                 sz = 4;
    2418           0 :                 break;
    2419             :         case AML_FIELD_QWORDACC:
    2420             :                 sz = 8;
    2421           0 :                 break;
    2422             :         default:
    2423             :                 sz = 1;
    2424           0 :                 break;
    2425             :         }
    2426             : 
    2427           0 :         pi.addr = (rgn->v_opregion.iobase + (bpos >> 3)) & ~(sz - 1);
    2428           0 :         bpos += ((rgn->v_opregion.iobase & (sz - 1)) << 3);
    2429           0 :         bpos &= ((sz << 3) - 1);
    2430             : 
    2431           0 :         if (rgn->v_opregion.iospace == ACPI_OPREG_PCICFG) {
    2432             :                 /* Get PCI Root Address for this opregion */
    2433           0 :                 aml_rdpciaddr(rgn->node->parent, &pi);
    2434           0 :         }
    2435             : 
    2436           0 :         tbit = &tmp.v_integer;
    2437           0 :         vbit = &val->v_integer;
    2438           0 :         tlen = roundup(bpos + blen, sz << 3);
    2439           0 :         type = rgn->v_opregion.iospace;
    2440             : 
    2441           0 :         if (aml_regionspace[type].handler == NULL) {
    2442           0 :                 printf("%s: unregistered RegionSpace 0x%x\n", __func__, type);
    2443           0 :                 return;
    2444             :         }
    2445             : 
    2446             :         /* Allocate temporary storage */
    2447           0 :         if (tlen > aml_intlen) {
    2448           0 :                 _aml_setvalue(&tmp, AML_OBJTYPE_BUFFER, tlen >> 3, 0);
    2449           0 :                 tbit = tmp.v_buffer;
    2450           0 :         }
    2451             : 
    2452           0 :         if (blen > aml_intlen) {
    2453           0 :                 if (mode == ACPI_IOREAD) {
    2454             :                         /* Read from a large field:  create buffer */
    2455           0 :                         _aml_setvalue(val, AML_OBJTYPE_BUFFER, (blen + 7) >> 3, 0);
    2456           0 :                 } else {
    2457             :                         /* Write to a large field.. create or convert buffer */
    2458           0 :                         val = aml_convert(val, AML_OBJTYPE_BUFFER, -1);
    2459             : 
    2460           0 :                         if (blen > (val->length << 3))
    2461           0 :                                 blen = val->length << 3;
    2462             :                 }
    2463           0 :                 vbit = val->v_buffer;
    2464           0 :         } else {
    2465           0 :                 if (mode == ACPI_IOREAD) {
    2466             :                         /* Read from a short field.. initialize integer */
    2467           0 :                         _aml_setvalue(val, AML_OBJTYPE_INTEGER, 0, 0);
    2468           0 :                 } else {
    2469             :                         /* Write to a short field.. convert to integer */
    2470           0 :                         val = aml_convert(val, AML_OBJTYPE_INTEGER, -1);
    2471             :                 }
    2472             :         }
    2473             : 
    2474           0 :         if (mode == ACPI_IOREAD) {
    2475             :                 /* Read bits from opregion */
    2476           0 :                 acpi_genio(acpi_softc, ACPI_IOREAD, type, pi.addr,
    2477           0 :                     sz, tlen >> 3, tbit);
    2478           0 :                 aml_bufcpy(vbit, 0, tbit, bpos, blen);
    2479           0 :         } else {
    2480             :                 /* Write bits to opregion */
    2481           0 :                 if (AML_FIELD_UPDATE(flag) == AML_FIELD_PRESERVE &&
    2482           0 :                     (bpos != 0 || blen != tlen)) {
    2483           0 :                         acpi_genio(acpi_softc, ACPI_IOREAD, type, pi.addr,
    2484           0 :                             sz, tlen >> 3, tbit);
    2485           0 :                 } else if (AML_FIELD_UPDATE(flag) == AML_FIELD_WRITEASONES) {
    2486           0 :                         memset(tbit, 0xff, tmp.length);
    2487           0 :                 }
    2488             :                 /* Copy target bits, then write to region */
    2489           0 :                 aml_bufcpy(tbit, bpos, vbit, 0, blen);
    2490           0 :                 acpi_genio(acpi_softc, ACPI_IOWRITE, type, pi.addr,
    2491           0 :                     sz, tlen >> 3, tbit);
    2492             : 
    2493           0 :                 aml_delref(&val, "fld.write");
    2494             :         }
    2495           0 :         aml_freevalue(&tmp);
    2496           0 : }
    2497             : 
    2498             : void
    2499           0 : aml_rwgpio(struct aml_value *conn, int bpos, int blen, struct aml_value *val,
    2500             :     int mode, int flag)
    2501             : {
    2502           0 :         union acpi_resource *crs = (union acpi_resource *)conn->v_buffer;
    2503             :         struct aml_node *node;
    2504             :         uint16_t pin;
    2505             :         int v = 0;
    2506             : 
    2507           0 :         if (conn->type != AML_OBJTYPE_BUFFER || conn->length < 5 ||
    2508           0 :             AML_CRSTYPE(crs) != LR_GPIO || AML_CRSLEN(crs) > conn->length)
    2509           0 :                 aml_die("Invalid GpioIo");
    2510           0 :         if (bpos != 0 || blen != 1)
    2511           0 :                 aml_die("Invalid GpioIo access");
    2512             : 
    2513           0 :         node = aml_searchname(conn->node,
    2514           0 :             (char *)&crs->pad[crs->lr_gpio.res_off]);
    2515           0 :         pin = *(uint16_t *)&crs->pad[crs->lr_gpio.pin_off];
    2516             : 
    2517           0 :         if (node == NULL || node->gpio == NULL)
    2518           0 :                 aml_die("Could not find GpioIo pin");
    2519             : 
    2520           0 :         if (mode == ACPI_IOWRITE) {
    2521           0 :                 v = aml_val2int(val);
    2522           0 :                 node->gpio->write_pin(node->gpio->cookie, pin, v);
    2523           0 :         } else {
    2524           0 :                 v = node->gpio->read_pin(node->gpio->cookie, pin);
    2525           0 :                 _aml_setvalue(val, AML_OBJTYPE_INTEGER, v, NULL);
    2526             :         }
    2527           0 : }
    2528             : 
    2529             : #ifndef SMALL_KERNEL
    2530             : 
    2531             : void
    2532           0 : aml_rwgsb(struct aml_value *conn, int alen, int bpos, int blen,
    2533             :     struct aml_value *val, int mode, int flag)
    2534             : {
    2535           0 :         union acpi_resource *crs = (union acpi_resource *)conn->v_buffer;
    2536             :         struct aml_node *node;
    2537             :         i2c_tag_t tag;
    2538             :         i2c_op_t op;
    2539             :         i2c_addr_t addr;
    2540             :         int cmdlen, buflen;
    2541           0 :         uint8_t cmd;
    2542             :         uint8_t *buf;
    2543             :         int err;
    2544             : 
    2545           0 :         if (conn->type != AML_OBJTYPE_BUFFER || conn->length < 5 ||
    2546           0 :             AML_CRSTYPE(crs) != LR_SERBUS || AML_CRSLEN(crs) > conn->length ||
    2547           0 :             crs->lr_i2cbus.revid != 1 || crs->lr_i2cbus.type != LR_SERBUS_I2C)
    2548           0 :                 aml_die("Invalid GenericSerialBus");
    2549           0 :         if (AML_FIELD_ACCESS(flag) != AML_FIELD_BUFFERACC ||
    2550           0 :             bpos & 0x3 || blen != 8)
    2551           0 :                 aml_die("Invalid GenericSerialBus access");
    2552             : 
    2553           0 :         node = aml_searchname(conn->node,
    2554           0 :             (char *)&crs->lr_i2cbus.vdata[crs->lr_i2cbus.tlength - 6]);
    2555             : 
    2556           0 :         if (node == NULL || node->i2c == NULL)
    2557           0 :                 aml_die("Could not find GenericSerialBus controller");
    2558             : 
    2559           0 :         switch (((flag >> 6) & 0x3)) {
    2560             :         case 0:                 /* Normal */
    2561           0 :                 switch (AML_FIELD_ATTR(flag)) {
    2562             :                 case 0x02:      /* AttribQuick */
    2563             :                         cmdlen = 0;
    2564             :                         buflen = 0;
    2565           0 :                         break;
    2566             :                 case 0x04:      /* AttribSendReceive */
    2567             :                         cmdlen = 0;
    2568             :                         buflen = 1;
    2569           0 :                         break;
    2570             :                 case 0x06:      /* AttribByte */
    2571             :                         cmdlen = 1;
    2572             :                         buflen = 1;
    2573           0 :                         break;
    2574             :                 case 0x08:      /* AttribWord */
    2575             :                         cmdlen = 1;
    2576             :                         buflen = 2;
    2577           0 :                         break;
    2578             :                 case 0x0b:      /* AttribBytes */
    2579             :                         cmdlen = 1;
    2580             :                         buflen = alen;
    2581           0 :                         break;
    2582             :                 case 0x0e:      /* AttribRawBytes */
    2583             :                         cmdlen = 0;
    2584             :                         buflen = alen;
    2585           0 :                         break;
    2586             :                 default:
    2587           0 :                         aml_die("unsupported access type 0x%x", flag);
    2588           0 :                         break;
    2589             :                 }
    2590             :                 break;
    2591             :         case 1:                 /* AttribBytes */
    2592             :                 cmdlen = 1;
    2593           0 :                 buflen = AML_FIELD_ATTR(flag);
    2594           0 :                 break;
    2595             :         case 2:                 /* AttribRawBytes */
    2596             :                 cmdlen = 0;
    2597           0 :                 buflen = AML_FIELD_ATTR(flag);
    2598           0 :                 break;
    2599             :         default:
    2600           0 :                 aml_die("unsupported access type 0x%x", flag);
    2601           0 :                 break;
    2602             :         }
    2603             : 
    2604           0 :         if (mode == ACPI_IOREAD) {
    2605           0 :                 _aml_setvalue(val, AML_OBJTYPE_BUFFER, buflen + 2, NULL);
    2606             :                 op = I2C_OP_READ_WITH_STOP;
    2607           0 :         } else {
    2608             :                 op = I2C_OP_WRITE_WITH_STOP;
    2609             :         }
    2610             : 
    2611           0 :         tag = node->i2c;
    2612           0 :         addr = crs->lr_i2cbus._adr;
    2613           0 :         cmd = bpos >> 3;
    2614           0 :         buf = val->v_buffer;
    2615             : 
    2616           0 :         iic_acquire_bus(tag, 0);
    2617           0 :         err = iic_exec(tag, op, addr, &cmd, cmdlen, &buf[2], buflen, 0);
    2618           0 :         iic_release_bus(tag, 0);
    2619             : 
    2620             :         /*
    2621             :          * The ACPI specification doesn't tell us what the status
    2622             :          * codes mean beyond implying that zero means success.  So use
    2623             :          * the error returned from the transfer.  All possible error
    2624             :          * numbers should fit in a single byte.
    2625             :          */
    2626           0 :         buf[0] = err;
    2627           0 : }
    2628             : 
    2629             : #endif
    2630             : 
    2631             : void
    2632           0 : aml_rwindexfield(struct aml_value *fld, struct aml_value *val, int mode)
    2633             : {
    2634           0 :         struct aml_value tmp, *ref1, *ref2;
    2635             :         void *tbit, *vbit;
    2636             :         int vpos, bpos, blen;
    2637             :         int indexval;
    2638             :         int sz, len;
    2639             : 
    2640           0 :         ref2 = fld->v_field.ref2;
    2641           0 :         ref1 = fld->v_field.ref1;
    2642           0 :         bpos = fld->v_field.bitpos;
    2643           0 :         blen = fld->v_field.bitlen;
    2644             : 
    2645           0 :         memset(&tmp, 0, sizeof(tmp));
    2646           0 :         tmp.refcnt = 99;
    2647             : 
    2648             :         /* Get field access size */
    2649           0 :         switch (AML_FIELD_ACCESS(fld->v_field.flags)) {
    2650             :         case AML_FIELD_WORDACC:
    2651             :                 sz = 2;
    2652           0 :                 break;
    2653             :         case AML_FIELD_DWORDACC:
    2654             :                 sz = 4;
    2655           0 :                 break;
    2656             :         case AML_FIELD_QWORDACC:
    2657             :                 sz = 8;
    2658           0 :                 break;
    2659             :         default:
    2660             :                 sz = 1;
    2661           0 :                 break;
    2662             :         }
    2663             : 
    2664           0 :         if (blen > aml_intlen) {
    2665           0 :                 if (mode == ACPI_IOREAD) {
    2666             :                         /* Read from a large field: create buffer */
    2667           0 :                         _aml_setvalue(val, AML_OBJTYPE_BUFFER,
    2668           0 :                             (blen + 7) >> 3, 0);
    2669           0 :                 }
    2670           0 :                 vbit = val->v_buffer;
    2671           0 :         } else {
    2672           0 :                 if (mode == ACPI_IOREAD) {
    2673             :                         /* Read from a short field: initialize integer */
    2674           0 :                         _aml_setvalue(val, AML_OBJTYPE_INTEGER, 0, 0);
    2675           0 :                 }
    2676           0 :                 vbit = &val->v_integer;
    2677             :         }
    2678           0 :         tbit = &tmp.v_integer;
    2679             :         vpos = 0;
    2680             : 
    2681           0 :         indexval = (bpos >> 3) & ~(sz - 1);
    2682           0 :         bpos = bpos - (indexval << 3);
    2683             : 
    2684           0 :         while (blen > 0) {
    2685           0 :                 len = min(blen, (sz << 3) - bpos);
    2686             : 
    2687             :                 /* Write index register */
    2688           0 :                 _aml_setvalue(&tmp, AML_OBJTYPE_INTEGER, indexval, 0);
    2689           0 :                 aml_rwfield(ref2, 0, aml_intlen, &tmp, ACPI_IOWRITE);
    2690           0 :                 indexval += sz;
    2691             : 
    2692             :                 /* Read/write data register */
    2693           0 :                 _aml_setvalue(&tmp, AML_OBJTYPE_INTEGER, 0, 0);
    2694           0 :                 if (mode == ACPI_IOWRITE)
    2695           0 :                         aml_bufcpy(tbit, 0, vbit, vpos, len);
    2696           0 :                 aml_rwfield(ref1, bpos, len, &tmp, mode);
    2697           0 :                 if (mode == ACPI_IOREAD)
    2698           0 :                         aml_bufcpy(vbit, vpos, tbit, 0, len);
    2699           0 :                 vpos += len;
    2700           0 :                 blen -= len;
    2701             :                 bpos = 0;
    2702             :         }
    2703           0 : }
    2704             : 
    2705             : void
    2706           0 : aml_rwfield(struct aml_value *fld, int bpos, int blen, struct aml_value *val,
    2707             :     int mode)
    2708             : {
    2709           0 :         struct aml_value tmp, *ref1, *ref2;
    2710             : 
    2711           0 :         ref2 = fld->v_field.ref2;
    2712           0 :         ref1 = fld->v_field.ref1;
    2713           0 :         if (blen > fld->v_field.bitlen)
    2714           0 :                 blen = fld->v_field.bitlen;
    2715             : 
    2716           0 :         aml_lockfield(NULL, fld);
    2717           0 :         memset(&tmp, 0, sizeof(tmp));
    2718           0 :         aml_addref(&tmp, "fld.write");
    2719           0 :         if (fld->v_field.type == AMLOP_INDEXFIELD) {
    2720           0 :                 aml_rwindexfield(fld, val, mode);
    2721           0 :         } else if (fld->v_field.type == AMLOP_BANKFIELD) {
    2722           0 :                 _aml_setvalue(&tmp, AML_OBJTYPE_INTEGER, fld->v_field.ref3, 0);
    2723           0 :                 aml_rwfield(ref2, 0, aml_intlen, &tmp, ACPI_IOWRITE);
    2724           0 :                 aml_rwgen(ref1, fld->v_field.bitpos, fld->v_field.bitlen,
    2725           0 :                     val, mode, fld->v_field.flags);
    2726           0 :         } else if (fld->v_field.type == AMLOP_FIELD) {
    2727           0 :                 switch (ref1->v_opregion.iospace) {
    2728             :                 case ACPI_OPREG_GPIO:
    2729           0 :                         aml_rwgpio(ref2, bpos, blen, val, mode,
    2730           0 :                             fld->v_field.flags);
    2731           0 :                         break;
    2732             : #ifndef SMALL_KERNEL
    2733             :                 case ACPI_OPREG_GSB:
    2734           0 :                         aml_rwgsb(ref2, fld->v_field.ref3,
    2735           0 :                             fld->v_field.bitpos + bpos, blen,
    2736           0 :                             val, mode, fld->v_field.flags);
    2737           0 :                         break;
    2738             : #endif
    2739             :                 default:
    2740           0 :                         aml_rwgen(ref1, fld->v_field.bitpos + bpos, blen,
    2741           0 :                             val, mode, fld->v_field.flags);
    2742           0 :                         break;
    2743             :                 }
    2744           0 :         } else if (mode == ACPI_IOREAD) {
    2745             :                 /* bufferfield:read */
    2746           0 :                 _aml_setvalue(val, AML_OBJTYPE_INTEGER, 0, 0);
    2747           0 :                 aml_bufcpy(&val->v_integer, 0, ref1->v_buffer,
    2748           0 :                     fld->v_field.bitpos, fld->v_field.bitlen);
    2749           0 :         } else {
    2750             :                 /* bufferfield:write */
    2751           0 :                 val = aml_convert(val, AML_OBJTYPE_INTEGER, -1);
    2752           0 :                 aml_bufcpy(ref1->v_buffer, fld->v_field.bitpos, &val->v_integer,
    2753           0 :                     0, fld->v_field.bitlen);
    2754           0 :                 aml_delref(&val, "wrbuffld");
    2755             :         }
    2756           0 :         aml_unlockfield(NULL, fld);
    2757           0 : }
    2758             : 
    2759             : /* Create Field Object          data            index
    2760             :  *   AMLOP_FIELD                n:OpRegion      NULL
    2761             :  *   AMLOP_INDEXFIELD           n:Field         n:Field
    2762             :  *   AMLOP_BANKFIELD            n:OpRegion      n:Field
    2763             :  *   AMLOP_CREATEFIELD          t:Buffer        NULL
    2764             :  *   AMLOP_CREATEBITFIELD       t:Buffer        NULL
    2765             :  *   AMLOP_CREATEBYTEFIELD      t:Buffer        NULL
    2766             :  *   AMLOP_CREATEWORDFIELD      t:Buffer        NULL
    2767             :  *   AMLOP_CREATEDWORDFIELD     t:Buffer        NULL
    2768             :  *   AMLOP_CREATEQWORDFIELD     t:Buffer        NULL
    2769             :  *   AMLOP_INDEX                t:Buffer        NULL
    2770             :  */
    2771             : void
    2772           0 : aml_createfield(struct aml_value *field, int opcode,
    2773             :                 struct aml_value *data, int bpos, int blen,
    2774             :                 struct aml_value *index, int indexval, int flags)
    2775             : {
    2776             :         dnprintf(10, "## %s(%s): %s %.4x-%.4x\n",
    2777             :             aml_mnem(opcode, 0),
    2778             :             blen > aml_intlen ? "BUF" : "INT",
    2779             :             aml_nodename(field->node), bpos, blen);
    2780             :         if (index) {
    2781             :                 dnprintf(10, "  index:%s:%.2x\n", aml_nodename(index->node),
    2782             :                     indexval);
    2783             :         }
    2784             :         dnprintf(10, "  data:%s\n", aml_nodename(data->node));
    2785           0 :         field->type = (opcode == AMLOP_FIELD ||
    2786           0 :             opcode == AMLOP_INDEXFIELD ||
    2787           0 :             opcode == AMLOP_BANKFIELD) ?
    2788             :             AML_OBJTYPE_FIELDUNIT :
    2789             :             AML_OBJTYPE_BUFFERFIELD;
    2790             : 
    2791           0 :         if (field->type == AML_OBJTYPE_BUFFERFIELD &&
    2792           0 :             data->type != AML_OBJTYPE_BUFFER)
    2793           0 :                 data = aml_convert(data, AML_OBJTYPE_BUFFER, -1);
    2794             : 
    2795           0 :         field->v_field.type = opcode;
    2796           0 :         field->v_field.bitpos = bpos;
    2797           0 :         field->v_field.bitlen = blen;
    2798           0 :         field->v_field.ref3 = indexval;
    2799           0 :         field->v_field.ref2 = index;
    2800           0 :         field->v_field.ref1 = data;
    2801           0 :         field->v_field.flags = flags;
    2802             : 
    2803             :         /* Increase reference count */
    2804           0 :         aml_addref(data, "Field.Data");
    2805           0 :         aml_addref(index, "Field.Index");
    2806           0 : }
    2807             : 
    2808             : /* Parse Field/IndexField/BankField scope */
    2809             : void
    2810           0 : aml_parsefieldlist(struct aml_scope *mscope, int opcode, int flags,
    2811             :     struct aml_value *data, struct aml_value *index, int indexval)
    2812             : {
    2813             :         struct aml_value *conn = NULL;
    2814           0 :         struct aml_value *rv;
    2815             :         int bpos, blen;
    2816             : 
    2817           0 :         if (mscope == NULL)
    2818           0 :                 return;
    2819             :         bpos = 0;
    2820           0 :         while (mscope->pos < mscope->end) {
    2821           0 :                 switch (*mscope->pos) {
    2822             :                 case 0x00: /* ReservedField */
    2823           0 :                         mscope->pos++;
    2824           0 :                         blen = aml_parselength(mscope);
    2825           0 :                         break;
    2826             :                 case 0x01: /* AccessField */
    2827           0 :                         mscope->pos++;
    2828             :                         blen = 0;
    2829           0 :                         flags = aml_get8(mscope->pos++);
    2830           0 :                         flags |= aml_get8(mscope->pos++) << 8;
    2831           0 :                         break;
    2832             :                 case 0x02: /* ConnectionField */
    2833           0 :                         mscope->pos++;
    2834             :                         blen = 0;
    2835           0 :                         conn = aml_parse(mscope, 'o', "Connection");
    2836           0 :                         if (conn == NULL)
    2837           0 :                                 aml_die("Could not parse connection");
    2838           0 :                         conn->node = mscope->node;
    2839           0 :                         break;
    2840             :                 case 0x03: /* ExtendedAccessField */
    2841           0 :                         mscope->pos++;
    2842             :                         blen = 0;
    2843           0 :                         flags = aml_get8(mscope->pos++);
    2844           0 :                         flags |= aml_get8(mscope->pos++) << 8;
    2845           0 :                         indexval = aml_get8(mscope->pos++);
    2846           0 :                         break;
    2847             :                 default: /* NamedField */
    2848           0 :                         mscope->pos = aml_parsename(mscope->node, mscope->pos,
    2849             :                             &rv, 1);
    2850           0 :                         blen = aml_parselength(mscope);
    2851           0 :                         aml_createfield(rv, opcode, data, bpos, blen,
    2852           0 :                             conn ? conn : index, indexval, flags);
    2853           0 :                         aml_delref(&rv, 0);
    2854           0 :                         break;
    2855             :                 }
    2856           0 :                 bpos += blen;
    2857             :         }
    2858           0 :         aml_popscope(mscope);
    2859           0 : }
    2860             : 
    2861             : /*
    2862             :  * Mutex/Event utility functions
    2863             :  */
    2864             : int     acpi_mutex_acquire(struct aml_scope *, struct aml_value *, int);
    2865             : void    acpi_mutex_release(struct aml_scope *, struct aml_value *);
    2866             : int     acpi_event_wait(struct aml_scope *, struct aml_value *, int);
    2867             : void    acpi_event_signal(struct aml_scope *, struct aml_value *);
    2868             : void    acpi_event_reset(struct aml_scope *, struct aml_value *);
    2869             : 
    2870             : int
    2871           0 : acpi_mutex_acquire(struct aml_scope *scope, struct aml_value *mtx,
    2872             :     int timeout)
    2873             : {
    2874           0 :         if (mtx->v_mtx.owner == NULL || scope == mtx->v_mtx.owner) {
    2875             :                 /* We are now the owner */
    2876           0 :                 mtx->v_mtx.owner = scope;
    2877           0 :                 if (mtx == aml_global_lock) {
    2878             :                         dnprintf(10,"LOCKING GLOBAL\n");
    2879           0 :                         acpi_glk_enter();
    2880           0 :                 }
    2881             :                 dnprintf(5,"%s acquires mutex %s\n", scope->node->name,
    2882             :                     mtx->node->name);
    2883           0 :                 return (0);
    2884           0 :         } else if (timeout == 0) {
    2885           0 :                 return (-1);
    2886             :         }
    2887             :         /* Wait for mutex */
    2888           0 :         return (0);
    2889           0 : }
    2890             : 
    2891             : void
    2892           0 : acpi_mutex_release(struct aml_scope *scope, struct aml_value *mtx)
    2893             : {
    2894           0 :         if (mtx == aml_global_lock) {
    2895             :                 dnprintf(10,"UNLOCKING GLOBAL\n");
    2896           0 :                 acpi_glk_leave();
    2897           0 :         }
    2898             :         dnprintf(5, "%s releases mutex %s\n", scope->node->name,
    2899             :             mtx->node->name);
    2900           0 :         mtx->v_mtx.owner = NULL;
    2901             :         /* Wakeup waiters */
    2902           0 : }
    2903             : 
    2904             : int
    2905           0 : acpi_event_wait(struct aml_scope *scope, struct aml_value *evt, int timeout)
    2906             : {
    2907             :         /* Wait for event to occur; do work in meantime */
    2908           0 :         evt->v_evt.state = 0;
    2909           0 :         while (!evt->v_evt.state) {
    2910           0 :                 if (!acpi_dotask(acpi_softc) && !cold)
    2911           0 :                         tsleep(evt, PWAIT, "acpievt", 1);
    2912             :                 else
    2913           0 :                         delay(100);
    2914             :         }
    2915           0 :         if (evt->v_evt.state == 1) {
    2916             :                 /* Object is signaled */
    2917           0 :                 return (0);
    2918           0 :         } else if (timeout == 0) {
    2919             :                 /* Zero timeout */
    2920           0 :                 return (-1);
    2921             :         }
    2922             :         /* Wait for timeout or signal */
    2923           0 :         return (0);
    2924           0 : }
    2925             : 
    2926             : void
    2927           0 : acpi_event_signal(struct aml_scope *scope, struct aml_value *evt)
    2928             : {
    2929           0 :         evt->v_evt.state = 1;
    2930             :         /* Wakeup waiters */
    2931           0 : }
    2932             : 
    2933             : void
    2934           0 : acpi_event_reset(struct aml_scope *scope, struct aml_value *evt)
    2935             : {
    2936           0 :         evt->v_evt.state = 0;
    2937           0 : }
    2938             : 
    2939             : /* Store result value into an object */
    2940             : void
    2941           0 : aml_store(struct aml_scope *scope, struct aml_value *lhs , int64_t ival,
    2942             :     struct aml_value *rhs)
    2943             : {
    2944           0 :         struct aml_value tmp;
    2945             :         struct aml_node *node;
    2946             :         int mlen;
    2947             : 
    2948             :         /* Already set */
    2949           0 :         if (lhs == rhs || lhs == NULL || lhs->type == AML_OBJTYPE_NOTARGET) {
    2950           0 :                 return;
    2951             :         }
    2952           0 :         memset(&tmp, 0, sizeof(tmp));
    2953           0 :         tmp.refcnt=99;
    2954           0 :         if (rhs == NULL) {
    2955           0 :                 rhs = _aml_setvalue(&tmp, AML_OBJTYPE_INTEGER, ival, NULL);
    2956           0 :         }
    2957           0 :         if (rhs->type == AML_OBJTYPE_BUFFERFIELD ||
    2958           0 :             rhs->type == AML_OBJTYPE_FIELDUNIT) {
    2959           0 :                 aml_rwfield(rhs, 0, rhs->v_field.bitlen, &tmp, ACPI_IOREAD);
    2960           0 :                 rhs = &tmp;
    2961           0 :         }
    2962             :         /* Store to LocalX: free value */
    2963           0 :         if (lhs->stack >= AMLOP_LOCAL0 && lhs->stack <= AMLOP_LOCAL7)
    2964           0 :                 aml_freevalue(lhs);
    2965             : 
    2966           0 :         lhs = aml_gettgt(lhs, AMLOP_STORE);
    2967           0 :         switch (lhs->type) {
    2968             :         case AML_OBJTYPE_UNINITIALIZED:
    2969           0 :                 aml_copyvalue(lhs, rhs);
    2970           0 :                 break;
    2971             :         case AML_OBJTYPE_BUFFERFIELD:
    2972             :         case AML_OBJTYPE_FIELDUNIT:
    2973           0 :                 aml_rwfield(lhs, 0, lhs->v_field.bitlen, rhs, ACPI_IOWRITE);
    2974           0 :                 break;
    2975             :         case AML_OBJTYPE_DEBUGOBJ:
    2976             :                 break;
    2977             :         case AML_OBJTYPE_INTEGER:
    2978           0 :                 rhs = aml_convert(rhs, lhs->type, -1);
    2979           0 :                 lhs->v_integer = rhs->v_integer;
    2980           0 :                 aml_delref(&rhs, "store.int");
    2981           0 :                 break;
    2982             :         case AML_OBJTYPE_BUFFER:
    2983             :         case AML_OBJTYPE_STRING:
    2984           0 :                 rhs = aml_convert(rhs, lhs->type, -1);
    2985           0 :                 if (lhs->length < rhs->length) {
    2986             :                         dnprintf(10, "Overrun! %d,%d\n",
    2987             :                             lhs->length, rhs->length);
    2988           0 :                         aml_freevalue(lhs);
    2989           0 :                         _aml_setvalue(lhs, rhs->type, rhs->length, NULL);
    2990           0 :                 }
    2991           0 :                 mlen = min(lhs->length, rhs->length);
    2992           0 :                 memset(lhs->v_buffer, 0x00, lhs->length);
    2993           0 :                 memcpy(lhs->v_buffer, rhs->v_buffer, mlen);
    2994           0 :                 aml_delref(&rhs, "store.bufstr");
    2995           0 :                 break;
    2996             :         case AML_OBJTYPE_PACKAGE:
    2997             :                 /* Convert to LHS type, copy into LHS */
    2998           0 :                 if (rhs->type != AML_OBJTYPE_PACKAGE) {
    2999           0 :                         aml_die("Copy non-package into package?");
    3000           0 :                 }
    3001           0 :                 aml_freevalue(lhs);
    3002           0 :                 aml_copyvalue(lhs, rhs);
    3003           0 :                 break;
    3004             :         case AML_OBJTYPE_NAMEREF:
    3005           0 :                 node = __aml_searchname(scope->node, lhs->v_nameref, 1);
    3006           0 :                 if (node == NULL) {
    3007           0 :                         aml_die("Could not create node %s", lhs->v_nameref);
    3008           0 :                 }
    3009           0 :                 aml_copyvalue(node->value, rhs);
    3010           0 :                 break;
    3011             :         case AML_OBJTYPE_METHOD:
    3012             :                 /* Method override */
    3013           0 :                 if (rhs->type != AML_OBJTYPE_INTEGER) {
    3014           0 :                         aml_die("Overriding a method with a non-int?");
    3015           0 :                 }
    3016           0 :                 aml_freevalue(lhs);
    3017           0 :                 aml_copyvalue(lhs, rhs);
    3018           0 :                 break;
    3019             :         default:
    3020           0 :                 aml_die("Store to default type!     %x\n", lhs->type);
    3021           0 :                 break;
    3022             :         }
    3023           0 :         aml_freevalue(&tmp);
    3024           0 : }
    3025             : 
    3026             : #ifdef DDB
    3027             : /* Disassembler routines */
    3028             : void aml_disprintf(void *arg, const char *fmt, ...);
    3029             : 
    3030             : void
    3031           0 : aml_disprintf(void *arg, const char *fmt, ...)
    3032             : {
    3033           0 :         va_list ap;
    3034             : 
    3035           0 :         va_start(ap, fmt);
    3036           0 :         vprintf(fmt, ap);
    3037           0 :         va_end(ap);
    3038           0 : }
    3039             : 
    3040             : void
    3041           0 : aml_disasm(struct aml_scope *scope, int lvl,
    3042             :     void (*dbprintf)(void *, const char *, ...)
    3043             :             __attribute__((__format__(__kprintf__,2,3))),
    3044             :     void *arg)
    3045             : {
    3046             :         int pc, opcode;
    3047             :         struct aml_opcode *htab;
    3048             :         uint64_t ival;
    3049           0 :         struct aml_value *rv, tmp;
    3050             :         uint8_t *end = NULL;
    3051           0 :         struct aml_scope ms;
    3052             :         char *ch;
    3053           0 :         char  mch[64];
    3054             : 
    3055           0 :         if (dbprintf == NULL)
    3056           0 :                 dbprintf = aml_disprintf;
    3057             : 
    3058           0 :         pc = aml_pc(scope->pos);
    3059           0 :         opcode = aml_parseopcode(scope);
    3060           0 :         htab = aml_findopcode(opcode);
    3061             : 
    3062             :         /* Display address + indent */
    3063           0 :         if (lvl <= 0x7FFF) {
    3064           0 :                 dbprintf(arg, "%.4x ", pc);
    3065           0 :                 for (pc=0; pc<lvl; pc++) {
    3066           0 :                         dbprintf(arg, "     ");
    3067             :                 }
    3068             :         }
    3069             :         ch = NULL;
    3070           0 :         switch (opcode) {
    3071             :         case AMLOP_NAMECHAR:
    3072           0 :                 scope->pos = aml_parsename(scope->node, scope->pos, &rv, 0);
    3073           0 :                 if (rv->type == AML_OBJTYPE_NAMEREF) {
    3074             :                         ch = "@@@";
    3075           0 :                         aml_delref(&rv, "disasm");
    3076           0 :                         break;
    3077             :                 }
    3078             :                 /* if this is a method, get arguments */
    3079           0 :                 strlcpy(mch, aml_nodename(rv->node), sizeof(mch));
    3080           0 :                 if (rv->type == AML_OBJTYPE_METHOD) {
    3081           0 :                         strlcat(mch, "(", sizeof(mch));
    3082           0 :                         for (ival=0; 
    3083           0 :                             ival < AML_METHOD_ARGCOUNT(rv->v_method.flags);
    3084           0 :                             ival++) {
    3085           0 :                                 strlcat(mch, ival ? ", %z" : "%z",
    3086             :                                     sizeof(mch));
    3087             :                         }
    3088           0 :                         strlcat(mch, ")", sizeof(mch));
    3089           0 :                 }
    3090           0 :                 aml_delref(&rv, "");
    3091             :                 ch = mch;
    3092           0 :                 break;
    3093             : 
    3094             :         case AMLOP_ZERO:
    3095             :         case AMLOP_ONE:
    3096             :         case AMLOP_ONES:
    3097             :         case AMLOP_LOCAL0:
    3098             :         case AMLOP_LOCAL1:
    3099             :         case AMLOP_LOCAL2:
    3100             :         case AMLOP_LOCAL3:
    3101             :         case AMLOP_LOCAL4:
    3102             :         case AMLOP_LOCAL5:
    3103             :         case AMLOP_LOCAL6:
    3104             :         case AMLOP_LOCAL7:
    3105             :         case AMLOP_ARG0:
    3106             :         case AMLOP_ARG1:
    3107             :         case AMLOP_ARG2:
    3108             :         case AMLOP_ARG3:
    3109             :         case AMLOP_ARG4:
    3110             :         case AMLOP_ARG5:
    3111             :         case AMLOP_ARG6:
    3112             :         case AMLOP_NOP:
    3113             :         case AMLOP_REVISION:
    3114             :         case AMLOP_DEBUG:
    3115             :         case AMLOP_CONTINUE:
    3116             :         case AMLOP_BREAKPOINT:
    3117             :         case AMLOP_BREAK:
    3118             :                 ch="%m";
    3119           0 :                 break;
    3120             :         case AMLOP_BYTEPREFIX:
    3121             :                 ch="%b";
    3122           0 :                 break;
    3123             :         case AMLOP_WORDPREFIX:
    3124             :                 ch="%w";
    3125           0 :                 break;
    3126             :         case AMLOP_DWORDPREFIX:
    3127             :                 ch="%d";
    3128           0 :                 break;
    3129             :         case AMLOP_QWORDPREFIX:
    3130             :                 ch="%q";
    3131           0 :                 break;
    3132             :         case AMLOP_STRINGPREFIX:
    3133             :                 ch="%a";
    3134           0 :                 break;
    3135             : 
    3136             :         case AMLOP_INCREMENT:
    3137             :         case AMLOP_DECREMENT:
    3138             :         case AMLOP_LNOT:
    3139             :         case AMLOP_SIZEOF:
    3140             :         case AMLOP_DEREFOF:
    3141             :         case AMLOP_REFOF:
    3142             :         case AMLOP_OBJECTTYPE:
    3143             :         case AMLOP_UNLOAD:
    3144             :         case AMLOP_RELEASE:
    3145             :         case AMLOP_SIGNAL:
    3146             :         case AMLOP_RESET:
    3147             :         case AMLOP_STALL:
    3148             :         case AMLOP_SLEEP:
    3149             :         case AMLOP_RETURN:
    3150             :                 ch="%m(%n)";
    3151           0 :                 break;
    3152             :         case AMLOP_OR:
    3153             :         case AMLOP_ADD:
    3154             :         case AMLOP_AND:
    3155             :         case AMLOP_NAND:
    3156             :         case AMLOP_XOR:
    3157             :         case AMLOP_SHL:
    3158             :         case AMLOP_SHR:
    3159             :         case AMLOP_NOR:
    3160             :         case AMLOP_MOD:
    3161             :         case AMLOP_SUBTRACT:
    3162             :         case AMLOP_MULTIPLY:
    3163             :         case AMLOP_INDEX:
    3164             :         case AMLOP_CONCAT:
    3165             :         case AMLOP_CONCATRES:
    3166             :         case AMLOP_TOSTRING:
    3167             :                 ch="%m(%n, %n, %n)";
    3168           0 :                 break;
    3169             :         case AMLOP_CREATEBYTEFIELD:
    3170             :         case AMLOP_CREATEWORDFIELD:
    3171             :         case AMLOP_CREATEDWORDFIELD:
    3172             :         case AMLOP_CREATEQWORDFIELD:
    3173             :         case AMLOP_CREATEBITFIELD:
    3174             :                 ch="%m(%n, %n, %N)";
    3175           0 :                 break;
    3176             :         case AMLOP_CREATEFIELD:
    3177             :                 ch="%m(%n, %n, %n, %N)";
    3178           0 :                 break;
    3179             :         case AMLOP_DIVIDE:
    3180             :         case AMLOP_MID:
    3181             :                 ch="%m(%n, %n, %n, %n)";
    3182           0 :                 break;
    3183             :         case AMLOP_LAND:
    3184             :         case AMLOP_LOR:
    3185             :         case AMLOP_LNOTEQUAL:
    3186             :         case AMLOP_LLESSEQUAL:
    3187             :         case AMLOP_LLESS:
    3188             :         case AMLOP_LEQUAL:
    3189             :         case AMLOP_LGREATEREQUAL:
    3190             :         case AMLOP_LGREATER:
    3191             :         case AMLOP_NOT:
    3192             :         case AMLOP_FINDSETLEFTBIT:
    3193             :         case AMLOP_FINDSETRIGHTBIT:
    3194             :         case AMLOP_TOINTEGER:
    3195             :         case AMLOP_TOBUFFER:
    3196             :         case AMLOP_TOHEXSTRING:
    3197             :         case AMLOP_TODECSTRING:
    3198             :         case AMLOP_FROMBCD:
    3199             :         case AMLOP_TOBCD:
    3200             :         case AMLOP_WAIT:
    3201             :         case AMLOP_LOAD:
    3202             :         case AMLOP_STORE:
    3203             :         case AMLOP_NOTIFY:
    3204             :         case AMLOP_COPYOBJECT:
    3205             :                 ch="%m(%n, %n)";
    3206           0 :                 break;
    3207             :         case AMLOP_ACQUIRE:
    3208             :                 ch = "%m(%n, %w)";
    3209           0 :                 break;
    3210             :         case AMLOP_CONDREFOF:
    3211             :                 ch="%m(%R, %n)";
    3212           0 :                 break;
    3213             :         case AMLOP_ALIAS:
    3214             :                 ch="%m(%n, %N)";
    3215           0 :                 break;
    3216             :         case AMLOP_NAME:
    3217             :                 ch="%m(%N, %n)";
    3218           0 :                 break;
    3219             :         case AMLOP_EVENT:
    3220             :                 ch="%m(%N)";
    3221           0 :                 break;
    3222             :         case AMLOP_MUTEX:
    3223             :                 ch = "%m(%N, %b)";
    3224           0 :                 break;
    3225             :         case AMLOP_OPREGION:
    3226             :                 ch = "%m(%N, %b, %n, %n)";
    3227           0 :                 break;
    3228             :         case AMLOP_DATAREGION:
    3229             :                 ch="%m(%N, %n, %n, %n)";
    3230           0 :                 break;
    3231             :         case AMLOP_FATAL:
    3232             :                 ch = "%m(%b, %d, %n)";
    3233           0 :                 break;
    3234             :         case AMLOP_IF:
    3235             :         case AMLOP_WHILE:
    3236             :         case AMLOP_SCOPE:
    3237             :         case AMLOP_THERMALZONE:
    3238             :         case AMLOP_VARPACKAGE:
    3239           0 :                 end = aml_parseend(scope);
    3240             :                 ch = "%m(%n) {\n%T}";
    3241           0 :                 break;
    3242             :         case AMLOP_DEVICE:
    3243           0 :                 end = aml_parseend(scope);
    3244             :                 ch = "%m(%N) {\n%T}";
    3245           0 :                 break;
    3246             :         case AMLOP_POWERRSRC:
    3247           0 :                 end = aml_parseend(scope);
    3248             :                 ch = "%m(%N, %b, %w) {\n%T}";
    3249           0 :                 break;
    3250             :         case AMLOP_PROCESSOR:
    3251           0 :                 end = aml_parseend(scope);
    3252             :                 ch = "%m(%N, %b, %d, %b) {\n%T}";
    3253           0 :                 break;
    3254             :         case AMLOP_METHOD:
    3255           0 :                 end = aml_parseend(scope);
    3256             :                 ch = "%m(%N, %b) {\n%T}";
    3257           0 :                 break;
    3258             :         case AMLOP_PACKAGE:
    3259           0 :                 end = aml_parseend(scope);
    3260             :                 ch = "%m(%b) {\n%T}";
    3261           0 :                 break;
    3262             :         case AMLOP_ELSE:
    3263           0 :                 end = aml_parseend(scope);
    3264             :                 ch = "%m {\n%T}";
    3265           0 :                 break;
    3266             :         case AMLOP_BUFFER:
    3267           0 :                 end = aml_parseend(scope);
    3268             :                 ch = "%m(%n) { %B }";
    3269           0 :                 break;
    3270             :         case AMLOP_INDEXFIELD:
    3271           0 :                 end = aml_parseend(scope);
    3272             :                 ch = "%m(%n, %n, %b) {\n%F}";
    3273           0 :                 break;
    3274             :         case AMLOP_BANKFIELD:
    3275           0 :                 end = aml_parseend(scope);
    3276             :                 ch = "%m(%n, %n, %n, %b) {\n%F}";
    3277           0 :                 break;
    3278             :         case AMLOP_FIELD:
    3279           0 :                 end = aml_parseend(scope);
    3280             :                 ch = "%m(%n, %b) {\n%F}";
    3281           0 :                 break;
    3282             :         case AMLOP_MATCH:
    3283             :                 ch = "%m(%n, %b, %n, %b, %n, %n)";
    3284           0 :                 break;
    3285             :         case AMLOP_LOADTABLE:
    3286             :                 ch = "%m(%n, %n, %n, %n, %n, %n)";
    3287           0 :                 break;
    3288             :         default:
    3289           0 :                 aml_die("opcode = %x\n", opcode);
    3290           0 :                 break;
    3291             :         }
    3292             : 
    3293             :         /* Parse printable buffer args */
    3294           0 :         while (ch && *ch) {
    3295             :                 char c;
    3296             : 
    3297           0 :                 if (*ch != '%') {
    3298           0 :                         dbprintf(arg,"%c", *(ch++));
    3299           0 :                         continue;
    3300             :                 }
    3301           0 :                 c = *(++ch);
    3302           0 :                 switch (c) {
    3303             :                 case 'b':
    3304             :                 case 'w':
    3305             :                 case 'd':
    3306             :                 case 'q':
    3307             :                         /* Parse simple object: don't allocate */
    3308           0 :                         aml_parsesimple(scope, c, &tmp);
    3309           0 :                         dbprintf(arg,"0x%llx", tmp.v_integer);
    3310           0 :                         break;
    3311             :                 case 'a':
    3312           0 :                         dbprintf(arg, "\'%s\'", scope->pos);
    3313           0 :                         scope->pos += strlen(scope->pos)+1;
    3314           0 :                         break;
    3315             :                 case 'N':
    3316             :                         /* Create Name */
    3317           0 :                         rv = aml_parsesimple(scope, c, NULL);
    3318           0 :                         dbprintf(arg, "%s", aml_nodename(rv->node));
    3319           0 :                         break;
    3320             :                 case 'm':
    3321             :                         /* display mnemonic */
    3322           0 :                         dbprintf(arg, "%s", htab->mnem);
    3323           0 :                         break;
    3324             :                 case 'R':
    3325             :                         /* Search name */
    3326           0 :                         printf("%s", aml_getname(scope->pos));
    3327           0 :                         scope->pos = aml_parsename(scope->node, scope->pos,
    3328             :                             &rv, 0);
    3329           0 :                         aml_delref(&rv, 0);
    3330           0 :                         break;
    3331             :                 case 'z':
    3332             :                 case 'n':
    3333             :                         /* generic arg: recurse */
    3334           0 :                         aml_disasm(scope, lvl | 0x8000, dbprintf, arg);
    3335           0 :                         break;
    3336             :                 case 'B':
    3337             :                         /* Buffer */
    3338           0 :                         scope->pos = end;
    3339           0 :                         break;
    3340             :                 case 'F':
    3341             :                         /* Scope: Field List */
    3342           0 :                         memset(&ms, 0, sizeof(ms));
    3343           0 :                         ms.node = scope->node;
    3344           0 :                         ms.start = scope->pos;
    3345           0 :                         ms.end = end;
    3346           0 :                         ms.pos = ms.start;
    3347           0 :                         ms.type = AMLOP_FIELD;
    3348             : 
    3349           0 :                         while (ms.pos < ms.end) {
    3350           0 :                                 if (*ms.pos == 0x00) {
    3351           0 :                                         ms.pos++;
    3352           0 :                                         aml_parselength(&ms);
    3353           0 :                                 } else if (*ms.pos == 0x01) {
    3354           0 :                                         ms.pos+=3;
    3355           0 :                                 } else {
    3356           0 :                                         ms.pos = aml_parsename(ms.node,
    3357             :                                              ms.pos, &rv, 1);
    3358           0 :                                         aml_parselength(&ms);
    3359           0 :                                         dbprintf(arg,"     %s\n",
    3360           0 :                                             aml_nodename(rv->node));
    3361           0 :                                         aml_delref(&rv, 0);
    3362             :                                 }
    3363             :                         }
    3364             : 
    3365             :                         /* Display address and closing bracket */
    3366           0 :                         dbprintf(arg,"%.4x ", aml_pc(scope->pos));
    3367           0 :                         for (pc=0; pc<(lvl & 0x7FFF); pc++) {
    3368           0 :                                 dbprintf(arg,"  ");
    3369             :                         }
    3370           0 :                         scope->pos = end;
    3371           0 :                         break;
    3372             :                 case 'T':
    3373             :                         /* Scope: Termlist */
    3374           0 :                         memset(&ms, 0, sizeof(ms));
    3375           0 :                         ms.node = scope->node;
    3376           0 :                         ms.start = scope->pos;
    3377           0 :                         ms.end = end;
    3378           0 :                         ms.pos = ms.start;
    3379           0 :                         ms.type = AMLOP_SCOPE;
    3380             : 
    3381           0 :                         while (ms.pos < ms.end) {
    3382           0 :                                 aml_disasm(&ms, (lvl + 1) & 0x7FFF,
    3383             :                                     dbprintf, arg);
    3384             :                         }
    3385             : 
    3386             :                         /* Display address and closing bracket */
    3387           0 :                         dbprintf(arg,"%.4x ", aml_pc(scope->pos));
    3388           0 :                         for (pc=0; pc<(lvl & 0x7FFF); pc++) {
    3389           0 :                                 dbprintf(arg,"  ");
    3390             :                         }
    3391           0 :                         scope->pos = end;
    3392           0 :                         break;
    3393             :                 }
    3394           0 :                 ch++;
    3395           0 :         }
    3396           0 :         if (lvl <= 0x7FFF) {
    3397           0 :                 dbprintf(arg,"\n");
    3398           0 :         }
    3399           0 : }
    3400             : #endif /* DDB */
    3401             : 
    3402             : int aml_busy;
    3403             : 
    3404             : /* Evaluate method or buffervalue objects */
    3405             : struct aml_value *
    3406           0 : aml_eval(struct aml_scope *scope, struct aml_value *my_ret, int ret_type,
    3407             :     int argc, struct aml_value *argv)
    3408             : {
    3409             :         struct aml_value *tmp = my_ret;
    3410             :         struct aml_scope *ms;
    3411             :         int idx;
    3412             : 
    3413           0 :         switch (tmp->type) {
    3414             :         case AML_OBJTYPE_NAMEREF:
    3415           0 :                 my_ret = aml_seterror(scope, "Undefined name: %s",
    3416           0 :                     aml_getname(my_ret->v_nameref));
    3417           0 :                 break;
    3418             :         case AML_OBJTYPE_METHOD:
    3419             :                 dnprintf(10,"\n--== Eval Method [%s, %d args] to %c ==--\n",
    3420             :                     aml_nodename(tmp->node),
    3421             :                     AML_METHOD_ARGCOUNT(tmp->v_method.flags),
    3422             :                     ret_type);
    3423           0 :                 ms = aml_pushscope(scope, tmp, tmp->node, AMLOP_METHOD);
    3424             : 
    3425             :                 /* Parse method arguments */
    3426           0 :                 for (idx=0; idx<AML_METHOD_ARGCOUNT(tmp->v_method.flags); idx++) {
    3427             :                         struct aml_value *sp;
    3428             : 
    3429           0 :                         sp = aml_getstack(ms, AMLOP_ARG0+idx);
    3430           0 :                         if (argv) {
    3431           0 :                                 aml_copyvalue(sp, &argv[idx]);
    3432           0 :                         } else {
    3433           0 :                                 _aml_setvalue(sp, AML_OBJTYPE_OBJREF, AMLOP_ARG0 + idx, 0);
    3434           0 :                                 sp->v_objref.ref = aml_parse(scope, 't', "ARGX");
    3435             :                         }
    3436             :                 }
    3437             : #ifdef ACPI_DEBUG
    3438             :                 aml_showstack(ms);
    3439             : #endif
    3440             : 
    3441             :                 /* Evaluate method scope */
    3442           0 :                 aml_root.start = tmp->v_method.base;
    3443           0 :                 if (tmp->v_method.fneval != NULL) {
    3444           0 :                         my_ret = tmp->v_method.fneval(ms, NULL);
    3445           0 :                 } else {
    3446           0 :                         aml_parse(ms, 'T', "METHEVAL");
    3447           0 :                         my_ret = ms->retv;
    3448             :                 }
    3449             :                 dnprintf(10,"\n--==Finished evaluating method: %s %c\n",
    3450             :                     aml_nodename(tmp->node), ret_type);
    3451             : #ifdef ACPI_DEBUG
    3452             :                 aml_showvalue(my_ret);
    3453             :                 aml_showstack(ms);
    3454             : #endif
    3455           0 :                 aml_popscope(ms);
    3456           0 :                 break;
    3457             :         case AML_OBJTYPE_BUFFERFIELD:
    3458             :         case AML_OBJTYPE_FIELDUNIT:
    3459           0 :                 my_ret = aml_allocvalue(0,0,NULL);
    3460             :                 dnprintf(20,"quick: Convert Bufferfield to %c %p\n",
    3461             :                     ret_type, my_ret);
    3462           0 :                 aml_rwfield(tmp, 0, tmp->v_field.bitlen, my_ret, ACPI_IOREAD);
    3463           0 :                 break;
    3464             :         }
    3465           0 :         if (ret_type == 'i' && my_ret && my_ret->type != AML_OBJTYPE_INTEGER) {
    3466             : #ifndef SMALL_KERNEL
    3467           0 :                 aml_showvalue(my_ret);
    3468             : #endif
    3469           0 :                 aml_die("Not Integer");
    3470           0 :         }
    3471           0 :         return my_ret;
    3472             : }
    3473             : 
    3474             : /*
    3475             :  * The following opcodes produce return values
    3476             :  *   TOSTRING   -> Str
    3477             :  *   TOHEXSTR   -> Str
    3478             :  *   TODECSTR   -> Str
    3479             :  *   STRINGPFX  -> Str
    3480             :  *   BUFFER     -> Buf
    3481             :  *   CONCATRES  -> Buf
    3482             :  *   TOBUFFER   -> Buf
    3483             :  *   MID        -> Buf|Str
    3484             :  *   CONCAT     -> Buf|Str
    3485             :  *   PACKAGE    -> Pkg
    3486             :  *   VARPACKAGE -> Pkg
    3487             :  *   LOCALx     -> Obj
    3488             :  *   ARGx       -> Obj
    3489             :  *   NAMECHAR   -> Obj
    3490             :  *   REFOF      -> ObjRef
    3491             :  *   INDEX      -> ObjRef
    3492             :  *   DEREFOF    -> DataRefObj
    3493             :  *   COPYOBJECT -> DataRefObj
    3494             :  *   STORE      -> DataRefObj
    3495             : 
    3496             :  *   ZERO       -> Int
    3497             :  *   ONE        -> Int
    3498             :  *   ONES       -> Int
    3499             :  *   REVISION   -> Int
    3500             :  *   B/W/D/Q    -> Int
    3501             :  *   OR         -> Int
    3502             :  *   AND        -> Int
    3503             :  *   ADD        -> Int
    3504             :  *   NAND       -> Int
    3505             :  *   XOR        -> Int
    3506             :  *   SHL        -> Int
    3507             :  *   SHR        -> Int
    3508             :  *   NOR        -> Int
    3509             :  *   MOD        -> Int
    3510             :  *   SUBTRACT   -> Int
    3511             :  *   MULTIPLY   -> Int
    3512             :  *   DIVIDE     -> Int
    3513             :  *   NOT        -> Int
    3514             :  *   TOBCD      -> Int
    3515             :  *   FROMBCD    -> Int
    3516             :  *   FSLEFTBIT  -> Int
    3517             :  *   FSRIGHTBIT -> Int
    3518             :  *   INCREMENT  -> Int
    3519             :  *   DECREMENT  -> Int
    3520             :  *   TOINTEGER  -> Int
    3521             :  *   MATCH      -> Int
    3522             :  *   SIZEOF     -> Int
    3523             :  *   OBJECTTYPE -> Int
    3524             :  *   TIMER      -> Int
    3525             : 
    3526             :  *   CONDREFOF  -> Bool
    3527             :  *   ACQUIRE    -> Bool
    3528             :  *   WAIT       -> Bool
    3529             :  *   LNOT       -> Bool
    3530             :  *   LAND       -> Bool
    3531             :  *   LOR        -> Bool
    3532             :  *   LLESS      -> Bool
    3533             :  *   LEQUAL     -> Bool
    3534             :  *   LGREATER   -> Bool
    3535             :  *   LNOTEQUAL  -> Bool
    3536             :  *   LLESSEQUAL -> Bool
    3537             :  *   LGREATEREQ -> Bool
    3538             : 
    3539             :  *   LOADTABLE  -> DDB
    3540             :  *   DEBUG      -> Debug
    3541             : 
    3542             :  *   The following opcodes do not generate a return value:
    3543             :  *   NOP
    3544             :  *   BREAKPOINT
    3545             :  *   RELEASE
    3546             :  *   RESET
    3547             :  *   SIGNAL
    3548             :  *   NAME
    3549             :  *   ALIAS
    3550             :  *   OPREGION
    3551             :  *   DATAREGION
    3552             :  *   EVENT
    3553             :  *   MUTEX
    3554             :  *   SCOPE
    3555             :  *   DEVICE
    3556             :  *   THERMALZONE
    3557             :  *   POWERRSRC
    3558             :  *   PROCESSOR
    3559             :  *   METHOD
    3560             :  *   CREATEFIELD
    3561             :  *   CREATEBITFIELD
    3562             :  *   CREATEBYTEFIELD
    3563             :  *   CREATEWORDFIELD
    3564             :  *   CREATEDWORDFIELD
    3565             :  *   CREATEQWORDFIELD
    3566             :  *   FIELD
    3567             :  *   INDEXFIELD
    3568             :  *   BANKFIELD
    3569             :  *   STALL
    3570             :  *   SLEEP
    3571             :  *   NOTIFY
    3572             :  *   FATAL
    3573             :  *   LOAD
    3574             :  *   UNLOAD
    3575             :  *   IF
    3576             :  *   ELSE
    3577             :  *   WHILE
    3578             :  *   BREAK
    3579             :  *   CONTINUE
    3580             :  */
    3581             : 
    3582             : /* Parse a simple object from AML Bytestream */
    3583             : struct aml_value *
    3584           0 : aml_parsesimple(struct aml_scope *scope, char ch, struct aml_value *rv)
    3585             : {
    3586           0 :         if (rv == NULL)
    3587           0 :                 rv = aml_allocvalue(0,0,NULL);
    3588           0 :         switch (ch) {
    3589             :         case AML_ARG_REVISION:
    3590           0 :                 _aml_setvalue(rv, AML_OBJTYPE_INTEGER, AML_REVISION, NULL);
    3591           0 :                 break;
    3592             :         case AML_ARG_DEBUG:
    3593           0 :                 _aml_setvalue(rv, AML_OBJTYPE_DEBUGOBJ, 0, NULL);
    3594           0 :                 break;
    3595             :         case AML_ARG_BYTE:
    3596           0 :                 _aml_setvalue(rv, AML_OBJTYPE_INTEGER,
    3597           0 :                     aml_get8(scope->pos), NULL);
    3598           0 :                 scope->pos += 1;
    3599           0 :                 break;
    3600             :         case AML_ARG_WORD:
    3601           0 :                 _aml_setvalue(rv, AML_OBJTYPE_INTEGER,
    3602           0 :                     aml_get16(scope->pos), NULL);
    3603           0 :                 scope->pos += 2;
    3604           0 :                 break;
    3605             :         case AML_ARG_DWORD:
    3606           0 :                 _aml_setvalue(rv, AML_OBJTYPE_INTEGER,
    3607           0 :                     aml_get32(scope->pos), NULL);
    3608           0 :                 scope->pos += 4;
    3609           0 :                 break;
    3610             :         case AML_ARG_QWORD:
    3611           0 :                 _aml_setvalue(rv, AML_OBJTYPE_INTEGER,
    3612           0 :                     aml_get64(scope->pos), NULL);
    3613           0 :                 scope->pos += 8;
    3614           0 :                 break;
    3615             :         case AML_ARG_STRING:
    3616           0 :                 _aml_setvalue(rv, AML_OBJTYPE_STRING, -1, scope->pos);
    3617           0 :                 scope->pos += rv->length+1;
    3618           0 :                 break;
    3619             :         }
    3620           0 :         return rv;
    3621             : }
    3622             : 
    3623             : /*
    3624             :  * Main Opcode Parser/Evaluator
    3625             :  *
    3626             :  * ret_type is expected type for return value
    3627             :  *   'o' = Data Object (Int/Str/Buf/Pkg/Name)
    3628             :  *   'i' = Integer
    3629             :  *   't' = TermArg     (Int/Str/Buf/Pkg)
    3630             :  *   'r' = Target      (NamedObj/Local/Arg/Null)
    3631             :  *   'S' = SuperName   (NamedObj/Local/Arg)
    3632             :  *   'T' = TermList
    3633             :  */
    3634             : #define aml_debugger(x)
    3635             : 
    3636             : int maxdp;
    3637             : 
    3638             : struct aml_value *
    3639           0 : aml_gettgt(struct aml_value *val, int opcode)
    3640             : {
    3641           0 :         while (val && val->type == AML_OBJTYPE_OBJREF) {
    3642           0 :                 val = val->v_objref.ref;
    3643             :         }
    3644           0 :         return val;
    3645             : }
    3646             : 
    3647             : struct aml_value *
    3648           0 : aml_seterror(struct aml_scope *scope, const char *fmt, ...)
    3649             : {
    3650           0 :         va_list ap;
    3651             : 
    3652           0 :         va_start(ap, fmt);
    3653           0 :         printf("### AML PARSE ERROR (0x%x): ", aml_pc(scope->pos));
    3654           0 :         vprintf(fmt, ap);
    3655           0 :         printf("\n");
    3656           0 :         va_end(ap);
    3657             : 
    3658           0 :         while (scope) {
    3659           0 :                 scope->pos = scope->end;
    3660           0 :                 scope = scope->parent;
    3661             :         }
    3662           0 :         aml_error++;
    3663           0 :         return aml_allocvalue(AML_OBJTYPE_INTEGER, 0, 0);
    3664           0 : }
    3665             : 
    3666             : struct aml_value *
    3667           0 : aml_loadtable(struct acpi_softc *sc, const char *signature,
    3668             :      const char *oemid, const char *oemtableid, const char *rootpath,
    3669             :      const char *parameterpath, struct aml_value *parameterdata)
    3670             : {
    3671             :         struct acpi_table_header *hdr;
    3672             :         struct acpi_dsdt *p_dsdt;
    3673             :         struct acpi_q *entry;
    3674             : 
    3675           0 :         if (strlen(rootpath) > 0)
    3676           0 :                 aml_die("LoadTable: RootPathString unsupported");
    3677           0 :         if (strlen(parameterpath) > 0)
    3678           0 :                 aml_die("LoadTable: ParameterPathString unsupported");
    3679             : 
    3680           0 :         SIMPLEQ_FOREACH(entry, &sc->sc_tables, q_next) {
    3681           0 :                 hdr = entry->q_table;
    3682           0 :                 if (strncmp(hdr->signature, signature,
    3683           0 :                     sizeof(hdr->signature)) == 0 &&
    3684           0 :                     strncmp(hdr->oemid, oemid, sizeof(hdr->oemid)) == 0 &&
    3685           0 :                     strncmp(hdr->oemtableid, oemtableid,
    3686           0 :                     sizeof(hdr->oemtableid)) == 0) {
    3687           0 :                         p_dsdt = entry->q_table;
    3688           0 :                         acpi_parse_aml(sc, p_dsdt->aml, p_dsdt->hdr_length -
    3689             :                             sizeof(p_dsdt->hdr));
    3690           0 :                         return aml_allocvalue(AML_OBJTYPE_DDBHANDLE, 0, 0);
    3691             :                 }
    3692             :         }
    3693             : 
    3694           0 :         return aml_allocvalue(AML_OBJTYPE_INTEGER, 0, 0);
    3695           0 : }
    3696             : 
    3697             : /* Load new SSDT scope from memory address */
    3698             : struct aml_scope *
    3699           0 : aml_load(struct acpi_softc *sc, struct aml_scope *scope,
    3700             :     struct aml_value *rgn, struct aml_value *ddb)
    3701             : {
    3702             :         struct acpi_q *entry;
    3703             :         struct acpi_dsdt *p_ssdt;
    3704           0 :         struct aml_value tmp;
    3705             : 
    3706           0 :         ddb->type = AML_OBJTYPE_DDBHANDLE;
    3707           0 :         ddb->v_integer = 0;
    3708             : 
    3709           0 :         memset(&tmp, 0, sizeof(tmp));
    3710           0 :         if (rgn->type != AML_OBJTYPE_OPREGION ||
    3711           0 :             rgn->v_opregion.iospace != GAS_SYSTEM_MEMORY)
    3712             :                 goto fail;
    3713             : 
    3714             :         /* Load SSDT from memory */
    3715           0 :         entry = acpi_maptable(sc, rgn->v_opregion.iobase, "SSDT", NULL, NULL, 1);
    3716           0 :         if (entry == NULL)
    3717             :                 goto fail;
    3718             : 
    3719             :         dnprintf(10, "%s: loaded SSDT %s @ %llx\n", sc->sc_dev.dv_xname,
    3720             :             aml_nodename(rgn->node), rgn->v_opregion.iobase);
    3721           0 :         ddb->v_integer = entry->q_id;
    3722             : 
    3723           0 :         p_ssdt = entry->q_table;
    3724           0 :         tmp.v_buffer = p_ssdt->aml;
    3725           0 :         tmp.length   = p_ssdt->hdr_length - sizeof(p_ssdt->hdr);
    3726             : 
    3727           0 :         return aml_pushscope(scope, &tmp, scope->node,
    3728             :             AMLOP_LOAD);
    3729             : fail:
    3730           0 :         printf("%s: unable to load %s\n", sc->sc_dev.dv_xname,
    3731           0 :             aml_nodename(rgn->node));
    3732           0 :         return NULL;
    3733           0 : }
    3734             : 
    3735             : struct aml_value *
    3736           0 : aml_parse(struct aml_scope *scope, int ret_type, const char *stype)
    3737             : {
    3738             :         int    opcode, idx, pc;
    3739             :         struct aml_opcode *htab;
    3740           0 :         struct aml_value *opargs[8], *my_ret, *rv;
    3741             :         struct aml_scope *mscope, *iscope;
    3742             :         uint8_t *start, *end;
    3743             :         const char *ch;
    3744             :         int64_t ival;
    3745           0 :         struct timespec ts;
    3746             : 
    3747           0 :         my_ret = NULL;
    3748           0 :         if (scope == NULL || scope->pos >= scope->end) {
    3749           0 :                 return NULL;
    3750             :         }
    3751           0 :         if (odp++ > 125)
    3752           0 :                 panic("depth");
    3753           0 :         if (odp > maxdp) {
    3754           0 :                 maxdp = odp;
    3755             :                 dnprintf(10, "max depth: %d\n", maxdp);
    3756           0 :         }
    3757             :         end = NULL;
    3758           0 :         iscope = scope;
    3759             :  start:
    3760             :         /* --== Stage 0: Get Opcode ==-- */
    3761           0 :         start = scope->pos;
    3762           0 :         pc = aml_pc(scope->pos);
    3763             :         aml_debugger(scope);
    3764             : 
    3765           0 :         opcode = aml_parseopcode(scope);
    3766           0 :         htab = aml_findopcode(opcode);
    3767           0 :         if (htab == NULL) {
    3768             :                 /* No opcode handler */
    3769           0 :                 aml_die("Unknown opcode: %.4x @ %.4x", opcode, pc);
    3770           0 :         }
    3771             :         dnprintf(18,"%.4x %s\n", pc, aml_mnem(opcode, scope->pos));
    3772             : 
    3773             :         /* --== Stage 1: Process opcode arguments ==-- */
    3774           0 :         memset(opargs, 0, sizeof(opargs));
    3775             :         idx = 0;
    3776           0 :         for (ch = htab->args; *ch; ch++) {
    3777           0 :                 rv = NULL;
    3778           0 :                 switch (*ch) {
    3779             :                 case AML_ARG_OBJLEN:
    3780           0 :                         end = aml_parseend(scope);
    3781           0 :                         break;
    3782             :                 case AML_ARG_IFELSE:
    3783             :                         /* Special Case: IF-ELSE:piTbpT or IF:piT */
    3784           0 :                         ch = (*end == AMLOP_ELSE && end < scope->end) ?
    3785             :                             "-TbpT" : "-T";
    3786           0 :                         break;
    3787             : 
    3788             :                         /* Complex arguments */
    3789             :                 case 's':
    3790             :                 case 'S':
    3791             :                 case AML_ARG_TARGET:
    3792             :                 case AML_ARG_TERMOBJ:
    3793             :                 case AML_ARG_INTEGER:
    3794           0 :                         if (*ch == 'r' && *scope->pos == AMLOP_ZERO) {
    3795             :                                 /* Special case: NULL Target */
    3796           0 :                                 rv = aml_allocvalue(AML_OBJTYPE_NOTARGET, 0, NULL);
    3797           0 :                                 scope->pos++;
    3798           0 :                         }
    3799             :                         else {
    3800           0 :                                 rv = aml_parse(scope, *ch, htab->mnem);
    3801           0 :                                 if (rv == NULL || aml_error)
    3802             :                                         goto parse_error;
    3803             :                         }
    3804             :                         break;
    3805             : 
    3806             :                         /* Simple arguments */
    3807             :                 case AML_ARG_BUFFER:
    3808             :                 case AML_ARG_METHOD:
    3809             :                 case AML_ARG_FIELDLIST:
    3810             :                 case AML_ARG_TERMOBJLIST:
    3811           0 :                         rv = aml_allocvalue(AML_OBJTYPE_SCOPE, 0, NULL);
    3812           0 :                         rv->v_buffer = scope->pos;
    3813           0 :                         rv->length = end - scope->pos;
    3814           0 :                         scope->pos = end;
    3815           0 :                         break;
    3816             :                 case AML_ARG_CONST:
    3817           0 :                         rv = aml_allocvalue(AML_OBJTYPE_INTEGER,
    3818           0 :                             (char)opcode, NULL);
    3819           0 :                         break;
    3820             :                 case AML_ARG_CREATENAME:
    3821           0 :                         scope->pos = aml_parsename(scope->node, scope->pos,
    3822             :                             &rv, 1);
    3823           0 :                         break;
    3824             :                 case AML_ARG_SEARCHNAME:
    3825           0 :                         scope->pos = aml_parsename(scope->node, scope->pos,
    3826             :                             &rv, 0);
    3827           0 :                         break;
    3828             :                 case AML_ARG_BYTE:
    3829             :                 case AML_ARG_WORD:
    3830             :                 case AML_ARG_DWORD:
    3831             :                 case AML_ARG_QWORD:
    3832             :                 case AML_ARG_DEBUG:
    3833             :                 case AML_ARG_STRING:
    3834             :                 case AML_ARG_REVISION:
    3835           0 :                         rv = aml_parsesimple(scope, *ch, NULL);
    3836           0 :                         break;
    3837             :                 case AML_ARG_STKLOCAL:
    3838             :                 case AML_ARG_STKARG:
    3839           0 :                         rv = aml_getstack(scope, opcode);
    3840           0 :                         break;
    3841             :                 default:
    3842           0 :                         aml_die("Unknown arg type: %c\n", *ch);
    3843           0 :                         break;
    3844             :                 }
    3845           0 :                 if (rv != NULL)
    3846           0 :                         opargs[idx++] = rv;
    3847             :                 }
    3848             : 
    3849             :         /* --== Stage 2: Process opcode ==-- */
    3850             :         ival = 0;
    3851           0 :         my_ret = NULL;
    3852             :         mscope = NULL;
    3853           0 :         switch (opcode) {
    3854             :         case AMLOP_NOP:
    3855             :         case AMLOP_BREAKPOINT:
    3856             :                 break;
    3857             :         case AMLOP_LOCAL0:
    3858             :         case AMLOP_LOCAL1:
    3859             :         case AMLOP_LOCAL2:
    3860             :         case AMLOP_LOCAL3:
    3861             :         case AMLOP_LOCAL4:
    3862             :         case AMLOP_LOCAL5:
    3863             :         case AMLOP_LOCAL6:
    3864             :         case AMLOP_LOCAL7:
    3865             :         case AMLOP_ARG0:
    3866             :         case AMLOP_ARG1:
    3867             :         case AMLOP_ARG2:
    3868             :         case AMLOP_ARG3:
    3869             :         case AMLOP_ARG4:
    3870             :         case AMLOP_ARG5:
    3871             :         case AMLOP_ARG6:
    3872           0 :                 my_ret = opargs[0];
    3873           0 :                 aml_addref(my_ret, htab->mnem);
    3874           0 :                 break;
    3875             :         case AMLOP_NAMECHAR:
    3876             :                 /* opargs[0] = named object (node != NULL), or nameref */
    3877           0 :                 my_ret = opargs[0];
    3878           0 :                 if (scope->type == AMLOP_PACKAGE) {
    3879             :                         /* Special case for package */
    3880           0 :                         if (my_ret->type == AML_OBJTYPE_NAMEREF)
    3881           0 :                                 my_ret = aml_allocvalue(AML_OBJTYPE_STRING, -1,
    3882           0 :                                     aml_getname(my_ret->v_nameref));
    3883           0 :                         else if (my_ret->node)
    3884           0 :                                 my_ret = aml_allocvalue(AML_OBJTYPE_STRING, -1,
    3885           0 :                                     aml_nodename(my_ret->node));
    3886             :                         break;
    3887             :                 }
    3888           0 :                 if (my_ret->type == AML_OBJTYPE_OBJREF) {
    3889           0 :                         my_ret = my_ret->v_objref.ref;
    3890           0 :                         aml_addref(my_ret, "de-alias");
    3891           0 :                 }
    3892           0 :                 if (ret_type == 'i' || ret_type == 't' || ret_type == 'T') {
    3893             :                         /* Return TermArg or Integer: Evaluate object */
    3894           0 :                         my_ret = aml_eval(scope, my_ret, ret_type, 0, NULL);
    3895           0 :                 } else if (my_ret->type == AML_OBJTYPE_METHOD) {
    3896             :                         /* This should only happen with CondRef */
    3897             :                         dnprintf(12,"non-termarg method : %s\n", stype);
    3898           0 :                         aml_addref(my_ret, "zoom");
    3899           0 :                 }
    3900             :                 break;
    3901             : 
    3902             :         case AMLOP_ZERO:
    3903             :         case AMLOP_ONE:
    3904             :         case AMLOP_ONES:
    3905             :         case AMLOP_DEBUG:
    3906             :         case AMLOP_REVISION:
    3907             :         case AMLOP_BYTEPREFIX:
    3908             :         case AMLOP_WORDPREFIX:
    3909             :         case AMLOP_DWORDPREFIX:
    3910             :         case AMLOP_QWORDPREFIX:
    3911             :         case AMLOP_STRINGPREFIX:
    3912           0 :                 my_ret = opargs[0];
    3913           0 :                 break;
    3914             : 
    3915             :         case AMLOP_BUFFER:
    3916             :                 /* Buffer: iB => Buffer */
    3917           0 :                 my_ret = aml_allocvalue(AML_OBJTYPE_BUFFER,
    3918           0 :                     opargs[0]->v_integer, NULL);
    3919           0 :                 memcpy(my_ret->v_buffer, opargs[1]->v_buffer,
    3920             :                     opargs[1]->length);
    3921           0 :                 break;
    3922             :         case AMLOP_PACKAGE:
    3923             :         case AMLOP_VARPACKAGE:
    3924             :                 /* Package/VarPackage: bT/iT => Package */
    3925           0 :                 my_ret = aml_allocvalue(AML_OBJTYPE_PACKAGE,
    3926           0 :                     opargs[0]->v_integer, 0);
    3927           0 :                 mscope = aml_pushscope(scope, opargs[1], scope->node,
    3928             :                     AMLOP_PACKAGE);
    3929             : 
    3930             :                 /* Recursively parse package contents */
    3931           0 :                 for (idx=0; idx<my_ret->length; idx++) {
    3932           0 :                         rv = aml_parse(mscope, 'o', "Package");
    3933           0 :                         if (rv != NULL) {
    3934           0 :                                 aml_delref(&my_ret->v_package[idx], "pkginit");
    3935           0 :                                 my_ret->v_package[idx] = rv;
    3936           0 :                         }
    3937             :                 }
    3938           0 :                 aml_popscope(mscope);
    3939             :                 mscope = NULL;
    3940           0 :                 break;
    3941             : 
    3942             :                 /* Math/Logical operations */
    3943             :         case AMLOP_OR:
    3944             :         case AMLOP_ADD:
    3945             :         case AMLOP_AND:
    3946             :         case AMLOP_NAND:
    3947             :         case AMLOP_XOR:
    3948             :         case AMLOP_SHL:
    3949             :         case AMLOP_SHR:
    3950             :         case AMLOP_NOR:
    3951             :         case AMLOP_MOD:
    3952             :         case AMLOP_SUBTRACT:
    3953             :         case AMLOP_MULTIPLY:
    3954             :                 /* XXX: iir => I */
    3955           0 :                 ival = aml_evalexpr(opargs[0]->v_integer,
    3956           0 :                     opargs[1]->v_integer, opcode);
    3957           0 :                 aml_store(scope, opargs[2], ival, NULL);
    3958           0 :                 break;
    3959             :         case AMLOP_DIVIDE:
    3960             :                 /* Divide: iirr => I */
    3961           0 :                 if (opargs[1]->v_integer == 0) {
    3962           0 :                         my_ret = aml_seterror(scope, "Divide by Zero!");
    3963           0 :                         break;
    3964             :                 }
    3965           0 :                 ival = aml_evalexpr(opargs[0]->v_integer,
    3966             :                     opargs[1]->v_integer, AMLOP_MOD);
    3967           0 :                 aml_store(scope, opargs[2], ival, NULL);
    3968             : 
    3969           0 :                 ival = aml_evalexpr(opargs[0]->v_integer,
    3970           0 :                     opargs[1]->v_integer, AMLOP_DIVIDE);
    3971           0 :                 aml_store(scope, opargs[3], ival, NULL);
    3972           0 :                 break;
    3973             :         case AMLOP_NOT:
    3974             :         case AMLOP_TOBCD:
    3975             :         case AMLOP_FROMBCD:
    3976             :         case AMLOP_FINDSETLEFTBIT:
    3977             :         case AMLOP_FINDSETRIGHTBIT:
    3978             :                 /* XXX: ir => I */
    3979           0 :                 ival = aml_evalexpr(opargs[0]->v_integer, 0, opcode);
    3980           0 :                 aml_store(scope, opargs[1], ival, NULL);
    3981           0 :                 break;
    3982             :         case AMLOP_INCREMENT:
    3983             :         case AMLOP_DECREMENT:
    3984             :                 /* Inc/Dec: S => I */
    3985           0 :                 my_ret = aml_eval(scope, opargs[0], AML_ARG_INTEGER, 0, NULL);
    3986           0 :                 ival = aml_evalexpr(my_ret->v_integer, 1, opcode);
    3987           0 :                 aml_store(scope, opargs[0], ival, NULL);
    3988           0 :                 break;
    3989             :         case AMLOP_LNOT:
    3990             :                 /* LNot: i => Bool */
    3991           0 :                 ival = aml_evalexpr(opargs[0]->v_integer, 0, opcode);
    3992           0 :                 break;
    3993             :         case AMLOP_LOR:
    3994             :         case AMLOP_LAND:
    3995             :                 /* XXX: ii => Bool */
    3996           0 :                 ival = aml_evalexpr(opargs[0]->v_integer,
    3997           0 :                     opargs[1]->v_integer, opcode);
    3998           0 :                 break;
    3999             :         case AMLOP_LLESS:
    4000             :         case AMLOP_LEQUAL:
    4001             :         case AMLOP_LGREATER:
    4002             :         case AMLOP_LNOTEQUAL:
    4003             :         case AMLOP_LLESSEQUAL:
    4004             :         case AMLOP_LGREATEREQUAL:
    4005             :                 /* XXX: tt => Bool */
    4006           0 :                 ival = aml_compare(opargs[0], opargs[1], opcode);
    4007           0 :                 break;
    4008             : 
    4009             :                 /* Reference/Store operations */
    4010             :         case AMLOP_CONDREFOF:
    4011             :                 /* CondRef: rr => I */
    4012             :                 ival = 0;
    4013           0 :                 if (opargs[0]->node != NULL) {
    4014             :                         /* Create Object Reference */
    4015           0 :                         rv = aml_allocvalue(AML_OBJTYPE_OBJREF, opcode,
    4016           0 :                                 opargs[0]);
    4017           0 :                         aml_addref(opargs[0], "CondRef");
    4018           0 :                         aml_store(scope, opargs[1], 0, rv);
    4019           0 :                         aml_delref(&rv, 0);
    4020             : 
    4021             :                         /* Mark that we found it */
    4022             :                         ival = -1;
    4023           0 :                 }
    4024             :                 break;
    4025             :         case AMLOP_REFOF:
    4026             :                 /* RefOf: r => ObjRef */
    4027           0 :                 my_ret = aml_allocvalue(AML_OBJTYPE_OBJREF, opcode, opargs[0]);
    4028           0 :                 aml_addref(my_ret->v_objref.ref, "RefOf");
    4029           0 :                 break;
    4030             :         case AMLOP_INDEX:
    4031             :                 /* Index: tir => ObjRef */
    4032           0 :                 idx = opargs[1]->v_integer;
    4033           0 :                 if (idx >= opargs[0]->length || idx < 0) {
    4034             : #ifndef SMALL_KERNEL
    4035           0 :                         aml_showvalue(opargs[0]);
    4036             : #endif
    4037           0 :                         aml_die("Index out of bounds %d/%d\n", idx,
    4038             :                             opargs[0]->length);
    4039           0 :                 }
    4040           0 :                 switch (opargs[0]->type) {
    4041             :                 case AML_OBJTYPE_PACKAGE:
    4042             :                         /* Don't set opargs[0] to NULL */
    4043           0 :                         if (ret_type == 't' || ret_type == 'i' || ret_type == 'T') {
    4044           0 :                                 my_ret = opargs[0]->v_package[idx];
    4045           0 :                                 aml_addref(my_ret, "Index.Package");
    4046           0 :                         } else {
    4047           0 :                                 my_ret = aml_allocvalue(AML_OBJTYPE_OBJREF, AMLOP_PACKAGE,
    4048           0 :                                     opargs[0]->v_package[idx]);
    4049           0 :                                 aml_addref(my_ret->v_objref.ref,
    4050             :                                     "Index.Package");
    4051             :                         }
    4052             :                         break;
    4053             :                 case AML_OBJTYPE_BUFFER:
    4054             :                 case AML_OBJTYPE_STRING:
    4055             :                 case AML_OBJTYPE_INTEGER:
    4056           0 :                         rv = aml_convert(opargs[0], AML_OBJTYPE_BUFFER, -1);
    4057           0 :                         if (ret_type == 't' || ret_type == 'i' || ret_type == 'T') {
    4058             :                                 dnprintf(12,"Index.Buf Term: %d = %x\n",
    4059             :                                     idx, rv->v_buffer[idx]);
    4060           0 :                                 ival = rv->v_buffer[idx];
    4061           0 :                         } else {
    4062             :                                 dnprintf(12, "Index.Buf Targ\n");
    4063           0 :                                 my_ret = aml_allocvalue(0,0,NULL);
    4064           0 :                                 aml_createfield(my_ret, AMLOP_INDEX, rv,
    4065           0 :                                     8 * idx, 8, NULL, 0, AML_FIELD_BYTEACC);
    4066             :                         }
    4067           0 :                         aml_delref(&rv, "Index.BufStr");
    4068           0 :                         break;
    4069             :                 default:
    4070           0 :                         aml_die("Unknown index : %x\n", opargs[0]->type);
    4071           0 :                         break;
    4072             :                 }
    4073           0 :                 aml_store(scope, opargs[2], ival, my_ret);
    4074           0 :                 break;
    4075             :         case AMLOP_DEREFOF:
    4076             :                 /* DerefOf: t:ObjRef => DataRefObj */
    4077           0 :                 if (opargs[0]->type == AML_OBJTYPE_OBJREF) {
    4078           0 :                         my_ret = opargs[0]->v_objref.ref;
    4079           0 :                         aml_addref(my_ret, "DerefOf");
    4080           0 :                 } else {
    4081           0 :                         my_ret = opargs[0];
    4082             :                         //aml_addref(my_ret, "DerefOf");
    4083             :                 }
    4084             :                 break;
    4085             :         case AMLOP_COPYOBJECT:
    4086             :                 /* CopyObject: t:DataRefObj, s:implename => DataRefObj */
    4087           0 :                 my_ret = opargs[0];
    4088           0 :                 aml_freevalue(opargs[1]);
    4089           0 :                 aml_copyvalue(opargs[1], opargs[0]);
    4090           0 :                 break;
    4091             :         case AMLOP_STORE:
    4092             :                 /* Store: t:DataRefObj, S:upername => DataRefObj */
    4093           0 :                 my_ret = opargs[0];
    4094           0 :                 aml_store(scope, opargs[1], 0, opargs[0]);
    4095           0 :                 break;
    4096             : 
    4097             :                 /* Conversion */
    4098             :         case AMLOP_TOINTEGER:
    4099             :                 /* Source:CData, Result => Integer */
    4100           0 :                 my_ret = aml_convert(opargs[0], AML_OBJTYPE_INTEGER, -1);
    4101           0 :                 aml_store(scope, opargs[1], 0, my_ret);
    4102           0 :                 break;
    4103             :         case AMLOP_TOBUFFER:
    4104             :                 /* Source:CData, Result => Buffer */
    4105           0 :                 my_ret = aml_convert(opargs[0], AML_OBJTYPE_BUFFER, -1);
    4106           0 :                 aml_store(scope, opargs[1], 0, my_ret);
    4107           0 :                 break;
    4108             :         case AMLOP_TOHEXSTRING:
    4109             :                 /* Source:CData, Result => String */
    4110           0 :                 my_ret = aml_convert(opargs[0], AML_OBJTYPE_HEXSTRING, -1);
    4111           0 :                 aml_store(scope, opargs[1], 0, my_ret);
    4112           0 :                 break;
    4113             :         case AMLOP_TODECSTRING:
    4114             :                 /* Source:CData, Result => String */
    4115           0 :                 my_ret = aml_convert(opargs[0], AML_OBJTYPE_DECSTRING, -1);
    4116           0 :                 aml_store(scope, opargs[1], 0, my_ret);
    4117           0 :                 break;
    4118             :         case AMLOP_TOSTRING:
    4119             :                 /* Source:B, Length:I, Result => String */
    4120           0 :                 my_ret = aml_convert(opargs[0], AML_OBJTYPE_STRING,
    4121           0 :                     opargs[1]->v_integer);
    4122           0 :                 aml_store(scope, opargs[2], 0, my_ret);
    4123           0 :                 break;
    4124             :         case AMLOP_CONCAT:
    4125             :                 /* Source1:CData, Source2:CData, Result => CData */
    4126           0 :                 my_ret = aml_concat(opargs[0], opargs[1]);
    4127           0 :                 aml_store(scope, opargs[2], 0, my_ret);
    4128           0 :                 break;
    4129             :         case AMLOP_CONCATRES:
    4130             :                 /* Concat two resource buffers: buf1, buf2, result => Buffer */
    4131           0 :                 my_ret = aml_concatres(opargs[0], opargs[1]);
    4132           0 :                 aml_store(scope, opargs[2], 0, my_ret);
    4133           0 :                 break;
    4134             :         case AMLOP_MID:
    4135             :                 /* Source:BS, Index:I, Length:I, Result => BS */
    4136           0 :                 my_ret = aml_mid(opargs[0], opargs[1]->v_integer,
    4137           0 :                     opargs[2]->v_integer);
    4138           0 :                 aml_store(scope, opargs[3], 0, my_ret);
    4139           0 :                 break;
    4140             :         case AMLOP_MATCH:
    4141             :                 /* Match: Pkg, Op1, Val1, Op2, Val2, Index */
    4142           0 :                 ival = aml_match(opargs[0], opargs[5]->v_integer,
    4143           0 :                     opargs[1]->v_integer, opargs[2]->v_integer,
    4144           0 :                     opargs[3]->v_integer, opargs[4]->v_integer);
    4145           0 :                 break;
    4146             :         case AMLOP_SIZEOF:
    4147             :                 /* Sizeof: S => i */
    4148           0 :                 rv = aml_gettgt(opargs[0], opcode);
    4149           0 :                 ival = rv->length;
    4150           0 :                 break;
    4151             :         case AMLOP_OBJECTTYPE:
    4152             :                 /* ObjectType: S => i */
    4153           0 :                 rv = aml_gettgt(opargs[0], opcode);
    4154           0 :                 ival = rv->type;
    4155           0 :                 break;
    4156             : 
    4157             :                 /* Mutex/Event handlers */
    4158             :         case AMLOP_ACQUIRE:
    4159             :                 /* Acquire: Sw => Bool */
    4160           0 :                 rv = aml_gettgt(opargs[0], opcode);
    4161           0 :                 ival = acpi_mutex_acquire(scope, rv,
    4162           0 :                     opargs[1]->v_integer);
    4163           0 :                 break;
    4164             :         case AMLOP_RELEASE:
    4165             :                 /* Release: S */
    4166           0 :                 rv = aml_gettgt(opargs[0], opcode);
    4167           0 :                 acpi_mutex_release(scope, rv);
    4168           0 :                 break;
    4169             :         case AMLOP_WAIT:
    4170             :                 /* Wait: Si => Bool */
    4171           0 :                 rv = aml_gettgt(opargs[0], opcode);
    4172           0 :                 ival = acpi_event_wait(scope, rv,
    4173           0 :                     opargs[1]->v_integer);
    4174           0 :                 break;
    4175             :         case AMLOP_RESET:
    4176             :                 /* Reset: S */
    4177           0 :                 rv = aml_gettgt(opargs[0], opcode);
    4178           0 :                 acpi_event_reset(scope, rv);
    4179           0 :                 break;
    4180             :         case AMLOP_SIGNAL:
    4181             :                 /* Signal: S */
    4182           0 :                 rv = aml_gettgt(opargs[0], opcode);
    4183           0 :                 acpi_event_signal(scope, rv);
    4184           0 :                 break;
    4185             : 
    4186             :                 /* Named objects */
    4187             :         case AMLOP_NAME:
    4188             :                 /* Name: Nt */
    4189           0 :                 rv = opargs[0];
    4190           0 :                 aml_freevalue(rv);
    4191           0 :                         aml_copyvalue(rv, opargs[1]);
    4192           0 :                 break;
    4193             :         case AMLOP_ALIAS:
    4194             :                 /* Alias: nN */
    4195           0 :                 rv = _aml_setvalue(opargs[1], AML_OBJTYPE_OBJREF, opcode, 0);
    4196           0 :                 rv->v_objref.ref = aml_gettgt(opargs[0], opcode);
    4197           0 :                 aml_addref(rv->v_objref.ref, "Alias");
    4198           0 :                 break;
    4199             :         case AMLOP_OPREGION:
    4200             :                 /* OpRegion: Nbii */
    4201           0 :                 rv = _aml_setvalue(opargs[0], AML_OBJTYPE_OPREGION, 0, 0);
    4202           0 :                 rv->v_opregion.iospace = opargs[1]->v_integer;
    4203           0 :                 rv->v_opregion.iobase = opargs[2]->v_integer;
    4204           0 :                 rv->v_opregion.iolen = opargs[3]->v_integer;
    4205           0 :                 rv->v_opregion.flag = 0;
    4206           0 :                 break;
    4207             :         case AMLOP_DATAREGION:
    4208             :                 /* DataTableRegion: N,t:SigStr,t:OemIDStr,t:OemTableIDStr */
    4209           0 :                 rv = _aml_setvalue(opargs[0], AML_OBJTYPE_OPREGION, 0, 0);
    4210           0 :                 rv->v_opregion.iospace = GAS_SYSTEM_MEMORY;
    4211           0 :                 rv->v_opregion.iobase = 0;
    4212           0 :                 rv->v_opregion.iolen = 0;
    4213           0 :                 aml_die("AML-DataTableRegion\n");
    4214           0 :                 break;
    4215             :         case AMLOP_EVENT:
    4216             :                 /* Event: N */
    4217           0 :                 rv = _aml_setvalue(opargs[0], AML_OBJTYPE_EVENT, 0, 0);
    4218           0 :                 rv->v_integer = 0;
    4219           0 :                 break;
    4220             :         case AMLOP_MUTEX:
    4221             :                 /* Mutex: Nw */
    4222           0 :                 rv = _aml_setvalue(opargs[0], AML_OBJTYPE_MUTEX, 0, 0);
    4223           0 :                 rv->v_mtx.synclvl = opargs[1]->v_integer;
    4224           0 :                 break;
    4225             :         case AMLOP_SCOPE:
    4226             :                 /* Scope: NT */
    4227           0 :                 rv = opargs[0];
    4228           0 :                 if (rv->type == AML_OBJTYPE_NAMEREF) {
    4229           0 :                         printf("Undefined scope: %s\n", aml_getname(rv->v_nameref));
    4230           0 :                         break;
    4231             :                 }
    4232           0 :                 mscope = aml_pushscope(scope, opargs[1], rv->node, opcode);
    4233           0 :                 break;
    4234             :         case AMLOP_DEVICE:
    4235             :                 /* Device: NT */
    4236           0 :                 rv = _aml_setvalue(opargs[0], AML_OBJTYPE_DEVICE, 0, 0);
    4237           0 :                 mscope = aml_pushscope(scope, opargs[1], rv->node, opcode);
    4238           0 :                 break;
    4239             :         case AMLOP_THERMALZONE:
    4240             :                 /* ThermalZone: NT */
    4241           0 :                 rv = _aml_setvalue(opargs[0], AML_OBJTYPE_THERMZONE, 0, 0);
    4242           0 :                 mscope = aml_pushscope(scope, opargs[1], rv->node, opcode);
    4243           0 :                 break;
    4244             :         case AMLOP_POWERRSRC:
    4245             :                 /* PowerRsrc: NbwT */
    4246           0 :                 rv = _aml_setvalue(opargs[0], AML_OBJTYPE_POWERRSRC, 0, 0);
    4247           0 :                 rv->v_powerrsrc.pwr_level = opargs[1]->v_integer;
    4248           0 :                 rv->v_powerrsrc.pwr_order = opargs[2]->v_integer;
    4249           0 :                 mscope = aml_pushscope(scope, opargs[3], rv->node, opcode);
    4250           0 :                 break;
    4251             :         case AMLOP_PROCESSOR:
    4252             :                 /* Processor: NbdbT */
    4253           0 :                 rv = _aml_setvalue(opargs[0], AML_OBJTYPE_PROCESSOR, 0, 0);
    4254           0 :                 rv->v_processor.proc_id = opargs[1]->v_integer;
    4255           0 :                 rv->v_processor.proc_addr = opargs[2]->v_integer;
    4256           0 :                 rv->v_processor.proc_len = opargs[3]->v_integer;
    4257           0 :                 mscope = aml_pushscope(scope, opargs[4], rv->node, opcode);
    4258           0 :                 break;
    4259             :         case AMLOP_METHOD:
    4260             :                 /* Method: NbM */
    4261           0 :                 rv = _aml_setvalue(opargs[0], AML_OBJTYPE_METHOD, 0, 0);
    4262           0 :                 rv->v_method.flags = opargs[1]->v_integer;
    4263           0 :                 rv->v_method.start = opargs[2]->v_buffer;
    4264           0 :                 rv->v_method.end = rv->v_method.start + opargs[2]->length;
    4265           0 :                 rv->v_method.base = aml_root.start;
    4266           0 :                 break;
    4267             : 
    4268             :                 /* Field objects */
    4269             :         case AMLOP_CREATEFIELD:
    4270             :                 /* Source:B, BitIndex:I, NumBits:I, FieldName */
    4271           0 :                 rv = _aml_setvalue(opargs[3], AML_OBJTYPE_BUFFERFIELD, 0, 0);
    4272           0 :                 aml_createfield(rv, opcode, opargs[0], opargs[1]->v_integer,
    4273           0 :                     opargs[2]->v_integer, NULL, 0, 0);
    4274           0 :                 break;
    4275             :         case AMLOP_CREATEBITFIELD:
    4276             :                 /* Source:B, BitIndex:I, FieldName */
    4277           0 :                 rv = _aml_setvalue(opargs[2], AML_OBJTYPE_BUFFERFIELD, 0, 0);
    4278           0 :                 aml_createfield(rv, opcode, opargs[0], opargs[1]->v_integer,
    4279             :                     1, NULL, 0, 0);
    4280           0 :                 break;
    4281             :         case AMLOP_CREATEBYTEFIELD:
    4282             :                 /* Source:B, ByteIndex:I, FieldName */
    4283           0 :                 rv = _aml_setvalue(opargs[2], AML_OBJTYPE_BUFFERFIELD, 0, 0);
    4284           0 :                 aml_createfield(rv, opcode, opargs[0], opargs[1]->v_integer*8,
    4285             :                     8, NULL, 0, AML_FIELD_BYTEACC);
    4286           0 :                 break;
    4287             :         case AMLOP_CREATEWORDFIELD:
    4288             :                 /* Source:B, ByteIndex:I, FieldName */
    4289           0 :                 rv = _aml_setvalue(opargs[2], AML_OBJTYPE_BUFFERFIELD, 0, 0);
    4290           0 :                 aml_createfield(rv, opcode, opargs[0], opargs[1]->v_integer*8,
    4291             :                     16, NULL, 0, AML_FIELD_WORDACC);
    4292           0 :                 break;
    4293             :         case AMLOP_CREATEDWORDFIELD:
    4294             :                 /* Source:B, ByteIndex:I, FieldName */
    4295           0 :                 rv = _aml_setvalue(opargs[2], AML_OBJTYPE_BUFFERFIELD, 0, 0);
    4296           0 :                 aml_createfield(rv, opcode, opargs[0], opargs[1]->v_integer*8,
    4297             :                     32, NULL, 0, AML_FIELD_DWORDACC);
    4298           0 :                 break;
    4299             :         case AMLOP_CREATEQWORDFIELD:
    4300             :                 /* Source:B, ByteIndex:I, FieldName */
    4301           0 :                 rv = _aml_setvalue(opargs[2], AML_OBJTYPE_BUFFERFIELD, 0, 0);
    4302           0 :                 aml_createfield(rv, opcode, opargs[0], opargs[1]->v_integer*8,
    4303             :                     64, NULL, 0, AML_FIELD_QWORDACC);
    4304           0 :                 break;
    4305             :         case AMLOP_FIELD:
    4306             :                 /* Field: n:OpRegion, b:Flags, F:ieldlist */
    4307           0 :                 mscope = aml_pushscope(scope, opargs[2], scope->node, opcode);
    4308           0 :                 aml_parsefieldlist(mscope, opcode, opargs[1]->v_integer,
    4309           0 :                     opargs[0], NULL, 0);
    4310             :                 mscope = NULL;
    4311           0 :                 break;
    4312             :         case AMLOP_INDEXFIELD:
    4313             :                 /* IndexField: n:Index, n:Data, b:Flags, F:ieldlist */
    4314           0 :                 mscope = aml_pushscope(scope, opargs[3], scope->node, opcode);
    4315           0 :                 aml_parsefieldlist(mscope, opcode, opargs[2]->v_integer,
    4316           0 :                     opargs[1], opargs[0], 0);
    4317             :                 mscope = NULL;
    4318           0 :                 break;
    4319             :         case AMLOP_BANKFIELD:
    4320             :                 /* BankField: n:OpRegion, n:Field, i:Bank, b:Flags, F:ieldlist */
    4321           0 :                 mscope = aml_pushscope(scope, opargs[4], scope->node, opcode);
    4322           0 :                 aml_parsefieldlist(mscope, opcode, opargs[3]->v_integer,
    4323           0 :                     opargs[0], opargs[1], opargs[2]->v_integer);
    4324             :                 mscope = NULL;
    4325           0 :                 break;
    4326             : 
    4327             :                 /* Misc functions */
    4328             :         case AMLOP_STALL:
    4329             :                 /* Stall: i */
    4330           0 :                 acpi_stall(opargs[0]->v_integer);
    4331           0 :                 break;
    4332             :         case AMLOP_SLEEP:
    4333             :                 /* Sleep: i */
    4334           0 :                 acpi_sleep(opargs[0]->v_integer, "amlsleep");
    4335           0 :                 break;
    4336             :         case AMLOP_NOTIFY:
    4337             :                 /* Notify: Si */
    4338           0 :                 rv = aml_gettgt(opargs[0], opcode);
    4339             :                 dnprintf(50,"Notifying: %s %llx\n",
    4340             :                     aml_nodename(rv->node),
    4341             :                     opargs[1]->v_integer);
    4342           0 :                 aml_notify(rv->node, opargs[1]->v_integer);
    4343           0 :                 break;
    4344             :         case AMLOP_TIMER:
    4345             :                 /* Timer: => i */
    4346           0 :                 nanouptime(&ts);
    4347           0 :                 ival = ts.tv_sec * 10000000 + ts.tv_nsec / 100;
    4348           0 :                 break;
    4349             :         case AMLOP_FATAL:
    4350             :                 /* Fatal: bdi */
    4351           0 :                 aml_die("AML FATAL ERROR: %x,%x,%x\n",
    4352             :                     opargs[0]->v_integer, opargs[1]->v_integer,
    4353             :                     opargs[2]->v_integer);
    4354           0 :                 break;
    4355             :         case AMLOP_LOADTABLE:
    4356             :                 /* LoadTable(Sig:Str, OEMID:Str, OEMTable:Str, [RootPath:Str], [ParmPath:Str],
    4357             :                    [ParmData:DataRefObj]) => DDBHandle */
    4358           0 :                 my_ret = aml_loadtable(acpi_softc, opargs[0]->v_string,
    4359           0 :                     opargs[1]->v_string, opargs[2]->v_string,
    4360           0 :                     opargs[3]->v_string, opargs[4]->v_string, opargs[5]);
    4361           0 :                 break;
    4362             :         case AMLOP_LOAD:
    4363             :                 /* Load(Object:NameString, DDBHandle:SuperName) */
    4364           0 :                 mscope = aml_load(acpi_softc, scope, opargs[0], opargs[1]);
    4365           0 :                 break;
    4366             :         case AMLOP_UNLOAD:
    4367             :                 /* DDBHandle */
    4368           0 :                 aml_die("Unload");
    4369           0 :                 break;
    4370             : 
    4371             :                 /* Control Flow */
    4372             :         case AMLOP_IF:
    4373             :                 /* Arguments: iT or iTbT */
    4374           0 :                 if (opargs[0]->v_integer) {
    4375             :                         dnprintf(10,"parse-if @ %.4x\n", pc);
    4376           0 :                         mscope = aml_pushscope(scope, opargs[1], scope->node,
    4377             :                             AMLOP_IF);
    4378           0 :                 } else if (opargs[3] != NULL) {
    4379             :                         dnprintf(10,"parse-else @ %.4x\n", pc);
    4380           0 :                         mscope = aml_pushscope(scope, opargs[3], scope->node,
    4381             :                             AMLOP_ELSE);
    4382           0 :                 }
    4383             :                 break;
    4384             :         case AMLOP_WHILE:
    4385           0 :                 if (opargs[0]->v_integer) {
    4386             :                         /* Set parent position to start of WHILE */
    4387           0 :                         scope->pos = start;
    4388           0 :                         mscope = aml_pushscope(scope, opargs[1], scope->node,
    4389             :                             AMLOP_WHILE);
    4390           0 :                 }
    4391             :                 break;
    4392             :         case AMLOP_BREAK:
    4393             :                 /* Break: Find While Scope parent, mark type as null */
    4394           0 :                 aml_findscope(scope, AMLOP_WHILE, AMLOP_BREAK);
    4395           0 :                 break;
    4396             :         case AMLOP_CONTINUE:
    4397             :                 /* Find Scope.. mark all objects as invalid on way to root */
    4398           0 :                 aml_findscope(scope, AMLOP_WHILE, AMLOP_CONTINUE);
    4399           0 :                 break;
    4400             :         case AMLOP_RETURN:
    4401           0 :                 mscope = aml_findscope(scope, AMLOP_METHOD, AMLOP_RETURN);
    4402           0 :                 if (mscope->retv) {
    4403           0 :                         aml_die("already allocated\n");
    4404           0 :                 }
    4405           0 :                 mscope->retv = aml_allocvalue(0,0,NULL);
    4406           0 :                 aml_copyvalue(mscope->retv, opargs[0]);
    4407             :                 mscope = NULL;
    4408           0 :                 break;
    4409             :         default:
    4410             :                 /* may be set direct result */
    4411           0 :                 aml_die("Unknown opcode: %x:%s\n", opcode, htab->mnem);
    4412           0 :                 break;
    4413             :         }
    4414           0 :         if (mscope != NULL) {
    4415             :                 /* Change our scope to new scope */
    4416             :                 scope = mscope;
    4417           0 :         }
    4418           0 :         if ((ret_type == 'i' || ret_type == 't') && my_ret == NULL) {
    4419             :                 dnprintf(10,"quick: %.4x [%s] alloc return integer = 0x%llx\n",
    4420             :                     pc, htab->mnem, ival);
    4421           0 :                 my_ret = aml_allocvalue(AML_OBJTYPE_INTEGER, ival, NULL);
    4422           0 :         }
    4423           0 :         if (ret_type == 'i' && my_ret && my_ret->type != AML_OBJTYPE_INTEGER) {
    4424             :                 dnprintf(10,"quick: %.4x convert to integer %s -> %s\n",
    4425             :                     pc, htab->mnem, stype);
    4426           0 :                 my_ret = aml_convert(my_ret, AML_OBJTYPE_INTEGER, -1);
    4427           0 :         }
    4428           0 :         if (my_ret != NULL) {
    4429             :                 /* Display result */
    4430             :                 dnprintf(20,"quick: %.4x %18s %c %.4x\n", pc, stype,
    4431             :                     ret_type, my_ret->stack);
    4432             :         }
    4433             : 
    4434             :         /* End opcode: display/free arguments */
    4435             : parse_error:
    4436           0 :         for (idx=0; idx<8; idx++) {
    4437           0 :                 if (opargs[idx] == my_ret)
    4438           0 :                         opargs[idx] = NULL;
    4439           0 :                 aml_delref(&opargs[idx], "oparg");
    4440             :         }
    4441             : 
    4442             :         /* If parsing whole scope and not done, start again */
    4443           0 :         if (ret_type == 'T') {
    4444           0 :                 aml_delref(&my_ret, "scope.loop");
    4445           0 :                 while (scope->pos >= scope->end && scope != iscope) {
    4446             :                         /* Pop intermediate scope */
    4447           0 :                         scope = aml_popscope(scope);
    4448             :                 }
    4449           0 :                 if (scope->pos && scope->pos < scope->end)
    4450           0 :                         goto start;
    4451             :         }
    4452             : 
    4453           0 :         odp--;
    4454             :         dnprintf(50, ">>return [%s] %s %c %p\n", aml_nodename(scope->node),
    4455             :             stype, ret_type, my_ret);
    4456             : 
    4457           0 :         return my_ret;
    4458           0 : }
    4459             : 
    4460             : int
    4461           0 : acpi_parse_aml(struct acpi_softc *sc, uint8_t *start, uint32_t length)
    4462             : {
    4463             :         struct aml_scope *scope;
    4464           0 :         struct aml_value res;
    4465             : 
    4466           0 :         aml_root.start = start;
    4467           0 :         memset(&res, 0, sizeof(res));
    4468           0 :         res.type = AML_OBJTYPE_SCOPE;
    4469           0 :         res.length = length;
    4470           0 :         res.v_buffer = start;
    4471             : 
    4472             :         /* Push toplevel scope, parse AML */
    4473           0 :         aml_error = 0;
    4474           0 :         scope = aml_pushscope(NULL, &res, &aml_root, AMLOP_SCOPE);
    4475           0 :         aml_busy++;
    4476           0 :         aml_parse(scope, 'T', "TopLevel");
    4477           0 :         aml_busy--;
    4478           0 :         aml_popscope(scope);
    4479             : 
    4480           0 :         if (aml_error) {
    4481           0 :                 printf("error in acpi_parse_aml\n");
    4482           0 :                 return -1;
    4483             :         }
    4484           0 :         return (0);
    4485           0 : }
    4486             : 
    4487             : /*
    4488             :  * @@@: External API
    4489             :  *
    4490             :  * evaluate an AML node
    4491             :  * Returns a copy of the value in res  (must be freed by user)
    4492             :  */
    4493             : int
    4494           0 : aml_evalnode(struct acpi_softc *sc, struct aml_node *node,
    4495             :     int argc, struct aml_value *argv, struct aml_value *res)
    4496             : {
    4497           0 :         struct aml_value *xres;
    4498             : 
    4499           0 :         if (res)
    4500           0 :                 memset(res, 0, sizeof(*res));
    4501           0 :         if (node == NULL || node->value == NULL)
    4502           0 :                 return (ACPI_E_BADVALUE);
    4503             :         dnprintf(12,"EVALNODE: %s %lx\n", aml_nodename(node), acpi_nalloc);
    4504             : 
    4505           0 :         aml_error = 0;
    4506           0 :         xres = aml_eval(NULL, node->value, 't', argc, argv);
    4507           0 :         if (xres) {
    4508           0 :                 if (res)
    4509           0 :                         aml_copyvalue(res, xres);
    4510           0 :                 if (xres != node->value)
    4511           0 :                         aml_delref(&xres, "evalnode");
    4512             :         }
    4513           0 :         if (aml_error) {
    4514           0 :                 printf("error evaluating: %s\n", aml_nodename(node));
    4515           0 :                 return (-1);
    4516             :         }
    4517           0 :         return (0);
    4518           0 : }
    4519             : 
    4520             : int
    4521           0 : aml_node_setval(struct acpi_softc *sc, struct aml_node *node, int64_t val)
    4522             : {
    4523           0 :         struct aml_value env;
    4524             : 
    4525           0 :         if (!node)
    4526           0 :                 return (0);
    4527             : 
    4528           0 :         memset(&env, 0, sizeof(env));
    4529           0 :         env.type = AML_OBJTYPE_INTEGER;
    4530           0 :         env.v_integer = val;
    4531             : 
    4532           0 :         return aml_evalnode(sc, node, 1, &env, NULL);
    4533           0 : }
    4534             : 
    4535             : /*
    4536             :  * evaluate an AML name
    4537             :  * Returns a copy of the value in res  (must be freed by user)
    4538             :  */
    4539             : int
    4540           0 : aml_evalname(struct acpi_softc *sc, struct aml_node *parent, const char *name,
    4541             :     int argc, struct aml_value *argv, struct aml_value *res)
    4542             : {
    4543           0 :         parent = aml_searchname(parent, name);
    4544           0 :         return aml_evalnode(sc, parent, argc, argv, res);
    4545             : }
    4546             : 
    4547             : /*
    4548             :  * evaluate an AML integer object
    4549             :  */
    4550             : int
    4551           0 : aml_evalinteger(struct acpi_softc *sc, struct aml_node *parent,
    4552             :     const char *name, int argc, struct aml_value *argv, int64_t *ival)
    4553             : {
    4554           0 :         struct aml_value res;
    4555             :         int rc;
    4556             : 
    4557           0 :         parent = aml_searchname(parent, name);
    4558           0 :         rc = aml_evalnode(sc, parent, argc, argv, &res);
    4559           0 :         if (rc == 0) {
    4560           0 :                 *ival = aml_val2int(&res);
    4561           0 :                 aml_freevalue(&res);
    4562           0 :         }
    4563           0 :         return rc;
    4564           0 : }
    4565             : 
    4566             : /*
    4567             :  * Search for an AML name in namespace.. root only
    4568             :  */
    4569             : struct aml_node *
    4570           0 : __aml_searchname(struct aml_node *root, const void *vname, int create)
    4571             : {
    4572             :         char *name = (char *)vname;
    4573           0 :         char  nseg[AML_NAMESEG_LEN + 1];
    4574             :         int   i;
    4575             : 
    4576             :         dnprintf(25,"Searchname: %s:%s = ", aml_nodename(root), name);
    4577           0 :         while (*name == AMLOP_ROOTCHAR) {
    4578             :                 root = &aml_root;
    4579           0 :                 name++;
    4580             :         }
    4581           0 :         while (*name != 0) {
    4582             :                 /* Ugh.. we can have short names here: append '_' */
    4583           0 :                 strlcpy(nseg, "____", sizeof(nseg));
    4584           0 :                 for (i=0; i < AML_NAMESEG_LEN && *name && *name != '.'; i++)
    4585           0 :                         nseg[i] = *name++;
    4586           0 :                 if (*name == '.')
    4587           0 :                         name++;
    4588           0 :                 root = __aml_search(root, nseg, create);
    4589             :         }
    4590             :         dnprintf(25,"%p %s\n", root, aml_nodename(root));
    4591           0 :         return root;
    4592           0 : }
    4593             : 
    4594             : struct aml_node *
    4595           0 : aml_searchname(struct aml_node *root, const void *vname)
    4596             : {
    4597           0 :         return __aml_searchname(root, vname, 0);
    4598             : }
    4599             : 
    4600             : /*
    4601             :  * Search for relative name
    4602             :  */
    4603             : struct aml_node *
    4604           0 : aml_searchrel(struct aml_node *root, const void *vname)
    4605             : {
    4606             :         struct aml_node *res;
    4607             : 
    4608           0 :         while (root) {
    4609           0 :                 res = aml_searchname(root, vname);
    4610           0 :                 if (res != NULL)
    4611           0 :                         return res;
    4612           0 :                 root = root->parent;
    4613             :         }
    4614           0 :         return NULL;
    4615           0 : }
    4616             : 
    4617             : #ifndef SMALL_KERNEL
    4618             : 
    4619             : void
    4620           0 : acpi_getdevlist(struct acpi_devlist_head *list, struct aml_node *root,
    4621             :     struct aml_value *pkg, int off)
    4622             : {
    4623             :         struct acpi_devlist *dl;
    4624             :         struct aml_node *node;
    4625             :         int idx;
    4626             : 
    4627           0 :         for (idx=off; idx<pkg->length; idx++) {
    4628           0 :                 node = aml_searchname(root, pkg->v_package[idx]->v_string);
    4629           0 :                 if (node) {
    4630           0 :                         dl = acpi_os_malloc(sizeof(*dl));
    4631           0 :                         if (dl) {
    4632           0 :                                 dl->dev_node = node;
    4633           0 :                                 TAILQ_INSERT_TAIL(list, dl, dev_link);
    4634           0 :                         }
    4635             :                 }
    4636             :         }
    4637           0 : }
    4638             : 
    4639             : void
    4640           0 : acpi_freedevlist(struct acpi_devlist_head *list)
    4641             : {
    4642             :         struct acpi_devlist *dl;
    4643             : 
    4644           0 :         while ((dl = TAILQ_FIRST(list)) != NULL) {
    4645           0 :                 TAILQ_REMOVE(list, dl, dev_link);
    4646           0 :                 acpi_os_free(dl);
    4647             :         }
    4648           0 : }
    4649             : #endif /* SMALL_KERNEL */

Generated by: LCOV version 1.13