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