root/dev/acpi/dsdt.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. aml_pc
  2. _aml_die
  3. aml_hashopcodes
  4. aml_findopcode
  5. aml_mnem
  6. aml_args
  7. _acpi_os_malloc
  8. _acpi_os_free
  9. acpi_sleep
  10. acpi_stall
  11. acpi_mutex_acquire
  12. acpi_mutex_release
  13. aml_dump
  14. aml_tstbit
  15. aml_setbit
  16. aml_gasio
  17. acpi_poll
  18. aml_register_notify
  19. aml_notify
  20. aml_notify_dev
  21. acpi_poll_notify
  22. __aml_search
  23. aml_nodename
  24. aml_getname
  25. aml_createname
  26. aml_searchname
  27. aml_delchildren
  28. aml_alloctmp
  29. aml_pushscope
  30. aml_popscope
  31. aml_parsenode
  32. aml_setbufint
  33. aml_getbufint
  34. aml_lockfield
  35. aml_unlockfield
  36. aml_getbuffer
  37. aml_fieldio
  38. aml_showvalue
  39. aml_derefvalue
  40. aml_str2int
  41. aml_val2int
  42. _aml_setvalue
  43. aml_copyvalue
  44. is_local
  45. aml_setvalue
  46. aml_allocvalue
  47. aml_freevalue
  48. aml_addref
  49. _aml_delref
  50. aml_convradix
  51. aml_lsb
  52. aml_msb
  53. aml_evalexpr
  54. aml_cmpvalue
  55. aml_bufcpy
  56. aml_callmethod
  57. aml_evalmethod
  58. aml_evalnode
  59. aml_evalname
  60. aml_evalinteger
  61. aml_walknodes
  62. aml_walktree
  63. aml_walkroot
  64. aml_find_node
  65. aml_parseopcode
  66. aml_parsename
  67. aml_parselength
  68. aml_parseend
  69. aml_resize
  70. aml_match
  71. aml_getpciaddr
  72. aml_fixref
  73. aml_parseint
  74. aml_evaltarget
  75. aml_evalterm
  76. aml_parsenamed
  77. aml_parsenamedscope
  78. aml_parsemath
  79. aml_parsecompare
  80. aml_parseif
  81. aml_parsewhile
  82. aml_parsebufpkg
  83. aml_parsemethod
  84. aml_parsesimple
  85. aml_parsefieldunit
  86. aml_parsebufferfield
  87. aml_parsemuxaction
  88. aml_parsemisc2
  89. aml_parsemisc3
  90. aml_parsematch
  91. aml_parseref
  92. aml_parsestring
  93. aml_parseterm
  94. aml_parsetarget
  95. aml_parseop
  96. aml_eisaid
  97. aml_fixup_dsdt
  98. aml_callosi
  99. aml_create_defaultobjects
  100. aml_print_resource
  101. aml_mapresource
  102. aml_parse_resource
  103. aml_foreachpkg
  104. acpi_parse_aml
  105. aml_fixup_node
  106. aml_postparse

    1 /* $OpenBSD: dsdt.c,v 1.87 2007/04/11 02:51:11 jordan 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/device.h>
   21 #include <sys/malloc.h>
   22 #include <sys/proc.h>
   23 
   24 #include <machine/bus.h>
   25 
   26 #ifdef DDB
   27 #include <machine/db_machdep.h>
   28 #include <ddb/db_command.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 #define opsize(opcode) (((opcode) & 0xFF00) ? 2 : 1)
   37 
   38 #define AML_CHECKSTACK()
   39 
   40 #define AML_FIELD_RESERVED      0x00
   41 #define AML_FIELD_ATTRIB        0x01
   42 
   43 #define AML_REVISION            0x01
   44 #define AML_INTSTRLEN           16
   45 #define AML_NAMESEG_LEN         4
   46 
   47 #define aml_valid(pv)    ((pv) != NULL)
   48 
   49 #define aml_ipaddr(n) ((n)-aml_root.start)
   50 
   51 extern int hz;
   52 
   53 struct aml_scope;
   54 
   55 int                     aml_cmpvalue(struct aml_value *, struct aml_value *, int);
   56 void                    aml_copyvalue(struct aml_value *, struct aml_value *);
   57 
   58 void                    aml_setvalue(struct aml_scope *, struct aml_value *,
   59                             struct aml_value *, int64_t);
   60 void                    aml_freevalue(struct aml_value *);
   61 struct aml_value        *aml_allocvalue(int, int64_t, const void *);
   62 struct aml_value        *_aml_setvalue(struct aml_value *, int, int64_t,
   63                             const void *);
   64 
   65 u_int64_t               aml_convradix(u_int64_t, int, int);
   66 int64_t                 aml_evalexpr(int64_t, int64_t, int);
   67 int                     aml_lsb(u_int64_t);
   68 int                     aml_msb(u_int64_t);
   69 
   70 int                     aml_tstbit(const u_int8_t *, int);
   71 void                    aml_setbit(u_int8_t *, int, int);
   72 
   73 void                    aml_bufcpy(void *, int, const void *, int, int);
   74 int                     aml_evalinteger(struct acpi_softc *, struct aml_node *,
   75                             const char *, int, struct aml_value *, int64_t *);
   76 
   77 void                    _aml_delref(struct aml_value **val, const char *, int);
   78 void                    aml_delref(struct aml_value **);
   79 void                    aml_addref(struct aml_value *);
   80 int                     aml_pc(uint8_t *);
   81 
   82 #define aml_delref(x) _aml_delref(x, __FUNCTION__, __LINE__)
   83 
   84 struct aml_value        *aml_parseop(struct aml_scope *, struct aml_value *);
   85 struct aml_value        *aml_parsetarget(struct aml_scope *, struct aml_value *,
   86                             struct aml_value **);
   87 struct aml_value        *aml_parseterm(struct aml_scope *, struct aml_value *);
   88 
   89 struct aml_value        *aml_evaltarget(struct aml_scope *scope,
   90                             struct aml_value *res);
   91 int                     aml_evalterm(struct aml_scope *scope,
   92                             struct aml_value *raw, struct aml_value *dst);
   93 void                    aml_gasio(struct acpi_softc *, int, uint64_t, uint64_t,
   94                             int, int, int, void *, int);
   95 
   96 struct aml_opcode       *aml_findopcode(int);
   97 
   98 #define acpi_os_malloc(sz) _acpi_os_malloc(sz, __FUNCTION__, __LINE__)
   99 #define acpi_os_free(ptr)  _acpi_os_free(ptr, __FUNCTION__, __LINE__)
  100 
  101 void                    *_acpi_os_malloc(size_t, const char *, int);
  102 void                    _acpi_os_free(void *, const char *, int);
  103 void                    acpi_sleep(int);
  104 void                    acpi_stall(int);
  105 
  106 struct aml_value        *aml_callosi(struct aml_scope *, struct aml_value *);
  107 struct aml_value        *aml_callmethod(struct aml_scope *, struct aml_value *);
  108 struct aml_value        *aml_evalmethod(struct aml_scope *, struct aml_node *,
  109                             int, struct aml_value *, struct aml_value *);
  110 
  111 const char *aml_getname(const char *);
  112 void                    aml_dump(int, u_int8_t *);
  113 void                    _aml_die(const char *fn, int line, const char *fmt, ...);
  114 #define aml_die(x...)   _aml_die(__FUNCTION__, __LINE__, x)
  115 
  116 /*
  117  * @@@: Global variables
  118  */
  119 int                     aml_intlen = 64;
  120 struct aml_node         aml_root;
  121 struct aml_value        *aml_global_lock;
  122 struct acpi_softc       *dsdt_softc;
  123 
  124 struct aml_value *aml_parsenamed(struct aml_scope *, int, struct aml_value *);
  125 struct aml_value *aml_parsenamedscope(struct aml_scope *, int, struct aml_value *);
  126 struct aml_value *aml_parsemath(struct aml_scope *, int, struct aml_value *);
  127 struct aml_value *aml_parsecompare(struct aml_scope *, int, struct aml_value *);
  128 struct aml_value *aml_parseif(struct aml_scope *, int, struct aml_value *);
  129 struct aml_value *aml_parsewhile(struct aml_scope *, int, struct aml_value *);
  130 struct aml_value *aml_parsebufpkg(struct aml_scope *, int, struct aml_value *);
  131 struct aml_value *aml_parsemethod(struct aml_scope *, int, struct aml_value *);
  132 struct aml_value *aml_parsesimple(struct aml_scope *, int, struct aml_value *);
  133 struct aml_value *aml_parsefieldunit(struct aml_scope *, int, struct aml_value *);
  134 struct aml_value *aml_parsebufferfield(struct aml_scope *, int, struct aml_value *);
  135 struct aml_value *aml_parsemisc3(struct aml_scope *, int, struct aml_value *);
  136 struct aml_value *aml_parsemuxaction(struct aml_scope *, int, struct aml_value *);
  137 struct aml_value *aml_parsemisc2(struct aml_scope *, int, struct aml_value *);
  138 struct aml_value *aml_parsematch(struct aml_scope *, int, struct aml_value *);
  139 struct aml_value *aml_parseref(struct aml_scope *, int, struct aml_value *);
  140 struct aml_value *aml_parsestring(struct aml_scope *, int, struct aml_value *);
  141 
  142 /* Perfect Hash key */
  143 #define HASH_OFF                6904
  144 #define HASH_SIZE               179
  145 #define HASH_KEY(k)             (((k) ^ HASH_OFF) % HASH_SIZE)
  146 
  147 /*
  148  * XXX this array should be sorted, and then aml_findopcode() should
  149  * do a binary search
  150  */
  151 struct aml_opcode **aml_ophash;
  152 struct aml_opcode aml_table[] = {
  153         /* Simple types */
  154         { AMLOP_ZERO,           "Zero",         "c",    aml_parsesimple },
  155         { AMLOP_ONE,            "One",          "c",    aml_parsesimple },
  156         { AMLOP_ONES,           "Ones",         "c",    aml_parsesimple },
  157         { AMLOP_REVISION,       "Revision",     "R",    aml_parsesimple },
  158         { AMLOP_BYTEPREFIX,     ".Byte",        "b",    aml_parsesimple },
  159         { AMLOP_WORDPREFIX,     ".Word",        "w",    aml_parsesimple },
  160         { AMLOP_DWORDPREFIX,    ".DWord",       "d",    aml_parsesimple },
  161         { AMLOP_QWORDPREFIX,    ".QWord",       "q",    aml_parsesimple },
  162         { AMLOP_STRINGPREFIX,   ".String",      "a",    aml_parsesimple },
  163         { AMLOP_DEBUG,          "DebugOp",      "D",    aml_parsesimple },
  164         { AMLOP_BUFFER,         "Buffer",       "piB",  aml_parsebufpkg },
  165         { AMLOP_PACKAGE,        "Package",      "pbT",  aml_parsebufpkg },
  166         { AMLOP_VARPACKAGE,     "VarPackage",   "piT",  aml_parsebufpkg },
  167 
  168         /* Simple objects */
  169         { AMLOP_LOCAL0,         "Local0",       "L",    aml_parseref },
  170         { AMLOP_LOCAL1,         "Local1",       "L",    aml_parseref },
  171         { AMLOP_LOCAL2,         "Local2",       "L",    aml_parseref },
  172         { AMLOP_LOCAL3,         "Local3",       "L",    aml_parseref },
  173         { AMLOP_LOCAL4,         "Local4",       "L",    aml_parseref },
  174         { AMLOP_LOCAL5,         "Local5",       "L",    aml_parseref },
  175         { AMLOP_LOCAL6,         "Local6",       "L",    aml_parseref },
  176         { AMLOP_LOCAL7,         "Local7",       "L",    aml_parseref },
  177         { AMLOP_ARG0,           "Arg0",         "A",    aml_parseref },
  178         { AMLOP_ARG1,           "Arg1",         "A",    aml_parseref },
  179         { AMLOP_ARG2,           "Arg2",         "A",    aml_parseref },
  180         { AMLOP_ARG3,           "Arg3",         "A",    aml_parseref },
  181         { AMLOP_ARG4,           "Arg4",         "A",    aml_parseref },
  182         { AMLOP_ARG5,           "Arg5",         "A",    aml_parseref },
  183         { AMLOP_ARG6,           "Arg6",         "A",    aml_parseref },
  184 
  185         /* Control flow */
  186         { AMLOP_IF,             "If",           "pI",   aml_parseif },
  187         { AMLOP_ELSE,           "Else",         "pT" },
  188         { AMLOP_WHILE,          "While",        "piT",  aml_parsewhile },
  189         { AMLOP_BREAK,          "Break",        "" },
  190         { AMLOP_CONTINUE,       "Continue",     "" },
  191         { AMLOP_RETURN,         "Return",       "t",    aml_parseref },
  192         { AMLOP_FATAL,          "Fatal",        "bdi",  aml_parsemisc2 },
  193         { AMLOP_NOP,            "Nop",          "",     aml_parsesimple },
  194         { AMLOP_BREAKPOINT,     "BreakPoint",   "" },
  195 
  196         /* Arithmetic operations */
  197         { AMLOP_INCREMENT,      "Increment",    "t",    aml_parsemath },
  198         { AMLOP_DECREMENT,      "Decrement",    "t",    aml_parsemath },
  199         { AMLOP_ADD,            "Add",          "iir",  aml_parsemath },
  200         { AMLOP_SUBTRACT,       "Subtract",     "iir",  aml_parsemath },
  201         { AMLOP_MULTIPLY,       "Multiply",     "iir",  aml_parsemath },
  202         { AMLOP_DIVIDE,         "Divide",       "iirr", aml_parsemath },
  203         { AMLOP_SHL,            "ShiftLeft",    "iir",  aml_parsemath },
  204         { AMLOP_SHR,            "ShiftRight",   "iir",  aml_parsemath },
  205         { AMLOP_AND,            "And",          "iir",  aml_parsemath },
  206         { AMLOP_NAND,           "Nand",         "iir",  aml_parsemath },
  207         { AMLOP_OR,             "Or",           "iir",  aml_parsemath },
  208         { AMLOP_NOR,            "Nor",          "iir",  aml_parsemath },
  209         { AMLOP_XOR,            "Xor",          "iir",  aml_parsemath },
  210         { AMLOP_NOT,            "Not",          "ir",   aml_parsemath },
  211         { AMLOP_MOD,            "Mod",          "iir",  aml_parsemath },
  212         { AMLOP_FINDSETLEFTBIT, "FindSetLeftBit", "ir", aml_parsemath },
  213         { AMLOP_FINDSETRIGHTBIT,"FindSetRightBit", "ir",aml_parsemath },
  214 
  215         /* Logical test operations */
  216         { AMLOP_LAND,           "LAnd",         "ii",   aml_parsemath },
  217         { AMLOP_LOR,            "LOr",          "ii",   aml_parsemath },
  218         { AMLOP_LNOT,           "LNot",         "i",    aml_parsemath },
  219         { AMLOP_LNOTEQUAL,      "LNotEqual",    "tt",   aml_parsecompare },
  220         { AMLOP_LLESSEQUAL,     "LLessEqual",   "tt",   aml_parsecompare },
  221         { AMLOP_LGREATEREQUAL,  "LGreaterEqual", "tt",  aml_parsecompare },
  222         { AMLOP_LEQUAL,         "LEqual",       "tt",   aml_parsecompare },
  223         { AMLOP_LGREATER,       "LGreater",     "tt",   aml_parsecompare },
  224         { AMLOP_LLESS,          "LLess",        "tt",   aml_parsecompare },
  225 
  226         /* Named objects */
  227         { AMLOP_NAMECHAR,       ".NameRef",     "n",    aml_parsesimple },
  228         { AMLOP_ALIAS,          "Alias",        "nN",   aml_parsenamed },
  229         { AMLOP_NAME,           "Name", "Nt",   aml_parsenamed },
  230         { AMLOP_EVENT,          "Event",        "N",    aml_parsenamed },
  231         { AMLOP_MUTEX,          "Mutex",        "Nb",   aml_parsenamed },
  232         { AMLOP_DATAREGION,     "DataRegion",   "Nttt", aml_parsenamed },
  233         { AMLOP_OPREGION,       "OpRegion",     "Nbii", aml_parsenamed },
  234         { AMLOP_SCOPE,          "Scope",        "pNT",  aml_parsenamedscope },
  235         { AMLOP_DEVICE,         "Device",       "pNT",  aml_parsenamedscope },
  236         { AMLOP_POWERRSRC,      "Power Resource", "pNbwT", aml_parsenamedscope },
  237         { AMLOP_THERMALZONE,    "ThermalZone",  "pNT",  aml_parsenamedscope },
  238         { AMLOP_PROCESSOR,      "Processor",    "pNbdbT", aml_parsenamedscope },
  239         { AMLOP_METHOD,         "Method",       "pNfM", aml_parsemethod },
  240 
  241         /* Field operations */
  242         { AMLOP_FIELD,          "Field",        "pnfF",         aml_parsefieldunit },
  243         { AMLOP_INDEXFIELD,     "IndexField",   "pntfF",        aml_parsefieldunit },
  244         { AMLOP_BANKFIELD,      "BankField",    "pnnifF",       aml_parsefieldunit },
  245         { AMLOP_CREATEFIELD,    "CreateField",  "tiiN",         aml_parsebufferfield },
  246         { AMLOP_CREATEQWORDFIELD, "CreateQWordField","tiN",     aml_parsebufferfield },
  247         { AMLOP_CREATEDWORDFIELD, "CreateDWordField","tiN",     aml_parsebufferfield },
  248         { AMLOP_CREATEWORDFIELD, "CreateWordField", "tiN",      aml_parsebufferfield },
  249         { AMLOP_CREATEBYTEFIELD, "CreateByteField", "tiN",      aml_parsebufferfield },
  250         { AMLOP_CREATEBITFIELD, "CreateBitField", "tiN",        aml_parsebufferfield },
  251 
  252         /* Conversion operations */
  253         { AMLOP_TOINTEGER,      "ToInteger",    "tr",   aml_parsemath },
  254         { AMLOP_TOBUFFER,       "ToBuffer",     "tr",   },
  255         { AMLOP_TODECSTRING,    "ToDecString",  "ir",   aml_parsestring },
  256         { AMLOP_TOHEXSTRING,    "ToHexString",  "ir",   aml_parsestring },
  257         { AMLOP_TOSTRING,       "ToString",     "t",    aml_parsestring },
  258         { AMLOP_MID,            "Mid",          "tiir", aml_parsestring },
  259         { AMLOP_FROMBCD,        "FromBCD",      "ir",   aml_parsemath },
  260         { AMLOP_TOBCD,          "ToBCD",        "ir",   aml_parsemath },
  261 
  262         /* Mutex/Signal operations */
  263         { AMLOP_ACQUIRE,        "Acquire",      "tw",   aml_parsemuxaction },
  264         { AMLOP_RELEASE,        "Release",      "t",    aml_parsemuxaction },
  265         { AMLOP_SIGNAL,         "Signal",       "t",    aml_parsemuxaction },
  266         { AMLOP_WAIT,           "Wait",         "ti",   aml_parsemuxaction },
  267         { AMLOP_RESET,          "Reset",        "t",    aml_parsemuxaction },
  268 
  269         { AMLOP_INDEX,          "Index",        "tir",  aml_parseref },
  270         { AMLOP_DEREFOF,        "DerefOf",      "t",    aml_parseref },
  271         { AMLOP_REFOF,          "RefOf",        "t",    aml_parseref },
  272         { AMLOP_CONDREFOF,      "CondRef",      "nr",   aml_parseref },
  273 
  274         { AMLOP_LOADTABLE,      "LoadTable",    "tttttt" },
  275         { AMLOP_STALL,          "Stall",        "i",    aml_parsemisc2 },
  276         { AMLOP_SLEEP,          "Sleep",        "i",    aml_parsemisc2 },
  277         { AMLOP_LOAD,           "Load",         "nt",   aml_parseref },
  278         { AMLOP_UNLOAD,         "Unload",       "t" },
  279         { AMLOP_STORE,          "Store",        "tr",   aml_parseref },
  280         { AMLOP_CONCAT,         "Concat",       "ttr",  aml_parsestring },
  281         { AMLOP_CONCATRES,      "ConcatRes",    "ttt" },
  282         { AMLOP_NOTIFY,         "Notify",       "ti",   aml_parsemisc2 },
  283         { AMLOP_SIZEOF,         "Sizeof",       "t",    aml_parsemisc3 },
  284         { AMLOP_MATCH,          "Match",        "tbibii", aml_parsematch },
  285         { AMLOP_OBJECTTYPE,     "ObjectType",   "t",    aml_parsemisc3 },
  286         { AMLOP_COPYOBJECT,     "CopyObject",   "tr",   aml_parseref },
  287 };
  288 
  289 int aml_pc(uint8_t *src)
  290 {
  291         return src - aml_root.start;
  292 }
  293 
  294 struct aml_scope *aml_lastscope;
  295 
  296 void _aml_die(const char *fn, int line, const char *fmt, ...)
  297 {
  298         struct aml_scope *root;
  299         va_list ap;
  300         int idx;
  301 
  302         va_start(ap, fmt);
  303         vprintf(fmt, ap);
  304         printf("\n");
  305         va_end(ap);
  306 
  307         for (root = aml_lastscope; root && root->pos; root = root->parent) {
  308                 printf("%.4x Called: %s\n", aml_pc(root->pos),
  309                     aml_nodename(root->node));
  310                 for (idx = 0; idx < root->nargs; idx++) {
  311                         printf("  arg%d: ", idx);
  312                         aml_showvalue(&root->args[idx], 0);
  313                 }
  314                 for (idx = 0; root->locals && idx < AML_MAX_LOCAL; idx++) {
  315                         if (root->locals[idx].type) {
  316                                 printf("  local%d: ", idx);
  317                                 aml_showvalue(&root->locals[idx], 0);
  318                         }
  319                 }
  320         }
  321 
  322         /* XXX: don't panic */
  323         panic("aml_die %s:%d", fn, line);
  324 }
  325 
  326 void
  327 aml_hashopcodes(void)
  328 {
  329         int i;
  330 
  331         /* Dynamically allocate hash table */
  332         aml_ophash = (struct aml_opcode **)acpi_os_malloc(HASH_SIZE*sizeof(struct aml_opcode *));
  333         for (i = 0; i < sizeof(aml_table) / sizeof(aml_table[0]); i++)
  334                 aml_ophash[HASH_KEY(aml_table[i].opcode)] = &aml_table[i];
  335 }
  336 
  337 struct aml_opcode *
  338 aml_findopcode(int opcode)
  339 {
  340         struct aml_opcode *hop;
  341 
  342         hop = aml_ophash[HASH_KEY(opcode)];
  343         if (hop && hop->opcode == opcode)
  344                 return hop;
  345         return NULL;
  346 }
  347 
  348 const char *
  349 aml_mnem(int opcode, uint8_t *pos)
  350 {
  351         struct aml_opcode *tab;
  352         static char mnemstr[32];
  353 
  354         if ((tab = aml_findopcode(opcode)) != NULL) {
  355                 strlcpy(mnemstr, tab->mnem, sizeof(mnemstr));
  356                 if (pos != NULL) {
  357                         switch (opcode) {
  358                         case AMLOP_STRINGPREFIX:
  359                                 snprintf(mnemstr, sizeof(mnemstr), "\"%s\"", pos);
  360                                 break;
  361                         case AMLOP_BYTEPREFIX:
  362                                 snprintf(mnemstr, sizeof(mnemstr), "0x%.2x",
  363                                          *(uint8_t *)pos);
  364                                 break;
  365                         case AMLOP_WORDPREFIX:
  366                                 snprintf(mnemstr, sizeof(mnemstr), "0x%.4x",
  367                                          *(uint16_t *)pos);
  368                                 break;
  369                         case AMLOP_DWORDPREFIX:
  370                                 snprintf(mnemstr, sizeof(mnemstr), "0x%.4x",
  371                                          *(uint16_t *)pos);
  372                                 break;
  373                         case AMLOP_NAMECHAR:
  374                                 strlcpy(mnemstr, aml_getname(pos), sizeof(mnemstr));
  375                                 break;
  376                         }
  377                 }
  378                 return mnemstr;
  379         }
  380         return ("xxx");
  381 }
  382 
  383 const char *
  384 aml_args(int opcode)
  385 {
  386         struct aml_opcode *tab;
  387 
  388         if ((tab = aml_findopcode(opcode)) != NULL)
  389                 return tab->args;
  390         return ("");
  391 }
  392 
  393 struct aml_notify_data {
  394         struct aml_node         *node;
  395         char                    pnpid[20];
  396         void                    *cbarg;
  397         int                     (*cbproc)(struct aml_node *, int, void *);
  398         int                     poll;
  399 
  400         SLIST_ENTRY(aml_notify_data) link;
  401 };
  402 
  403 SLIST_HEAD(aml_notify_head, aml_notify_data);
  404 struct aml_notify_head aml_notify_list =
  405     LIST_HEAD_INITIALIZER(&aml_notify_list);
  406 
  407 /*
  408  *  @@@: Memory management functions
  409  */
  410 
  411 long acpi_nalloc;
  412 
  413 struct acpi_memblock {
  414         size_t size;
  415 };
  416 
  417 void *
  418 _acpi_os_malloc(size_t size, const char *fn, int line)
  419 {
  420         struct acpi_memblock *sptr;
  421 
  422         sptr = malloc(size+sizeof(*sptr), M_DEVBUF, M_WAITOK);
  423         dnprintf(99, "alloc: %x %s:%d\n", sptr, fn, line);
  424         if (sptr) {
  425                 acpi_nalloc += size;
  426                 sptr->size = size;
  427                 memset(&sptr[1], 0, size);
  428                 return &sptr[1];
  429         }
  430         return NULL;
  431 }
  432 
  433 void
  434 _acpi_os_free(void *ptr, const char *fn, int line)
  435 {
  436         struct acpi_memblock *sptr;
  437 
  438         if (ptr != NULL) {
  439                 sptr = &(((struct acpi_memblock *)ptr)[-1]);
  440                 acpi_nalloc -= sptr->size;
  441 
  442                 dnprintf(99, "free: %x %s:%d\n", sptr, fn, line);
  443                 free(sptr, M_DEVBUF);
  444         }
  445 }
  446 
  447 void
  448 acpi_sleep(int ms)
  449 {
  450         int to = ms * hz / 1000;
  451 
  452         if (cold)
  453                 delay(ms * 1000);
  454         else {
  455                 if (to <= 0)
  456                         to = 1;
  457                 while (tsleep(dsdt_softc, PWAIT, "asleep", to) !=
  458                     EWOULDBLOCK);
  459         }
  460 }
  461 
  462 void
  463 acpi_stall(int us)
  464 {
  465         delay(us);
  466 }
  467 
  468 int
  469 acpi_mutex_acquire(struct aml_value *val, int timeout)
  470 {
  471         /* XXX we currently do not have concurrency so assume mutex succeeds */
  472         dnprintf(50, "acpi_mutex_acquire\n");
  473 
  474         return (0);
  475 #if 0
  476         struct acpi_mutex *mtx = val->v_mutex;
  477         int rv = 0, ts, tries = 0;
  478 
  479         if (val->type != AML_OBJTYPE_MUTEX) {
  480                 printf("acpi_mutex_acquire: invalid mutex\n");
  481                 return (1);
  482         }
  483 
  484         if (timeout == 0xffff)
  485                 timeout = 0;
  486 
  487         /* lock recursion be damned, panic if that happens */
  488         rw_enter_write(&mtx->amt_lock);
  489         while (mtx->amt_ref_count) {
  490                 rw_exit_write(&mtx->amt_lock);
  491                 /* block access */
  492                 ts = tsleep(mtx, PWAIT, mtx->amt_name, timeout / hz);
  493                 if (ts == EWOULDBLOCK) {
  494                         rv = 1; /* mutex not acquired */
  495                         goto done;
  496                 }
  497                 tries++;
  498                 rw_enter_write(&mtx->amt_lock);
  499         }
  500 
  501         mtx->amt_ref_count++;
  502         rw_exit_write(&mtx->amt_lock);
  503 done:
  504         return (rv);
  505 #endif
  506 }
  507 
  508 void
  509 acpi_mutex_release(struct aml_value *val)
  510 {
  511         dnprintf(50, "acpi_mutex_release\n");
  512 #if 0
  513         struct acpi_mutex *mtx = val->v_mutex;
  514 
  515         /* sanity */
  516         if (val->type != AML_OBJTYPE_MUTEX) {
  517                 printf("acpi_mutex_acquire: invalid mutex\n");
  518                 return;
  519         }
  520 
  521         rw_enter_write(&mtx->amt_lock);
  522 
  523         if (mtx->amt_ref_count == 0) {
  524                 printf("acpi_mutex_release underflow %s\n", mtx->amt_name);
  525                 goto done;
  526         }
  527 
  528         mtx->amt_ref_count--;
  529         wakeup(mtx); /* wake all of them up */
  530 done:
  531         rw_exit_write(&mtx->amt_lock);
  532 #endif
  533 }
  534 
  535 /*
  536  * @@@: Misc utility functions
  537  */
  538 
  539 void
  540 aml_dump(int len, u_int8_t *buf)
  541 {
  542         int             idx;
  543 
  544         dnprintf(50, "{ ");
  545         for (idx = 0; idx < len; idx++) {
  546                 dnprintf(50, "%s0x%.2x", idx ? ", " : "", buf[idx]);
  547         }
  548         dnprintf(50, " }\n");
  549 }
  550 
  551 /* Bit mangling code */
  552 int
  553 aml_tstbit(const u_int8_t *pb, int bit)
  554 {
  555         pb += aml_bytepos(bit);
  556 
  557         return (*pb & aml_bitmask(bit));
  558 }
  559 
  560 void
  561 aml_setbit(u_int8_t *pb, int bit, int val)
  562 {
  563         pb += aml_bytepos(bit);
  564 
  565         if (val)
  566                 *pb |= aml_bitmask(bit);
  567         else
  568                 *pb &= ~aml_bitmask(bit);
  569 }
  570 
  571 /* Read/Write to hardware I/O fields */
  572 void
  573 aml_gasio(struct acpi_softc *sc, int type, uint64_t base, uint64_t length,
  574     int bitpos, int bitlen, int size, void *buf, int mode)
  575 {
  576         dnprintf(10, "-- aml_gasio: %.2x"
  577             " base:%llx len:%llx bpos:%.4x blen:%.4x sz:%.2x mode=%s\n",
  578             type, base, length, bitpos, bitlen, size,
  579             mode==ACPI_IOREAD?"read":"write");
  580         acpi_gasio(sc, mode, type, base+(bitpos>>3),
  581             (size>>3), (bitlen>>3), buf);
  582 #ifdef ACPI_DEBUG
  583         while (bitlen > 0) {
  584                 dnprintf(10, "%.2x ", *(uint8_t *)buf);
  585                 buf++;
  586                 bitlen -=8;
  587         }
  588         dnprintf(10, "\n");
  589 #endif
  590 }
  591 
  592 /*
  593  * @@@: Notify functions
  594  */
  595 void
  596 acpi_poll(void *arg)
  597 {
  598         dsdt_softc->sc_poll = 1;
  599         dsdt_softc->sc_wakeup = 0;
  600         wakeup(dsdt_softc);
  601 
  602         timeout_add(&dsdt_softc->sc_dev_timeout, 10 * hz);
  603 }
  604 
  605 void
  606 aml_register_notify(struct aml_node *node, const char *pnpid,
  607     int (*proc)(struct aml_node *, int, void *), void *arg, int poll)
  608 {
  609         struct aml_notify_data  *pdata;
  610         extern int acpi_poll_enabled;
  611 
  612         dnprintf(10, "aml_register_notify: %s %s %x\n",
  613             node->name, pnpid ? pnpid : "", proc);
  614 
  615         pdata = acpi_os_malloc(sizeof(struct aml_notify_data));
  616         pdata->node = node;
  617         pdata->cbarg = arg;
  618         pdata->cbproc = proc;
  619         pdata->poll = poll;
  620 
  621         if (pnpid)
  622                 strlcpy(pdata->pnpid, pnpid, sizeof(pdata->pnpid));
  623 
  624         SLIST_INSERT_HEAD(&aml_notify_list, pdata, link);
  625 
  626         if (poll && !acpi_poll_enabled)
  627                 timeout_add(&dsdt_softc->sc_dev_timeout, 10 * hz);
  628 }
  629 
  630 void
  631 aml_notify(struct aml_node *node, int notify_value)
  632 {
  633         struct aml_notify_data  *pdata = NULL;
  634 
  635         if (node == NULL)
  636                 return;
  637 
  638         SLIST_FOREACH(pdata, &aml_notify_list, link)
  639                 if (pdata->node == node)
  640                         pdata->cbproc(pdata->node, notify_value, pdata->cbarg);
  641 }
  642 
  643 void
  644 aml_notify_dev(const char *pnpid, int notify_value)
  645 {
  646         struct aml_notify_data  *pdata = NULL;
  647 
  648         if (pnpid == NULL)
  649                 return;
  650 
  651         SLIST_FOREACH(pdata, &aml_notify_list, link)
  652                 if (pdata->pnpid && !strcmp(pdata->pnpid, pnpid))
  653                         pdata->cbproc(pdata->node, notify_value, pdata->cbarg);
  654 }
  655 
  656 void acpi_poll_notify(void)
  657 {
  658         struct aml_notify_data  *pdata = NULL;
  659 
  660         SLIST_FOREACH(pdata, &aml_notify_list, link)
  661                 if (pdata->cbproc && pdata->poll)
  662                         pdata->cbproc(pdata->node, 0, pdata->cbarg);
  663 }
  664 
  665 /*
  666  * @@@: Namespace functions
  667  */
  668 
  669 struct aml_node *__aml_search(struct aml_node *, uint8_t *);
  670 void aml_delchildren(struct aml_node *);
  671 
  672 
  673 /* Search for a name in children nodes */
  674 struct aml_node *
  675 __aml_search(struct aml_node *root, uint8_t *nameseg)
  676 {
  677         if (root == NULL)
  678                 return NULL;
  679         for (root = root->child; root; root = root->sibling) {
  680                 if (!memcmp(root->name, nameseg, AML_NAMESEG_LEN))
  681                         return root;
  682         }
  683         return NULL;
  684 }
  685 
  686 /* Get absolute pathname of AML node */
  687 const char *
  688 aml_nodename(struct aml_node *node)
  689 {
  690         static char namebuf[128];
  691 
  692         namebuf[0] = 0;
  693         if (node) {
  694                 aml_nodename(node->parent);
  695                 if (node->parent != &aml_root)
  696                         strlcat(namebuf, ".", sizeof(namebuf));
  697                 strlcat(namebuf, node->name, sizeof(namebuf));
  698                 return namebuf+1;
  699         }
  700         return namebuf;
  701 }
  702 
  703 const char *
  704 aml_getname(const char *name)
  705 {
  706         static char namebuf[128], *p;
  707         int count;
  708 
  709         p = namebuf;
  710         while (*name == AMLOP_ROOTCHAR || *name == AMLOP_PARENTPREFIX) {
  711                 *(p++) = *(name++);
  712         }
  713         switch (*name) {
  714         case 0x00:
  715                 count = 0;
  716                 break;
  717         case AMLOP_MULTINAMEPREFIX:
  718                 count = name[1];
  719                 name += 2;
  720                 break;
  721         case AMLOP_DUALNAMEPREFIX:
  722                 count = 2;
  723                 name += 1;
  724                 break;
  725         default:
  726                 count = 1;
  727         }
  728         while (count--) {
  729                 memcpy(p, name, 4);
  730                 p[4] = '.';
  731                 p += 5;
  732                 name += 4;
  733                 if (*name == '.') name++;
  734         }
  735         *(--p) = 0;
  736         return namebuf;
  737 }
  738 
  739 /* Create name/value pair in namespace */
  740 struct aml_node *
  741 aml_createname(struct aml_node *root, const void *vname, struct aml_value *value)
  742 {
  743         struct aml_node *node, **pp;
  744         uint8_t *name = (uint8_t *)vname;
  745         int count;
  746 
  747         if (*name == AMLOP_ROOTCHAR) {
  748                 root = &aml_root;
  749                 name++;
  750         }
  751         while (*name == AMLOP_PARENTPREFIX && root) {
  752                 root = root->parent;
  753                 name++;
  754         }
  755         switch (*name) {
  756         case 0x00:
  757                 return root;
  758         case AMLOP_MULTINAMEPREFIX:
  759                 count = name[1];
  760                 name += 2;
  761                 break;
  762         case AMLOP_DUALNAMEPREFIX:
  763                 count = 2;
  764                 name += 1;
  765                 break;
  766         default:
  767                 count = 1;
  768                 break;
  769         }
  770         node = NULL;
  771         while (count-- && root) {
  772                 /* Create new name if it does not exist */
  773                 if ((node = __aml_search(root, name)) == NULL) {
  774                         node = acpi_os_malloc(sizeof(struct aml_node));
  775 
  776                         memcpy((void *)node->name, name, AML_NAMESEG_LEN);
  777                         for (pp = &root->child; *pp; pp = &(*pp)->sibling)
  778                                 ;
  779                         node->parent = root;
  780                         node->sibling = NULL;
  781                         *pp = node;
  782                 }
  783                 root = node;
  784                 name += AML_NAMESEG_LEN;
  785         }
  786         /* If node created, set value pointer */
  787         if (node && value) {
  788                 node->value = value;
  789                 value->node = node;
  790         }
  791         return node;
  792 }
  793 
  794 /* Search namespace for a named node */
  795 struct aml_node *
  796 aml_searchname(struct aml_node *root, const void *vname)
  797 {
  798         struct aml_node *node;
  799         uint8_t *name = (uint8_t *)vname;
  800         int count;
  801 
  802         if (*name == AMLOP_ROOTCHAR) {
  803                 root = &aml_root;
  804                 name++;
  805         }
  806         while (*name == AMLOP_PARENTPREFIX && root) {
  807                 root = root->parent;
  808                 name++;
  809         }
  810         if (strlen(name) < AML_NAMESEG_LEN) {
  811                 aml_die("bad name");
  812         }
  813         switch (*name) {
  814         case 0x00:
  815                 return root;
  816         case AMLOP_MULTINAMEPREFIX:
  817                 count = name[1];
  818                 name += 2;
  819                 break;
  820         case AMLOP_DUALNAMEPREFIX:
  821                 count = 2;
  822                 name += 1;
  823                 break;
  824         default:
  825                 if (name[4] == '.') {
  826                         /* Called from user code */
  827                         while (*name && (root = __aml_search(root, name)) != NULL) {
  828                                 name += AML_NAMESEG_LEN+1;
  829                         }
  830                         return root;
  831                 }
  832                 /* Special case.. search relative for name */
  833                 while (root && (node = __aml_search(root, name)) == NULL) {
  834                         root = root->parent;
  835                 }
  836                 return node;
  837         }
  838         /* Search absolute for name*/
  839         while (count-- && (root = __aml_search(root, name)) != NULL) {
  840                 name += AML_NAMESEG_LEN;
  841         }
  842         return root;
  843 }
  844 
  845 /* Free all children nodes/values */
  846 void
  847 aml_delchildren(struct aml_node *node)
  848 {
  849         struct aml_node *onode;
  850 
  851         if (node == NULL)
  852                 return;
  853         while ((onode = node->child) != NULL) {
  854                 node->child = onode->sibling;
  855 
  856                 aml_delchildren(onode);
  857 
  858                 /* Decrease reference count */
  859                 aml_delref(&onode->value);
  860 
  861                 /* Delete node */
  862                 acpi_os_free(onode);
  863         }
  864 }
  865 
  866 /*
  867  * @@@: Value functions
  868  */
  869 
  870 struct aml_value        *aml_alloctmp(struct aml_scope *, int);
  871 struct aml_scope        *aml_pushscope(struct aml_scope *, uint8_t *,
  872                             uint8_t *, struct aml_node *);
  873 struct aml_scope        *aml_popscope(struct aml_scope *);
  874 int                     aml_parsenode(struct aml_scope *, struct aml_node *,
  875                             uint8_t *, uint8_t **, struct aml_value *);
  876 
  877 #define AML_LHS         0
  878 #define AML_RHS         1
  879 #define AML_DST         2
  880 #define AML_DST2        3
  881 
  882 /* Allocate temporary storage in this scope */
  883 struct aml_value *
  884 aml_alloctmp(struct aml_scope *scope, int narg)
  885 {
  886         struct aml_vallist *tmp;
  887 
  888         /* Allocate array of temp values */
  889         tmp = (struct aml_vallist *)acpi_os_malloc(sizeof(struct aml_vallist) +
  890             narg * sizeof(struct aml_value));
  891 
  892         tmp->obj = (struct aml_value *)&tmp[1];
  893         tmp->nobj = narg;
  894 
  895         /* Link into scope */
  896         tmp->next = scope->tmpvals;
  897         scope->tmpvals = tmp;
  898 
  899         /* Return array of values */
  900         return tmp->obj;
  901 }
  902 
  903 /* Allocate+push parser scope */
  904 struct aml_scope *
  905 aml_pushscope(struct aml_scope *parent, uint8_t *start, uint8_t  *end,
  906     struct aml_node *node)
  907 {
  908         struct aml_scope *scope;
  909 
  910         scope = acpi_os_malloc(sizeof(struct aml_scope));
  911         scope->pos = start;
  912         scope->end = end;
  913         scope->node = node;
  914         scope->parent = parent;
  915         scope->sc = dsdt_softc;
  916 
  917         aml_lastscope = scope;
  918 
  919         return scope;
  920 }
  921 
  922 struct aml_scope *
  923 aml_popscope(struct aml_scope *scope)
  924 {
  925         struct aml_scope *nscope;
  926         struct aml_vallist *ol;
  927         int idx;
  928 
  929         if (scope == NULL)
  930                 return NULL;
  931         nscope = scope->parent;
  932 
  933         /* Free temporary values */
  934         while ((ol = scope->tmpvals) != NULL) {
  935                 scope->tmpvals = ol->next;
  936                 for (idx = 0; idx < ol->nobj; idx++) {
  937                         aml_freevalue(&ol->obj[idx]);
  938                 }
  939                 acpi_os_free(ol);
  940         }
  941         acpi_os_free(scope);
  942 
  943         aml_lastscope = nscope;
  944 
  945         return nscope;
  946 }
  947 
  948 int
  949 aml_parsenode(struct aml_scope *parent, struct aml_node *node, uint8_t *start,
  950     uint8_t **end, struct aml_value *res)
  951 {
  952         struct aml_scope *scope;
  953 
  954         /* Don't parse zero-length scope */
  955         if (start == *end)
  956                 return 0;
  957         scope = aml_pushscope(parent, start, *end, node);
  958         if (res == NULL)
  959                 res = aml_alloctmp(scope, 1);
  960         while (scope != parent) {
  961                 while (scope->pos < scope->end)
  962                         aml_parseop(scope, res);
  963                 scope = aml_popscope(scope);
  964         }
  965         return 0;
  966 }
  967 
  968 /*
  969  * Field I/O code
  970  */
  971 void aml_setbufint(struct aml_value *, int, int, struct aml_value *);
  972 void aml_getbufint(struct aml_value *, int, int, struct aml_value *);
  973 void aml_fieldio(struct aml_scope *, struct aml_value *, struct aml_value *, int);
  974 void aml_unlockfield(struct aml_scope *, struct aml_value *);
  975 void aml_lockfield(struct aml_scope *, struct aml_value *);
  976 
  977 /* Copy from a bufferfield to an integer/buffer */
  978 void
  979 aml_setbufint(struct aml_value *dst, int bitpos, int bitlen,
  980     struct aml_value *src)
  981 {
  982         if (src->type != AML_OBJTYPE_BUFFER)
  983                 aml_die("wrong setbufint type\n");
  984 
  985 #if 1
  986         /* Return buffer type */
  987         _aml_setvalue(dst, AML_OBJTYPE_BUFFER, (bitlen+7)>>3, NULL);
  988         aml_bufcpy(dst->v_buffer, 0, src->v_buffer, bitpos, bitlen);
  989 #else
  990         if (bitlen < aml_intlen) {
  991                 /* XXX: Endian issues?? */
  992                 /* Return integer type */
  993                 _aml_setvalue(dst, AML_OBJTYPE_INTEGER, 0, NULL);
  994                 aml_bufcpy(&dst->v_integer, 0, src->v_buffer, bitpos, bitlen);
  995         } else {
  996                 /* Return buffer type */
  997                 _aml_setvalue(dst, AML_OBJTYPE_BUFFER, (bitlen+7)>>3, NULL);
  998                 aml_bufcpy(dst->v_buffer, 0, src->v_buffer, bitpos, bitlen);
  999         }
 1000 #endif
 1001 }
 1002 
 1003 /* Copy from a string/integer/buffer to a bufferfield */
 1004 void
 1005 aml_getbufint(struct aml_value *src, int bitpos, int bitlen,
 1006     struct aml_value *dst)
 1007 {
 1008         if (dst->type != AML_OBJTYPE_BUFFER)
 1009                 aml_die("wrong getbufint type\n");
 1010         switch (src->type) {
 1011         case AML_OBJTYPE_INTEGER:
 1012                 if (bitlen >= aml_intlen)
 1013                         bitlen = aml_intlen;
 1014                 aml_bufcpy(dst->v_buffer, bitpos, &src->v_integer, 0, bitlen);
 1015                 break;
 1016         case AML_OBJTYPE_BUFFER:
 1017                 if (bitlen >= 8*src->length)
 1018                         bitlen = 8*src->length;
 1019                 aml_bufcpy(dst->v_buffer, bitpos, src->v_buffer, 0, bitlen);
 1020                 break;
 1021         case AML_OBJTYPE_STRING:
 1022                 if (bitlen >= 8*src->length)
 1023                         bitlen = 8*src->length;
 1024                 aml_bufcpy(dst->v_buffer, bitpos, src->v_string, 0, bitlen);
 1025                 break;
 1026         }
 1027 }
 1028 
 1029 void
 1030 aml_lockfield(struct aml_scope *scope, struct aml_value *field)
 1031 {
 1032         if (AML_FIELD_LOCK(field->v_field.flags) == AML_FIELD_LOCK_ON) {
 1033                 /* XXX: do locking here */
 1034         }
 1035 }
 1036 
 1037 void
 1038 aml_unlockfield(struct aml_scope *scope, struct aml_value *field)
 1039 {
 1040         if (AML_FIELD_LOCK(field->v_field.flags) == AML_FIELD_LOCK_ON) {
 1041                 /* XXX: do unlocking here */
 1042         }
 1043 }
 1044 
 1045 void *aml_getbuffer(struct aml_value *, int *);
 1046 
 1047 void *
 1048 aml_getbuffer(struct aml_value *val, int *bitlen)
 1049 {
 1050         switch (val->type) {
 1051         case AML_OBJTYPE_INTEGER:
 1052         case AML_OBJTYPE_STATICINT:
 1053                 *bitlen = aml_intlen;
 1054                 return (&val->v_integer);
 1055 
 1056         case AML_OBJTYPE_BUFFER:
 1057         case AML_OBJTYPE_STRING:
 1058                 *bitlen = val->length<<3;
 1059                 return (val->v_buffer);
 1060 
 1061         default:
 1062                 aml_die("getvbi");
 1063         }
 1064 
 1065         return (NULL);
 1066 }
 1067 
 1068 /*
 1069  * Buffer/Region: read/write to bitfields
 1070  */
 1071 void
 1072 aml_fieldio(struct aml_scope *scope, struct aml_value *field,
 1073     struct aml_value *res, int mode)
 1074 {
 1075         struct aml_value *pop, tf;
 1076         int bpos, blen, aligned, mask;
 1077         void    *iobuf, *iobuf2;
 1078         uint64_t iobase;
 1079 
 1080         pop = field->v_field.ref1;
 1081         bpos = field->v_field.bitpos;
 1082         blen = field->v_field.bitlen;
 1083 
 1084         dnprintf(55,"--fieldio: %s [%s] bp:%.4x bl:%.4x\n",
 1085             mode == ACPI_IOREAD ? "rd" : "wr",
 1086             aml_nodename(field->node), bpos, blen);
 1087 
 1088         aml_lockfield(scope, field);
 1089         switch (field->v_field.type) {
 1090         case AMLOP_INDEXFIELD:
 1091                 /* Set Index */
 1092                 memcpy(&tf, field->v_field.ref2, sizeof(struct aml_value));
 1093                 tf.v_field.bitpos += (bpos & 7);
 1094                 tf.v_field.bitlen  = blen;
 1095 
 1096                 aml_setvalue(scope, pop, NULL, bpos>>3);
 1097                 aml_fieldio(scope, &tf, res, mode);
 1098 #ifdef ACPI_DEBUG
 1099                 dnprintf(55, "-- post indexfield %x,%x @ %x,%x\n", 
 1100                     bpos & 3, blen, 
 1101                     field->v_field.ref2->v_field.bitpos, 
 1102                     field->v_field.ref2->v_field.bitlen);
 1103 
 1104                 iobuf = aml_getbuffer(res, &aligned);
 1105                 aml_dump(aligned >> 3, iobuf);
 1106 #endif
 1107                 break;
 1108         case AMLOP_BANKFIELD:
 1109                 /* Set Bank */
 1110                 memcpy(&tf, field->v_field.ref2, sizeof(struct aml_value));
 1111                 tf.v_field.bitpos += (bpos & 7);
 1112                 tf.v_field.bitlen  = blen;
 1113 
 1114                 aml_setvalue(scope, pop, NULL, field->v_field.ref3);
 1115                 aml_fieldio(scope, &tf, res, mode);
 1116 #ifdef ACPI_DEBUG
 1117                 dnprintf(55, "-- post bankfield %x,%x @ %x,%x\n", 
 1118                     bpos & 3, blen, 
 1119                     field->v_field.ref2->v_field.bitpos, 
 1120                     field->v_field.ref2->v_field.bitlen);
 1121 
 1122                 iobuf = aml_getbuffer(res, &aligned);
 1123                 aml_dump(aligned >> 3, iobuf);
 1124 #endif
 1125                 break;
 1126         case AMLOP_FIELD:
 1127                 /* This is an I/O field */
 1128                 if (pop->type != AML_OBJTYPE_OPREGION)
 1129                         aml_die("Not an opregion!\n");
 1130 
 1131                 /* Get field access size */
 1132                 switch (AML_FIELD_ACCESS(field->v_field.flags)) {
 1133                 case AML_FIELD_ANYACC:
 1134                 case AML_FIELD_BYTEACC:
 1135                         mask = 7;
 1136                         break;
 1137                 case AML_FIELD_WORDACC:
 1138                         mask = 15;
 1139                         break;
 1140                 case AML_FIELD_DWORDACC:
 1141                         mask = 31;
 1142                         break;
 1143                 case AML_FIELD_QWORDACC:
 1144                         mask = 63;
 1145                         break;
 1146                 }
 1147 
 1148                 /* Pre-allocate return value for reads */
 1149                 if (mode == ACPI_IOREAD)
 1150                         _aml_setvalue(res, AML_OBJTYPE_BUFFER,
 1151                             (field->v_field.bitlen+7)>>3, NULL);
 1152                 
 1153                 /* Get aligned bitpos/bitlength */
 1154                 blen = ((bpos & mask) + blen + mask) & ~mask;
 1155                 bpos = bpos & ~mask;
 1156                 aligned = (bpos == field->v_field.bitpos &&
 1157                     blen == field->v_field.bitlen);
 1158                 iobase = pop->v_opregion.iobase;
 1159 
 1160                 /* Check for aligned reads/writes */
 1161                 if (aligned) {
 1162                         iobuf = aml_getbuffer(res, &aligned);
 1163                         aml_gasio(scope->sc, pop->v_opregion.iospace,
 1164                             iobase, pop->v_opregion.iolen, bpos, blen,
 1165                             mask + 1, iobuf, mode); 
 1166 #ifdef ACPI_DEBUG
 1167                         dnprintf(55, "aligned: %s @ %.4x:%.4x + %.4x\n",
 1168                             mode == ACPI_IOREAD ? "rd" : "wr", 
 1169                             bpos, blen, aligned);
 1170 
 1171                         aml_dump(blen >> 3, iobuf);
 1172 #endif
 1173                 }
 1174                 else if (mode == ACPI_IOREAD) {
 1175                         iobuf = acpi_os_malloc(blen>>3);
 1176                         aml_gasio(scope->sc, pop->v_opregion.iospace,
 1177                             iobase, pop->v_opregion.iolen, bpos, blen,
 1178                             mask + 1, iobuf, mode);
 1179 
 1180                         /* ASSERT: res is buffer type as it was set above */
 1181                         aml_bufcpy(res->v_buffer, 0, iobuf, 
 1182                             field->v_field.bitpos & mask,
 1183                             field->v_field.bitlen);
 1184 
 1185 #ifdef ACPI_DEBUG
 1186                         dnprintf(55,"non-aligned read: %.4x:%.4x : ", 
 1187                             field->v_field.bitpos & mask,
 1188                             field->v_field.bitlen);
 1189 
 1190                         aml_dump(blen >> 3, iobuf);
 1191                         dnprintf(55,"post-read: ");
 1192                         aml_dump((field->v_field.bitlen+7)>>3, res->v_buffer);
 1193 #endif
 1194                         acpi_os_free(iobuf);
 1195                 }
 1196                 else {
 1197                         iobuf = acpi_os_malloc(blen >> 3);
 1198                         switch (AML_FIELD_UPDATE(field->v_field.flags)) {
 1199                         case AML_FIELD_WRITEASONES:
 1200                                 memset(iobuf, 0xFF, blen >> 3);
 1201                                 break;
 1202                         case AML_FIELD_PRESERVE:
 1203                                 aml_gasio(scope->sc, pop->v_opregion.iospace,
 1204                                     iobase, pop->v_opregion.iolen, bpos, blen,
 1205                                     mask + 1, iobuf, ACPI_IOREAD);
 1206                                 break;
 1207                         }
 1208                         /* Copy into IOBUF */
 1209                         iobuf2 = aml_getbuffer(res, &aligned);
 1210                         aml_bufcpy(iobuf, field->v_field.bitpos & mask,
 1211                             iobuf2, 0, field->v_field.bitlen);
 1212 
 1213 #ifdef ACPI_DEBUG
 1214                         dnprintf(55,"non-aligned write: %.4x:%.4x : ", 
 1215                             field->v_field.bitpos & mask,
 1216                             field->v_field.bitlen);
 1217 
 1218                         aml_dump(blen >> 3, iobuf);
 1219 #endif
 1220                         aml_gasio(scope->sc, pop->v_opregion.iospace,
 1221                             iobase, pop->v_opregion.iolen, bpos, blen,
 1222                             mask + 1, iobuf, mode);
 1223 
 1224                         acpi_os_free(iobuf);
 1225                 }
 1226                 /* Verify that I/O is in range */
 1227 #if 0
 1228                 /*
 1229                  * XXX: some I/O ranges are on dword boundaries, but their
 1230                  * length is incorrect eg. dword access, but length of
 1231                  * opregion is 2 bytes.
 1232                  */
 1233                 if ((bpos+blen) >= (pop->v_opregion.iolen * 8)) {
 1234                         aml_die("Out of bounds I/O!!! region:%x:%llx:%x %x\n",
 1235                             pop->v_opregion.iospace, pop->v_opregion.iobase,
 1236                             pop->v_opregion.iolen, bpos+blen);
 1237                 }
 1238 #endif
 1239                 break;
 1240         default:
 1241                 /* This is a buffer field */
 1242                 if (mode == ACPI_IOREAD)
 1243                         aml_setbufint(res, bpos, blen, pop);
 1244                 else
 1245                         aml_getbufint(res, bpos, blen, pop);
 1246                 break;
 1247         }
 1248         aml_unlockfield(scope, field);
 1249 }
 1250 
 1251 /*
 1252  * @@@: Value set/compare/alloc/free routines
 1253  */
 1254 int64_t aml_str2int(const char *, int);
 1255 struct aml_value *aml_derefvalue(struct aml_scope *, struct aml_value *, int);
 1256 #define aml_dereftarget(s, v)   aml_derefvalue(s, v, ACPI_IOWRITE)
 1257 #define aml_derefterm(s, v, m)  aml_derefvalue(s, v, ACPI_IOREAD)
 1258 
 1259 void
 1260 aml_showvalue(struct aml_value *val, int lvl)
 1261 {
 1262         int idx;
 1263 
 1264         if (val == NULL)
 1265                 return;
 1266 
 1267         if (val->node)
 1268                 printf(" [%s]", aml_nodename(val->node));
 1269         printf(" %p cnt:%.2x stk:%.2x", val, val->refcnt, val->stack);
 1270         switch (val->type) {
 1271         case AML_OBJTYPE_STATICINT:
 1272         case AML_OBJTYPE_INTEGER:
 1273                 printf(" integer: %llx\n", val->v_integer);
 1274                 break;
 1275         case AML_OBJTYPE_STRING:
 1276                 printf(" string: %s\n", val->v_string);
 1277                 break;
 1278         case AML_OBJTYPE_METHOD:
 1279                 printf(" method: %.2x\n", val->v_method.flags);
 1280                 break;
 1281         case AML_OBJTYPE_PACKAGE:
 1282                 printf(" package: %.2x\n", val->length);
 1283                 for (idx = 0; idx < val->length; idx++)
 1284                         aml_showvalue(val->v_package[idx], lvl);
 1285                 break;
 1286         case AML_OBJTYPE_BUFFER:
 1287                 printf(" buffer: %.2x {", val->length);
 1288                 for (idx = 0; idx < val->length; idx++)
 1289                         printf("%s%.2x", idx ? ", " : "", val->v_buffer[idx]);
 1290                 printf("}\n");
 1291                 break;
 1292         case AML_OBJTYPE_FIELDUNIT:
 1293         case AML_OBJTYPE_BUFFERFIELD:
 1294                 printf(" field: bitpos=%.4x bitlen=%.4x ref1:%x ref2:%x [%s]\n",
 1295                     val->v_field.bitpos, val->v_field.bitlen,
 1296                     val->v_field.ref1, val->v_field.ref2,
 1297                     aml_mnem(val->v_field.type, NULL));
 1298                 aml_showvalue(val->v_field.ref1, lvl);
 1299                 aml_showvalue(val->v_field.ref2, lvl);
 1300                 break;
 1301         case AML_OBJTYPE_MUTEX:
 1302                 printf(" mutex: %s ref: %d\n",
 1303                     val->v_mutex ?  val->v_mutex->amt_name : "",
 1304                     val->v_mutex ?  val->v_mutex->amt_ref_count : 0);
 1305                 break;
 1306         case AML_OBJTYPE_EVENT:
 1307                 printf(" event:\n");
 1308                 break;
 1309         case AML_OBJTYPE_OPREGION:
 1310                 printf(" opregion: %.2x,%.8llx,%x\n",
 1311                     val->v_opregion.iospace, val->v_opregion.iobase,
 1312                     val->v_opregion.iolen);
 1313                 break;
 1314         case AML_OBJTYPE_NAMEREF:
 1315                 printf(" nameref: %s\n", aml_getname(val->v_nameref));
 1316                 break;
 1317         case AML_OBJTYPE_DEVICE:
 1318                 printf(" device:\n");
 1319                 break;
 1320         case AML_OBJTYPE_PROCESSOR:
 1321                 printf(" cpu: %.2x,%.4x,%.2x\n",
 1322                     val->v_processor.proc_id, val->v_processor.proc_addr,
 1323                     val->v_processor.proc_len);
 1324                 break;
 1325         case AML_OBJTYPE_THERMZONE:
 1326                 printf(" thermzone:\n");
 1327                 break;
 1328         case AML_OBJTYPE_POWERRSRC:
 1329                 printf(" pwrrsrc: %.2x,%.2x\n",
 1330                     val->v_powerrsrc.pwr_level, val->v_powerrsrc.pwr_order);
 1331                 break;
 1332         case AML_OBJTYPE_OBJREF:
 1333                 printf(" objref: %p index:%x\n", val->v_objref.ref,
 1334                     val->v_objref.index);
 1335                 aml_showvalue(val->v_objref.ref, lvl);
 1336                 break;
 1337         default:
 1338                 printf(" !!type: %x\n", val->type);
 1339         }
 1340 }
 1341 
 1342 /* Perform DeRef on value. If ACPI_IOREAD, will perform buffer/IO field read */
 1343 struct aml_value *
 1344 aml_derefvalue(struct aml_scope *scope, struct aml_value *ref, int mode)
 1345 {
 1346         struct aml_node *node;
 1347         struct aml_value *tmp;
 1348         int64_t tmpint;
 1349         int argc, index;
 1350 
 1351         for (;;) {
 1352                 switch (ref->type) {
 1353                 case AML_OBJTYPE_NAMEREF:
 1354                         node = aml_searchname(scope->node, ref->v_nameref);
 1355                         if (node == NULL || node->value == NULL)
 1356                                 return ref;
 1357                         ref = node->value;
 1358                         break;
 1359 
 1360                 case AML_OBJTYPE_OBJREF:
 1361                         index = ref->v_objref.index;
 1362                         ref = aml_dereftarget(scope, ref->v_objref.ref);
 1363                         if (index != -1) {
 1364                                 if (index >= ref->length)
 1365                                         aml_die("index.buf out of bounds: "
 1366                                             "%d/%d\n", index, ref->length);
 1367                                 switch (ref->type) {
 1368                                 case AML_OBJTYPE_PACKAGE:
 1369                                         ref = ref->v_package[index];
 1370                                         break;
 1371                                 case AML_OBJTYPE_STATICINT:
 1372                                 case AML_OBJTYPE_INTEGER:
 1373                                         /* Convert to temporary buffer */
 1374                                         if (ref->node)
 1375                                                 aml_die("named integer index\n");
 1376                                         tmpint = ref->v_integer;
 1377                                         _aml_setvalue(ref, AML_OBJTYPE_BUFFER,
 1378                                             aml_intlen>>3, &tmpint);
 1379                                         /* FALLTHROUGH */
 1380                                 case AML_OBJTYPE_BUFFER:
 1381                                 case AML_OBJTYPE_STRING:
 1382                                         /* Return contents at this index */
 1383                                         tmp = aml_alloctmp(scope, 1);
 1384                                         if (mode == ACPI_IOREAD) {
 1385                                                 /* Shortcut: return integer
 1386                                                  * contents of buffer at index */
 1387                                                 _aml_setvalue(tmp,
 1388                                                     AML_OBJTYPE_INTEGER,
 1389                                                     ref->v_buffer[index], NULL);
 1390                                         } else {
 1391                                                 _aml_setvalue(tmp,
 1392                                                     AML_OBJTYPE_BUFFERFIELD,
 1393                                                     0, NULL);
 1394                                                 tmp->v_field.type =
 1395                                                     AMLOP_CREATEBYTEFIELD;
 1396                                                 tmp->v_field.bitpos = index * 8;
 1397                                                 tmp->v_field.bitlen = 8;
 1398                                                 tmp->v_field.ref1 = ref;
 1399                                                 aml_addref(ref);
 1400                                         }
 1401                                         return tmp;
 1402                                 default:
 1403                                         aml_die("unknown index type: %d", ref->type);
 1404                                         break;
 1405                                 }
 1406                         }
 1407                         break;
 1408 
 1409                 case AML_OBJTYPE_METHOD:
 1410                         /* Read arguments from current scope */
 1411                         argc = AML_METHOD_ARGCOUNT(ref->v_method.flags);
 1412                         tmp = aml_alloctmp(scope, argc+1);
 1413                         for (index = 0; index < argc; index++) {
 1414                                 aml_parseop(scope, &tmp[index]);
 1415                                 aml_addref(&tmp[index]);
 1416                         }
 1417                         ref = aml_evalmethod(scope, ref->node, argc, tmp, &tmp[argc]);
 1418                         break;
 1419 
 1420                 case AML_OBJTYPE_BUFFERFIELD:
 1421                 case AML_OBJTYPE_FIELDUNIT:
 1422                         if (mode == ACPI_IOREAD) {
 1423                                 /* Read I/O field into temporary storage */
 1424                                 tmp = aml_alloctmp(scope, 1);
 1425                                 aml_fieldio(scope, ref, tmp, ACPI_IOREAD);
 1426                                 return tmp;
 1427                         }
 1428                         return ref;
 1429 
 1430                 default:
 1431                         return ref;
 1432                 }
 1433 
 1434         }
 1435 }
 1436 
 1437 int64_t
 1438 aml_str2int(const char *str, int radix)
 1439 {
 1440         /* XXX: fixme */
 1441         return 0;
 1442 }
 1443 
 1444 int64_t
 1445 aml_val2int(struct aml_value *rval)
 1446 {
 1447         int64_t ival = 0;
 1448 
 1449         if (rval == NULL) {
 1450                 dnprintf(50, "null val2int\n");
 1451                 return (0);
 1452         }
 1453         switch (rval->type) {
 1454         case AML_OBJTYPE_INTEGER:
 1455         case AML_OBJTYPE_STATICINT:
 1456                 ival = rval->v_integer;
 1457                 break;
 1458         case AML_OBJTYPE_BUFFER:
 1459                 aml_bufcpy(&ival, 0, rval->v_buffer, 0,
 1460                     min(aml_intlen, rval->length*8));
 1461                 break;
 1462         case AML_OBJTYPE_STRING:
 1463                 ival = (strncmp(rval->v_string, "0x", 2) == 0) ?
 1464                     aml_str2int(rval->v_string+2, 16) :
 1465                     aml_str2int(rval->v_string, 10);
 1466                 break;
 1467         }
 1468         return (ival);
 1469 }
 1470 
 1471 /* Sets value into LHS: lhs must already be cleared */
 1472 struct aml_value *
 1473 _aml_setvalue(struct aml_value *lhs, int type, int64_t ival, const void *bval)
 1474 {
 1475         memset(&lhs->_, 0x0, sizeof(lhs->_));
 1476 
 1477         lhs->type = type;
 1478         switch (lhs->type) {
 1479         case AML_OBJTYPE_INTEGER:
 1480         case AML_OBJTYPE_STATICINT:
 1481                 lhs->length = aml_intlen>>3;
 1482                 lhs->v_integer = ival;
 1483                 break;
 1484         case AML_OBJTYPE_METHOD:
 1485                 lhs->v_method.flags = ival;
 1486                 lhs->v_method.fneval = bval;
 1487                 break;
 1488         case AML_OBJTYPE_NAMEREF:
 1489                 lhs->v_nameref = (uint8_t *)bval;
 1490                 break;
 1491         case AML_OBJTYPE_OBJREF:
 1492                 lhs->v_objref.index = ival;
 1493                 lhs->v_objref.ref = (struct aml_value *)bval;
 1494                 break;
 1495         case AML_OBJTYPE_BUFFER:
 1496                 lhs->length = ival;
 1497                 lhs->v_buffer = (uint8_t *)acpi_os_malloc(ival);
 1498                 if (bval)
 1499                         memcpy(lhs->v_buffer, bval, ival);
 1500                 break;
 1501         case AML_OBJTYPE_STRING:
 1502                 if (ival == -1)
 1503                         ival = strlen((const char *)bval);
 1504                 lhs->length = ival;
 1505                 lhs->v_string = (char *)acpi_os_malloc(ival+1);
 1506                 if (bval)
 1507                         strncpy(lhs->v_string, (const char *)bval, ival);
 1508                 break;
 1509         case AML_OBJTYPE_PACKAGE:
 1510                 lhs->length = ival;
 1511                 lhs->v_package = (struct aml_value **)acpi_os_malloc(ival *
 1512                     sizeof(struct aml_value *));
 1513                 for (ival = 0; ival < lhs->length; ival++)
 1514                         lhs->v_package[ival] = aml_allocvalue(
 1515                             AML_OBJTYPE_UNINITIALIZED, 0, NULL);
 1516                 break;
 1517         }
 1518         return lhs;
 1519 }
 1520 
 1521 /* Copy object to another value: lhs must already be cleared */
 1522 void
 1523 aml_copyvalue(struct aml_value *lhs, struct aml_value *rhs)
 1524 {
 1525         int idx;
 1526 
 1527         lhs->type = rhs->type  & ~AML_STATIC;
 1528         switch (lhs->type) {
 1529         case AML_OBJTYPE_UNINITIALIZED:
 1530                 break;
 1531         case AML_OBJTYPE_STATICINT:
 1532         case AML_OBJTYPE_INTEGER:
 1533                 lhs->length = aml_intlen>>3;
 1534                 lhs->v_integer = rhs->v_integer;
 1535                 break;
 1536         case AML_OBJTYPE_MUTEX:
 1537                 lhs->v_mutex = rhs->v_mutex;
 1538                 break;
 1539         case AML_OBJTYPE_POWERRSRC:
 1540                 lhs->v_powerrsrc = rhs->v_powerrsrc;
 1541                 break;
 1542         case AML_OBJTYPE_METHOD:
 1543                 lhs->v_method = rhs->v_method;
 1544                 break;
 1545         case AML_OBJTYPE_BUFFER:
 1546                 _aml_setvalue(lhs, rhs->type, rhs->length, rhs->v_buffer);
 1547                 break;
 1548         case AML_OBJTYPE_STRING:
 1549                 _aml_setvalue(lhs, rhs->type, rhs->length, rhs->v_string);
 1550                 break;
 1551         case AML_OBJTYPE_OPREGION:
 1552                 lhs->v_opregion = rhs->v_opregion;
 1553                 break;
 1554         case AML_OBJTYPE_PROCESSOR:
 1555                 lhs->v_processor = rhs->v_processor;
 1556                 break;
 1557         case AML_OBJTYPE_NAMEREF:
 1558                 lhs->v_nameref = rhs->v_nameref;
 1559                 break;
 1560         case AML_OBJTYPE_PACKAGE:
 1561                 _aml_setvalue(lhs, rhs->type, rhs->length, NULL);
 1562                 for (idx = 0; idx < rhs->length; idx++)
 1563                         aml_copyvalue(lhs->v_package[idx], rhs->v_package[idx]);
 1564                 break;
 1565         case AML_OBJTYPE_OBJREF:
 1566                 lhs->v_objref = rhs->v_objref;
 1567                 break;
 1568         default:
 1569                 printf("copyvalue: %x", rhs->type);
 1570                 break;
 1571         }
 1572 }
 1573 
 1574 int is_local(struct aml_scope *, struct aml_value *);
 1575 
 1576 int is_local(struct aml_scope *scope, struct aml_value *val)
 1577 {
 1578         return val->stack;
 1579 }
 1580 
 1581 /* Guts of the code: Assign one value to another.  LHS may contain a previous value */
 1582 void
 1583 aml_setvalue(struct aml_scope *scope, struct aml_value *lhs,
 1584     struct aml_value *rhs, int64_t ival)
 1585 {
 1586         struct aml_value tmpint;
 1587 
 1588         /* Use integer as result */
 1589         if (rhs == NULL) {
 1590                 memset(&tmpint, 0, sizeof(tmpint));
 1591                 rhs = _aml_setvalue(&tmpint, AML_OBJTYPE_INTEGER, ival, NULL);
 1592         }
 1593 
 1594         if (is_local(scope, lhs)) {
 1595                 /* ACPI: Overwrite writing to LocalX */
 1596                 aml_freevalue(lhs);
 1597         }
 1598         else {
 1599                 lhs = aml_dereftarget(scope, lhs);
 1600         }
 1601 
 1602         switch (lhs->type) {
 1603         case AML_OBJTYPE_UNINITIALIZED:
 1604                 aml_copyvalue(lhs, rhs);
 1605                 break;
 1606         case AML_OBJTYPE_BUFFERFIELD:
 1607         case AML_OBJTYPE_FIELDUNIT:
 1608                 aml_fieldio(scope, lhs, rhs, ACPI_IOWRITE);
 1609                 break;
 1610         case AML_OBJTYPE_DEBUGOBJ:
 1611 #ifdef ACPI_DEBUG
 1612                 printf("-- debug --\n");
 1613                 aml_showvalue(rhs, 50);
 1614 #endif
 1615                 break;
 1616         case AML_OBJTYPE_STATICINT:
 1617                 if (lhs->node) {
 1618                         lhs->v_integer = aml_val2int(rhs);
 1619                 }
 1620                 break;
 1621         case AML_OBJTYPE_INTEGER:
 1622                 lhs->v_integer = aml_val2int(rhs);
 1623                 break;
 1624         case AML_OBJTYPE_BUFFER:
 1625                 if (lhs->node)
 1626                         dnprintf(40, "named.buffer\n");
 1627                 aml_freevalue(lhs);
 1628                 if (rhs->type == AML_OBJTYPE_BUFFER)
 1629                         _aml_setvalue(lhs, AML_OBJTYPE_BUFFER, rhs->length,
 1630                             rhs->v_buffer);
 1631                 else if (rhs->type == AML_OBJTYPE_INTEGER ||
 1632                             rhs->type == AML_OBJTYPE_STATICINT)
 1633                         _aml_setvalue(lhs, AML_OBJTYPE_BUFFER,
 1634                             sizeof(rhs->v_integer), &rhs->v_integer);
 1635                 else if (rhs->type == AML_OBJTYPE_STRING)
 1636                         _aml_setvalue(lhs, AML_OBJTYPE_BUFFER, rhs->length+1,
 1637                             rhs->v_string);
 1638                 else {
 1639                         /* aml_showvalue(rhs); */
 1640                         aml_die("setvalue.buf : %x", aml_pc(scope->pos));
 1641                 }
 1642                 break;
 1643         case AML_OBJTYPE_STRING:
 1644                 if (lhs->node)
 1645                         dnprintf(40, "named string\n");
 1646                 aml_freevalue(lhs);
 1647                 if (rhs->type == AML_OBJTYPE_STRING)
 1648                         _aml_setvalue(lhs, AML_OBJTYPE_STRING, rhs->length,
 1649                             rhs->v_string);
 1650                 else if (rhs->type == AML_OBJTYPE_BUFFER)
 1651                         _aml_setvalue(lhs, AML_OBJTYPE_STRING, rhs->length,
 1652                             rhs->v_buffer);
 1653                 else if (rhs->type == AML_OBJTYPE_INTEGER || rhs->type == AML_OBJTYPE_STATICINT) {
 1654                         _aml_setvalue(lhs, AML_OBJTYPE_STRING, 10, NULL);
 1655                         snprintf(lhs->v_string, lhs->length, "%lld",
 1656                             rhs->v_integer);
 1657                 } else {
 1658                         //aml_showvalue(rhs);
 1659                         aml_die("setvalue.str");
 1660                 }
 1661                 break;
 1662         default:
 1663                 /* XXX: */
 1664                 dnprintf(10, "setvalue.unknown: %x", lhs->type);
 1665                 break;
 1666         }
 1667 }
 1668 
 1669 /* Allocate dynamic AML value
 1670  *   type : Type of object to allocate (AML_OBJTYPE_XXXX)
 1671  *   ival : Integer value (action depends on type)
 1672  *   bval : Buffer value (action depends on type)
 1673  */
 1674 struct aml_value *
 1675 aml_allocvalue(int type, int64_t ival, const void *bval)
 1676 {
 1677         struct aml_value *rv;
 1678 
 1679         rv = (struct aml_value *)acpi_os_malloc(sizeof(struct aml_value));
 1680         if (rv != NULL) {
 1681                 aml_addref(rv);
 1682                 return _aml_setvalue(rv, type, ival, bval);
 1683         }
 1684         return NULL;
 1685 }
 1686 
 1687 void
 1688 aml_freevalue(struct aml_value *val)
 1689 {
 1690         int idx;
 1691 
 1692         if (val == NULL)
 1693                 return;
 1694         switch (val->type) {
 1695         case AML_OBJTYPE_STRING:
 1696                 acpi_os_free(val->v_string);
 1697                 break;
 1698         case AML_OBJTYPE_BUFFER:
 1699                 acpi_os_free(val->v_buffer);
 1700                 break;
 1701         case AML_OBJTYPE_PACKAGE:
 1702                 for (idx = 0; idx < val->length; idx++) {
 1703                         aml_freevalue(val->v_package[idx]);
 1704                         acpi_os_free(val->v_package[idx]);
 1705                 }
 1706                 acpi_os_free(val->v_package);
 1707                 break;
 1708         case AML_OBJTYPE_BUFFERFIELD:
 1709         case AML_OBJTYPE_FIELDUNIT:
 1710                 aml_delref(&val->v_field.ref1);
 1711                 aml_delref(&val->v_field.ref2);
 1712                 break;
 1713         }
 1714         val->type = 0;
 1715         memset(&val->_, 0, sizeof(val->_));
 1716 }
 1717 
 1718 /* Increase reference count */
 1719 void
 1720 aml_addref(struct aml_value *val)
 1721 {
 1722         if (val)
 1723                 val->refcnt++;
 1724 }
 1725 
 1726 /* Decrease reference count + delete value */
 1727 
 1728 void
 1729 _aml_delref(struct aml_value **val, const char *fn, int line)
 1730 {
 1731         if (val == NULL || *val == NULL)
 1732                 return;
 1733         if ((*val)->stack > 0) {
 1734                 /* Don't delete locals */
 1735                 return;
 1736         }
 1737         if ((*val)->refcnt & ~0xFF)
 1738                 printf("-- invalid ref: %x:%s:%d\n", (*val)->refcnt, fn, line);
 1739         if (--(*val)->refcnt == 0) {
 1740                 aml_freevalue(*val);
 1741                 acpi_os_free(*val);
 1742                 *val = NULL;
 1743         }
 1744 }
 1745 
 1746 /*
 1747  * @@@: Math eval routines
 1748  */
 1749 
 1750 /* Convert number from one radix to another
 1751  * Used in BCD conversion routines */
 1752 u_int64_t
 1753 aml_convradix(u_int64_t val, int iradix, int oradix)
 1754 {
 1755         u_int64_t rv = 0, pwr;
 1756 
 1757         rv = 0;
 1758         pwr = 1;
 1759         while (val) {
 1760                 rv += (val % iradix) * pwr;
 1761                 val /= iradix;
 1762                 pwr *= oradix;
 1763         }
 1764         return rv;
 1765 }
 1766 
 1767 /* Calculate LSB */
 1768 int
 1769 aml_lsb(u_int64_t val)
 1770 {
 1771         int             lsb;
 1772 
 1773         if (val == 0)
 1774                 return (0);
 1775 
 1776         for (lsb = 1; !(val & 0x1); lsb++)
 1777                 val >>= 1;
 1778 
 1779         return (lsb);
 1780 }
 1781 
 1782 /* Calculate MSB */
 1783 int
 1784 aml_msb(u_int64_t val)
 1785 {
 1786         int             msb;
 1787 
 1788         if (val == 0)
 1789                 return (0);
 1790 
 1791         for (msb = 1; val != 0x1; msb++)
 1792                 val >>= 1;
 1793 
 1794         return (msb);
 1795 }
 1796 
 1797 /* Evaluate Math operands */
 1798 int64_t
 1799 aml_evalexpr(int64_t lhs, int64_t rhs, int opcode)
 1800 {
 1801         int64_t res;
 1802 
 1803         switch (opcode) {
 1804                 /* Math operations */
 1805         case AMLOP_INCREMENT:
 1806         case AMLOP_ADD:
 1807                 res = (lhs + rhs);
 1808                 break;
 1809         case AMLOP_DECREMENT:
 1810         case AMLOP_SUBTRACT:
 1811                 res = (lhs - rhs);
 1812                 break;
 1813         case AMLOP_MULTIPLY:
 1814                 res = (lhs * rhs);
 1815                 break;
 1816         case AMLOP_DIVIDE:
 1817                 res = (lhs / rhs);
 1818                 break;
 1819         case AMLOP_MOD:
 1820                 res = (lhs % rhs);
 1821                 break;
 1822         case AMLOP_SHL:
 1823                 res = (lhs << rhs);
 1824                 break;
 1825         case AMLOP_SHR:
 1826                 res = (lhs >> rhs);
 1827                 break;
 1828         case AMLOP_AND:
 1829                 res = (lhs & rhs);
 1830                 break;
 1831         case AMLOP_NAND:
 1832                 res = ~(lhs & rhs);
 1833                 break;
 1834         case AMLOP_OR:
 1835                 res = (lhs | rhs);
 1836                 break;
 1837         case AMLOP_NOR:
 1838                 res = ~(lhs | rhs);
 1839                 break;
 1840         case AMLOP_XOR:
 1841                 res = (lhs ^ rhs);
 1842                 break;
 1843         case AMLOP_NOT:
 1844                 res = ~(lhs);
 1845                 break;
 1846 
 1847                 /* Conversion/misc */
 1848         case AMLOP_FINDSETLEFTBIT:
 1849                 res = aml_msb(lhs);
 1850                 break;
 1851         case AMLOP_FINDSETRIGHTBIT:
 1852                 res = aml_lsb(lhs);
 1853                 break;
 1854         case AMLOP_TOINTEGER:
 1855                 res = (lhs);
 1856                 break;
 1857         case AMLOP_FROMBCD:
 1858                 res = aml_convradix(lhs, 16, 10);
 1859                 break;
 1860         case AMLOP_TOBCD:
 1861                 res = aml_convradix(lhs, 10, 16);
 1862                 break;
 1863 
 1864                 /* Logical/Comparison */
 1865         case AMLOP_LAND:
 1866                 res = (lhs && rhs);
 1867                 break;
 1868         case AMLOP_LOR:
 1869                 res = (lhs || rhs);
 1870                 break;
 1871         case AMLOP_LNOT:
 1872                 res = (!lhs);
 1873                 break;
 1874         case AMLOP_LNOTEQUAL:
 1875                 res = (lhs != rhs);
 1876                 break;
 1877         case AMLOP_LLESSEQUAL:
 1878                 res = (lhs <= rhs);
 1879                 break;
 1880         case AMLOP_LGREATEREQUAL:
 1881                 res = (lhs >= rhs);
 1882                 break;
 1883         case AMLOP_LEQUAL:
 1884                 res = (lhs == rhs);
 1885                 break;
 1886         case AMLOP_LGREATER:
 1887                 res = (lhs > rhs);
 1888                 break;
 1889         case AMLOP_LLESS:
 1890                 res = (lhs < rhs);
 1891                 break;
 1892         }
 1893 
 1894         dnprintf(50,"aml_evalexpr: %s %llx %llx = %llx\n",
 1895                  aml_mnem(opcode, NULL), lhs, rhs, res);
 1896 
 1897         return res;
 1898 }
 1899 
 1900 int
 1901 aml_cmpvalue(struct aml_value *lhs, struct aml_value *rhs, int opcode)
 1902 {
 1903         int rc, lt, rt;
 1904 
 1905         rc = 0;
 1906         lt = lhs->type & ~AML_STATIC;
 1907         rt = rhs->type & ~AML_STATIC;
 1908         if (lt == rt) {
 1909                 switch (lt) {
 1910                 case AML_OBJTYPE_STATICINT:
 1911                 case AML_OBJTYPE_INTEGER:
 1912                         rc = (lhs->v_integer - rhs->v_integer);
 1913                         break;
 1914                 case AML_OBJTYPE_STRING:
 1915                         rc = strncmp(lhs->v_string, rhs->v_string,
 1916                             min(lhs->length, rhs->length));
 1917                         if (rc == 0)
 1918                                 rc = lhs->length - rhs->length;
 1919                         break;
 1920                 case AML_OBJTYPE_BUFFER:
 1921                         rc = memcmp(lhs->v_buffer, rhs->v_buffer,
 1922                             min(lhs->length, rhs->length));
 1923                         if (rc == 0)
 1924                                 rc = lhs->length - rhs->length;
 1925                         break;
 1926                 }
 1927         } else if (lt == AML_OBJTYPE_INTEGER) {
 1928                 rc = lhs->v_integer - aml_val2int(rhs);
 1929         } else if (rt == AML_OBJTYPE_INTEGER) {
 1930                 rc = aml_val2int(lhs) - rhs->v_integer;
 1931         } else {
 1932                 aml_die("mismatched compare\n");
 1933         }
 1934         return aml_evalexpr(rc, 0, opcode);
 1935 }
 1936 
 1937 /*
 1938  * aml_bufcpy copies/shifts buffer data, special case for aligned transfers
 1939  * dstPos/srcPos are bit positions within destination/source buffers
 1940  */
 1941 void
 1942 aml_bufcpy(void *pvDst, int dstPos, const void *pvSrc, int srcPos, int len)
 1943 {
 1944         const u_int8_t *pSrc = pvSrc;
 1945         u_int8_t *pDst = pvDst;
 1946         int             idx;
 1947 
 1948         if (aml_bytealigned(dstPos|srcPos|len)) {
 1949                 /* Aligned transfer: use memcpy */
 1950                 memcpy(pDst+aml_bytepos(dstPos), pSrc+aml_bytepos(srcPos),
 1951                     aml_bytelen(len));
 1952                 return;
 1953         }
 1954 
 1955         /* Misaligned transfer: perform bitwise copy (slow) */
 1956         for (idx = 0; idx < len; idx++)
 1957                 aml_setbit(pDst, idx + dstPos, aml_tstbit(pSrc, idx + srcPos));
 1958 }
 1959 
 1960 struct aml_value *
 1961 aml_callmethod(struct aml_scope *scope, struct aml_value *val)
 1962 {
 1963         while (scope->pos < scope->end)
 1964                 aml_parseterm(scope, val);
 1965         return val;
 1966 }
 1967 
 1968 /*
 1969  * Evaluate an AML method
 1970  *
 1971  * Returns a copy of the result in res (must be freed by user)
 1972  */
 1973 struct aml_value *
 1974 aml_evalmethod(struct aml_scope *parent, struct aml_node *node,
 1975     int argc, struct aml_value *argv, struct aml_value *res)
 1976 {
 1977         struct aml_scope *scope;
 1978 
 1979         scope = aml_pushscope(parent, node->value->v_method.start,
 1980             node->value->v_method.end, node);
 1981         scope->args = argv;
 1982         scope->nargs = argc;
 1983 
 1984         if (res == NULL)
 1985                 res = aml_alloctmp(scope, 1);
 1986 
 1987 #ifdef ACPI_DEBUG
 1988         dnprintf(10, "calling [%s] (%d args)\n",
 1989             aml_nodename(node), scope->nargs);
 1990         for (argc = 0; argc < scope->nargs; argc++) {
 1991                 dnprintf(10, "  arg%d: ", argc);
 1992                 aml_showvalue(&scope->args[argc], 10);
 1993         }
 1994         node->value->v_method.fneval(scope, res);
 1995         dnprintf(10, "[%s] returns: ", aml_nodename(node));
 1996         aml_showvalue(res, 10);
 1997 #else
 1998         node->value->v_method.fneval(scope, res);
 1999 #endif
 2000         /* Free any temporary children nodes */
 2001         aml_delchildren(node);
 2002         aml_popscope(scope);
 2003 
 2004         return res;
 2005 }
 2006 
 2007 /*
 2008  * @@@: External API
 2009  *
 2010  * evaluate an AML node
 2011  * Returns a copy of the value in res  (must be freed by user)
 2012  */
 2013 int
 2014 aml_evalnode(struct acpi_softc *sc, struct aml_node *node,
 2015     int argc, struct aml_value *argv, struct aml_value *res)
 2016 {
 2017         static int lastck;
 2018         struct aml_node *ref;
 2019 
 2020         if (res)
 2021                 memset(res, 0, sizeof(struct aml_value));
 2022         if (node == NULL || node->value == NULL)
 2023                 return (ACPI_E_BADVALUE);
 2024 
 2025         switch (node->value->type) {
 2026         case AML_OBJTYPE_METHOD:
 2027                 aml_evalmethod(NULL, node, argc, argv, res);
 2028                 if (acpi_nalloc > lastck) {
 2029                         /* Check if our memory usage has increased */
 2030                         dnprintf(10, "Leaked: [%s] %d\n",
 2031                             aml_nodename(node), acpi_nalloc);
 2032                         lastck = acpi_nalloc;
 2033                 }
 2034                 break;
 2035         case AML_OBJTYPE_STATICINT:
 2036         case AML_OBJTYPE_INTEGER:
 2037         case AML_OBJTYPE_STRING:
 2038         case AML_OBJTYPE_BUFFER:
 2039         case AML_OBJTYPE_PACKAGE:
 2040         case AML_OBJTYPE_EVENT:
 2041         case AML_OBJTYPE_DEVICE:
 2042         case AML_OBJTYPE_MUTEX:
 2043         case AML_OBJTYPE_OPREGION:
 2044         case AML_OBJTYPE_POWERRSRC:
 2045         case AML_OBJTYPE_PROCESSOR:
 2046         case AML_OBJTYPE_THERMZONE:
 2047         case AML_OBJTYPE_DEBUGOBJ:
 2048                 if (res)
 2049                         aml_copyvalue(res, node->value);
 2050                 break;
 2051         case AML_OBJTYPE_NAMEREF:
 2052                 if (res == NULL)
 2053                         break;
 2054                 if ((ref = aml_searchname(node, node->value->v_nameref)) != NULL)
 2055                         _aml_setvalue(res, AML_OBJTYPE_OBJREF, -1, ref);
 2056                 else
 2057                         aml_copyvalue(res, node->value);
 2058                 break;
 2059         default:
 2060                 break;
 2061         }
 2062         return (0);
 2063 }
 2064 
 2065 /*
 2066  * evaluate an AML name
 2067  * Returns a copy of the value in res  (must be freed by user)
 2068  */
 2069 int
 2070 aml_evalname(struct acpi_softc *sc, struct aml_node *parent, const char *name,
 2071     int argc, struct aml_value *argv, struct aml_value *res)
 2072 {
 2073         return aml_evalnode(sc, aml_searchname(parent, name), argc, argv, res);
 2074 }
 2075 
 2076 int
 2077 aml_evalinteger(struct acpi_softc *sc, struct aml_node *parent,
 2078     const char *name, int argc, struct aml_value *argv, int64_t *ival)
 2079 {
 2080         struct aml_value res;
 2081 
 2082         if (name != NULL)
 2083                 parent = aml_searchname(parent, name);
 2084         if (aml_evalnode(sc, parent, argc, argv, &res) == 0) {
 2085                 *ival = aml_val2int(&res);
 2086                 aml_freevalue(&res);
 2087                 return 0;
 2088         }
 2089         return 1;
 2090 }
 2091 
 2092 void
 2093 aml_walknodes(struct aml_node *node, int mode,
 2094     int (*nodecb)(struct aml_node *, void *), void *arg)
 2095 {
 2096         struct aml_node *child;
 2097 
 2098         if (node == NULL)
 2099                 return;
 2100         if (mode == AML_WALK_PRE)
 2101                 nodecb(node, arg);
 2102         for (child = node->child; child; child = child->sibling)
 2103                 aml_walknodes(child, mode, nodecb, arg);
 2104         if (mode == AML_WALK_POST)
 2105                 nodecb(node, arg);
 2106 }
 2107 
 2108 void
 2109 aml_walktree(struct aml_node *node)
 2110 {
 2111         while (node) {
 2112                 aml_showvalue(node->value, 0);
 2113                 aml_walktree(node->child);
 2114                 node = node->sibling;
 2115         }
 2116 }
 2117 
 2118 void
 2119 aml_walkroot(void)
 2120 {
 2121         aml_walktree(aml_root.child);
 2122 }
 2123 
 2124 int
 2125 aml_find_node(struct aml_node *node, const char *name,
 2126     void (*cbproc)(struct aml_node *, void *arg), void *arg)
 2127 {
 2128         const char *nn;
 2129 
 2130         while (node) {
 2131                 if ((nn = node->name) != NULL) {
 2132                         if (*nn == AMLOP_ROOTCHAR) nn++;
 2133                         while (*nn == AMLOP_PARENTPREFIX) nn++;
 2134                         if (!strcmp(name, nn))
 2135                                 cbproc(node, arg);
 2136                 }
 2137                 aml_find_node(node->child, name, cbproc, arg);
 2138                 node = node->sibling;
 2139         }
 2140         return (0);
 2141 }
 2142 
 2143 /*
 2144  * @@@: Parser functions
 2145  */
 2146 uint8_t *aml_parsename(struct aml_scope *);
 2147 uint8_t *aml_parseend(struct aml_scope *scope);
 2148 int     aml_parselength(struct aml_scope *);
 2149 int     aml_parseopcode(struct aml_scope *);
 2150 
 2151 /* Get AML Opcode */
 2152 int
 2153 aml_parseopcode(struct aml_scope *scope)
 2154 {
 2155         int opcode = (scope->pos[0]);
 2156         int twocode = (scope->pos[0]<<8) + scope->pos[1];
 2157 
 2158         /* Check if this is an embedded name */
 2159         switch (opcode) {
 2160         case AMLOP_ROOTCHAR:
 2161         case AMLOP_PARENTPREFIX:
 2162         case AMLOP_MULTINAMEPREFIX:
 2163         case AMLOP_DUALNAMEPREFIX:
 2164         case AMLOP_NAMECHAR:
 2165         case 'A' ... 'Z':
 2166                 return AMLOP_NAMECHAR;
 2167         }
 2168         if (twocode == AMLOP_LNOTEQUAL || twocode == AMLOP_LLESSEQUAL ||
 2169             twocode == AMLOP_LGREATEREQUAL || opcode == AMLOP_EXTPREFIX) {
 2170                 scope->pos += 2;
 2171                 return twocode;
 2172         }
 2173         scope->pos += 1;
 2174         return opcode;
 2175 }
 2176 
 2177 /* Decode embedded AML Namestring */
 2178 uint8_t *
 2179 aml_parsename(struct aml_scope *scope)
 2180 {
 2181         uint8_t *name = scope->pos;
 2182 
 2183         while (*scope->pos == AMLOP_ROOTCHAR || *scope->pos == AMLOP_PARENTPREFIX)
 2184                 scope->pos++;
 2185 
 2186         switch (*scope->pos) {
 2187         case 0x00:
 2188                 break;
 2189         case AMLOP_MULTINAMEPREFIX:
 2190                 scope->pos += 2+AML_NAMESEG_LEN*scope->pos[1];
 2191                 break;
 2192         case AMLOP_DUALNAMEPREFIX:
 2193                 scope->pos += 1+AML_NAMESEG_LEN*2;
 2194                 break;
 2195         default:
 2196                 scope->pos += AML_NAMESEG_LEN;
 2197                 break;
 2198         }
 2199         return name;
 2200 }
 2201 
 2202 /* Decode AML Length field */
 2203 int
 2204 aml_parselength(struct aml_scope *scope)
 2205 {
 2206         int len = (*scope->pos & 0xF);
 2207 
 2208         switch (*scope->pos >> 6) {
 2209         case 0x00:
 2210                 len = scope->pos[0] & 0x3F;
 2211                 scope->pos += 1;
 2212                 break;
 2213         case 0x01:
 2214                 len += (scope->pos[1]<<4L);
 2215                 scope->pos += 2;
 2216                 break;
 2217         case 0x02:
 2218                 len += (scope->pos[1]<<4L) + (scope->pos[2]<<12L);
 2219                 scope->pos += 3;
 2220                 break;
 2221         case 0x03:
 2222                 len += (scope->pos[1]<<4L) + (scope->pos[2]<<12L) +
 2223                     (scope->pos[3]<<20L);
 2224                 scope->pos += 4;
 2225                 break;
 2226         }
 2227         return len;
 2228 }
 2229 
 2230 /* Get address of end of scope; based on current address */
 2231 uint8_t *
 2232 aml_parseend(struct aml_scope *scope)
 2233 {
 2234         uint8_t *pos = scope->pos;
 2235         int len;
 2236 
 2237         len = aml_parselength(scope);
 2238         if (pos+len > scope->end) {
 2239                 dnprintf(10,
 2240                     "Bad scope... runover pos:%.4x new end:%.4x scope "
 2241                     "end:%.4x\n", aml_pc(pos), aml_pc(pos+len),
 2242                     aml_pc(scope->end));
 2243                 pos = scope->end;
 2244         }
 2245         return pos+len;
 2246 }
 2247 
 2248 /*
 2249  * @@@: Opcode utility functions
 2250  */
 2251 int             aml_match(int, int64_t, struct aml_value *);
 2252 void            aml_fixref(struct aml_value **);
 2253 int64_t         aml_parseint(struct aml_scope *, int);
 2254 void            aml_resize(struct aml_value *val, int newsize);
 2255 
 2256 void
 2257 aml_resize(struct aml_value *val, int newsize)
 2258 {
 2259         void *oldptr;
 2260         int oldsize;
 2261 
 2262         if (val->length >= newsize)
 2263                 return;
 2264         oldsize = val->length;
 2265         switch (val->type) {
 2266         case AML_OBJTYPE_BUFFER:
 2267                 oldptr = val->v_buffer;
 2268                 _aml_setvalue(val, val->type, newsize, NULL);
 2269                 memcpy(val->v_buffer, oldptr, oldsize);
 2270                 acpi_os_free(oldptr);
 2271                 break;
 2272         case AML_OBJTYPE_STRING:
 2273                 oldptr = val->v_string;
 2274                 _aml_setvalue(val, val->type, newsize+1, NULL);
 2275                 memcpy(val->v_string, oldptr, oldsize);
 2276                 acpi_os_free(oldptr);
 2277                 break;
 2278         }
 2279 }
 2280 
 2281 
 2282 int
 2283 aml_match(int op, int64_t mv1, struct aml_value *mv2)
 2284 {
 2285         struct aml_value tmpint;
 2286 
 2287         memset(&tmpint, 0, sizeof(tmpint));
 2288         _aml_setvalue(&tmpint, AML_OBJTYPE_INTEGER, mv1, NULL);
 2289         switch (op) {
 2290         case AML_MATCH_EQ:
 2291                 return aml_cmpvalue(&tmpint, mv2, AMLOP_LEQUAL);
 2292         case AML_MATCH_LT:
 2293                 return aml_cmpvalue(&tmpint, mv2, AMLOP_LLESS);
 2294         case AML_MATCH_LE:
 2295                 return aml_cmpvalue(&tmpint, mv2, AMLOP_LLESSEQUAL);
 2296         case AML_MATCH_GE:
 2297                 return aml_cmpvalue(&tmpint, mv2, AMLOP_LGREATEREQUAL);
 2298         case AML_MATCH_GT:
 2299                 return aml_cmpvalue(&tmpint, mv2, AMLOP_LGREATER);
 2300         }
 2301         return (1);
 2302 }
 2303 
 2304 int amlop_delay;
 2305 
 2306 u_int64_t
 2307 aml_getpciaddr(struct acpi_softc *sc, struct aml_node *root)
 2308 {
 2309         struct aml_value tmpres;
 2310         u_int64_t pciaddr;
 2311 
 2312         /* PCI */
 2313         pciaddr = 0;
 2314         if (!aml_evalname(dsdt_softc, root, "_ADR", 0, NULL, &tmpres)) {
 2315                 /* Device:Function are bits 16-31,32-47 */
 2316                 pciaddr += (aml_val2int(&tmpres) << 16L);
 2317                 aml_freevalue(&tmpres);
 2318                 dnprintf(20, "got _adr [%s]\n", aml_nodename(root));
 2319         } else {
 2320                 /* Mark invalid */
 2321                 pciaddr += (0xFFFF << 16L);
 2322                 return pciaddr;
 2323         }
 2324 
 2325         if (!aml_evalname(dsdt_softc, root, "_BBN", 0, NULL, &tmpres)) {
 2326                 /* PCI bus is in bits 48-63 */
 2327                 pciaddr += (aml_val2int(&tmpres) << 48L);
 2328                 aml_freevalue(&tmpres);
 2329                 dnprintf(20, "got _bbn [%s]\n", aml_nodename(root));
 2330         }
 2331         dnprintf(20, "got pciaddr: %s:%llx\n", aml_nodename(root), pciaddr);
 2332         return pciaddr;
 2333 }
 2334 
 2335 /* Fixup references for BufferFields/FieldUnits */
 2336 void
 2337 aml_fixref(struct aml_value **res)
 2338 {
 2339         struct aml_value *oldres;
 2340 
 2341         while (*res && (*res)->type == AML_OBJTYPE_OBJREF &&
 2342             (*res)->v_objref.index == -1) {
 2343                 oldres = (*res)->v_objref.ref;
 2344                 aml_delref(res);
 2345                 aml_addref(oldres);
 2346                 *res = oldres;
 2347         }
 2348 }
 2349 
 2350 int64_t
 2351 aml_parseint(struct aml_scope *scope, int opcode)
 2352 {
 2353         uint8_t *np = scope->pos;
 2354         struct aml_value *tmpval;
 2355         int64_t rval;
 2356 
 2357         if (opcode == AML_ANYINT)
 2358                 opcode = aml_parseopcode(scope);
 2359         switch (opcode) {
 2360         case AMLOP_ZERO:
 2361                 rval = 0;
 2362                 break;
 2363         case AMLOP_ONE:
 2364                 rval = 1;
 2365                 break;
 2366         case AMLOP_ONES:
 2367                 rval = -1;
 2368                 break;
 2369         case AMLOP_REVISION:
 2370                 rval = AML_REVISION;
 2371                 break;
 2372         case AMLOP_BYTEPREFIX:
 2373                 np = scope->pos;
 2374                 rval = *(uint8_t *)scope->pos;
 2375                 scope->pos += 1;
 2376                 break;
 2377         case AMLOP_WORDPREFIX:
 2378                 np = scope->pos;
 2379                 rval = aml_letohost16(*(uint16_t *)scope->pos);
 2380                 scope->pos += 2;
 2381                 break;
 2382         case AMLOP_DWORDPREFIX:
 2383                 np = scope->pos;
 2384                 rval = aml_letohost32(*(uint32_t *)scope->pos);
 2385                 scope->pos += 4;
 2386                 break;
 2387         case AMLOP_QWORDPREFIX:
 2388                 np = scope->pos;
 2389                 rval = aml_letohost64(*(uint64_t *)scope->pos);
 2390                 scope->pos += 8;
 2391                 break;
 2392         default:
 2393                 scope->pos = np;
 2394                 tmpval = aml_alloctmp(scope, 1);
 2395                 aml_parseterm(scope, tmpval);
 2396                 return aml_val2int(tmpval);
 2397         }
 2398         dnprintf(15, "%.4x: [%s] %s\n", aml_pc(scope->pos-opsize(opcode)),
 2399             aml_nodename(scope->node), aml_mnem(opcode, np));
 2400         return rval;
 2401 }
 2402 
 2403 struct aml_value *
 2404 aml_evaltarget(struct aml_scope *scope, struct aml_value *res)
 2405 {
 2406         return res;
 2407 }
 2408 
 2409 int
 2410 aml_evalterm(struct aml_scope *scope, struct aml_value *raw,
 2411     struct aml_value *dst)
 2412 {
 2413         struct aml_value *deref;
 2414 
 2415         aml_freevalue(dst);
 2416         deref = aml_derefterm(scope, raw, 0);
 2417         aml_copyvalue(dst, deref);
 2418         return 0;
 2419 }
 2420 
 2421 
 2422 /*
 2423  * @@@: Opcode functions
 2424  */
 2425 
 2426 /* Parse named objects */
 2427 struct aml_value *
 2428 aml_parsenamed(struct aml_scope *scope, int opcode, struct aml_value *res)
 2429 {
 2430         uint8_t *name;
 2431         int s, offs = 0;
 2432 
 2433         AML_CHECKSTACK();
 2434         name = aml_parsename(scope);
 2435 
 2436         res = aml_allocvalue(AML_OBJTYPE_UNINITIALIZED, 0, NULL);
 2437         switch (opcode) {
 2438         case AMLOP_NAME:
 2439                 aml_parseop(scope, res);
 2440                 break;
 2441         case AMLOP_ALIAS:
 2442                 _aml_setvalue(res, AML_OBJTYPE_NAMEREF, 0, name);
 2443                 name = aml_parsename(scope);
 2444                 break;
 2445         case AMLOP_EVENT:
 2446                 _aml_setvalue(res, AML_OBJTYPE_EVENT, 0, NULL);
 2447                 break;
 2448         case AMLOP_MUTEX:
 2449                 /* XXX mutex is unused since we don't have concurrency */
 2450                 _aml_setvalue(res, AML_OBJTYPE_MUTEX, 0, NULL);
 2451                 res->v_mutex = (struct acpi_mutex *)acpi_os_malloc(
 2452                     sizeof(struct acpi_mutex));
 2453                 res->v_mutex->amt_synclevel = aml_parseint(scope,
 2454                     AMLOP_BYTEPREFIX);
 2455                 s = strlen(aml_getname(name));
 2456                 if (s > 4)
 2457                         offs = s - 4;
 2458                 strlcpy(res->v_mutex->amt_name, aml_getname(name) + offs,
 2459                     ACPI_MTX_MAXNAME);
 2460                 rw_init(&res->v_mutex->amt_lock, res->v_mutex->amt_name);
 2461                 break;
 2462         case AMLOP_OPREGION:
 2463                 _aml_setvalue(res, AML_OBJTYPE_OPREGION, 0, NULL);
 2464                 res->v_opregion.iospace = aml_parseint(scope, AMLOP_BYTEPREFIX);
 2465                 res->v_opregion.iobase = aml_parseint(scope, AML_ANYINT);
 2466                 res->v_opregion.iolen = aml_parseint(scope, AML_ANYINT);
 2467                 if (res->v_opregion.iospace == GAS_PCI_CFG_SPACE) {
 2468                         res->v_opregion.iobase += aml_getpciaddr(dsdt_softc,
 2469                             scope->node);
 2470                         dnprintf(20, "got ioaddr: %s.%s:%llx\n",
 2471                             aml_nodename(scope->node), aml_getname(name),
 2472                             res->v_opregion.iobase);
 2473                 }
 2474                 break;
 2475         }
 2476         aml_createname(scope->node, name, res);
 2477 
 2478         return res;
 2479 }
 2480 
 2481 /* Parse Named objects with scope */
 2482 struct aml_value *
 2483 aml_parsenamedscope(struct aml_scope *scope, int opcode, struct aml_value *res)
 2484 {
 2485         uint8_t *end, *name;
 2486         struct aml_node *node;
 2487 
 2488         AML_CHECKSTACK();
 2489         end = aml_parseend(scope);
 2490         name = aml_parsename(scope);
 2491 
 2492         switch (opcode) {
 2493         case AMLOP_DEVICE:
 2494                 res = aml_allocvalue(AML_OBJTYPE_DEVICE, 0, NULL);
 2495                 break;
 2496         case AMLOP_SCOPE:
 2497                 res = NULL;
 2498                 break;
 2499         case AMLOP_PROCESSOR:
 2500                 res = aml_allocvalue(AML_OBJTYPE_PROCESSOR, 0, NULL);
 2501                 res->v_processor.proc_id = aml_parseint(scope, AMLOP_BYTEPREFIX);
 2502                 res->v_processor.proc_addr = aml_parseint(scope, AMLOP_DWORDPREFIX);
 2503                 res->v_processor.proc_len = aml_parseint(scope, AMLOP_BYTEPREFIX);
 2504                 break;
 2505         case AMLOP_POWERRSRC:
 2506                 res = aml_allocvalue(AML_OBJTYPE_POWERRSRC, 0, NULL);
 2507                 res->v_powerrsrc.pwr_level = aml_parseint(scope, AMLOP_BYTEPREFIX);
 2508                 res->v_powerrsrc.pwr_order = aml_parseint(scope, AMLOP_BYTEPREFIX);
 2509                 break;
 2510         case AMLOP_THERMALZONE:
 2511                 res = aml_allocvalue(AML_OBJTYPE_THERMZONE, 0, NULL);
 2512                 break;
 2513         }
 2514         node = aml_createname(scope->node, name, res);
 2515         aml_parsenode(scope, node, scope->pos, &end, NULL);
 2516         scope->pos = end;
 2517 
 2518         return res;
 2519 }
 2520 
 2521 /* Parse math opcodes */
 2522 struct aml_value *
 2523 aml_parsemath(struct aml_scope *scope, int opcode, struct aml_value *res)
 2524 {
 2525         struct aml_value *tmparg;
 2526         int64_t i1, i2, i3;
 2527 
 2528         tmparg = aml_alloctmp(scope, 1);
 2529         AML_CHECKSTACK();
 2530         switch (opcode) {
 2531         case AMLOP_LNOT:
 2532                 i2 = 0;
 2533                 i1 = aml_parseint(scope, AML_ANYINT);
 2534                 break;
 2535         case AMLOP_LAND:
 2536         case AMLOP_LOR:
 2537                 i1 = aml_parseint(scope, AML_ANYINT);
 2538                 i2 = aml_parseint(scope, AML_ANYINT);
 2539                 break;
 2540         case AMLOP_NOT:
 2541         case AMLOP_TOBCD:
 2542         case AMLOP_FROMBCD:
 2543         case AMLOP_TOINTEGER:
 2544         case AMLOP_FINDSETLEFTBIT:
 2545         case AMLOP_FINDSETRIGHTBIT:
 2546                 i2 = 0;
 2547                 i1 = aml_parseint(scope, AML_ANYINT);
 2548                 aml_parsetarget(scope, tmparg, NULL);
 2549                 break;
 2550         case AMLOP_INCREMENT:
 2551         case AMLOP_DECREMENT:
 2552                 aml_parsetarget(scope, tmparg, NULL);
 2553                 i1 = aml_val2int(aml_derefterm(scope, tmparg, 0));
 2554                 i2 = 1;
 2555                 break;
 2556         case AMLOP_DIVIDE:
 2557                 i1 = aml_parseint(scope, AML_ANYINT);
 2558                 i2 = aml_parseint(scope, AML_ANYINT);
 2559 
 2560                 aml_parsetarget(scope, tmparg, NULL);   // remainder
 2561                 aml_setvalue(scope, tmparg, NULL, (i1 % i2));
 2562 
 2563                 aml_parsetarget(scope, tmparg, NULL);   // quotient
 2564                 break;
 2565         default:
 2566                 i1 = aml_parseint(scope, AML_ANYINT);
 2567                 i2 = aml_parseint(scope, AML_ANYINT);
 2568                 aml_parsetarget(scope, tmparg, NULL);
 2569                 break;
 2570         }
 2571         i3 = aml_evalexpr(i1, i2, opcode);
 2572         aml_setvalue(scope, res, NULL, i3);
 2573         aml_setvalue(scope, tmparg, NULL, i3);
 2574         return (res);
 2575 }
 2576 
 2577 /* Parse logical comparison opcodes */
 2578 struct aml_value *
 2579 aml_parsecompare(struct aml_scope *scope, int opcode, struct aml_value *res)
 2580 {
 2581         struct aml_value *tmparg;
 2582         int rc;
 2583 
 2584         AML_CHECKSTACK();
 2585         tmparg = aml_alloctmp(scope, 2);
 2586         aml_parseterm(scope, &tmparg[AML_LHS]);
 2587         aml_parseterm(scope, &tmparg[AML_RHS]);
 2588 
 2589         /* Compare both values */
 2590         rc = aml_cmpvalue(&tmparg[AML_LHS], &tmparg[AML_RHS], opcode);
 2591         aml_setvalue(scope, res, NULL, rc);
 2592 
 2593         return res;
 2594 }
 2595 
 2596 /* Parse IF/ELSE opcodes */
 2597 struct aml_value *
 2598 aml_parseif(struct aml_scope *scope, int opcode, struct aml_value *res)
 2599 {
 2600         int64_t test;
 2601         uint8_t *end;
 2602 
 2603         AML_CHECKSTACK();
 2604         end = aml_parseend(scope);
 2605         test = aml_parseint(scope, AML_ANYINT);
 2606 
 2607         dnprintf(40, "@ iftest: %llx\n", test);
 2608         while (test && scope->pos < end) {
 2609                 /* Parse if scope */
 2610                 aml_parseterm(scope, res);
 2611         }
 2612         if (scope->pos >= scope->end)
 2613                 return res;
 2614 
 2615         if (*end == AMLOP_ELSE) {
 2616                 scope->pos = ++end;
 2617                 end = aml_parseend(scope);
 2618                 while (!test && scope->pos < end) {
 2619                         /* Parse ELSE scope */
 2620                         aml_parseterm(scope, res);
 2621                 }
 2622         }
 2623         if (scope->pos < end)
 2624                 scope->pos = end;
 2625         return res;
 2626 }
 2627 
 2628 struct aml_value *
 2629 aml_parsewhile(struct aml_scope *scope, int opcode, struct aml_value *res)
 2630 {
 2631         uint8_t *end, *start;
 2632         int test, cnt;
 2633 
 2634         AML_CHECKSTACK();
 2635         end = aml_parseend(scope);
 2636         start = scope->pos;
 2637         cnt = 0;
 2638         do {
 2639                 test = 1;
 2640                 if (scope->pos == start || scope->pos == end) {
 2641                         scope->pos = start;
 2642                         test = aml_parseint(scope, AML_ANYINT);
 2643                         dnprintf(40, "@whiletest = %d %x\n", test, cnt++);
 2644                 } else if (*scope->pos == AMLOP_BREAK) {
 2645                         scope->pos++;
 2646                         test = 0;
 2647                 } else if (*scope->pos == AMLOP_CONTINUE) {
 2648                         scope->pos = start;
 2649                 } else {
 2650                         aml_parseterm(scope, res);
 2651                 }
 2652         } while (test && scope->pos <= end && cnt < 0x199);
 2653         /* XXX: shouldn't need breakout counter */
 2654 
 2655         dnprintf(40, "Set While end : %x\n", cnt);
 2656         if (scope->pos < end)
 2657                 scope->pos = end;
 2658         return res;
 2659 }
 2660 
 2661 /* Parse Buffer/Package opcodes */
 2662 struct aml_value *
 2663 aml_parsebufpkg(struct aml_scope *scope, int opcode, struct aml_value *res)
 2664 {
 2665         uint8_t *end;
 2666         int len;
 2667 
 2668         AML_CHECKSTACK();
 2669         end = aml_parseend(scope);
 2670         len = aml_parseint(scope, (opcode == AMLOP_PACKAGE) ?
 2671             AMLOP_BYTEPREFIX : AML_ANYINT);
 2672 
 2673         switch (opcode) {
 2674         case AMLOP_BUFFER:
 2675                 _aml_setvalue(res, AML_OBJTYPE_BUFFER, len, NULL);
 2676                 if (scope->pos < end) {
 2677                         memcpy(res->v_buffer, scope->pos, end-scope->pos);
 2678                 }
 2679                 if (len != end-scope->pos) {
 2680                         dnprintf(99, "buffer: %.4x %.4x\n", len, end-scope->pos);
 2681                 }
 2682                 break;
 2683         case AMLOP_PACKAGE:
 2684         case AMLOP_VARPACKAGE:
 2685                 _aml_setvalue(res, AML_OBJTYPE_PACKAGE, len, NULL);
 2686                 for (len = 0; len < res->length && scope->pos < end; len++) {
 2687                         aml_parseop(scope, res->v_package[len]);
 2688                 }
 2689                 if (scope->pos != end) {
 2690                         dnprintf(99, "Package not equiv!! %.4x %.4x %d of %d\n",
 2691                             aml_pc(scope->pos), aml_pc(end), len, res->length);
 2692                 }
 2693                 break;
 2694         }
 2695         scope->pos = end;
 2696         return res;
 2697 }
 2698 
 2699 struct aml_value *
 2700 aml_parsemethod(struct aml_scope *scope, int opcode, struct aml_value *res)
 2701 {
 2702         uint8_t *end, *name;
 2703 
 2704         AML_CHECKSTACK();
 2705         end = aml_parseend(scope);
 2706         name = aml_parsename(scope);
 2707 
 2708         res = aml_allocvalue(AML_OBJTYPE_METHOD, 0, NULL);
 2709         res->v_method.flags = aml_parseint(scope, AMLOP_BYTEPREFIX);
 2710         res->v_method.start = scope->pos;
 2711         res->v_method.end = end;
 2712         res->v_method.fneval = aml_callmethod;
 2713         aml_createname(scope->node, name, res);
 2714 
 2715         scope->pos = end;
 2716 
 2717         return res;
 2718 }
 2719 
 2720 /* Parse simple type opcodes */
 2721 struct aml_value *
 2722 aml_parsesimple(struct aml_scope *scope, int opcode, struct aml_value *res)
 2723 {
 2724         struct aml_node *node;
 2725 
 2726         AML_CHECKSTACK();
 2727         switch (opcode) {
 2728         case AMLOP_ZERO:
 2729                 _aml_setvalue(res, AML_OBJTYPE_INTEGER+AML_STATIC,
 2730                     aml_parseint(scope, opcode), NULL);
 2731                 break;
 2732         case AMLOP_ONE:
 2733         case AMLOP_ONES:
 2734         case AMLOP_BYTEPREFIX:
 2735         case AMLOP_WORDPREFIX:
 2736         case AMLOP_DWORDPREFIX:
 2737         case AMLOP_QWORDPREFIX:
 2738         case AMLOP_REVISION:
 2739                 _aml_setvalue(res, AML_OBJTYPE_INTEGER,
 2740                     aml_parseint(scope, opcode), NULL);
 2741                 break;
 2742         case AMLOP_DEBUG:
 2743                 _aml_setvalue(res, AML_OBJTYPE_DEBUGOBJ, 0, NULL);
 2744                 break;
 2745         case AMLOP_STRINGPREFIX:
 2746                 _aml_setvalue(res, AML_OBJTYPE_STRING, -1, scope->pos);
 2747                 scope->pos += res->length+1;
 2748                 break;
 2749         case AMLOP_NAMECHAR:
 2750                 _aml_setvalue(res, AML_OBJTYPE_NAMEREF, 0, NULL);
 2751                 res->v_nameref = aml_parsename(scope);
 2752                 node = aml_searchname(scope->node, res->v_nameref);
 2753                 if (node && node->value)
 2754                         _aml_setvalue(res, AML_OBJTYPE_OBJREF, -1, node->value);
 2755                 break;
 2756         }
 2757         return res;
 2758 }
 2759 
 2760 /* Parse field unit opcodes */
 2761 struct aml_value *
 2762 aml_parsefieldunit(struct aml_scope *scope, int opcode, struct aml_value *res)
 2763 {
 2764         uint8_t *end, *name;
 2765         struct aml_value *fld;
 2766 
 2767         AML_CHECKSTACK();
 2768         end = aml_parseend(scope);
 2769 
 2770         switch (opcode) {
 2771         case AMLOP_FIELD:
 2772                 aml_parsetarget(scope, NULL, &res->v_field.ref1);
 2773                 break;
 2774         case AMLOP_INDEXFIELD:
 2775                 aml_parsetarget(scope, NULL, &res->v_field.ref1);
 2776                 aml_parsetarget(scope, NULL, &res->v_field.ref2);
 2777                 break;
 2778         case AMLOP_BANKFIELD:
 2779                 aml_parsetarget(scope, NULL, &res->v_field.ref1);
 2780                 aml_parsetarget(scope, NULL, &res->v_field.ref2);
 2781                 res->v_field.ref3 = aml_parseint(scope, AML_ANYINT);
 2782                 break;
 2783         }
 2784         res->v_field.flags = aml_parseint(scope, AMLOP_BYTEPREFIX);
 2785         res->v_field.type = opcode;
 2786 
 2787         aml_fixref(&res->v_field.ref1);
 2788         aml_fixref(&res->v_field.ref2);
 2789 
 2790         while (scope->pos < end) {
 2791                 switch (*scope->pos) {
 2792                 case 0x00: // reserved
 2793                         scope->pos++;
 2794                         res->v_field.bitlen = aml_parselength(scope);
 2795                         break;
 2796                 case 0x01: // attrib
 2797                         scope->pos++;
 2798                         /* XXX: do something with this */
 2799                         aml_parseint(scope, AMLOP_BYTEPREFIX);
 2800                         aml_parseint(scope, AMLOP_BYTEPREFIX);
 2801                         res->v_field.bitlen = 0;
 2802                         break;
 2803                 default:
 2804                         name = aml_parsename(scope);
 2805                         res->v_field.bitlen = aml_parselength(scope);
 2806 
 2807                         /* Allocate new fieldunit */
 2808                         fld = aml_allocvalue(AML_OBJTYPE_FIELDUNIT, 0, NULL);
 2809 
 2810                         /* Increase reference count on field */
 2811                         fld->v_field = res->v_field;
 2812                         aml_addref(fld->v_field.ref1);
 2813                         aml_addref(fld->v_field.ref2);
 2814 
 2815                         aml_createname(scope->node, name, fld);
 2816                         break;
 2817                 }
 2818                 res->v_field.bitpos += res->v_field.bitlen;
 2819         }
 2820         /* Delete redundant reference */
 2821         aml_delref(&res->v_field.ref1);
 2822         aml_delref(&res->v_field.ref2);
 2823         return res;
 2824 }
 2825 
 2826 /* Parse CreateXXXField opcodes */
 2827 struct aml_value *
 2828 aml_parsebufferfield(struct aml_scope *scope, int opcode,
 2829     struct aml_value *res)
 2830 {
 2831         uint8_t *name;
 2832 
 2833         AML_CHECKSTACK();
 2834         res = aml_allocvalue(AML_OBJTYPE_BUFFERFIELD, 0, NULL);
 2835         res->v_field.type = opcode;
 2836         aml_parsetarget(scope, NULL, &res->v_field.ref1);
 2837         res->v_field.bitpos = aml_parseint(scope, AML_ANYINT);
 2838 
 2839         aml_fixref(&res->v_field.ref1);
 2840 
 2841         switch (opcode) {
 2842         case AMLOP_CREATEFIELD:
 2843                 res->v_field.bitlen = aml_parseint(scope, AML_ANYINT);
 2844                 break;
 2845         case AMLOP_CREATEBITFIELD:
 2846                 res->v_field.bitlen = 1;
 2847                 break;
 2848         case AMLOP_CREATEBYTEFIELD:
 2849                 res->v_field.bitlen = 8;
 2850                 res->v_field.bitpos *= 8;
 2851                 break;
 2852         case AMLOP_CREATEWORDFIELD:
 2853                 res->v_field.bitlen = 16;
 2854                 res->v_field.bitpos *= 8;
 2855                 break;
 2856         case AMLOP_CREATEDWORDFIELD:
 2857                 res->v_field.bitlen = 32;
 2858                 res->v_field.bitpos *= 8;
 2859                 break;
 2860         case AMLOP_CREATEQWORDFIELD:
 2861                 res->v_field.bitlen = 64;
 2862                 res->v_field.bitpos *= 8;
 2863                 break;
 2864         }
 2865         name = aml_parsename(scope);
 2866         aml_createname(scope->node, name, res);
 2867 
 2868         return res;
 2869 }
 2870 
 2871 /* Parse Mutex/Event action */
 2872 struct aml_value *
 2873 aml_parsemuxaction(struct aml_scope *scope, int opcode, struct aml_value *res)
 2874 {
 2875         struct aml_value *tmparg;
 2876         int64_t i1;
 2877         int rv;
 2878 
 2879         AML_CHECKSTACK();
 2880 
 2881         tmparg = aml_alloctmp(scope, 1);
 2882         aml_parsetarget(scope, tmparg, NULL);
 2883         switch (opcode) {
 2884         case AMLOP_ACQUIRE:
 2885                 /* Assert: tmparg is AML_OBJTYPE_MUTEX */
 2886                 i1 = aml_parseint(scope, AMLOP_WORDPREFIX);
 2887                 rv = acpi_mutex_acquire(tmparg->v_objref.ref, i1);
 2888                 /* Return true if timed out */
 2889                 aml_setvalue(scope, res, NULL, rv);
 2890                 break;
 2891         case AMLOP_RELEASE:
 2892                 acpi_mutex_release(tmparg->v_objref.ref);
 2893                 break;
 2894 
 2895         case AMLOP_WAIT:
 2896                 /* Assert: tmparg is AML_OBJTYPE_EVENT */
 2897                 i1 = aml_parseint(scope, AML_ANYINT);
 2898 
 2899                 /* Return true if timed out */
 2900                 aml_setvalue(scope, res, NULL, 0);
 2901                 break;
 2902         case AMLOP_SIGNAL:
 2903                 break;
 2904         case AMLOP_RESET:
 2905                 break;
 2906         }
 2907 
 2908         return res;
 2909 }
 2910 
 2911 /* Parse Miscellaneous opcodes */
 2912 struct aml_value *
 2913 aml_parsemisc2(struct aml_scope *scope, int opcode, struct aml_value *res)
 2914 {
 2915         struct aml_value *tmparg, *dev;
 2916         int i1, i2, i3;
 2917 
 2918         AML_CHECKSTACK();
 2919 
 2920         switch (opcode) {
 2921         case AMLOP_NOTIFY:
 2922                 /* Assert: tmparg is nameref or objref */
 2923                 tmparg = aml_alloctmp(scope, 1);
 2924                 aml_parseop(scope, tmparg);
 2925                 dev = aml_dereftarget(scope, tmparg);
 2926 
 2927                 i1 = aml_parseint(scope, AML_ANYINT);
 2928                 if (dev && dev->node) {
 2929                         dnprintf(10, "Notify: [%s] %.2x\n",
 2930                             aml_nodename(dev->node), i1);
 2931                         aml_notify(dev->node, i1);
 2932                 }
 2933                 break;
 2934         case AMLOP_SLEEP:
 2935                 i1 = aml_parseint(scope, AML_ANYINT);
 2936                 dnprintf(50, "SLEEP: %x\n", i1);
 2937                 if (i1)
 2938                         acpi_sleep(i1);
 2939                 else {
 2940                         dnprintf(10, "acpi_sleep(0)\n");
 2941                 }
 2942                 break;
 2943         case AMLOP_STALL:
 2944                 i1 = aml_parseint(scope, AML_ANYINT);
 2945                 dnprintf(50, "STALL: %x\n", i1);
 2946                 if (i1)
 2947                         acpi_stall(i1);
 2948                 else {
 2949                         dnprintf(10, "acpi_stall(0)\n");
 2950                 }
 2951                 break;
 2952         case AMLOP_FATAL:
 2953                 i1 = aml_parseint(scope, AMLOP_BYTEPREFIX);
 2954                 i2 = aml_parseint(scope, AMLOP_DWORDPREFIX);
 2955                 i3 = aml_parseint(scope, AML_ANYINT);
 2956                 aml_die("FATAL: %x %x %x\n", i1, i2, i3);
 2957                 break;
 2958         }
 2959         return res;
 2960 }
 2961 
 2962 /* Parse Miscellaneous opcodes */
 2963 struct aml_value *
 2964 aml_parsemisc3(struct aml_scope *scope, int opcode, struct aml_value *res)
 2965 {
 2966         struct aml_value *tmparg;
 2967 
 2968         AML_CHECKSTACK();
 2969         tmparg = aml_alloctmp(scope, 1);
 2970         aml_parseterm(scope, tmparg);
 2971         switch (opcode) {
 2972         case AMLOP_SIZEOF:
 2973                 aml_setvalue(scope, res, NULL, tmparg->length);
 2974                 break;
 2975         case AMLOP_OBJECTTYPE:
 2976                 aml_setvalue(scope, res, NULL, tmparg->type);
 2977                 break;
 2978         }
 2979 
 2980         return res;
 2981 }
 2982 
 2983 /* Parse AMLOP_MATCH */
 2984 struct aml_value *
 2985 aml_parsematch(struct aml_scope *scope, int opcode, struct aml_value *res)
 2986 {
 2987         struct aml_value *pkg;
 2988         int op1, op2, idx, mv1, mv2;
 2989 
 2990         AML_CHECKSTACK();
 2991         pkg = aml_parseterm(scope, NULL);
 2992         op1 = aml_parseint(scope, AMLOP_BYTEPREFIX);
 2993         mv1 = aml_parseint(scope, AML_ANYINT);
 2994         op2 = aml_parseint(scope, AMLOP_BYTEPREFIX);
 2995         mv2 = aml_parseint(scope, AML_ANYINT);
 2996         idx = aml_parseint(scope, AML_ANYINT);
 2997 
 2998         aml_setvalue(scope, res, NULL, -1);
 2999         while (idx < pkg->length) {
 3000                 if (aml_match(op1, mv1, pkg->v_package[idx]) ||
 3001                     aml_match(op2, mv2, pkg->v_package[idx])) {
 3002                         aml_setvalue(scope, res, NULL, idx);
 3003                         break;
 3004                 }
 3005                 idx++;
 3006         }
 3007         aml_delref(&pkg);
 3008         return res;
 3009 }
 3010 
 3011 /* Parse referenced objects */
 3012 struct aml_value *
 3013 aml_parseref(struct aml_scope *scope, int opcode, struct aml_value *res)
 3014 {
 3015         struct aml_value *tmparg;
 3016 
 3017         AML_CHECKSTACK();
 3018 
 3019         switch (opcode) {
 3020         case AMLOP_INDEX:
 3021                 tmparg = aml_alloctmp(scope, 1);
 3022                 _aml_setvalue(res, AML_OBJTYPE_OBJREF, -1, NULL);
 3023                 aml_parsetarget(scope, tmparg, NULL);
 3024 
 3025                 res->v_objref.index = aml_parseint(scope, AML_ANYINT);
 3026                 res->v_objref.ref = aml_dereftarget(scope, tmparg);
 3027 
 3028                 aml_parsetarget(scope, tmparg, NULL);
 3029                 aml_setvalue(scope, tmparg, res, 0);
 3030                 break;
 3031         case AMLOP_DEREFOF:
 3032                 aml_parseop(scope, res);
 3033                 break;
 3034         case AMLOP_RETURN:
 3035                 tmparg = aml_alloctmp(scope, 1);
 3036                 aml_parseterm(scope, tmparg);
 3037                 aml_setvalue(scope, res, tmparg, 0);
 3038                 scope->pos = scope->end;
 3039                 break;
 3040         case AMLOP_ARG0 ... AMLOP_ARG6:
 3041                 opcode -= AMLOP_ARG0;
 3042                 if (scope->args == NULL || opcode >= scope->nargs)
 3043                         aml_die("arg %d out of range", opcode);
 3044 
 3045                 /* Create OBJREF to stack variable */
 3046                 _aml_setvalue(res, AML_OBJTYPE_OBJREF, -1,
 3047                     &scope->args[opcode]);
 3048                 break;
 3049         case AMLOP_LOCAL0 ... AMLOP_LOCAL7:
 3050                 opcode -= AMLOP_LOCAL0;
 3051 
 3052                 /* No locals exist.. lazy allocate */
 3053                 if (scope->locals == NULL) {
 3054                         dnprintf(10, "Lazy alloc locals\n");
 3055                         scope->locals = aml_alloctmp(scope, AML_MAX_LOCAL);
 3056                 }
 3057 
 3058                 /* Create OBJREF to stack variable */
 3059                 _aml_setvalue(res, AML_OBJTYPE_OBJREF, -1,
 3060                     &scope->locals[opcode]);
 3061                 res->v_objref.ref->stack = opcode+AMLOP_LOCAL0;
 3062                 break;
 3063         case AMLOP_LOAD:
 3064                 tmparg = aml_alloctmp(scope, 2);
 3065                 aml_parseop(scope, &tmparg[0]);
 3066                 aml_parseop(scope, &tmparg[1]);
 3067                 break;
 3068         case AMLOP_STORE:
 3069                 tmparg = aml_alloctmp(scope, 1);
 3070                 aml_parseterm(scope, res);
 3071                 aml_parsetarget(scope, tmparg, NULL);
 3072 
 3073                 while (tmparg->type == AML_OBJTYPE_OBJREF) {
 3074                         if (tmparg->v_objref.index != -1)
 3075                                 break;
 3076                         tmparg = tmparg->v_objref.ref;
 3077                 }
 3078                 aml_setvalue(scope, tmparg, res, 0);
 3079                 break;
 3080         case AMLOP_REFOF:
 3081                 _aml_setvalue(res, AML_OBJTYPE_OBJREF, -1, NULL);
 3082                 aml_parsetarget(scope, NULL, &res->v_objref.ref);
 3083                 break;
 3084         case AMLOP_CONDREFOF:
 3085                 /* Returns true if object exists */
 3086                 tmparg = aml_alloctmp(scope, 2);
 3087                 aml_parsetarget(scope, &tmparg[0], NULL);
 3088                 aml_parsetarget(scope, &tmparg[1], NULL);
 3089                 if (tmparg[0].type != AML_OBJTYPE_NAMEREF) {
 3090                         /* Object exists */
 3091                         aml_freevalue(&tmparg[1]);
 3092                         aml_setvalue(scope, &tmparg[1], &tmparg[0], 0);
 3093                         aml_setvalue(scope, res, NULL, 1);
 3094                 } else {
 3095                         /* Object doesn't exist */
 3096                         aml_setvalue(scope, res, NULL, 0);
 3097                 }
 3098                 break;
 3099         }
 3100 
 3101         return res;
 3102 }
 3103 
 3104 struct aml_value *
 3105 aml_parsestring(struct aml_scope *scope, int opcode, struct aml_value *res)
 3106 {
 3107         struct aml_value *tmpval;
 3108         int i1, i2;
 3109 
 3110         AML_CHECKSTACK();
 3111         switch (opcode) {
 3112         case AMLOP_CONCAT:
 3113                 tmpval = aml_alloctmp(scope, 4);
 3114                 aml_parseterm(scope, &tmpval[AML_LHS]);
 3115                 aml_parseterm(scope, &tmpval[AML_RHS]);
 3116                 aml_parsetarget(scope, &tmpval[AML_DST], NULL);
 3117                 if (tmpval[AML_LHS].type == AML_OBJTYPE_BUFFER &&
 3118                     tmpval[AML_RHS].type == AML_OBJTYPE_BUFFER) {
 3119                         aml_resize(&tmpval[AML_LHS],
 3120                             tmpval[AML_LHS].length+tmpval[AML_RHS].length);
 3121                         memcpy(&tmpval[AML_LHS].v_buffer+tmpval[AML_LHS].length,
 3122                             tmpval[AML_RHS].v_buffer, tmpval[AML_RHS].length);
 3123                         aml_setvalue(scope, &tmpval[AML_DST], &tmpval[AML_LHS], 0);
 3124                 }
 3125                 if (tmpval[AML_LHS].type == AML_OBJTYPE_STRING &&
 3126                     tmpval[AML_RHS].type == AML_OBJTYPE_STRING) {
 3127                         aml_resize(&tmpval[AML_LHS],
 3128                             tmpval[AML_LHS].length+tmpval[AML_RHS].length);
 3129                         memcpy(&tmpval[AML_LHS].v_string+tmpval[AML_LHS].length,
 3130                             tmpval[AML_RHS].v_buffer, tmpval[AML_RHS].length);
 3131                         aml_setvalue(scope, &tmpval[AML_DST], &tmpval[AML_LHS], 0);
 3132                 } else {
 3133                         aml_die("concat");
 3134                 }
 3135                 break;
 3136         case AMLOP_MID:
 3137                 tmpval = aml_alloctmp(scope, 2);
 3138                 aml_parseterm(scope, &tmpval[0]);
 3139                 i1 = aml_parseint(scope, AML_ANYINT); // start
 3140                 i2 = aml_parseint(scope, AML_ANYINT); // length
 3141                 aml_parsetarget(scope, &tmpval[1], NULL);
 3142                 if (i1 > tmpval[0].length)
 3143                         i1 = tmpval[0].length;
 3144                 if (i1+i2 > tmpval[0].length)
 3145                         i2 = tmpval[0].length-i1;
 3146                 _aml_setvalue(res, AML_OBJTYPE_STRING, i2, tmpval[0].v_string+i1);
 3147                 break;
 3148         case AMLOP_TODECSTRING:
 3149         case AMLOP_TOHEXSTRING:
 3150                 i1 = aml_parseint(scope, AML_ANYINT);
 3151                 _aml_setvalue(res, AML_OBJTYPE_STRING, 20, NULL);
 3152                 snprintf(res->v_string, res->length,
 3153                     ((opcode == AMLOP_TODECSTRING) ? "%d" : "%x"), i1);
 3154                 break;
 3155         default:
 3156                 aml_die("to_string");
 3157                 break;
 3158         }
 3159 
 3160         return res;
 3161 }
 3162 
 3163 struct aml_value *
 3164 aml_parseterm(struct aml_scope *scope, struct aml_value *res)
 3165 {
 3166         struct aml_value *tmpres;
 3167 
 3168         /* If no value specified, allocate dynamic */
 3169         if (res == NULL)
 3170                 res = aml_allocvalue(AML_OBJTYPE_UNINITIALIZED, 0, NULL);
 3171         tmpres = aml_alloctmp(scope, 1);
 3172         aml_parseop(scope, tmpres);
 3173         aml_evalterm(scope, tmpres, res);
 3174         return res;
 3175 }
 3176 
 3177 struct aml_value *
 3178 aml_parsetarget(struct aml_scope *scope, struct aml_value *res,
 3179     struct aml_value **opt)
 3180 {
 3181         struct aml_value *dummy;
 3182 
 3183         /* If no value specified, allocate dynamic */
 3184         if (res == NULL)
 3185                 res = aml_allocvalue(AML_OBJTYPE_UNINITIALIZED, 0, NULL);
 3186         aml_parseop(scope, res);
 3187         if (opt == NULL)
 3188                 opt = &dummy;
 3189 
 3190         *opt = aml_evaltarget(scope, res);
 3191 
 3192         return res;
 3193 }
 3194 
 3195 int odp;
 3196 
 3197 /* Main Opcode Parser/Evaluator */
 3198 struct aml_value *
 3199 aml_parseop(struct aml_scope *scope, struct aml_value *res)
 3200 {
 3201         int opcode;
 3202         struct aml_opcode *htab;
 3203         struct aml_value *rv = NULL;
 3204 
 3205         if (odp++ > 25)
 3206                 panic("depth");
 3207         
 3208         aml_freevalue(res);
 3209         opcode = aml_parseopcode(scope);
 3210         dnprintf(15, "%.4x: [%s] %s\n", aml_pc(scope->pos-opsize(opcode)),
 3211             aml_nodename(scope->node), aml_mnem(opcode, scope->pos));
 3212         delay(amlop_delay);
 3213 
 3214         htab = aml_findopcode(opcode);
 3215         if (htab && htab->handler) {
 3216                 rv = htab->handler(scope, opcode, res);
 3217         } else {
 3218                 /* No opcode handler */
 3219                 aml_die("Unknown opcode: %.4x @ %.4x", opcode,
 3220                     aml_pc(scope->pos - opsize(opcode)));
 3221         }
 3222         odp--;
 3223         return rv;
 3224 }
 3225 
 3226 const char hext[] = "0123456789ABCDEF";
 3227 
 3228 const char *
 3229 aml_eisaid(u_int32_t pid)
 3230 {
 3231         static char id[8];
 3232 
 3233         id[0] = '@' + ((pid >> 2) & 0x1F);
 3234         id[1] = '@' + ((pid << 3) & 0x18) + ((pid >> 13) & 0x7);
 3235         id[2] = '@' + ((pid >> 8) & 0x1F);
 3236         id[3] = hext[(pid >> 20) & 0xF];
 3237         id[4] = hext[(pid >> 16) & 0xF];
 3238         id[5] = hext[(pid >> 28) & 0xF];
 3239         id[6] = hext[(pid >> 24) & 0xF];
 3240         id[7] = 0;
 3241         return id;
 3242 }
 3243 
 3244 /*
 3245  * @@@: Fixup DSDT code
 3246  */
 3247 struct aml_fixup {
 3248         int             offset;
 3249         u_int8_t        oldv, newv;
 3250 } __ibm300gl[] = {
 3251         { 0x19, 0x3a, 0x3b },
 3252         { -1 }
 3253 };
 3254 
 3255 struct aml_blacklist {
 3256         const char      *oem, *oemtbl;
 3257         struct aml_fixup *fixtab;
 3258         u_int8_t        cksum;
 3259 } amlfix_list[] = {
 3260         { "IBM   ", "CDTPWSNH", __ibm300gl, 0x41 },
 3261         { NULL },
 3262 };
 3263 
 3264 void
 3265 aml_fixup_dsdt(u_int8_t *acpi_hdr, u_int8_t *base, int len)
 3266 {
 3267         struct acpi_table_header *hdr = (struct acpi_table_header *)acpi_hdr;
 3268         struct aml_blacklist *fixlist;
 3269         struct aml_fixup *fixtab;
 3270 
 3271         for (fixlist = amlfix_list; fixlist->oem; fixlist++) {
 3272                 if (!memcmp(fixlist->oem, hdr->oemid, 6) &&
 3273                     !memcmp(fixlist->oemtbl, hdr->oemtableid, 8) &&
 3274                     fixlist->cksum == hdr->checksum) {
 3275                         /* Found a potential fixup entry */
 3276                         for (fixtab = fixlist->fixtab; fixtab->offset != -1;
 3277                             fixtab++) {
 3278                                 if (base[fixtab->offset] == fixtab->oldv)
 3279                                         base[fixtab->offset] = fixtab->newv;
 3280                         }
 3281                 }
 3282         }
 3283 }
 3284 
 3285 /*
 3286  * @@@: Default Object creation
 3287  */
 3288 struct aml_defval {
 3289         const char              *name;
 3290         int                     type;
 3291         int64_t                 ival;
 3292         const void              *bval;
 3293         struct aml_value        **gval;
 3294 } aml_defobj[] = {
 3295         { "_OS_", AML_OBJTYPE_STRING, -1, "OpenBSD" },
 3296         { "_REV", AML_OBJTYPE_INTEGER, 2, NULL },
 3297         { "_GL", AML_OBJTYPE_MUTEX, 1, NULL, &aml_global_lock },
 3298         { "_OSI", AML_OBJTYPE_METHOD, 1, aml_callosi },
 3299         { NULL }
 3300 };
 3301 
 3302 /* _OSI Default Method:
 3303  * Returns True if string argument matches list of known OS strings
 3304  * We return True for Windows to fake out nasty bad AML
 3305  */
 3306 char *aml_valid_osi[] = { 
 3307         "OpenBSD",
 3308         "Windows 2000",
 3309         "Windows 2001",
 3310         "Windows 2001.1",
 3311         "Windows 2001 SP0",
 3312         "Windows 2001 SP1",
 3313         "Windows 2001 SP2",
 3314         "Windows 2001 SP3",
 3315         "Windows 2001 SP4",
 3316         "Windows 2006",
 3317         NULL
 3318 };
 3319 
 3320 struct aml_value *
 3321 aml_callosi(struct aml_scope *scope, struct aml_value *val)
 3322 {
 3323         struct aml_value tmpstr, *arg;
 3324         int idx, result;
 3325 
 3326         /* Perform comparison with valid strings */
 3327         result = 0;
 3328         memset(&tmpstr, 0, sizeof(tmpstr));
 3329         tmpstr.type = AML_OBJTYPE_STRING;
 3330         arg = aml_derefvalue(scope, &scope->args[0], ACPI_IOREAD);
 3331 
 3332         for (idx=0; !result && aml_valid_osi[idx] != NULL; idx++) {
 3333                 tmpstr.v_string = aml_valid_osi[idx];
 3334                 tmpstr.length = strlen(tmpstr.v_string);
 3335                 
 3336                 result = aml_cmpvalue(arg, &tmpstr, AMLOP_LEQUAL);
 3337         }
 3338         aml_setvalue(scope, val, NULL, result);
 3339         return val;
 3340 }
 3341 
 3342 void
 3343 aml_create_defaultobjects()
 3344 {
 3345         struct aml_value *tmp;
 3346         struct aml_defval *def;
 3347 
 3348         for (def = aml_defobj; def->name; def++) {
 3349                 /* Allocate object value + add to namespace */
 3350                 tmp = aml_allocvalue(def->type, def->ival, def->bval);
 3351                 aml_createname(&aml_root, def->name, tmp);
 3352                 if (def->gval) {
 3353                         /* Set root object pointer */
 3354                         *def->gval = tmp;
 3355                 }
 3356         }
 3357 }
 3358 
 3359 int
 3360 aml_print_resource(union acpi_resource *crs, void *arg)
 3361 {
 3362         int typ = AML_CRSTYPE(crs);
 3363 
 3364         switch (typ) {
 3365         case LR_EXTIRQ:
 3366                 printf("extirq\tflags:%.2x len:%.2x irq:%.4x\n",
 3367                     crs->lr_extirq.flags, crs->lr_extirq.irq_count,
 3368                     aml_letohost32(crs->lr_extirq.irq[0]));
 3369                 break;
 3370         case SR_IRQ:
 3371                 printf("irq\t%.4x %.2x\n", aml_letohost16(crs->sr_irq.irq_mask),
 3372                     crs->sr_irq.irq_flags);
 3373                 break;
 3374         case SR_DMA:
 3375                 printf("dma\t%.2x %.2x\n", crs->sr_dma.channel,
 3376                     crs->sr_dma.flags);
 3377                 break;
 3378         case SR_IOPORT:
 3379                 printf("ioport\tflags:%.2x _min:%.4x _max:%.4x _aln:%.2x _len:%.2x\n",
 3380                     crs->sr_ioport.flags, crs->sr_ioport._min,
 3381                     crs->sr_ioport._max, crs->sr_ioport._aln,
 3382                     crs->sr_ioport._len);
 3383                 break;
 3384         case SR_STARTDEP:
 3385                 printf("startdep\n");
 3386                 break;
 3387         case SR_ENDDEP:
 3388                 printf("enddep\n");
 3389                 break;
 3390         case LR_WORD:
 3391                 printf("word\ttype:%.2x flags:%.2x tflag:%.2x gra:%.4x min:%.4x max:%.4x tra:%.4x len:%.4x\n",
 3392                         crs->lr_word.type, crs->lr_word.flags, crs->lr_word.tflags,
 3393                         crs->lr_word._gra, crs->lr_word._min, crs->lr_word._max,
 3394                         crs->lr_word._tra, crs->lr_word._len);
 3395                 break;
 3396         case LR_DWORD:
 3397                 printf("dword\ttype:%.2x flags:%.2x tflag:%.2x gra:%.8x min:%.8x max:%.8x tra:%.8x len:%.8x\n",
 3398                         crs->lr_dword.type, crs->lr_dword.flags, crs->lr_dword.tflags,
 3399                         crs->lr_dword._gra, crs->lr_dword._min, crs->lr_dword._max,
 3400                         crs->lr_dword._tra, crs->lr_dword._len);
 3401                 break;
 3402         case LR_QWORD:
 3403                 printf("dword\ttype:%.2x flags:%.2x tflag:%.2x gra:%.16llx min:%.16llx max:%.16llx tra:%.16llx len:%.16llx\n",
 3404                         crs->lr_qword.type, crs->lr_qword.flags, crs->lr_qword.tflags,
 3405                         crs->lr_qword._gra, crs->lr_qword._min, crs->lr_qword._max,
 3406                         crs->lr_qword._tra, crs->lr_qword._len);
 3407                 break;
 3408         default:
 3409                 printf("unknown type: %x\n", typ);
 3410                 break;
 3411         }
 3412         return (0);
 3413 }
 3414 
 3415 union acpi_resource *aml_mapresource(union acpi_resource *);
 3416 
 3417 union acpi_resource *
 3418 aml_mapresource(union acpi_resource *crs)
 3419 {
 3420         static union acpi_resource map;
 3421         int rlen;
 3422 
 3423         rlen = AML_CRSLEN(crs);
 3424         if (rlen >= sizeof(map))
 3425                 return crs;
 3426 
 3427         memset(&map, 0, sizeof(map));
 3428         memcpy(&map, crs, rlen);
 3429 
 3430         return &map;
 3431 }
 3432 
 3433 int
 3434 aml_parse_resource(int length, uint8_t *buffer,
 3435     int (*crs_enum)(union acpi_resource *, void *), void *arg)
 3436 {
 3437         int off, rlen;
 3438         union acpi_resource *crs;
 3439 
 3440         for (off = 0; off < length; off += rlen) {
 3441                 crs = (union acpi_resource *)(buffer+off);
 3442         
 3443                 rlen = AML_CRSLEN(crs);
 3444                 if (crs->hdr.typecode == 0x79 || rlen <= 3)
 3445                         break;
 3446 
 3447                 crs = aml_mapresource(crs);
 3448 #ifdef ACPI_DEBUG
 3449                 aml_print_resource(crs, NULL);
 3450 #endif
 3451                 crs_enum(crs, arg);
 3452         }
 3453 
 3454         return 0;
 3455 }
 3456 
 3457 void
 3458 aml_foreachpkg(struct aml_value *pkg, int start, 
 3459                void (*fn)(struct aml_value *, void *), 
 3460                void *arg)
 3461 {
 3462         int idx;
 3463         
 3464         if (pkg->type != AML_OBJTYPE_PACKAGE)
 3465                 return;
 3466         for (idx=start; idx<pkg->length; idx++) 
 3467                 fn(pkg->v_package[idx], arg);
 3468 }
 3469 
 3470 int
 3471 acpi_parse_aml(struct acpi_softc *sc, u_int8_t *start, u_int32_t length)
 3472 {
 3473         u_int8_t *end;
 3474 
 3475         dsdt_softc = sc;
 3476 
 3477         strlcpy(aml_root.name, "\\", sizeof(aml_root.name));
 3478         if (aml_root.start == NULL) {
 3479                 aml_root.start = start;
 3480                 aml_root.end = start+length;
 3481         }
 3482         end = start+length;
 3483         aml_parsenode(NULL, &aml_root, start, &end, NULL);
 3484         dnprintf(50, " : parsed %d AML bytes\n", length);
 3485 
 3486         return (0);
 3487 }
 3488 
 3489 /*
 3490  * Walk nodes and perform fixups for nameref
 3491  */
 3492 int aml_fixup_node(struct aml_node *, void *);
 3493 
 3494 int aml_fixup_node(struct aml_node *node, void *arg)
 3495 {
 3496         struct aml_value *val = arg;
 3497         int i;
 3498 
 3499         if (node->value == NULL)
 3500                 return (0);
 3501         if (arg == NULL)
 3502                 aml_fixup_node(node, node->value);
 3503         else if (val->type == AML_OBJTYPE_NAMEREF) {
 3504                 node = aml_searchname(node, val->v_nameref);
 3505                 if (node && node->value) {
 3506                         _aml_setvalue(val, AML_OBJTYPE_OBJREF, -1,
 3507                             node->value);
 3508                 }
 3509         } else if (val->type == AML_OBJTYPE_PACKAGE) {
 3510                 for (i = 0; i < val->length; i++)
 3511                         aml_fixup_node(node, val->v_package[i]);
 3512         } else if (val->type == AML_OBJTYPE_OPREGION) {
 3513                 if (val->v_opregion.iospace != GAS_PCI_CFG_SPACE)
 3514                         return (0);
 3515                 if (ACPI_PCI_FN(val->v_opregion.iobase) != 0xFFFF)
 3516                         return (0);
 3517                 val->v_opregion.iobase =
 3518                     ACPI_PCI_REG(val->v_opregion.iobase) +
 3519                     aml_getpciaddr(dsdt_softc, node);
 3520                 dnprintf(20, "late ioaddr : %s:%llx\n",
 3521                     aml_nodename(node), val->v_opregion.iobase);
 3522         }
 3523         return (0);
 3524 }
 3525 
 3526 void
 3527 aml_postparse()
 3528 {
 3529         aml_walknodes(&aml_root, AML_WALK_PRE, aml_fixup_node, NULL);
 3530 }

/* [<][>][^][v][top][bottom][index][help] */