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