[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

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