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