[BACK]Return to dsdt.c CVS log [TXT][DIR] Up to [local] / sys / dev / acpi

Annotation of sys/dev/acpi/dsdt.c, Revision 1.1

1.1     ! nbrk        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: }

CVSweb