xref: /openbsd-src/sys/dev/acpi/dsdt.c (revision 99fd087599a8791921855f21bd7e36130f39aadc)
1 /* $OpenBSD: dsdt.c,v 1.249 2019/10/16 01:43:50 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 	"Windows 2016",
1507 	"Windows 2017",
1508 	"Windows 2017.2",
1509 	"Windows 2018",
1510 	"Windows 2018.2",
1511 	"Windows 2019",
1512 	NULL
1513 };
1514 
1515 struct aml_value *
1516 aml_callosi(struct aml_scope *scope, struct aml_value *val)
1517 {
1518 	int idx, result=0;
1519 	struct aml_value *fa;
1520 
1521 	fa = aml_getstack(scope, AMLOP_ARG0);
1522 
1523 	if (hw_vendor != NULL &&
1524 	    (strcmp(hw_vendor, "Apple Inc.") == 0 ||
1525 	    strcmp(hw_vendor, "Apple Computer, Inc.") == 0)) {
1526 		if (strcmp(fa->v_string, "Darwin") == 0) {
1527 			dnprintf(10,"osi: returning 1 for %s on %s hardware\n",
1528 			    fa->v_string, hw_vendor);
1529 			result = 1;
1530 		} else
1531 			dnprintf(10,"osi: on %s hardware, but ignoring %s\n",
1532 			    hw_vendor, fa->v_string);
1533 
1534 		return aml_allocvalue(AML_OBJTYPE_INTEGER, result, NULL);
1535 	}
1536 
1537 	for (idx=0; !result && aml_valid_osi[idx] != NULL; idx++) {
1538 		dnprintf(10,"osi: %s,%s\n", fa->v_string, aml_valid_osi[idx]);
1539 		result = !strcmp(fa->v_string, aml_valid_osi[idx]);
1540 	}
1541 	dnprintf(10,"@@ OSI found: %x\n", result);
1542 	return aml_allocvalue(AML_OBJTYPE_INTEGER, result, NULL);
1543 }
1544 
1545 void
1546 aml_create_defaultobjects(void)
1547 {
1548 	struct aml_value *tmp;
1549 	struct aml_defval *def;
1550 
1551 #ifdef ACPI_MEMDEBUG
1552 	LIST_INIT(&acpi_memhead);
1553 #endif
1554 
1555 	osstring[1] = 'i';
1556 	osstring[6] = 'o';
1557 	osstring[15] = 'w';
1558 	osstring[18] = 'N';
1559 
1560 	SIMPLEQ_INIT(&aml_root.son);
1561 	strlcpy(aml_root.name, "\\", sizeof(aml_root.name));
1562 	aml_root.value = aml_allocvalue(0, 0, NULL);
1563 	aml_root.value->node = &aml_root;
1564 
1565 	for (def = aml_defobj; def->name; def++) {
1566 		/* Allocate object value + add to namespace */
1567 		aml_parsename(&aml_root, (uint8_t *)def->name, &tmp, 1);
1568 		_aml_setvalue(tmp, def->type, def->ival, def->bval);
1569 		if (def->gval) {
1570 			/* Set root object pointer */
1571 			*def->gval = tmp;
1572 		}
1573 		aml_delref(&tmp, 0);
1574 	}
1575 }
1576 
1577 #ifdef ACPI_DEBUG
1578 int
1579 aml_print_resource(union acpi_resource *crs, void *arg)
1580 {
1581 	int typ = AML_CRSTYPE(crs);
1582 
1583 	switch (typ) {
1584 	case LR_EXTIRQ:
1585 		printf("extirq\tflags:%.2x len:%.2x irq:%.4x\n",
1586 		    crs->lr_extirq.flags, crs->lr_extirq.irq_count,
1587 		    letoh32(crs->lr_extirq.irq[0]));
1588 		break;
1589 	case SR_IRQ:
1590 		printf("irq\t%.4x %.2x\n", letoh16(crs->sr_irq.irq_mask),
1591 		    crs->sr_irq.irq_flags);
1592 		break;
1593 	case SR_DMA:
1594 		printf("dma\t%.2x %.2x\n", crs->sr_dma.channel,
1595 		    crs->sr_dma.flags);
1596 		break;
1597 	case SR_IOPORT:
1598 		printf("ioport\tflags:%.2x _min:%.4x _max:%.4x _aln:%.2x _len:%.2x\n",
1599 		    crs->sr_ioport.flags, crs->sr_ioport._min,
1600 		    crs->sr_ioport._max, crs->sr_ioport._aln,
1601 		    crs->sr_ioport._len);
1602 		break;
1603 	case SR_STARTDEP:
1604 		printf("startdep\n");
1605 		break;
1606 	case SR_ENDDEP:
1607 		printf("enddep\n");
1608 		break;
1609 	case LR_WORD:
1610 		printf("word\ttype:%.2x flags:%.2x tflag:%.2x gra:%.4x min:%.4x max:%.4x tra:%.4x len:%.4x\n",
1611 			crs->lr_word.type, crs->lr_word.flags, crs->lr_word.tflags,
1612 			crs->lr_word._gra, crs->lr_word._min, crs->lr_word._max,
1613 			crs->lr_word._tra, crs->lr_word._len);
1614 		break;
1615 	case LR_DWORD:
1616 		printf("dword\ttype:%.2x flags:%.2x tflag:%.2x gra:%.8x min:%.8x max:%.8x tra:%.8x len:%.8x\n",
1617 			crs->lr_dword.type, crs->lr_dword.flags, crs->lr_dword.tflags,
1618 			crs->lr_dword._gra, crs->lr_dword._min, crs->lr_dword._max,
1619 			crs->lr_dword._tra, crs->lr_dword._len);
1620 		break;
1621 	case LR_QWORD:
1622 		printf("dword\ttype:%.2x flags:%.2x tflag:%.2x gra:%.16llx min:%.16llx max:%.16llx tra:%.16llx len:%.16llx\n",
1623 			crs->lr_qword.type, crs->lr_qword.flags, crs->lr_qword.tflags,
1624 			crs->lr_qword._gra, crs->lr_qword._min, crs->lr_qword._max,
1625 			crs->lr_qword._tra, crs->lr_qword._len);
1626 		break;
1627 	default:
1628 		printf("unknown type: %x\n", typ);
1629 		break;
1630 	}
1631 	return (0);
1632 }
1633 #endif /* ACPI_DEBUG */
1634 
1635 union acpi_resource *aml_mapresource(union acpi_resource *);
1636 
1637 union acpi_resource *
1638 aml_mapresource(union acpi_resource *crs)
1639 {
1640 	static union acpi_resource map;
1641 	int rlen;
1642 
1643 	rlen = AML_CRSLEN(crs);
1644 	if (rlen >= sizeof(map))
1645 		return crs;
1646 
1647 	memset(&map, 0, sizeof(map));
1648 	memcpy(&map, crs, rlen);
1649 
1650 	return &map;
1651 }
1652 
1653 int
1654 aml_parse_resource(struct aml_value *res,
1655     int (*crs_enum)(int, union acpi_resource *, void *), void *arg)
1656 {
1657 	int off, rlen, crsidx;
1658 	union acpi_resource *crs;
1659 
1660 	if (res->type != AML_OBJTYPE_BUFFER || res->length < 5)
1661 		return (-1);
1662 	for (off = 0, crsidx = 0; off < res->length; off += rlen, crsidx++) {
1663 		crs = (union acpi_resource *)(res->v_buffer+off);
1664 
1665 		rlen = AML_CRSLEN(crs);
1666 		if (crs->hdr.typecode == SRT_ENDTAG || !rlen)
1667 			break;
1668 
1669 		crs = aml_mapresource(crs);
1670 #ifdef ACPI_DEBUG
1671 		aml_print_resource(crs, NULL);
1672 #endif
1673 		crs_enum(crsidx, crs, arg);
1674 	}
1675 
1676 	return (0);
1677 }
1678 
1679 void
1680 aml_foreachpkg(struct aml_value *pkg, int start,
1681     void (*fn)(struct aml_value *, void *), void *arg)
1682 {
1683 	int idx;
1684 
1685 	if (pkg->type != AML_OBJTYPE_PACKAGE)
1686 		return;
1687 	for (idx=start; idx<pkg->length; idx++)
1688 		fn(pkg->v_package[idx], arg);
1689 }
1690 
1691 /*
1692  * Walk nodes and perform fixups for nameref
1693  */
1694 int aml_fixup_node(struct aml_node *, void *);
1695 
1696 int aml_fixup_node(struct aml_node *node, void *arg)
1697 {
1698 	struct aml_value *val = arg;
1699 	int i;
1700 
1701 	if (node->value == NULL)
1702 		return (0);
1703 	if (arg == NULL)
1704 		aml_fixup_node(node, node->value);
1705 	else if (val->type == AML_OBJTYPE_NAMEREF) {
1706 		node = aml_searchname(node, val->v_nameref);
1707 		if (node && node->value) {
1708 			_aml_setvalue(val, AML_OBJTYPE_OBJREF, AMLOP_NAMECHAR,
1709 			    node->value);
1710 		}
1711 	} else if (val->type == AML_OBJTYPE_PACKAGE) {
1712 		for (i = 0; i < val->length; i++)
1713 			aml_fixup_node(node, val->v_package[i]);
1714 	}
1715 	return (0);
1716 }
1717 
1718 void
1719 aml_postparse(void)
1720 {
1721 	aml_walknodes(&aml_root, AML_WALK_PRE, aml_fixup_node, NULL);
1722 }
1723 
1724 #ifndef SMALL_KERNEL
1725 const char *
1726 aml_val_to_string(const struct aml_value *val)
1727 {
1728 	static char buffer[256];
1729 
1730 	int len;
1731 
1732 	switch (val->type) {
1733 	case AML_OBJTYPE_BUFFER:
1734 		len = val->length;
1735 		if (len >= sizeof(buffer))
1736 			len = sizeof(buffer) - 1;
1737 		memcpy(buffer, val->v_buffer, len);
1738 		buffer[len] = 0;
1739 		break;
1740 	case AML_OBJTYPE_STRING:
1741 		strlcpy(buffer, val->v_string, sizeof(buffer));
1742 		break;
1743 	case AML_OBJTYPE_INTEGER:
1744 		snprintf(buffer, sizeof(buffer), "%llx", val->v_integer);
1745 		break;
1746 	default:
1747 		snprintf(buffer, sizeof(buffer),
1748 		    "Failed to convert type %d to string!", val->type);
1749 	};
1750 
1751 	return (buffer);
1752 }
1753 #endif /* SMALL_KERNEL */
1754 
1755 int aml_error;
1756 
1757 struct aml_value *aml_gettgt(struct aml_value *, int);
1758 struct aml_value *aml_eval(struct aml_scope *, struct aml_value *, int, int,
1759     struct aml_value *);
1760 struct aml_value *aml_parsesimple(struct aml_scope *, char,
1761     struct aml_value *);
1762 struct aml_value *aml_parse(struct aml_scope *, int, const char *);
1763 struct aml_value *aml_seterror(struct aml_scope *, const char *, ...);
1764 
1765 struct aml_scope *aml_findscope(struct aml_scope *, int, int);
1766 struct aml_scope *aml_pushscope(struct aml_scope *, struct aml_value *,
1767     struct aml_node *, int);
1768 struct aml_scope *aml_popscope(struct aml_scope *);
1769 
1770 void		aml_showstack(struct aml_scope *);
1771 struct aml_value *aml_convert(struct aml_value *, int, int);
1772 
1773 int		aml_matchtest(int64_t, int64_t, int);
1774 int		aml_match(struct aml_value *, int, int, int, int, int);
1775 
1776 int		aml_compare(struct aml_value *, struct aml_value *, int);
1777 struct aml_value *aml_concat(struct aml_value *, struct aml_value *);
1778 struct aml_value *aml_concatres(struct aml_value *, struct aml_value *);
1779 struct aml_value *aml_mid(struct aml_value *, int, int);
1780 int		aml_ccrlen(int, union acpi_resource *, void *);
1781 
1782 void		aml_store(struct aml_scope *, struct aml_value *, int64_t,
1783     struct aml_value *);
1784 
1785 /*
1786  * Reference Count functions
1787  */
1788 void
1789 aml_addref(struct aml_value *val, const char *lbl)
1790 {
1791 	if (val == NULL)
1792 		return;
1793 	dnprintf(50, "XAddRef: %p %s:[%s] %d\n",
1794 	    val, lbl,
1795 	    val->node ? aml_nodename(val->node) : "INTERNAL",
1796 	    val->refcnt);
1797 	val->refcnt++;
1798 }
1799 
1800 /* Decrease reference counter */
1801 void
1802 aml_delref(struct aml_value **pv, const char *lbl)
1803 {
1804 	struct aml_value *val;
1805 
1806 	if (pv == NULL || *pv == NULL)
1807 		return;
1808 	val = *pv;
1809 	val->refcnt--;
1810 	if (val->refcnt == 0) {
1811 		dnprintf(50, "XDelRef: %p %s %2d [%s] %s\n",
1812 		    val, lbl,
1813 		    val->refcnt,
1814 		    val->node ? aml_nodename(val->node) : "INTERNAL",
1815 		    val->refcnt ? "" : "---------------- FREEING");
1816 
1817 		aml_freevalue(val);
1818 		acpi_os_free(val);
1819 		*pv = NULL;
1820 	}
1821 }
1822 
1823 /* Walk list of parent scopes until we find one of 'type'
1824  * If endscope is set, mark all intermediate scopes as invalid (used for Method/While) */
1825 struct aml_scope *
1826 aml_findscope(struct aml_scope *scope, int type, int endscope)
1827 {
1828 	while (scope) {
1829 		switch (endscope) {
1830 		case AMLOP_RETURN:
1831 			scope->pos = scope->end;
1832 			if (scope->type == AMLOP_WHILE)
1833 				scope->pos = NULL;
1834 			break;
1835 		case AMLOP_CONTINUE:
1836 			scope->pos = scope->end;
1837 			break;
1838 		case AMLOP_BREAK:
1839 			scope->pos = scope->end;
1840 			if (scope->type == type)
1841 				scope->parent->pos = scope->end;
1842 			break;
1843 		}
1844 		if (scope->type == type)
1845 			break;
1846 		scope = scope->parent;
1847 	}
1848 	return scope;
1849 }
1850 
1851 struct aml_value *
1852 aml_getstack(struct aml_scope *scope, int opcode)
1853 {
1854 	struct aml_value *sp;
1855 
1856 	sp = NULL;
1857 	scope = aml_findscope(scope, AMLOP_METHOD, 0);
1858 	if (scope == NULL)
1859 		return NULL;
1860 	if (opcode >= AMLOP_LOCAL0 && opcode <= AMLOP_LOCAL7) {
1861 		if (scope->locals == NULL)
1862 			scope->locals = aml_allocvalue(AML_OBJTYPE_PACKAGE, 8, NULL);
1863 		sp = scope->locals->v_package[opcode - AMLOP_LOCAL0];
1864 		sp->stack = opcode;
1865 	} else if (opcode >= AMLOP_ARG0 && opcode <= AMLOP_ARG6) {
1866 		if (scope->args == NULL)
1867 			scope->args = aml_allocvalue(AML_OBJTYPE_PACKAGE, 7, NULL);
1868 		sp = scope->args->v_package[opcode - AMLOP_ARG0];
1869 		if (sp->type == AML_OBJTYPE_OBJREF)
1870 			sp = sp->v_objref.ref;
1871 	}
1872 	return sp;
1873 }
1874 
1875 #ifdef ACPI_DEBUG
1876 /* Dump AML Stack */
1877 void
1878 aml_showstack(struct aml_scope *scope)
1879 {
1880 	struct aml_value *sp;
1881 	int idx;
1882 
1883 	dnprintf(10, "===== Stack %s:%s\n", aml_nodename(scope->node),
1884 	    aml_mnem(scope->type, 0));
1885 	for (idx=0; scope->args && idx<7; idx++) {
1886 		sp = aml_getstack(scope, AMLOP_ARG0+idx);
1887 		if (sp && sp->type) {
1888 			dnprintf(10," Arg%d: ", idx);
1889 			aml_showvalue(sp);
1890 		}
1891 	}
1892 	for (idx=0; scope->locals && idx<8; idx++) {
1893 		sp = aml_getstack(scope, AMLOP_LOCAL0+idx);
1894 		if (sp && sp->type) {
1895 			dnprintf(10," Local%d: ", idx);
1896 			aml_showvalue(sp);
1897 		}
1898 	}
1899 }
1900 #endif
1901 
1902 /* Create a new scope object */
1903 struct aml_scope *
1904 aml_pushscope(struct aml_scope *parent, struct aml_value *range,
1905     struct aml_node *node, int type)
1906 {
1907 	struct aml_scope *scope;
1908 	uint8_t *start, *end;
1909 
1910 	if (range->type == AML_OBJTYPE_METHOD) {
1911 		start = range->v_method.start;
1912 		end = range->v_method.end;
1913 	} else {
1914 		start = range->v_buffer;
1915 		end = start + range->length;
1916 		if (start == end)
1917 			return NULL;
1918 	}
1919 	scope = acpi_os_malloc(sizeof(struct aml_scope));
1920 	if (scope == NULL)
1921 		return NULL;
1922 
1923 	scope->node = node;
1924 	scope->start = start;
1925 	scope->end = end;
1926 	scope->pos = scope->start;
1927 	scope->parent = parent;
1928 	scope->type = type;
1929 	scope->sc = acpi_softc;
1930 
1931 	if (parent)
1932 		scope->depth = parent->depth+1;
1933 
1934 	aml_lastscope = scope;
1935 
1936 	return scope;
1937 }
1938 
1939 /* Free a scope object and any children */
1940 struct aml_scope *
1941 aml_popscope(struct aml_scope *scope)
1942 {
1943 	struct aml_scope *nscope;
1944 
1945 	if (scope == NULL)
1946 		return NULL;
1947 
1948 	nscope = scope->parent;
1949 
1950 	if (scope->type == AMLOP_METHOD)
1951 		aml_delchildren(scope->node);
1952 	if (scope->locals) {
1953 		aml_freevalue(scope->locals);
1954 		acpi_os_free(scope->locals);
1955 		scope->locals = NULL;
1956 	}
1957 	if (scope->args) {
1958 		aml_freevalue(scope->args);
1959 		acpi_os_free(scope->args);
1960 		scope->args = NULL;
1961 	}
1962 	acpi_os_free(scope);
1963 	aml_lastscope = nscope;
1964 
1965 	return nscope;
1966 }
1967 
1968 /* Test AMLOP_MATCH codes */
1969 int
1970 aml_matchtest(int64_t a, int64_t b, int op)
1971 {
1972 	switch (op) {
1973 	case AML_MATCH_TR:
1974 		return (1);
1975 	case AML_MATCH_EQ:
1976 		return (a == b);
1977 	case AML_MATCH_LT:
1978 		return (a < b);
1979 	case AML_MATCH_LE:
1980 		return (a <= b);
1981 	case AML_MATCH_GE:
1982 		return (a >= b);
1983 	case AML_MATCH_GT:
1984 		return (a > b);
1985 	}
1986 	return (0);
1987 }
1988 
1989 /* Search a package for a matching value */
1990 int
1991 aml_match(struct aml_value *pkg, int index,
1992 	   int op1, int v1,
1993 	   int op2, int v2)
1994 {
1995 	struct aml_value *tmp;
1996 	int flag;
1997 
1998 	while (index < pkg->length) {
1999 		/* Convert package value to integer */
2000 		tmp = aml_convert(pkg->v_package[index],
2001 		    AML_OBJTYPE_INTEGER, -1);
2002 
2003 		/* Perform test */
2004 		flag = aml_matchtest(tmp->v_integer, v1, op1) &&
2005 		    aml_matchtest(tmp->v_integer, v2, op2);
2006 		aml_delref(&tmp, "xmatch");
2007 
2008 		if (flag)
2009 			return index;
2010 		index++;
2011 	}
2012 	return -1;
2013 }
2014 
2015 /*
2016  * Conversion routines
2017  */
2018 int64_t
2019 aml_hextoint(const char *str)
2020 {
2021 	int64_t v = 0;
2022 	char c;
2023 
2024 	while (*str) {
2025 		if (*str >= '0' && *str <= '9')
2026 			c = *(str++) - '0';
2027 		else if (*str >= 'a' && *str <= 'f')
2028 			c = *(str++) - 'a' + 10;
2029 		else if (*str >= 'A' && *str <= 'F')
2030 			c = *(str++) - 'A' + 10;
2031 		else
2032 			break;
2033 		v = (v << 4) + c;
2034 	}
2035 	return v;
2036 
2037 }
2038 
2039 struct aml_value *
2040 aml_convert(struct aml_value *a, int ctype, int clen)
2041 {
2042 	struct aml_value *c = NULL;
2043 
2044 	/* Object is already this type */
2045 	if (clen == -1)
2046 		clen = a->length;
2047 	if (a->type == ctype) {
2048 		aml_addref(a, "XConvert");
2049 		return a;
2050 	}
2051 	switch (ctype) {
2052 	case AML_OBJTYPE_BUFFER:
2053 		dnprintf(10,"convert to buffer\n");
2054 		switch (a->type) {
2055 		case AML_OBJTYPE_INTEGER:
2056 			c = aml_allocvalue(AML_OBJTYPE_BUFFER, a->length,
2057 			    &a->v_integer);
2058 			break;
2059 		case AML_OBJTYPE_STRING:
2060 			c = aml_allocvalue(AML_OBJTYPE_BUFFER, a->length,
2061 			    a->v_string);
2062 			break;
2063 		}
2064 		break;
2065 	case AML_OBJTYPE_INTEGER:
2066 		dnprintf(10,"convert to integer : %x\n", a->type);
2067 		switch (a->type) {
2068 		case AML_OBJTYPE_BUFFER:
2069 			c = aml_allocvalue(AML_OBJTYPE_INTEGER, 0, NULL);
2070 			memcpy(&c->v_integer, a->v_buffer,
2071 			    min(a->length, c->length));
2072 			break;
2073 		case AML_OBJTYPE_STRING:
2074 			c = aml_allocvalue(AML_OBJTYPE_INTEGER, 0, NULL);
2075 			c->v_integer = aml_hextoint(a->v_string);
2076 			break;
2077 		case AML_OBJTYPE_UNINITIALIZED:
2078 			c = aml_allocvalue(AML_OBJTYPE_INTEGER, 0, NULL);
2079 			break;
2080 		}
2081 		break;
2082 	case AML_OBJTYPE_STRING:
2083 	case AML_OBJTYPE_HEXSTRING:
2084 	case AML_OBJTYPE_DECSTRING:
2085 		dnprintf(10,"convert to string\n");
2086 		switch (a->type) {
2087 		case AML_OBJTYPE_INTEGER:
2088 			c = aml_allocvalue(AML_OBJTYPE_STRING, 20, NULL);
2089 			snprintf(c->v_string, c->length, (ctype == AML_OBJTYPE_HEXSTRING) ?
2090 			    "0x%llx" : "%lld", a->v_integer);
2091 			break;
2092 		case AML_OBJTYPE_BUFFER:
2093 			c = aml_allocvalue(AML_OBJTYPE_STRING, a->length,
2094 			    a->v_buffer);
2095 			break;
2096 		case AML_OBJTYPE_STRING:
2097 			aml_addref(a, "XConvert");
2098 			return a;
2099 		}
2100 		break;
2101 	}
2102 	if (c == NULL) {
2103 #ifndef SMALL_KERNEL
2104 		aml_showvalue(a);
2105 #endif
2106 		aml_die("Could not convert %x to %x\n", a->type, ctype);
2107 	}
2108 	return c;
2109 }
2110 
2111 int
2112 aml_compare(struct aml_value *a1, struct aml_value *a2, int opcode)
2113 {
2114 	int rc = 0;
2115 
2116 	/* Convert A2 to type of A1 */
2117 	a2 = aml_convert(a2, a1->type, -1);
2118 	if (a1->type == AML_OBJTYPE_INTEGER)
2119 		rc = aml_evalexpr(a1->v_integer, a2->v_integer, opcode);
2120 	else {
2121 		/* Perform String/Buffer comparison */
2122 		rc = memcmp(a1->v_buffer, a2->v_buffer,
2123 		    min(a1->length, a2->length));
2124 		if (rc == 0) {
2125 			/* If buffers match, which one is longer */
2126 			rc = a1->length - a2->length;
2127 		}
2128 		/* Perform comparison against zero */
2129 		rc = aml_evalexpr(rc, 0, opcode);
2130 	}
2131 	/* Either deletes temp buffer, or decrease refcnt on original A2 */
2132 	aml_delref(&a2, "xcompare");
2133 	return rc;
2134 }
2135 
2136 /* Concatenate two objects, returning pointer to new object */
2137 struct aml_value *
2138 aml_concat(struct aml_value *a1, struct aml_value *a2)
2139 {
2140 	struct aml_value *c = NULL;
2141 
2142 	/* Convert arg2 to type of arg1 */
2143 	a2 = aml_convert(a2, a1->type, -1);
2144 	switch (a1->type) {
2145 	case AML_OBJTYPE_INTEGER:
2146 		c = aml_allocvalue(AML_OBJTYPE_BUFFER,
2147 		    a1->length + a2->length, NULL);
2148 		memcpy(c->v_buffer, &a1->v_integer, a1->length);
2149 		memcpy(c->v_buffer+a1->length, &a2->v_integer, a2->length);
2150 		break;
2151 	case AML_OBJTYPE_BUFFER:
2152 		c = aml_allocvalue(AML_OBJTYPE_BUFFER,
2153 		    a1->length + a2->length, NULL);
2154 		memcpy(c->v_buffer, a1->v_buffer, a1->length);
2155 		memcpy(c->v_buffer+a1->length, a2->v_buffer, a2->length);
2156 		break;
2157 	case AML_OBJTYPE_STRING:
2158 		c = aml_allocvalue(AML_OBJTYPE_STRING,
2159 		    a1->length + a2->length, NULL);
2160 		memcpy(c->v_string, a1->v_string, a1->length);
2161 		memcpy(c->v_string+a1->length, a2->v_string, a2->length);
2162 		break;
2163 	default:
2164 		aml_die("concat type mismatch %d != %d\n", a1->type, a2->type);
2165 		break;
2166 	}
2167 	/* Either deletes temp buffer, or decrease refcnt on original A2 */
2168 	aml_delref(&a2, "xconcat");
2169 	return c;
2170 }
2171 
2172 /* Calculate length of Resource Template */
2173 int
2174 aml_ccrlen(int crsidx, union acpi_resource *rs, void *arg)
2175 {
2176 	int *plen = arg;
2177 
2178 	*plen += AML_CRSLEN(rs);
2179 	return (0);
2180 }
2181 
2182 /* Concatenate resource templates, returning pointer to new object */
2183 struct aml_value *
2184 aml_concatres(struct aml_value *a1, struct aml_value *a2)
2185 {
2186 	struct aml_value *c;
2187 	int l1 = 0, l2 = 0, l3 = 2;
2188 	uint8_t a3[] = { SRT_ENDTAG, 0x00 };
2189 
2190 	if (a1->type != AML_OBJTYPE_BUFFER || a2->type != AML_OBJTYPE_BUFFER)
2191 		aml_die("concatres: not buffers\n");
2192 
2193 	/* Walk a1, a2, get length minus end tags, concatenate buffers, add end tag */
2194 	aml_parse_resource(a1, aml_ccrlen, &l1);
2195 	aml_parse_resource(a2, aml_ccrlen, &l2);
2196 
2197 	/* Concatenate buffers, add end tag */
2198 	c = aml_allocvalue(AML_OBJTYPE_BUFFER, l1+l2+l3, NULL);
2199 	memcpy(c->v_buffer,    a1->v_buffer, l1);
2200 	memcpy(c->v_buffer+l1, a2->v_buffer, l2);
2201 	memcpy(c->v_buffer+l1+l2, a3,        l3);
2202 
2203 	return c;
2204 }
2205 
2206 /* Extract substring from string or buffer */
2207 struct aml_value *
2208 aml_mid(struct aml_value *src, int index, int length)
2209 {
2210 	if (index > src->length)
2211 		index = src->length;
2212 	if ((index + length) > src->length)
2213 		length = src->length - index;
2214 	return aml_allocvalue(src->type, length, src->v_buffer + index);
2215 }
2216 
2217 /*
2218  * Field I/O utility functions
2219  */
2220 void aml_createfield(struct aml_value *, int, struct aml_value *, int, int,
2221     struct aml_value *, int, int);
2222 void aml_parsefieldlist(struct aml_scope *, int, int,
2223     struct aml_value *, struct aml_value *, int);
2224 
2225 int
2226 aml_evalhid(struct aml_node *node, struct aml_value *val)
2227 {
2228 	if (aml_evalname(acpi_softc, node, "_HID", 0, NULL, val))
2229 		return (-1);
2230 
2231 	/* Integer _HID: convert to EISA ID */
2232 	if (val->type == AML_OBJTYPE_INTEGER)
2233 		_aml_setvalue(val, AML_OBJTYPE_STRING, -1, aml_eisaid(val->v_integer));
2234 	return (0);
2235 }
2236 
2237 int
2238 aml_opreg_sysmem_handler(void *cookie, int iodir, uint64_t address, int size,
2239     uint64_t *value)
2240 {
2241 	return acpi_gasio(acpi_softc, iodir, GAS_SYSTEM_MEMORY,
2242 	    address, size, size, value);
2243 }
2244 
2245 int
2246 aml_opreg_sysio_handler(void *cookie, int iodir, uint64_t address, int size,
2247     uint64_t *value)
2248 {
2249 	return acpi_gasio(acpi_softc, iodir, GAS_SYSTEM_IOSPACE,
2250 	    address, size, size, value);
2251 }
2252 
2253 int
2254 aml_opreg_pcicfg_handler(void *cookie, int iodir, uint64_t address, int size,
2255     uint64_t *value)
2256 {
2257 	return acpi_gasio(acpi_softc, iodir, GAS_PCI_CFG_SPACE,
2258 	    address, size, size, value);
2259 }
2260 
2261 int
2262 aml_opreg_ec_handler(void *cookie, int iodir, uint64_t address, int size,
2263     uint64_t *value)
2264 {
2265 	return acpi_gasio(acpi_softc, iodir, GAS_EMBEDDED,
2266 	    address, size, size, value);
2267 }
2268 
2269 struct aml_regionspace {
2270 	void *cookie;
2271 	int (*handler)(void *, int, uint64_t, int, uint64_t *);
2272 };
2273 
2274 struct aml_regionspace aml_regionspace[256] = {
2275 	[ACPI_OPREG_SYSMEM] = { NULL, aml_opreg_sysmem_handler },
2276 	[ACPI_OPREG_SYSIO] = { NULL, aml_opreg_sysio_handler },
2277 	[ACPI_OPREG_PCICFG] = { NULL, aml_opreg_pcicfg_handler },
2278 	[ACPI_OPREG_EC] = { NULL, aml_opreg_ec_handler },
2279 };
2280 
2281 void
2282 aml_register_regionspace(struct aml_node *node, int iospace, void *cookie,
2283     int (*handler)(void *, int, uint64_t, int, uint64_t *))
2284 {
2285 	struct aml_value arg[2];
2286 
2287 	KASSERT(iospace >= 0 && iospace < 256);
2288 
2289 	aml_regionspace[iospace].cookie = cookie;
2290 	aml_regionspace[iospace].handler = handler;
2291 
2292 	/* Register address space. */
2293 	memset(&arg, 0, sizeof(arg));
2294 	arg[0].type = AML_OBJTYPE_INTEGER;
2295 	arg[0].v_integer = iospace;
2296 	arg[1].type = AML_OBJTYPE_INTEGER;
2297 	arg[1].v_integer = 1;
2298 	node = aml_searchname(node, "_REG");
2299 	if (node)
2300 		aml_evalnode(acpi_softc, node, 2, arg, NULL);
2301 }
2302 
2303 void aml_rwgen(struct aml_value *, int, int, struct aml_value *, int, int);
2304 void aml_rwgpio(struct aml_value *, int, int, struct aml_value *, int, int);
2305 void aml_rwgsb(struct aml_value *, int, int, int, struct aml_value *, int, int);
2306 void aml_rwindexfield(struct aml_value *, struct aml_value *val, int);
2307 void aml_rwfield(struct aml_value *, int, int, struct aml_value *, int);
2308 
2309 /* Get PCI address for opregion objects */
2310 int
2311 aml_rdpciaddr(struct aml_node *pcidev, union amlpci_t *addr)
2312 {
2313 	int64_t res;
2314 
2315 	addr->bus = 0;
2316 	addr->seg = 0;
2317 	if (aml_evalinteger(acpi_softc, pcidev, "_ADR", 0, NULL, &res) == 0) {
2318 		addr->fun = res & 0xFFFF;
2319 		addr->dev = res >> 16;
2320 	}
2321 	while (pcidev != NULL) {
2322 		/* HID device (PCI or PCIE root): eval _SEG and _BBN */
2323 		if (__aml_search(pcidev, "_HID", 0)) {
2324 			if (aml_evalinteger(acpi_softc, pcidev, "_SEG",
2325 			        0, NULL, &res) == 0) {
2326 				addr->seg = res;
2327 			}
2328 			if (aml_evalinteger(acpi_softc, pcidev, "_BBN",
2329 			        0, NULL, &res) == 0) {
2330 				addr->bus = res;
2331 				break;
2332 			}
2333 		}
2334 		pcidev = pcidev->parent;
2335 	}
2336 	return (0);
2337 }
2338 
2339 int
2340 acpi_genio(struct acpi_softc *sc, int iodir, int iospace, uint64_t address,
2341     int access_size, int len, void *buffer)
2342 {
2343 	struct aml_regionspace *region = &aml_regionspace[iospace];
2344 	uint8_t *pb;
2345 	int reg;
2346 
2347 	dnprintf(50, "genio: %.2x 0x%.8llx %s\n",
2348 	    iospace, address, (iodir == ACPI_IOWRITE) ? "write" : "read");
2349 
2350 	KASSERT((len % access_size) == 0);
2351 
2352 	pb = (uint8_t *)buffer;
2353 	for (reg = 0; reg < len; reg += access_size) {
2354 		uint64_t value;
2355 		int err;
2356 
2357 		if (iodir == ACPI_IOREAD) {
2358 			err = region->handler(region->cookie, iodir,
2359 			    address + reg, access_size, &value);
2360 			if (err)
2361 				return err;
2362 			switch (access_size) {
2363 			case 1:
2364 				*(uint8_t *)(pb + reg) = value;
2365 				break;
2366 			case 2:
2367 				*(uint16_t *)(pb + reg) = value;
2368 				break;
2369 			case 4:
2370 				*(uint32_t *)(pb + reg) = value;
2371 				break;
2372 			default:
2373 				printf("%s: invalid access size %d on read\n",
2374 				    __func__, access_size);
2375 				return -1;
2376 			}
2377 		} else {
2378 			switch (access_size) {
2379 			case 1:
2380 				value = *(uint8_t *)(pb + reg);
2381 				break;
2382 			case 2:
2383 				value = *(uint16_t *)(pb + reg);
2384 				break;
2385 			case 4:
2386 				value = *(uint32_t *)(pb + reg);
2387 				break;
2388 			default:
2389 				printf("%s: invalid access size %d on write\n",
2390 				    __func__, access_size);
2391 				return -1;
2392 			}
2393 			err = region->handler(region->cookie, iodir,
2394 			    address + reg, access_size, &value);
2395 			if (err)
2396 				return err;
2397 		}
2398 	}
2399 
2400 	return 0;
2401 }
2402 
2403 /* Read/Write from opregion object */
2404 void
2405 aml_rwgen(struct aml_value *rgn, int bpos, int blen, struct aml_value *val,
2406     int mode, int flag)
2407 {
2408 	struct aml_value tmp;
2409 	union amlpci_t pi;
2410 	void *tbit, *vbit;
2411 	int tlen, type, sz;
2412 
2413 	dnprintf(10," %5s %.2x %.8llx %.4x [%s]\n",
2414 		mode == ACPI_IOREAD ? "read" : "write",
2415 		rgn->v_opregion.iospace,
2416 		rgn->v_opregion.iobase + (bpos >> 3),
2417 		blen, aml_nodename(rgn->node));
2418 	memset(&tmp, 0, sizeof(tmp));
2419 
2420 	/* Get field access size */
2421 	switch (AML_FIELD_ACCESS(flag)) {
2422 	case AML_FIELD_WORDACC:
2423 		sz = 2;
2424 		break;
2425 	case AML_FIELD_DWORDACC:
2426 		sz = 4;
2427 		break;
2428 	case AML_FIELD_QWORDACC:
2429 		sz = 8;
2430 		break;
2431 	default:
2432 		sz = 1;
2433 		break;
2434 	}
2435 
2436 	pi.addr = (rgn->v_opregion.iobase + (bpos >> 3)) & ~(sz - 1);
2437 	bpos += ((rgn->v_opregion.iobase & (sz - 1)) << 3);
2438 	bpos &= ((sz << 3) - 1);
2439 
2440 	if (rgn->v_opregion.iospace == ACPI_OPREG_PCICFG) {
2441 		/* Get PCI Root Address for this opregion */
2442 		aml_rdpciaddr(rgn->node->parent, &pi);
2443 	}
2444 
2445 	tbit = &tmp.v_integer;
2446 	vbit = &val->v_integer;
2447 	tlen = roundup(bpos + blen, sz << 3);
2448 	type = rgn->v_opregion.iospace;
2449 
2450 	if (aml_regionspace[type].handler == NULL) {
2451 		printf("%s: unregistered RegionSpace 0x%x\n", __func__, type);
2452 		return;
2453 	}
2454 
2455 	/* Allocate temporary storage */
2456 	if (tlen > aml_intlen) {
2457 		_aml_setvalue(&tmp, AML_OBJTYPE_BUFFER, tlen >> 3, 0);
2458 		tbit = tmp.v_buffer;
2459 	}
2460 
2461 	if (blen > aml_intlen) {
2462 		if (mode == ACPI_IOREAD) {
2463 			/* Read from a large field:  create buffer */
2464 			_aml_setvalue(val, AML_OBJTYPE_BUFFER, (blen + 7) >> 3, 0);
2465 		} else {
2466 			/* Write to a large field.. create or convert buffer */
2467 			val = aml_convert(val, AML_OBJTYPE_BUFFER, -1);
2468 
2469 			if (blen > (val->length << 3))
2470 				blen = val->length << 3;
2471 		}
2472 		vbit = val->v_buffer;
2473 	} else {
2474 		if (mode == ACPI_IOREAD) {
2475 			/* Read from a short field.. initialize integer */
2476 			_aml_setvalue(val, AML_OBJTYPE_INTEGER, 0, 0);
2477 		} else {
2478 			/* Write to a short field.. convert to integer */
2479 			val = aml_convert(val, AML_OBJTYPE_INTEGER, -1);
2480 		}
2481 	}
2482 
2483 	if (mode == ACPI_IOREAD) {
2484 		/* Read bits from opregion */
2485 		acpi_genio(acpi_softc, ACPI_IOREAD, type, pi.addr,
2486 		    sz, tlen >> 3, tbit);
2487 		aml_bufcpy(vbit, 0, tbit, bpos, blen);
2488 	} else {
2489 		/* Write bits to opregion */
2490 		if (AML_FIELD_UPDATE(flag) == AML_FIELD_PRESERVE &&
2491 		    (bpos != 0 || blen != tlen)) {
2492 			acpi_genio(acpi_softc, ACPI_IOREAD, type, pi.addr,
2493 			    sz, tlen >> 3, tbit);
2494 		} else if (AML_FIELD_UPDATE(flag) == AML_FIELD_WRITEASONES) {
2495 			memset(tbit, 0xff, tmp.length);
2496 		}
2497 		/* Copy target bits, then write to region */
2498 		aml_bufcpy(tbit, bpos, vbit, 0, blen);
2499 		acpi_genio(acpi_softc, ACPI_IOWRITE, type, pi.addr,
2500 		    sz, tlen >> 3, tbit);
2501 
2502 		aml_delref(&val, "fld.write");
2503 	}
2504 	aml_freevalue(&tmp);
2505 }
2506 
2507 void
2508 aml_rwgpio(struct aml_value *conn, int bpos, int blen, struct aml_value *val,
2509     int mode, int flag)
2510 {
2511 	union acpi_resource *crs = (union acpi_resource *)conn->v_buffer;
2512 	struct aml_node *node;
2513 	uint16_t pin;
2514 	int v = 0;
2515 
2516 	if (conn->type != AML_OBJTYPE_BUFFER || conn->length < 5 ||
2517 	    AML_CRSTYPE(crs) != LR_GPIO || AML_CRSLEN(crs) > conn->length)
2518 		aml_die("Invalid GpioIo");
2519 	if (bpos != 0 || blen != 1)
2520 		aml_die("Invalid GpioIo access");
2521 
2522 	node = aml_searchname(conn->node,
2523 	    (char *)&crs->pad[crs->lr_gpio.res_off]);
2524 	pin = *(uint16_t *)&crs->pad[crs->lr_gpio.pin_off];
2525 
2526 	if (node == NULL || node->gpio == NULL)
2527 		aml_die("Could not find GpioIo pin");
2528 
2529 	if (mode == ACPI_IOWRITE) {
2530 		v = aml_val2int(val);
2531 		node->gpio->write_pin(node->gpio->cookie, pin, v);
2532 	} else {
2533 		v = node->gpio->read_pin(node->gpio->cookie, pin);
2534 		_aml_setvalue(val, AML_OBJTYPE_INTEGER, v, NULL);
2535 	}
2536 }
2537 
2538 #ifndef SMALL_KERNEL
2539 
2540 void
2541 aml_rwgsb(struct aml_value *conn, int alen, int bpos, int blen,
2542     struct aml_value *val, int mode, int flag)
2543 {
2544 	union acpi_resource *crs = (union acpi_resource *)conn->v_buffer;
2545 	struct aml_node *node;
2546 	i2c_tag_t tag;
2547 	i2c_op_t op;
2548 	i2c_addr_t addr;
2549 	int cmdlen, buflen;
2550 	uint8_t cmd;
2551 	uint8_t *buf;
2552 	int err;
2553 
2554 	if (conn->type != AML_OBJTYPE_BUFFER || conn->length < 5 ||
2555 	    AML_CRSTYPE(crs) != LR_SERBUS || AML_CRSLEN(crs) > conn->length ||
2556 	    crs->lr_i2cbus.revid != 1 || crs->lr_i2cbus.type != LR_SERBUS_I2C)
2557 		aml_die("Invalid GenericSerialBus");
2558 	if (AML_FIELD_ACCESS(flag) != AML_FIELD_BUFFERACC ||
2559 	    bpos & 0x3 || blen != 8)
2560 		aml_die("Invalid GenericSerialBus access");
2561 
2562 	node = aml_searchname(conn->node,
2563 	    (char *)&crs->lr_i2cbus.vdata[crs->lr_i2cbus.tlength - 6]);
2564 
2565 	if (node == NULL || node->i2c == NULL)
2566 		aml_die("Could not find GenericSerialBus controller");
2567 
2568 	switch (((flag >> 6) & 0x3)) {
2569 	case 0:			/* Normal */
2570 		switch (AML_FIELD_ATTR(flag)) {
2571 		case 0x02:	/* AttribQuick */
2572 			cmdlen = 0;
2573 			buflen = 0;
2574 			break;
2575 		case 0x04:	/* AttribSendReceive */
2576 			cmdlen = 0;
2577 			buflen = 1;
2578 			break;
2579 		case 0x06:	/* AttribByte */
2580 			cmdlen = 1;
2581 			buflen = 1;
2582 			break;
2583 		case 0x08:	/* AttribWord */
2584 			cmdlen = 1;
2585 			buflen = 2;
2586 			break;
2587 		case 0x0b:	/* AttribBytes */
2588 			cmdlen = 1;
2589 			buflen = alen;
2590 			break;
2591 		case 0x0e:	/* AttribRawBytes */
2592 			cmdlen = 0;
2593 			buflen = alen;
2594 			break;
2595 		default:
2596 			aml_die("unsupported access type 0x%x", flag);
2597 			break;
2598 		}
2599 		break;
2600 	case 1:			/* AttribBytes */
2601 		cmdlen = 1;
2602 		buflen = AML_FIELD_ATTR(flag);
2603 		break;
2604 	case 2:			/* AttribRawBytes */
2605 		cmdlen = 0;
2606 		buflen = AML_FIELD_ATTR(flag);
2607 		break;
2608 	default:
2609 		aml_die("unsupported access type 0x%x", flag);
2610 		break;
2611 	}
2612 
2613 	if (mode == ACPI_IOREAD) {
2614 		_aml_setvalue(val, AML_OBJTYPE_BUFFER, buflen + 2, NULL);
2615 		op = I2C_OP_READ_WITH_STOP;
2616 	} else {
2617 		op = I2C_OP_WRITE_WITH_STOP;
2618 	}
2619 
2620 	tag = node->i2c;
2621 	addr = crs->lr_i2cbus._adr;
2622 	cmd = bpos >> 3;
2623 	buf = val->v_buffer;
2624 
2625 	iic_acquire_bus(tag, 0);
2626 	err = iic_exec(tag, op, addr, &cmd, cmdlen, &buf[2], buflen, 0);
2627 	iic_release_bus(tag, 0);
2628 
2629 	/*
2630 	 * The ACPI specification doesn't tell us what the status
2631 	 * codes mean beyond implying that zero means success.  So use
2632 	 * the error returned from the transfer.  All possible error
2633 	 * numbers should fit in a single byte.
2634 	 */
2635 	buf[0] = err;
2636 }
2637 
2638 #endif
2639 
2640 void
2641 aml_rwindexfield(struct aml_value *fld, struct aml_value *val, int mode)
2642 {
2643 	struct aml_value tmp, *ref1, *ref2;
2644 	void *tbit, *vbit;
2645 	int vpos, bpos, blen;
2646 	int indexval;
2647 	int sz, len;
2648 
2649 	ref2 = fld->v_field.ref2;
2650 	ref1 = fld->v_field.ref1;
2651 	bpos = fld->v_field.bitpos;
2652 	blen = fld->v_field.bitlen;
2653 
2654 	memset(&tmp, 0, sizeof(tmp));
2655 	tmp.refcnt = 99;
2656 
2657 	/* Get field access size */
2658 	switch (AML_FIELD_ACCESS(fld->v_field.flags)) {
2659 	case AML_FIELD_WORDACC:
2660 		sz = 2;
2661 		break;
2662 	case AML_FIELD_DWORDACC:
2663 		sz = 4;
2664 		break;
2665 	case AML_FIELD_QWORDACC:
2666 		sz = 8;
2667 		break;
2668 	default:
2669 		sz = 1;
2670 		break;
2671 	}
2672 
2673 	if (blen > aml_intlen) {
2674 		if (mode == ACPI_IOREAD) {
2675 			/* Read from a large field: create buffer */
2676 			_aml_setvalue(val, AML_OBJTYPE_BUFFER,
2677 			    (blen + 7) >> 3, 0);
2678 		}
2679 		vbit = val->v_buffer;
2680 	} else {
2681 		if (mode == ACPI_IOREAD) {
2682 			/* Read from a short field: initialize integer */
2683 			_aml_setvalue(val, AML_OBJTYPE_INTEGER, 0, 0);
2684 		}
2685 		vbit = &val->v_integer;
2686 	}
2687 	tbit = &tmp.v_integer;
2688 	vpos = 0;
2689 
2690 	indexval = (bpos >> 3) & ~(sz - 1);
2691 	bpos = bpos - (indexval << 3);
2692 
2693 	while (blen > 0) {
2694 		len = min(blen, (sz << 3) - bpos);
2695 
2696 		/* Write index register */
2697 		_aml_setvalue(&tmp, AML_OBJTYPE_INTEGER, indexval, 0);
2698 		aml_rwfield(ref2, 0, aml_intlen, &tmp, ACPI_IOWRITE);
2699 		indexval += sz;
2700 
2701 		/* Read/write data register */
2702 		_aml_setvalue(&tmp, AML_OBJTYPE_INTEGER, 0, 0);
2703 		if (mode == ACPI_IOWRITE)
2704 			aml_bufcpy(tbit, 0, vbit, vpos, len);
2705 		aml_rwfield(ref1, bpos, len, &tmp, mode);
2706 		if (mode == ACPI_IOREAD)
2707 			aml_bufcpy(vbit, vpos, tbit, 0, len);
2708 		vpos += len;
2709 		blen -= len;
2710 		bpos = 0;
2711 	}
2712 }
2713 
2714 void
2715 aml_rwfield(struct aml_value *fld, int bpos, int blen, struct aml_value *val,
2716     int mode)
2717 {
2718 	struct aml_value tmp, *ref1, *ref2;
2719 
2720 	ref2 = fld->v_field.ref2;
2721 	ref1 = fld->v_field.ref1;
2722 	if (blen > fld->v_field.bitlen)
2723 		blen = fld->v_field.bitlen;
2724 
2725 	aml_lockfield(NULL, fld);
2726 	memset(&tmp, 0, sizeof(tmp));
2727 	aml_addref(&tmp, "fld.write");
2728 	if (fld->v_field.type == AMLOP_INDEXFIELD) {
2729 		aml_rwindexfield(fld, val, mode);
2730 	} else if (fld->v_field.type == AMLOP_BANKFIELD) {
2731 		_aml_setvalue(&tmp, AML_OBJTYPE_INTEGER, fld->v_field.ref3, 0);
2732 		aml_rwfield(ref2, 0, aml_intlen, &tmp, ACPI_IOWRITE);
2733 		aml_rwgen(ref1, fld->v_field.bitpos, fld->v_field.bitlen,
2734 		    val, mode, fld->v_field.flags);
2735 	} else if (fld->v_field.type == AMLOP_FIELD) {
2736 		switch (ref1->v_opregion.iospace) {
2737 		case ACPI_OPREG_GPIO:
2738 			aml_rwgpio(ref2, bpos, blen, val, mode,
2739 			    fld->v_field.flags);
2740 			break;
2741 #ifndef SMALL_KERNEL
2742 		case ACPI_OPREG_GSB:
2743 			aml_rwgsb(ref2, fld->v_field.ref3,
2744 			    fld->v_field.bitpos + bpos, blen,
2745 			    val, mode, fld->v_field.flags);
2746 			break;
2747 #endif
2748 		default:
2749 			aml_rwgen(ref1, fld->v_field.bitpos + bpos, blen,
2750 			    val, mode, fld->v_field.flags);
2751 			break;
2752 		}
2753 	} else if (mode == ACPI_IOREAD) {
2754 		/* bufferfield:read */
2755 		_aml_setvalue(val, AML_OBJTYPE_INTEGER, 0, 0);
2756 		aml_bufcpy(&val->v_integer, 0, ref1->v_buffer,
2757 		    fld->v_field.bitpos, fld->v_field.bitlen);
2758 	} else {
2759 		/* bufferfield:write */
2760 		val = aml_convert(val, AML_OBJTYPE_INTEGER, -1);
2761 		aml_bufcpy(ref1->v_buffer, fld->v_field.bitpos, &val->v_integer,
2762 		    0, fld->v_field.bitlen);
2763 		aml_delref(&val, "wrbuffld");
2764 	}
2765 	aml_unlockfield(NULL, fld);
2766 }
2767 
2768 /* Create Field Object          data		index
2769  *   AMLOP_FIELD		n:OpRegion	NULL
2770  *   AMLOP_INDEXFIELD		n:Field		n:Field
2771  *   AMLOP_BANKFIELD		n:OpRegion	n:Field
2772  *   AMLOP_CREATEFIELD		t:Buffer	NULL
2773  *   AMLOP_CREATEBITFIELD	t:Buffer	NULL
2774  *   AMLOP_CREATEBYTEFIELD	t:Buffer	NULL
2775  *   AMLOP_CREATEWORDFIELD	t:Buffer	NULL
2776  *   AMLOP_CREATEDWORDFIELD	t:Buffer	NULL
2777  *   AMLOP_CREATEQWORDFIELD	t:Buffer	NULL
2778  *   AMLOP_INDEX		t:Buffer	NULL
2779  */
2780 void
2781 aml_createfield(struct aml_value *field, int opcode,
2782 		struct aml_value *data, int bpos, int blen,
2783 		struct aml_value *index, int indexval, int flags)
2784 {
2785 	dnprintf(10, "## %s(%s): %s %.4x-%.4x\n",
2786 	    aml_mnem(opcode, 0),
2787 	    blen > aml_intlen ? "BUF" : "INT",
2788 	    aml_nodename(field->node), bpos, blen);
2789 	if (index) {
2790 		dnprintf(10, "  index:%s:%.2x\n", aml_nodename(index->node),
2791 		    indexval);
2792 	}
2793 	dnprintf(10, "  data:%s\n", aml_nodename(data->node));
2794 	field->type = (opcode == AMLOP_FIELD ||
2795 	    opcode == AMLOP_INDEXFIELD ||
2796 	    opcode == AMLOP_BANKFIELD) ?
2797 	    AML_OBJTYPE_FIELDUNIT :
2798 	    AML_OBJTYPE_BUFFERFIELD;
2799 
2800 	if (field->type == AML_OBJTYPE_BUFFERFIELD &&
2801 	    data->type != AML_OBJTYPE_BUFFER)
2802 		data = aml_convert(data, AML_OBJTYPE_BUFFER, -1);
2803 
2804 	field->v_field.type = opcode;
2805 	field->v_field.bitpos = bpos;
2806 	field->v_field.bitlen = blen;
2807 	field->v_field.ref3 = indexval;
2808 	field->v_field.ref2 = index;
2809 	field->v_field.ref1 = data;
2810 	field->v_field.flags = flags;
2811 
2812 	/* Increase reference count */
2813 	aml_addref(data, "Field.Data");
2814 	aml_addref(index, "Field.Index");
2815 }
2816 
2817 /* Parse Field/IndexField/BankField scope */
2818 void
2819 aml_parsefieldlist(struct aml_scope *mscope, int opcode, int flags,
2820     struct aml_value *data, struct aml_value *index, int indexval)
2821 {
2822 	struct aml_value *conn = NULL;
2823 	struct aml_value *rv;
2824 	int bpos, blen;
2825 
2826 	if (mscope == NULL)
2827 		return;
2828 	bpos = 0;
2829 	while (mscope->pos < mscope->end) {
2830 		switch (*mscope->pos) {
2831 		case 0x00: /* ReservedField */
2832 			mscope->pos++;
2833 			blen = aml_parselength(mscope);
2834 			break;
2835 		case 0x01: /* AccessField */
2836 			mscope->pos++;
2837 			blen = 0;
2838 			flags = aml_get8(mscope->pos++);
2839 			flags |= aml_get8(mscope->pos++) << 8;
2840 			break;
2841 		case 0x02: /* ConnectionField */
2842 			mscope->pos++;
2843 			blen = 0;
2844 			conn = aml_parse(mscope, 'o', "Connection");
2845 			if (conn == NULL)
2846 				aml_die("Could not parse connection");
2847 			conn->node = mscope->node;
2848 			break;
2849 		case 0x03: /* ExtendedAccessField */
2850 			mscope->pos++;
2851 			blen = 0;
2852 			flags = aml_get8(mscope->pos++);
2853 			flags |= aml_get8(mscope->pos++) << 8;
2854 			indexval = aml_get8(mscope->pos++);
2855 			break;
2856 		default: /* NamedField */
2857 			mscope->pos = aml_parsename(mscope->node, mscope->pos,
2858 			    &rv, 1);
2859 			blen = aml_parselength(mscope);
2860 			aml_createfield(rv, opcode, data, bpos, blen,
2861 			    conn ? conn : index, indexval, flags);
2862 			aml_delref(&rv, 0);
2863 			break;
2864 		}
2865 		bpos += blen;
2866 	}
2867 	aml_popscope(mscope);
2868 }
2869 
2870 /*
2871  * Mutex/Event utility functions
2872  */
2873 int	acpi_mutex_acquire(struct aml_scope *, struct aml_value *, int);
2874 void	acpi_mutex_release(struct aml_scope *, struct aml_value *);
2875 int	acpi_event_wait(struct aml_scope *, struct aml_value *, int);
2876 void	acpi_event_signal(struct aml_scope *, struct aml_value *);
2877 void	acpi_event_reset(struct aml_scope *, struct aml_value *);
2878 
2879 int
2880 acpi_mutex_acquire(struct aml_scope *scope, struct aml_value *mtx,
2881     int timeout)
2882 {
2883 	if (mtx->v_mtx.owner == NULL || scope == mtx->v_mtx.owner) {
2884 		/* We are now the owner */
2885 		mtx->v_mtx.owner = scope;
2886 		if (mtx == aml_global_lock) {
2887 			dnprintf(10,"LOCKING GLOBAL\n");
2888 			acpi_glk_enter();
2889 		}
2890 		dnprintf(5,"%s acquires mutex %s\n", scope->node->name,
2891 		    mtx->node->name);
2892 		return (0);
2893 	} else if (timeout == 0) {
2894 		return (-1);
2895 	}
2896 	/* Wait for mutex */
2897 	return (0);
2898 }
2899 
2900 void
2901 acpi_mutex_release(struct aml_scope *scope, struct aml_value *mtx)
2902 {
2903 	if (mtx == aml_global_lock) {
2904 		dnprintf(10,"UNLOCKING GLOBAL\n");
2905 		acpi_glk_leave();
2906 	}
2907 	dnprintf(5, "%s releases mutex %s\n", scope->node->name,
2908 	    mtx->node->name);
2909 	mtx->v_mtx.owner = NULL;
2910 	/* Wakeup waiters */
2911 }
2912 
2913 int
2914 acpi_event_wait(struct aml_scope *scope, struct aml_value *evt, int timeout)
2915 {
2916 	/* Wait for event to occur; do work in meantime */
2917 	while (evt->v_evt.state == 0 && timeout >= 0) {
2918 		if (acpi_dotask(acpi_softc))
2919 		    continue;
2920 		if (!cold) {
2921 			if (rwsleep(evt, &acpi_softc->sc_lck, PWAIT,
2922 			    "acpievt", 1) == EWOULDBLOCK) {
2923 				if (timeout < AML_NO_TIMEOUT)
2924 					timeout -= (1000 / hz);
2925 			}
2926 		} else {
2927 			delay(1000);
2928 			if (timeout < AML_NO_TIMEOUT)
2929 				timeout--;
2930 		}
2931 	}
2932 	if (evt->v_evt.state == 0)
2933 		return (-1);
2934 	evt->v_evt.state--;
2935 	return (0);
2936 }
2937 
2938 void
2939 acpi_event_signal(struct aml_scope *scope, struct aml_value *evt)
2940 {
2941 	evt->v_evt.state++;
2942 	if (evt->v_evt.state > 0)
2943 		wakeup_one(evt);
2944 }
2945 
2946 void
2947 acpi_event_reset(struct aml_scope *scope, struct aml_value *evt)
2948 {
2949 	evt->v_evt.state = 0;
2950 }
2951 
2952 /* Store result value into an object */
2953 void
2954 aml_store(struct aml_scope *scope, struct aml_value *lhs , int64_t ival,
2955     struct aml_value *rhs)
2956 {
2957 	struct aml_value tmp;
2958 	struct aml_node *node;
2959 	int mlen;
2960 
2961 	/* Already set */
2962 	if (lhs == rhs || lhs == NULL || lhs->type == AML_OBJTYPE_NOTARGET) {
2963 		return;
2964 	}
2965 	memset(&tmp, 0, sizeof(tmp));
2966 	tmp.refcnt=99;
2967 	if (rhs == NULL) {
2968 		rhs = _aml_setvalue(&tmp, AML_OBJTYPE_INTEGER, ival, NULL);
2969 	}
2970 	if (rhs->type == AML_OBJTYPE_BUFFERFIELD ||
2971 	    rhs->type == AML_OBJTYPE_FIELDUNIT) {
2972 		aml_rwfield(rhs, 0, rhs->v_field.bitlen, &tmp, ACPI_IOREAD);
2973 		rhs = &tmp;
2974 	}
2975 	/* Store to LocalX: free value */
2976 	if (lhs->stack >= AMLOP_LOCAL0 && lhs->stack <= AMLOP_LOCAL7)
2977 		aml_freevalue(lhs);
2978 
2979 	lhs = aml_gettgt(lhs, AMLOP_STORE);
2980 	switch (lhs->type) {
2981 	case AML_OBJTYPE_UNINITIALIZED:
2982 		aml_copyvalue(lhs, rhs);
2983 		break;
2984 	case AML_OBJTYPE_BUFFERFIELD:
2985 	case AML_OBJTYPE_FIELDUNIT:
2986 		aml_rwfield(lhs, 0, lhs->v_field.bitlen, rhs, ACPI_IOWRITE);
2987 		break;
2988 	case AML_OBJTYPE_DEBUGOBJ:
2989 		break;
2990 	case AML_OBJTYPE_INTEGER:
2991 		rhs = aml_convert(rhs, lhs->type, -1);
2992 		lhs->v_integer = rhs->v_integer;
2993 		aml_delref(&rhs, "store.int");
2994 		break;
2995 	case AML_OBJTYPE_BUFFER:
2996 	case AML_OBJTYPE_STRING:
2997 		rhs = aml_convert(rhs, lhs->type, -1);
2998 		if (lhs->length < rhs->length) {
2999 			dnprintf(10, "Overrun! %d,%d\n",
3000 			    lhs->length, rhs->length);
3001 			aml_freevalue(lhs);
3002 			_aml_setvalue(lhs, rhs->type, rhs->length, NULL);
3003 		}
3004 		mlen = min(lhs->length, rhs->length);
3005 		memset(lhs->v_buffer, 0x00, lhs->length);
3006 		memcpy(lhs->v_buffer, rhs->v_buffer, mlen);
3007 		aml_delref(&rhs, "store.bufstr");
3008 		break;
3009 	case AML_OBJTYPE_PACKAGE:
3010 		/* Convert to LHS type, copy into LHS */
3011 		if (rhs->type != AML_OBJTYPE_PACKAGE) {
3012 			aml_die("Copy non-package into package?");
3013 		}
3014 		aml_freevalue(lhs);
3015 		aml_copyvalue(lhs, rhs);
3016 		break;
3017 	case AML_OBJTYPE_NAMEREF:
3018 		node = __aml_searchname(scope->node, lhs->v_nameref, 1);
3019 		if (node == NULL) {
3020 			aml_die("Could not create node %s", lhs->v_nameref);
3021 		}
3022 		aml_copyvalue(node->value, rhs);
3023 		break;
3024 	case AML_OBJTYPE_METHOD:
3025 		/* Method override */
3026 		if (rhs->type != AML_OBJTYPE_INTEGER) {
3027 			aml_die("Overriding a method with a non-int?");
3028 		}
3029 		aml_freevalue(lhs);
3030 		aml_copyvalue(lhs, rhs);
3031 		break;
3032 	default:
3033 		aml_die("Store to default type!	 %x\n", lhs->type);
3034 		break;
3035 	}
3036 	aml_freevalue(&tmp);
3037 }
3038 
3039 #ifdef DDB
3040 /* Disassembler routines */
3041 void aml_disprintf(void *arg, const char *fmt, ...);
3042 
3043 void
3044 aml_disprintf(void *arg, const char *fmt, ...)
3045 {
3046 	va_list ap;
3047 
3048 	va_start(ap, fmt);
3049 	vprintf(fmt, ap);
3050 	va_end(ap);
3051 }
3052 
3053 void
3054 aml_disasm(struct aml_scope *scope, int lvl,
3055     void (*dbprintf)(void *, const char *, ...)
3056 	    __attribute__((__format__(__kprintf__,2,3))),
3057     void *arg)
3058 {
3059 	int pc, opcode;
3060 	struct aml_opcode *htab;
3061 	uint64_t ival;
3062 	struct aml_value *rv, tmp;
3063 	uint8_t *end = NULL;
3064 	struct aml_scope ms;
3065 	char *ch;
3066 	char  mch[64];
3067 
3068 	if (dbprintf == NULL)
3069 		dbprintf = aml_disprintf;
3070 
3071 	pc = aml_pc(scope->pos);
3072 	opcode = aml_parseopcode(scope);
3073 	htab = aml_findopcode(opcode);
3074 
3075 	/* Display address + indent */
3076 	if (lvl <= 0x7FFF) {
3077 		dbprintf(arg, "%.4x ", pc);
3078 		for (pc=0; pc<lvl; pc++) {
3079 			dbprintf(arg, "	 ");
3080 		}
3081 	}
3082 	ch = NULL;
3083 	switch (opcode) {
3084 	case AMLOP_NAMECHAR:
3085 		scope->pos = aml_parsename(scope->node, scope->pos, &rv, 0);
3086 		if (rv->type == AML_OBJTYPE_NAMEREF) {
3087 			ch = "@@@";
3088 			aml_delref(&rv, "disasm");
3089 			break;
3090 		}
3091 		/* if this is a method, get arguments */
3092 		strlcpy(mch, aml_nodename(rv->node), sizeof(mch));
3093 		if (rv->type == AML_OBJTYPE_METHOD) {
3094 			strlcat(mch, "(", sizeof(mch));
3095 			for (ival=0;
3096 			    ival < AML_METHOD_ARGCOUNT(rv->v_method.flags);
3097 			    ival++) {
3098 				strlcat(mch, ival ? ", %z" : "%z",
3099 				    sizeof(mch));
3100 			}
3101 			strlcat(mch, ")", sizeof(mch));
3102 		}
3103 		aml_delref(&rv, "");
3104 		ch = mch;
3105 		break;
3106 
3107 	case AMLOP_ZERO:
3108 	case AMLOP_ONE:
3109 	case AMLOP_ONES:
3110 	case AMLOP_LOCAL0:
3111 	case AMLOP_LOCAL1:
3112 	case AMLOP_LOCAL2:
3113 	case AMLOP_LOCAL3:
3114 	case AMLOP_LOCAL4:
3115 	case AMLOP_LOCAL5:
3116 	case AMLOP_LOCAL6:
3117 	case AMLOP_LOCAL7:
3118 	case AMLOP_ARG0:
3119 	case AMLOP_ARG1:
3120 	case AMLOP_ARG2:
3121 	case AMLOP_ARG3:
3122 	case AMLOP_ARG4:
3123 	case AMLOP_ARG5:
3124 	case AMLOP_ARG6:
3125 	case AMLOP_NOP:
3126 	case AMLOP_REVISION:
3127 	case AMLOP_DEBUG:
3128 	case AMLOP_CONTINUE:
3129 	case AMLOP_BREAKPOINT:
3130 	case AMLOP_BREAK:
3131 		ch="%m";
3132 		break;
3133 	case AMLOP_BYTEPREFIX:
3134 		ch="%b";
3135 		break;
3136 	case AMLOP_WORDPREFIX:
3137 		ch="%w";
3138 		break;
3139 	case AMLOP_DWORDPREFIX:
3140 		ch="%d";
3141 		break;
3142 	case AMLOP_QWORDPREFIX:
3143 		ch="%q";
3144 		break;
3145 	case AMLOP_STRINGPREFIX:
3146 		ch="%a";
3147 		break;
3148 
3149 	case AMLOP_INCREMENT:
3150 	case AMLOP_DECREMENT:
3151 	case AMLOP_LNOT:
3152 	case AMLOP_SIZEOF:
3153 	case AMLOP_DEREFOF:
3154 	case AMLOP_REFOF:
3155 	case AMLOP_OBJECTTYPE:
3156 	case AMLOP_UNLOAD:
3157 	case AMLOP_RELEASE:
3158 	case AMLOP_SIGNAL:
3159 	case AMLOP_RESET:
3160 	case AMLOP_STALL:
3161 	case AMLOP_SLEEP:
3162 	case AMLOP_RETURN:
3163 		ch="%m(%n)";
3164 		break;
3165 	case AMLOP_OR:
3166 	case AMLOP_ADD:
3167 	case AMLOP_AND:
3168 	case AMLOP_NAND:
3169 	case AMLOP_XOR:
3170 	case AMLOP_SHL:
3171 	case AMLOP_SHR:
3172 	case AMLOP_NOR:
3173 	case AMLOP_MOD:
3174 	case AMLOP_SUBTRACT:
3175 	case AMLOP_MULTIPLY:
3176 	case AMLOP_INDEX:
3177 	case AMLOP_CONCAT:
3178 	case AMLOP_CONCATRES:
3179 	case AMLOP_TOSTRING:
3180 		ch="%m(%n, %n, %n)";
3181 		break;
3182 	case AMLOP_CREATEBYTEFIELD:
3183 	case AMLOP_CREATEWORDFIELD:
3184 	case AMLOP_CREATEDWORDFIELD:
3185 	case AMLOP_CREATEQWORDFIELD:
3186 	case AMLOP_CREATEBITFIELD:
3187 		ch="%m(%n, %n, %N)";
3188 		break;
3189 	case AMLOP_CREATEFIELD:
3190 		ch="%m(%n, %n, %n, %N)";
3191 		break;
3192 	case AMLOP_DIVIDE:
3193 	case AMLOP_MID:
3194 		ch="%m(%n, %n, %n, %n)";
3195 		break;
3196 	case AMLOP_LAND:
3197 	case AMLOP_LOR:
3198 	case AMLOP_LNOTEQUAL:
3199 	case AMLOP_LLESSEQUAL:
3200 	case AMLOP_LLESS:
3201 	case AMLOP_LEQUAL:
3202 	case AMLOP_LGREATEREQUAL:
3203 	case AMLOP_LGREATER:
3204 	case AMLOP_NOT:
3205 	case AMLOP_FINDSETLEFTBIT:
3206 	case AMLOP_FINDSETRIGHTBIT:
3207 	case AMLOP_TOINTEGER:
3208 	case AMLOP_TOBUFFER:
3209 	case AMLOP_TOHEXSTRING:
3210 	case AMLOP_TODECSTRING:
3211 	case AMLOP_FROMBCD:
3212 	case AMLOP_TOBCD:
3213 	case AMLOP_WAIT:
3214 	case AMLOP_LOAD:
3215 	case AMLOP_STORE:
3216 	case AMLOP_NOTIFY:
3217 	case AMLOP_COPYOBJECT:
3218 		ch="%m(%n, %n)";
3219 		break;
3220 	case AMLOP_ACQUIRE:
3221 		ch = "%m(%n, %w)";
3222 		break;
3223 	case AMLOP_CONDREFOF:
3224 		ch="%m(%R, %n)";
3225 		break;
3226 	case AMLOP_ALIAS:
3227 		ch="%m(%n, %N)";
3228 		break;
3229 	case AMLOP_NAME:
3230 		ch="%m(%N, %n)";
3231 		break;
3232 	case AMLOP_EVENT:
3233 		ch="%m(%N)";
3234 		break;
3235 	case AMLOP_MUTEX:
3236 		ch = "%m(%N, %b)";
3237 		break;
3238 	case AMLOP_OPREGION:
3239 		ch = "%m(%N, %b, %n, %n)";
3240 		break;
3241 	case AMLOP_DATAREGION:
3242 		ch="%m(%N, %n, %n, %n)";
3243 		break;
3244 	case AMLOP_FATAL:
3245 		ch = "%m(%b, %d, %n)";
3246 		break;
3247 	case AMLOP_IF:
3248 	case AMLOP_WHILE:
3249 	case AMLOP_SCOPE:
3250 	case AMLOP_THERMALZONE:
3251 	case AMLOP_VARPACKAGE:
3252 		end = aml_parseend(scope);
3253 		ch = "%m(%n) {\n%T}";
3254 		break;
3255 	case AMLOP_DEVICE:
3256 		end = aml_parseend(scope);
3257 		ch = "%m(%N) {\n%T}";
3258 		break;
3259 	case AMLOP_POWERRSRC:
3260 		end = aml_parseend(scope);
3261 		ch = "%m(%N, %b, %w) {\n%T}";
3262 		break;
3263 	case AMLOP_PROCESSOR:
3264 		end = aml_parseend(scope);
3265 		ch = "%m(%N, %b, %d, %b) {\n%T}";
3266 		break;
3267 	case AMLOP_METHOD:
3268 		end = aml_parseend(scope);
3269 		ch = "%m(%N, %b) {\n%T}";
3270 		break;
3271 	case AMLOP_PACKAGE:
3272 		end = aml_parseend(scope);
3273 		ch = "%m(%b) {\n%T}";
3274 		break;
3275 	case AMLOP_ELSE:
3276 		end = aml_parseend(scope);
3277 		ch = "%m {\n%T}";
3278 		break;
3279 	case AMLOP_BUFFER:
3280 		end = aml_parseend(scope);
3281 		ch = "%m(%n) { %B }";
3282 		break;
3283 	case AMLOP_INDEXFIELD:
3284 		end = aml_parseend(scope);
3285 		ch = "%m(%n, %n, %b) {\n%F}";
3286 		break;
3287 	case AMLOP_BANKFIELD:
3288 		end = aml_parseend(scope);
3289 		ch = "%m(%n, %n, %n, %b) {\n%F}";
3290 		break;
3291 	case AMLOP_FIELD:
3292 		end = aml_parseend(scope);
3293 		ch = "%m(%n, %b) {\n%F}";
3294 		break;
3295 	case AMLOP_MATCH:
3296 		ch = "%m(%n, %b, %n, %b, %n, %n)";
3297 		break;
3298 	case AMLOP_LOADTABLE:
3299 		ch = "%m(%n, %n, %n, %n, %n, %n)";
3300 		break;
3301 	default:
3302 		aml_die("opcode = %x\n", opcode);
3303 		break;
3304 	}
3305 
3306 	/* Parse printable buffer args */
3307 	while (ch && *ch) {
3308 		char c;
3309 
3310 		if (*ch != '%') {
3311 			dbprintf(arg,"%c", *(ch++));
3312 			continue;
3313 		}
3314 		c = *(++ch);
3315 		switch (c) {
3316 		case 'b':
3317 		case 'w':
3318 		case 'd':
3319 		case 'q':
3320 			/* Parse simple object: don't allocate */
3321 			aml_parsesimple(scope, c, &tmp);
3322 			dbprintf(arg,"0x%llx", tmp.v_integer);
3323 			break;
3324 		case 'a':
3325 			dbprintf(arg, "\'%s\'", scope->pos);
3326 			scope->pos += strlen(scope->pos)+1;
3327 			break;
3328 		case 'N':
3329 			/* Create Name */
3330 			rv = aml_parsesimple(scope, c, NULL);
3331 			dbprintf(arg, "%s", aml_nodename(rv->node));
3332 			break;
3333 		case 'm':
3334 			/* display mnemonic */
3335 			dbprintf(arg, "%s", htab->mnem);
3336 			break;
3337 		case 'R':
3338 			/* Search name */
3339 			printf("%s", aml_getname(scope->pos));
3340 			scope->pos = aml_parsename(scope->node, scope->pos,
3341 			    &rv, 0);
3342 			aml_delref(&rv, 0);
3343 			break;
3344 		case 'z':
3345 		case 'n':
3346 			/* generic arg: recurse */
3347 			aml_disasm(scope, lvl | 0x8000, dbprintf, arg);
3348 			break;
3349 		case 'B':
3350 			/* Buffer */
3351 			scope->pos = end;
3352 			break;
3353 		case 'F':
3354 			/* Scope: Field List */
3355 			memset(&ms, 0, sizeof(ms));
3356 			ms.node = scope->node;
3357 			ms.start = scope->pos;
3358 			ms.end = end;
3359 			ms.pos = ms.start;
3360 			ms.type = AMLOP_FIELD;
3361 
3362 			while (ms.pos < ms.end) {
3363 				if (*ms.pos == 0x00) {
3364 					ms.pos++;
3365 					aml_parselength(&ms);
3366 				} else if (*ms.pos == 0x01) {
3367 					ms.pos+=3;
3368 				} else {
3369 					ms.pos = aml_parsename(ms.node,
3370 					     ms.pos, &rv, 1);
3371 					aml_parselength(&ms);
3372 					dbprintf(arg,"	%s\n",
3373 					    aml_nodename(rv->node));
3374 					aml_delref(&rv, 0);
3375 				}
3376 			}
3377 
3378 			/* Display address and closing bracket */
3379 			dbprintf(arg,"%.4x ", aml_pc(scope->pos));
3380 			for (pc=0; pc<(lvl & 0x7FFF); pc++) {
3381 				dbprintf(arg,"  ");
3382 			}
3383 			scope->pos = end;
3384 			break;
3385 		case 'T':
3386 			/* Scope: Termlist */
3387 			memset(&ms, 0, sizeof(ms));
3388 			ms.node = scope->node;
3389 			ms.start = scope->pos;
3390 			ms.end = end;
3391 			ms.pos = ms.start;
3392 			ms.type = AMLOP_SCOPE;
3393 
3394 			while (ms.pos < ms.end) {
3395 				aml_disasm(&ms, (lvl + 1) & 0x7FFF,
3396 				    dbprintf, arg);
3397 			}
3398 
3399 			/* Display address and closing bracket */
3400 			dbprintf(arg,"%.4x ", aml_pc(scope->pos));
3401 			for (pc=0; pc<(lvl & 0x7FFF); pc++) {
3402 				dbprintf(arg,"  ");
3403 			}
3404 			scope->pos = end;
3405 			break;
3406 		}
3407 		ch++;
3408 	}
3409 	if (lvl <= 0x7FFF) {
3410 		dbprintf(arg,"\n");
3411 	}
3412 }
3413 #endif /* DDB */
3414 
3415 int aml_busy;
3416 
3417 /* Evaluate method or buffervalue objects */
3418 struct aml_value *
3419 aml_eval(struct aml_scope *scope, struct aml_value *my_ret, int ret_type,
3420     int argc, struct aml_value *argv)
3421 {
3422 	struct aml_value *tmp = my_ret;
3423 	struct aml_scope *ms;
3424 	int idx;
3425 
3426 	switch (tmp->type) {
3427 	case AML_OBJTYPE_NAMEREF:
3428 		my_ret = aml_seterror(scope, "Undefined name: %s",
3429 		    aml_getname(my_ret->v_nameref));
3430 		break;
3431 	case AML_OBJTYPE_METHOD:
3432 		dnprintf(10,"\n--== Eval Method [%s, %d args] to %c ==--\n",
3433 		    aml_nodename(tmp->node),
3434 		    AML_METHOD_ARGCOUNT(tmp->v_method.flags),
3435 		    ret_type);
3436 		ms = aml_pushscope(scope, tmp, tmp->node, AMLOP_METHOD);
3437 
3438 		/* Parse method arguments */
3439 		for (idx=0; idx<AML_METHOD_ARGCOUNT(tmp->v_method.flags); idx++) {
3440 			struct aml_value *sp;
3441 
3442 			sp = aml_getstack(ms, AMLOP_ARG0+idx);
3443 			if (argv) {
3444 				aml_copyvalue(sp, &argv[idx]);
3445 			} else {
3446 				_aml_setvalue(sp, AML_OBJTYPE_OBJREF, AMLOP_ARG0 + idx, 0);
3447 				sp->v_objref.ref = aml_parse(scope, 't', "ARGX");
3448 			}
3449 		}
3450 #ifdef ACPI_DEBUG
3451 		aml_showstack(ms);
3452 #endif
3453 
3454 		/* Evaluate method scope */
3455 		aml_root.start = tmp->v_method.base;
3456 		if (tmp->v_method.fneval != NULL) {
3457 			my_ret = tmp->v_method.fneval(ms, NULL);
3458 		} else {
3459 			aml_parse(ms, 'T', "METHEVAL");
3460 			my_ret = ms->retv;
3461 		}
3462 		dnprintf(10,"\n--==Finished evaluating method: %s %c\n",
3463 		    aml_nodename(tmp->node), ret_type);
3464 #ifdef ACPI_DEBUG
3465 		aml_showvalue(my_ret);
3466 		aml_showstack(ms);
3467 #endif
3468 		aml_popscope(ms);
3469 		break;
3470 	case AML_OBJTYPE_BUFFERFIELD:
3471 	case AML_OBJTYPE_FIELDUNIT:
3472 		my_ret = aml_allocvalue(0,0,NULL);
3473 		dnprintf(20,"quick: Convert Bufferfield to %c %p\n",
3474 		    ret_type, my_ret);
3475 		aml_rwfield(tmp, 0, tmp->v_field.bitlen, my_ret, ACPI_IOREAD);
3476 		break;
3477 	}
3478 	if (ret_type == 'i' && my_ret && my_ret->type != AML_OBJTYPE_INTEGER) {
3479 #ifndef SMALL_KERNEL
3480 		aml_showvalue(my_ret);
3481 #endif
3482 		aml_die("Not Integer");
3483 	}
3484 	return my_ret;
3485 }
3486 
3487 /*
3488  * The following opcodes produce return values
3489  *   TOSTRING	-> Str
3490  *   TOHEXSTR	-> Str
3491  *   TODECSTR	-> Str
3492  *   STRINGPFX	-> Str
3493  *   BUFFER	-> Buf
3494  *   CONCATRES	-> Buf
3495  *   TOBUFFER	-> Buf
3496  *   MID	-> Buf|Str
3497  *   CONCAT	-> Buf|Str
3498  *   PACKAGE	-> Pkg
3499  *   VARPACKAGE -> Pkg
3500  *   LOCALx	-> Obj
3501  *   ARGx	-> Obj
3502  *   NAMECHAR	-> Obj
3503  *   REFOF	-> ObjRef
3504  *   INDEX	-> ObjRef
3505  *   DEREFOF	-> DataRefObj
3506  *   COPYOBJECT -> DataRefObj
3507  *   STORE	-> DataRefObj
3508 
3509  *   ZERO	-> Int
3510  *   ONE	-> Int
3511  *   ONES	-> Int
3512  *   REVISION	-> Int
3513  *   B/W/D/Q	-> Int
3514  *   OR		-> Int
3515  *   AND	-> Int
3516  *   ADD	-> Int
3517  *   NAND	-> Int
3518  *   XOR	-> Int
3519  *   SHL	-> Int
3520  *   SHR	-> Int
3521  *   NOR	-> Int
3522  *   MOD	-> Int
3523  *   SUBTRACT	-> Int
3524  *   MULTIPLY	-> Int
3525  *   DIVIDE	-> Int
3526  *   NOT	-> Int
3527  *   TOBCD	-> Int
3528  *   FROMBCD	-> Int
3529  *   FSLEFTBIT	-> Int
3530  *   FSRIGHTBIT -> Int
3531  *   INCREMENT	-> Int
3532  *   DECREMENT	-> Int
3533  *   TOINTEGER	-> Int
3534  *   MATCH	-> Int
3535  *   SIZEOF	-> Int
3536  *   OBJECTTYPE -> Int
3537  *   TIMER	-> Int
3538 
3539  *   CONDREFOF	-> Bool
3540  *   ACQUIRE	-> Bool
3541  *   WAIT	-> Bool
3542  *   LNOT	-> Bool
3543  *   LAND	-> Bool
3544  *   LOR	-> Bool
3545  *   LLESS	-> Bool
3546  *   LEQUAL	-> Bool
3547  *   LGREATER	-> Bool
3548  *   LNOTEQUAL	-> Bool
3549  *   LLESSEQUAL -> Bool
3550  *   LGREATEREQ -> Bool
3551 
3552  *   LOADTABLE	-> DDB
3553  *   DEBUG	-> Debug
3554 
3555  *   The following opcodes do not generate a return value:
3556  *   NOP
3557  *   BREAKPOINT
3558  *   RELEASE
3559  *   RESET
3560  *   SIGNAL
3561  *   NAME
3562  *   ALIAS
3563  *   OPREGION
3564  *   DATAREGION
3565  *   EVENT
3566  *   MUTEX
3567  *   SCOPE
3568  *   DEVICE
3569  *   THERMALZONE
3570  *   POWERRSRC
3571  *   PROCESSOR
3572  *   METHOD
3573  *   CREATEFIELD
3574  *   CREATEBITFIELD
3575  *   CREATEBYTEFIELD
3576  *   CREATEWORDFIELD
3577  *   CREATEDWORDFIELD
3578  *   CREATEQWORDFIELD
3579  *   FIELD
3580  *   INDEXFIELD
3581  *   BANKFIELD
3582  *   STALL
3583  *   SLEEP
3584  *   NOTIFY
3585  *   FATAL
3586  *   LOAD
3587  *   UNLOAD
3588  *   IF
3589  *   ELSE
3590  *   WHILE
3591  *   BREAK
3592  *   CONTINUE
3593  */
3594 
3595 /* Parse a simple object from AML Bytestream */
3596 struct aml_value *
3597 aml_parsesimple(struct aml_scope *scope, char ch, struct aml_value *rv)
3598 {
3599 	if (rv == NULL)
3600 		rv = aml_allocvalue(0,0,NULL);
3601 	switch (ch) {
3602 	case AML_ARG_REVISION:
3603 		_aml_setvalue(rv, AML_OBJTYPE_INTEGER, AML_REVISION, NULL);
3604 		break;
3605 	case AML_ARG_DEBUG:
3606 		_aml_setvalue(rv, AML_OBJTYPE_DEBUGOBJ, 0, NULL);
3607 		break;
3608 	case AML_ARG_BYTE:
3609 		_aml_setvalue(rv, AML_OBJTYPE_INTEGER,
3610 		    aml_get8(scope->pos), NULL);
3611 		scope->pos += 1;
3612 		break;
3613 	case AML_ARG_WORD:
3614 		_aml_setvalue(rv, AML_OBJTYPE_INTEGER,
3615 		    aml_get16(scope->pos), NULL);
3616 		scope->pos += 2;
3617 		break;
3618 	case AML_ARG_DWORD:
3619 		_aml_setvalue(rv, AML_OBJTYPE_INTEGER,
3620 		    aml_get32(scope->pos), NULL);
3621 		scope->pos += 4;
3622 		break;
3623 	case AML_ARG_QWORD:
3624 		_aml_setvalue(rv, AML_OBJTYPE_INTEGER,
3625 		    aml_get64(scope->pos), NULL);
3626 		scope->pos += 8;
3627 		break;
3628 	case AML_ARG_STRING:
3629 		_aml_setvalue(rv, AML_OBJTYPE_STRING, -1, scope->pos);
3630 		scope->pos += rv->length+1;
3631 		break;
3632 	}
3633 	return rv;
3634 }
3635 
3636 /*
3637  * Main Opcode Parser/Evaluator
3638  *
3639  * ret_type is expected type for return value
3640  *   'o' = Data Object (Int/Str/Buf/Pkg/Name)
3641  *   'i' = Integer
3642  *   't' = TermArg     (Int/Str/Buf/Pkg)
3643  *   'r' = Target      (NamedObj/Local/Arg/Null)
3644  *   'S' = SuperName   (NamedObj/Local/Arg)
3645  *   'T' = TermList
3646  */
3647 #define aml_debugger(x)
3648 
3649 int maxdp;
3650 
3651 struct aml_value *
3652 aml_gettgt(struct aml_value *val, int opcode)
3653 {
3654 	while (val && val->type == AML_OBJTYPE_OBJREF) {
3655 		val = val->v_objref.ref;
3656 	}
3657 	return val;
3658 }
3659 
3660 struct aml_value *
3661 aml_seterror(struct aml_scope *scope, const char *fmt, ...)
3662 {
3663 	va_list ap;
3664 
3665 	va_start(ap, fmt);
3666 	printf("### AML PARSE ERROR (0x%x): ", aml_pc(scope->pos));
3667 	vprintf(fmt, ap);
3668 	printf("\n");
3669 	va_end(ap);
3670 
3671 	while (scope) {
3672 		scope->pos = scope->end;
3673 		scope = scope->parent;
3674 	}
3675 	aml_error++;
3676 	return aml_allocvalue(AML_OBJTYPE_INTEGER, 0, 0);
3677 }
3678 
3679 struct aml_value *
3680 aml_loadtable(struct acpi_softc *sc, const char *signature,
3681      const char *oemid, const char *oemtableid, const char *rootpath,
3682      const char *parameterpath, struct aml_value *parameterdata)
3683 {
3684 	struct acpi_table_header *hdr;
3685 	struct acpi_dsdt *p_dsdt;
3686 	struct acpi_q *entry;
3687 
3688 	if (strlen(rootpath) > 0)
3689 		aml_die("LoadTable: RootPathString unsupported");
3690 	if (strlen(parameterpath) > 0)
3691 		aml_die("LoadTable: ParameterPathString unsupported");
3692 
3693 	SIMPLEQ_FOREACH(entry, &sc->sc_tables, q_next) {
3694 		hdr = entry->q_table;
3695 		if (strncmp(hdr->signature, signature,
3696 		    sizeof(hdr->signature)) == 0 &&
3697 		    strncmp(hdr->oemid, oemid, sizeof(hdr->oemid)) == 0 &&
3698 		    strncmp(hdr->oemtableid, oemtableid,
3699 		    sizeof(hdr->oemtableid)) == 0) {
3700 			p_dsdt = entry->q_table;
3701 			acpi_parse_aml(sc, p_dsdt->aml, p_dsdt->hdr_length -
3702 			    sizeof(p_dsdt->hdr));
3703 			return aml_allocvalue(AML_OBJTYPE_DDBHANDLE, 0, 0);
3704 		}
3705 	}
3706 
3707 	return aml_allocvalue(AML_OBJTYPE_INTEGER, 0, 0);
3708 }
3709 
3710 /* Load new SSDT scope from memory address */
3711 struct aml_scope *
3712 aml_load(struct acpi_softc *sc, struct aml_scope *scope,
3713     struct aml_value *rgn, struct aml_value *ddb)
3714 {
3715 	struct acpi_q *entry;
3716 	struct acpi_dsdt *p_ssdt;
3717 	struct aml_value tmp;
3718 
3719 	ddb->type = AML_OBJTYPE_DDBHANDLE;
3720 	ddb->v_integer = 0;
3721 
3722 	memset(&tmp, 0, sizeof(tmp));
3723 	if (rgn->type != AML_OBJTYPE_OPREGION ||
3724 	    rgn->v_opregion.iospace != GAS_SYSTEM_MEMORY)
3725 		goto fail;
3726 
3727 	/* Load SSDT from memory */
3728 	entry = acpi_maptable(sc, rgn->v_opregion.iobase, "SSDT", NULL, NULL, 1);
3729 	if (entry == NULL)
3730 		goto fail;
3731 
3732 	dnprintf(10, "%s: loaded SSDT %s @ %llx\n", sc->sc_dev.dv_xname,
3733 	    aml_nodename(rgn->node), rgn->v_opregion.iobase);
3734 	ddb->v_integer = entry->q_id;
3735 
3736 	p_ssdt = entry->q_table;
3737 	tmp.v_buffer = p_ssdt->aml;
3738 	tmp.length   = p_ssdt->hdr_length - sizeof(p_ssdt->hdr);
3739 
3740 	return aml_pushscope(scope, &tmp, scope->node,
3741 	    AMLOP_LOAD);
3742 fail:
3743 	printf("%s: unable to load %s\n", sc->sc_dev.dv_xname,
3744 	    aml_nodename(rgn->node));
3745 	return NULL;
3746 }
3747 
3748 struct aml_value *
3749 aml_parse(struct aml_scope *scope, int ret_type, const char *stype)
3750 {
3751 	int    opcode, idx, pc;
3752 	struct aml_opcode *htab;
3753 	struct aml_value *opargs[8], *my_ret, *rv;
3754 	struct aml_scope *mscope, *iscope;
3755 	uint8_t *start, *end;
3756 	const char *ch;
3757 	int64_t ival;
3758 	struct timespec ts;
3759 
3760 	my_ret = NULL;
3761 	if (scope == NULL || scope->pos >= scope->end) {
3762 		return NULL;
3763 	}
3764 	if (odp++ > 125)
3765 		panic("depth");
3766 	if (odp > maxdp) {
3767 		maxdp = odp;
3768 		dnprintf(10, "max depth: %d\n", maxdp);
3769 	}
3770 	end = NULL;
3771 	iscope = scope;
3772  start:
3773 	/* --== Stage 0: Get Opcode ==-- */
3774 	start = scope->pos;
3775 	pc = aml_pc(scope->pos);
3776 	aml_debugger(scope);
3777 
3778 	opcode = aml_parseopcode(scope);
3779 	htab = aml_findopcode(opcode);
3780 	if (htab == NULL) {
3781 		/* No opcode handler */
3782 		aml_die("Unknown opcode: %.4x @ %.4x", opcode, pc);
3783 	}
3784 	dnprintf(18,"%.4x %s\n", pc, aml_mnem(opcode, scope->pos));
3785 
3786 	/* --== Stage 1: Process opcode arguments ==-- */
3787 	memset(opargs, 0, sizeof(opargs));
3788 	idx = 0;
3789 	for (ch = htab->args; *ch; ch++) {
3790 		rv = NULL;
3791 		switch (*ch) {
3792 		case AML_ARG_OBJLEN:
3793 			end = aml_parseend(scope);
3794 			break;
3795 		case AML_ARG_IFELSE:
3796                         /* Special Case: IF-ELSE:piTbpT or IF:piT */
3797 			ch = (*end == AMLOP_ELSE && end < scope->end) ?
3798 			    "-TbpT" : "-T";
3799 			break;
3800 
3801 			/* Complex arguments */
3802 		case 's':
3803 		case 'S':
3804 		case AML_ARG_TARGET:
3805 		case AML_ARG_TERMOBJ:
3806 		case AML_ARG_INTEGER:
3807 			if (*ch == 'r' && *scope->pos == AMLOP_ZERO) {
3808 				/* Special case: NULL Target */
3809 				rv = aml_allocvalue(AML_OBJTYPE_NOTARGET, 0, NULL);
3810 				scope->pos++;
3811 			}
3812 			else {
3813 				rv = aml_parse(scope, *ch, htab->mnem);
3814 				if (rv == NULL || aml_error)
3815 					goto parse_error;
3816 			}
3817 			break;
3818 
3819 			/* Simple arguments */
3820 		case AML_ARG_BUFFER:
3821 		case AML_ARG_METHOD:
3822 		case AML_ARG_FIELDLIST:
3823 		case AML_ARG_TERMOBJLIST:
3824 			rv = aml_allocvalue(AML_OBJTYPE_SCOPE, 0, NULL);
3825 			rv->v_buffer = scope->pos;
3826 			rv->length = end - scope->pos;
3827 			scope->pos = end;
3828 			break;
3829 		case AML_ARG_CONST:
3830 			rv = aml_allocvalue(AML_OBJTYPE_INTEGER,
3831 			    (char)opcode, NULL);
3832 			break;
3833 		case AML_ARG_CREATENAME:
3834 			scope->pos = aml_parsename(scope->node, scope->pos,
3835 			    &rv, 1);
3836 			break;
3837 		case AML_ARG_SEARCHNAME:
3838 			scope->pos = aml_parsename(scope->node, scope->pos,
3839 			    &rv, 0);
3840 			break;
3841 		case AML_ARG_BYTE:
3842 		case AML_ARG_WORD:
3843 		case AML_ARG_DWORD:
3844 		case AML_ARG_QWORD:
3845 		case AML_ARG_DEBUG:
3846 		case AML_ARG_STRING:
3847 		case AML_ARG_REVISION:
3848 			rv = aml_parsesimple(scope, *ch, NULL);
3849 			break;
3850 		case AML_ARG_STKLOCAL:
3851 		case AML_ARG_STKARG:
3852 			rv = aml_getstack(scope, opcode);
3853 			break;
3854 		default:
3855 			aml_die("Unknown arg type: %c\n", *ch);
3856 			break;
3857 		}
3858 		if (rv != NULL)
3859 			opargs[idx++] = rv;
3860 		}
3861 
3862 	/* --== Stage 2: Process opcode ==-- */
3863 	ival = 0;
3864 	my_ret = NULL;
3865 	mscope = NULL;
3866 	switch (opcode) {
3867 	case AMLOP_NOP:
3868 	case AMLOP_BREAKPOINT:
3869 		break;
3870 	case AMLOP_LOCAL0:
3871 	case AMLOP_LOCAL1:
3872 	case AMLOP_LOCAL2:
3873 	case AMLOP_LOCAL3:
3874 	case AMLOP_LOCAL4:
3875 	case AMLOP_LOCAL5:
3876 	case AMLOP_LOCAL6:
3877 	case AMLOP_LOCAL7:
3878 	case AMLOP_ARG0:
3879 	case AMLOP_ARG1:
3880 	case AMLOP_ARG2:
3881 	case AMLOP_ARG3:
3882 	case AMLOP_ARG4:
3883 	case AMLOP_ARG5:
3884 	case AMLOP_ARG6:
3885 		my_ret = opargs[0];
3886 		aml_addref(my_ret, htab->mnem);
3887 		break;
3888 	case AMLOP_NAMECHAR:
3889 		/* opargs[0] = named object (node != NULL), or nameref */
3890 		my_ret = opargs[0];
3891 		if (scope->type == AMLOP_PACKAGE) {
3892 			/* Special case for package */
3893 			if (my_ret->type == AML_OBJTYPE_NAMEREF)
3894 				my_ret = aml_allocvalue(AML_OBJTYPE_STRING, -1,
3895 				    aml_getname(my_ret->v_nameref));
3896 			else if (my_ret->node)
3897 				my_ret = aml_allocvalue(AML_OBJTYPE_STRING, -1,
3898 				    aml_nodename(my_ret->node));
3899 			break;
3900 		}
3901 		if (my_ret->type == AML_OBJTYPE_OBJREF) {
3902 			my_ret = my_ret->v_objref.ref;
3903 			aml_addref(my_ret, "de-alias");
3904 		}
3905 		if (ret_type == 'i' || ret_type == 't' || ret_type == 'T') {
3906 			/* Return TermArg or Integer: Evaluate object */
3907 			my_ret = aml_eval(scope, my_ret, ret_type, 0, NULL);
3908 		} else if (my_ret->type == AML_OBJTYPE_METHOD) {
3909 			/* This should only happen with CondRef */
3910 			dnprintf(12,"non-termarg method : %s\n", stype);
3911 			aml_addref(my_ret, "zoom");
3912 		}
3913 		break;
3914 
3915 	case AMLOP_ZERO:
3916 	case AMLOP_ONE:
3917 	case AMLOP_ONES:
3918 	case AMLOP_DEBUG:
3919 	case AMLOP_REVISION:
3920 	case AMLOP_BYTEPREFIX:
3921 	case AMLOP_WORDPREFIX:
3922 	case AMLOP_DWORDPREFIX:
3923 	case AMLOP_QWORDPREFIX:
3924 	case AMLOP_STRINGPREFIX:
3925 		my_ret = opargs[0];
3926 		break;
3927 
3928 	case AMLOP_BUFFER:
3929 		/* Buffer: iB => Buffer */
3930 		my_ret = aml_allocvalue(AML_OBJTYPE_BUFFER,
3931 		    opargs[0]->v_integer, NULL);
3932 		memcpy(my_ret->v_buffer, opargs[1]->v_buffer,
3933 		    opargs[1]->length);
3934 		break;
3935 	case AMLOP_PACKAGE:
3936 	case AMLOP_VARPACKAGE:
3937 		/* Package/VarPackage: bT/iT => Package */
3938 		my_ret = aml_allocvalue(AML_OBJTYPE_PACKAGE,
3939 		    opargs[0]->v_integer, 0);
3940 		mscope = aml_pushscope(scope, opargs[1], scope->node,
3941 		    AMLOP_PACKAGE);
3942 
3943 		/* Recursively parse package contents */
3944 		for (idx=0; idx<my_ret->length; idx++) {
3945 			rv = aml_parse(mscope, 'o', "Package");
3946 			if (rv != NULL) {
3947 				aml_delref(&my_ret->v_package[idx], "pkginit");
3948 				my_ret->v_package[idx] = rv;
3949 			}
3950 		}
3951 		aml_popscope(mscope);
3952 		mscope = NULL;
3953 		break;
3954 
3955 		/* Math/Logical operations */
3956 	case AMLOP_OR:
3957 	case AMLOP_ADD:
3958 	case AMLOP_AND:
3959 	case AMLOP_NAND:
3960 	case AMLOP_XOR:
3961 	case AMLOP_SHL:
3962 	case AMLOP_SHR:
3963 	case AMLOP_NOR:
3964 	case AMLOP_MOD:
3965 	case AMLOP_SUBTRACT:
3966 	case AMLOP_MULTIPLY:
3967 		/* XXX: iir => I */
3968 		ival = aml_evalexpr(opargs[0]->v_integer,
3969 		    opargs[1]->v_integer, opcode);
3970 		aml_store(scope, opargs[2], ival, NULL);
3971 		break;
3972 	case AMLOP_DIVIDE:
3973 		/* Divide: iirr => I */
3974 		if (opargs[1]->v_integer == 0) {
3975 			my_ret = aml_seterror(scope, "Divide by Zero!");
3976 			break;
3977 		}
3978 		ival = aml_evalexpr(opargs[0]->v_integer,
3979 		    opargs[1]->v_integer, AMLOP_MOD);
3980 		aml_store(scope, opargs[2], ival, NULL);
3981 
3982 		ival = aml_evalexpr(opargs[0]->v_integer,
3983 		    opargs[1]->v_integer, AMLOP_DIVIDE);
3984 		aml_store(scope, opargs[3], ival, NULL);
3985 		break;
3986 	case AMLOP_NOT:
3987 	case AMLOP_TOBCD:
3988 	case AMLOP_FROMBCD:
3989 	case AMLOP_FINDSETLEFTBIT:
3990 	case AMLOP_FINDSETRIGHTBIT:
3991 		/* XXX: ir => I */
3992 		ival = aml_evalexpr(opargs[0]->v_integer, 0, opcode);
3993 		aml_store(scope, opargs[1], ival, NULL);
3994 		break;
3995 	case AMLOP_INCREMENT:
3996 	case AMLOP_DECREMENT:
3997 		/* Inc/Dec: S => I */
3998 		my_ret = aml_eval(scope, opargs[0], AML_ARG_INTEGER, 0, NULL);
3999 		ival = aml_evalexpr(my_ret->v_integer, 1, opcode);
4000 		aml_store(scope, opargs[0], ival, NULL);
4001 		break;
4002 	case AMLOP_LNOT:
4003 		/* LNot: i => Bool */
4004 		ival = aml_evalexpr(opargs[0]->v_integer, 0, opcode);
4005 		break;
4006 	case AMLOP_LOR:
4007 	case AMLOP_LAND:
4008 		/* XXX: ii => Bool */
4009 		ival = aml_evalexpr(opargs[0]->v_integer,
4010 		    opargs[1]->v_integer, opcode);
4011 		break;
4012 	case AMLOP_LLESS:
4013 	case AMLOP_LEQUAL:
4014 	case AMLOP_LGREATER:
4015 	case AMLOP_LNOTEQUAL:
4016 	case AMLOP_LLESSEQUAL:
4017 	case AMLOP_LGREATEREQUAL:
4018 		/* XXX: tt => Bool */
4019 		ival = aml_compare(opargs[0], opargs[1], opcode);
4020 		break;
4021 
4022 		/* Reference/Store operations */
4023 	case AMLOP_CONDREFOF:
4024 		/* CondRef: rr => I */
4025 		ival = 0;
4026 		if (opargs[0]->node != NULL) {
4027 			/* Create Object Reference */
4028 			rv = aml_allocvalue(AML_OBJTYPE_OBJREF, opcode,
4029 				opargs[0]);
4030 			aml_addref(opargs[0], "CondRef");
4031 			aml_store(scope, opargs[1], 0, rv);
4032 			aml_delref(&rv, 0);
4033 
4034 			/* Mark that we found it */
4035 			ival = -1;
4036 		}
4037 		break;
4038 	case AMLOP_REFOF:
4039 		/* RefOf: r => ObjRef */
4040 		my_ret = aml_allocvalue(AML_OBJTYPE_OBJREF, opcode, opargs[0]);
4041 		aml_addref(my_ret->v_objref.ref, "RefOf");
4042 		break;
4043 	case AMLOP_INDEX:
4044 		/* Index: tir => ObjRef */
4045 		idx = opargs[1]->v_integer;
4046 		/* Reading past the end of the array? - Ignore */
4047 		if (idx >= opargs[0]->length || idx < 0)
4048 			break;
4049 		switch (opargs[0]->type) {
4050 		case AML_OBJTYPE_PACKAGE:
4051 			/* Don't set opargs[0] to NULL */
4052 			if (ret_type == 't' || ret_type == 'i' || ret_type == 'T') {
4053 				my_ret = opargs[0]->v_package[idx];
4054 				aml_addref(my_ret, "Index.Package");
4055 			} else {
4056 				my_ret = aml_allocvalue(AML_OBJTYPE_OBJREF, AMLOP_PACKAGE,
4057 				    opargs[0]->v_package[idx]);
4058 				aml_addref(my_ret->v_objref.ref,
4059 				    "Index.Package");
4060 			}
4061 			break;
4062 		case AML_OBJTYPE_BUFFER:
4063 		case AML_OBJTYPE_STRING:
4064 		case AML_OBJTYPE_INTEGER:
4065 			rv = aml_convert(opargs[0], AML_OBJTYPE_BUFFER, -1);
4066 			if (ret_type == 't' || ret_type == 'i' || ret_type == 'T') {
4067 				dnprintf(12,"Index.Buf Term: %d = %x\n",
4068 				    idx, rv->v_buffer[idx]);
4069 				ival = rv->v_buffer[idx];
4070 			} else {
4071 				dnprintf(12, "Index.Buf Targ\n");
4072 				my_ret = aml_allocvalue(0,0,NULL);
4073 				aml_createfield(my_ret, AMLOP_INDEX, rv,
4074 				    8 * idx, 8, NULL, 0, AML_FIELD_BYTEACC);
4075 			}
4076 			aml_delref(&rv, "Index.BufStr");
4077 			break;
4078 		default:
4079 			aml_die("Unknown index : %x\n", opargs[0]->type);
4080 			break;
4081 		}
4082 		aml_store(scope, opargs[2], ival, my_ret);
4083 		break;
4084 	case AMLOP_DEREFOF:
4085 		/* DerefOf: t:ObjRef => DataRefObj */
4086 		if (opargs[0]->type == AML_OBJTYPE_OBJREF) {
4087 			my_ret = opargs[0]->v_objref.ref;
4088 			aml_addref(my_ret, "DerefOf");
4089 		} else {
4090 			my_ret = opargs[0];
4091 			//aml_addref(my_ret, "DerefOf");
4092 		}
4093 		break;
4094 	case AMLOP_COPYOBJECT:
4095 		/* CopyObject: t:DataRefObj, s:implename => DataRefObj */
4096 		my_ret = opargs[0];
4097 		aml_freevalue(opargs[1]);
4098 		aml_copyvalue(opargs[1], opargs[0]);
4099 		break;
4100 	case AMLOP_STORE:
4101 		/* Store: t:DataRefObj, S:upername => DataRefObj */
4102 		my_ret = opargs[0];
4103 		aml_store(scope, opargs[1], 0, opargs[0]);
4104 		break;
4105 
4106 		/* Conversion */
4107 	case AMLOP_TOINTEGER:
4108 		/* Source:CData, Result => Integer */
4109 		my_ret = aml_convert(opargs[0], AML_OBJTYPE_INTEGER, -1);
4110 		aml_store(scope, opargs[1], 0, my_ret);
4111 		break;
4112 	case AMLOP_TOBUFFER:
4113 		/* Source:CData, Result => Buffer */
4114 		my_ret = aml_convert(opargs[0], AML_OBJTYPE_BUFFER, -1);
4115 		aml_store(scope, opargs[1], 0, my_ret);
4116 		break;
4117 	case AMLOP_TOHEXSTRING:
4118 		/* Source:CData, Result => String */
4119 		my_ret = aml_convert(opargs[0], AML_OBJTYPE_HEXSTRING, -1);
4120 		aml_store(scope, opargs[1], 0, my_ret);
4121 		break;
4122 	case AMLOP_TODECSTRING:
4123 		/* Source:CData, Result => String */
4124 		my_ret = aml_convert(opargs[0], AML_OBJTYPE_DECSTRING, -1);
4125 		aml_store(scope, opargs[1], 0, my_ret);
4126 		break;
4127 	case AMLOP_TOSTRING:
4128 		/* Source:B, Length:I, Result => String */
4129 		my_ret = aml_convert(opargs[0], AML_OBJTYPE_STRING,
4130 		    opargs[1]->v_integer);
4131 		aml_store(scope, opargs[2], 0, my_ret);
4132 		break;
4133 	case AMLOP_CONCAT:
4134 		/* Source1:CData, Source2:CData, Result => CData */
4135 		my_ret = aml_concat(opargs[0], opargs[1]);
4136 		aml_store(scope, opargs[2], 0, my_ret);
4137 		break;
4138 	case AMLOP_CONCATRES:
4139 		/* Concat two resource buffers: buf1, buf2, result => Buffer */
4140 		my_ret = aml_concatres(opargs[0], opargs[1]);
4141 		aml_store(scope, opargs[2], 0, my_ret);
4142 		break;
4143 	case AMLOP_MID:
4144 		/* Source:BS, Index:I, Length:I, Result => BS */
4145 		my_ret = aml_mid(opargs[0], opargs[1]->v_integer,
4146 		    opargs[2]->v_integer);
4147 		aml_store(scope, opargs[3], 0, my_ret);
4148 		break;
4149 	case AMLOP_MATCH:
4150 		/* Match: Pkg, Op1, Val1, Op2, Val2, Index */
4151 		ival = aml_match(opargs[0], opargs[5]->v_integer,
4152 		    opargs[1]->v_integer, opargs[2]->v_integer,
4153 		    opargs[3]->v_integer, opargs[4]->v_integer);
4154 		break;
4155 	case AMLOP_SIZEOF:
4156 		/* Sizeof: S => i */
4157 		rv = aml_gettgt(opargs[0], opcode);
4158 		ival = rv->length;
4159 		break;
4160 	case AMLOP_OBJECTTYPE:
4161 		/* ObjectType: S => i */
4162 		rv = aml_gettgt(opargs[0], opcode);
4163 		ival = rv->type;
4164 		break;
4165 
4166 		/* Mutex/Event handlers */
4167 	case AMLOP_ACQUIRE:
4168 		/* Acquire: Sw => Bool */
4169 		rv = aml_gettgt(opargs[0], opcode);
4170 		ival = acpi_mutex_acquire(scope, rv,
4171 		    opargs[1]->v_integer);
4172 		break;
4173 	case AMLOP_RELEASE:
4174 		/* Release: S */
4175 		rv = aml_gettgt(opargs[0], opcode);
4176 		acpi_mutex_release(scope, rv);
4177 		break;
4178 	case AMLOP_WAIT:
4179 		/* Wait: Si => Bool */
4180 		rv = aml_gettgt(opargs[0], opcode);
4181 		ival = acpi_event_wait(scope, rv,
4182 		    opargs[1]->v_integer);
4183 		break;
4184 	case AMLOP_RESET:
4185 		/* Reset: S */
4186 		rv = aml_gettgt(opargs[0], opcode);
4187 		acpi_event_reset(scope, rv);
4188 		break;
4189 	case AMLOP_SIGNAL:
4190 		/* Signal: S */
4191 		rv = aml_gettgt(opargs[0], opcode);
4192 		acpi_event_signal(scope, rv);
4193 		break;
4194 
4195 		/* Named objects */
4196 	case AMLOP_NAME:
4197 		/* Name: Nt */
4198 		rv = opargs[0];
4199 		aml_freevalue(rv);
4200 			aml_copyvalue(rv, opargs[1]);
4201 		break;
4202 	case AMLOP_ALIAS:
4203 		/* Alias: nN */
4204 		rv = _aml_setvalue(opargs[1], AML_OBJTYPE_OBJREF, opcode, 0);
4205 		rv->v_objref.ref = aml_gettgt(opargs[0], opcode);
4206 		aml_addref(rv->v_objref.ref, "Alias");
4207 		break;
4208 	case AMLOP_OPREGION:
4209 		/* OpRegion: Nbii */
4210 		rv = _aml_setvalue(opargs[0], AML_OBJTYPE_OPREGION, 0, 0);
4211 		rv->v_opregion.iospace = opargs[1]->v_integer;
4212 		rv->v_opregion.iobase = opargs[2]->v_integer;
4213 		rv->v_opregion.iolen = opargs[3]->v_integer;
4214 		rv->v_opregion.flag = 0;
4215 		break;
4216 	case AMLOP_DATAREGION:
4217 		/* DataTableRegion: N,t:SigStr,t:OemIDStr,t:OemTableIDStr */
4218 		rv = _aml_setvalue(opargs[0], AML_OBJTYPE_OPREGION, 0, 0);
4219 		rv->v_opregion.iospace = GAS_SYSTEM_MEMORY;
4220 		rv->v_opregion.iobase = 0;
4221 		rv->v_opregion.iolen = 0;
4222 		aml_die("AML-DataTableRegion\n");
4223 		break;
4224 	case AMLOP_EVENT:
4225 		/* Event: N */
4226 		rv = _aml_setvalue(opargs[0], AML_OBJTYPE_EVENT, 0, 0);
4227 		rv->v_evt.state = 0;
4228 		break;
4229 	case AMLOP_MUTEX:
4230 		/* Mutex: Nw */
4231 		rv = _aml_setvalue(opargs[0], AML_OBJTYPE_MUTEX, 0, 0);
4232 		rv->v_mtx.synclvl = opargs[1]->v_integer;
4233 		break;
4234 	case AMLOP_SCOPE:
4235 		/* Scope: NT */
4236 		rv = opargs[0];
4237 		if (rv->type == AML_OBJTYPE_NAMEREF) {
4238 			printf("Undefined scope: %s\n", aml_getname(rv->v_nameref));
4239 			break;
4240 		}
4241 		mscope = aml_pushscope(scope, opargs[1], rv->node, opcode);
4242 		break;
4243 	case AMLOP_DEVICE:
4244 		/* Device: NT */
4245 		rv = _aml_setvalue(opargs[0], AML_OBJTYPE_DEVICE, 0, 0);
4246 		mscope = aml_pushscope(scope, opargs[1], rv->node, opcode);
4247 		break;
4248 	case AMLOP_THERMALZONE:
4249 		/* ThermalZone: NT */
4250 		rv = _aml_setvalue(opargs[0], AML_OBJTYPE_THERMZONE, 0, 0);
4251 		mscope = aml_pushscope(scope, opargs[1], rv->node, opcode);
4252 		break;
4253 	case AMLOP_POWERRSRC:
4254 		/* PowerRsrc: NbwT */
4255 		rv = _aml_setvalue(opargs[0], AML_OBJTYPE_POWERRSRC, 0, 0);
4256 		rv->v_powerrsrc.pwr_level = opargs[1]->v_integer;
4257 		rv->v_powerrsrc.pwr_order = opargs[2]->v_integer;
4258 		mscope = aml_pushscope(scope, opargs[3], rv->node, opcode);
4259 		break;
4260 	case AMLOP_PROCESSOR:
4261 		/* Processor: NbdbT */
4262 		rv = _aml_setvalue(opargs[0], AML_OBJTYPE_PROCESSOR, 0, 0);
4263 		rv->v_processor.proc_id = opargs[1]->v_integer;
4264 		rv->v_processor.proc_addr = opargs[2]->v_integer;
4265 		rv->v_processor.proc_len = opargs[3]->v_integer;
4266 		mscope = aml_pushscope(scope, opargs[4], rv->node, opcode);
4267 		break;
4268 	case AMLOP_METHOD:
4269 		/* Method: NbM */
4270 		rv = _aml_setvalue(opargs[0], AML_OBJTYPE_METHOD, 0, 0);
4271 		rv->v_method.flags = opargs[1]->v_integer;
4272 		rv->v_method.start = opargs[2]->v_buffer;
4273 		rv->v_method.end = rv->v_method.start + opargs[2]->length;
4274 		rv->v_method.base = aml_root.start;
4275 		break;
4276 
4277 		/* Field objects */
4278 	case AMLOP_CREATEFIELD:
4279 		/* Source:B, BitIndex:I, NumBits:I, FieldName */
4280 		rv = _aml_setvalue(opargs[3], AML_OBJTYPE_BUFFERFIELD, 0, 0);
4281 		aml_createfield(rv, opcode, opargs[0], opargs[1]->v_integer,
4282 		    opargs[2]->v_integer, NULL, 0, 0);
4283 		break;
4284 	case AMLOP_CREATEBITFIELD:
4285 		/* Source:B, BitIndex:I, FieldName */
4286 		rv = _aml_setvalue(opargs[2], AML_OBJTYPE_BUFFERFIELD, 0, 0);
4287 		aml_createfield(rv, opcode, opargs[0], opargs[1]->v_integer,
4288 		    1, NULL, 0, 0);
4289 		break;
4290 	case AMLOP_CREATEBYTEFIELD:
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 		    8, NULL, 0, AML_FIELD_BYTEACC);
4295 		break;
4296 	case AMLOP_CREATEWORDFIELD:
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 		    16, NULL, 0, AML_FIELD_WORDACC);
4301 		break;
4302 	case AMLOP_CREATEDWORDFIELD:
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 		    32, NULL, 0, AML_FIELD_DWORDACC);
4307 		break;
4308 	case AMLOP_CREATEQWORDFIELD:
4309 		/* Source:B, ByteIndex:I, FieldName */
4310 		rv = _aml_setvalue(opargs[2], AML_OBJTYPE_BUFFERFIELD, 0, 0);
4311 		aml_createfield(rv, opcode, opargs[0], opargs[1]->v_integer*8,
4312 		    64, NULL, 0, AML_FIELD_QWORDACC);
4313 		break;
4314 	case AMLOP_FIELD:
4315 		/* Field: n:OpRegion, b:Flags, F:ieldlist */
4316 		mscope = aml_pushscope(scope, opargs[2], scope->node, opcode);
4317 		aml_parsefieldlist(mscope, opcode, opargs[1]->v_integer,
4318 		    opargs[0], NULL, 0);
4319 		mscope = NULL;
4320 		break;
4321 	case AMLOP_INDEXFIELD:
4322 		/* IndexField: n:Index, n:Data, b:Flags, F:ieldlist */
4323 		mscope = aml_pushscope(scope, opargs[3], scope->node, opcode);
4324 		aml_parsefieldlist(mscope, opcode, opargs[2]->v_integer,
4325 		    opargs[1], opargs[0], 0);
4326 		mscope = NULL;
4327 		break;
4328 	case AMLOP_BANKFIELD:
4329 		/* BankField: n:OpRegion, n:Field, i:Bank, b:Flags, F:ieldlist */
4330 		mscope = aml_pushscope(scope, opargs[4], scope->node, opcode);
4331 		aml_parsefieldlist(mscope, opcode, opargs[3]->v_integer,
4332 		    opargs[0], opargs[1], opargs[2]->v_integer);
4333 		mscope = NULL;
4334 		break;
4335 
4336 		/* Misc functions */
4337 	case AMLOP_STALL:
4338 		/* Stall: i */
4339 		acpi_stall(opargs[0]->v_integer);
4340 		break;
4341 	case AMLOP_SLEEP:
4342 		/* Sleep: i */
4343 		acpi_sleep(opargs[0]->v_integer, "amlsleep");
4344 		break;
4345 	case AMLOP_NOTIFY:
4346 		/* Notify: Si */
4347 		rv = aml_gettgt(opargs[0], opcode);
4348 		dnprintf(50,"Notifying: %s %llx\n",
4349 		    aml_nodename(rv->node),
4350 		    opargs[1]->v_integer);
4351 		aml_notify(rv->node, opargs[1]->v_integer);
4352 		break;
4353 	case AMLOP_TIMER:
4354 		/* Timer: => i */
4355 		nanouptime(&ts);
4356 		ival = ts.tv_sec * 10000000 + ts.tv_nsec / 100;
4357 		break;
4358 	case AMLOP_FATAL:
4359 		/* Fatal: bdi */
4360 		aml_die("AML FATAL ERROR: %x,%x,%x\n",
4361 		    opargs[0]->v_integer, opargs[1]->v_integer,
4362 		    opargs[2]->v_integer);
4363 		break;
4364 	case AMLOP_LOADTABLE:
4365 		/* LoadTable(Sig:Str, OEMID:Str, OEMTable:Str, [RootPath:Str], [ParmPath:Str],
4366 		   [ParmData:DataRefObj]) => DDBHandle */
4367 		my_ret = aml_loadtable(acpi_softc, opargs[0]->v_string,
4368 		    opargs[1]->v_string, opargs[2]->v_string,
4369 		    opargs[3]->v_string, opargs[4]->v_string, opargs[5]);
4370 		break;
4371 	case AMLOP_LOAD:
4372 		/* Load(Object:NameString, DDBHandle:SuperName) */
4373 		mscope = aml_load(acpi_softc, scope, opargs[0], opargs[1]);
4374 		break;
4375 	case AMLOP_UNLOAD:
4376 		/* DDBHandle */
4377 		aml_die("Unload");
4378 		break;
4379 
4380 		/* Control Flow */
4381 	case AMLOP_IF:
4382 		/* Arguments: iT or iTbT */
4383 		if (opargs[0]->v_integer) {
4384 			dnprintf(10,"parse-if @ %.4x\n", pc);
4385 			mscope = aml_pushscope(scope, opargs[1], scope->node,
4386 			    AMLOP_IF);
4387 		} else if (opargs[3] != NULL) {
4388 			dnprintf(10,"parse-else @ %.4x\n", pc);
4389 			mscope = aml_pushscope(scope, opargs[3], scope->node,
4390 			    AMLOP_ELSE);
4391 		}
4392 		break;
4393 	case AMLOP_WHILE:
4394 		if (opargs[0]->v_integer) {
4395 			/* Set parent position to start of WHILE */
4396 			scope->pos = start;
4397 			mscope = aml_pushscope(scope, opargs[1], scope->node,
4398 			    AMLOP_WHILE);
4399 		}
4400 		break;
4401 	case AMLOP_BREAK:
4402 		/* Break: Find While Scope parent, mark type as null */
4403 		aml_findscope(scope, AMLOP_WHILE, AMLOP_BREAK);
4404 		break;
4405 	case AMLOP_CONTINUE:
4406 		/* Find Scope.. mark all objects as invalid on way to root */
4407 		aml_findscope(scope, AMLOP_WHILE, AMLOP_CONTINUE);
4408 		break;
4409 	case AMLOP_RETURN:
4410 		mscope = aml_findscope(scope, AMLOP_METHOD, AMLOP_RETURN);
4411 		if (mscope->retv) {
4412 			aml_die("already allocated\n");
4413 		}
4414 		mscope->retv = aml_allocvalue(0,0,NULL);
4415 		aml_copyvalue(mscope->retv, opargs[0]);
4416 		mscope = NULL;
4417 		break;
4418 	default:
4419 		/* may be set direct result */
4420 		aml_die("Unknown opcode: %x:%s\n", opcode, htab->mnem);
4421 		break;
4422 	}
4423 	if (mscope != NULL) {
4424 		/* Change our scope to new scope */
4425 		scope = mscope;
4426 	}
4427 	if ((ret_type == 'i' || ret_type == 't') && my_ret == NULL) {
4428 		dnprintf(10,"quick: %.4x [%s] alloc return integer = 0x%llx\n",
4429 		    pc, htab->mnem, ival);
4430 		my_ret = aml_allocvalue(AML_OBJTYPE_INTEGER, ival, NULL);
4431 	}
4432 	if (ret_type == 'i' && my_ret && my_ret->type != AML_OBJTYPE_INTEGER) {
4433 		dnprintf(10,"quick: %.4x convert to integer %s -> %s\n",
4434 		    pc, htab->mnem, stype);
4435 		my_ret = aml_convert(my_ret, AML_OBJTYPE_INTEGER, -1);
4436 	}
4437 	if (my_ret != NULL) {
4438 		/* Display result */
4439 		dnprintf(20,"quick: %.4x %18s %c %.4x\n", pc, stype,
4440 		    ret_type, my_ret->stack);
4441 	}
4442 
4443 	/* End opcode: display/free arguments */
4444 parse_error:
4445 	for (idx=0; idx<8; idx++) {
4446 		if (opargs[idx] == my_ret)
4447 			opargs[idx] = NULL;
4448 		aml_delref(&opargs[idx], "oparg");
4449 	}
4450 
4451 	/* If parsing whole scope and not done, start again */
4452 	if (ret_type == 'T') {
4453 		aml_delref(&my_ret, "scope.loop");
4454 		while (scope->pos >= scope->end && scope != iscope) {
4455 			/* Pop intermediate scope */
4456 			scope = aml_popscope(scope);
4457 		}
4458 		if (scope->pos && scope->pos < scope->end)
4459 			goto start;
4460 	}
4461 
4462 	odp--;
4463 	dnprintf(50, ">>return [%s] %s %c %p\n", aml_nodename(scope->node),
4464 	    stype, ret_type, my_ret);
4465 
4466 	return my_ret;
4467 }
4468 
4469 int
4470 acpi_parse_aml(struct acpi_softc *sc, uint8_t *start, uint32_t length)
4471 {
4472 	struct aml_scope *scope;
4473 	struct aml_value res;
4474 
4475 	aml_root.start = start;
4476 	memset(&res, 0, sizeof(res));
4477 	res.type = AML_OBJTYPE_SCOPE;
4478 	res.length = length;
4479 	res.v_buffer = start;
4480 
4481 	/* Push toplevel scope, parse AML */
4482 	aml_error = 0;
4483 	scope = aml_pushscope(NULL, &res, &aml_root, AMLOP_SCOPE);
4484 	aml_busy++;
4485 	aml_parse(scope, 'T', "TopLevel");
4486 	aml_busy--;
4487 	aml_popscope(scope);
4488 
4489 	if (aml_error) {
4490 		printf("error in acpi_parse_aml\n");
4491 		return -1;
4492 	}
4493 	return (0);
4494 }
4495 
4496 /*
4497  * @@@: External API
4498  *
4499  * evaluate an AML node
4500  * Returns a copy of the value in res  (must be freed by user)
4501  */
4502 int
4503 aml_evalnode(struct acpi_softc *sc, struct aml_node *node,
4504     int argc, struct aml_value *argv, struct aml_value *res)
4505 {
4506 	struct aml_value *xres;
4507 
4508 	if (res)
4509 		memset(res, 0, sizeof(*res));
4510 	if (node == NULL || node->value == NULL)
4511 		return (ACPI_E_BADVALUE);
4512 	dnprintf(12,"EVALNODE: %s %lx\n", aml_nodename(node), acpi_nalloc);
4513 
4514 	aml_error = 0;
4515 	xres = aml_eval(NULL, node->value, 't', argc, argv);
4516 	if (xres) {
4517 		if (res)
4518 			aml_copyvalue(res, xres);
4519 		if (xres != node->value)
4520 			aml_delref(&xres, "evalnode");
4521 	}
4522 	if (aml_error) {
4523 		printf("error evaluating: %s\n", aml_nodename(node));
4524 		return (-1);
4525 	}
4526 	return (0);
4527 }
4528 
4529 int
4530 aml_node_setval(struct acpi_softc *sc, struct aml_node *node, int64_t val)
4531 {
4532 	struct aml_value env;
4533 
4534 	if (!node)
4535 		return (0);
4536 
4537 	memset(&env, 0, sizeof(env));
4538 	env.type = AML_OBJTYPE_INTEGER;
4539 	env.v_integer = val;
4540 
4541 	return aml_evalnode(sc, node, 1, &env, NULL);
4542 }
4543 
4544 /*
4545  * evaluate an AML name
4546  * Returns a copy of the value in res  (must be freed by user)
4547  */
4548 int
4549 aml_evalname(struct acpi_softc *sc, struct aml_node *parent, const char *name,
4550     int argc, struct aml_value *argv, struct aml_value *res)
4551 {
4552 	parent = aml_searchname(parent, name);
4553 	return aml_evalnode(sc, parent, argc, argv, res);
4554 }
4555 
4556 /*
4557  * evaluate an AML integer object
4558  */
4559 int
4560 aml_evalinteger(struct acpi_softc *sc, struct aml_node *parent,
4561     const char *name, int argc, struct aml_value *argv, int64_t *ival)
4562 {
4563 	struct aml_value res;
4564 	int rc;
4565 
4566 	parent = aml_searchname(parent, name);
4567 	rc = aml_evalnode(sc, parent, argc, argv, &res);
4568 	if (rc == 0) {
4569 		*ival = aml_val2int(&res);
4570 		aml_freevalue(&res);
4571 	}
4572 	return rc;
4573 }
4574 
4575 /*
4576  * Search for an AML name in namespace.. root only
4577  */
4578 struct aml_node *
4579 __aml_searchname(struct aml_node *root, const void *vname, int create)
4580 {
4581 	char *name = (char *)vname;
4582 	char  nseg[AML_NAMESEG_LEN + 1];
4583 	int   i;
4584 
4585 	dnprintf(25,"Searchname: %s:%s = ", aml_nodename(root), name);
4586 	while (*name == AMLOP_ROOTCHAR) {
4587 		root = &aml_root;
4588 		name++;
4589 	}
4590 	while (*name != 0) {
4591 		/* Ugh.. we can have short names here: append '_' */
4592 		strlcpy(nseg, "____", sizeof(nseg));
4593 		for (i=0; i < AML_NAMESEG_LEN && *name && *name != '.'; i++)
4594 			nseg[i] = *name++;
4595 		if (*name == '.')
4596 			name++;
4597 		root = __aml_search(root, nseg, create);
4598 	}
4599 	dnprintf(25,"%p %s\n", root, aml_nodename(root));
4600 	return root;
4601 }
4602 
4603 struct aml_node *
4604 aml_searchname(struct aml_node *root, const void *vname)
4605 {
4606 	return __aml_searchname(root, vname, 0);
4607 }
4608 
4609 /*
4610  * Search for relative name
4611  */
4612 struct aml_node *
4613 aml_searchrel(struct aml_node *root, const void *vname)
4614 {
4615 	struct aml_node *res;
4616 
4617 	while (root) {
4618 		res = aml_searchname(root, vname);
4619 		if (res != NULL)
4620 			return res;
4621 		root = root->parent;
4622 	}
4623 	return NULL;
4624 }
4625 
4626 #ifndef SMALL_KERNEL
4627 
4628 void
4629 acpi_getdevlist(struct acpi_devlist_head *list, struct aml_node *root,
4630     struct aml_value *pkg, int off)
4631 {
4632 	struct acpi_devlist *dl;
4633 	struct aml_node *node;
4634 	int idx;
4635 
4636 	for (idx=off; idx<pkg->length; idx++) {
4637 		node = aml_searchname(root, pkg->v_package[idx]->v_string);
4638 		if (node) {
4639 			dl = acpi_os_malloc(sizeof(*dl));
4640 			if (dl) {
4641 				dl->dev_node = node;
4642 				TAILQ_INSERT_TAIL(list, dl, dev_link);
4643 			}
4644 		}
4645 	}
4646 }
4647 
4648 void
4649 acpi_freedevlist(struct acpi_devlist_head *list)
4650 {
4651 	struct acpi_devlist *dl;
4652 
4653 	while ((dl = TAILQ_FIRST(list)) != NULL) {
4654 		TAILQ_REMOVE(list, dl, dev_link);
4655 		acpi_os_free(dl);
4656 	}
4657 }
4658 #endif /* SMALL_KERNEL */
4659