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