The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/acpi/dsdt.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 264d421c7e83f206d5dc6bfc93cbfe43


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.