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